A plugin card showed "7 skills, 5 agents" and nothing more — the counts
were the whole story, so finding out WHICH skills a plugin ships meant
opening its install directory by hand. The contribution chips are now
buttons: clicking one expands a list naming each artifact with its
description, one surface open at a time. Commands render with their
slash. Hooks stay a plain chip — a plugin's hooks are matcher/command
pairs declared inline in plugin.json, not named artifacts.
`contributes.items` carries the four surfaces server-side; the existing
counts keep their type and are now derived from those lists, so a chip
reading "3 commands" can never sit beside a list holding two.
That also fixes a real blind spot. Each surface was read only from the
conventional install subdirectory, but plugin.json may declare its own
paths — this repo's own `ccam` lists three files under
plugins/ccam/commands/ and keeps commands/ empty, so it reported zero
commands. Both sources are now read and de-duplicated. A declared path
resolving outside the plugin's install directory is dropped: a manifest
is third-party data and must not turn the dashboard into an arbitrary
file reader.
Also pins the Refresh button's width: both labels share one grid cell so
the button is always as wide as "Refreshing…" / "Đang làm mới…" and no
longer resizes the toolbar when the state flips. Measuring the longest
real string beats a min-width that would be wrong in the next language.
Verified: npm run test:server (1370 tests, +6 for the new discovery),
npm run test:client (457, +3 for the expand behaviour), tsc --noEmit,
prettier and check-headers clean. Docs synced: docs/API.md, openapi.yaml
(new CcConfigPluginItem schema), ARCHITECTURE.md, docs/PLUGINS.md.
Adds POST /api/updates/apply (pull, rebuild, restart) plus an "Update now"
button and hourly auto-check in the UI, for checkouts that are safely
fast-forwardable. Reintroduces self-restart (previously removed in edc25ca
for cross-environment reliability concerns) per explicit user request.
Gives each lane its own slot-derived runtime (ports, detached process
lifecycle, profile-driven hooks) and its own database/Redis logical
index/.env file, so two lanes running the same repo's stack at once no
longer share state. Machine-level DB/Redis credentials live at
~/.ccam/secrets.env (mode 0600, never returned by any route); a hook's
output is redacted of that password (raw and URL-encoded forms) before
it reaches a log file or the lane_hook_output websocket broadcast.
Wired into provision/up/reset/remove; reset accepts --keep-db to skip
the drop/recreate/migrate/reseed block entirely.
Internal SmartGift build of a Claude Code monitoring dashboard.
Lanes: a durable unit of parallel agent work, one per working directory,
tracked across session restarts. Managed lanes are git worktrees the
dashboard provisions and can reset or remove behind a three-check destroy
guard and a counted preflight; adopted lanes are directories you already
own and are never destroyable.
Pipelines: a lane moves through pipeline stages. A stage the agent declares
with evidence renders green; a stage inferred from the tool-event stream
renders dashed amber and never counts as done. Detection is forward-only
within a 30-minute window, and never writes the declared stage.
Workspace: one page at /run with a lane grid, the selected lane's pipeline,
and a full Claude console behind a disclosure.