Files
mcpctl/pnpm-lock.yaml

10346 lines
334 KiB
YAML
Raw Permalink Normal View History

2026-02-21 03:10:39 +00:00
lockfileVersion: '9.0'
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
importers:
.:
devDependencies:
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
'@earendil-works/pi-ai':
specifier: ^0.84.1
version: 0.84.1(@modelcontextprotocol/sdk@1.26.0(zod@3.25.76))(ws@8.19.0)(zod@3.25.76)
'@earendil-works/pi-coding-agent':
specifier: 0.84.1
version: 0.84.1(@modelcontextprotocol/sdk@1.26.0(zod@3.25.76))(ws@8.19.0)(zod@3.25.76)
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
'@opencode-ai/plugin':
specifier: 1.18.15
version: 1.18.15(@opentui/core@0.4.5(typescript@5.9.3)(web-tree-sitter@0.25.10))(@opentui/keymap@0.4.5(@opentui/solid@0.4.5(solid-js@1.9.12)(typescript@5.9.3)(web-tree-sitter@0.25.10))(react@19.2.5)(solid-js@1.9.12)(typescript@5.9.3)(web-tree-sitter@0.25.10))(@opentui/solid@0.4.5(solid-js@1.9.12)(typescript@5.9.3)(web-tree-sitter@0.25.10))
'@opentui/core':
specifier: 0.4.5
version: 0.4.5(typescript@5.9.3)(web-tree-sitter@0.25.10)
'@opentui/keymap':
specifier: 0.4.5
version: 0.4.5(@opentui/solid@0.4.5(solid-js@1.9.12)(typescript@5.9.3)(web-tree-sitter@0.25.10))(react@19.2.5)(solid-js@1.9.12)(typescript@5.9.3)(web-tree-sitter@0.25.10)
'@opentui/solid':
specifier: 0.4.5
version: 0.4.5(solid-js@1.9.12)(typescript@5.9.3)(web-tree-sitter@0.25.10)
'@types/node':
specifier: ^25.3.0
version: 25.3.0
2026-02-21 03:10:39 +00:00
'@typescript-eslint/eslint-plugin':
specifier: ^8.56.0
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
version: 8.56.0(@typescript-eslint/parser@8.56.0(eslint@10.0.1(jiti@2.7.0))(typescript@5.9.3))(eslint@10.0.1(jiti@2.7.0))(typescript@5.9.3)
2026-02-21 03:10:39 +00:00
'@typescript-eslint/parser':
specifier: ^8.56.0
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
version: 8.56.0(eslint@10.0.1(jiti@2.7.0))(typescript@5.9.3)
2026-02-21 03:10:39 +00:00
'@vitest/coverage-v8':
specifier: ^4.0.18
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
version: 4.0.18(vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@25.3.0)(jiti@2.7.0)(jsdom@28.1.0)(lightningcss@1.32.0)(tsx@4.21.0)(yaml@2.9.0))
2026-02-21 03:10:39 +00:00
eslint:
specifier: ^10.0.1
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
version: 10.0.1(jiti@2.7.0)
2026-02-21 03:10:39 +00:00
eslint-config-prettier:
specifier: ^10.1.8
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
version: 10.1.8(eslint@10.0.1(jiti@2.7.0))
2026-02-21 03:10:39 +00:00
rimraf:
specifier: ^6.1.3
version: 6.1.3
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
solid-js:
specifier: 1.9.12
version: 1.9.12
2026-02-21 03:10:39 +00:00
tsx:
specifier: ^4.21.0
version: 4.21.0
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
typebox:
specifier: 1.3.11
version: 1.3.11
2026-02-21 03:10:39 +00:00
typescript:
specifier: ^5.9.3
version: 5.9.3
vitest:
specifier: ^4.0.18
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
version: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@25.3.0)(jiti@2.7.0)(jsdom@28.1.0)(lightningcss@1.32.0)(tsx@4.21.0)(yaml@2.9.0)
2026-02-21 03:10:39 +00:00
src/cli:
dependencies:
'@inkjs/ui':
specifier: ^2.0.0
version: 2.0.0(ink@6.8.0(@types/react@19.2.14)(react@19.2.4))
2026-02-21 03:10:39 +00:00
'@mcpctl/db':
specifier: workspace:*
version: link:../db
'@mcpctl/shared':
specifier: workspace:*
version: link:../shared
chalk:
specifier: ^5.4.0
version: 5.6.2
commander:
specifier: ^13.0.0
version: 13.1.0
diff:
specifier: ^8.0.3
version: 8.0.3
ink:
specifier: ^6.8.0
version: 6.8.0(@types/react@19.2.14)(react@19.2.4)
2026-02-21 03:10:39 +00:00
inquirer:
specifier: ^12.0.0
version: 12.11.1(@types/node@25.3.0)
2026-02-21 03:10:39 +00:00
js-yaml:
specifier: ^4.1.0
version: 4.1.1
react:
specifier: ^19.2.4
version: 19.2.4
zod:
specifier: ^3.24.0
version: 3.25.76
devDependencies:
'@types/diff':
specifier: ^8.0.0
version: 8.0.0
'@types/js-yaml':
specifier: ^4.0.9
version: 4.0.9
'@types/node':
specifier: ^25.3.0
version: 25.3.0
'@types/react':
specifier: ^19.2.14
version: 19.2.14
2026-02-21 03:10:39 +00:00
src/db:
dependencies:
'@mcpctl/shared':
specifier: workspace:*
version: link:../shared
'@prisma/client':
specifier: ^6.0.0
version: 6.19.2(prisma@6.19.2(typescript@5.9.3))(typescript@5.9.3)
devDependencies:
prisma:
specifier: ^6.0.0
version: 6.19.2(typescript@5.9.3)
src/mcpd:
dependencies:
'@fastify/cors':
specifier: ^10.0.0
version: 10.1.0
'@fastify/helmet':
specifier: ^12.0.0
version: 12.0.1
'@fastify/rate-limit':
specifier: ^10.0.0
version: 10.3.0
feat(mcpd+deploy): serve web UI at /ui + smoke tests + docs (Stage 6) The closing stage. mcpd now hosts the Stage 5 SPA, the Docker image bundles the build artifact, a smoke test exercises the personality HTTP surface end-to-end, and the user-facing docs spell out the mental model. mcpd: - Add @fastify/static dep. - New routes/web-ui.ts: registers /ui/* against a static bundle. Looks for the bundle at $MCPD_WEB_ROOT, then /usr/share/mcpd/web (the Docker image path), then a dev-tree fallback. Logs and skips cleanly if missing — API-only deploys keep working. - SPA fallback: any /ui/<path> that doesn't match a file falls through to index.html so direct hits to react-router URLs work. - /ui/* falls through to `kind: skip` in mapUrlToPermission, so the static assets are served unauthenticated. Each API call from the SPA still carries the bearer token. Deploy: - Dockerfile.mcpd builds the @mcpctl/web bundle in the same builder stage and copies dist/ to /usr/share/mcpd/web in the runtime image. Smoke (personality.smoke.test.ts): - Live mcpd flow: create secret/llm/agent/personality, attach an agent-direct prompt, verify the binding listing, reject double- attach (409) + foreign-agent prompt (400), set defaultPersonality by name, detach + delete cleanup. Docs: - New docs/personalities.md: VLAN-on-ethernet model, system-block ordering table, three prompt scopes, CLI walkthrough, web UI walkthrough, full API surface, RBAC notes. - agents.md and chat.md cross-link. - README's Agents section gains a Personalities subsection. Test count after Stage 6: mcpd: 801/801 cli: 430/430 web: 7/7 db: 58/62 (4 pre-existing) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:48:43 +01:00
'@fastify/static':
specifier: ^8.0.0
version: 8.3.0
'@kubernetes/client-node':
specifier: ^1.4.0
version: 1.4.0
2026-02-21 03:10:39 +00:00
'@mcpctl/db':
specifier: workspace:*
version: link:../db
'@mcpctl/shared':
specifier: workspace:*
version: link:../shared
'@prisma/client':
specifier: ^6.0.0
version: 6.19.2(prisma@6.19.2(typescript@5.9.3))(typescript@5.9.3)
bcrypt:
specifier: ^5.1.1
version: 5.1.1
feat(mcpd): ResourceRevision + ResourceProposal services + Prompt revision integration Phase 2 of the Skills + Revisions + Proposals work. Stands up the generic revision/proposal layer and wires Prompt into it. Skills will plug into the same infrastructure in PR-3 with no further service changes required. This PR is intentionally additive: PromptRequest table and routes are unchanged. The /api/v1/proposals API runs side-by-side with the legacy /api/v1/promptrequests API. The PromptRequest cutover (rename + backfill + mcplocal rewire) is deferred to a later PR so this one stays reviewable. ## What's added ### Repositories (src/mcpd/src/repositories/) - resource-revision.repository.ts — append-only revision log keyed by (resourceType, resourceId). Soft FK; no relations declared. Supports history listing, semver lookup, and contentHash cross-resource search. - resource-proposal.repository.ts — generic propose queue. Status lifecycle pending → approved | rejected. Mirrors Prompt's `?? ''` workaround for nullable-FK compound lookups. ### Services (src/mcpd/src/services/) - resource-revision.service.ts — record() inserts a revision with a stable sha256 contentHash computed from canonicalised JSON (key-sorted at every level so reordered objects produce the same hash). Caller passes a pre-computed semver; service does NOT decide bump policy. - resource-proposal.service.ts — propose / approve / reject / list, with a per-resourceType handler registry. PromptService registers the 'prompt' handler at construction; the SkillService will register 'skill' in PR-3. approve() runs in a Prisma $transaction so the resource update + revision insert + proposal status flip are atomic. ### Pure utility (src/mcpd/src/utils/semver.ts) - bumpSemver(current, kind) for major / minor / patch - compareSemver(a, b) — numeric, not lex (10 > 9) - isValidSemver(s) - Invalid input falls back to '0.1.0' rather than throwing — keeps the audit-write path from blowing up the prompt update if a row's semver ever drifts out of MAJOR.MINOR.PATCH shape. ### Routes (src/mcpd/src/routes/) - revisions.ts — GET /api/v1/revisions?resourceType=&resourceId=, GET /api/v1/revisions/:id, GET /api/v1/revisions/:id/diff?against=<id|live> (unified-format diff via the `diff` package), and POST /api/v1/prompts/:id/restore-revision { revisionId, note? }. - proposals.ts — GET / POST /api/v1/proposals, GET /api/v1/proposals/:id, PUT for body updates, POST .../approve and POST .../reject, plus DELETE. ## What's changed - PromptService.create / update now record a ResourceRevision when the revision service is wired. Update auto-bumps patch on content change; authors can override via `--bump major|minor|patch` or `--semver X.Y.Z` on the CLI (forwarded into the PUT body). Best-effort: revision write failures are swallowed so the prompt save still succeeds (revision is audit, not source of truth). - PromptService.setProposalService registers a 'prompt' approval handler with the proposal service. Approval runs in a Prisma transaction: upsert prompt → record revision → update currentRevisionId → flip proposal status. semver bumps to 0.1.0 on first approval, patch thereafter. - New CLI flags on `mcpctl edit prompt`: --bump, --semver, --note. They're prompt-only (validated client-side); other resources reject them. - Aliases in shared.ts: `proposal`/`prop` → proposals, `revision`/`rev` → revisions. - diff dependency added to mcpd. ## Tests - src/mcpd/tests/utils/semver.test.ts — covers bump/compare/validate including numeric (not lex) semver compare and invalid-input fallback. - prompt-service.test.ts updated: makePrompt fixture now sets semver + agentId + currentRevisionId; updatePrompt assertion expects the auto-bumped patch in the same update call. - prompt-routes.test.ts updated symmetrically. ## RBAC `proposals` and `revisions` URL segments map to the existing `prompts` permission for now. PR-7 may split if a "reviewer" role becomes useful. ## Verification Full suite: 158 test files / 2127 tests green. `pnpm build` clean across all 6 workspace packages. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 00:38:35 +01:00
diff:
specifier: ^5.2.0
version: 5.2.2
dockerode:
specifier: ^4.0.9
version: 4.0.9
2026-02-21 03:10:39 +00:00
fastify:
specifier: ^5.0.0
version: 5.7.4
js-yaml:
specifier: ^4.1.0
version: 4.1.1
pino:
specifier: ^10.3.1
version: 10.3.1
2026-02-21 03:10:39 +00:00
zod:
specifier: ^3.24.0
version: 3.25.76
devDependencies:
'@types/bcrypt':
specifier: ^5.0.2
version: 5.0.2
feat(mcpd): ResourceRevision + ResourceProposal services + Prompt revision integration Phase 2 of the Skills + Revisions + Proposals work. Stands up the generic revision/proposal layer and wires Prompt into it. Skills will plug into the same infrastructure in PR-3 with no further service changes required. This PR is intentionally additive: PromptRequest table and routes are unchanged. The /api/v1/proposals API runs side-by-side with the legacy /api/v1/promptrequests API. The PromptRequest cutover (rename + backfill + mcplocal rewire) is deferred to a later PR so this one stays reviewable. ## What's added ### Repositories (src/mcpd/src/repositories/) - resource-revision.repository.ts — append-only revision log keyed by (resourceType, resourceId). Soft FK; no relations declared. Supports history listing, semver lookup, and contentHash cross-resource search. - resource-proposal.repository.ts — generic propose queue. Status lifecycle pending → approved | rejected. Mirrors Prompt's `?? ''` workaround for nullable-FK compound lookups. ### Services (src/mcpd/src/services/) - resource-revision.service.ts — record() inserts a revision with a stable sha256 contentHash computed from canonicalised JSON (key-sorted at every level so reordered objects produce the same hash). Caller passes a pre-computed semver; service does NOT decide bump policy. - resource-proposal.service.ts — propose / approve / reject / list, with a per-resourceType handler registry. PromptService registers the 'prompt' handler at construction; the SkillService will register 'skill' in PR-3. approve() runs in a Prisma $transaction so the resource update + revision insert + proposal status flip are atomic. ### Pure utility (src/mcpd/src/utils/semver.ts) - bumpSemver(current, kind) for major / minor / patch - compareSemver(a, b) — numeric, not lex (10 > 9) - isValidSemver(s) - Invalid input falls back to '0.1.0' rather than throwing — keeps the audit-write path from blowing up the prompt update if a row's semver ever drifts out of MAJOR.MINOR.PATCH shape. ### Routes (src/mcpd/src/routes/) - revisions.ts — GET /api/v1/revisions?resourceType=&resourceId=, GET /api/v1/revisions/:id, GET /api/v1/revisions/:id/diff?against=<id|live> (unified-format diff via the `diff` package), and POST /api/v1/prompts/:id/restore-revision { revisionId, note? }. - proposals.ts — GET / POST /api/v1/proposals, GET /api/v1/proposals/:id, PUT for body updates, POST .../approve and POST .../reject, plus DELETE. ## What's changed - PromptService.create / update now record a ResourceRevision when the revision service is wired. Update auto-bumps patch on content change; authors can override via `--bump major|minor|patch` or `--semver X.Y.Z` on the CLI (forwarded into the PUT body). Best-effort: revision write failures are swallowed so the prompt save still succeeds (revision is audit, not source of truth). - PromptService.setProposalService registers a 'prompt' approval handler with the proposal service. Approval runs in a Prisma transaction: upsert prompt → record revision → update currentRevisionId → flip proposal status. semver bumps to 0.1.0 on first approval, patch thereafter. - New CLI flags on `mcpctl edit prompt`: --bump, --semver, --note. They're prompt-only (validated client-side); other resources reject them. - Aliases in shared.ts: `proposal`/`prop` → proposals, `revision`/`rev` → revisions. - diff dependency added to mcpd. ## Tests - src/mcpd/tests/utils/semver.test.ts — covers bump/compare/validate including numeric (not lex) semver compare and invalid-input fallback. - prompt-service.test.ts updated: makePrompt fixture now sets semver + agentId + currentRevisionId; updatePrompt assertion expects the auto-bumped patch in the same update call. - prompt-routes.test.ts updated symmetrically. ## RBAC `proposals` and `revisions` URL segments map to the existing `prompts` permission for now. PR-7 may split if a "reviewer" role becomes useful. ## Verification Full suite: 158 test files / 2127 tests green. `pnpm build` clean across all 6 workspace packages. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 00:38:35 +01:00
'@types/diff':
specifier: ^5.2.3
version: 5.2.3
'@types/dockerode':
specifier: ^4.0.1
version: 4.0.1
'@types/js-yaml':
specifier: ^4.0.9
version: 4.0.9
'@types/node':
specifier: ^25.3.0
version: 25.3.0
2026-02-21 03:10:39 +00:00
src/mcplocal:
dependencies:
'@fastify/cors':
specifier: ^10.0.0
version: 10.1.0
'@mcpctl/shared':
specifier: workspace:*
version: link:../shared
'@modelcontextprotocol/sdk':
specifier: ^1.0.0
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
version: 1.26.0(zod@4.1.8)
fastify:
specifier: ^5.0.0
version: 5.7.4
yaml:
specifier: ^2.8.2
version: 2.8.2
devDependencies:
'@types/node':
specifier: ^25.3.0
version: 25.3.0
src/pulumi:
devDependencies:
'@pulumi/pulumi':
specifier: ^3.0.0
version: 3.253.0(typescript@5.9.3)
2026-02-21 03:10:39 +00:00
src/shared:
dependencies:
zod:
specifier: ^3.24.0
version: 3.25.76
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
src/web:
dependencies:
'@monaco-editor/react':
specifier: ^4.7.0
version: 4.7.0(monaco-editor@0.55.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
feat(web): bold redesign — Tailwind v4 + shadcn-style primitives + Skills/Proposals/Revisions UI Phase 6 of the Skills + Revisions + Proposals work. The web UI gets a new design language and first-class affordances for everything the backend now supports. ## Visual direction - Tailwind v4 with custom @theme block (oklch tokens). Dark-mode-only (internal tool — light mode doubles QA surface). - Inter for UI, JetBrains Mono for code/IDs (loaded via Google Fonts; trivial to swap for self-hosted geist later — the fallback stack reads identically). - Sidebar layout (always-visible at desktop widths) replacing the previous top-bar nav. Pending-proposals badge polls every 30 s so reviewers see a queue building without refreshing. - Lucide icons throughout. - Spacing and radii on Tailwind defaults. Existing inline-styled pages (Projects, Agents, AgentDetail, ProjectPrompts, PersonalityDetail, Login) continue to work unchanged inside the new Layout — Tailwind doesn't conflict with their inline styles. A follow-up can migrate them incrementally. ## What's added ### Build infra (src/web/) - package.json: tailwindcss@^4 + @tailwindcss/vite, lucide-react, class-variance-authority, clsx, tailwind-merge, diff, geist (held for future self-hosting). - vite.config.ts: registers the @tailwindcss/vite plugin. - src/index.css: Tailwind import + @theme tokens + @layer base. - src/main.tsx: imports index.css. - src/lib/utils.ts: shadcn-style cn() helper. ### shadcn-style primitives (src/components/ui/) Hand-written rather than generated via `npx shadcn` so the repo doesn't depend on a CLI tool that needs interactive runtime: - button.tsx — variants: primary / secondary / ghost / danger / link; sizes: sm / md / lg / icon. - card.tsx — Card + Header/Title/Description/Content/Footer subparts. - badge.tsx — variants: default / info / success / warning / danger / outline. - input.tsx — Input + Textarea + Label. - tabs.tsx — no-dep accessible Tabs (no Radix needed for our use). - separator.tsx — h/v separator with role=separator. ### Diff component (src/components/Diff.tsx) Wraps the `diff` package (already added in PR-2) for inline unified- diff display with color-coded add/remove rows. Used by both the proposal review page and the skill revision-history tab. ### New pages (src/pages/) - Dashboard.tsx — at-a-glance home. Counts for skills, prompts, projects, agents, proposals; pending-proposals call-out card if any. - Skills.tsx — list view, separated into Global vs Project/Agent- scoped sections. - SkillDetail.tsx — name + semver + description; tabs for SKILL.md / Files / Metadata / History. History tab shows revisions with click-to-diff against the live body. - Proposals.tsx — queue with Pending/Approved/Rejected tabs. Pending count is highlighted in amber. - ProposalDetail.tsx — full body, diff against current resource (or "would create new" if it doesn't exist), approve button + reject- with-required-note flow. ### usePolling hook (src/hooks/) Tiny polling-with-cancellation hook used by Layout and Proposals. ### Layout rewrite (src/components/Layout.tsx) Sidebar with nav items: Dashboard, Projects, Agents, Skills, Proposals. Lucide icons. Active-route highlighting via NavLink. Pending-proposals warning badge on the Proposals item. ### Routes (src/App.tsx) New routes: /dashboard, /skills, /skills/:name, /proposals, /proposals/:id. Default redirects to /dashboard. ### API types (src/api.ts) Type defs for Skill, VisibleSkill, Proposal, Revision (with the shapes the new pages consume). ## Tests Existing 7 web tests still pass (Login + api). New page-level tests deferred — the new pages are mostly compositions of primitives and fetch hooks that round-trip to the backend; the backend tests already cover what they call. PR-7 polish can add render-and-click tests if coverage drift surfaces. ## Verification - `pnpm --filter @mcpctl/web build` clean, no warnings. - `pnpm test:run` whole monorepo: 162 test files / 2157 tests green. - Visual smoke deferred — needs a running mcpd to populate the fixtures. Manual smoke tested locally is the next step. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:54:55 +01:00
class-variance-authority:
specifier: ^0.7.1
version: 0.7.1
clsx:
specifier: ^2.1.1
version: 2.1.1
diff:
specifier: ^5.2.0
version: 5.2.2
geist:
specifier: ^1.5.1
version: 1.7.0(next@16.2.5(@babel/core@7.29.0)(@opentelemetry/api@1.9.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))
feat(web): bold redesign — Tailwind v4 + shadcn-style primitives + Skills/Proposals/Revisions UI Phase 6 of the Skills + Revisions + Proposals work. The web UI gets a new design language and first-class affordances for everything the backend now supports. ## Visual direction - Tailwind v4 with custom @theme block (oklch tokens). Dark-mode-only (internal tool — light mode doubles QA surface). - Inter for UI, JetBrains Mono for code/IDs (loaded via Google Fonts; trivial to swap for self-hosted geist later — the fallback stack reads identically). - Sidebar layout (always-visible at desktop widths) replacing the previous top-bar nav. Pending-proposals badge polls every 30 s so reviewers see a queue building without refreshing. - Lucide icons throughout. - Spacing and radii on Tailwind defaults. Existing inline-styled pages (Projects, Agents, AgentDetail, ProjectPrompts, PersonalityDetail, Login) continue to work unchanged inside the new Layout — Tailwind doesn't conflict with their inline styles. A follow-up can migrate them incrementally. ## What's added ### Build infra (src/web/) - package.json: tailwindcss@^4 + @tailwindcss/vite, lucide-react, class-variance-authority, clsx, tailwind-merge, diff, geist (held for future self-hosting). - vite.config.ts: registers the @tailwindcss/vite plugin. - src/index.css: Tailwind import + @theme tokens + @layer base. - src/main.tsx: imports index.css. - src/lib/utils.ts: shadcn-style cn() helper. ### shadcn-style primitives (src/components/ui/) Hand-written rather than generated via `npx shadcn` so the repo doesn't depend on a CLI tool that needs interactive runtime: - button.tsx — variants: primary / secondary / ghost / danger / link; sizes: sm / md / lg / icon. - card.tsx — Card + Header/Title/Description/Content/Footer subparts. - badge.tsx — variants: default / info / success / warning / danger / outline. - input.tsx — Input + Textarea + Label. - tabs.tsx — no-dep accessible Tabs (no Radix needed for our use). - separator.tsx — h/v separator with role=separator. ### Diff component (src/components/Diff.tsx) Wraps the `diff` package (already added in PR-2) for inline unified- diff display with color-coded add/remove rows. Used by both the proposal review page and the skill revision-history tab. ### New pages (src/pages/) - Dashboard.tsx — at-a-glance home. Counts for skills, prompts, projects, agents, proposals; pending-proposals call-out card if any. - Skills.tsx — list view, separated into Global vs Project/Agent- scoped sections. - SkillDetail.tsx — name + semver + description; tabs for SKILL.md / Files / Metadata / History. History tab shows revisions with click-to-diff against the live body. - Proposals.tsx — queue with Pending/Approved/Rejected tabs. Pending count is highlighted in amber. - ProposalDetail.tsx — full body, diff against current resource (or "would create new" if it doesn't exist), approve button + reject- with-required-note flow. ### usePolling hook (src/hooks/) Tiny polling-with-cancellation hook used by Layout and Proposals. ### Layout rewrite (src/components/Layout.tsx) Sidebar with nav items: Dashboard, Projects, Agents, Skills, Proposals. Lucide icons. Active-route highlighting via NavLink. Pending-proposals warning badge on the Proposals item. ### Routes (src/App.tsx) New routes: /dashboard, /skills, /skills/:name, /proposals, /proposals/:id. Default redirects to /dashboard. ### API types (src/api.ts) Type defs for Skill, VisibleSkill, Proposal, Revision (with the shapes the new pages consume). ## Tests Existing 7 web tests still pass (Login + api). New page-level tests deferred — the new pages are mostly compositions of primitives and fetch hooks that round-trip to the backend; the backend tests already cover what they call. PR-7 polish can add render-and-click tests if coverage drift surfaces. ## Verification - `pnpm --filter @mcpctl/web build` clean, no warnings. - `pnpm test:run` whole monorepo: 162 test files / 2157 tests green. - Visual smoke deferred — needs a running mcpd to populate the fixtures. Manual smoke tested locally is the next step. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:54:55 +01:00
lucide-react:
specifier: ^0.487.0
version: 0.487.0(react@19.2.5)
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
react:
specifier: ^19.2.5
version: 19.2.5
react-dom:
specifier: ^19.2.5
version: 19.2.5(react@19.2.5)
react-router-dom:
specifier: ^7.7.0
version: 7.14.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
feat(web): bold redesign — Tailwind v4 + shadcn-style primitives + Skills/Proposals/Revisions UI Phase 6 of the Skills + Revisions + Proposals work. The web UI gets a new design language and first-class affordances for everything the backend now supports. ## Visual direction - Tailwind v4 with custom @theme block (oklch tokens). Dark-mode-only (internal tool — light mode doubles QA surface). - Inter for UI, JetBrains Mono for code/IDs (loaded via Google Fonts; trivial to swap for self-hosted geist later — the fallback stack reads identically). - Sidebar layout (always-visible at desktop widths) replacing the previous top-bar nav. Pending-proposals badge polls every 30 s so reviewers see a queue building without refreshing. - Lucide icons throughout. - Spacing and radii on Tailwind defaults. Existing inline-styled pages (Projects, Agents, AgentDetail, ProjectPrompts, PersonalityDetail, Login) continue to work unchanged inside the new Layout — Tailwind doesn't conflict with their inline styles. A follow-up can migrate them incrementally. ## What's added ### Build infra (src/web/) - package.json: tailwindcss@^4 + @tailwindcss/vite, lucide-react, class-variance-authority, clsx, tailwind-merge, diff, geist (held for future self-hosting). - vite.config.ts: registers the @tailwindcss/vite plugin. - src/index.css: Tailwind import + @theme tokens + @layer base. - src/main.tsx: imports index.css. - src/lib/utils.ts: shadcn-style cn() helper. ### shadcn-style primitives (src/components/ui/) Hand-written rather than generated via `npx shadcn` so the repo doesn't depend on a CLI tool that needs interactive runtime: - button.tsx — variants: primary / secondary / ghost / danger / link; sizes: sm / md / lg / icon. - card.tsx — Card + Header/Title/Description/Content/Footer subparts. - badge.tsx — variants: default / info / success / warning / danger / outline. - input.tsx — Input + Textarea + Label. - tabs.tsx — no-dep accessible Tabs (no Radix needed for our use). - separator.tsx — h/v separator with role=separator. ### Diff component (src/components/Diff.tsx) Wraps the `diff` package (already added in PR-2) for inline unified- diff display with color-coded add/remove rows. Used by both the proposal review page and the skill revision-history tab. ### New pages (src/pages/) - Dashboard.tsx — at-a-glance home. Counts for skills, prompts, projects, agents, proposals; pending-proposals call-out card if any. - Skills.tsx — list view, separated into Global vs Project/Agent- scoped sections. - SkillDetail.tsx — name + semver + description; tabs for SKILL.md / Files / Metadata / History. History tab shows revisions with click-to-diff against the live body. - Proposals.tsx — queue with Pending/Approved/Rejected tabs. Pending count is highlighted in amber. - ProposalDetail.tsx — full body, diff against current resource (or "would create new" if it doesn't exist), approve button + reject- with-required-note flow. ### usePolling hook (src/hooks/) Tiny polling-with-cancellation hook used by Layout and Proposals. ### Layout rewrite (src/components/Layout.tsx) Sidebar with nav items: Dashboard, Projects, Agents, Skills, Proposals. Lucide icons. Active-route highlighting via NavLink. Pending-proposals warning badge on the Proposals item. ### Routes (src/App.tsx) New routes: /dashboard, /skills, /skills/:name, /proposals, /proposals/:id. Default redirects to /dashboard. ### API types (src/api.ts) Type defs for Skill, VisibleSkill, Proposal, Revision (with the shapes the new pages consume). ## Tests Existing 7 web tests still pass (Login + api). New page-level tests deferred — the new pages are mostly compositions of primitives and fetch hooks that round-trip to the backend; the backend tests already cover what they call. PR-7 polish can add render-and-click tests if coverage drift surfaces. ## Verification - `pnpm --filter @mcpctl/web build` clean, no warnings. - `pnpm test:run` whole monorepo: 162 test files / 2157 tests green. - Visual smoke deferred — needs a running mcpd to populate the fixtures. Manual smoke tested locally is the next step. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:54:55 +01:00
tailwind-merge:
specifier: ^3.3.1
version: 3.5.0
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
devDependencies:
feat(web): bold redesign — Tailwind v4 + shadcn-style primitives + Skills/Proposals/Revisions UI Phase 6 of the Skills + Revisions + Proposals work. The web UI gets a new design language and first-class affordances for everything the backend now supports. ## Visual direction - Tailwind v4 with custom @theme block (oklch tokens). Dark-mode-only (internal tool — light mode doubles QA surface). - Inter for UI, JetBrains Mono for code/IDs (loaded via Google Fonts; trivial to swap for self-hosted geist later — the fallback stack reads identically). - Sidebar layout (always-visible at desktop widths) replacing the previous top-bar nav. Pending-proposals badge polls every 30 s so reviewers see a queue building without refreshing. - Lucide icons throughout. - Spacing and radii on Tailwind defaults. Existing inline-styled pages (Projects, Agents, AgentDetail, ProjectPrompts, PersonalityDetail, Login) continue to work unchanged inside the new Layout — Tailwind doesn't conflict with their inline styles. A follow-up can migrate them incrementally. ## What's added ### Build infra (src/web/) - package.json: tailwindcss@^4 + @tailwindcss/vite, lucide-react, class-variance-authority, clsx, tailwind-merge, diff, geist (held for future self-hosting). - vite.config.ts: registers the @tailwindcss/vite plugin. - src/index.css: Tailwind import + @theme tokens + @layer base. - src/main.tsx: imports index.css. - src/lib/utils.ts: shadcn-style cn() helper. ### shadcn-style primitives (src/components/ui/) Hand-written rather than generated via `npx shadcn` so the repo doesn't depend on a CLI tool that needs interactive runtime: - button.tsx — variants: primary / secondary / ghost / danger / link; sizes: sm / md / lg / icon. - card.tsx — Card + Header/Title/Description/Content/Footer subparts. - badge.tsx — variants: default / info / success / warning / danger / outline. - input.tsx — Input + Textarea + Label. - tabs.tsx — no-dep accessible Tabs (no Radix needed for our use). - separator.tsx — h/v separator with role=separator. ### Diff component (src/components/Diff.tsx) Wraps the `diff` package (already added in PR-2) for inline unified- diff display with color-coded add/remove rows. Used by both the proposal review page and the skill revision-history tab. ### New pages (src/pages/) - Dashboard.tsx — at-a-glance home. Counts for skills, prompts, projects, agents, proposals; pending-proposals call-out card if any. - Skills.tsx — list view, separated into Global vs Project/Agent- scoped sections. - SkillDetail.tsx — name + semver + description; tabs for SKILL.md / Files / Metadata / History. History tab shows revisions with click-to-diff against the live body. - Proposals.tsx — queue with Pending/Approved/Rejected tabs. Pending count is highlighted in amber. - ProposalDetail.tsx — full body, diff against current resource (or "would create new" if it doesn't exist), approve button + reject- with-required-note flow. ### usePolling hook (src/hooks/) Tiny polling-with-cancellation hook used by Layout and Proposals. ### Layout rewrite (src/components/Layout.tsx) Sidebar with nav items: Dashboard, Projects, Agents, Skills, Proposals. Lucide icons. Active-route highlighting via NavLink. Pending-proposals warning badge on the Proposals item. ### Routes (src/App.tsx) New routes: /dashboard, /skills, /skills/:name, /proposals, /proposals/:id. Default redirects to /dashboard. ### API types (src/api.ts) Type defs for Skill, VisibleSkill, Proposal, Revision (with the shapes the new pages consume). ## Tests Existing 7 web tests still pass (Login + api). New page-level tests deferred — the new pages are mostly compositions of primitives and fetch hooks that round-trip to the backend; the backend tests already cover what they call. PR-7 polish can add render-and-click tests if coverage drift surfaces. ## Verification - `pnpm --filter @mcpctl/web build` clean, no warnings. - `pnpm test:run` whole monorepo: 162 test files / 2157 tests green. - Visual smoke deferred — needs a running mcpd to populate the fixtures. Manual smoke tested locally is the next step. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:54:55 +01:00
'@tailwindcss/vite':
specifier: ^4.1.16
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
version: 4.2.4(vite@7.3.1(@types/node@25.3.0)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.21.0)(yaml@2.9.0))
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
'@testing-library/jest-dom':
specifier: ^6.7.0
version: 6.9.1
'@testing-library/react':
specifier: ^16.3.0
version: 16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
feat(web): bold redesign — Tailwind v4 + shadcn-style primitives + Skills/Proposals/Revisions UI Phase 6 of the Skills + Revisions + Proposals work. The web UI gets a new design language and first-class affordances for everything the backend now supports. ## Visual direction - Tailwind v4 with custom @theme block (oklch tokens). Dark-mode-only (internal tool — light mode doubles QA surface). - Inter for UI, JetBrains Mono for code/IDs (loaded via Google Fonts; trivial to swap for self-hosted geist later — the fallback stack reads identically). - Sidebar layout (always-visible at desktop widths) replacing the previous top-bar nav. Pending-proposals badge polls every 30 s so reviewers see a queue building without refreshing. - Lucide icons throughout. - Spacing and radii on Tailwind defaults. Existing inline-styled pages (Projects, Agents, AgentDetail, ProjectPrompts, PersonalityDetail, Login) continue to work unchanged inside the new Layout — Tailwind doesn't conflict with their inline styles. A follow-up can migrate them incrementally. ## What's added ### Build infra (src/web/) - package.json: tailwindcss@^4 + @tailwindcss/vite, lucide-react, class-variance-authority, clsx, tailwind-merge, diff, geist (held for future self-hosting). - vite.config.ts: registers the @tailwindcss/vite plugin. - src/index.css: Tailwind import + @theme tokens + @layer base. - src/main.tsx: imports index.css. - src/lib/utils.ts: shadcn-style cn() helper. ### shadcn-style primitives (src/components/ui/) Hand-written rather than generated via `npx shadcn` so the repo doesn't depend on a CLI tool that needs interactive runtime: - button.tsx — variants: primary / secondary / ghost / danger / link; sizes: sm / md / lg / icon. - card.tsx — Card + Header/Title/Description/Content/Footer subparts. - badge.tsx — variants: default / info / success / warning / danger / outline. - input.tsx — Input + Textarea + Label. - tabs.tsx — no-dep accessible Tabs (no Radix needed for our use). - separator.tsx — h/v separator with role=separator. ### Diff component (src/components/Diff.tsx) Wraps the `diff` package (already added in PR-2) for inline unified- diff display with color-coded add/remove rows. Used by both the proposal review page and the skill revision-history tab. ### New pages (src/pages/) - Dashboard.tsx — at-a-glance home. Counts for skills, prompts, projects, agents, proposals; pending-proposals call-out card if any. - Skills.tsx — list view, separated into Global vs Project/Agent- scoped sections. - SkillDetail.tsx — name + semver + description; tabs for SKILL.md / Files / Metadata / History. History tab shows revisions with click-to-diff against the live body. - Proposals.tsx — queue with Pending/Approved/Rejected tabs. Pending count is highlighted in amber. - ProposalDetail.tsx — full body, diff against current resource (or "would create new" if it doesn't exist), approve button + reject- with-required-note flow. ### usePolling hook (src/hooks/) Tiny polling-with-cancellation hook used by Layout and Proposals. ### Layout rewrite (src/components/Layout.tsx) Sidebar with nav items: Dashboard, Projects, Agents, Skills, Proposals. Lucide icons. Active-route highlighting via NavLink. Pending-proposals warning badge on the Proposals item. ### Routes (src/App.tsx) New routes: /dashboard, /skills, /skills/:name, /proposals, /proposals/:id. Default redirects to /dashboard. ### API types (src/api.ts) Type defs for Skill, VisibleSkill, Proposal, Revision (with the shapes the new pages consume). ## Tests Existing 7 web tests still pass (Login + api). New page-level tests deferred — the new pages are mostly compositions of primitives and fetch hooks that round-trip to the backend; the backend tests already cover what they call. PR-7 polish can add render-and-click tests if coverage drift surfaces. ## Verification - `pnpm --filter @mcpctl/web build` clean, no warnings. - `pnpm test:run` whole monorepo: 162 test files / 2157 tests green. - Visual smoke deferred — needs a running mcpd to populate the fixtures. Manual smoke tested locally is the next step. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:54:55 +01:00
'@types/diff':
specifier: ^5.2.3
version: 5.2.3
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
'@types/react':
specifier: ^19.2.14
version: 19.2.14
'@types/react-dom':
specifier: ^19.2.0
version: 19.2.3(@types/react@19.2.14)
'@vitejs/plugin-react':
specifier: ^5.1.0
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
version: 5.2.0(vite@7.3.1(@types/node@25.3.0)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.21.0)(yaml@2.9.0))
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
jsdom:
specifier: ^28.0.0
version: 28.1.0
feat(web): bold redesign — Tailwind v4 + shadcn-style primitives + Skills/Proposals/Revisions UI Phase 6 of the Skills + Revisions + Proposals work. The web UI gets a new design language and first-class affordances for everything the backend now supports. ## Visual direction - Tailwind v4 with custom @theme block (oklch tokens). Dark-mode-only (internal tool — light mode doubles QA surface). - Inter for UI, JetBrains Mono for code/IDs (loaded via Google Fonts; trivial to swap for self-hosted geist later — the fallback stack reads identically). - Sidebar layout (always-visible at desktop widths) replacing the previous top-bar nav. Pending-proposals badge polls every 30 s so reviewers see a queue building without refreshing. - Lucide icons throughout. - Spacing and radii on Tailwind defaults. Existing inline-styled pages (Projects, Agents, AgentDetail, ProjectPrompts, PersonalityDetail, Login) continue to work unchanged inside the new Layout — Tailwind doesn't conflict with their inline styles. A follow-up can migrate them incrementally. ## What's added ### Build infra (src/web/) - package.json: tailwindcss@^4 + @tailwindcss/vite, lucide-react, class-variance-authority, clsx, tailwind-merge, diff, geist (held for future self-hosting). - vite.config.ts: registers the @tailwindcss/vite plugin. - src/index.css: Tailwind import + @theme tokens + @layer base. - src/main.tsx: imports index.css. - src/lib/utils.ts: shadcn-style cn() helper. ### shadcn-style primitives (src/components/ui/) Hand-written rather than generated via `npx shadcn` so the repo doesn't depend on a CLI tool that needs interactive runtime: - button.tsx — variants: primary / secondary / ghost / danger / link; sizes: sm / md / lg / icon. - card.tsx — Card + Header/Title/Description/Content/Footer subparts. - badge.tsx — variants: default / info / success / warning / danger / outline. - input.tsx — Input + Textarea + Label. - tabs.tsx — no-dep accessible Tabs (no Radix needed for our use). - separator.tsx — h/v separator with role=separator. ### Diff component (src/components/Diff.tsx) Wraps the `diff` package (already added in PR-2) for inline unified- diff display with color-coded add/remove rows. Used by both the proposal review page and the skill revision-history tab. ### New pages (src/pages/) - Dashboard.tsx — at-a-glance home. Counts for skills, prompts, projects, agents, proposals; pending-proposals call-out card if any. - Skills.tsx — list view, separated into Global vs Project/Agent- scoped sections. - SkillDetail.tsx — name + semver + description; tabs for SKILL.md / Files / Metadata / History. History tab shows revisions with click-to-diff against the live body. - Proposals.tsx — queue with Pending/Approved/Rejected tabs. Pending count is highlighted in amber. - ProposalDetail.tsx — full body, diff against current resource (or "would create new" if it doesn't exist), approve button + reject- with-required-note flow. ### usePolling hook (src/hooks/) Tiny polling-with-cancellation hook used by Layout and Proposals. ### Layout rewrite (src/components/Layout.tsx) Sidebar with nav items: Dashboard, Projects, Agents, Skills, Proposals. Lucide icons. Active-route highlighting via NavLink. Pending-proposals warning badge on the Proposals item. ### Routes (src/App.tsx) New routes: /dashboard, /skills, /skills/:name, /proposals, /proposals/:id. Default redirects to /dashboard. ### API types (src/api.ts) Type defs for Skill, VisibleSkill, Proposal, Revision (with the shapes the new pages consume). ## Tests Existing 7 web tests still pass (Login + api). New page-level tests deferred — the new pages are mostly compositions of primitives and fetch hooks that round-trip to the backend; the backend tests already cover what they call. PR-7 polish can add render-and-click tests if coverage drift surfaces. ## Verification - `pnpm --filter @mcpctl/web build` clean, no warnings. - `pnpm test:run` whole monorepo: 162 test files / 2157 tests green. - Visual smoke deferred — needs a running mcpd to populate the fixtures. Manual smoke tested locally is the next step. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:54:55 +01:00
tailwindcss:
specifier: ^4.1.16
version: 4.2.4
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
vite:
specifier: ^7.2.0
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
version: 7.3.1(@types/node@25.3.0)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.21.0)(yaml@2.9.0)
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
2026-02-21 03:10:39 +00:00
packages:
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
'@acemir/cssom@0.9.31':
resolution: {integrity: sha512-ZnR3GSaH+/vJ0YlHau21FjfLYjMpYVIzTD8M8vIEQvIGxeOXyXdzCI140rrCY862p/C/BbzWsjc1dgnM9mkoTA==}
'@adobe/css-tools@4.4.4':
resolution: {integrity: sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
'@ai-sdk/provider@3.0.8':
resolution: {integrity: sha512-oGMAgGoQdBXbZqNG0Ze56CHjDZ1IDYOwGYxYjO5KLSlz5HiNQ9udIXsPZ61VWaHGZ5XW/jyjmr6t2xz2jGVwbQ==}
engines: {node: '>=18'}
'@alcalzone/ansi-tokenize@0.2.5':
resolution: {integrity: sha512-3NX/MpTdroi0aKz134A6RC2Gb2iXVECN4QaAXnvCIxxIm3C3AVB1mkUe8NaaiyvOpDfsrqWhYtj+Q6a62RrTsw==}
engines: {node: '>=18'}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
'@ampproject/remapping@2.3.0':
resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==}
engines: {node: '>=6.0.0'}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
'@anthropic-ai/sdk@0.91.1':
resolution: {integrity: sha512-LAmu761tSN9r66ixvmciswUj/ZC+1Q4iAfpedTfSVLeswRwnY3n2Nb6Tsk+cLPP28aLOPWeMgIuTuCcMC6W/iw==}
hasBin: true
peerDependencies:
zod: ^3.25.0 || ^4.0.0
peerDependenciesMeta:
zod:
optional: true
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
'@asamuzakjp/css-color@5.1.11':
resolution: {integrity: sha512-KVw6qIiCTUQhByfTd78h2yD1/00waTmm9uy/R7Ck/ctUyAPj+AEDLkQIdJW0T8+qGgj3j5bpNKK7Q3G+LedJWg==}
engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0}
'@asamuzakjp/dom-selector@6.8.1':
resolution: {integrity: sha512-MvRz1nCqW0fsy8Qz4dnLIvhOlMzqDVBabZx6lH+YywFDdjXhMY37SmpV1XFX3JzG5GWHn63j6HX6QPr3lZXHvQ==}
'@asamuzakjp/generational-cache@1.0.1':
resolution: {integrity: sha512-wajfB8KqzMCN2KGNFdLkReeHncd0AslUSrvHVvvYWuU8ghncRJoA50kT3zP9MVL0+9g4/67H+cdvBskj9THPzg==}
engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0}
'@asamuzakjp/nwsapi@2.3.9':
resolution: {integrity: sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
'@aws-crypto/sha256-browser@5.2.0':
resolution: {integrity: sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==}
'@aws-crypto/sha256-js@5.2.0':
resolution: {integrity: sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==}
engines: {node: '>=16.0.0'}
'@aws-crypto/supports-web-crypto@5.2.0':
resolution: {integrity: sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==}
'@aws-crypto/util@5.2.0':
resolution: {integrity: sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==}
'@aws-sdk/client-bedrock-runtime@3.1048.0':
resolution: {integrity: sha512-u+NT61JZEkRFtpL0CAw1N1dwxnaLgwVXQl/zjJxTGgLyS/jTIdg2SdoEoCTHxgDyCnqa1HEi9QOoE9/pYRNpOQ==}
engines: {node: '>=20.0.0'}
'@aws-sdk/core@3.977.6':
resolution: {integrity: sha512-QiaJV4/zDrB4ZY2mfeSXSzSTc36W16sZXcGz+SPFk0CJ26gziO0cS+4LjJUMAbdeeBOvS0k0Aq1cZpfGdUXxSw==}
engines: {node: '>=20.0.0'}
'@aws-sdk/credential-provider-env@3.972.67':
resolution: {integrity: sha512-rcIpk5kxUqDaaNa6Xk23pQ6ViY7jlqzmfFWCahQcBT97ddXaXYYwzCen9Tz1Jvo6aJft6wDl5bN44/Jw5B4oLA==}
engines: {node: '>=20.0.0'}
'@aws-sdk/credential-provider-http@3.972.69':
resolution: {integrity: sha512-nggwJtZ4eeNsUw5IeWBMXsi1ryct5idi0K+/SCRF3kybLubOMaNTb3XCihXpWMiVpyzyPeIrl0zTkzhBH9porA==}
engines: {node: '>=20.0.0'}
'@aws-sdk/credential-provider-ini@3.973.12':
resolution: {integrity: sha512-pNEf/OeyN5X3VmLKlgSO6TqaWmW10CvI3TfwL1XhsuhYjSLT2VDaxFnCPHnOeQXSaFisMX4jNhpETriqN8DOmg==}
engines: {node: '>=20.0.0'}
'@aws-sdk/credential-provider-login@3.972.74':
resolution: {integrity: sha512-0AQfDcf99TNmqVKv0owHrw/TQs6i4ZE5t9qmz6NvO53bE/sA/tpXhXL9AAcEP1qHc6Zzjd1UMb69+/9zdhvY3g==}
engines: {node: '>=20.0.0'}
'@aws-sdk/credential-provider-node@3.972.78':
resolution: {integrity: sha512-OgPAnfvbGAMWac6yvxJ1ihslrvDpPVwR68D2csospdNCCyPvHk9JLzYKwz48SNiS1T2znDwHauywRKRFfpyYng==}
engines: {node: '>=20.0.0'}
'@aws-sdk/credential-provider-process@3.972.67':
resolution: {integrity: sha512-IlUEejorGTWKb4/Dm7K5Yw4QxUmXLThLhrvBmzVBqZFTbW72cv9LTcITmo1dsnYriALE4h68mOq4LB99x6sQ7Q==}
engines: {node: '>=20.0.0'}
'@aws-sdk/credential-provider-sso@3.973.11':
resolution: {integrity: sha512-gAQBkBZxUB84d71+pPcI9L+jh2ujhuAVxc/4FgGiWFDjkPBlMKxzd5XDtkSXTFX8Ro7ansnT88+XadasxMeCRw==}
engines: {node: '>=20.0.0'}
'@aws-sdk/credential-provider-web-identity@3.972.73':
resolution: {integrity: sha512-SnlEmQa6SjOgs6iOPLUQl1Eyq4AKiAdPQlkOhFhqNfDtDCwibMGvL6QlkSmf3o6vAUSImzdPCxowT5dfQUZP1A==}
engines: {node: '>=20.0.0'}
'@aws-sdk/eventstream-handler-node@3.972.31':
resolution: {integrity: sha512-/BRzvkp46mF6eXBL/l9WKPQQfifLlUPaWli6n9/T/WDLUg8he7TCyuNFnk6RvHP5j5W/kMj5Gxw7W778LJaXDA==}
engines: {node: '>=20.0.0'}
'@aws-sdk/middleware-eventstream@3.972.26':
resolution: {integrity: sha512-2eIvouTZoxPu5ClHY6ij13De1yhY8Rmllt0dlGeBNXX3wmR7fU1pvMCGb50fKm1GxcuntWK0t1T0cMjTyDoUQA==}
engines: {node: '>=20.0.0'}
'@aws-sdk/middleware-websocket@3.972.49':
resolution: {integrity: sha512-wGYJvu1/stdWuzGcNyh44u8aY7ArU8XFrMesBlzIYn70HWVCRBNEngQexDuPIMu0NEgsKGKmTc0uvnS/bF7KWw==}
engines: {node: '>= 14.0.0'}
'@aws-sdk/nested-clients@3.997.41':
resolution: {integrity: sha512-RDHqPGQWlF6tatA/Tp3rg6oIwtgN9IVderxE+9av2Y93Dfyu+mO1hZ5Bu2jpfZg2rwdNbsssnwM+sLafIczMlQ==}
engines: {node: '>=20.0.0'}
'@aws-sdk/signature-v4-multi-region@3.996.43':
resolution: {integrity: sha512-lKekx8bLBXSv4O+cslk9Zfnw2XKSkWBs3uWL5QGhH2ZAQfNS7FE0vcSSN2vD/AhxX54ZTywWxR4STThoeOXlBA==}
engines: {node: '>=20.0.0'}
'@aws-sdk/token-providers@3.1048.0':
resolution: {integrity: sha512-k0y/GcuesuSfWyUM0WamrGyeZmltRYaPbHO82UDA6mZ/doB+FOHKutikPAtSXMn/hDz970cF+iRuuiYO9VEbAA==}
engines: {node: '>=20.0.0'}
'@aws-sdk/token-providers@3.1103.0':
resolution: {integrity: sha512-N4wy26MNn31ItGVHYHPrEuCIFY4MBBjC+C5v1lJKqIUSA7OZBdhleCY53zCCrXn27hsk7YNOaTuhQu807S4AfQ==}
engines: {node: '>=20.0.0'}
'@aws-sdk/types@3.974.2':
resolution: {integrity: sha512-3W6IUtSxFbH6X7Wb7DzGCV5QiFQsd0g8bOfntpmDxQlzBoKWUMBu/JPQR0DwkE+Hpnxd6db1tXbOwdeHddG6cA==}
engines: {node: '>=20.0.0'}
'@aws-sdk/util-locate-window@3.965.8':
resolution: {integrity: sha512-uUbMs1cBZPafD0ohUj6EwNf0fPZ534NvBxHox4hjX+0Rxq5paSYUem7+hi833pYrzrcnBATKIYpR02MDXT5M9g==}
engines: {node: '>=20.0.0'}
'@aws-sdk/xml-builder@3.972.37':
resolution: {integrity: sha512-zKq4HQum8JwDyEuyfuI4bbiAcU0KxP6qy+9PR/IsR92IyE/DaBAikzAS50tjxip4bqIIANpCcG+Yyj6CVhXupg==}
engines: {node: '>=20.0.0'}
'@aws/lambda-invoke-store@0.3.0':
resolution: {integrity: sha512-sl4Bm6yiMNYrZKkqqDFWN0UfnWhlS8ivKxrYl+6t0gCLrqr8y3B2IqZZbFRkfaVVp7C/baApyh71P+LeE1A2sQ==}
engines: {node: '>=18.0.0'}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
'@babel/code-frame@7.29.0':
resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==}
engines: {node: '>=6.9.0'}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
'@babel/code-frame@7.29.7':
resolution: {integrity: sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==}
engines: {node: '>=6.9.0'}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
'@babel/compat-data@7.29.0':
resolution: {integrity: sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==}
engines: {node: '>=6.9.0'}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
'@babel/core@7.28.0':
resolution: {integrity: sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ==}
engines: {node: '>=6.9.0'}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
'@babel/core@7.29.0':
resolution: {integrity: sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==}
engines: {node: '>=6.9.0'}
'@babel/generator@7.29.1':
resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==}
engines: {node: '>=6.9.0'}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
'@babel/generator@7.29.8':
resolution: {integrity: sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg==}
engines: {node: '>=6.9.0'}
'@babel/helper-annotate-as-pure@7.29.7':
resolution: {integrity: sha512-OoK6239jHPuSQOoS0kfTVKn0b/rVTk0seKq4Gd2UMLtmOVLjDC0ki3e+c90Trqv2gMfvJFqkiljrr568+qddiw==}
engines: {node: '>=6.9.0'}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
'@babel/helper-compilation-targets@7.28.6':
resolution: {integrity: sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==}
engines: {node: '>=6.9.0'}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
'@babel/helper-create-class-features-plugin@7.29.7':
resolution: {integrity: sha512-IY3ZD9Tmooqr3TUhc3DUWxiuo8xx1DWLhd5M7hQ+ZWJamqM2BbalrBJb2MisSLoYorOj75U03qULCxQTY9r3hg==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
'@babel/helper-globals@7.28.0':
resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==}
engines: {node: '>=6.9.0'}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
'@babel/helper-globals@7.29.7':
resolution: {integrity: sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==}
engines: {node: '>=6.9.0'}
'@babel/helper-member-expression-to-functions@7.29.7':
resolution: {integrity: sha512-j+7JYmk1JYDtACIGj0QJqqWZjoUpMoEikQGADMaHgCMCSDqd2+P32rfcibUNrGOMWrlzK1WJBdxrB3JJQZwWtg==}
engines: {node: '>=6.9.0'}
'@babel/helper-module-imports@7.18.6':
resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==}
engines: {node: '>=6.9.0'}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
'@babel/helper-module-imports@7.28.6':
resolution: {integrity: sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==}
engines: {node: '>=6.9.0'}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
'@babel/helper-module-imports@7.29.7':
resolution: {integrity: sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==}
engines: {node: '>=6.9.0'}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
'@babel/helper-module-transforms@7.28.6':
resolution: {integrity: sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
'@babel/helper-module-transforms@7.29.7':
resolution: {integrity: sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0
'@babel/helper-optimise-call-expression@7.29.7':
resolution: {integrity: sha512-+kmGVjcT9RGYzoDwdwEqEvGgKe3BYq+O1iGzjFubaNgZHwYHP6lsF2Yghf4kEuv9BV7tYDZ913aBW9am6YKong==}
engines: {node: '>=6.9.0'}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
'@babel/helper-plugin-utils@7.28.6':
resolution: {integrity: sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==}
engines: {node: '>=6.9.0'}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
'@babel/helper-plugin-utils@7.29.7':
resolution: {integrity: sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==}
engines: {node: '>=6.9.0'}
'@babel/helper-replace-supers@7.29.7':
resolution: {integrity: sha512-atfGXWSeCiF4DnKZIfmJfQRkSw9b9gNNXR1kqKjbhG4pGYCOnkp8OcTB8E3NXjBu8NpheSnOeNKz8KT7UNFTmQ==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0
'@babel/helper-skip-transparent-expression-wrappers@7.29.7':
resolution: {integrity: sha512-brcMGQaVzIeUb+6/bs1Av0f8YuNNjKY2JyvfRCsFuFsdKccEQ5Ges2y74D74NZ1Rz8lKJ9ksJkfqwQFJ/iNEyQ==}
engines: {node: '>=6.9.0'}
2026-02-21 03:10:39 +00:00
'@babel/helper-string-parser@7.27.1':
resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==}
engines: {node: '>=6.9.0'}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
'@babel/helper-string-parser@7.29.7':
resolution: {integrity: sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==}
engines: {node: '>=6.9.0'}
2026-02-21 03:10:39 +00:00
'@babel/helper-validator-identifier@7.28.5':
resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==}
engines: {node: '>=6.9.0'}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
'@babel/helper-validator-identifier@7.29.7':
resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==}
engines: {node: '>=6.9.0'}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
'@babel/helper-validator-option@7.27.1':
resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==}
engines: {node: '>=6.9.0'}
'@babel/helpers@7.29.2':
resolution: {integrity: sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==}
engines: {node: '>=6.9.0'}
2026-02-21 03:10:39 +00:00
'@babel/parser@7.29.0':
resolution: {integrity: sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==}
engines: {node: '>=6.0.0'}
hasBin: true
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
'@babel/parser@7.29.8':
resolution: {integrity: sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==}
engines: {node: '>=6.0.0'}
hasBin: true
'@babel/plugin-syntax-jsx@7.29.7':
resolution: {integrity: sha512-TSu8+mHCoEaaCDEZ0I3+6mvTBYR4PCxQwf2z9/r5Tbztv6NaLR3B9thGTTxX2WGuGHJqRiAbKPeGTJ5XWXVg6A==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
'@babel/plugin-syntax-typescript@7.29.7':
resolution: {integrity: sha512-ngr+82Sh0xMz25TPCZi+nC2iTzjfCdWS2ONXTp/PtSCHCgaCNBpdMqgvJ2ccdLlClVZ7sisIgB914j/JFe+RZA==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
'@babel/plugin-transform-modules-commonjs@7.29.7':
resolution: {integrity: sha512-j0vCldybPC5b5dwCQOJ21uKtHzt7hxLygJTg9eF1ScfaikEDNfzn94XoW5Fi+seBR0nCyL23xaBFFkq7dTM8XQ==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
'@babel/plugin-transform-react-jsx-self@7.27.1':
resolution: {integrity: sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
'@babel/plugin-transform-react-jsx-source@7.27.1':
resolution: {integrity: sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
'@babel/plugin-transform-typescript@7.29.7':
resolution: {integrity: sha512-jK52h8LaLc7JarhQV2ofeFMts4H7vnOXnqZNA6fYglBTZewRBE51KWt3BUltW1P+KoPsYkHoJeXePuz4zo2LMw==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
'@babel/preset-typescript@7.27.1':
resolution: {integrity: sha512-l7WfQfX0WK4M0v2RudjuQK4u99BS6yLHYEmdtVPP7lKV013zr9DygFuWNlnbvQ9LR+LS0Egz/XAvGx5U9MX0fQ==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
'@babel/runtime@7.29.2':
resolution: {integrity: sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==}
engines: {node: '>=6.9.0'}
'@babel/template@7.28.6':
resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==}
engines: {node: '>=6.9.0'}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
'@babel/template@7.29.7':
resolution: {integrity: sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==}
engines: {node: '>=6.9.0'}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
'@babel/traverse@7.29.0':
resolution: {integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==}
engines: {node: '>=6.9.0'}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
'@babel/traverse@7.29.8':
resolution: {integrity: sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg==}
engines: {node: '>=6.9.0'}
2026-02-21 03:10:39 +00:00
'@babel/types@7.29.0':
resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==}
engines: {node: '>=6.9.0'}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
'@babel/types@7.29.8':
resolution: {integrity: sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==}
engines: {node: '>=6.9.0'}
'@balena/dockerignore@1.0.2':
resolution: {integrity: sha512-wMue2Sy4GAVTk6Ic4tJVcnfdau+gx2EnG7S+uAEe+TWJFqE4YoWN4/H8MSLj4eYJKxGg26lZwboEniNiNwZQ6Q==}
2026-02-21 03:10:39 +00:00
'@bcoe/v8-coverage@1.0.2':
resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==}
engines: {node: '>=18'}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
'@bramus/specificity@2.4.2':
resolution: {integrity: sha512-ctxtJ/eA+t+6q2++vj5j7FYX3nRu311q1wfYH3xjlLOsczhlhxAg2FWNUXhpGvAw3BWo1xBcvOV6/YLc2r5FJw==}
hasBin: true
'@csstools/color-helpers@6.0.2':
resolution: {integrity: sha512-LMGQLS9EuADloEFkcTBR3BwV/CGHV7zyDxVRtVDTwdI2Ca4it0CCVTT9wCkxSgokjE5Ho41hEPgb8OEUwoXr6Q==}
engines: {node: '>=20.19.0'}
'@csstools/css-calc@3.2.0':
resolution: {integrity: sha512-bR9e6o2BDB12jzN/gIbjHa5wLJ4UjD1CB9pM7ehlc0ddk6EBz+yYS1EV2MF55/HUxrHcB/hehAyt5vhsA3hx7w==}
engines: {node: '>=20.19.0'}
peerDependencies:
'@csstools/css-parser-algorithms': ^4.0.0
'@csstools/css-tokenizer': ^4.0.0
'@csstools/css-color-parser@4.1.0':
resolution: {integrity: sha512-U0KhLYmy2GVj6q4T3WaAe6NPuFYCPQoE3b0dRGxejWDgcPp8TP7S5rVdM5ZrFaqu4N67X8YaPBw14dQSYx3IyQ==}
engines: {node: '>=20.19.0'}
peerDependencies:
'@csstools/css-parser-algorithms': ^4.0.0
'@csstools/css-tokenizer': ^4.0.0
'@csstools/css-parser-algorithms@4.0.0':
resolution: {integrity: sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w==}
engines: {node: '>=20.19.0'}
peerDependencies:
'@csstools/css-tokenizer': ^4.0.0
'@csstools/css-syntax-patches-for-csstree@1.1.3':
resolution: {integrity: sha512-SH60bMfrRCJF3morcdk57WklujF4Jr/EsQUzqkarfHXEFcAR1gg7fS/chAE922Sehgzc1/+Tz5H3Ypa1HiEKrg==}
peerDependencies:
css-tree: ^3.2.1
peerDependenciesMeta:
css-tree:
optional: true
'@csstools/css-tokenizer@4.0.0':
resolution: {integrity: sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==}
engines: {node: '>=20.19.0'}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
'@earendil-works/pi-agent-core@0.84.1':
resolution: {integrity: sha512-evyzXYWCLQGmcaBYHlmSku02r8qoN4SGI60GZABo6iV+H+nqX+P9ud8fEZ4GmRq9mUSREvvfX+w9dA9ThF9C6w==}
engines: {node: '>=22.19.0'}
'@earendil-works/pi-ai@0.84.1':
resolution: {integrity: sha512-wMsAdJMxuNri08vLqTyYVI201DQQezGhPSTkzYsHdw5dYX3rCNwEmSvpaAwhi7ELKI/2tE/CEgSWg/6iRxSgdQ==}
engines: {node: '>=22.19.0'}
hasBin: true
'@earendil-works/pi-client@0.84.1':
resolution: {integrity: sha512-/V5hGHE4Zq+jG0GtwIB9PyBUOGd6gBLZ7lkQYFKchKnxYHeH3rmWC5xw4kpnZKKBuBuFTdLVbU9vEjlAGMMb2A==}
engines: {node: '>=22.19.0'}
'@earendil-works/pi-coding-agent@0.84.1':
resolution: {integrity: sha512-ncAqFrG+iybuPGOhMiZoEHkEzTpJgz3guYD32pD+M7ucc0WeHmauP6wa7qwP8V/KWvsZDVNa5XGsdZ7fkC7w7A==}
engines: {node: '>=22.19.0'}
hasBin: true
'@earendil-works/pi-protocol@0.84.1':
resolution: {integrity: sha512-Ox1pciyeSPGEEUcxvR0/dJcrY7C6hrEGA8y71rOsvSIUlXN1Cbp/be/eoL71OGDBk5O97TeQPfWN6Ju/2Ehjww==}
engines: {node: '>=22.19.0'}
'@earendil-works/pi-telemetry@0.84.1':
resolution: {integrity: sha512-180/xGJtsq7IoR3p9EKWjRd0e9M4DkxInhlo9xyD7prDC7Qrhqq+nhvwrW0lFjPfXcEI2FSHmGCSyvSJE9GsaQ==}
engines: {node: '>=22.19.0'}
'@earendil-works/pi-tui@0.84.1':
resolution: {integrity: sha512-udeXFbgEhJ6JiB0uguwNVNkDy2FENfmtQwPcY+/iJ8GWeq18wkal1tKqa5YyeH0IqtX1vG0cGh8zfSYzyzVuLA==}
engines: {node: '>=22.19.0'}
feat(web): bold redesign — Tailwind v4 + shadcn-style primitives + Skills/Proposals/Revisions UI Phase 6 of the Skills + Revisions + Proposals work. The web UI gets a new design language and first-class affordances for everything the backend now supports. ## Visual direction - Tailwind v4 with custom @theme block (oklch tokens). Dark-mode-only (internal tool — light mode doubles QA surface). - Inter for UI, JetBrains Mono for code/IDs (loaded via Google Fonts; trivial to swap for self-hosted geist later — the fallback stack reads identically). - Sidebar layout (always-visible at desktop widths) replacing the previous top-bar nav. Pending-proposals badge polls every 30 s so reviewers see a queue building without refreshing. - Lucide icons throughout. - Spacing and radii on Tailwind defaults. Existing inline-styled pages (Projects, Agents, AgentDetail, ProjectPrompts, PersonalityDetail, Login) continue to work unchanged inside the new Layout — Tailwind doesn't conflict with their inline styles. A follow-up can migrate them incrementally. ## What's added ### Build infra (src/web/) - package.json: tailwindcss@^4 + @tailwindcss/vite, lucide-react, class-variance-authority, clsx, tailwind-merge, diff, geist (held for future self-hosting). - vite.config.ts: registers the @tailwindcss/vite plugin. - src/index.css: Tailwind import + @theme tokens + @layer base. - src/main.tsx: imports index.css. - src/lib/utils.ts: shadcn-style cn() helper. ### shadcn-style primitives (src/components/ui/) Hand-written rather than generated via `npx shadcn` so the repo doesn't depend on a CLI tool that needs interactive runtime: - button.tsx — variants: primary / secondary / ghost / danger / link; sizes: sm / md / lg / icon. - card.tsx — Card + Header/Title/Description/Content/Footer subparts. - badge.tsx — variants: default / info / success / warning / danger / outline. - input.tsx — Input + Textarea + Label. - tabs.tsx — no-dep accessible Tabs (no Radix needed for our use). - separator.tsx — h/v separator with role=separator. ### Diff component (src/components/Diff.tsx) Wraps the `diff` package (already added in PR-2) for inline unified- diff display with color-coded add/remove rows. Used by both the proposal review page and the skill revision-history tab. ### New pages (src/pages/) - Dashboard.tsx — at-a-glance home. Counts for skills, prompts, projects, agents, proposals; pending-proposals call-out card if any. - Skills.tsx — list view, separated into Global vs Project/Agent- scoped sections. - SkillDetail.tsx — name + semver + description; tabs for SKILL.md / Files / Metadata / History. History tab shows revisions with click-to-diff against the live body. - Proposals.tsx — queue with Pending/Approved/Rejected tabs. Pending count is highlighted in amber. - ProposalDetail.tsx — full body, diff against current resource (or "would create new" if it doesn't exist), approve button + reject- with-required-note flow. ### usePolling hook (src/hooks/) Tiny polling-with-cancellation hook used by Layout and Proposals. ### Layout rewrite (src/components/Layout.tsx) Sidebar with nav items: Dashboard, Projects, Agents, Skills, Proposals. Lucide icons. Active-route highlighting via NavLink. Pending-proposals warning badge on the Proposals item. ### Routes (src/App.tsx) New routes: /dashboard, /skills, /skills/:name, /proposals, /proposals/:id. Default redirects to /dashboard. ### API types (src/api.ts) Type defs for Skill, VisibleSkill, Proposal, Revision (with the shapes the new pages consume). ## Tests Existing 7 web tests still pass (Login + api). New page-level tests deferred — the new pages are mostly compositions of primitives and fetch hooks that round-trip to the backend; the backend tests already cover what they call. PR-7 polish can add render-and-click tests if coverage drift surfaces. ## Verification - `pnpm --filter @mcpctl/web build` clean, no warnings. - `pnpm test:run` whole monorepo: 162 test files / 2157 tests green. - Visual smoke deferred — needs a running mcpd to populate the fixtures. Manual smoke tested locally is the next step. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:54:55 +01:00
'@emnapi/runtime@1.10.0':
resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==}
2026-02-21 03:10:39 +00:00
'@esbuild/aix-ppc64@0.27.3':
resolution: {integrity: sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==}
engines: {node: '>=18'}
cpu: [ppc64]
os: [aix]
'@esbuild/android-arm64@0.27.3':
resolution: {integrity: sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==}
engines: {node: '>=18'}
cpu: [arm64]
os: [android]
'@esbuild/android-arm@0.27.3':
resolution: {integrity: sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==}
engines: {node: '>=18'}
cpu: [arm]
os: [android]
'@esbuild/android-x64@0.27.3':
resolution: {integrity: sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==}
engines: {node: '>=18'}
cpu: [x64]
os: [android]
'@esbuild/darwin-arm64@0.27.3':
resolution: {integrity: sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==}
engines: {node: '>=18'}
cpu: [arm64]
os: [darwin]
'@esbuild/darwin-x64@0.27.3':
resolution: {integrity: sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==}
engines: {node: '>=18'}
cpu: [x64]
os: [darwin]
'@esbuild/freebsd-arm64@0.27.3':
resolution: {integrity: sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==}
engines: {node: '>=18'}
cpu: [arm64]
os: [freebsd]
'@esbuild/freebsd-x64@0.27.3':
resolution: {integrity: sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==}
engines: {node: '>=18'}
cpu: [x64]
os: [freebsd]
'@esbuild/linux-arm64@0.27.3':
resolution: {integrity: sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==}
engines: {node: '>=18'}
cpu: [arm64]
os: [linux]
'@esbuild/linux-arm@0.27.3':
resolution: {integrity: sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==}
engines: {node: '>=18'}
cpu: [arm]
os: [linux]
'@esbuild/linux-ia32@0.27.3':
resolution: {integrity: sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==}
engines: {node: '>=18'}
cpu: [ia32]
os: [linux]
'@esbuild/linux-loong64@0.27.3':
resolution: {integrity: sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==}
engines: {node: '>=18'}
cpu: [loong64]
os: [linux]
'@esbuild/linux-mips64el@0.27.3':
resolution: {integrity: sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==}
engines: {node: '>=18'}
cpu: [mips64el]
os: [linux]
'@esbuild/linux-ppc64@0.27.3':
resolution: {integrity: sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==}
engines: {node: '>=18'}
cpu: [ppc64]
os: [linux]
'@esbuild/linux-riscv64@0.27.3':
resolution: {integrity: sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==}
engines: {node: '>=18'}
cpu: [riscv64]
os: [linux]
'@esbuild/linux-s390x@0.27.3':
resolution: {integrity: sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==}
engines: {node: '>=18'}
cpu: [s390x]
os: [linux]
'@esbuild/linux-x64@0.27.3':
resolution: {integrity: sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==}
engines: {node: '>=18'}
cpu: [x64]
os: [linux]
'@esbuild/netbsd-arm64@0.27.3':
resolution: {integrity: sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==}
engines: {node: '>=18'}
cpu: [arm64]
os: [netbsd]
'@esbuild/netbsd-x64@0.27.3':
resolution: {integrity: sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==}
engines: {node: '>=18'}
cpu: [x64]
os: [netbsd]
'@esbuild/openbsd-arm64@0.27.3':
resolution: {integrity: sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==}
engines: {node: '>=18'}
cpu: [arm64]
os: [openbsd]
'@esbuild/openbsd-x64@0.27.3':
resolution: {integrity: sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==}
engines: {node: '>=18'}
cpu: [x64]
os: [openbsd]
'@esbuild/openharmony-arm64@0.27.3':
resolution: {integrity: sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==}
engines: {node: '>=18'}
cpu: [arm64]
os: [openharmony]
'@esbuild/sunos-x64@0.27.3':
resolution: {integrity: sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==}
engines: {node: '>=18'}
cpu: [x64]
os: [sunos]
'@esbuild/win32-arm64@0.27.3':
resolution: {integrity: sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==}
engines: {node: '>=18'}
cpu: [arm64]
os: [win32]
'@esbuild/win32-ia32@0.27.3':
resolution: {integrity: sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==}
engines: {node: '>=18'}
cpu: [ia32]
os: [win32]
'@esbuild/win32-x64@0.27.3':
resolution: {integrity: sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==}
engines: {node: '>=18'}
cpu: [x64]
os: [win32]
'@eslint-community/eslint-utils@4.9.1':
resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
'@eslint-community/regexpp@4.12.2':
resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==}
engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
'@eslint/config-array@0.23.2':
resolution: {integrity: sha512-YF+fE6LV4v5MGWRGj7G404/OZzGNepVF8fxk7jqmqo3lrza7a0uUcDnROGRBG1WFC1omYUS/Wp1f42i0M+3Q3A==}
engines: {node: ^20.19.0 || ^22.13.0 || >=24}
'@eslint/config-helpers@0.5.2':
resolution: {integrity: sha512-a5MxrdDXEvqnIq+LisyCX6tQMPF/dSJpCfBgBauY+pNZ28yCtSsTvyTYrMhaI+LK26bVyCJfJkT0u8KIj2i1dQ==}
engines: {node: ^20.19.0 || ^22.13.0 || >=24}
'@eslint/core@1.1.0':
resolution: {integrity: sha512-/nr9K9wkr3P1EzFTdFdMoLuo1PmIxjmwvPozwoSodjNBdefGujXQUF93u1DDZpEaTuDvMsIQddsd35BwtrW9Xw==}
engines: {node: ^20.19.0 || ^22.13.0 || >=24}
'@eslint/object-schema@3.0.2':
resolution: {integrity: sha512-HOy56KJt48Bx8KmJ+XGQNSUMT/6dZee/M54XyUyuvTvPXJmsERRvBchsUVx1UMe1WwIH49XLAczNC7V2INsuUw==}
engines: {node: ^20.19.0 || ^22.13.0 || >=24}
'@eslint/plugin-kit@0.6.0':
resolution: {integrity: sha512-bIZEUzOI1jkhviX2cp5vNyXQc6olzb2ohewQubuYlMXZ2Q/XjBO0x0XhGPvc9fjSIiUN0vw+0hq53BJ4eQSJKQ==}
engines: {node: ^20.19.0 || ^22.13.0 || >=24}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
'@exodus/bytes@1.15.0':
resolution: {integrity: sha512-UY0nlA+feH81UGSHv92sLEPLCeZFjXOuHhrIo0HQydScuQc8s0A7kL/UdgwgDq8g8ilksmuoF35YVTNphV2aBQ==}
engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0}
peerDependencies:
'@noble/hashes': ^1.8.0 || ^2.0.0
peerDependenciesMeta:
'@noble/hashes':
optional: true
feat(mcpd+deploy): serve web UI at /ui + smoke tests + docs (Stage 6) The closing stage. mcpd now hosts the Stage 5 SPA, the Docker image bundles the build artifact, a smoke test exercises the personality HTTP surface end-to-end, and the user-facing docs spell out the mental model. mcpd: - Add @fastify/static dep. - New routes/web-ui.ts: registers /ui/* against a static bundle. Looks for the bundle at $MCPD_WEB_ROOT, then /usr/share/mcpd/web (the Docker image path), then a dev-tree fallback. Logs and skips cleanly if missing — API-only deploys keep working. - SPA fallback: any /ui/<path> that doesn't match a file falls through to index.html so direct hits to react-router URLs work. - /ui/* falls through to `kind: skip` in mapUrlToPermission, so the static assets are served unauthenticated. Each API call from the SPA still carries the bearer token. Deploy: - Dockerfile.mcpd builds the @mcpctl/web bundle in the same builder stage and copies dist/ to /usr/share/mcpd/web in the runtime image. Smoke (personality.smoke.test.ts): - Live mcpd flow: create secret/llm/agent/personality, attach an agent-direct prompt, verify the binding listing, reject double- attach (409) + foreign-agent prompt (400), set defaultPersonality by name, detach + delete cleanup. Docs: - New docs/personalities.md: VLAN-on-ethernet model, system-block ordering table, three prompt scopes, CLI walkthrough, web UI walkthrough, full API surface, RBAC notes. - agents.md and chat.md cross-link. - README's Agents section gains a Personalities subsection. Test count after Stage 6: mcpd: 801/801 cli: 430/430 web: 7/7 db: 58/62 (4 pre-existing) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:48:43 +01:00
'@fastify/accept-negotiator@2.0.1':
resolution: {integrity: sha512-/c/TW2bO/v9JeEgoD/g1G5GxGeCF1Hafdf79WPmUlgYiBXummY0oX3VVq4yFkKKVBKDNlaDUYoab7g38RpPqCQ==}
2026-02-21 03:10:39 +00:00
'@fastify/ajv-compiler@4.0.5':
resolution: {integrity: sha512-KoWKW+MhvfTRWL4qrhUwAAZoaChluo0m0vbiJlGMt2GXvL4LVPQEjt8kSpHI3IBq5Rez8fg+XeH3cneztq+C7A==}
'@fastify/cors@10.1.0':
resolution: {integrity: sha512-MZyBCBJtII60CU9Xme/iE4aEy8G7QpzGR8zkdXZkDFt7ElEMachbE61tfhAG/bvSaULlqlf0huMT12T7iqEmdQ==}
'@fastify/error@4.2.0':
resolution: {integrity: sha512-RSo3sVDXfHskiBZKBPRgnQTtIqpi/7zhJOEmAxCiBcM7d0uwdGdxLlsCaLzGs8v8NnxIRlfG0N51p5yFaOentQ==}
'@fastify/fast-json-stringify-compiler@5.0.3':
resolution: {integrity: sha512-uik7yYHkLr6fxd8hJSZ8c+xF4WafPK+XzneQDPU+D10r5X19GW8lJcom2YijX2+qtFF1ENJlHXKFM9ouXNJYgQ==}
'@fastify/forwarded@3.0.1':
resolution: {integrity: sha512-JqDochHFqXs3C3Ml3gOY58zM7OqO9ENqPo0UqAjAjH8L01fRZqwX9iLeX34//kiJubF7r2ZQHtBRU36vONbLlw==}
'@fastify/helmet@12.0.1':
resolution: {integrity: sha512-kkjBcedWwdflRThovGuvN9jB2QQLytBqArCFPdMIb7o2Fp0l/H3xxYi/6x/SSRuH/FFt9qpTGIfJz2bfnMrLqA==}
'@fastify/merge-json-schemas@0.2.1':
resolution: {integrity: sha512-OA3KGBCy6KtIvLf8DINC5880o5iBlDX4SxzLQS8HorJAbqluzLRn80UXU0bxZn7UOFhFgpRJDasfwn9nG4FG4A==}
'@fastify/proxy-addr@5.1.0':
resolution: {integrity: sha512-INS+6gh91cLUjB+PVHfu1UqcB76Sqtpyp7bnL+FYojhjygvOPA9ctiD/JDKsyD9Xgu4hUhCSJBPig/w7duNajw==}
'@fastify/rate-limit@10.3.0':
resolution: {integrity: sha512-eIGkG9XKQs0nyynatApA3EVrojHOuq4l6fhB4eeCk4PIOeadvOJz9/4w3vGI44Go17uaXOWEcPkaD8kuKm7g6Q==}
feat(mcpd+deploy): serve web UI at /ui + smoke tests + docs (Stage 6) The closing stage. mcpd now hosts the Stage 5 SPA, the Docker image bundles the build artifact, a smoke test exercises the personality HTTP surface end-to-end, and the user-facing docs spell out the mental model. mcpd: - Add @fastify/static dep. - New routes/web-ui.ts: registers /ui/* against a static bundle. Looks for the bundle at $MCPD_WEB_ROOT, then /usr/share/mcpd/web (the Docker image path), then a dev-tree fallback. Logs and skips cleanly if missing — API-only deploys keep working. - SPA fallback: any /ui/<path> that doesn't match a file falls through to index.html so direct hits to react-router URLs work. - /ui/* falls through to `kind: skip` in mapUrlToPermission, so the static assets are served unauthenticated. Each API call from the SPA still carries the bearer token. Deploy: - Dockerfile.mcpd builds the @mcpctl/web bundle in the same builder stage and copies dist/ to /usr/share/mcpd/web in the runtime image. Smoke (personality.smoke.test.ts): - Live mcpd flow: create secret/llm/agent/personality, attach an agent-direct prompt, verify the binding listing, reject double- attach (409) + foreign-agent prompt (400), set defaultPersonality by name, detach + delete cleanup. Docs: - New docs/personalities.md: VLAN-on-ethernet model, system-block ordering table, three prompt scopes, CLI walkthrough, web UI walkthrough, full API surface, RBAC notes. - agents.md and chat.md cross-link. - README's Agents section gains a Personalities subsection. Test count after Stage 6: mcpd: 801/801 cli: 430/430 web: 7/7 db: 58/62 (4 pre-existing) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:48:43 +01:00
'@fastify/send@4.1.0':
resolution: {integrity: sha512-TMYeQLCBSy2TOFmV95hQWkiTYgC/SEx7vMdV+wnZVX4tt8VBLKzmH8vV9OzJehV0+XBfg+WxPMt5wp+JBUKsVw==}
'@fastify/static@8.3.0':
resolution: {integrity: sha512-yKxviR5PH1OKNnisIzZKmgZSus0r2OZb8qCSbqmw34aolT4g3UlzYfeBRym+HJ1J471CR8e2ldNub4PubD1coA==}
'@gar/promise-retry@1.0.3':
resolution: {integrity: sha512-GmzA9ckNokPypTg10pgpeHNQe7ph+iIKKmhKu3Ob9ANkswreCx7R3cKmY781K8QK3AqVL3xVh9A42JvIAbkkSA==}
engines: {node: ^20.17.0 || >=22.9.0}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
'@google/genai@1.52.0':
resolution: {integrity: sha512-gwSvbpiN/17O9TbsqSsE/OzZcpv5Fo4RQjdngGgogtuB9RsyJ8ZHhX5KjHj1bp5N9snN2eK8LDGXSaWW2hof8Q==}
engines: {node: '>=20.0.0'}
peerDependencies:
'@modelcontextprotocol/sdk': ^1.25.2
peerDependenciesMeta:
'@modelcontextprotocol/sdk':
optional: true
'@grpc/grpc-js@1.14.3':
resolution: {integrity: sha512-Iq8QQQ/7X3Sac15oB6p0FmUg/klxQvXLeileoqrTRGJYLV+/9tubbr9ipz0GKHjmXVsgFPo/+W+2cA8eNcR+XA==}
engines: {node: '>=12.10.0'}
'@grpc/proto-loader@0.7.15':
resolution: {integrity: sha512-tMXdRCfYVixjuFK+Hk0Q1s38gV9zDiDJfWL3h1rv4Qc39oILCu1TRTDt7+fGUI8K4G1Fj125Hx/ru3azECWTyQ==}
engines: {node: '>=6'}
hasBin: true
'@grpc/proto-loader@0.8.0':
resolution: {integrity: sha512-rc1hOQtjIWGxcxpb9aHAfLpIctjEnsDehj0DAiVfBlmT84uvR0uUtN2hEi/ecvWVjXUGf5qPF4qEgiLOx1YIMQ==}
engines: {node: '>=6'}
hasBin: true
2026-02-21 03:10:39 +00:00
'@hono/node-server@1.19.9':
resolution: {integrity: sha512-vHL6w3ecZsky+8P5MD+eFfaGTyCeOHUIFYMGpQGbrBTSmNNoxv0if69rEZ5giu36weC5saFuznL411gRX7bJDw==}
engines: {node: '>=18.14.1'}
peerDependencies:
hono: ^4
'@humanfs/core@0.19.1':
resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==}
engines: {node: '>=18.18.0'}
'@humanfs/node@0.16.7':
resolution: {integrity: sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==}
engines: {node: '>=18.18.0'}
'@humanwhocodes/module-importer@1.0.1':
resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==}
engines: {node: '>=12.22'}
'@humanwhocodes/retry@0.4.3':
resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==}
engines: {node: '>=18.18'}
feat(web): bold redesign — Tailwind v4 + shadcn-style primitives + Skills/Proposals/Revisions UI Phase 6 of the Skills + Revisions + Proposals work. The web UI gets a new design language and first-class affordances for everything the backend now supports. ## Visual direction - Tailwind v4 with custom @theme block (oklch tokens). Dark-mode-only (internal tool — light mode doubles QA surface). - Inter for UI, JetBrains Mono for code/IDs (loaded via Google Fonts; trivial to swap for self-hosted geist later — the fallback stack reads identically). - Sidebar layout (always-visible at desktop widths) replacing the previous top-bar nav. Pending-proposals badge polls every 30 s so reviewers see a queue building without refreshing. - Lucide icons throughout. - Spacing and radii on Tailwind defaults. Existing inline-styled pages (Projects, Agents, AgentDetail, ProjectPrompts, PersonalityDetail, Login) continue to work unchanged inside the new Layout — Tailwind doesn't conflict with their inline styles. A follow-up can migrate them incrementally. ## What's added ### Build infra (src/web/) - package.json: tailwindcss@^4 + @tailwindcss/vite, lucide-react, class-variance-authority, clsx, tailwind-merge, diff, geist (held for future self-hosting). - vite.config.ts: registers the @tailwindcss/vite plugin. - src/index.css: Tailwind import + @theme tokens + @layer base. - src/main.tsx: imports index.css. - src/lib/utils.ts: shadcn-style cn() helper. ### shadcn-style primitives (src/components/ui/) Hand-written rather than generated via `npx shadcn` so the repo doesn't depend on a CLI tool that needs interactive runtime: - button.tsx — variants: primary / secondary / ghost / danger / link; sizes: sm / md / lg / icon. - card.tsx — Card + Header/Title/Description/Content/Footer subparts. - badge.tsx — variants: default / info / success / warning / danger / outline. - input.tsx — Input + Textarea + Label. - tabs.tsx — no-dep accessible Tabs (no Radix needed for our use). - separator.tsx — h/v separator with role=separator. ### Diff component (src/components/Diff.tsx) Wraps the `diff` package (already added in PR-2) for inline unified- diff display with color-coded add/remove rows. Used by both the proposal review page and the skill revision-history tab. ### New pages (src/pages/) - Dashboard.tsx — at-a-glance home. Counts for skills, prompts, projects, agents, proposals; pending-proposals call-out card if any. - Skills.tsx — list view, separated into Global vs Project/Agent- scoped sections. - SkillDetail.tsx — name + semver + description; tabs for SKILL.md / Files / Metadata / History. History tab shows revisions with click-to-diff against the live body. - Proposals.tsx — queue with Pending/Approved/Rejected tabs. Pending count is highlighted in amber. - ProposalDetail.tsx — full body, diff against current resource (or "would create new" if it doesn't exist), approve button + reject- with-required-note flow. ### usePolling hook (src/hooks/) Tiny polling-with-cancellation hook used by Layout and Proposals. ### Layout rewrite (src/components/Layout.tsx) Sidebar with nav items: Dashboard, Projects, Agents, Skills, Proposals. Lucide icons. Active-route highlighting via NavLink. Pending-proposals warning badge on the Proposals item. ### Routes (src/App.tsx) New routes: /dashboard, /skills, /skills/:name, /proposals, /proposals/:id. Default redirects to /dashboard. ### API types (src/api.ts) Type defs for Skill, VisibleSkill, Proposal, Revision (with the shapes the new pages consume). ## Tests Existing 7 web tests still pass (Login + api). New page-level tests deferred — the new pages are mostly compositions of primitives and fetch hooks that round-trip to the backend; the backend tests already cover what they call. PR-7 polish can add render-and-click tests if coverage drift surfaces. ## Verification - `pnpm --filter @mcpctl/web build` clean, no warnings. - `pnpm test:run` whole monorepo: 162 test files / 2157 tests green. - Visual smoke deferred — needs a running mcpd to populate the fixtures. Manual smoke tested locally is the next step. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:54:55 +01:00
'@img/colour@1.1.0':
resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==}
engines: {node: '>=18'}
'@img/sharp-darwin-arm64@0.34.5':
resolution: {integrity: sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [arm64]
os: [darwin]
'@img/sharp-darwin-x64@0.34.5':
resolution: {integrity: sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [x64]
os: [darwin]
'@img/sharp-libvips-darwin-arm64@1.2.4':
resolution: {integrity: sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==}
cpu: [arm64]
os: [darwin]
'@img/sharp-libvips-darwin-x64@1.2.4':
resolution: {integrity: sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==}
cpu: [x64]
os: [darwin]
'@img/sharp-libvips-linux-arm64@1.2.4':
resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==}
cpu: [arm64]
os: [linux]
'@img/sharp-libvips-linux-arm@1.2.4':
resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==}
cpu: [arm]
os: [linux]
'@img/sharp-libvips-linux-ppc64@1.2.4':
resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==}
cpu: [ppc64]
os: [linux]
'@img/sharp-libvips-linux-riscv64@1.2.4':
resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==}
cpu: [riscv64]
os: [linux]
'@img/sharp-libvips-linux-s390x@1.2.4':
resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==}
cpu: [s390x]
os: [linux]
'@img/sharp-libvips-linux-x64@1.2.4':
resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==}
cpu: [x64]
os: [linux]
'@img/sharp-libvips-linuxmusl-arm64@1.2.4':
resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==}
cpu: [arm64]
os: [linux]
'@img/sharp-libvips-linuxmusl-x64@1.2.4':
resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==}
cpu: [x64]
os: [linux]
'@img/sharp-linux-arm64@0.34.5':
resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [arm64]
os: [linux]
'@img/sharp-linux-arm@0.34.5':
resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [arm]
os: [linux]
'@img/sharp-linux-ppc64@0.34.5':
resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [ppc64]
os: [linux]
'@img/sharp-linux-riscv64@0.34.5':
resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [riscv64]
os: [linux]
'@img/sharp-linux-s390x@0.34.5':
resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [s390x]
os: [linux]
'@img/sharp-linux-x64@0.34.5':
resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [x64]
os: [linux]
'@img/sharp-linuxmusl-arm64@0.34.5':
resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [arm64]
os: [linux]
'@img/sharp-linuxmusl-x64@0.34.5':
resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [x64]
os: [linux]
'@img/sharp-wasm32@0.34.5':
resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [wasm32]
'@img/sharp-win32-arm64@0.34.5':
resolution: {integrity: sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [arm64]
os: [win32]
'@img/sharp-win32-ia32@0.34.5':
resolution: {integrity: sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [ia32]
os: [win32]
'@img/sharp-win32-x64@0.34.5':
resolution: {integrity: sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [x64]
os: [win32]
'@inkjs/ui@2.0.0':
resolution: {integrity: sha512-5+8fJmwtF9UvikzLfph9sA+LS+l37Ij/szQltkuXLOAXwNkBX9innfzh4pLGXIB59vKEQUtc6D4qGvhD7h3pAg==}
engines: {node: '>=18'}
peerDependencies:
ink: '>=5'
2026-02-21 03:10:39 +00:00
'@inquirer/ansi@1.0.2':
resolution: {integrity: sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ==}
engines: {node: '>=18'}
'@inquirer/checkbox@4.3.2':
resolution: {integrity: sha512-VXukHf0RR1doGe6Sm4F0Em7SWYLTHSsbGfJdS9Ja2bX5/D5uwVOEjr07cncLROdBvmnvCATYEWlHqYmXv2IlQA==}
engines: {node: '>=18'}
peerDependencies:
'@types/node': '>=18'
peerDependenciesMeta:
'@types/node':
optional: true
'@inquirer/confirm@5.1.21':
resolution: {integrity: sha512-KR8edRkIsUayMXV+o3Gv+q4jlhENF9nMYUZs9PA2HzrXeHI8M5uDag70U7RJn9yyiMZSbtF5/UexBtAVtZGSbQ==}
engines: {node: '>=18'}
peerDependencies:
'@types/node': '>=18'
peerDependenciesMeta:
'@types/node':
optional: true
'@inquirer/core@10.3.2':
resolution: {integrity: sha512-43RTuEbfP8MbKzedNqBrlhhNKVwoK//vUFNW3Q3vZ88BLcrs4kYpGg+B2mm5p2K/HfygoCxuKwJJiv8PbGmE0A==}
engines: {node: '>=18'}
peerDependencies:
'@types/node': '>=18'
peerDependenciesMeta:
'@types/node':
optional: true
'@inquirer/editor@4.2.23':
resolution: {integrity: sha512-aLSROkEwirotxZ1pBaP8tugXRFCxW94gwrQLxXfrZsKkfjOYC1aRvAZuhpJOb5cu4IBTJdsCigUlf2iCOu4ZDQ==}
engines: {node: '>=18'}
peerDependencies:
'@types/node': '>=18'
peerDependenciesMeta:
'@types/node':
optional: true
'@inquirer/expand@4.0.23':
resolution: {integrity: sha512-nRzdOyFYnpeYTTR2qFwEVmIWypzdAx/sIkCMeTNTcflFOovfqUk+HcFhQQVBftAh9gmGrpFj6QcGEqrDMDOiew==}
engines: {node: '>=18'}
peerDependencies:
'@types/node': '>=18'
peerDependenciesMeta:
'@types/node':
optional: true
'@inquirer/external-editor@1.0.3':
resolution: {integrity: sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==}
engines: {node: '>=18'}
peerDependencies:
'@types/node': '>=18'
peerDependenciesMeta:
'@types/node':
optional: true
'@inquirer/figures@1.0.15':
resolution: {integrity: sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g==}
engines: {node: '>=18'}
'@inquirer/input@4.3.1':
resolution: {integrity: sha512-kN0pAM4yPrLjJ1XJBjDxyfDduXOuQHrBB8aLDMueuwUGn+vNpF7Gq7TvyVxx8u4SHlFFj4trmj+a2cbpG4Jn1g==}
engines: {node: '>=18'}
peerDependencies:
'@types/node': '>=18'
peerDependenciesMeta:
'@types/node':
optional: true
'@inquirer/number@3.0.23':
resolution: {integrity: sha512-5Smv0OK7K0KUzUfYUXDXQc9jrf8OHo4ktlEayFlelCjwMXz0299Y8OrI+lj7i4gCBY15UObk76q0QtxjzFcFcg==}
engines: {node: '>=18'}
peerDependencies:
'@types/node': '>=18'
peerDependenciesMeta:
'@types/node':
optional: true
'@inquirer/password@4.0.23':
resolution: {integrity: sha512-zREJHjhT5vJBMZX/IUbyI9zVtVfOLiTO66MrF/3GFZYZ7T4YILW5MSkEYHceSii/KtRk+4i3RE7E1CUXA2jHcA==}
engines: {node: '>=18'}
peerDependencies:
'@types/node': '>=18'
peerDependenciesMeta:
'@types/node':
optional: true
'@inquirer/prompts@7.10.1':
resolution: {integrity: sha512-Dx/y9bCQcXLI5ooQ5KyvA4FTgeo2jYj/7plWfV5Ak5wDPKQZgudKez2ixyfz7tKXzcJciTxqLeK7R9HItwiByg==}
engines: {node: '>=18'}
peerDependencies:
'@types/node': '>=18'
peerDependenciesMeta:
'@types/node':
optional: true
'@inquirer/rawlist@4.1.11':
resolution: {integrity: sha512-+LLQB8XGr3I5LZN/GuAHo+GpDJegQwuPARLChlMICNdwW7OwV2izlCSCxN6cqpL0sMXmbKbFcItJgdQq5EBXTw==}
engines: {node: '>=18'}
peerDependencies:
'@types/node': '>=18'
peerDependenciesMeta:
'@types/node':
optional: true
'@inquirer/search@3.2.2':
resolution: {integrity: sha512-p2bvRfENXCZdWF/U2BXvnSI9h+tuA8iNqtUKb9UWbmLYCRQxd8WkvwWvYn+3NgYaNwdUkHytJMGG4MMLucI1kA==}
engines: {node: '>=18'}
peerDependencies:
'@types/node': '>=18'
peerDependenciesMeta:
'@types/node':
optional: true
'@inquirer/select@4.4.2':
resolution: {integrity: sha512-l4xMuJo55MAe+N7Qr4rX90vypFwCajSakx59qe/tMaC1aEHWLyw68wF4o0A4SLAY4E0nd+Vt+EyskeDIqu1M6w==}
engines: {node: '>=18'}
peerDependencies:
'@types/node': '>=18'
peerDependenciesMeta:
'@types/node':
optional: true
'@inquirer/type@3.0.10':
resolution: {integrity: sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA==}
engines: {node: '>=18'}
peerDependencies:
'@types/node': '>=18'
peerDependenciesMeta:
'@types/node':
optional: true
feat(mcpd+deploy): serve web UI at /ui + smoke tests + docs (Stage 6) The closing stage. mcpd now hosts the Stage 5 SPA, the Docker image bundles the build artifact, a smoke test exercises the personality HTTP surface end-to-end, and the user-facing docs spell out the mental model. mcpd: - Add @fastify/static dep. - New routes/web-ui.ts: registers /ui/* against a static bundle. Looks for the bundle at $MCPD_WEB_ROOT, then /usr/share/mcpd/web (the Docker image path), then a dev-tree fallback. Logs and skips cleanly if missing — API-only deploys keep working. - SPA fallback: any /ui/<path> that doesn't match a file falls through to index.html so direct hits to react-router URLs work. - /ui/* falls through to `kind: skip` in mapUrlToPermission, so the static assets are served unauthenticated. Each API call from the SPA still carries the bearer token. Deploy: - Dockerfile.mcpd builds the @mcpctl/web bundle in the same builder stage and copies dist/ to /usr/share/mcpd/web in the runtime image. Smoke (personality.smoke.test.ts): - Live mcpd flow: create secret/llm/agent/personality, attach an agent-direct prompt, verify the binding listing, reject double- attach (409) + foreign-agent prompt (400), set defaultPersonality by name, detach + delete cleanup. Docs: - New docs/personalities.md: VLAN-on-ethernet model, system-block ordering table, three prompt scopes, CLI walkthrough, web UI walkthrough, full API surface, RBAC notes. - agents.md and chat.md cross-link. - README's Agents section gains a Personalities subsection. Test count after Stage 6: mcpd: 801/801 cli: 430/430 web: 7/7 db: 58/62 (4 pre-existing) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:48:43 +01:00
'@isaacs/cliui@9.0.0':
resolution: {integrity: sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg==}
engines: {node: '>=18'}
'@isaacs/fs-minipass@4.0.1':
resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==}
engines: {node: '>=18.0.0'}
'@isaacs/string-locale-compare@1.1.0':
resolution: {integrity: sha512-SQ7Kzhh9+D+ZW9MA0zkYv3VXhIDNx+LzM6EJ+/65I3QY+enU6Itte7E5XX7EWrqLW2FN4n06GWzBnPoC3th2aQ==}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
'@jridgewell/gen-mapping@0.3.13':
resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==}
'@jridgewell/remapping@2.3.5':
resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==}
2026-02-21 03:10:39 +00:00
'@jridgewell/resolve-uri@3.1.2':
resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
engines: {node: '>=6.0.0'}
'@jridgewell/sourcemap-codec@1.5.5':
resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==}
'@jridgewell/trace-mapping@0.3.31':
resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
'@js-sdsl/ordered-map@4.4.2':
resolution: {integrity: sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==}
'@jsep-plugin/assignment@1.3.0':
resolution: {integrity: sha512-VVgV+CXrhbMI3aSusQyclHkenWSAm95WaiKrMxRFam3JSUiIaQjoMIw2sEs/OX4XifnqeQUN4DYbJjlA8EfktQ==}
engines: {node: '>= 10.16.0'}
peerDependencies:
jsep: ^0.4.0||^1.0.0
'@jsep-plugin/regex@1.0.4':
resolution: {integrity: sha512-q7qL4Mgjs1vByCaTnDFcBnV9HS7GVPJX5vyVoCgZHNSC9rjwIlmbXG5sUuorR5ndfHAIlJ8pVStxvjXHbNvtUg==}
engines: {node: '>= 10.16.0'}
peerDependencies:
jsep: ^0.4.0||^1.0.0
'@kubernetes/client-node@1.4.0':
resolution: {integrity: sha512-Zge3YvF7DJi264dU1b3wb/GmzR99JhUpqTvp+VGHfwZT+g7EOOYNScDJNZwXy9cszyIGPIs0VHr+kk8e95qqrA==}
'@logdna/tail-file@2.2.0':
resolution: {integrity: sha512-XGSsWDweP80Fks16lwkAUIr54ICyBs6PsI4mpfTLQaWgEJRtY9xEV+PeyDpJ+sJEGZxqINlpmAwe/6tS1pP8Ng==}
engines: {node: '>=10.3.0'}
2026-02-21 03:10:39 +00:00
'@lukeed/ms@2.0.2':
resolution: {integrity: sha512-9I2Zn6+NJLfaGoz9jN3lpwDgAYvfGeNYdbAIjJOqzs4Tpc+VU3Jqq4IofSUBKajiDS8k9fZIg18/z13mpk1bsA==}
engines: {node: '>=8'}
'@mapbox/node-pre-gyp@1.0.11':
resolution: {integrity: sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==}
hasBin: true
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
'@mariozechner/clipboard-darwin-arm64@0.3.9':
resolution: {integrity: sha512-BfgV7vCEWZwJwZJw03r6bP5+tf0iI/ANuQYCxi9RNn7FrWB3yzGuMKCrNLRl6V761vXRdL8+OqZ0wd4TqlsNOQ==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [darwin]
'@mariozechner/clipboard-darwin-universal@0.3.9':
resolution: {integrity: sha512-BGGR4iA9Z2shAjI65eI5xtyb3LYNlDW9X3gxKxDbqtbnREohsrqznov6zpKoIrsRWpzlYVEdKphS7ksJ0/ndSQ==}
engines: {node: '>= 10'}
os: [darwin]
'@mariozechner/clipboard-darwin-x64@0.3.9':
resolution: {integrity: sha512-4kURmCbS6nt8uYhtmWpUcJWyPHfmAr5dTpXD1nO3pIfa+TSQ9DbrGOYCKH+aEFW47XhQ4Vp8ZTszie+wfFvDKg==}
engines: {node: '>= 10'}
cpu: [x64]
os: [darwin]
'@mariozechner/clipboard-linux-arm64-gnu@0.3.9':
resolution: {integrity: sha512-g59OkUGP2DDfCOIKypHeYgv2M55u/cKvXa5dSxFbEJ34XvIQMdcVmpKCkGUro3ZgefXiGVdwguvTMQGpHWzIXw==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
'@mariozechner/clipboard-linux-arm64-musl@0.3.9':
resolution: {integrity: sha512-AGuJdgKsmJdm4Pych7kv3sqe591ERRaAHW3xjLooiFzn8J+PxUyof++7YZrB5Y5tpnTO+K18Og3taj2NpluCRQ==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
'@mariozechner/clipboard-linux-riscv64-gnu@0.3.9':
resolution: {integrity: sha512-DXBEAiuMpk7dhS1a9NzNxVAFi1vaKoPu7rQNgY8LIDLGrK3lnIp3nT10DUum+PKVJoJppIP+NAA8IZe4DMNDPw==}
engines: {node: '>= 10'}
cpu: [riscv64]
os: [linux]
'@mariozechner/clipboard-linux-x64-gnu@0.3.9':
resolution: {integrity: sha512-WORrMLd6EpElEME7JRKfSaY34nW1P5LbdgK5YNCS1ncG2LqmITsSMEJ8nh2mpvxb3TxqbOOKgY7k9eMJYlW9Mw==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
'@mariozechner/clipboard-linux-x64-musl@0.3.9':
resolution: {integrity: sha512-/DHn+1DrfL6oRaPPWXaOKvonFFrni666fxd+zFqiQEfvBH0tsHVWjq9iqBk0oDp0qaPA72lIMy5BptxISBEhZQ==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
'@mariozechner/clipboard-win32-arm64-msvc@0.3.9':
resolution: {integrity: sha512-O5FHD3ErkMwMhNzAfu3ggy0ug4z7btZuoQgwwxlzPrwV2bxlD6WDpqBY4NCgICAgZdDKdp+loUEKVAVt8aYnhQ==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [win32]
'@mariozechner/clipboard-win32-x64-msvc@0.3.9':
resolution: {integrity: sha512-ihQC3EufqEY81vhXBgVBtK4prL+wc62zJsSvxrgz7K1hsdt6OObz6v9p3Rn1OG3GJksTTKMJF0u/guMISHPhSA==}
engines: {node: '>= 10'}
cpu: [x64]
os: [win32]
'@mariozechner/clipboard@0.3.9':
resolution: {integrity: sha512-ABnA53mdfkGZwOFUdZNv2S0CWGO/EIuPj8Vv9xmBFmSYg/qFc7ihO6q5FcQjvoE67kZpWkEc4AhD6B/os04yuA==}
engines: {node: '>= 10'}
'@mistralai/mistralai@2.2.6':
resolution: {integrity: sha512-W8pX7zHxjJvMIpw8JMxeJEleapXX0Q9NPszdNzqkM3MIEoIGPObdodujj+WHteXEvGfaP/AMwlNyRfEzSY6dQQ==}
peerDependencies:
'@opentelemetry/api': ^1.9.0
peerDependenciesMeta:
'@opentelemetry/api':
optional: true
2026-02-21 03:10:39 +00:00
'@modelcontextprotocol/sdk@1.26.0':
resolution: {integrity: sha512-Y5RmPncpiDtTXDbLKswIJzTqu2hyBKxTNsgKqKclDbhIgg1wgtf1fRuvxgTnRfcnxtvvgbIEcqUOzZrJ6iSReg==}
engines: {node: '>=18'}
peerDependencies:
'@cfworker/json-schema': ^4.1.1
zod: ^3.25 || ^4.0
peerDependenciesMeta:
'@cfworker/json-schema':
optional: true
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
'@monaco-editor/loader@1.7.0':
resolution: {integrity: sha512-gIwR1HrJrrx+vfyOhYmCZ0/JcWqG5kbfG7+d3f/C1LXk2EvzAbHSg3MQ5lO2sMlo9izoAZ04shohfKLVT6crVA==}
'@monaco-editor/react@4.7.0':
resolution: {integrity: sha512-cyzXQCtO47ydzxpQtCGSQGOC8Gk3ZUeBXFAxD+CWXYFo5OqZyZUonFl0DwUlTyAfRHntBfw2p3w4s9R6oe1eCA==}
peerDependencies:
monaco-editor: '>= 0.25.0 < 1'
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
'@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.4':
resolution: {integrity: sha512-LCkGo6JDfaBhgST7UpPWgNgLINpcpabaHfyz5OBx75nUYxBsaEPxjnyNjWpeb/xBup/682QnBfRBy2/LvPutZQ==}
cpu: [arm64]
os: [darwin]
'@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.4':
resolution: {integrity: sha512-zExlW9zUJKZH/tOtVMttwjKa4Xm/3KcNjnE3dPN92uCktwavMxpgCA3MoJK/DOnTWsQgo224OaST27/mPNAf+w==}
cpu: [x64]
os: [darwin]
'@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.4':
resolution: {integrity: sha512-dgX0P/9wGPJeHFBG+ZmhgE6bmtMt7NP5CRBGyyktpopdk/mW4POnrpQsSLtKI1dwpc+pPLuXHDh6vvskyQE/sw==}
cpu: [arm64]
os: [linux]
'@msgpackr-extract/msgpackr-extract-linux-arm@3.0.4':
resolution: {integrity: sha512-Tg3yX65f5GbtXLkrYEHE5oibZG9epyYWas7FogTTEJeDEF9JlXJzKgXaNhT3UXlTOeA+AfZpYZYZ0uPj7Cfquw==}
cpu: [arm]
os: [linux]
'@msgpackr-extract/msgpackr-extract-linux-x64@3.0.4':
resolution: {integrity: sha512-8TNXMEjJc3QEy7R/x1INhgiU+XakDAFUzBhaz7+Rbrs8NH5UQeHQxxmzsSBJGyV6I1jW79undiQm8tOI+D+8FQ==}
cpu: [x64]
os: [linux]
'@msgpackr-extract/msgpackr-extract-win32-x64@3.0.4':
resolution: {integrity: sha512-CmCXPQrkbwExx3j946/PtHWHbYJiCRBRDl4BlkRQcJB/YOwQxJRTpoo7aTsortjgoJ1x7opzTSxn7C+ASSLVjQ==}
cpu: [x64]
os: [win32]
feat(web): bold redesign — Tailwind v4 + shadcn-style primitives + Skills/Proposals/Revisions UI Phase 6 of the Skills + Revisions + Proposals work. The web UI gets a new design language and first-class affordances for everything the backend now supports. ## Visual direction - Tailwind v4 with custom @theme block (oklch tokens). Dark-mode-only (internal tool — light mode doubles QA surface). - Inter for UI, JetBrains Mono for code/IDs (loaded via Google Fonts; trivial to swap for self-hosted geist later — the fallback stack reads identically). - Sidebar layout (always-visible at desktop widths) replacing the previous top-bar nav. Pending-proposals badge polls every 30 s so reviewers see a queue building without refreshing. - Lucide icons throughout. - Spacing and radii on Tailwind defaults. Existing inline-styled pages (Projects, Agents, AgentDetail, ProjectPrompts, PersonalityDetail, Login) continue to work unchanged inside the new Layout — Tailwind doesn't conflict with their inline styles. A follow-up can migrate them incrementally. ## What's added ### Build infra (src/web/) - package.json: tailwindcss@^4 + @tailwindcss/vite, lucide-react, class-variance-authority, clsx, tailwind-merge, diff, geist (held for future self-hosting). - vite.config.ts: registers the @tailwindcss/vite plugin. - src/index.css: Tailwind import + @theme tokens + @layer base. - src/main.tsx: imports index.css. - src/lib/utils.ts: shadcn-style cn() helper. ### shadcn-style primitives (src/components/ui/) Hand-written rather than generated via `npx shadcn` so the repo doesn't depend on a CLI tool that needs interactive runtime: - button.tsx — variants: primary / secondary / ghost / danger / link; sizes: sm / md / lg / icon. - card.tsx — Card + Header/Title/Description/Content/Footer subparts. - badge.tsx — variants: default / info / success / warning / danger / outline. - input.tsx — Input + Textarea + Label. - tabs.tsx — no-dep accessible Tabs (no Radix needed for our use). - separator.tsx — h/v separator with role=separator. ### Diff component (src/components/Diff.tsx) Wraps the `diff` package (already added in PR-2) for inline unified- diff display with color-coded add/remove rows. Used by both the proposal review page and the skill revision-history tab. ### New pages (src/pages/) - Dashboard.tsx — at-a-glance home. Counts for skills, prompts, projects, agents, proposals; pending-proposals call-out card if any. - Skills.tsx — list view, separated into Global vs Project/Agent- scoped sections. - SkillDetail.tsx — name + semver + description; tabs for SKILL.md / Files / Metadata / History. History tab shows revisions with click-to-diff against the live body. - Proposals.tsx — queue with Pending/Approved/Rejected tabs. Pending count is highlighted in amber. - ProposalDetail.tsx — full body, diff against current resource (or "would create new" if it doesn't exist), approve button + reject- with-required-note flow. ### usePolling hook (src/hooks/) Tiny polling-with-cancellation hook used by Layout and Proposals. ### Layout rewrite (src/components/Layout.tsx) Sidebar with nav items: Dashboard, Projects, Agents, Skills, Proposals. Lucide icons. Active-route highlighting via NavLink. Pending-proposals warning badge on the Proposals item. ### Routes (src/App.tsx) New routes: /dashboard, /skills, /skills/:name, /proposals, /proposals/:id. Default redirects to /dashboard. ### API types (src/api.ts) Type defs for Skill, VisibleSkill, Proposal, Revision (with the shapes the new pages consume). ## Tests Existing 7 web tests still pass (Login + api). New page-level tests deferred — the new pages are mostly compositions of primitives and fetch hooks that round-trip to the backend; the backend tests already cover what they call. PR-7 polish can add render-and-click tests if coverage drift surfaces. ## Verification - `pnpm --filter @mcpctl/web build` clean, no warnings. - `pnpm test:run` whole monorepo: 162 test files / 2157 tests green. - Visual smoke deferred — needs a running mcpd to populate the fixtures. Manual smoke tested locally is the next step. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:54:55 +01:00
'@next/env@16.2.5':
resolution: {integrity: sha512-Lb9ElHD2klcyeVD25vW+siPFqz9QMzDUSgvFZNO+dZEKoMHex4viJhVuzBhrXKqb+UKnih7mVYbt50/7KLsSCA==}
'@next/swc-darwin-arm64@16.2.5':
resolution: {integrity: sha512-BW+8PGVmsruomXHsitD8JG6gny9lEdobctjBwvtPF8AKtxGDR7nR35FOl/oK9UAPXBOBm+vx0k8qtpeHOXQMGQ==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [darwin]
'@next/swc-darwin-x64@16.2.5':
resolution: {integrity: sha512-ZoCGnCl9LlQJWmqXrZAUlNxvuNmclvE+7zUif+nDydkkehl9FKxHJ+wxSQMj+C37BYFerKiEdX9s9o02ir975Q==}
engines: {node: '>= 10'}
cpu: [x64]
os: [darwin]
'@next/swc-linux-arm64-gnu@16.2.5':
resolution: {integrity: sha512-AwcZzMChaWkOTZt3vu+2ZMIj8g4dYQY+B8VUVhlFSQ2JtvyZpefyYHTe00D6b6L7BysYw7vl3zsvs9jix8tl5Q==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
'@next/swc-linux-arm64-musl@16.2.5':
resolution: {integrity: sha512-QqMgqWbCBFsfiQ7BF3dUlW8HJy1LWhpcqbTpoHMWA9IV+TnWwDKozQJA5NdIAHjQ00yX2Q7AUkLr/XK4n77q8A==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
'@next/swc-linux-x64-gnu@16.2.5':
resolution: {integrity: sha512-3hzeiFGZtyATVx9pCeuzTshXmh50vHZitqaeZiyJZaUmjQyrfjsVUgS8apOj1vEJCIpKJM/55F45yPAV2kpjsA==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
'@next/swc-linux-x64-musl@16.2.5':
resolution: {integrity: sha512-0mzZV/mAt7Qj2tYNdTB6AqrS8dwng/AQLSYC5Z1YLpZdi2wxqKDPK7RY2RvjB1fXyJfOfdA3l/yTF5yLi+WfuQ==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
'@next/swc-win32-arm64-msvc@16.2.5':
resolution: {integrity: sha512-f/H4nZ2zJBvA8/+HpsB9mNonF9zfQoAU6D0WxJrfzhJDvJLfngVN85oqxUyrDVK99DIFfFYhLpGa5K+c5uotSw==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [win32]
'@next/swc-win32-x64-msvc@16.2.5':
resolution: {integrity: sha512-nuP7DHs4koAojsIxVPkihNgKiRUKtCU65j5X6DAbSy8VBrfT/o90bCLLHPf51JEdOZwZMFzM6e0NiGWfIWjVAg==}
engines: {node: '>= 10'}
cpu: [x64]
os: [win32]
'@npmcli/agent@4.0.2':
resolution: {integrity: sha512-EUEuWAxnL07Sp5/iC/1X6Xj+XThUvnbei9zfRWZdEXa7lss9RTHMhAHBeg+MZ5To9s/gGaSI+UwZTPdYMvKSeg==}
engines: {node: ^20.17.0 || >=22.9.0}
'@npmcli/arborist@9.9.0':
resolution: {integrity: sha512-tzsb1R8mx0k0drlLDT/9ckEYaQHIaWnUti/ci2IaFoQqdqwfmYrc+90p1+QEZC/ocvqcxBep9P1xKw4FbAGofw==}
engines: {node: ^20.17.0 || >=22.9.0}
hasBin: true
'@npmcli/fs@5.0.0':
resolution: {integrity: sha512-7OsC1gNORBEawOa5+j2pXN9vsicaIOH5cPXxoR6fJOmH6/EXpJB2CajXOu1fPRFun2m1lktEFX11+P89hqO/og==}
engines: {node: ^20.17.0 || >=22.9.0}
'@npmcli/git@7.0.2':
resolution: {integrity: sha512-oeolHDjExNAJAnlYP2qzNjMX/Xi9bmu78C9dIGr4xjobrSKbuMYCph8lTzn4vnW3NjIqVmw/f8BCfouqyJXlRg==}
engines: {node: ^20.17.0 || >=22.9.0}
'@npmcli/installed-package-contents@4.0.0':
resolution: {integrity: sha512-yNyAdkBxB72gtZ4GrwXCM0ZUedo9nIbOMKfGjt6Cu6DXf0p8y1PViZAKDC8q8kv/fufx0WTjRBdSlyrvnP7hmA==}
engines: {node: ^20.17.0 || >=22.9.0}
hasBin: true
'@npmcli/map-workspaces@5.0.3':
resolution: {integrity: sha512-o2grssXo1e774E5OtEwwrgoszYRh0lqkJH+Pb9r78UcqdGJRDRfhpM8DvZPjzNLLNYeD/rNbjOKM3Ss5UABROw==}
engines: {node: ^20.17.0 || >=22.9.0}
'@npmcli/metavuln-calculator@9.0.3':
resolution: {integrity: sha512-94GLSYhLXF2t2LAC7pDwLaM4uCARzxShyAQKsirmlNcpidH89VA4/+K1LbJmRMgz5gy65E/QBBWQdUvGLe2Frg==}
engines: {node: ^20.17.0 || >=22.9.0}
'@npmcli/name-from-folder@4.0.0':
resolution: {integrity: sha512-qfrhVlOSqmKM8i6rkNdZzABj8MKEITGFAY+4teqBziksCQAOLutiAxM1wY2BKEd8KjUSpWmWCYxvXr0y4VTlPg==}
engines: {node: ^20.17.0 || >=22.9.0}
'@npmcli/node-gyp@5.0.0':
resolution: {integrity: sha512-uuG5HZFXLfyFKqg8QypsmgLQW7smiRjVc45bqD/ofZZcR/uxEjgQU8qDPv0s9TEeMUiAAU/GC5bR6++UdTirIQ==}
engines: {node: ^20.17.0 || >=22.9.0}
'@npmcli/package-json@7.0.5':
resolution: {integrity: sha512-iVuTlG3ORq2iaVa1IWUxAO/jIp77tUKBhoMjuzYW2kL4MLN1bi/ofqkZ7D7OOwh8coAx1/S2ge0rMdGv8sLSOQ==}
engines: {node: ^20.17.0 || >=22.9.0}
'@npmcli/promise-spawn@9.0.1':
resolution: {integrity: sha512-OLUaoqBuyxeTqUvjA3FZFiXUfYC1alp3Sa99gW3EUDz3tZ3CbXDdcZ7qWKBzicrJleIgucoWamWH1saAmH/l2Q==}
engines: {node: ^20.17.0 || >=22.9.0}
'@npmcli/query@5.0.0':
resolution: {integrity: sha512-8TZWfTQOsODpLqo9SVhVjHovmKXNpevHU0gO9e+y4V4fRIOneiXy0u0sMP9LmS71XivrEWfZWg50ReH4WRT4aQ==}
engines: {node: ^20.17.0 || >=22.9.0}
'@npmcli/redact@4.0.0':
resolution: {integrity: sha512-gOBg5YHMfZy+TfHArfVogwgfBeQnKbbGo3pSUyK/gSI0AVu+pEiDVcKlQb0D8Mg1LNRZILZ6XG8I5dJ4KuAd9Q==}
engines: {node: ^20.17.0 || >=22.9.0}
'@npmcli/run-script@10.0.4':
resolution: {integrity: sha512-mGUWr1uMnf0le2TwfOZY4SFxZGXGfm4Jtay/nwAa2FLNAKXUoUwaGwBMNH36UHPtinWfTSJ3nqFQr0091CxVGg==}
engines: {node: ^20.17.0 || >=22.9.0}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
'@opencode-ai/plugin@1.18.15':
resolution: {integrity: sha512-AY10RtFbzLkf951dbLkSGJdBeddeS6ojbjvqCpWnINedqlj2cK/GF91xWjWnlHpqQZ4GABLPCuoSJx8mGmKvCw==}
peerDependencies:
'@opentui/core': '>=0.4.5'
'@opentui/keymap': '>=0.4.5'
'@opentui/solid': '>=0.4.5'
peerDependenciesMeta:
'@opentui/core':
optional: true
'@opentui/keymap':
optional: true
'@opentui/solid':
optional: true
'@opencode-ai/sdk@1.18.15':
resolution: {integrity: sha512-8sfo9nGiVwesAZW9Wqkvynyn7w4wYaHx1O9qOHpYL65+Bs2XUpHP3kBbZe58gjQydFgk6I74kUF7sqCiPu2arQ==}
'@opentelemetry/api-logs@0.220.0':
resolution: {integrity: sha512-CmVa4ImJ+ynfrPMNaAXHET6Bhb44SwzmfyVJFq9ni2jgXJR/l7C6gfVFddNmHP+ZOkP9cf4f9DBe68qVLTHc9w==}
engines: {node: '>=8.0.0'}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
'@opentelemetry/api@1.9.0':
resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==}
engines: {node: '>=8.0.0'}
'@opentelemetry/api@1.9.1':
resolution: {integrity: sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==}
engines: {node: '>=8.0.0'}
'@opentelemetry/context-async-hooks@2.9.0':
resolution: {integrity: sha512-OQ0vzvbZBiUhjqLnUaoNfYmP8553Crr3aggB4y0ZUi815mZ7idpdJXQmoKdeBKJelYttoBlLSSHubmyw3wvX4w==}
engines: {node: ^18.19.0 || >=20.6.0}
peerDependencies:
'@opentelemetry/api': '>=1.0.0 <1.10.0'
'@opentelemetry/core@2.9.0':
resolution: {integrity: sha512-m2nckMT80NnmjTYSPjJQObBJ+8dgkoajEOUbznL8AHZ3T3yHRk2P7gI1PhEBc1+lOnrYE9UWrWHqJDsmqjmNbw==}
engines: {node: ^18.19.0 || >=20.6.0}
peerDependencies:
'@opentelemetry/api': '>=1.0.0 <1.10.0'
'@opentelemetry/exporter-trace-otlp-grpc@0.220.0':
resolution: {integrity: sha512-bv1xmNhmNwIM6MdUBw4yYuJeVcEViVLk3uD69vOQMwueHBnfyl/u0HnBlB1FNY/Te0UOzJzvcbyR8wN6b+iGbA==}
engines: {node: ^18.19.0 || >=20.6.0}
peerDependencies:
'@opentelemetry/api': ^1.3.0
'@opentelemetry/exporter-zipkin@2.9.0':
resolution: {integrity: sha512-RwINoce2BH8T4obT5pMcAla2sWma1YZvYuaktWmTluQ0PkQdvv5D060rWI1+kawX+J2qBRcMbwrZJJNcMJUauQ==}
engines: {node: ^18.19.0 || >=20.6.0}
peerDependencies:
'@opentelemetry/api': ^1.0.0
'@opentelemetry/instrumentation-grpc@0.220.0':
resolution: {integrity: sha512-U1EF8KKu52XwH2ybUkjVDmaVQZGf3mXirRSw1KJQrOV5aymgJgkPJV7+kRPqawZe0rpVc/BK+pPSyMWuQoyJJQ==}
engines: {node: ^18.19.0 || >=20.6.0}
peerDependencies:
'@opentelemetry/api': ^1.3.0
'@opentelemetry/instrumentation@0.220.0':
resolution: {integrity: sha512-xQx3E2WxP1mDvKzxLxX+CTCtNLa560YJZ3087qYHerl2YmiKpv7AH+dAy7vmx+eVrZ5BwhfWUAVoKOoxCNHcpw==}
engines: {node: ^18.19.0 || >=20.6.0}
peerDependencies:
'@opentelemetry/api': ^1.3.0
'@opentelemetry/otlp-exporter-base@0.220.0':
resolution: {integrity: sha512-CXYo8UD5Mn9YbgebO2EL4wejtA+gxLmLiu6HCk2KH2BR7XhFN6/6p1UlCb23DYCjeYkndevLHuejCCN1yx4+OQ==}
engines: {node: ^18.19.0 || >=20.6.0}
peerDependencies:
'@opentelemetry/api': ^1.3.0
'@opentelemetry/otlp-grpc-exporter-base@0.220.0':
resolution: {integrity: sha512-/eIkBPMBTIvM3x/0mDX4aJeSkYifYClnBPr68PL1h5LV4VQv4+SV6CGrpiZ4fIWDnobVmhTWCm1J/QRdAWUfvA==}
engines: {node: ^18.19.0 || >=20.6.0}
peerDependencies:
'@opentelemetry/api': ^1.3.0
'@opentelemetry/otlp-transformer@0.220.0':
resolution: {integrity: sha512-lXGrv7KXZ0gNH9SVNUaa6vv6phVYGvJxfXAlMbzbakiXru75f5MZl8Z7oqiMMQD77riVHJCFlQvbZs/VVN2/4A==}
engines: {node: ^18.19.0 || >=20.6.0}
peerDependencies:
'@opentelemetry/api': ^1.3.0
'@opentelemetry/resources@2.9.0':
resolution: {integrity: sha512-jyA5MBLQ+Dkl3+JsZkUoUvL7yHvU64kLsvpXKarWm6347Sl1t1bXFTFykUePNpT5WH5pm9a2Qtt03iIYQhZ1Fg==}
engines: {node: ^18.19.0 || >=20.6.0}
peerDependencies:
'@opentelemetry/api': '>=1.3.0 <1.10.0'
'@opentelemetry/sdk-logs@0.220.0':
resolution: {integrity: sha512-WywcTkQtv2iNmt+6y5Kcd4rzvx9bLVsBa2Nwcmg01IUaBTkTow3W4d9KE5vNBpEDtb9tp21WcRBY/lANRrApYA==}
engines: {node: ^18.19.0 || >=20.6.0}
peerDependencies:
'@opentelemetry/api': '>=1.4.0 <1.10.0'
'@opentelemetry/sdk-metrics@2.9.0':
resolution: {integrity: sha512-Xx8RGS4H5XEBl01WuCreMIpiah9cCXMbSkeuIePPdD2cUpq/vUzYmj8E/MK1OsbOc93FuAD4jfn2WOacKwLn7Q==}
engines: {node: ^18.19.0 || >=20.6.0}
peerDependencies:
'@opentelemetry/api': '>=1.9.0 <1.10.0'
'@opentelemetry/sdk-trace-base@2.9.0':
resolution: {integrity: sha512-cp9zmTl62R8PJrpvFcmc8N2JQU/xfa0S+61q511Nji+QxCfZ8Ifvg7H27G8cANe4crg4RTrWsVvanHiXjSp6ag==}
engines: {node: ^18.19.0 || >=20.6.0}
peerDependencies:
'@opentelemetry/api': '>=1.3.0 <1.10.0'
'@opentelemetry/sdk-trace-node@2.9.0':
resolution: {integrity: sha512-ec9a7ps37huy5itYk0MalaZdSLlM6AXWp/FhtEjgMpp5leEGojBDvAl/UWttQnkMZOvFHKzRESn8TD3yKTF5nQ==}
engines: {node: ^18.19.0 || >=20.6.0}
peerDependencies:
'@opentelemetry/api': '>=1.0.0 <1.10.0'
'@opentelemetry/sdk-trace@2.9.0':
resolution: {integrity: sha512-sGA19HvtrrSKYsseHphluH6j3p6Xa3fqc7c7y8f/7mYWejc1lyDFcpSdD1kYa50HCLUeEo4zA5bW0pniaPszuw==}
engines: {node: ^18.19.0 || >=20.6.0}
peerDependencies:
'@opentelemetry/api': '>=1.3.0 <1.10.0'
'@opentelemetry/semantic-conventions@1.43.0':
resolution: {integrity: sha512-eSYWTm620tTk45EKSedaUL8MFYI8hW164hIXsgIHyxu3VobUB3fFCu5t0hQby6OoWRPsG1KkKUG2M5UadiLiVg==}
engines: {node: '>=14'}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
'@opentui/core-darwin-arm64@0.4.5':
resolution: {integrity: sha512-8KUG0oRidnR+oW1RSZJ72/PhZLl+qRRMk5U/mieF4c0SJ5V3tYACpBZAKzQfHNd1f7QzD8FHZct1lPpQgtmkWg==}
cpu: [arm64]
os: [darwin]
'@opentui/core-darwin-x64@0.4.5':
resolution: {integrity: sha512-R2bocsg55gwjOqCp/MWFgFYzRmsduKegB6nzgFAPCvAD/L5Jf30xpWJWFlSg3x8vxe1L9WJ84dfqa4M7mZZ3wA==}
cpu: [x64]
os: [darwin]
'@opentui/core-linux-arm64-musl@0.4.5':
resolution: {integrity: sha512-ieqdyKI6EIYPalYAETB2wsdP83hr5Ifi+dFnBFUmdEEFHsoKwBmn2S7bsTOYlX7Bg03F4/YPIg+IvRpeC+cUJw==}
cpu: [arm64]
os: [linux]
'@opentui/core-linux-arm64@0.4.5':
resolution: {integrity: sha512-R4MZ25a4CzOAGVjW9aj1hUfzQGVfCJwrwBDbNs2SXaIvzcZqkxCVtU4FoQ5LsaD0j/BdNQVg2CIfFkFsm1fDuQ==}
cpu: [arm64]
os: [linux]
'@opentui/core-linux-x64-musl@0.4.5':
resolution: {integrity: sha512-mKVKcIcPiSVVZZsdPSBoWwoa2/TCeQAaMDeHF7PFw2kt5bTXZPP7xxWfRQLCNIcA1eaGl59UuwUWHDR2Ve548Q==}
cpu: [x64]
os: [linux]
'@opentui/core-linux-x64@0.4.5':
resolution: {integrity: sha512-SNyuQoxMKI1vuJhgxSSW96adWM6LqFl2SoS3GM4tGeneGOanVVG2Y06PvlytXvF4cKik97t0rqkVMRetmOs93w==}
cpu: [x64]
os: [linux]
'@opentui/core-win32-arm64@0.4.5':
resolution: {integrity: sha512-GHTTsqeR45q2Iek9Rb7ty+x/hAKn2jZ1ujlCgPR8LBKyF7h0E1dNFryoZ7ehMc3kJndP1sKn836IemKFqxuDdQ==}
cpu: [arm64]
os: [win32]
'@opentui/core-win32-x64@0.4.5':
resolution: {integrity: sha512-Y8T/yXCDGagRGiQrtmuB6AhRcPucKFs/Dre3v8kJwNYqDccI4FzUPKclZ7djfmRZNjl7JUqPhZZP/PwDpQocMg==}
cpu: [x64]
os: [win32]
'@opentui/core@0.4.5':
resolution: {integrity: sha512-JsgRTPkA6e+Vxmumxai6SElOSlRQkbzNKHlCfemlArRiLhfC1IZ9RXJo2QH4xSu+uBOWAM90uss73/pPlkdEig==}
peerDependencies:
web-tree-sitter: 0.25.10
'@opentui/keymap@0.4.5':
resolution: {integrity: sha512-S1wzKHhF70zT6bH+VBFY+lSeTImLcIFW28JNQiME8MoPcy6KGPs7rKFSHrb/U7P8rsTJeRfW5A4d1Cy6PKodDg==}
peerDependencies:
'@opentui/react': 0.4.5
'@opentui/solid': 0.4.5
react: '>=19.2.0'
solid-js: 1.9.12
peerDependenciesMeta:
'@opentui/react':
optional: true
'@opentui/solid':
optional: true
react:
optional: true
solid-js:
optional: true
'@opentui/solid@0.4.5':
resolution: {integrity: sha512-B0RSkXnrtPVfEJOX+Hj+axjLJ3lzbG1BZw5I7Pvb9OPp48Vzg2cW2a3cSa86/q48ndLt647i/XwFPIw/jqnI5g==}
peerDependencies:
solid-js: 1.9.12
2026-02-21 03:10:39 +00:00
'@pinojs/redact@0.4.0':
resolution: {integrity: sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg==}
'@prisma/client@6.19.2':
resolution: {integrity: sha512-gR2EMvfK/aTxsuooaDA32D8v+us/8AAet+C3J1cc04SW35FPdZYgLF+iN4NDLUgAaUGTKdAB0CYenu1TAgGdMg==}
engines: {node: '>=18.18'}
peerDependencies:
prisma: '*'
typescript: '>=5.1.0'
peerDependenciesMeta:
prisma:
optional: true
typescript:
optional: true
'@prisma/config@6.19.2':
resolution: {integrity: sha512-kadBGDl+aUswv/zZMk9Mx0C8UZs1kjao8H9/JpI4Wh4SHZaM7zkTwiKn/iFLfRg+XtOAo/Z/c6pAYhijKl0nzQ==}
'@prisma/debug@6.19.2':
resolution: {integrity: sha512-lFnEZsLdFLmEVCVNdskLDCL8Uup41GDfU0LUfquw+ercJC8ODTuL0WNKgOKmYxCJVvFwf0OuZBzW99DuWmoH2A==}
'@prisma/engines-version@7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7':
resolution: {integrity: sha512-03bgb1VD5gvuumNf+7fVGBzfpJPjmqV423l/WxsWk2cNQ42JD0/SsFBPhN6z8iAvdHs07/7ei77SKu7aZfq8bA==}
'@prisma/engines@6.19.2':
resolution: {integrity: sha512-TTkJ8r+uk/uqczX40wb+ODG0E0icVsMgwCTyTHXehaEfb0uo80M9g1aW1tEJrxmFHeOZFXdI2sTA1j1AgcHi4A==}
'@prisma/fetch-engine@6.19.2':
resolution: {integrity: sha512-h4Ff4Pho+SR1S8XerMCC12X//oY2bG3Iug/fUnudfcXEUnIeRiBdXHFdGlGOgQ3HqKgosTEhkZMvGM9tWtYC+Q==}
'@prisma/get-platform@6.19.2':
resolution: {integrity: sha512-PGLr06JUSTqIvztJtAzIxOwtWKtJm5WwOG6xpsgD37Rc84FpfUBGLKz65YpJBGtkRQGXTYEFie7pYALocC3MtA==}
'@protobufjs/aspromise@1.1.2':
resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==}
'@protobufjs/base64@1.1.2':
resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==}
'@protobufjs/codegen@2.0.4':
resolution: {integrity: sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==}
'@protobufjs/eventemitter@1.1.0':
resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==}
'@protobufjs/fetch@1.1.0':
resolution: {integrity: sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==}
'@protobufjs/float@1.0.2':
resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==}
'@protobufjs/inquire@1.1.0':
resolution: {integrity: sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==}
'@protobufjs/path@1.1.2':
resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==}
'@protobufjs/pool@1.1.0':
resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==}
'@protobufjs/utf8@1.1.0':
resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==}
'@pulumi/pulumi@3.253.0':
resolution: {integrity: sha512-riKRPh6hNCA/NRxVSOLx08c0rqgWYnKGOTgPZzCXi5TglVEERiXHW4U2DaTpP978FI1Xo1iqCa41vmd5i/PNHw==}
engines: {node: '>=22'}
peerDependencies:
ts-node: '>= 7.0.1 < 12'
typescript: '>= 3.8.3 < 7'
peerDependenciesMeta:
ts-node:
optional: true
typescript:
optional: true
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
'@rolldown/pluginutils@1.0.0-rc.3':
resolution: {integrity: sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q==}
2026-02-21 03:10:39 +00:00
'@rollup/rollup-android-arm-eabi@4.58.0':
resolution: {integrity: sha512-mr0tmS/4FoVk1cnaeN244A/wjvGDNItZKR8hRhnmCzygyRXYtKF5jVDSIILR1U97CTzAYmbgIj/Dukg62ggG5w==}
cpu: [arm]
os: [android]
'@rollup/rollup-android-arm64@4.58.0':
resolution: {integrity: sha512-+s++dbp+/RTte62mQD9wLSbiMTV+xr/PeRJEc/sFZFSBRlHPNPVaf5FXlzAL77Mr8FtSfQqCN+I598M8U41ccQ==}
cpu: [arm64]
os: [android]
'@rollup/rollup-darwin-arm64@4.58.0':
resolution: {integrity: sha512-MFWBwTcYs0jZbINQBXHfSrpSQJq3IUOakcKPzfeSznONop14Pxuqa0Kg19GD0rNBMPQI2tFtu3UzapZpH0Uc1Q==}
cpu: [arm64]
os: [darwin]
'@rollup/rollup-darwin-x64@4.58.0':
resolution: {integrity: sha512-yiKJY7pj9c9JwzuKYLFaDZw5gma3fI9bkPEIyofvVfsPqjCWPglSHdpdwXpKGvDeYDms3Qal8qGMEHZ1M/4Udg==}
cpu: [x64]
os: [darwin]
'@rollup/rollup-freebsd-arm64@4.58.0':
resolution: {integrity: sha512-x97kCoBh5MOevpn/CNK9W1x8BEzO238541BGWBc315uOlN0AD/ifZ1msg+ZQB05Ux+VF6EcYqpiagfLJ8U3LvQ==}
cpu: [arm64]
os: [freebsd]
'@rollup/rollup-freebsd-x64@4.58.0':
resolution: {integrity: sha512-Aa8jPoZ6IQAG2eIrcXPpjRcMjROMFxCt1UYPZZtCxRV68WkuSigYtQ/7Zwrcr2IvtNJo7T2JfDXyMLxq5L4Jlg==}
cpu: [x64]
os: [freebsd]
'@rollup/rollup-linux-arm-gnueabihf@4.58.0':
resolution: {integrity: sha512-Ob8YgT5kD/lSIYW2Rcngs5kNB/44Q2RzBSPz9brf2WEtcGR7/f/E9HeHn1wYaAwKBni+bdXEwgHvUd0x12lQSA==}
cpu: [arm]
os: [linux]
'@rollup/rollup-linux-arm-musleabihf@4.58.0':
resolution: {integrity: sha512-K+RI5oP1ceqoadvNt1FecL17Qtw/n9BgRSzxif3rTL2QlIu88ccvY+Y9nnHe/cmT5zbH9+bpiJuG1mGHRVwF4Q==}
cpu: [arm]
os: [linux]
'@rollup/rollup-linux-arm64-gnu@4.58.0':
resolution: {integrity: sha512-T+17JAsCKUjmbopcKepJjHWHXSjeW7O5PL7lEFaeQmiVyw4kkc5/lyYKzrv6ElWRX/MrEWfPiJWqbTvfIvjM1Q==}
cpu: [arm64]
os: [linux]
'@rollup/rollup-linux-arm64-musl@4.58.0':
resolution: {integrity: sha512-cCePktb9+6R9itIJdeCFF9txPU7pQeEHB5AbHu/MKsfH/k70ZtOeq1k4YAtBv9Z7mmKI5/wOLYjQ+B9QdxR6LA==}
cpu: [arm64]
os: [linux]
'@rollup/rollup-linux-loong64-gnu@4.58.0':
resolution: {integrity: sha512-iekUaLkfliAsDl4/xSdoCJ1gnnIXvoNz85C8U8+ZxknM5pBStfZjeXgB8lXobDQvvPRCN8FPmmuTtH+z95HTmg==}
cpu: [loong64]
os: [linux]
'@rollup/rollup-linux-loong64-musl@4.58.0':
resolution: {integrity: sha512-68ofRgJNl/jYJbxFjCKE7IwhbfxOl1muPN4KbIqAIe32lm22KmU7E8OPvyy68HTNkI2iV/c8y2kSPSm2mW/Q9Q==}
cpu: [loong64]
os: [linux]
'@rollup/rollup-linux-ppc64-gnu@4.58.0':
resolution: {integrity: sha512-dpz8vT0i+JqUKuSNPCP5SYyIV2Lh0sNL1+FhM7eLC457d5B9/BC3kDPp5BBftMmTNsBarcPcoz5UGSsnCiw4XQ==}
cpu: [ppc64]
os: [linux]
'@rollup/rollup-linux-ppc64-musl@4.58.0':
resolution: {integrity: sha512-4gdkkf9UJ7tafnweBCR/mk4jf3Jfl0cKX9Np80t5i78kjIH0ZdezUv/JDI2VtruE5lunfACqftJ8dIMGN4oHew==}
cpu: [ppc64]
os: [linux]
'@rollup/rollup-linux-riscv64-gnu@4.58.0':
resolution: {integrity: sha512-YFS4vPnOkDTD/JriUeeZurFYoJhPf9GQQEF/v4lltp3mVcBmnsAdjEWhr2cjUCZzZNzxCG0HZOvJU44UGHSdzw==}
cpu: [riscv64]
os: [linux]
'@rollup/rollup-linux-riscv64-musl@4.58.0':
resolution: {integrity: sha512-x2xgZlFne+QVNKV8b4wwaCS8pwq3y14zedZ5DqLzjdRITvreBk//4Knbcvm7+lWmms9V9qFp60MtUd0/t/PXPw==}
cpu: [riscv64]
os: [linux]
'@rollup/rollup-linux-s390x-gnu@4.58.0':
resolution: {integrity: sha512-jIhrujyn4UnWF8S+DHSkAkDEO3hLX0cjzxJZPLF80xFyzyUIYgSMRcYQ3+uqEoyDD2beGq7Dj7edi8OnJcS/hg==}
cpu: [s390x]
os: [linux]
'@rollup/rollup-linux-x64-gnu@4.58.0':
resolution: {integrity: sha512-+410Srdoh78MKSJxTQ+hZ/Mx+ajd6RjjPwBPNd0R3J9FtL6ZA0GqiiyNjCO9In0IzZkCNrpGymSfn+kgyPQocg==}
cpu: [x64]
os: [linux]
'@rollup/rollup-linux-x64-musl@4.58.0':
resolution: {integrity: sha512-ZjMyby5SICi227y1MTR3VYBpFTdZs823Rs/hpakufleBoufoOIB6jtm9FEoxn/cgO7l6PM2rCEl5Kre5vX0QrQ==}
cpu: [x64]
os: [linux]
'@rollup/rollup-openbsd-x64@4.58.0':
resolution: {integrity: sha512-ds4iwfYkSQ0k1nb8LTcyXw//ToHOnNTJtceySpL3fa7tc/AsE+UpUFphW126A6fKBGJD5dhRvg8zw1rvoGFxmw==}
cpu: [x64]
os: [openbsd]
'@rollup/rollup-openharmony-arm64@4.58.0':
resolution: {integrity: sha512-fd/zpJniln4ICdPkjWFhZYeY/bpnaN9pGa6ko+5WD38I0tTqk9lXMgXZg09MNdhpARngmxiCg0B0XUamNw/5BQ==}
cpu: [arm64]
os: [openharmony]
'@rollup/rollup-win32-arm64-msvc@4.58.0':
resolution: {integrity: sha512-YpG8dUOip7DCz3nr/JUfPbIUo+2d/dy++5bFzgi4ugOGBIox+qMbbqt/JoORwvI/C9Kn2tz6+Bieoqd5+B1CjA==}
cpu: [arm64]
os: [win32]
'@rollup/rollup-win32-ia32-msvc@4.58.0':
resolution: {integrity: sha512-b9DI8jpFQVh4hIXFr0/+N/TzLdpBIoPzjt0Rt4xJbW3mzguV3mduR9cNgiuFcuL/TeORejJhCWiAXe3E/6PxWA==}
cpu: [ia32]
os: [win32]
'@rollup/rollup-win32-x64-gnu@4.58.0':
resolution: {integrity: sha512-CSrVpmoRJFN06LL9xhkitkwUcTZtIotYAF5p6XOR2zW0Zz5mzb3IPpcoPhB02frzMHFNo1reQ9xSF5fFm3hUsQ==}
cpu: [x64]
os: [win32]
'@rollup/rollup-win32-x64-msvc@4.58.0':
resolution: {integrity: sha512-QFsBgQNTnh5K0t/sBsjJLq24YVqEIVkGpfN2VHsnN90soZyhaiA9UUHufcctVNL4ypJY0wrwad0wslx2KJQ1/w==}
cpu: [x64]
os: [win32]
'@sigstore/bundle@4.0.0':
resolution: {integrity: sha512-NwCl5Y0V6Di0NexvkTqdoVfmjTaQwoLM236r89KEojGmq/jMls8S+zb7yOwAPdXvbwfKDlP+lmXgAL4vKSQT+A==}
engines: {node: ^20.17.0 || >=22.9.0}
'@sigstore/core@3.2.1':
resolution: {integrity: sha512-qRsxPnCrbC/puegGxKuynfnxgLiHqWStrSjxkoB4YKqq3Z3s4cyZyj42ZdWFAEblNP65C+rBH8EuREHIXoi83g==}
engines: {node: ^20.17.0 || >=22.9.0}
'@sigstore/protobuf-specs@0.5.1':
resolution: {integrity: sha512-/ScWUhhoFasJsSRGTVBwId1loQjjnjAfE4djL6ZhrXRpNCmPTnUKF5Jokd58ILseOMjzET3UrMOtJPS9sYeI0g==}
engines: {node: ^18.17.0 || >=20.5.0}
'@sigstore/sign@4.1.1':
resolution: {integrity: sha512-Hf4xglukg0XXQ2RiD5vSoLjdPe8OBUPA8XeVjUObheuDcWdYWrnH/BNmxZCzkAy68MzmNCxXLeurJvs6hcP2OQ==}
engines: {node: ^20.17.0 || >=22.9.0}
'@sigstore/tuf@4.0.2':
resolution: {integrity: sha512-TCAzTy0xzdP79EnxSjq9KQ3eaR7+FmudLC6eRKknVKZbV7ZNlGLClAAQb/HMNJ5n2OBNk2GT1tEmU0xuPr+SLQ==}
engines: {node: ^20.17.0 || >=22.9.0}
'@sigstore/verify@3.1.1':
resolution: {integrity: sha512-qv7+G3J2cc6wwFj3yKvXOamzqhMwSk1ogPGmhpS8iXllcPrJaIIBA+4HbttlHVu1pqWTdmaCH/WE7UOC51kdoA==}
engines: {node: ^20.17.0 || >=22.9.0}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
'@silvia-odwyer/photon-node@0.3.4':
resolution: {integrity: sha512-bnly4BKB3KDTFxrUIcgCLbaeVVS8lrAkri1pEzskpmxu9MdfGQTy8b8EgcD83ywD3RPMsIulY8xJH5Awa+t9fA==}
'@smithy/core@3.31.1':
resolution: {integrity: sha512-CyogUINxvi7C7LDsh8Syo6hVJOT9ckz4rG8dRZfTJ8r91HkMY59PnNooaj7WcHyxEkxPfBAmbgztZU+xTo76lg==}
engines: {node: '>=18.0.0'}
'@smithy/credential-provider-imds@4.4.16':
resolution: {integrity: sha512-QfuLWAkLzptffFW980AFeHZFdqds2B64rpEd3uJ6lgs3xVn9QegGMUgUcj+4d7dRrAsya3r58ZKpku97WcFb4w==}
engines: {node: '>=18.0.0'}
'@smithy/fetch-http-handler@5.6.13':
resolution: {integrity: sha512-4fW86pEUOMbrD5nkbyl/tTvPHHWJFbuB2odl6ps9lWfHoXf9HWh3Q/Smh59qH1g7+c/BSZghX6bbUk4gsiMs8A==}
engines: {node: '>=18.0.0'}
'@smithy/is-array-buffer@2.2.0':
resolution: {integrity: sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==}
engines: {node: '>=14.0.0'}
'@smithy/node-http-handler@4.7.3':
resolution: {integrity: sha512-/jPhevcTFPMVl6KNjbaI47iOg1zxC7IsnX4PQDGVZKMFceOXtB8IEYaB7a9VvkP/3oC60WzTeKocvSI7vLT0vA==}
engines: {node: '>=18.0.0'}
'@smithy/node-http-handler@4.9.13':
resolution: {integrity: sha512-Nmd/Nl35zfYrd+a6OO2cDJb3GPh9bgTjIUhcM+JFfjpp8/osCgboDV5nCT1I01Pv6R13eSKDKLSoVa5ZB6Zsfw==}
engines: {node: '>=18.0.0'}
'@smithy/signature-v4@5.6.12':
resolution: {integrity: sha512-I6KLtq3H0qqSuV9vLglfi8puHqzygzWHOnI4z/Rdoo+q50vvo18vBRdPAvvEtcaKROz7Zn6qnPa14kRfPH6PcQ==}
engines: {node: '>=18.0.0'}
'@smithy/types@4.16.1':
resolution: {integrity: sha512-0JFs3V2y2M9tKW5na/qxe69Zv+uxLMO7QBbhxF/FHu/Gp2NFZAAL9tWl9PU02xxo07pb3G9FTyjNc6D5uZrJIg==}
engines: {node: '>=18.0.0'}
'@smithy/util-buffer-from@2.2.0':
resolution: {integrity: sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==}
engines: {node: '>=14.0.0'}
'@smithy/util-utf8@2.3.0':
resolution: {integrity: sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==}
engines: {node: '>=14.0.0'}
2026-02-21 03:10:39 +00:00
'@standard-schema/spec@1.1.0':
resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==}
feat(web): bold redesign — Tailwind v4 + shadcn-style primitives + Skills/Proposals/Revisions UI Phase 6 of the Skills + Revisions + Proposals work. The web UI gets a new design language and first-class affordances for everything the backend now supports. ## Visual direction - Tailwind v4 with custom @theme block (oklch tokens). Dark-mode-only (internal tool — light mode doubles QA surface). - Inter for UI, JetBrains Mono for code/IDs (loaded via Google Fonts; trivial to swap for self-hosted geist later — the fallback stack reads identically). - Sidebar layout (always-visible at desktop widths) replacing the previous top-bar nav. Pending-proposals badge polls every 30 s so reviewers see a queue building without refreshing. - Lucide icons throughout. - Spacing and radii on Tailwind defaults. Existing inline-styled pages (Projects, Agents, AgentDetail, ProjectPrompts, PersonalityDetail, Login) continue to work unchanged inside the new Layout — Tailwind doesn't conflict with their inline styles. A follow-up can migrate them incrementally. ## What's added ### Build infra (src/web/) - package.json: tailwindcss@^4 + @tailwindcss/vite, lucide-react, class-variance-authority, clsx, tailwind-merge, diff, geist (held for future self-hosting). - vite.config.ts: registers the @tailwindcss/vite plugin. - src/index.css: Tailwind import + @theme tokens + @layer base. - src/main.tsx: imports index.css. - src/lib/utils.ts: shadcn-style cn() helper. ### shadcn-style primitives (src/components/ui/) Hand-written rather than generated via `npx shadcn` so the repo doesn't depend on a CLI tool that needs interactive runtime: - button.tsx — variants: primary / secondary / ghost / danger / link; sizes: sm / md / lg / icon. - card.tsx — Card + Header/Title/Description/Content/Footer subparts. - badge.tsx — variants: default / info / success / warning / danger / outline. - input.tsx — Input + Textarea + Label. - tabs.tsx — no-dep accessible Tabs (no Radix needed for our use). - separator.tsx — h/v separator with role=separator. ### Diff component (src/components/Diff.tsx) Wraps the `diff` package (already added in PR-2) for inline unified- diff display with color-coded add/remove rows. Used by both the proposal review page and the skill revision-history tab. ### New pages (src/pages/) - Dashboard.tsx — at-a-glance home. Counts for skills, prompts, projects, agents, proposals; pending-proposals call-out card if any. - Skills.tsx — list view, separated into Global vs Project/Agent- scoped sections. - SkillDetail.tsx — name + semver + description; tabs for SKILL.md / Files / Metadata / History. History tab shows revisions with click-to-diff against the live body. - Proposals.tsx — queue with Pending/Approved/Rejected tabs. Pending count is highlighted in amber. - ProposalDetail.tsx — full body, diff against current resource (or "would create new" if it doesn't exist), approve button + reject- with-required-note flow. ### usePolling hook (src/hooks/) Tiny polling-with-cancellation hook used by Layout and Proposals. ### Layout rewrite (src/components/Layout.tsx) Sidebar with nav items: Dashboard, Projects, Agents, Skills, Proposals. Lucide icons. Active-route highlighting via NavLink. Pending-proposals warning badge on the Proposals item. ### Routes (src/App.tsx) New routes: /dashboard, /skills, /skills/:name, /proposals, /proposals/:id. Default redirects to /dashboard. ### API types (src/api.ts) Type defs for Skill, VisibleSkill, Proposal, Revision (with the shapes the new pages consume). ## Tests Existing 7 web tests still pass (Login + api). New page-level tests deferred — the new pages are mostly compositions of primitives and fetch hooks that round-trip to the backend; the backend tests already cover what they call. PR-7 polish can add render-and-click tests if coverage drift surfaces. ## Verification - `pnpm --filter @mcpctl/web build` clean, no warnings. - `pnpm test:run` whole monorepo: 162 test files / 2157 tests green. - Visual smoke deferred — needs a running mcpd to populate the fixtures. Manual smoke tested locally is the next step. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:54:55 +01:00
'@swc/helpers@0.5.15':
resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==}
'@tailwindcss/node@4.2.4':
resolution: {integrity: sha512-Ai7+yQPxz3ddrDQzFfBKdHEVBg0w3Zl83jnjuwxnZOsnH9pGn93QHQtpU0p/8rYWxvbFZHneni6p1BSLK4DkGA==}
'@tailwindcss/oxide-android-arm64@4.2.4':
resolution: {integrity: sha512-e7MOr1SAn9U8KlZzPi1ZXGZHeC5anY36qjNwmZv9pOJ8E4Q6jmD1vyEHkQFmNOIN7twGPEMXRHmitN4zCMN03g==}
engines: {node: '>= 20'}
cpu: [arm64]
os: [android]
'@tailwindcss/oxide-darwin-arm64@4.2.4':
resolution: {integrity: sha512-tSC/Kbqpz/5/o/C2sG7QvOxAKqyd10bq+ypZNf+9Fi2TvbVbv1zNpcEptcsU7DPROaSbVgUXmrzKhurFvo5eDg==}
engines: {node: '>= 20'}
cpu: [arm64]
os: [darwin]
'@tailwindcss/oxide-darwin-x64@4.2.4':
resolution: {integrity: sha512-yPyUXn3yO/ufR6+Kzv0t4fCg2qNr90jxXc5QqBpjlPNd0NqyDXcmQb/6weunH/MEDXW5dhyEi+agTDiqa3WsGg==}
engines: {node: '>= 20'}
cpu: [x64]
os: [darwin]
'@tailwindcss/oxide-freebsd-x64@4.2.4':
resolution: {integrity: sha512-BoMIB4vMQtZsXdGLVc2z+P9DbETkiopogfWZKbWwM8b/1Vinbs4YcUwo+kM/KeLkX3Ygrf4/PsRndKaYhS8Eiw==}
engines: {node: '>= 20'}
cpu: [x64]
os: [freebsd]
'@tailwindcss/oxide-linux-arm-gnueabihf@4.2.4':
resolution: {integrity: sha512-7pIHBLTHYRAlS7V22JNuTh33yLH4VElwKtB3bwchK/UaKUPpQ0lPQiOWcbm4V3WP2I6fNIJ23vABIvoy2izdwA==}
engines: {node: '>= 20'}
cpu: [arm]
os: [linux]
'@tailwindcss/oxide-linux-arm64-gnu@4.2.4':
resolution: {integrity: sha512-+E4wxJ0ZGOzSH325reXTWB48l42i93kQqMvDyz5gqfRzRZ7faNhnmvlV4EPGJU3QJM/3Ab5jhJ5pCRUsKn6OQw==}
engines: {node: '>= 20'}
cpu: [arm64]
os: [linux]
'@tailwindcss/oxide-linux-arm64-musl@4.2.4':
resolution: {integrity: sha512-bBADEGAbo4ASnppIziaQJelekCxdMaxisrk+fB7Thit72IBnALp9K6ffA2G4ruj90G9XRS2VQ6q2bCKbfFV82g==}
engines: {node: '>= 20'}
cpu: [arm64]
os: [linux]
'@tailwindcss/oxide-linux-x64-gnu@4.2.4':
resolution: {integrity: sha512-7Mx25E4WTfnht0TVRTyC00j3i0M+EeFe7wguMDTlX4mRxafznw0CA8WJkFjWYH5BlgELd1kSjuU2JiPnNZbJDA==}
engines: {node: '>= 20'}
cpu: [x64]
os: [linux]
'@tailwindcss/oxide-linux-x64-musl@4.2.4':
resolution: {integrity: sha512-2wwJRF7nyhOR0hhHoChc04xngV3iS+akccHTGtz965FwF0up4b2lOdo6kI1EbDaEXKgvcrFBYcYQQ/rrnWFVfA==}
engines: {node: '>= 20'}
cpu: [x64]
os: [linux]
'@tailwindcss/oxide-wasm32-wasi@4.2.4':
resolution: {integrity: sha512-FQsqApeor8Fo6gUEklzmaa9994orJZZDBAlQpK2Mq+DslRKFJeD6AjHpBQ0kZFQohVr8o85PPh8eOy86VlSCmw==}
engines: {node: '>=14.0.0'}
cpu: [wasm32]
bundledDependencies:
- '@napi-rs/wasm-runtime'
- '@emnapi/core'
- '@emnapi/runtime'
- '@tybys/wasm-util'
- '@emnapi/wasi-threads'
- tslib
'@tailwindcss/oxide-win32-arm64-msvc@4.2.4':
resolution: {integrity: sha512-L9BXqxC4ToVgwMFqj3pmZRqyHEztulpUJzCxUtLjobMCzTPsGt1Fa9enKbOpY2iIyVtaHNeNvAK8ERP/64sqGQ==}
engines: {node: '>= 20'}
cpu: [arm64]
os: [win32]
'@tailwindcss/oxide-win32-x64-msvc@4.2.4':
resolution: {integrity: sha512-ESlKG0EpVJQwRjXDDa9rLvhEAh0mhP1sF7sap9dNZT0yyl9SAG6T7gdP09EH0vIv0UNTlo6jPWyujD6559fZvw==}
engines: {node: '>= 20'}
cpu: [x64]
os: [win32]
'@tailwindcss/oxide@4.2.4':
resolution: {integrity: sha512-9El/iI069DKDSXwTvB9J4BwdO5JhRrOweGaK25taBAvBXyXqJAX+Jqdvs8r8gKpsI/1m0LeJLyQYTf/WLrBT1Q==}
engines: {node: '>= 20'}
'@tailwindcss/vite@4.2.4':
resolution: {integrity: sha512-pCvohwOCspk3ZFn6eJzrrX3g4n2JY73H6MmYC87XfGPyTty4YsCjYTMArRZm/zOI8dIt3+EcrLHAFPe5A4bgtw==}
peerDependencies:
vite: ^5.2.0 || ^6 || ^7 || ^8
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
'@testing-library/dom@10.4.1':
resolution: {integrity: sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==}
engines: {node: '>=18'}
'@testing-library/jest-dom@6.9.1':
resolution: {integrity: sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==}
engines: {node: '>=14', npm: '>=6', yarn: '>=1'}
'@testing-library/react@16.3.2':
resolution: {integrity: sha512-XU5/SytQM+ykqMnAnvB2umaJNIOsLF3PVv//1Ew4CTcpz0/BRyy/af40qqrt7SjKpDdT1saBMc42CUok5gaw+g==}
engines: {node: '>=18'}
peerDependencies:
'@testing-library/dom': ^10.0.0
'@types/react': ^18.0.0 || ^19.0.0
'@types/react-dom': ^18.0.0 || ^19.0.0
react: ^18.0.0 || ^19.0.0
react-dom: ^18.0.0 || ^19.0.0
peerDependenciesMeta:
'@types/react':
optional: true
'@types/react-dom':
optional: true
'@tufjs/canonical-json@2.0.0':
resolution: {integrity: sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA==}
engines: {node: ^16.14.0 || >=18.0.0}
'@tufjs/models@4.1.0':
resolution: {integrity: sha512-Y8cK9aggNRsqJVaKUlEYs4s7CvQ1b1ta2DVPyAimb0I2qhzjNk+A+mxvll/klL0RlfuIUei8BF7YWiua4kQqww==}
engines: {node: ^20.17.0 || >=22.9.0}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
'@types/aria-query@5.0.4':
resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==}
'@types/babel__core@7.20.5':
resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==}
'@types/babel__generator@7.27.0':
resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==}
'@types/babel__template@7.4.4':
resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==}
'@types/babel__traverse@7.28.0':
resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==}
'@types/bcrypt@5.0.2':
resolution: {integrity: sha512-6atioO8Y75fNcbmj0G7UjI9lXN2pQ/IGJ2FWT4a/btd0Lk9lQalHLKhkgKVZ3r+spnmWUKfbMi1GEe9wyHQfNQ==}
2026-02-21 03:10:39 +00:00
'@types/chai@5.2.3':
resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==}
'@types/deep-eql@4.0.2':
resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==}
feat(mcpd): ResourceRevision + ResourceProposal services + Prompt revision integration Phase 2 of the Skills + Revisions + Proposals work. Stands up the generic revision/proposal layer and wires Prompt into it. Skills will plug into the same infrastructure in PR-3 with no further service changes required. This PR is intentionally additive: PromptRequest table and routes are unchanged. The /api/v1/proposals API runs side-by-side with the legacy /api/v1/promptrequests API. The PromptRequest cutover (rename + backfill + mcplocal rewire) is deferred to a later PR so this one stays reviewable. ## What's added ### Repositories (src/mcpd/src/repositories/) - resource-revision.repository.ts — append-only revision log keyed by (resourceType, resourceId). Soft FK; no relations declared. Supports history listing, semver lookup, and contentHash cross-resource search. - resource-proposal.repository.ts — generic propose queue. Status lifecycle pending → approved | rejected. Mirrors Prompt's `?? ''` workaround for nullable-FK compound lookups. ### Services (src/mcpd/src/services/) - resource-revision.service.ts — record() inserts a revision with a stable sha256 contentHash computed from canonicalised JSON (key-sorted at every level so reordered objects produce the same hash). Caller passes a pre-computed semver; service does NOT decide bump policy. - resource-proposal.service.ts — propose / approve / reject / list, with a per-resourceType handler registry. PromptService registers the 'prompt' handler at construction; the SkillService will register 'skill' in PR-3. approve() runs in a Prisma $transaction so the resource update + revision insert + proposal status flip are atomic. ### Pure utility (src/mcpd/src/utils/semver.ts) - bumpSemver(current, kind) for major / minor / patch - compareSemver(a, b) — numeric, not lex (10 > 9) - isValidSemver(s) - Invalid input falls back to '0.1.0' rather than throwing — keeps the audit-write path from blowing up the prompt update if a row's semver ever drifts out of MAJOR.MINOR.PATCH shape. ### Routes (src/mcpd/src/routes/) - revisions.ts — GET /api/v1/revisions?resourceType=&resourceId=, GET /api/v1/revisions/:id, GET /api/v1/revisions/:id/diff?against=<id|live> (unified-format diff via the `diff` package), and POST /api/v1/prompts/:id/restore-revision { revisionId, note? }. - proposals.ts — GET / POST /api/v1/proposals, GET /api/v1/proposals/:id, PUT for body updates, POST .../approve and POST .../reject, plus DELETE. ## What's changed - PromptService.create / update now record a ResourceRevision when the revision service is wired. Update auto-bumps patch on content change; authors can override via `--bump major|minor|patch` or `--semver X.Y.Z` on the CLI (forwarded into the PUT body). Best-effort: revision write failures are swallowed so the prompt save still succeeds (revision is audit, not source of truth). - PromptService.setProposalService registers a 'prompt' approval handler with the proposal service. Approval runs in a Prisma transaction: upsert prompt → record revision → update currentRevisionId → flip proposal status. semver bumps to 0.1.0 on first approval, patch thereafter. - New CLI flags on `mcpctl edit prompt`: --bump, --semver, --note. They're prompt-only (validated client-side); other resources reject them. - Aliases in shared.ts: `proposal`/`prop` → proposals, `revision`/`rev` → revisions. - diff dependency added to mcpd. ## Tests - src/mcpd/tests/utils/semver.test.ts — covers bump/compare/validate including numeric (not lex) semver compare and invalid-input fallback. - prompt-service.test.ts updated: makePrompt fixture now sets semver + agentId + currentRevisionId; updatePrompt assertion expects the auto-bumped patch in the same update call. - prompt-routes.test.ts updated symmetrically. ## RBAC `proposals` and `revisions` URL segments map to the existing `prompts` permission for now. PR-7 may split if a "reviewer" role becomes useful. ## Verification Full suite: 158 test files / 2127 tests green. `pnpm build` clean across all 6 workspace packages. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 00:38:35 +01:00
'@types/diff@5.2.3':
resolution: {integrity: sha512-K0Oqlrq3kQMaO2RhfrNQX5trmt+XLyom88zS0u84nnIcLvFnRUMRRHmrGny5GSM+kNO9IZLARsdQHDzkhAgmrQ==}
'@types/diff@8.0.0':
resolution: {integrity: sha512-o7jqJM04gfaYrdCecCVMbZhNdG6T1MHg/oQoRFdERLV+4d+V7FijhiEAbFu0Usww84Yijk9yH58U4Jk4HbtzZw==}
deprecated: This is a stub types definition. diff provides its own type definitions, so you do not need this installed.
'@types/docker-modem@3.0.6':
resolution: {integrity: sha512-yKpAGEuKRSS8wwx0joknWxsmLha78wNMe9R2S3UNsVOkZded8UqOrV8KoeDXoXsjndxwyF3eIhyClGbO1SEhEg==}
'@types/dockerode@4.0.1':
resolution: {integrity: sha512-cmUpB+dPN955PxBEuXE3f6lKO1hHiIGYJA46IVF3BJpNsZGvtBDcRnlrHYHtOH/B6vtDOyl2kZ2ShAu3mgc27Q==}
2026-02-21 03:10:39 +00:00
'@types/esrecurse@4.3.1':
resolution: {integrity: sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==}
'@types/estree@1.0.8':
resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==}
'@types/google-protobuf@3.15.12':
resolution: {integrity: sha512-40um9QqwHjRS92qnOaDpL7RmDK15NuZYo9HihiJRbYkMQZlWnuH8AdvbMy8/o6lgLmKbDUKa+OALCltHdbOTpQ==}
'@types/js-yaml@4.0.9':
resolution: {integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==}
2026-02-21 03:10:39 +00:00
'@types/json-schema@7.0.15':
resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
'@types/node-fetch@2.6.13':
resolution: {integrity: sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw==}
'@types/node@18.19.130':
resolution: {integrity: sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg==}
'@types/node@24.12.2':
resolution: {integrity: sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g==}
'@types/node@25.3.0':
resolution: {integrity: sha512-4K3bqJpXpqfg2XKGK9bpDTc6xO/xoUP/RBWS7AtRMug6zZFaRekiLzjVtAoZMquxoAbzBvy5nxQ7veS5eYzf8A==}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
'@types/react-dom@19.2.3':
resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==}
peerDependencies:
'@types/react': ^19.2.0
'@types/react@19.2.14':
resolution: {integrity: sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
'@types/retry@0.12.0':
resolution: {integrity: sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==}
'@types/semver@7.7.1':
resolution: {integrity: sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA==}
'@types/ssh2@1.15.5':
resolution: {integrity: sha512-N1ASjp/nXH3ovBHddRJpli4ozpk6UdDYIX4RJWFa9L1YKnzdhTlVmiGHm4DZnj/jLbqZpes4aeR30EFGQtvhQQ==}
'@types/stream-buffers@3.0.8':
resolution: {integrity: sha512-J+7VaHKNvlNPJPEJXX/fKa9DZtR/xPMwuIbe+yNOwp1YB+ApUOBv2aUpEoBJEi8nJgbgs1x8e73ttg0r1rSUdw==}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
'@types/trusted-types@2.0.7':
resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==}
2026-02-21 03:10:39 +00:00
'@typescript-eslint/eslint-plugin@8.56.0':
resolution: {integrity: sha512-lRyPDLzNCuae71A3t9NEINBiTn7swyOhvUj3MyUOxb8x6g6vPEFoOU+ZRmGMusNC3X3YMhqMIX7i8ShqhT74Pw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
'@typescript-eslint/parser': ^8.56.0
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
typescript: '>=4.8.4 <6.0.0'
'@typescript-eslint/parser@8.56.0':
resolution: {integrity: sha512-IgSWvLobTDOjnaxAfDTIHaECbkNlAlKv2j5SjpB2v7QHKv1FIfjwMy8FsDbVfDX/KjmCmYICcw7uGaXLhtsLNg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
typescript: '>=4.8.4 <6.0.0'
'@typescript-eslint/project-service@8.56.0':
resolution: {integrity: sha512-M3rnyL1vIQOMeWxTWIW096/TtVP+8W3p/XnaFflhmcFp+U4zlxUxWj4XwNs6HbDeTtN4yun0GNTTDBw/SvufKg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
typescript: '>=4.8.4 <6.0.0'
'@typescript-eslint/scope-manager@8.56.0':
resolution: {integrity: sha512-7UiO/XwMHquH+ZzfVCfUNkIXlp/yQjjnlYUyYz7pfvlK3/EyyN6BK+emDmGNyQLBtLGaYrTAI6KOw8tFucWL2w==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@typescript-eslint/tsconfig-utils@8.56.0':
resolution: {integrity: sha512-bSJoIIt4o3lKXD3xmDh9chZcjCz5Lk8xS7Rxn+6l5/pKrDpkCwtQNQQwZ2qRPk7TkUYhrq3WPIHXOXlbXP0itg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
typescript: '>=4.8.4 <6.0.0'
'@typescript-eslint/type-utils@8.56.0':
resolution: {integrity: sha512-qX2L3HWOU2nuDs6GzglBeuFXviDODreS58tLY/BALPC7iu3Fa+J7EOTwnX9PdNBxUI7Uh0ntP0YWGnxCkXzmfA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
typescript: '>=4.8.4 <6.0.0'
'@typescript-eslint/types@8.56.0':
resolution: {integrity: sha512-DBsLPs3GsWhX5HylbP9HNG15U0bnwut55Lx12bHB9MpXxQ+R5GC8MwQe+N1UFXxAeQDvEsEDY6ZYwX03K7Z6HQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@typescript-eslint/typescript-estree@8.56.0':
resolution: {integrity: sha512-ex1nTUMWrseMltXUHmR2GAQ4d+WjkZCT4f+4bVsps8QEdh0vlBsaCokKTPlnqBFqqGaxilDNJG7b8dolW2m43Q==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
typescript: '>=4.8.4 <6.0.0'
'@typescript-eslint/utils@8.56.0':
resolution: {integrity: sha512-RZ3Qsmi2nFGsS+n+kjLAYDPVlrzf7UhTffrDIKr+h2yzAlYP/y5ZulU0yeDEPItos2Ph46JAL5P/On3pe7kDIQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
typescript: '>=4.8.4 <6.0.0'
'@typescript-eslint/visitor-keys@8.56.0':
resolution: {integrity: sha512-q+SL+b+05Ud6LbEE35qe4A99P+htKTKVbyiNEe45eCbJFyh/HVK9QXwlrbz+Q4L8SOW4roxSVwXYj4DMBT7Ieg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
'@vitejs/plugin-react@5.2.0':
resolution: {integrity: sha512-YmKkfhOAi3wsB1PhJq5Scj3GXMn3WvtQ/JC0xoopuHoXSdmtdStOpFrYaT1kie2YgFBcIe64ROzMYRjCrYOdYw==}
engines: {node: ^20.19.0 || >=22.12.0}
peerDependencies:
vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0
2026-02-21 03:10:39 +00:00
'@vitest/coverage-v8@4.0.18':
resolution: {integrity: sha512-7i+N2i0+ME+2JFZhfuz7Tg/FqKtilHjGyGvoHYQ6iLV0zahbsJ9sljC9OcFcPDbhYKCet+sG8SsVqlyGvPflZg==}
peerDependencies:
'@vitest/browser': 4.0.18
vitest: 4.0.18
peerDependenciesMeta:
'@vitest/browser':
optional: true
'@vitest/expect@4.0.18':
resolution: {integrity: sha512-8sCWUyckXXYvx4opfzVY03EOiYVxyNrHS5QxX3DAIi5dpJAAkyJezHCP77VMX4HKA2LDT/Jpfo8i2r5BE3GnQQ==}
'@vitest/mocker@4.0.18':
resolution: {integrity: sha512-HhVd0MDnzzsgevnOWCBj5Otnzobjy5wLBe4EdeeFGv8luMsGcYqDuFRMcttKWZA5vVO8RFjexVovXvAM4JoJDQ==}
peerDependencies:
msw: ^2.4.9
vite: ^6.0.0 || ^7.0.0-0
peerDependenciesMeta:
msw:
optional: true
vite:
optional: true
'@vitest/pretty-format@4.0.18':
resolution: {integrity: sha512-P24GK3GulZWC5tz87ux0m8OADrQIUVDPIjjj65vBXYG17ZeU3qD7r+MNZ1RNv4l8CGU2vtTRqixrOi9fYk/yKw==}
'@vitest/runner@4.0.18':
resolution: {integrity: sha512-rpk9y12PGa22Jg6g5M3UVVnTS7+zycIGk9ZNGN+m6tZHKQb7jrP7/77WfZy13Y/EUDd52NDsLRQhYKtv7XfPQw==}
'@vitest/snapshot@4.0.18':
resolution: {integrity: sha512-PCiV0rcl7jKQjbgYqjtakly6T1uwv/5BQ9SwBLekVg/EaYeQFPiXcgrC2Y7vDMA8dM1SUEAEV82kgSQIlXNMvA==}
'@vitest/spy@4.0.18':
resolution: {integrity: sha512-cbQt3PTSD7P2OARdVW3qWER5EGq7PHlvE+QfzSC0lbwO+xnt7+XH06ZzFjFRgzUX//JmpxrCu92VdwvEPlWSNw==}
'@vitest/utils@4.0.18':
resolution: {integrity: sha512-msMRKLMVLWygpK3u2Hybgi4MNjcYJvwTb0Ru09+fOyCXIgT5raYP041DRRdiJiI3k/2U6SEbAETB3YtBrUkCFA==}
abbrev@1.1.1:
resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==}
abbrev@4.0.0:
resolution: {integrity: sha512-a1wflyaL0tHtJSmLSOVybYhy22vRih4eduhhrkcjgrWGnRfrZtovJ2FRjxuTtkkj47O/baf0R86QU5OuYpz8fA==}
engines: {node: ^20.17.0 || >=22.9.0}
2026-02-21 03:10:39 +00:00
abstract-logging@2.0.1:
resolution: {integrity: sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==}
accepts@2.0.0:
resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==}
engines: {node: '>= 0.6'}
acorn-jsx@5.3.2:
resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
peerDependencies:
acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
acorn@8.16.0:
resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==}
engines: {node: '>=0.4.0'}
hasBin: true
agent-base@6.0.2:
resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==}
engines: {node: '>= 6.0.0'}
agent-base@7.1.4:
resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==}
engines: {node: '>= 14'}
2026-02-21 03:10:39 +00:00
ajv-formats@3.0.1:
resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==}
peerDependencies:
ajv: ^8.0.0
peerDependenciesMeta:
ajv:
optional: true
ajv@6.14.0:
resolution: {integrity: sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==}
ajv@8.18.0:
resolution: {integrity: sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==}
ansi-escapes@7.3.0:
resolution: {integrity: sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==}
engines: {node: '>=18'}
2026-02-21 03:10:39 +00:00
ansi-regex@5.0.1:
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
engines: {node: '>=8'}
ansi-regex@6.2.2:
resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==}
engines: {node: '>=12'}
2026-02-21 03:10:39 +00:00
ansi-styles@4.3.0:
resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
engines: {node: '>=8'}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
ansi-styles@5.2.0:
resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==}
engines: {node: '>=10'}
ansi-styles@6.2.3:
resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==}
engines: {node: '>=12'}
aproba@2.1.0:
resolution: {integrity: sha512-tLIEcj5GuR2RSTnxNKdkK0dJ/GrC7P38sUkiDmDuHfsHmbagTFAxDVIBltoklXEVIQ/f14IL8IMJ5pn9Hez1Ew==}
are-we-there-yet@2.0.0:
resolution: {integrity: sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==}
engines: {node: '>=10'}
deprecated: This package is no longer supported.
2026-02-21 03:10:39 +00:00
argparse@2.0.1:
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
aria-query@5.3.0:
resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==}
aria-query@5.3.2:
resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==}
engines: {node: '>= 0.4'}
asn1@0.2.6:
resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==}
2026-02-21 03:10:39 +00:00
assertion-error@2.0.1:
resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==}
engines: {node: '>=12'}
ast-v8-to-istanbul@0.3.11:
resolution: {integrity: sha512-Qya9fkoofMjCBNVdWINMjB5KZvkYfaO9/anwkWnjxibpWUxo5iHl2sOdP7/uAqaRuUYuoo8rDwnbaaKVFxoUvw==}
asynckit@0.4.0:
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
2026-02-21 03:10:39 +00:00
atomic-sleep@1.0.0:
resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==}
engines: {node: '>=8.0.0'}
auto-bind@5.0.1:
resolution: {integrity: sha512-ooviqdwwgfIfNmDwo94wlshcdzfO64XV0Cg6oDsDYBJfITDz1EngD2z7DkbvCWn+XIMsIqW27sEVF6qcpJrRcg==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
2026-02-21 03:10:39 +00:00
avvio@9.2.0:
resolution: {integrity: sha512-2t/sy01ArdHHE0vRH5Hsay+RtCZt3dLPji7W7/MMOCEgze5b7SNDC4j5H6FnVgPkI1MTNFGzHdHrVXDDl7QSSQ==}
b4a@1.8.0:
resolution: {integrity: sha512-qRuSmNSkGQaHwNbM7J78Wwy+ghLEYF1zNrSeMxj4Kgw6y33O3mXcQ6Ie9fRvfU/YnxWkOchPXbaLb73TkIsfdg==}
peerDependencies:
react-native-b4a: '*'
peerDependenciesMeta:
react-native-b4a:
optional: true
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
babel-plugin-jsx-dom-expressions@0.40.7:
resolution: {integrity: sha512-/O6JWUmjv03OI9lL2ry9bUjpD5S3PclM55RRJEyCdcFZ5W2SEA/59d+l2hNsk3gI6kiWRdRPdOtqZmsQzFN1pQ==}
peerDependencies:
'@babel/core': ^7.20.12
babel-plugin-module-resolver@5.0.2:
resolution: {integrity: sha512-9KtaCazHee2xc0ibfqsDeamwDps6FZNo5S0Q81dUqEuFzVwPhcT4J5jOqIVvgCA3Q/wO9hKYxN/Ds3tIsp5ygg==}
babel-preset-solid@1.9.12:
resolution: {integrity: sha512-LLqnuKVDlKpyBlMPcH6qEvs/wmS9a+NczppxJ3ryS/c0O5IiSFOIBQi9GzyiGDSbcJpx4Gr87jyFTos1MyEuWg==}
peerDependencies:
'@babel/core': ^7.0.0
solid-js: ^1.9.12
peerDependenciesMeta:
solid-js:
optional: true
2026-02-21 03:10:39 +00:00
balanced-match@1.0.2:
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
balanced-match@4.0.3:
resolution: {integrity: sha512-1pHv8LX9CpKut1Zp4EXey7Z8OfH11ONNH6Dhi2WDUt31VVZFXZzKwXcysBgqSumFCmR+0dqjMK5v5JiFHzi0+g==}
engines: {node: 20 || >=22}
bare-events@2.8.2:
resolution: {integrity: sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==}
peerDependencies:
bare-abort-controller: '*'
peerDependenciesMeta:
bare-abort-controller:
optional: true
bare-fs@4.6.0:
resolution: {integrity: sha512-2YkS7NuiJceSEbyEOdSNLE9tsGd+f4+f7C+Nik/MCk27SYdwIMPT/yRKvg++FZhQXgk0KWJKJyXX9RhVV0RGqA==}
engines: {bare: '>=1.16.0'}
peerDependencies:
bare-buffer: '*'
peerDependenciesMeta:
bare-buffer:
optional: true
bare-os@3.8.7:
resolution: {integrity: sha512-G4Gr1UsGeEy2qtDTZwL7JFLo2wapUarz7iTMcYcMFdS89AIQuBoyjgXZz0Utv7uHs3xA9LckhVbeBi8lEQrC+w==}
engines: {bare: '>=1.14.0'}
bare-path@3.0.0:
resolution: {integrity: sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==}
bare-stream@2.12.0:
resolution: {integrity: sha512-w28i8lkBgREV3rPXGbgK+BO66q+ZpKqRWrZLiCdmmUlLPrQ45CzkvRhN+7lnv00Gpi2zy5naRxnUFAxCECDm9g==}
peerDependencies:
bare-abort-controller: '*'
bare-buffer: '*'
bare-events: '*'
peerDependenciesMeta:
bare-abort-controller:
optional: true
bare-buffer:
optional: true
bare-events:
optional: true
bare-url@2.4.0:
resolution: {integrity: sha512-NSTU5WN+fy/L0DDenfE8SXQna4voXuW0FHM7wH8i3/q9khUSchfPbPezO4zSFMnDGIf9YE+mt/RWhZgNRKRIXA==}
base64-js@1.5.1:
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
baseline-browser-mapping@2.10.23:
resolution: {integrity: sha512-xwVXGqevyKPsiuQdLj+dZMVjidjJV508TBqexND5HrF89cGdCYCJFB3qhcxRHSeMctdCfbR1jrxBajhDy7o29g==}
engines: {node: '>=6.0.0'}
hasBin: true
bcrypt-pbkdf@1.0.2:
resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==}
bcrypt@5.1.1:
resolution: {integrity: sha512-AGBHOG5hPYZ5Xl9KXzU5iKq9516yEmvCKDg3ecP5kX2aB6UqTeXZxk2ELnDgDm6BQSMlLt9rDB4LoSMx0rYwww==}
engines: {node: '>= 10.0.0'}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
bidi-js@1.0.3:
resolution: {integrity: sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
bignumber.js@9.3.1:
resolution: {integrity: sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==}
bin-links@6.0.2:
resolution: {integrity: sha512-frE1t78WOwJ45PKV2cF2tNPjTcs9L1J9s6VkrV59wanRP4GlaomuxYPVma7BwthMg8WnfSory4w5PTE6FZZ81w==}
engines: {node: ^20.17.0 || >=22.9.0}
bl@4.1.0:
resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==}
2026-02-21 03:10:39 +00:00
body-parser@2.2.2:
resolution: {integrity: sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==}
engines: {node: '>=18'}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
bowser@2.14.1:
resolution: {integrity: sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==}
brace-expansion@1.1.12:
resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==}
2026-02-21 03:10:39 +00:00
brace-expansion@2.0.2:
resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==}
brace-expansion@5.0.2:
resolution: {integrity: sha512-Pdk8c9poy+YhOgVWw1JNN22/HcivgKWwpxKq04M/jTmHyCZn12WPJebZxdjSa5TmBqISrUSgNYU3eRORljfCCw==}
engines: {node: 20 || >=22}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
brace-expansion@5.0.9:
resolution: {integrity: sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==}
engines: {node: 20 || >=22}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
browserslist@4.28.2:
resolution: {integrity: sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==}
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
hasBin: true
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
buffer-equal-constant-time@1.0.1:
resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==}
buffer-from@1.1.2:
resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
buffer@5.7.1:
resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==}
buildcheck@0.0.7:
resolution: {integrity: sha512-lHblz4ahamxpTmnsk+MNTRWsjYKv965MwOrSJyeD588rR3Jcu7swE+0wN5F+PbL5cjgu/9ObkhfzEPuofEMwLA==}
engines: {node: '>=10.0.0'}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
bun-ffi-structs@0.2.4:
resolution: {integrity: sha512-AJzsqoVFs1KBbJbWHIYrVZLDC3NhTqqh25awRXqzoLzmBAKr5oqk6+CwuYHAekKx+VBCYVohBoKuRq40dV+TYg==}
peerDependencies:
typescript: ^5
2026-02-21 03:10:39 +00:00
bytes@3.1.2:
resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==}
engines: {node: '>= 0.8'}
c12@3.1.0:
resolution: {integrity: sha512-uWoS8OU1MEIsOv8p/5a82c3H31LsWVR5qiyXVfBNOzfffjUWtPnhAb4BYI2uG2HfGmZmFjCtui5XNWaps+iFuw==}
peerDependencies:
magicast: ^0.3.5
peerDependenciesMeta:
magicast:
optional: true
cacache@20.0.4:
resolution: {integrity: sha512-M3Lab8NPYlZU2exsL3bMVvMrMqgwCnMWfdZbK28bn3pK6APT/Te/I8hjRPNu1uwORY9a1eEQoifXbKPQMfMTOA==}
engines: {node: ^20.17.0 || >=22.9.0}
2026-02-21 03:10:39 +00:00
call-bind-apply-helpers@1.0.2:
resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==}
engines: {node: '>= 0.4'}
call-bound@1.0.4:
resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==}
engines: {node: '>= 0.4'}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
caniuse-lite@1.0.30001791:
resolution: {integrity: sha512-yk0l/YSrOnFZk3UROpDLQD9+kC1l4meK/wed583AXrzoarMGJcbRi2Q4RaUYbKxYAsZ8sWmaSa/DsLmdBeI1vQ==}
2026-02-21 03:10:39 +00:00
chai@6.2.2:
resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==}
engines: {node: '>=18'}
chalk@5.6.2:
resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==}
engines: {node: ^12.17.0 || ^14.13 || >=16.0.0}
chardet@2.1.1:
resolution: {integrity: sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==}
chokidar@4.0.3:
resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==}
engines: {node: '>= 14.16.0'}
chownr@1.1.4:
resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==}
chownr@2.0.0:
resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==}
engines: {node: '>=10'}
chownr@3.0.0:
resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==}
engines: {node: '>=18'}
2026-02-21 03:10:39 +00:00
citty@0.1.6:
resolution: {integrity: sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==}
citty@0.2.1:
resolution: {integrity: sha512-kEV95lFBhQgtogAPlQfJJ0WGVSokvLr/UEoFPiKKOXF7pl98HfUVUD0ejsuTCld/9xH9vogSywZ5KqHzXrZpqg==}
cjs-module-lexer@2.2.0:
resolution: {integrity: sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ==}
feat(web): bold redesign — Tailwind v4 + shadcn-style primitives + Skills/Proposals/Revisions UI Phase 6 of the Skills + Revisions + Proposals work. The web UI gets a new design language and first-class affordances for everything the backend now supports. ## Visual direction - Tailwind v4 with custom @theme block (oklch tokens). Dark-mode-only (internal tool — light mode doubles QA surface). - Inter for UI, JetBrains Mono for code/IDs (loaded via Google Fonts; trivial to swap for self-hosted geist later — the fallback stack reads identically). - Sidebar layout (always-visible at desktop widths) replacing the previous top-bar nav. Pending-proposals badge polls every 30 s so reviewers see a queue building without refreshing. - Lucide icons throughout. - Spacing and radii on Tailwind defaults. Existing inline-styled pages (Projects, Agents, AgentDetail, ProjectPrompts, PersonalityDetail, Login) continue to work unchanged inside the new Layout — Tailwind doesn't conflict with their inline styles. A follow-up can migrate them incrementally. ## What's added ### Build infra (src/web/) - package.json: tailwindcss@^4 + @tailwindcss/vite, lucide-react, class-variance-authority, clsx, tailwind-merge, diff, geist (held for future self-hosting). - vite.config.ts: registers the @tailwindcss/vite plugin. - src/index.css: Tailwind import + @theme tokens + @layer base. - src/main.tsx: imports index.css. - src/lib/utils.ts: shadcn-style cn() helper. ### shadcn-style primitives (src/components/ui/) Hand-written rather than generated via `npx shadcn` so the repo doesn't depend on a CLI tool that needs interactive runtime: - button.tsx — variants: primary / secondary / ghost / danger / link; sizes: sm / md / lg / icon. - card.tsx — Card + Header/Title/Description/Content/Footer subparts. - badge.tsx — variants: default / info / success / warning / danger / outline. - input.tsx — Input + Textarea + Label. - tabs.tsx — no-dep accessible Tabs (no Radix needed for our use). - separator.tsx — h/v separator with role=separator. ### Diff component (src/components/Diff.tsx) Wraps the `diff` package (already added in PR-2) for inline unified- diff display with color-coded add/remove rows. Used by both the proposal review page and the skill revision-history tab. ### New pages (src/pages/) - Dashboard.tsx — at-a-glance home. Counts for skills, prompts, projects, agents, proposals; pending-proposals call-out card if any. - Skills.tsx — list view, separated into Global vs Project/Agent- scoped sections. - SkillDetail.tsx — name + semver + description; tabs for SKILL.md / Files / Metadata / History. History tab shows revisions with click-to-diff against the live body. - Proposals.tsx — queue with Pending/Approved/Rejected tabs. Pending count is highlighted in amber. - ProposalDetail.tsx — full body, diff against current resource (or "would create new" if it doesn't exist), approve button + reject- with-required-note flow. ### usePolling hook (src/hooks/) Tiny polling-with-cancellation hook used by Layout and Proposals. ### Layout rewrite (src/components/Layout.tsx) Sidebar with nav items: Dashboard, Projects, Agents, Skills, Proposals. Lucide icons. Active-route highlighting via NavLink. Pending-proposals warning badge on the Proposals item. ### Routes (src/App.tsx) New routes: /dashboard, /skills, /skills/:name, /proposals, /proposals/:id. Default redirects to /dashboard. ### API types (src/api.ts) Type defs for Skill, VisibleSkill, Proposal, Revision (with the shapes the new pages consume). ## Tests Existing 7 web tests still pass (Login + api). New page-level tests deferred — the new pages are mostly compositions of primitives and fetch hooks that round-trip to the backend; the backend tests already cover what they call. PR-7 polish can add render-and-click tests if coverage drift surfaces. ## Verification - `pnpm --filter @mcpctl/web build` clean, no warnings. - `pnpm test:run` whole monorepo: 162 test files / 2157 tests green. - Visual smoke deferred — needs a running mcpd to populate the fixtures. Manual smoke tested locally is the next step. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:54:55 +01:00
class-variance-authority@0.7.1:
resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==}
cli-boxes@3.0.0:
resolution: {integrity: sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==}
engines: {node: '>=10'}
cli-cursor@4.0.0:
resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
cli-spinners@3.4.0:
resolution: {integrity: sha512-bXfOC4QcT1tKXGorxL3wbJm6XJPDqEnij2gQ2m7ESQuE+/z9YFIWnl/5RpTiKWbMq3EVKR4fRLJGn6DVfu0mpw==}
engines: {node: '>=18.20'}
cli-truncate@5.1.1:
resolution: {integrity: sha512-SroPvNHxUnk+vIW/dOSfNqdy1sPEFkrTk6TUtqLCnBlo3N7TNYYkzzN7uSD6+jVjrdO4+p8nH7JzH6cIvUem6A==}
engines: {node: '>=20'}
2026-02-21 03:10:39 +00:00
cli-width@4.1.0:
resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==}
engines: {node: '>= 12'}
feat(web): bold redesign — Tailwind v4 + shadcn-style primitives + Skills/Proposals/Revisions UI Phase 6 of the Skills + Revisions + Proposals work. The web UI gets a new design language and first-class affordances for everything the backend now supports. ## Visual direction - Tailwind v4 with custom @theme block (oklch tokens). Dark-mode-only (internal tool — light mode doubles QA surface). - Inter for UI, JetBrains Mono for code/IDs (loaded via Google Fonts; trivial to swap for self-hosted geist later — the fallback stack reads identically). - Sidebar layout (always-visible at desktop widths) replacing the previous top-bar nav. Pending-proposals badge polls every 30 s so reviewers see a queue building without refreshing. - Lucide icons throughout. - Spacing and radii on Tailwind defaults. Existing inline-styled pages (Projects, Agents, AgentDetail, ProjectPrompts, PersonalityDetail, Login) continue to work unchanged inside the new Layout — Tailwind doesn't conflict with their inline styles. A follow-up can migrate them incrementally. ## What's added ### Build infra (src/web/) - package.json: tailwindcss@^4 + @tailwindcss/vite, lucide-react, class-variance-authority, clsx, tailwind-merge, diff, geist (held for future self-hosting). - vite.config.ts: registers the @tailwindcss/vite plugin. - src/index.css: Tailwind import + @theme tokens + @layer base. - src/main.tsx: imports index.css. - src/lib/utils.ts: shadcn-style cn() helper. ### shadcn-style primitives (src/components/ui/) Hand-written rather than generated via `npx shadcn` so the repo doesn't depend on a CLI tool that needs interactive runtime: - button.tsx — variants: primary / secondary / ghost / danger / link; sizes: sm / md / lg / icon. - card.tsx — Card + Header/Title/Description/Content/Footer subparts. - badge.tsx — variants: default / info / success / warning / danger / outline. - input.tsx — Input + Textarea + Label. - tabs.tsx — no-dep accessible Tabs (no Radix needed for our use). - separator.tsx — h/v separator with role=separator. ### Diff component (src/components/Diff.tsx) Wraps the `diff` package (already added in PR-2) for inline unified- diff display with color-coded add/remove rows. Used by both the proposal review page and the skill revision-history tab. ### New pages (src/pages/) - Dashboard.tsx — at-a-glance home. Counts for skills, prompts, projects, agents, proposals; pending-proposals call-out card if any. - Skills.tsx — list view, separated into Global vs Project/Agent- scoped sections. - SkillDetail.tsx — name + semver + description; tabs for SKILL.md / Files / Metadata / History. History tab shows revisions with click-to-diff against the live body. - Proposals.tsx — queue with Pending/Approved/Rejected tabs. Pending count is highlighted in amber. - ProposalDetail.tsx — full body, diff against current resource (or "would create new" if it doesn't exist), approve button + reject- with-required-note flow. ### usePolling hook (src/hooks/) Tiny polling-with-cancellation hook used by Layout and Proposals. ### Layout rewrite (src/components/Layout.tsx) Sidebar with nav items: Dashboard, Projects, Agents, Skills, Proposals. Lucide icons. Active-route highlighting via NavLink. Pending-proposals warning badge on the Proposals item. ### Routes (src/App.tsx) New routes: /dashboard, /skills, /skills/:name, /proposals, /proposals/:id. Default redirects to /dashboard. ### API types (src/api.ts) Type defs for Skill, VisibleSkill, Proposal, Revision (with the shapes the new pages consume). ## Tests Existing 7 web tests still pass (Login + api). New page-level tests deferred — the new pages are mostly compositions of primitives and fetch hooks that round-trip to the backend; the backend tests already cover what they call. PR-7 polish can add render-and-click tests if coverage drift surfaces. ## Verification - `pnpm --filter @mcpctl/web build` clean, no warnings. - `pnpm test:run` whole monorepo: 162 test files / 2157 tests green. - Visual smoke deferred — needs a running mcpd to populate the fixtures. Manual smoke tested locally is the next step. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:54:55 +01:00
client-only@0.0.1:
resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==}
cliui@8.0.1:
resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
engines: {node: '>=12'}
feat(web): bold redesign — Tailwind v4 + shadcn-style primitives + Skills/Proposals/Revisions UI Phase 6 of the Skills + Revisions + Proposals work. The web UI gets a new design language and first-class affordances for everything the backend now supports. ## Visual direction - Tailwind v4 with custom @theme block (oklch tokens). Dark-mode-only (internal tool — light mode doubles QA surface). - Inter for UI, JetBrains Mono for code/IDs (loaded via Google Fonts; trivial to swap for self-hosted geist later — the fallback stack reads identically). - Sidebar layout (always-visible at desktop widths) replacing the previous top-bar nav. Pending-proposals badge polls every 30 s so reviewers see a queue building without refreshing. - Lucide icons throughout. - Spacing and radii on Tailwind defaults. Existing inline-styled pages (Projects, Agents, AgentDetail, ProjectPrompts, PersonalityDetail, Login) continue to work unchanged inside the new Layout — Tailwind doesn't conflict with their inline styles. A follow-up can migrate them incrementally. ## What's added ### Build infra (src/web/) - package.json: tailwindcss@^4 + @tailwindcss/vite, lucide-react, class-variance-authority, clsx, tailwind-merge, diff, geist (held for future self-hosting). - vite.config.ts: registers the @tailwindcss/vite plugin. - src/index.css: Tailwind import + @theme tokens + @layer base. - src/main.tsx: imports index.css. - src/lib/utils.ts: shadcn-style cn() helper. ### shadcn-style primitives (src/components/ui/) Hand-written rather than generated via `npx shadcn` so the repo doesn't depend on a CLI tool that needs interactive runtime: - button.tsx — variants: primary / secondary / ghost / danger / link; sizes: sm / md / lg / icon. - card.tsx — Card + Header/Title/Description/Content/Footer subparts. - badge.tsx — variants: default / info / success / warning / danger / outline. - input.tsx — Input + Textarea + Label. - tabs.tsx — no-dep accessible Tabs (no Radix needed for our use). - separator.tsx — h/v separator with role=separator. ### Diff component (src/components/Diff.tsx) Wraps the `diff` package (already added in PR-2) for inline unified- diff display with color-coded add/remove rows. Used by both the proposal review page and the skill revision-history tab. ### New pages (src/pages/) - Dashboard.tsx — at-a-glance home. Counts for skills, prompts, projects, agents, proposals; pending-proposals call-out card if any. - Skills.tsx — list view, separated into Global vs Project/Agent- scoped sections. - SkillDetail.tsx — name + semver + description; tabs for SKILL.md / Files / Metadata / History. History tab shows revisions with click-to-diff against the live body. - Proposals.tsx — queue with Pending/Approved/Rejected tabs. Pending count is highlighted in amber. - ProposalDetail.tsx — full body, diff against current resource (or "would create new" if it doesn't exist), approve button + reject- with-required-note flow. ### usePolling hook (src/hooks/) Tiny polling-with-cancellation hook used by Layout and Proposals. ### Layout rewrite (src/components/Layout.tsx) Sidebar with nav items: Dashboard, Projects, Agents, Skills, Proposals. Lucide icons. Active-route highlighting via NavLink. Pending-proposals warning badge on the Proposals item. ### Routes (src/App.tsx) New routes: /dashboard, /skills, /skills/:name, /proposals, /proposals/:id. Default redirects to /dashboard. ### API types (src/api.ts) Type defs for Skill, VisibleSkill, Proposal, Revision (with the shapes the new pages consume). ## Tests Existing 7 web tests still pass (Login + api). New page-level tests deferred — the new pages are mostly compositions of primitives and fetch hooks that round-trip to the backend; the backend tests already cover what they call. PR-7 polish can add render-and-click tests if coverage drift surfaces. ## Verification - `pnpm --filter @mcpctl/web build` clean, no warnings. - `pnpm test:run` whole monorepo: 162 test files / 2157 tests green. - Visual smoke deferred — needs a running mcpd to populate the fixtures. Manual smoke tested locally is the next step. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:54:55 +01:00
clsx@2.1.1:
resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==}
engines: {node: '>=6'}
cmd-shim@8.0.0:
resolution: {integrity: sha512-Jk/BK6NCapZ58BKUxlSI+ouKRbjH1NLZCgJkYoab+vEHUY3f6OzpNBN9u7HFSv9J6TRDGs4PLOHezoKGaFRSCA==}
engines: {node: ^20.17.0 || >=22.9.0}
code-excerpt@4.0.0:
resolution: {integrity: sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
2026-02-21 03:10:39 +00:00
color-convert@2.0.1:
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
engines: {node: '>=7.0.0'}
color-name@1.1.4:
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
color-support@1.1.3:
resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==}
hasBin: true
combined-stream@1.0.8:
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
engines: {node: '>= 0.8'}
2026-02-21 03:10:39 +00:00
commander@13.1.0:
resolution: {integrity: sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==}
engines: {node: '>=18'}
common-ancestor-path@2.0.0:
resolution: {integrity: sha512-dnN3ibLeoRf2HNC+OlCiNc5d2zxbLJXOtiZUudNFSXZrNSydxcCsSpRzXwfu7BBWCIfHPw+xTayeBvJCP/D8Ng==}
engines: {node: '>= 18'}
concat-map@0.0.1:
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
2026-02-21 03:10:39 +00:00
confbox@0.2.4:
resolution: {integrity: sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==}
consola@3.4.2:
resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==}
engines: {node: ^14.18.0 || >=16.10.0}
console-control-strings@1.1.0:
resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==}
feat(mcpd+deploy): serve web UI at /ui + smoke tests + docs (Stage 6) The closing stage. mcpd now hosts the Stage 5 SPA, the Docker image bundles the build artifact, a smoke test exercises the personality HTTP surface end-to-end, and the user-facing docs spell out the mental model. mcpd: - Add @fastify/static dep. - New routes/web-ui.ts: registers /ui/* against a static bundle. Looks for the bundle at $MCPD_WEB_ROOT, then /usr/share/mcpd/web (the Docker image path), then a dev-tree fallback. Logs and skips cleanly if missing — API-only deploys keep working. - SPA fallback: any /ui/<path> that doesn't match a file falls through to index.html so direct hits to react-router URLs work. - /ui/* falls through to `kind: skip` in mapUrlToPermission, so the static assets are served unauthenticated. Each API call from the SPA still carries the bearer token. Deploy: - Dockerfile.mcpd builds the @mcpctl/web bundle in the same builder stage and copies dist/ to /usr/share/mcpd/web in the runtime image. Smoke (personality.smoke.test.ts): - Live mcpd flow: create secret/llm/agent/personality, attach an agent-direct prompt, verify the binding listing, reject double- attach (409) + foreign-agent prompt (400), set defaultPersonality by name, detach + delete cleanup. Docs: - New docs/personalities.md: VLAN-on-ethernet model, system-block ordering table, three prompt scopes, CLI walkthrough, web UI walkthrough, full API surface, RBAC notes. - agents.md and chat.md cross-link. - README's Agents section gains a Personalities subsection. Test count after Stage 6: mcpd: 801/801 cli: 430/430 web: 7/7 db: 58/62 (4 pre-existing) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:48:43 +01:00
content-disposition@0.5.4:
resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==}
engines: {node: '>= 0.6'}
2026-02-21 03:10:39 +00:00
content-disposition@1.0.1:
resolution: {integrity: sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==}
engines: {node: '>=18'}
content-type@1.0.5:
resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==}
engines: {node: '>= 0.6'}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
convert-source-map@2.0.0:
resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
convert-to-spaces@2.0.1:
resolution: {integrity: sha512-rcQ1bsQO9799wq24uE5AM2tAILy4gXGIK/njFWcVQkGNZ96edlpY+A7bjwvzjYvLDyzmG1MmMLZhpcsb+klNMQ==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
2026-02-21 03:10:39 +00:00
cookie-signature@1.2.2:
resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==}
engines: {node: '>=6.6.0'}
cookie@0.7.2:
resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==}
engines: {node: '>= 0.6'}
cookie@1.1.1:
resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==}
engines: {node: '>=18'}
cors@2.8.6:
resolution: {integrity: sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==}
engines: {node: '>= 0.10'}
cpu-features@0.0.10:
resolution: {integrity: sha512-9IkYqtX3YHPCzoVg1Py+o9057a3i0fp7S530UWokCSaFVTc7CwXPRiOjRjBQQ18ZCNafx78YfnG+HALxtVmOGA==}
engines: {node: '>=10.0.0'}
2026-02-21 03:10:39 +00:00
cross-spawn@7.0.6:
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
engines: {node: '>= 8'}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
css-tree@3.2.1:
resolution: {integrity: sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==}
engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0}
css.escape@1.5.1:
resolution: {integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==}
cssesc@3.0.0:
resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
engines: {node: '>=4'}
hasBin: true
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
cssstyle@6.2.0:
resolution: {integrity: sha512-Fm5NvhYathRnXNVndkUsCCuR63DCLVVwGOOwQw782coXFi5HhkXdu289l59HlXZBawsyNccXfWRYvLzcDCdDig==}
engines: {node: '>=20'}
csstype@3.2.3:
resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
data-uri-to-buffer@4.0.1:
resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==}
engines: {node: '>= 12'}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
data-urls@7.0.0:
resolution: {integrity: sha512-23XHcCF+coGYevirZceTVD7NdJOqVn+49IHyxgszm+JIiHLoB2TkmPtsYkNWT1pvRSGkc35L6NHs0yHkN2SumA==}
engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0}
2026-02-21 03:10:39 +00:00
debug@4.4.3:
resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==}
engines: {node: '>=6.0'}
peerDependencies:
supports-color: '*'
peerDependenciesMeta:
supports-color:
optional: true
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
decimal.js@10.6.0:
resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==}
2026-02-21 03:10:39 +00:00
deep-is@0.1.4:
resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
deepmerge-ts@7.1.5:
resolution: {integrity: sha512-HOJkrhaYsweh+W+e74Yn7YStZOilkoPb6fycpwNLKzSPtruFs48nYis0zy5yJz1+ktUhHxoRDJ27RQAWLIJVJw==}
engines: {node: '>=16.0.0'}
deepmerge@4.3.1:
resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==}
engines: {node: '>=0.10.0'}
2026-02-21 03:10:39 +00:00
defu@6.1.4:
resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==}
delayed-stream@1.0.0:
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
engines: {node: '>=0.4.0'}
delegates@1.0.0:
resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==}
2026-02-21 03:10:39 +00:00
depd@2.0.0:
resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==}
engines: {node: '>= 0.8'}
dequal@2.0.3:
resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
engines: {node: '>=6'}
destr@2.0.5:
resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==}
detect-libc@2.1.2:
resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
engines: {node: '>=8'}
feat(mcpd): ResourceRevision + ResourceProposal services + Prompt revision integration Phase 2 of the Skills + Revisions + Proposals work. Stands up the generic revision/proposal layer and wires Prompt into it. Skills will plug into the same infrastructure in PR-3 with no further service changes required. This PR is intentionally additive: PromptRequest table and routes are unchanged. The /api/v1/proposals API runs side-by-side with the legacy /api/v1/promptrequests API. The PromptRequest cutover (rename + backfill + mcplocal rewire) is deferred to a later PR so this one stays reviewable. ## What's added ### Repositories (src/mcpd/src/repositories/) - resource-revision.repository.ts — append-only revision log keyed by (resourceType, resourceId). Soft FK; no relations declared. Supports history listing, semver lookup, and contentHash cross-resource search. - resource-proposal.repository.ts — generic propose queue. Status lifecycle pending → approved | rejected. Mirrors Prompt's `?? ''` workaround for nullable-FK compound lookups. ### Services (src/mcpd/src/services/) - resource-revision.service.ts — record() inserts a revision with a stable sha256 contentHash computed from canonicalised JSON (key-sorted at every level so reordered objects produce the same hash). Caller passes a pre-computed semver; service does NOT decide bump policy. - resource-proposal.service.ts — propose / approve / reject / list, with a per-resourceType handler registry. PromptService registers the 'prompt' handler at construction; the SkillService will register 'skill' in PR-3. approve() runs in a Prisma $transaction so the resource update + revision insert + proposal status flip are atomic. ### Pure utility (src/mcpd/src/utils/semver.ts) - bumpSemver(current, kind) for major / minor / patch - compareSemver(a, b) — numeric, not lex (10 > 9) - isValidSemver(s) - Invalid input falls back to '0.1.0' rather than throwing — keeps the audit-write path from blowing up the prompt update if a row's semver ever drifts out of MAJOR.MINOR.PATCH shape. ### Routes (src/mcpd/src/routes/) - revisions.ts — GET /api/v1/revisions?resourceType=&resourceId=, GET /api/v1/revisions/:id, GET /api/v1/revisions/:id/diff?against=<id|live> (unified-format diff via the `diff` package), and POST /api/v1/prompts/:id/restore-revision { revisionId, note? }. - proposals.ts — GET / POST /api/v1/proposals, GET /api/v1/proposals/:id, PUT for body updates, POST .../approve and POST .../reject, plus DELETE. ## What's changed - PromptService.create / update now record a ResourceRevision when the revision service is wired. Update auto-bumps patch on content change; authors can override via `--bump major|minor|patch` or `--semver X.Y.Z` on the CLI (forwarded into the PUT body). Best-effort: revision write failures are swallowed so the prompt save still succeeds (revision is audit, not source of truth). - PromptService.setProposalService registers a 'prompt' approval handler with the proposal service. Approval runs in a Prisma transaction: upsert prompt → record revision → update currentRevisionId → flip proposal status. semver bumps to 0.1.0 on first approval, patch thereafter. - New CLI flags on `mcpctl edit prompt`: --bump, --semver, --note. They're prompt-only (validated client-side); other resources reject them. - Aliases in shared.ts: `proposal`/`prop` → proposals, `revision`/`rev` → revisions. - diff dependency added to mcpd. ## Tests - src/mcpd/tests/utils/semver.test.ts — covers bump/compare/validate including numeric (not lex) semver compare and invalid-input fallback. - prompt-service.test.ts updated: makePrompt fixture now sets semver + agentId + currentRevisionId; updatePrompt assertion expects the auto-bumped patch in the same update call. - prompt-routes.test.ts updated symmetrically. ## RBAC `proposals` and `revisions` URL segments map to the existing `prompts` permission for now. PR-7 may split if a "reviewer" role becomes useful. ## Verification Full suite: 158 test files / 2127 tests green. `pnpm build` clean across all 6 workspace packages. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 00:38:35 +01:00
diff@5.2.2:
resolution: {integrity: sha512-vtcDfH3TOjP8UekytvnHH1o1P4FcUdt4eQ1Y+Abap1tk/OB2MWQvcwS2ClCd1zuIhc3JKOx6p3kod8Vfys3E+A==}
engines: {node: '>=0.3.1'}
diff@8.0.3:
resolution: {integrity: sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ==}
engines: {node: '>=0.3.1'}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
diff@8.0.4:
resolution: {integrity: sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==}
engines: {node: '>=0.3.1'}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
diff@9.0.0:
resolution: {integrity: sha512-svtcdpS8CgJyqAjEQIXdb3OjhFVVYjzGAPO8WGCmRbrml64SPw/jJD4GoE98aR7r25A0XcgrK3F02yw9R/vhQw==}
engines: {node: '>=0.3.1'}
docker-modem@5.0.6:
resolution: {integrity: sha512-ens7BiayssQz/uAxGzH8zGXCtiV24rRWXdjNha5V4zSOcxmAZsfGVm/PPFbwQdqEkDnhG+SyR9E3zSHUbOKXBQ==}
engines: {node: '>= 8.0'}
dockerode@4.0.9:
resolution: {integrity: sha512-iND4mcOWhPaCNh54WmK/KoSb35AFqPAUWFMffTQcp52uQt36b5uNwEJTSXntJZBbeGad72Crbi/hvDIv6us/6Q==}
engines: {node: '>= 8.0'}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
dom-accessibility-api@0.5.16:
resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==}
dom-accessibility-api@0.6.3:
resolution: {integrity: sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==}
dompurify@3.2.7:
resolution: {integrity: sha512-WhL/YuveyGXJaerVlMYGWhvQswa7myDG17P7Vu65EWC05o8vfeNbvNf4d/BOvH99+ZW+LlQsc1GDKMa1vNK6dw==}
2026-02-21 03:10:39 +00:00
dotenv@16.6.1:
resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==}
engines: {node: '>=12'}
dunder-proto@1.0.1:
resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
engines: {node: '>= 0.4'}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
ecdsa-sig-formatter@1.0.11:
resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==}
2026-02-21 03:10:39 +00:00
ee-first@1.1.1:
resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
effect@3.18.4:
resolution: {integrity: sha512-b1LXQJLe9D11wfnOKAk3PKxuqYshQ0Heez+y5pnkd3jLj1yx9QhM72zZ9uUrOQyNvrs2GZZd/3maL0ZV18YuDA==}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
effect@4.0.0-beta.83:
resolution: {integrity: sha512-0wsak8RtgGAr9UWSbVDgJHZcUqMSvicHcvaZv1MbMM7MCGgW4Rn/137J1MHQbwYPcwYGxT/IqehFd+UbYuj78w==}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
electron-to-chromium@1.5.344:
resolution: {integrity: sha512-4MxfbmNDm+KPh066EZy+eUnkcDPcZ35wNmOWzFuh/ijvHsve6kbLTLURy88uCNK5FbpN+yk2nQY6BYh1GEt+wg==}
emoji-regex@10.6.0:
resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==}
2026-02-21 03:10:39 +00:00
emoji-regex@8.0.0:
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
empathic@2.0.0:
resolution: {integrity: sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==}
engines: {node: '>=14'}
encodeurl@2.0.0:
resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==}
engines: {node: '>= 0.8'}
end-of-stream@1.4.5:
resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==}
feat(web): bold redesign — Tailwind v4 + shadcn-style primitives + Skills/Proposals/Revisions UI Phase 6 of the Skills + Revisions + Proposals work. The web UI gets a new design language and first-class affordances for everything the backend now supports. ## Visual direction - Tailwind v4 with custom @theme block (oklch tokens). Dark-mode-only (internal tool — light mode doubles QA surface). - Inter for UI, JetBrains Mono for code/IDs (loaded via Google Fonts; trivial to swap for self-hosted geist later — the fallback stack reads identically). - Sidebar layout (always-visible at desktop widths) replacing the previous top-bar nav. Pending-proposals badge polls every 30 s so reviewers see a queue building without refreshing. - Lucide icons throughout. - Spacing and radii on Tailwind defaults. Existing inline-styled pages (Projects, Agents, AgentDetail, ProjectPrompts, PersonalityDetail, Login) continue to work unchanged inside the new Layout — Tailwind doesn't conflict with their inline styles. A follow-up can migrate them incrementally. ## What's added ### Build infra (src/web/) - package.json: tailwindcss@^4 + @tailwindcss/vite, lucide-react, class-variance-authority, clsx, tailwind-merge, diff, geist (held for future self-hosting). - vite.config.ts: registers the @tailwindcss/vite plugin. - src/index.css: Tailwind import + @theme tokens + @layer base. - src/main.tsx: imports index.css. - src/lib/utils.ts: shadcn-style cn() helper. ### shadcn-style primitives (src/components/ui/) Hand-written rather than generated via `npx shadcn` so the repo doesn't depend on a CLI tool that needs interactive runtime: - button.tsx — variants: primary / secondary / ghost / danger / link; sizes: sm / md / lg / icon. - card.tsx — Card + Header/Title/Description/Content/Footer subparts. - badge.tsx — variants: default / info / success / warning / danger / outline. - input.tsx — Input + Textarea + Label. - tabs.tsx — no-dep accessible Tabs (no Radix needed for our use). - separator.tsx — h/v separator with role=separator. ### Diff component (src/components/Diff.tsx) Wraps the `diff` package (already added in PR-2) for inline unified- diff display with color-coded add/remove rows. Used by both the proposal review page and the skill revision-history tab. ### New pages (src/pages/) - Dashboard.tsx — at-a-glance home. Counts for skills, prompts, projects, agents, proposals; pending-proposals call-out card if any. - Skills.tsx — list view, separated into Global vs Project/Agent- scoped sections. - SkillDetail.tsx — name + semver + description; tabs for SKILL.md / Files / Metadata / History. History tab shows revisions with click-to-diff against the live body. - Proposals.tsx — queue with Pending/Approved/Rejected tabs. Pending count is highlighted in amber. - ProposalDetail.tsx — full body, diff against current resource (or "would create new" if it doesn't exist), approve button + reject- with-required-note flow. ### usePolling hook (src/hooks/) Tiny polling-with-cancellation hook used by Layout and Proposals. ### Layout rewrite (src/components/Layout.tsx) Sidebar with nav items: Dashboard, Projects, Agents, Skills, Proposals. Lucide icons. Active-route highlighting via NavLink. Pending-proposals warning badge on the Proposals item. ### Routes (src/App.tsx) New routes: /dashboard, /skills, /skills/:name, /proposals, /proposals/:id. Default redirects to /dashboard. ### API types (src/api.ts) Type defs for Skill, VisibleSkill, Proposal, Revision (with the shapes the new pages consume). ## Tests Existing 7 web tests still pass (Login + api). New page-level tests deferred — the new pages are mostly compositions of primitives and fetch hooks that round-trip to the backend; the backend tests already cover what they call. PR-7 polish can add render-and-click tests if coverage drift surfaces. ## Verification - `pnpm --filter @mcpctl/web build` clean, no warnings. - `pnpm test:run` whole monorepo: 162 test files / 2157 tests green. - Visual smoke deferred — needs a running mcpd to populate the fixtures. Manual smoke tested locally is the next step. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:54:55 +01:00
enhanced-resolve@5.21.0:
resolution: {integrity: sha512-otxSQPw4lkOZWkHpB3zaEQs6gWYEsmX4xQF68ElXC/TWvGxGMSGOvoNbaLXm6/cS/fSfHtsEdw90y20PCd+sCA==}
engines: {node: '>=10.13.0'}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
entities@6.0.1:
resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==}
engines: {node: '>=0.12'}
entities@7.0.1:
resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==}
engines: {node: '>=0.12'}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
entities@8.0.0:
resolution: {integrity: sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA==}
engines: {node: '>=20.19.0'}
env-paths@2.2.1:
resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==}
engines: {node: '>=6'}
environment@1.1.0:
resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==}
engines: {node: '>=18'}
2026-02-21 03:10:39 +00:00
es-define-property@1.0.1:
resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==}
engines: {node: '>= 0.4'}
es-errors@1.3.0:
resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
engines: {node: '>= 0.4'}
es-module-lexer@1.7.0:
resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==}
es-module-lexer@2.3.1:
resolution: {integrity: sha512-shc1dbU90Yl/xq1QrC7QRtfcwURZuVRfPhZbDoldJ1cn1gzDvBaBWlv0eFolj5+0znnPJz5TXLxsN77X/12KTA==}
2026-02-21 03:10:39 +00:00
es-object-atoms@1.1.1:
resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==}
engines: {node: '>= 0.4'}
es-set-tostringtag@2.1.0:
resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==}
engines: {node: '>= 0.4'}
es-toolkit@1.44.0:
resolution: {integrity: sha512-6penXeZalaV88MM3cGkFZZfOoLGWshWWfdy0tWw/RlVVyhvMaWSBTOvXNeiW3e5FwdS5ePW0LGEu17zT139ktg==}
2026-02-21 03:10:39 +00:00
esbuild@0.27.3:
resolution: {integrity: sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==}
engines: {node: '>=18'}
hasBin: true
escalade@3.2.0:
resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==}
engines: {node: '>=6'}
2026-02-21 03:10:39 +00:00
escape-html@1.0.3:
resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==}
escape-string-regexp@2.0.0:
resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==}
engines: {node: '>=8'}
2026-02-21 03:10:39 +00:00
escape-string-regexp@4.0.0:
resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
engines: {node: '>=10'}
eslint-config-prettier@10.1.8:
resolution: {integrity: sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==}
hasBin: true
peerDependencies:
eslint: '>=7.0.0'
eslint-scope@9.1.1:
resolution: {integrity: sha512-GaUN0sWim5qc8KVErfPBWmc31LEsOkrUJbvJZV+xuL3u2phMUK4HIvXlWAakfC8W4nzlK+chPEAkYOYb5ZScIw==}
engines: {node: ^20.19.0 || ^22.13.0 || >=24}
eslint-visitor-keys@3.4.3:
resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
eslint-visitor-keys@5.0.1:
resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==}
engines: {node: ^20.19.0 || ^22.13.0 || >=24}
eslint@10.0.1:
resolution: {integrity: sha512-20MV9SUdeN6Jd84xESsKhRly+/vxI+hwvpBMA93s+9dAcjdCuCojn4IqUGS3lvVaqjVYGYHSRMCpeFtF2rQYxQ==}
engines: {node: ^20.19.0 || ^22.13.0 || >=24}
hasBin: true
peerDependencies:
jiti: '*'
peerDependenciesMeta:
jiti:
optional: true
espree@11.1.1:
resolution: {integrity: sha512-AVHPqQoZYc+RUM4/3Ly5udlZY/U4LS8pIG05jEjWM2lQMU/oaZ7qshzAl2YP1tfNmXfftH3ohurfwNAug+MnsQ==}
engines: {node: ^20.19.0 || ^22.13.0 || >=24}
esquery@1.7.0:
resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==}
engines: {node: '>=0.10'}
esrecurse@4.3.0:
resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==}
engines: {node: '>=4.0'}
estraverse@5.3.0:
resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==}
engines: {node: '>=4.0'}
estree-walker@3.0.3:
resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==}
esutils@2.0.3:
resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
engines: {node: '>=0.10.0'}
etag@1.8.1:
resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==}
engines: {node: '>= 0.6'}
events-universal@1.0.1:
resolution: {integrity: sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==}
2026-02-21 03:10:39 +00:00
eventsource-parser@3.0.6:
resolution: {integrity: sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==}
engines: {node: '>=18.0.0'}
eventsource@3.0.7:
resolution: {integrity: sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==}
engines: {node: '>=18.0.0'}
execa@5.1.1:
resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==}
engines: {node: '>=10'}
2026-02-21 03:10:39 +00:00
expect-type@1.3.0:
resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==}
engines: {node: '>=12.0.0'}
exponential-backoff@3.1.3:
resolution: {integrity: sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==}
2026-02-21 03:10:39 +00:00
express-rate-limit@8.2.1:
resolution: {integrity: sha512-PCZEIEIxqwhzw4KF0n7QF4QqruVTcF73O5kFKUnGOyjbCCgizBBiFaYpd/fnBLUMPw/BWw9OsiN7GgrNYr7j6g==}
engines: {node: '>= 16'}
peerDependencies:
express: '>= 4.11'
express@5.2.1:
resolution: {integrity: sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==}
engines: {node: '>= 18'}
exsolve@1.0.8:
resolution: {integrity: sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
extend@3.0.2:
resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==}
2026-02-21 03:10:39 +00:00
fast-check@3.23.2:
resolution: {integrity: sha512-h5+1OzzfCC3Ef7VbtKdcv7zsstUQwUDlYpUTvjeUsJAssPgLn7QzbboPtL5ro04Mq0rPOsMzl7q5hIbRs2wD1A==}
engines: {node: '>=8.0.0'}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
fast-check@4.9.0:
resolution: {integrity: sha512-7ms6T7SybUev/PQITciI0yLM2pOSFy5zpG8Ty7tQofcVaQUvrMXp6CBwqF6fThLCLOrfBtuHAtwq6Yu4XPCllg==}
engines: {node: '>=12.17.0'}
2026-02-21 03:10:39 +00:00
fast-decode-uri-component@1.0.1:
resolution: {integrity: sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==}
fast-deep-equal@3.1.3:
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
fast-fifo@1.3.2:
resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==}
2026-02-21 03:10:39 +00:00
fast-json-stable-stringify@2.1.0:
resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
fast-json-stringify@6.3.0:
resolution: {integrity: sha512-oRCntNDY/329HJPlmdNLIdogNtt6Vyjb1WuT01Soss3slIdyUp8kAcDU3saQTOquEK8KFVfwIIF7FebxUAu+yA==}
fast-levenshtein@2.0.6:
resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==}
fast-querystring@1.1.2:
resolution: {integrity: sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==}
fast-uri@3.1.0:
resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==}
fastify-plugin@5.1.0:
resolution: {integrity: sha512-FAIDA8eovSt5qcDgcBvDuX/v0Cjz0ohGhENZ/wpc3y+oZCY2afZ9Baqql3g/lC+OHRnciQol4ww7tuthOb9idw==}
fastify@5.7.4:
resolution: {integrity: sha512-e6l5NsRdaEP8rdD8VR0ErJASeyaRbzXYpmkrpr2SuvuMq6Si3lvsaVy5C+7gLanEkvjpMDzBXWE5HPeb/hgTxA==}
fastq@1.20.1:
resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==}
fdir@6.5.0:
resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==}
engines: {node: '>=12.0.0'}
peerDependencies:
picomatch: ^3 || ^4
peerDependenciesMeta:
picomatch:
optional: true
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
fetch-blob@3.2.0:
resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==}
engines: {node: ^12.20 || >= 14.13}
figures@6.1.0:
resolution: {integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==}
engines: {node: '>=18'}
2026-02-21 03:10:39 +00:00
file-entry-cache@8.0.0:
resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==}
engines: {node: '>=16.0.0'}
finalhandler@2.1.1:
resolution: {integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==}
engines: {node: '>= 18.0.0'}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
find-babel-config@2.1.2:
resolution: {integrity: sha512-ZfZp1rQyp4gyuxqt1ZqjFGVeVBvmpURMqdIWXbPRfB97Bf6BzdK/xSIbylEINzQ0kB5tlDQfn9HkNXXWsqTqLg==}
find-my-way-ts@0.1.6:
resolution: {integrity: sha512-a85L9ZoXtNAey3Y6Z+eBWW658kO/MwR7zIafkIUPUMf3isZG0NCs2pjW2wtjxAKuJPxMAsHUIP4ZPGv0o5gyTA==}
2026-02-21 03:10:39 +00:00
find-my-way@9.4.0:
resolution: {integrity: sha512-5Ye4vHsypZRYtS01ob/iwHzGRUDELlsoCftI/OZFhcLs1M0tkGPcXldE80TAZC5yYuJMBPJQQ43UHlqbJWiX2w==}
engines: {node: '>=20'}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
find-up@3.0.0:
resolution: {integrity: sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==}
engines: {node: '>=6'}
2026-02-21 03:10:39 +00:00
find-up@5.0.0:
resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
engines: {node: '>=10'}
flat-cache@4.0.1:
resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==}
engines: {node: '>=16'}
flatted@3.3.3:
resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==}
feat(mcpd+deploy): serve web UI at /ui + smoke tests + docs (Stage 6) The closing stage. mcpd now hosts the Stage 5 SPA, the Docker image bundles the build artifact, a smoke test exercises the personality HTTP surface end-to-end, and the user-facing docs spell out the mental model. mcpd: - Add @fastify/static dep. - New routes/web-ui.ts: registers /ui/* against a static bundle. Looks for the bundle at $MCPD_WEB_ROOT, then /usr/share/mcpd/web (the Docker image path), then a dev-tree fallback. Logs and skips cleanly if missing — API-only deploys keep working. - SPA fallback: any /ui/<path> that doesn't match a file falls through to index.html so direct hits to react-router URLs work. - /ui/* falls through to `kind: skip` in mapUrlToPermission, so the static assets are served unauthenticated. Each API call from the SPA still carries the bearer token. Deploy: - Dockerfile.mcpd builds the @mcpctl/web bundle in the same builder stage and copies dist/ to /usr/share/mcpd/web in the runtime image. Smoke (personality.smoke.test.ts): - Live mcpd flow: create secret/llm/agent/personality, attach an agent-direct prompt, verify the binding listing, reject double- attach (409) + foreign-agent prompt (400), set defaultPersonality by name, detach + delete cleanup. Docs: - New docs/personalities.md: VLAN-on-ethernet model, system-block ordering table, three prompt scopes, CLI walkthrough, web UI walkthrough, full API surface, RBAC notes. - agents.md and chat.md cross-link. - README's Agents section gains a Personalities subsection. Test count after Stage 6: mcpd: 801/801 cli: 430/430 web: 7/7 db: 58/62 (4 pre-existing) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:48:43 +01:00
foreground-child@3.3.1:
resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==}
engines: {node: '>=14'}
form-data@4.0.5:
resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==}
engines: {node: '>= 6'}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
formdata-polyfill@4.0.10:
resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==}
engines: {node: '>=12.20.0'}
2026-02-21 03:10:39 +00:00
forwarded@0.2.0:
resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==}
engines: {node: '>= 0.6'}
fresh@2.0.0:
resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==}
engines: {node: '>= 0.8'}
fs-constants@1.0.0:
resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==}
fs-minipass@2.1.0:
resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==}
engines: {node: '>= 8'}
fs-minipass@3.0.3:
resolution: {integrity: sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==}
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
fs.realpath@1.0.0:
resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
2026-02-21 03:10:39 +00:00
fsevents@2.3.3:
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
os: [darwin]
function-bind@1.1.2:
resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
gauge@3.0.2:
resolution: {integrity: sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==}
engines: {node: '>=10'}
deprecated: This package is no longer supported.
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
gaxios@7.3.0:
resolution: {integrity: sha512-RB5vLV+vvQeoFPCX4QMK6/hjVkbIamPp1QSUD0CiZcnj12qbpiL+pLbYtgD+oZkWl0tl9z+o2Utp+MpM3QRhBA==}
engines: {node: '>=18'}
gcp-metadata@8.1.2:
resolution: {integrity: sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg==}
engines: {node: '>=18'}
feat(web): bold redesign — Tailwind v4 + shadcn-style primitives + Skills/Proposals/Revisions UI Phase 6 of the Skills + Revisions + Proposals work. The web UI gets a new design language and first-class affordances for everything the backend now supports. ## Visual direction - Tailwind v4 with custom @theme block (oklch tokens). Dark-mode-only (internal tool — light mode doubles QA surface). - Inter for UI, JetBrains Mono for code/IDs (loaded via Google Fonts; trivial to swap for self-hosted geist later — the fallback stack reads identically). - Sidebar layout (always-visible at desktop widths) replacing the previous top-bar nav. Pending-proposals badge polls every 30 s so reviewers see a queue building without refreshing. - Lucide icons throughout. - Spacing and radii on Tailwind defaults. Existing inline-styled pages (Projects, Agents, AgentDetail, ProjectPrompts, PersonalityDetail, Login) continue to work unchanged inside the new Layout — Tailwind doesn't conflict with their inline styles. A follow-up can migrate them incrementally. ## What's added ### Build infra (src/web/) - package.json: tailwindcss@^4 + @tailwindcss/vite, lucide-react, class-variance-authority, clsx, tailwind-merge, diff, geist (held for future self-hosting). - vite.config.ts: registers the @tailwindcss/vite plugin. - src/index.css: Tailwind import + @theme tokens + @layer base. - src/main.tsx: imports index.css. - src/lib/utils.ts: shadcn-style cn() helper. ### shadcn-style primitives (src/components/ui/) Hand-written rather than generated via `npx shadcn` so the repo doesn't depend on a CLI tool that needs interactive runtime: - button.tsx — variants: primary / secondary / ghost / danger / link; sizes: sm / md / lg / icon. - card.tsx — Card + Header/Title/Description/Content/Footer subparts. - badge.tsx — variants: default / info / success / warning / danger / outline. - input.tsx — Input + Textarea + Label. - tabs.tsx — no-dep accessible Tabs (no Radix needed for our use). - separator.tsx — h/v separator with role=separator. ### Diff component (src/components/Diff.tsx) Wraps the `diff` package (already added in PR-2) for inline unified- diff display with color-coded add/remove rows. Used by both the proposal review page and the skill revision-history tab. ### New pages (src/pages/) - Dashboard.tsx — at-a-glance home. Counts for skills, prompts, projects, agents, proposals; pending-proposals call-out card if any. - Skills.tsx — list view, separated into Global vs Project/Agent- scoped sections. - SkillDetail.tsx — name + semver + description; tabs for SKILL.md / Files / Metadata / History. History tab shows revisions with click-to-diff against the live body. - Proposals.tsx — queue with Pending/Approved/Rejected tabs. Pending count is highlighted in amber. - ProposalDetail.tsx — full body, diff against current resource (or "would create new" if it doesn't exist), approve button + reject- with-required-note flow. ### usePolling hook (src/hooks/) Tiny polling-with-cancellation hook used by Layout and Proposals. ### Layout rewrite (src/components/Layout.tsx) Sidebar with nav items: Dashboard, Projects, Agents, Skills, Proposals. Lucide icons. Active-route highlighting via NavLink. Pending-proposals warning badge on the Proposals item. ### Routes (src/App.tsx) New routes: /dashboard, /skills, /skills/:name, /proposals, /proposals/:id. Default redirects to /dashboard. ### API types (src/api.ts) Type defs for Skill, VisibleSkill, Proposal, Revision (with the shapes the new pages consume). ## Tests Existing 7 web tests still pass (Login + api). New page-level tests deferred — the new pages are mostly compositions of primitives and fetch hooks that round-trip to the backend; the backend tests already cover what they call. PR-7 polish can add render-and-click tests if coverage drift surfaces. ## Verification - `pnpm --filter @mcpctl/web build` clean, no warnings. - `pnpm test:run` whole monorepo: 162 test files / 2157 tests green. - Visual smoke deferred — needs a running mcpd to populate the fixtures. Manual smoke tested locally is the next step. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:54:55 +01:00
geist@1.7.0:
resolution: {integrity: sha512-ZaoiZwkSf0DwwB1ncdLKp+ggAldqxl5L1+SXaNIBGkPAqcu+xjVJLxlf3/S8vLt9UHx1xu5fz3lbzKCj5iOVdQ==}
peerDependencies:
next: '>=13.2.0'
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
gensync@1.0.0-beta.2:
resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
engines: {node: '>=6.9.0'}
get-caller-file@2.0.5:
resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
engines: {node: 6.* || 8.* || >= 10.*}
get-east-asian-width@1.5.0:
resolution: {integrity: sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==}
engines: {node: '>=18'}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
get-east-asian-width@1.6.0:
resolution: {integrity: sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==}
engines: {node: '>=18'}
2026-02-21 03:10:39 +00:00
get-intrinsic@1.3.0:
resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==}
engines: {node: '>= 0.4'}
get-proto@1.0.1:
resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==}
engines: {node: '>= 0.4'}
get-stream@6.0.1:
resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==}
engines: {node: '>=10'}
2026-02-21 03:10:39 +00:00
get-tsconfig@4.13.6:
resolution: {integrity: sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw==}
giget@2.0.0:
resolution: {integrity: sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA==}
hasBin: true
glob-parent@6.0.2:
resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
engines: {node: '>=10.13.0'}
feat(mcpd+deploy): serve web UI at /ui + smoke tests + docs (Stage 6) The closing stage. mcpd now hosts the Stage 5 SPA, the Docker image bundles the build artifact, a smoke test exercises the personality HTTP surface end-to-end, and the user-facing docs spell out the mental model. mcpd: - Add @fastify/static dep. - New routes/web-ui.ts: registers /ui/* against a static bundle. Looks for the bundle at $MCPD_WEB_ROOT, then /usr/share/mcpd/web (the Docker image path), then a dev-tree fallback. Logs and skips cleanly if missing — API-only deploys keep working. - SPA fallback: any /ui/<path> that doesn't match a file falls through to index.html so direct hits to react-router URLs work. - /ui/* falls through to `kind: skip` in mapUrlToPermission, so the static assets are served unauthenticated. Each API call from the SPA still carries the bearer token. Deploy: - Dockerfile.mcpd builds the @mcpctl/web bundle in the same builder stage and copies dist/ to /usr/share/mcpd/web in the runtime image. Smoke (personality.smoke.test.ts): - Live mcpd flow: create secret/llm/agent/personality, attach an agent-direct prompt, verify the binding listing, reject double- attach (409) + foreign-agent prompt (400), set defaultPersonality by name, detach + delete cleanup. Docs: - New docs/personalities.md: VLAN-on-ethernet model, system-block ordering table, three prompt scopes, CLI walkthrough, web UI walkthrough, full API surface, RBAC notes. - agents.md and chat.md cross-link. - README's Agents section gains a Personalities subsection. Test count after Stage 6: mcpd: 801/801 cli: 430/430 web: 7/7 db: 58/62 (4 pre-existing) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:48:43 +01:00
glob@11.1.0:
resolution: {integrity: sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==}
engines: {node: 20 || >=22}
deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
hasBin: true
2026-02-21 03:10:39 +00:00
glob@13.0.6:
resolution: {integrity: sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==}
engines: {node: 18 || 20 || >=22}
glob@7.2.3:
resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
glob@9.3.5:
resolution: {integrity: sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==}
engines: {node: '>=16 || 14 >=14.17'}
deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
google-auth-library@10.9.1:
resolution: {integrity: sha512-i1ydyHrqcIxXkWh/uBmVkzCvIuq5yiK2ATndIe5XxKholrG/MTYP9xGYka4sQhrbIAgGjL2B6NOE7rFaiF3fXw==}
engines: {node: '>=18'}
google-logging-utils@1.1.3:
resolution: {integrity: sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA==}
engines: {node: '>=14'}
google-protobuf@3.21.4:
resolution: {integrity: sha512-MnG7N936zcKTco4Jd2PX2U96Kf9PxygAPKBug+74LHzmHXmceN16MmRcdgZv+DGef/S9YvQAfRsNCn4cjf9yyQ==}
2026-02-21 03:10:39 +00:00
gopd@1.2.0:
resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==}
engines: {node: '>= 0.4'}
feat(web): bold redesign — Tailwind v4 + shadcn-style primitives + Skills/Proposals/Revisions UI Phase 6 of the Skills + Revisions + Proposals work. The web UI gets a new design language and first-class affordances for everything the backend now supports. ## Visual direction - Tailwind v4 with custom @theme block (oklch tokens). Dark-mode-only (internal tool — light mode doubles QA surface). - Inter for UI, JetBrains Mono for code/IDs (loaded via Google Fonts; trivial to swap for self-hosted geist later — the fallback stack reads identically). - Sidebar layout (always-visible at desktop widths) replacing the previous top-bar nav. Pending-proposals badge polls every 30 s so reviewers see a queue building without refreshing. - Lucide icons throughout. - Spacing and radii on Tailwind defaults. Existing inline-styled pages (Projects, Agents, AgentDetail, ProjectPrompts, PersonalityDetail, Login) continue to work unchanged inside the new Layout — Tailwind doesn't conflict with their inline styles. A follow-up can migrate them incrementally. ## What's added ### Build infra (src/web/) - package.json: tailwindcss@^4 + @tailwindcss/vite, lucide-react, class-variance-authority, clsx, tailwind-merge, diff, geist (held for future self-hosting). - vite.config.ts: registers the @tailwindcss/vite plugin. - src/index.css: Tailwind import + @theme tokens + @layer base. - src/main.tsx: imports index.css. - src/lib/utils.ts: shadcn-style cn() helper. ### shadcn-style primitives (src/components/ui/) Hand-written rather than generated via `npx shadcn` so the repo doesn't depend on a CLI tool that needs interactive runtime: - button.tsx — variants: primary / secondary / ghost / danger / link; sizes: sm / md / lg / icon. - card.tsx — Card + Header/Title/Description/Content/Footer subparts. - badge.tsx — variants: default / info / success / warning / danger / outline. - input.tsx — Input + Textarea + Label. - tabs.tsx — no-dep accessible Tabs (no Radix needed for our use). - separator.tsx — h/v separator with role=separator. ### Diff component (src/components/Diff.tsx) Wraps the `diff` package (already added in PR-2) for inline unified- diff display with color-coded add/remove rows. Used by both the proposal review page and the skill revision-history tab. ### New pages (src/pages/) - Dashboard.tsx — at-a-glance home. Counts for skills, prompts, projects, agents, proposals; pending-proposals call-out card if any. - Skills.tsx — list view, separated into Global vs Project/Agent- scoped sections. - SkillDetail.tsx — name + semver + description; tabs for SKILL.md / Files / Metadata / History. History tab shows revisions with click-to-diff against the live body. - Proposals.tsx — queue with Pending/Approved/Rejected tabs. Pending count is highlighted in amber. - ProposalDetail.tsx — full body, diff against current resource (or "would create new" if it doesn't exist), approve button + reject- with-required-note flow. ### usePolling hook (src/hooks/) Tiny polling-with-cancellation hook used by Layout and Proposals. ### Layout rewrite (src/components/Layout.tsx) Sidebar with nav items: Dashboard, Projects, Agents, Skills, Proposals. Lucide icons. Active-route highlighting via NavLink. Pending-proposals warning badge on the Proposals item. ### Routes (src/App.tsx) New routes: /dashboard, /skills, /skills/:name, /proposals, /proposals/:id. Default redirects to /dashboard. ### API types (src/api.ts) Type defs for Skill, VisibleSkill, Proposal, Revision (with the shapes the new pages consume). ## Tests Existing 7 web tests still pass (Login + api). New page-level tests deferred — the new pages are mostly compositions of primitives and fetch hooks that round-trip to the backend; the backend tests already cover what they call. PR-7 polish can add render-and-click tests if coverage drift surfaces. ## Verification - `pnpm --filter @mcpctl/web build` clean, no warnings. - `pnpm test:run` whole monorepo: 162 test files / 2157 tests green. - Visual smoke deferred — needs a running mcpd to populate the fixtures. Manual smoke tested locally is the next step. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:54:55 +01:00
graceful-fs@4.2.11:
resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
grok-mermaid@0.2.2:
resolution: {integrity: sha512-XcJEP5dDC8liHBh52mlLjU18fNvu1ckFsu0QpIG3+APZ270fsj9wxpiA6cOURmbUEuoMVgjbC2+UYgTdCqqgzA==}
engines: {node: '>=18'}
2026-02-21 03:10:39 +00:00
has-flag@4.0.0:
resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
engines: {node: '>=8'}
has-symbols@1.1.0:
resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==}
engines: {node: '>= 0.4'}
has-tostringtag@1.0.2:
resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==}
engines: {node: '>= 0.4'}
has-unicode@2.0.1:
resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==}
2026-02-21 03:10:39 +00:00
hasown@2.0.2:
resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
engines: {node: '>= 0.4'}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
hasown@2.0.4:
resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==}
engines: {node: '>= 0.4'}
2026-02-21 03:10:39 +00:00
helmet@7.2.0:
resolution: {integrity: sha512-ZRiwvN089JfMXokizgqEPXsl2Guk094yExfoDXR0cBYWxtBbaSww/w+vT4WEJsBW2iTUi1GgZ6swmoug3Oy4Xw==}
engines: {node: '>=16.0.0'}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
highlight.js@10.7.3:
resolution: {integrity: sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==}
2026-02-21 03:10:39 +00:00
hono@4.12.0:
resolution: {integrity: sha512-NekXntS5M94pUfiVZ8oXXK/kkri+5WpX2/Ik+LVsl+uvw+soj4roXIsPqO+XsWrAw20mOzaXOZf3Q7PfB9A/IA==}
engines: {node: '>=16.9.0'}
hosted-git-info@7.0.2:
resolution: {integrity: sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==}
engines: {node: ^16.14.0 || >=18.0.0}
hosted-git-info@9.0.3:
resolution: {integrity: sha512-Hc+ghLoSt6QaYZUv0WBiIvmMDZuZZ7oaDvdH8MbfOO4lOsxdXLEvuC6ePoGs9H1X9oCLyq6+NVN0MKqD+ydxyg==}
engines: {node: ^20.17.0 || >=22.9.0}
hpagent@1.2.0:
resolution: {integrity: sha512-A91dYTeIB6NoXG+PxTQpCCDDnfHsW9kc06Lvpu1TEe9gnd6ZFeiBoRO9JvzEv6xK7EX97/dUE8g/vBMTqTS3CA==}
engines: {node: '>=14'}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
html-encoding-sniffer@6.0.0:
resolution: {integrity: sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==}
engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
html-entities@2.3.3:
resolution: {integrity: sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==}
2026-02-21 03:10:39 +00:00
html-escaper@2.0.2:
resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==}
http-cache-semantics@4.2.0:
resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==}
2026-02-21 03:10:39 +00:00
http-errors@2.0.1:
resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==}
engines: {node: '>= 0.8'}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
http-proxy-agent@7.0.2:
resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==}
engines: {node: '>= 14'}
https-proxy-agent@5.0.1:
resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==}
engines: {node: '>= 6'}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
https-proxy-agent@7.0.6:
resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==}
engines: {node: '>= 14'}
human-signals@2.1.0:
resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==}
engines: {node: '>=10.17.0'}
2026-02-21 03:10:39 +00:00
iconv-lite@0.7.2:
resolution: {integrity: sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==}
engines: {node: '>=0.10.0'}
ieee754@1.2.1:
resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
ignore-walk@8.0.0:
resolution: {integrity: sha512-FCeMZT4NiRQGh+YkeKMtWrOmBgWjHjMJ26WQWrRQyoyzqevdaGSakUaJW5xQYmjLlUVk2qUnCjYVBax9EKKg8A==}
engines: {node: ^20.17.0 || >=22.9.0}
2026-02-21 03:10:39 +00:00
ignore@5.3.2:
resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
engines: {node: '>= 4'}
ignore@7.0.5:
resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==}
engines: {node: '>= 4'}
import-in-the-middle@3.3.1:
resolution: {integrity: sha512-0rymlHSFLwZ0ixx8DaQkoIyZojJPY2a0K2nEYslhKJ6jIYO/m0IcCb7iQsFPmS7WmKwISZiIrv5Icstrw/CmqA==}
engines: {node: '>=18'}
2026-02-21 03:10:39 +00:00
imurmurhash@0.1.4:
resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
engines: {node: '>=0.8.19'}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
indent-string@4.0.0:
resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==}
engines: {node: '>=8'}
indent-string@5.0.0:
resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==}
engines: {node: '>=12'}
inflight@1.0.6:
resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
2026-02-21 03:10:39 +00:00
inherits@2.0.4:
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
ini@2.0.0:
resolution: {integrity: sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==}
engines: {node: '>=10'}
ini@6.0.0:
resolution: {integrity: sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ==}
engines: {node: ^20.17.0 || >=22.9.0}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
ini@7.0.0:
resolution: {integrity: sha512-ifK0CgjALofS5bkrcTy4RaQ9Vx2Knf/eLeIO+NaswQEpH1UblrtTSCIvN71qQDMq0PeQ/SSPojvEJp9vvvfr+w==}
engines: {node: ^22.22.2 || ^24.15.0 || >=26.0.0}
ink@6.8.0:
resolution: {integrity: sha512-sbl1RdLOgkO9isK42WCZlJCFN9hb++sX9dsklOvfd1YQ3bQ2AiFu12Q6tFlr0HvEUvzraJntQCCpfEoUe9DSzA==}
engines: {node: '>=20'}
peerDependencies:
'@types/react': '>=19.0.0'
react: '>=19.0.0'
react-devtools-core: '>=6.1.2'
peerDependenciesMeta:
'@types/react':
optional: true
react-devtools-core:
optional: true
2026-02-21 03:10:39 +00:00
inquirer@12.11.1:
resolution: {integrity: sha512-9VF7mrY+3OmsAfjH3yKz/pLbJ5z22E23hENKw3/LNSaA/sAt3v49bDRY+Ygct1xwuKT+U+cBfTzjCPySna69Qw==}
engines: {node: '>=18'}
peerDependencies:
'@types/node': '>=18'
peerDependenciesMeta:
'@types/node':
optional: true
ip-address@10.0.1:
resolution: {integrity: sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA==}
engines: {node: '>= 12'}
ipaddr.js@1.9.1:
resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==}
engines: {node: '>= 0.10'}
ipaddr.js@2.3.0:
resolution: {integrity: sha512-Zv/pA+ciVFbCSBBjGfaKUya/CcGmUHzTydLMaTwrUUEM2DIEO3iZvueGxmacvmN50fGpGVKeTXpb2LcYQxeVdg==}
engines: {node: '>= 10'}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
is-core-module@2.16.2:
resolution: {integrity: sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==}
engines: {node: '>= 0.4'}
2026-02-21 03:10:39 +00:00
is-extglob@2.1.1:
resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
engines: {node: '>=0.10.0'}
is-fullwidth-code-point@3.0.0:
resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
engines: {node: '>=8'}
is-fullwidth-code-point@5.1.0:
resolution: {integrity: sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==}
engines: {node: '>=18'}
2026-02-21 03:10:39 +00:00
is-glob@4.0.3:
resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
engines: {node: '>=0.10.0'}
is-in-ci@2.0.0:
resolution: {integrity: sha512-cFeerHriAnhrQSbpAxL37W1wcJKUUX07HyLWZCW1URJT/ra3GyUTzBgUnh24TMVfNTV2Hij2HLxkPHFZfOZy5w==}
engines: {node: '>=20'}
hasBin: true
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
is-potential-custom-element-name@1.0.1:
resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==}
2026-02-21 03:10:39 +00:00
is-promise@4.0.0:
resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==}
is-stream@2.0.1:
resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==}
engines: {node: '>=8'}
is-unicode-supported@2.1.0:
resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==}
engines: {node: '>=18'}
2026-02-21 03:10:39 +00:00
isexe@2.0.0:
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
isexe@4.0.0:
resolution: {integrity: sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==}
engines: {node: '>=20'}
isomorphic-ws@5.0.0:
resolution: {integrity: sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==}
peerDependencies:
ws: '*'
2026-02-21 03:10:39 +00:00
istanbul-lib-coverage@3.2.2:
resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==}
engines: {node: '>=8'}
istanbul-lib-report@3.0.1:
resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==}
engines: {node: '>=10'}
istanbul-reports@3.2.0:
resolution: {integrity: sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==}
engines: {node: '>=8'}
feat(mcpd+deploy): serve web UI at /ui + smoke tests + docs (Stage 6) The closing stage. mcpd now hosts the Stage 5 SPA, the Docker image bundles the build artifact, a smoke test exercises the personality HTTP surface end-to-end, and the user-facing docs spell out the mental model. mcpd: - Add @fastify/static dep. - New routes/web-ui.ts: registers /ui/* against a static bundle. Looks for the bundle at $MCPD_WEB_ROOT, then /usr/share/mcpd/web (the Docker image path), then a dev-tree fallback. Logs and skips cleanly if missing — API-only deploys keep working. - SPA fallback: any /ui/<path> that doesn't match a file falls through to index.html so direct hits to react-router URLs work. - /ui/* falls through to `kind: skip` in mapUrlToPermission, so the static assets are served unauthenticated. Each API call from the SPA still carries the bearer token. Deploy: - Dockerfile.mcpd builds the @mcpctl/web bundle in the same builder stage and copies dist/ to /usr/share/mcpd/web in the runtime image. Smoke (personality.smoke.test.ts): - Live mcpd flow: create secret/llm/agent/personality, attach an agent-direct prompt, verify the binding listing, reject double- attach (409) + foreign-agent prompt (400), set defaultPersonality by name, detach + delete cleanup. Docs: - New docs/personalities.md: VLAN-on-ethernet model, system-block ordering table, three prompt scopes, CLI walkthrough, web UI walkthrough, full API surface, RBAC notes. - agents.md and chat.md cross-link. - README's Agents section gains a Personalities subsection. Test count after Stage 6: mcpd: 801/801 cli: 430/430 web: 7/7 db: 58/62 (4 pre-existing) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:48:43 +01:00
jackspeak@4.2.3:
resolution: {integrity: sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg==}
engines: {node: 20 || >=22}
2026-02-21 03:10:39 +00:00
jiti@2.6.1:
resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==}
hasBin: true
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
jiti@2.7.0:
resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==}
hasBin: true
2026-02-21 03:10:39 +00:00
jose@6.1.3:
resolution: {integrity: sha512-0TpaTfihd4QMNwrz/ob2Bp7X04yuxJkjRGi4aKmOqwhov54i6u79oCv7T+C7lo70MKH6BesI3vscD1yb/yzKXQ==}
js-tokens@10.0.0:
resolution: {integrity: sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
js-tokens@4.0.0:
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
2026-02-21 03:10:39 +00:00
js-yaml@4.1.1:
resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==}
hasBin: true
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
jsdom@28.1.0:
resolution: {integrity: sha512-0+MoQNYyr2rBHqO1xilltfDjV9G7ymYGlAUazgcDLQaUf8JDHbuGwsxN6U9qWaElZ4w1B2r7yEGIL3GdeW3Rug==}
engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0}
peerDependencies:
canvas: ^3.0.0
peerDependenciesMeta:
canvas:
optional: true
jsep@1.4.0:
resolution: {integrity: sha512-B7qPcEVE3NVkmSJbaYxvv4cHkVW7DQsZz13pUMrfS8z8Q/BuShN+gcTXrUlPiGqM2/t/EEaI030bpxMqY8gMlw==}
engines: {node: '>= 10.16.0'}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
jsesc@3.1.0:
resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==}
engines: {node: '>=6'}
hasBin: true
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
json-bigint@1.0.0:
resolution: {integrity: sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==}
2026-02-21 03:10:39 +00:00
json-buffer@3.0.1:
resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==}
json-parse-even-better-errors@5.0.0:
resolution: {integrity: sha512-ZF1nxZ28VhQouRWhUcVlUIN3qwSgPuswK05s/HIaoetAoE/9tngVmCHjSxmSQPav1nd+lPtTL0YZ/2AFdR/iYQ==}
engines: {node: ^20.17.0 || >=22.9.0}
2026-02-21 03:10:39 +00:00
json-schema-ref-resolver@3.0.0:
resolution: {integrity: sha512-hOrZIVL5jyYFjzk7+y7n5JDzGlU8rfWDuYyHwGa2WA8/pcmMHezp2xsVwxrebD/Q9t8Nc5DboieySDpCp4WG4A==}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
json-schema-to-ts@3.1.1:
resolution: {integrity: sha512-+DWg8jCJG2TEnpy7kOm/7/AxaYoaRbjVB4LFZLySZlWn8exGs3A4OLJR966cVvU26N7X9TWxl+Jsw7dzAqKT6g==}
engines: {node: '>=16'}
2026-02-21 03:10:39 +00:00
json-schema-traverse@0.4.1:
resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
json-schema-traverse@1.0.0:
resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==}
json-schema-typed@8.0.2:
resolution: {integrity: sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
json-schema@0.4.0:
resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==}
2026-02-21 03:10:39 +00:00
json-stable-stringify-without-jsonify@1.0.1:
resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
json-stringify-nice@1.1.4:
resolution: {integrity: sha512-5Z5RFW63yxReJ7vANgW6eZFGWaQvnPE3WNmZoOJrSkGju2etKA2L5rrOa1sm877TVTFt57A80BH1bArcmlLfPw==}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
json5@2.2.3:
resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==}
engines: {node: '>=6'}
hasBin: true
jsonparse@1.3.1:
resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==}
engines: {'0': node >= 0.2.0}
jsonpath-plus@10.4.0:
resolution: {integrity: sha512-T92WWatJXmhBbKsgH/0hl+jxjdXrifi5IKeMY02DWggRxX0UElcbVzPlmgLTbvsPeW1PasQ6xE2Q75stkhGbsA==}
engines: {node: '>=18.0.0'}
hasBin: true
just-diff-apply@5.5.0:
resolution: {integrity: sha512-OYTthRfSh55WOItVqwpefPtNt2VdKsq5AnAK6apdtR6yCH8pr0CmSr710J0Mf+WdQy7K/OzMy7K2MgAfdQURDw==}
just-diff@6.0.2:
resolution: {integrity: sha512-S59eriX5u3/QhMNq3v/gm8Kd0w8OS6Tz2FS1NG4blv+z0MuQcBRJyFWjdovM0Rad4/P4aUPFtnkNjMjyMlMSYA==}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
jwa@2.0.1:
resolution: {integrity: sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==}
jws@4.0.1:
resolution: {integrity: sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==}
2026-02-21 03:10:39 +00:00
keyv@4.5.4:
resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
kubernetes-types@1.30.0:
resolution: {integrity: sha512-Dew1okvhM/SQcIa2rcgujNndZwU8VnSapDgdxlYoB84ZlpAD43U6KLAFqYo17ykSFGHNPrg0qry0bP+GJd9v7Q==}
2026-02-21 03:10:39 +00:00
levn@0.4.1:
resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
engines: {node: '>= 0.8.0'}
light-my-request@6.6.0:
resolution: {integrity: sha512-CHYbu8RtboSIoVsHZ6Ye4cj4Aw/yg2oAFimlF7mNvfDV192LR7nDiKtSIfCuLT7KokPSTn/9kfVLm5OGN0A28A==}
feat(web): bold redesign — Tailwind v4 + shadcn-style primitives + Skills/Proposals/Revisions UI Phase 6 of the Skills + Revisions + Proposals work. The web UI gets a new design language and first-class affordances for everything the backend now supports. ## Visual direction - Tailwind v4 with custom @theme block (oklch tokens). Dark-mode-only (internal tool — light mode doubles QA surface). - Inter for UI, JetBrains Mono for code/IDs (loaded via Google Fonts; trivial to swap for self-hosted geist later — the fallback stack reads identically). - Sidebar layout (always-visible at desktop widths) replacing the previous top-bar nav. Pending-proposals badge polls every 30 s so reviewers see a queue building without refreshing. - Lucide icons throughout. - Spacing and radii on Tailwind defaults. Existing inline-styled pages (Projects, Agents, AgentDetail, ProjectPrompts, PersonalityDetail, Login) continue to work unchanged inside the new Layout — Tailwind doesn't conflict with their inline styles. A follow-up can migrate them incrementally. ## What's added ### Build infra (src/web/) - package.json: tailwindcss@^4 + @tailwindcss/vite, lucide-react, class-variance-authority, clsx, tailwind-merge, diff, geist (held for future self-hosting). - vite.config.ts: registers the @tailwindcss/vite plugin. - src/index.css: Tailwind import + @theme tokens + @layer base. - src/main.tsx: imports index.css. - src/lib/utils.ts: shadcn-style cn() helper. ### shadcn-style primitives (src/components/ui/) Hand-written rather than generated via `npx shadcn` so the repo doesn't depend on a CLI tool that needs interactive runtime: - button.tsx — variants: primary / secondary / ghost / danger / link; sizes: sm / md / lg / icon. - card.tsx — Card + Header/Title/Description/Content/Footer subparts. - badge.tsx — variants: default / info / success / warning / danger / outline. - input.tsx — Input + Textarea + Label. - tabs.tsx — no-dep accessible Tabs (no Radix needed for our use). - separator.tsx — h/v separator with role=separator. ### Diff component (src/components/Diff.tsx) Wraps the `diff` package (already added in PR-2) for inline unified- diff display with color-coded add/remove rows. Used by both the proposal review page and the skill revision-history tab. ### New pages (src/pages/) - Dashboard.tsx — at-a-glance home. Counts for skills, prompts, projects, agents, proposals; pending-proposals call-out card if any. - Skills.tsx — list view, separated into Global vs Project/Agent- scoped sections. - SkillDetail.tsx — name + semver + description; tabs for SKILL.md / Files / Metadata / History. History tab shows revisions with click-to-diff against the live body. - Proposals.tsx — queue with Pending/Approved/Rejected tabs. Pending count is highlighted in amber. - ProposalDetail.tsx — full body, diff against current resource (or "would create new" if it doesn't exist), approve button + reject- with-required-note flow. ### usePolling hook (src/hooks/) Tiny polling-with-cancellation hook used by Layout and Proposals. ### Layout rewrite (src/components/Layout.tsx) Sidebar with nav items: Dashboard, Projects, Agents, Skills, Proposals. Lucide icons. Active-route highlighting via NavLink. Pending-proposals warning badge on the Proposals item. ### Routes (src/App.tsx) New routes: /dashboard, /skills, /skills/:name, /proposals, /proposals/:id. Default redirects to /dashboard. ### API types (src/api.ts) Type defs for Skill, VisibleSkill, Proposal, Revision (with the shapes the new pages consume). ## Tests Existing 7 web tests still pass (Login + api). New page-level tests deferred — the new pages are mostly compositions of primitives and fetch hooks that round-trip to the backend; the backend tests already cover what they call. PR-7 polish can add render-and-click tests if coverage drift surfaces. ## Verification - `pnpm --filter @mcpctl/web build` clean, no warnings. - `pnpm test:run` whole monorepo: 162 test files / 2157 tests green. - Visual smoke deferred — needs a running mcpd to populate the fixtures. Manual smoke tested locally is the next step. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:54:55 +01:00
lightningcss-android-arm64@1.32.0:
resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==}
engines: {node: '>= 12.0.0'}
cpu: [arm64]
os: [android]
lightningcss-darwin-arm64@1.32.0:
resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==}
engines: {node: '>= 12.0.0'}
cpu: [arm64]
os: [darwin]
lightningcss-darwin-x64@1.32.0:
resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==}
engines: {node: '>= 12.0.0'}
cpu: [x64]
os: [darwin]
lightningcss-freebsd-x64@1.32.0:
resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==}
engines: {node: '>= 12.0.0'}
cpu: [x64]
os: [freebsd]
lightningcss-linux-arm-gnueabihf@1.32.0:
resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==}
engines: {node: '>= 12.0.0'}
cpu: [arm]
os: [linux]
lightningcss-linux-arm64-gnu@1.32.0:
resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==}
engines: {node: '>= 12.0.0'}
cpu: [arm64]
os: [linux]
lightningcss-linux-arm64-musl@1.32.0:
resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==}
engines: {node: '>= 12.0.0'}
cpu: [arm64]
os: [linux]
lightningcss-linux-x64-gnu@1.32.0:
resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==}
engines: {node: '>= 12.0.0'}
cpu: [x64]
os: [linux]
lightningcss-linux-x64-musl@1.32.0:
resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==}
engines: {node: '>= 12.0.0'}
cpu: [x64]
os: [linux]
lightningcss-win32-arm64-msvc@1.32.0:
resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==}
engines: {node: '>= 12.0.0'}
cpu: [arm64]
os: [win32]
lightningcss-win32-x64-msvc@1.32.0:
resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==}
engines: {node: '>= 12.0.0'}
cpu: [x64]
os: [win32]
lightningcss@1.32.0:
resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==}
engines: {node: '>= 12.0.0'}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
locate-path@3.0.0:
resolution: {integrity: sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==}
engines: {node: '>=6'}
2026-02-21 03:10:39 +00:00
locate-path@6.0.0:
resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
engines: {node: '>=10'}
lodash.camelcase@4.3.0:
resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==}
long@5.3.2:
resolution: {integrity: sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==}
lru-cache@10.4.3:
resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==}
2026-02-21 03:10:39 +00:00
lru-cache@11.2.6:
resolution: {integrity: sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==}
engines: {node: 20 || >=22}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
lru-cache@5.1.1:
resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
feat(web): bold redesign — Tailwind v4 + shadcn-style primitives + Skills/Proposals/Revisions UI Phase 6 of the Skills + Revisions + Proposals work. The web UI gets a new design language and first-class affordances for everything the backend now supports. ## Visual direction - Tailwind v4 with custom @theme block (oklch tokens). Dark-mode-only (internal tool — light mode doubles QA surface). - Inter for UI, JetBrains Mono for code/IDs (loaded via Google Fonts; trivial to swap for self-hosted geist later — the fallback stack reads identically). - Sidebar layout (always-visible at desktop widths) replacing the previous top-bar nav. Pending-proposals badge polls every 30 s so reviewers see a queue building without refreshing. - Lucide icons throughout. - Spacing and radii on Tailwind defaults. Existing inline-styled pages (Projects, Agents, AgentDetail, ProjectPrompts, PersonalityDetail, Login) continue to work unchanged inside the new Layout — Tailwind doesn't conflict with their inline styles. A follow-up can migrate them incrementally. ## What's added ### Build infra (src/web/) - package.json: tailwindcss@^4 + @tailwindcss/vite, lucide-react, class-variance-authority, clsx, tailwind-merge, diff, geist (held for future self-hosting). - vite.config.ts: registers the @tailwindcss/vite plugin. - src/index.css: Tailwind import + @theme tokens + @layer base. - src/main.tsx: imports index.css. - src/lib/utils.ts: shadcn-style cn() helper. ### shadcn-style primitives (src/components/ui/) Hand-written rather than generated via `npx shadcn` so the repo doesn't depend on a CLI tool that needs interactive runtime: - button.tsx — variants: primary / secondary / ghost / danger / link; sizes: sm / md / lg / icon. - card.tsx — Card + Header/Title/Description/Content/Footer subparts. - badge.tsx — variants: default / info / success / warning / danger / outline. - input.tsx — Input + Textarea + Label. - tabs.tsx — no-dep accessible Tabs (no Radix needed for our use). - separator.tsx — h/v separator with role=separator. ### Diff component (src/components/Diff.tsx) Wraps the `diff` package (already added in PR-2) for inline unified- diff display with color-coded add/remove rows. Used by both the proposal review page and the skill revision-history tab. ### New pages (src/pages/) - Dashboard.tsx — at-a-glance home. Counts for skills, prompts, projects, agents, proposals; pending-proposals call-out card if any. - Skills.tsx — list view, separated into Global vs Project/Agent- scoped sections. - SkillDetail.tsx — name + semver + description; tabs for SKILL.md / Files / Metadata / History. History tab shows revisions with click-to-diff against the live body. - Proposals.tsx — queue with Pending/Approved/Rejected tabs. Pending count is highlighted in amber. - ProposalDetail.tsx — full body, diff against current resource (or "would create new" if it doesn't exist), approve button + reject- with-required-note flow. ### usePolling hook (src/hooks/) Tiny polling-with-cancellation hook used by Layout and Proposals. ### Layout rewrite (src/components/Layout.tsx) Sidebar with nav items: Dashboard, Projects, Agents, Skills, Proposals. Lucide icons. Active-route highlighting via NavLink. Pending-proposals warning badge on the Proposals item. ### Routes (src/App.tsx) New routes: /dashboard, /skills, /skills/:name, /proposals, /proposals/:id. Default redirects to /dashboard. ### API types (src/api.ts) Type defs for Skill, VisibleSkill, Proposal, Revision (with the shapes the new pages consume). ## Tests Existing 7 web tests still pass (Login + api). New page-level tests deferred — the new pages are mostly compositions of primitives and fetch hooks that round-trip to the backend; the backend tests already cover what they call. PR-7 polish can add render-and-click tests if coverage drift surfaces. ## Verification - `pnpm --filter @mcpctl/web build` clean, no warnings. - `pnpm test:run` whole monorepo: 162 test files / 2157 tests green. - Visual smoke deferred — needs a running mcpd to populate the fixtures. Manual smoke tested locally is the next step. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:54:55 +01:00
lucide-react@0.487.0:
resolution: {integrity: sha512-aKqhOQ+YmFnwq8dWgGjOuLc8V1R9/c/yOd+zDY4+ohsR2Jo05lSGc3WsstYPIzcTpeosN7LoCkLReUUITvaIvw==}
peerDependencies:
react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
lz-string@1.5.0:
resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==}
hasBin: true
2026-02-21 03:10:39 +00:00
magic-string@0.30.21:
resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
magicast@0.5.2:
resolution: {integrity: sha512-E3ZJh4J3S9KfwdjZhe2afj6R9lGIN5Pher1pF39UGrXRqq/VDaGVIGN13BjHd2u8B61hArAGOnso7nBOouW3TQ==}
make-dir@3.1.0:
resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==}
engines: {node: '>=8'}
2026-02-21 03:10:39 +00:00
make-dir@4.0.0:
resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==}
engines: {node: '>=10'}
make-fetch-happen@15.0.6:
resolution: {integrity: sha512-Je0fLJ0F5atA7F+eIlLzk+Wkcl57JDf4kf+EW8xiP5E31xOQxkIxTbgf1Oi1Lw9tRI9UEMRdI5Vz2xTzoNU1Jw==}
engines: {node: ^20.17.0 || >=22.9.0}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
marked@14.0.0:
resolution: {integrity: sha512-uIj4+faQ+MgHgwUW1l2PsPglZLOLOT1uErt06dAPtx2kjteLAkbsd/0FiYg/MGS+i7ZKLb7w2WClxHkzOOuryQ==}
engines: {node: '>= 18'}
hasBin: true
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
marked@17.0.1:
resolution: {integrity: sha512-boeBdiS0ghpWcSwoNm/jJBwdpFaMnZWRzjA6SkUMYb40SVaN1x7mmfGKp0jvexGcx+7y2La5zRZsYFZI6Qpypg==}
engines: {node: '>= 20'}
hasBin: true
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
marked@18.0.5:
resolution: {integrity: sha512-S6GcvALHg6K4ohtu4E7x0a1AqhAjp6cV8KhLSyN9qVapnzJkusVBxZRcIU9AeYsbe6P1hKDusSbEOzGyyuce6w==}
engines: {node: '>= 20'}
hasBin: true
2026-02-21 03:10:39 +00:00
math-intrinsics@1.1.0:
resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
engines: {node: '>= 0.4'}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
mdn-data@2.27.1:
resolution: {integrity: sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==}
2026-02-21 03:10:39 +00:00
media-typer@1.1.0:
resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==}
engines: {node: '>= 0.8'}
merge-descriptors@2.0.0:
resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==}
engines: {node: '>=18'}
merge-stream@2.0.0:
resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==}
mime-db@1.52.0:
resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
engines: {node: '>= 0.6'}
2026-02-21 03:10:39 +00:00
mime-db@1.54.0:
resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==}
engines: {node: '>= 0.6'}
mime-types@2.1.35:
resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
engines: {node: '>= 0.6'}
2026-02-21 03:10:39 +00:00
mime-types@3.0.2:
resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==}
engines: {node: '>=18'}
feat(mcpd+deploy): serve web UI at /ui + smoke tests + docs (Stage 6) The closing stage. mcpd now hosts the Stage 5 SPA, the Docker image bundles the build artifact, a smoke test exercises the personality HTTP surface end-to-end, and the user-facing docs spell out the mental model. mcpd: - Add @fastify/static dep. - New routes/web-ui.ts: registers /ui/* against a static bundle. Looks for the bundle at $MCPD_WEB_ROOT, then /usr/share/mcpd/web (the Docker image path), then a dev-tree fallback. Logs and skips cleanly if missing — API-only deploys keep working. - SPA fallback: any /ui/<path> that doesn't match a file falls through to index.html so direct hits to react-router URLs work. - /ui/* falls through to `kind: skip` in mapUrlToPermission, so the static assets are served unauthenticated. Each API call from the SPA still carries the bearer token. Deploy: - Dockerfile.mcpd builds the @mcpctl/web bundle in the same builder stage and copies dist/ to /usr/share/mcpd/web in the runtime image. Smoke (personality.smoke.test.ts): - Live mcpd flow: create secret/llm/agent/personality, attach an agent-direct prompt, verify the binding listing, reject double- attach (409) + foreign-agent prompt (400), set defaultPersonality by name, detach + delete cleanup. Docs: - New docs/personalities.md: VLAN-on-ethernet model, system-block ordering table, three prompt scopes, CLI walkthrough, web UI walkthrough, full API surface, RBAC notes. - agents.md and chat.md cross-link. - README's Agents section gains a Personalities subsection. Test count after Stage 6: mcpd: 801/801 cli: 430/430 web: 7/7 db: 58/62 (4 pre-existing) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:48:43 +01:00
mime@3.0.0:
resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==}
engines: {node: '>=10.0.0'}
hasBin: true
mimic-fn@2.1.0:
resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==}
engines: {node: '>=6'}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
min-indent@1.0.1:
resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==}
engines: {node: '>=4'}
2026-02-21 03:10:39 +00:00
minimatch@10.2.2:
resolution: {integrity: sha512-+G4CpNBxa5MprY+04MbgOw1v7So6n5JY166pFi9KfYwT78fxScCeSNQSNzp6dpPSW2rONOps6Ocam1wFhCgoVw==}
engines: {node: 18 || 20 || >=22}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
minimatch@10.2.5:
resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==}
engines: {node: 18 || 20 || >=22}
minimatch@3.1.2:
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
minimatch@8.0.7:
resolution: {integrity: sha512-V+1uQNdzybxa14e/p00HZnQNNcTjnRJjDxg2V8wtkjFctq4M7hXFws4oekyTP0Jebeq7QYtpFyOeBAjc88zvYg==}
engines: {node: '>=16 || 14 >=14.17'}
2026-02-21 03:10:39 +00:00
minimatch@9.0.5:
resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
engines: {node: '>=16 || 14 >=14.17'}
minimist@1.2.8:
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
minipass-collect@2.0.1:
resolution: {integrity: sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==}
engines: {node: '>=16 || 14 >=14.17'}
minipass-fetch@5.0.2:
resolution: {integrity: sha512-2d0q2a8eCi2IRg/IGubCNRJoYbA1+YPXAzQVRFmB45gdGZafyivnZ5YSEfo3JikbjGxOdntGFvBQGqaSMXlAFQ==}
engines: {node: ^20.17.0 || >=22.9.0}
minipass-flush@1.0.7:
resolution: {integrity: sha512-TbqTz9cUwWyHS2Dy89P3ocAGUGxKjjLuR9z8w4WUTGAVgEj17/4nhgo2Du56i0Fm3Pm30g4iA8Lcqctc76jCzA==}
engines: {node: '>= 8'}
minipass-pipeline@1.2.4:
resolution: {integrity: sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==}
engines: {node: '>=8'}
minipass-sized@2.0.0:
resolution: {integrity: sha512-zSsHhto5BcUVM2m1LurnXY6M//cGhVaegT71OfOXoprxT6o780GZd792ea6FfrQkuU4usHZIUczAQMRUE2plzA==}
engines: {node: '>=8'}
minipass@3.3.6:
resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==}
engines: {node: '>=8'}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
minipass@4.2.8:
resolution: {integrity: sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==}
engines: {node: '>=8'}
minipass@5.0.0:
resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==}
engines: {node: '>=8'}
2026-02-21 03:10:39 +00:00
minipass@7.1.3:
resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==}
engines: {node: '>=16 || 14 >=14.17'}
minizlib@2.1.2:
resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==}
engines: {node: '>= 8'}
minizlib@3.1.0:
resolution: {integrity: sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==}
engines: {node: '>= 18'}
mkdirp-classic@0.5.3:
resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==}
mkdirp@1.0.4:
resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==}
engines: {node: '>=10'}
hasBin: true
2026-02-21 03:10:39 +00:00
mnemonist@0.40.0:
resolution: {integrity: sha512-kdd8AFNig2AD5Rkih7EPCXhu/iMvwevQFX/uEiGhZyPZi7fHqOoF4V4kHLpCfysxXMgQ4B52kdPMCwARshKvEg==}
module-details-from-path@1.0.4:
resolution: {integrity: sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
monaco-editor@0.55.1:
resolution: {integrity: sha512-jz4x+TJNFHwHtwuV9vA9rMujcZRb0CEilTEwG2rRSpe/A7Jdkuj8xPKttCgOh+v/lkHy7HsZ64oj+q3xoAFl9A==}
2026-02-21 03:10:39 +00:00
ms@2.1.3:
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
msgpackr-extract@3.0.4:
resolution: {integrity: sha512-4kmO/MdyUIkLIvTPr8VHLil4AtoKIoniWPIEk5+CDy0xnWC84azhSFmuJ7PxZdsYtiP5kEeQsORAVIeMgxT+Hw==}
hasBin: true
msgpackr@2.0.5:
resolution: {integrity: sha512-cef05H/dSYpLpqp3sj/qyZh5vhUYCalnaLO7j1yOmpsR0y/XwLVtK7r5gn+U/F7CTEfMowcGhlUQJDLcLf7jcA==}
multipasta@0.2.8:
resolution: {integrity: sha512-ZPWuMKyv0cSO29f7hozp+k6+crZbQijV8ipMvxNxRf2SwtYGTX1ZX89Kd20VV4H9Znonx+EQn+iy1wGQsJ+b+Q==}
2026-02-21 03:10:39 +00:00
mute-stream@2.0.0:
resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==}
engines: {node: ^18.17.0 || >=20.5.0}
nan@2.25.0:
resolution: {integrity: sha512-0M90Ag7Xn5KMLLZ7zliPWP3rT90P6PN+IzVFS0VqmnPktBk3700xUVv8Ikm9EUaUE5SDWdp/BIxdENzVznpm1g==}
2026-02-21 03:10:39 +00:00
nanoid@3.3.11:
resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==}
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
hasBin: true
natural-compare@1.4.0:
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
negotiator@1.0.0:
resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==}
engines: {node: '>= 0.6'}
feat(web): bold redesign — Tailwind v4 + shadcn-style primitives + Skills/Proposals/Revisions UI Phase 6 of the Skills + Revisions + Proposals work. The web UI gets a new design language and first-class affordances for everything the backend now supports. ## Visual direction - Tailwind v4 with custom @theme block (oklch tokens). Dark-mode-only (internal tool — light mode doubles QA surface). - Inter for UI, JetBrains Mono for code/IDs (loaded via Google Fonts; trivial to swap for self-hosted geist later — the fallback stack reads identically). - Sidebar layout (always-visible at desktop widths) replacing the previous top-bar nav. Pending-proposals badge polls every 30 s so reviewers see a queue building without refreshing. - Lucide icons throughout. - Spacing and radii on Tailwind defaults. Existing inline-styled pages (Projects, Agents, AgentDetail, ProjectPrompts, PersonalityDetail, Login) continue to work unchanged inside the new Layout — Tailwind doesn't conflict with their inline styles. A follow-up can migrate them incrementally. ## What's added ### Build infra (src/web/) - package.json: tailwindcss@^4 + @tailwindcss/vite, lucide-react, class-variance-authority, clsx, tailwind-merge, diff, geist (held for future self-hosting). - vite.config.ts: registers the @tailwindcss/vite plugin. - src/index.css: Tailwind import + @theme tokens + @layer base. - src/main.tsx: imports index.css. - src/lib/utils.ts: shadcn-style cn() helper. ### shadcn-style primitives (src/components/ui/) Hand-written rather than generated via `npx shadcn` so the repo doesn't depend on a CLI tool that needs interactive runtime: - button.tsx — variants: primary / secondary / ghost / danger / link; sizes: sm / md / lg / icon. - card.tsx — Card + Header/Title/Description/Content/Footer subparts. - badge.tsx — variants: default / info / success / warning / danger / outline. - input.tsx — Input + Textarea + Label. - tabs.tsx — no-dep accessible Tabs (no Radix needed for our use). - separator.tsx — h/v separator with role=separator. ### Diff component (src/components/Diff.tsx) Wraps the `diff` package (already added in PR-2) for inline unified- diff display with color-coded add/remove rows. Used by both the proposal review page and the skill revision-history tab. ### New pages (src/pages/) - Dashboard.tsx — at-a-glance home. Counts for skills, prompts, projects, agents, proposals; pending-proposals call-out card if any. - Skills.tsx — list view, separated into Global vs Project/Agent- scoped sections. - SkillDetail.tsx — name + semver + description; tabs for SKILL.md / Files / Metadata / History. History tab shows revisions with click-to-diff against the live body. - Proposals.tsx — queue with Pending/Approved/Rejected tabs. Pending count is highlighted in amber. - ProposalDetail.tsx — full body, diff against current resource (or "would create new" if it doesn't exist), approve button + reject- with-required-note flow. ### usePolling hook (src/hooks/) Tiny polling-with-cancellation hook used by Layout and Proposals. ### Layout rewrite (src/components/Layout.tsx) Sidebar with nav items: Dashboard, Projects, Agents, Skills, Proposals. Lucide icons. Active-route highlighting via NavLink. Pending-proposals warning badge on the Proposals item. ### Routes (src/App.tsx) New routes: /dashboard, /skills, /skills/:name, /proposals, /proposals/:id. Default redirects to /dashboard. ### API types (src/api.ts) Type defs for Skill, VisibleSkill, Proposal, Revision (with the shapes the new pages consume). ## Tests Existing 7 web tests still pass (Login + api). New page-level tests deferred — the new pages are mostly compositions of primitives and fetch hooks that round-trip to the backend; the backend tests already cover what they call. PR-7 polish can add render-and-click tests if coverage drift surfaces. ## Verification - `pnpm --filter @mcpctl/web build` clean, no warnings. - `pnpm test:run` whole monorepo: 162 test files / 2157 tests green. - Visual smoke deferred — needs a running mcpd to populate the fixtures. Manual smoke tested locally is the next step. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:54:55 +01:00
next@16.2.5:
resolution: {integrity: sha512-TkVTm9F2WEulkgGljm4wPwNgvCCWCVw6StUHsZb8WZpHFRjepoUWg3d7L4IMg7IyjcJ4Co9eVhpro8e8O+KarQ==}
engines: {node: '>=20.9.0'}
hasBin: true
peerDependencies:
'@opentelemetry/api': ^1.1.0
'@playwright/test': ^1.51.1
babel-plugin-react-compiler: '*'
react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0
react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0
sass: ^1.3.0
peerDependenciesMeta:
'@opentelemetry/api':
optional: true
'@playwright/test':
optional: true
babel-plugin-react-compiler:
optional: true
sass:
optional: true
node-addon-api@5.1.0:
resolution: {integrity: sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
node-domexception@1.0.0:
resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==}
engines: {node: '>=10.5.0'}
deprecated: Use your platform's native DOMException instead
2026-02-21 03:10:39 +00:00
node-fetch-native@1.6.7:
resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==}
node-fetch@2.7.0:
resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==}
engines: {node: 4.x || >=6.0.0}
peerDependencies:
encoding: ^0.1.0
peerDependenciesMeta:
encoding:
optional: true
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
node-fetch@3.3.2:
resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
node-gyp-build-optional-packages@5.2.2:
resolution: {integrity: sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==}
hasBin: true
node-gyp@12.4.0:
resolution: {integrity: sha512-OMcPNvqTCFUnNaBlmdgq+lfNqY7gTiSmNRDjY3uAXRyudeKZEZxu3CLtjMQrx4zZxCX2b/mpNqTtwuCJgXhHkw==}
engines: {node: ^20.17.0 || >=22.9.0}
hasBin: true
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
node-releases@2.0.38:
resolution: {integrity: sha512-3qT/88Y3FbH/Kx4szpQQ4HzUbVrHPKTLVpVocKiLfoYvw9XSGOX2FmD2d6DrXbVYyAQTF2HeF6My8jmzx7/CRw==}
nopt@5.0.0:
resolution: {integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==}
engines: {node: '>=6'}
hasBin: true
nopt@9.0.0:
resolution: {integrity: sha512-Zhq3a+yFKrYwSBluL4H9XP3m3y5uvQkB/09CwDruCiRmR/UJYnn9W4R48ry0uGC70aeTPKLynBtscP9efFFcPw==}
engines: {node: ^20.17.0 || >=22.9.0}
hasBin: true
normalize-package-data@6.0.2:
resolution: {integrity: sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==}
engines: {node: ^16.14.0 || >=18.0.0}
npm-bundled@5.0.0:
resolution: {integrity: sha512-JLSpbzh6UUXIEoqPsYBvVNVmyrjVZ1fzEFbqxKkTJQkWBO3xFzFT+KDnSKQWwOQNbuWRwt5LSD6HOTLGIWzfrw==}
engines: {node: ^20.17.0 || >=22.9.0}
npm-install-checks@8.0.0:
resolution: {integrity: sha512-ScAUdMpyzkbpxoNekQ3tNRdFI8SJ86wgKZSQZdUxT+bj0wVFpsEMWnkXP0twVe1gJyNF5apBWDJhhIbgrIViRA==}
engines: {node: ^20.17.0 || >=22.9.0}
npm-normalize-package-bin@5.0.0:
resolution: {integrity: sha512-CJi3OS4JLsNMmr2u07OJlhcrPxCeOeP/4xq67aWNai6TNWWbTrlNDgl8NcFKVlcBKp18GPj+EzbNIgrBfZhsag==}
engines: {node: ^20.17.0 || >=22.9.0}
npm-package-arg@13.0.2:
resolution: {integrity: sha512-IciCE3SY3uE84Ld8WZU23gAPPV9rIYod4F+rc+vJ7h7cwAJt9Vk6TVsK60ry7Uj3SRS3bqRRIGuTp9YVlk6WNA==}
engines: {node: ^20.17.0 || >=22.9.0}
npm-packlist@10.0.4:
resolution: {integrity: sha512-uMW73iajD8hiH4ZBxEV3HC+eTnppIqwakjOYuvgddnalIw2lJguKviK1pcUJDlIWm1wSJkchpDZDSVVsZEYRng==}
engines: {node: ^20.17.0 || >=22.9.0}
npm-pick-manifest@11.0.3:
resolution: {integrity: sha512-buzyCfeoGY/PxKqmBqn1IUJrZnUi1VVJTdSSRPGI60tJdUhUoSQFhs0zycJokDdOznQentgrpf8LayEHyyYlqQ==}
engines: {node: ^20.17.0 || >=22.9.0}
npm-registry-fetch@19.1.1:
resolution: {integrity: sha512-TakBap6OM1w0H73VZVDf44iFXsOS3h+L4wVMXmbWOQroZgFhMch0juN6XSzBNlD965yIKvWg2dfu7NSiaYLxtw==}
engines: {node: ^20.17.0 || >=22.9.0}
npm-run-path@4.0.1:
resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==}
engines: {node: '>=8'}
npmlog@5.0.1:
resolution: {integrity: sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==}
deprecated: This package is no longer supported.
2026-02-21 03:10:39 +00:00
nypm@0.6.5:
resolution: {integrity: sha512-K6AJy1GMVyfyMXRVB88700BJqNUkByijGJM8kEHpLdcAt+vSQAVfkWWHYzuRXHSY6xA2sNc5RjTj0p9rE2izVQ==}
engines: {node: '>=18'}
hasBin: true
oauth4webapi@3.8.5:
resolution: {integrity: sha512-A8jmyUckVhRJj5lspguklcl90Ydqk61H3dcU0oLhH3Yv13KpAliKTt5hknpGGPZSSfOwGyraNEFmofDYH+1kSg==}
2026-02-21 03:10:39 +00:00
object-assign@4.1.1:
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
engines: {node: '>=0.10.0'}
object-inspect@1.13.4:
resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==}
engines: {node: '>= 0.4'}
obliterator@2.0.5:
resolution: {integrity: sha512-42CPE9AhahZRsMNslczq0ctAEtqk8Eka26QofnqC346BZdHDySk3LWka23LI7ULIw11NmltpiLagIq8gBozxTw==}
obug@2.1.1:
resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==}
ohash@2.0.11:
resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==}
on-exit-leak-free@2.1.2:
resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==}
engines: {node: '>=14.0.0'}
on-finished@2.4.1:
resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==}
engines: {node: '>= 0.8'}
once@1.4.0:
resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
onetime@5.1.2:
resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==}
engines: {node: '>=6'}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
openai@6.26.0:
resolution: {integrity: sha512-zd23dbWTjiJ6sSAX6s0HrCZi41JwTA1bQVs0wLQPZ2/5o2gxOJA5wh7yOAUgwYybfhDXyhwlpeQf7Mlgx8EOCA==}
hasBin: true
peerDependencies:
ws: ^8.18.0
zod: ^3.25 || ^4.0
peerDependenciesMeta:
ws:
optional: true
zod:
optional: true
openid-client@6.8.2:
resolution: {integrity: sha512-uOvTCndr4udZsKihJ68H9bUICrriHdUVJ6Az+4Ns6cW55rwM5h0bjVIzDz2SxgOI84LKjFyjOFvERLzdTUROGA==}
2026-02-21 03:10:39 +00:00
optionator@0.9.4:
resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==}
engines: {node: '>= 0.8.0'}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
p-limit@2.3.0:
resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==}
engines: {node: '>=6'}
2026-02-21 03:10:39 +00:00
p-limit@3.1.0:
resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
engines: {node: '>=10'}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
p-locate@3.0.0:
resolution: {integrity: sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==}
engines: {node: '>=6'}
2026-02-21 03:10:39 +00:00
p-locate@5.0.0:
resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
engines: {node: '>=10'}
p-map@7.0.5:
resolution: {integrity: sha512-e8vJF4XdVkzqqSHguEMz41mQO1wKwxKm5ENrUJQUu9kLDCtn83cxbyHZcszr4QC5zEA7WffRRC4gsTecC7J9oA==}
engines: {node: '>=18'}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
p-retry@4.6.2:
resolution: {integrity: sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==}
engines: {node: '>=8'}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
p-try@2.2.0:
resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==}
engines: {node: '>=6'}
2026-02-21 03:10:39 +00:00
package-json-from-dist@1.0.1:
resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==}
pacote@21.5.1:
resolution: {integrity: sha512-KvcJ9iy3crysCsgqc4+PknH/w6jkrp8JN36mpZBPwNaDRwTfMZD37YzRazNstiZUOhuF5pno9f78n9mEJBavwg==}
engines: {node: ^20.17.0 || >=22.9.0}
hasBin: true
parse-conflict-json@5.0.1:
resolution: {integrity: sha512-ZHEmNKMq1wyJXNwLxyHnluPfRAFSIliBvbK/UiOceROt4Xh9Pz0fq49NytIaeaCUf5VR86hwQ/34FCcNU5/LKQ==}
engines: {node: ^20.17.0 || >=22.9.0}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
parse5@7.3.0:
resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
parse5@8.0.1:
resolution: {integrity: sha512-z1e/HMG90obSGeidlli3hj7cbocou0/wa5HacvI3ASx34PecNjNQeaHNo5WIZpWofN9kgkqV1q5YvXe3F0FoPw==}
2026-02-21 03:10:39 +00:00
parseurl@1.3.3:
resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==}
engines: {node: '>= 0.8'}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
partial-json@0.1.7:
resolution: {integrity: sha512-Njv/59hHaokb/hRUjce3Hdv12wd60MtM9Z5Olmn+nehe0QDAsRtRbJPvJ0Z91TusF0SuZRIvnM+S4l6EIP8leA==}
patch-console@2.0.0:
resolution: {integrity: sha512-0YNdUceMdaQwoKce1gatDScmMo5pu/tfABfnzEqeG0gtTmd7mh/WcwgUjtAeOU7N8nFFlbQBnFK2gXW5fGvmMA==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
path-exists@3.0.0:
resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==}
engines: {node: '>=4'}
2026-02-21 03:10:39 +00:00
path-exists@4.0.0:
resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
engines: {node: '>=8'}
path-is-absolute@1.0.1:
resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
engines: {node: '>=0.10.0'}
2026-02-21 03:10:39 +00:00
path-key@3.1.1:
resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
engines: {node: '>=8'}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
path-parse@1.0.7:
resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
path-scurry@1.11.1:
resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==}
engines: {node: '>=16 || 14 >=14.18'}
2026-02-21 03:10:39 +00:00
path-scurry@2.0.2:
resolution: {integrity: sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==}
engines: {node: 18 || 20 || >=22}
path-to-regexp@8.3.0:
resolution: {integrity: sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==}
pathe@2.0.3:
resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==}
perfect-debounce@1.0.0:
resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==}
picocolors@1.1.1:
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
picomatch@4.0.3:
resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==}
engines: {node: '>=12'}
pino-abstract-transport@3.0.0:
resolution: {integrity: sha512-wlfUczU+n7Hy/Ha5j9a/gZNy7We5+cXp8YL+X+PG8S0KXxw7n/JXA3c46Y0zQznIJ83URJiwy7Lh56WLokNuxg==}
pino-std-serializers@7.1.0:
resolution: {integrity: sha512-BndPH67/JxGExRgiX1dX0w1FvZck5Wa4aal9198SrRhZjH3GxKQUKIBnYJTdj2HDN3UQAS06HlfcSbQj2OHmaw==}
pino@10.3.1:
resolution: {integrity: sha512-r34yH/GlQpKZbU1BvFFqOjhISRo1MNx1tWYsYvmj6KIRHSPMT2+yHOEb1SG6NMvRoHRF0a07kCOox/9yakl1vg==}
hasBin: true
pkce-challenge@5.0.1:
resolution: {integrity: sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==}
engines: {node: '>=16.20.0'}
pkg-types@2.3.0:
resolution: {integrity: sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
pkg-up@3.1.0:
resolution: {integrity: sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==}
engines: {node: '>=8'}
postcss-selector-parser@7.1.4:
resolution: {integrity: sha512-HeP7D2wyhkR+XaK6v4W8oRF62Dsz4flyuczALJp61GckGm42u1saSSJ/0auvcBqxs3jMRFEcPK34At/0JBKdOg==}
engines: {node: '>=4'}
feat(web): bold redesign — Tailwind v4 + shadcn-style primitives + Skills/Proposals/Revisions UI Phase 6 of the Skills + Revisions + Proposals work. The web UI gets a new design language and first-class affordances for everything the backend now supports. ## Visual direction - Tailwind v4 with custom @theme block (oklch tokens). Dark-mode-only (internal tool — light mode doubles QA surface). - Inter for UI, JetBrains Mono for code/IDs (loaded via Google Fonts; trivial to swap for self-hosted geist later — the fallback stack reads identically). - Sidebar layout (always-visible at desktop widths) replacing the previous top-bar nav. Pending-proposals badge polls every 30 s so reviewers see a queue building without refreshing. - Lucide icons throughout. - Spacing and radii on Tailwind defaults. Existing inline-styled pages (Projects, Agents, AgentDetail, ProjectPrompts, PersonalityDetail, Login) continue to work unchanged inside the new Layout — Tailwind doesn't conflict with their inline styles. A follow-up can migrate them incrementally. ## What's added ### Build infra (src/web/) - package.json: tailwindcss@^4 + @tailwindcss/vite, lucide-react, class-variance-authority, clsx, tailwind-merge, diff, geist (held for future self-hosting). - vite.config.ts: registers the @tailwindcss/vite plugin. - src/index.css: Tailwind import + @theme tokens + @layer base. - src/main.tsx: imports index.css. - src/lib/utils.ts: shadcn-style cn() helper. ### shadcn-style primitives (src/components/ui/) Hand-written rather than generated via `npx shadcn` so the repo doesn't depend on a CLI tool that needs interactive runtime: - button.tsx — variants: primary / secondary / ghost / danger / link; sizes: sm / md / lg / icon. - card.tsx — Card + Header/Title/Description/Content/Footer subparts. - badge.tsx — variants: default / info / success / warning / danger / outline. - input.tsx — Input + Textarea + Label. - tabs.tsx — no-dep accessible Tabs (no Radix needed for our use). - separator.tsx — h/v separator with role=separator. ### Diff component (src/components/Diff.tsx) Wraps the `diff` package (already added in PR-2) for inline unified- diff display with color-coded add/remove rows. Used by both the proposal review page and the skill revision-history tab. ### New pages (src/pages/) - Dashboard.tsx — at-a-glance home. Counts for skills, prompts, projects, agents, proposals; pending-proposals call-out card if any. - Skills.tsx — list view, separated into Global vs Project/Agent- scoped sections. - SkillDetail.tsx — name + semver + description; tabs for SKILL.md / Files / Metadata / History. History tab shows revisions with click-to-diff against the live body. - Proposals.tsx — queue with Pending/Approved/Rejected tabs. Pending count is highlighted in amber. - ProposalDetail.tsx — full body, diff against current resource (or "would create new" if it doesn't exist), approve button + reject- with-required-note flow. ### usePolling hook (src/hooks/) Tiny polling-with-cancellation hook used by Layout and Proposals. ### Layout rewrite (src/components/Layout.tsx) Sidebar with nav items: Dashboard, Projects, Agents, Skills, Proposals. Lucide icons. Active-route highlighting via NavLink. Pending-proposals warning badge on the Proposals item. ### Routes (src/App.tsx) New routes: /dashboard, /skills, /skills/:name, /proposals, /proposals/:id. Default redirects to /dashboard. ### API types (src/api.ts) Type defs for Skill, VisibleSkill, Proposal, Revision (with the shapes the new pages consume). ## Tests Existing 7 web tests still pass (Login + api). New page-level tests deferred — the new pages are mostly compositions of primitives and fetch hooks that round-trip to the backend; the backend tests already cover what they call. PR-7 polish can add render-and-click tests if coverage drift surfaces. ## Verification - `pnpm --filter @mcpctl/web build` clean, no warnings. - `pnpm test:run` whole monorepo: 162 test files / 2157 tests green. - Visual smoke deferred — needs a running mcpd to populate the fixtures. Manual smoke tested locally is the next step. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:54:55 +01:00
postcss@8.4.31:
resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==}
engines: {node: ^10 || ^12 || >=14}
2026-02-21 03:10:39 +00:00
postcss@8.5.6:
resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==}
engines: {node: ^10 || ^12 || >=14}
prelude-ls@1.2.1:
resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
engines: {node: '>= 0.8.0'}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
pretty-format@27.5.1:
resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==}
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
2026-02-21 03:10:39 +00:00
prisma@6.19.2:
resolution: {integrity: sha512-XTKeKxtQElcq3U9/jHyxSPgiRgeYDKxWTPOf6NkXA0dNj5j40MfEsZkMbyNpwDWCUv7YBFUl7I2VK/6ALbmhEg==}
engines: {node: '>=18.18'}
hasBin: true
peerDependencies:
typescript: '>=5.1.0'
peerDependenciesMeta:
typescript:
optional: true
proc-log@6.1.0:
resolution: {integrity: sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==}
engines: {node: ^20.17.0 || >=22.9.0}
2026-02-21 03:10:39 +00:00
process-warning@4.0.1:
resolution: {integrity: sha512-3c2LzQ3rY9d0hc1emcsHhfT9Jwz0cChib/QN89oME2R451w5fy3f0afAhERFZAwrbDU43wk12d0ORBpDVME50Q==}
process-warning@5.0.0:
resolution: {integrity: sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==}
proggy@4.0.0:
resolution: {integrity: sha512-MbA4R+WQT76ZBm/5JUpV9yqcJt92175+Y0Bodg3HgiXzrmKu7Ggq+bpn6y6wHH+gN9NcyKn3yg1+d47VaKwNAQ==}
engines: {node: ^20.17.0 || >=22.9.0}
promise-all-reject-late@1.0.1:
resolution: {integrity: sha512-vuf0Lf0lOxyQREH7GDIOUMLS7kz+gs8i6B+Yi8dC68a2sychGrHTJYghMBD6k7eUcH0H5P73EckCA48xijWqXw==}
promise-call-limit@3.0.2:
resolution: {integrity: sha512-mRPQO2T1QQVw11E7+UdCJu7S61eJVWknzml9sC1heAdj1jxl0fWMBypIt9ZOcLFf8FkG995ZD7RnVk7HH72fZw==}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
proper-lockfile@4.1.2:
resolution: {integrity: sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==}
protobufjs@7.5.4:
resolution: {integrity: sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==}
engines: {node: '>=12.0.0'}
2026-02-21 03:10:39 +00:00
proxy-addr@2.0.7:
resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==}
engines: {node: '>= 0.10'}
pump@3.0.3:
resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==}
2026-02-21 03:10:39 +00:00
punycode@2.3.1:
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
engines: {node: '>=6'}
pure-rand@6.1.0:
resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
pure-rand@8.4.2:
resolution: {integrity: sha512-vvuOGgcuPJAirlHvuQw1TrOiw7ptaIXXmIbNuiNOY6lNGJJH49PQ1Kj4nd783nPdQhQdicgOjVI2yI/9BD6/Ng==}
2026-02-21 03:10:39 +00:00
qs@6.15.0:
resolution: {integrity: sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==}
engines: {node: '>=0.6'}
quick-format-unescaped@4.0.4:
resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==}
range-parser@1.2.1:
resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==}
engines: {node: '>= 0.6'}
raw-body@3.0.2:
resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==}
engines: {node: '>= 0.10'}
rc9@2.1.2:
resolution: {integrity: sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
react-dom@19.2.5:
resolution: {integrity: sha512-J5bAZz+DXMMwW/wV3xzKke59Af6CHY7G4uYLN1OvBcKEsWOs4pQExj86BBKamxl/Ik5bx9whOrvBlSDfWzgSag==}
peerDependencies:
react: ^19.2.5
react-is@17.0.2:
resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==}
react-reconciler@0.33.0:
resolution: {integrity: sha512-KetWRytFv1epdpJc3J4G75I4WrplZE5jOL7Yq0p34+OVOKF4Se7WrdIdVC45XsSSmUTlht2FM/fM1FZb1mfQeA==}
engines: {node: '>=0.10.0'}
peerDependencies:
react: ^19.2.0
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
react-refresh@0.18.0:
resolution: {integrity: sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==}
engines: {node: '>=0.10.0'}
react-router-dom@7.14.2:
resolution: {integrity: sha512-YZcM5ES8jJSM+KrJ9BdvHHqlnGTg5tH3sC5ChFRj4inosKctdyzBDhOyyHdGk597q2OT6NTrCA1OvB/YDwfekQ==}
engines: {node: '>=20.0.0'}
peerDependencies:
react: '>=18'
react-dom: '>=18'
react-router@7.14.2:
resolution: {integrity: sha512-yCqNne6I8IB6rVCH7XUvlBK7/QKyqypBFGv+8dj4QBFJiiRX+FG7/nkdAvGElyvVZ/HQP5N19wzteuTARXi5Gw==}
engines: {node: '>=20.0.0'}
peerDependencies:
react: '>=18'
react-dom: '>=18'
peerDependenciesMeta:
react-dom:
optional: true
react@19.2.4:
resolution: {integrity: sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==}
engines: {node: '>=0.10.0'}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
react@19.2.5:
resolution: {integrity: sha512-llUJLzz1zTUBrskt2pwZgLq59AemifIftw4aB7JxOqf1HY2FDaGDxgwpAPVzHU1kdWabH7FauP4i1oEeer2WCA==}
engines: {node: '>=0.10.0'}
read-cmd-shim@6.0.0:
resolution: {integrity: sha512-1zM5HuOfagXCBWMN83fuFI/x+T/UhZ7k+KIzhrHXcQoeX5+7gmaDYjELQHmmzIodumBHeByBJT4QYS7ufAgs7A==}
engines: {node: ^20.17.0 || >=22.9.0}
readable-stream@3.6.2:
resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==}
engines: {node: '>= 6'}
2026-02-21 03:10:39 +00:00
readdirp@4.1.2:
resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==}
engines: {node: '>= 14.18.0'}
real-require@0.2.0:
resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==}
engines: {node: '>= 12.13.0'}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
redent@3.0.0:
resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==}
engines: {node: '>=8'}
require-directory@2.1.1:
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
engines: {node: '>=0.10.0'}
2026-02-21 03:10:39 +00:00
require-from-string@2.0.2:
resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
engines: {node: '>=0.10.0'}
require-in-the-middle@8.0.1:
resolution: {integrity: sha512-QT7FVMXfWOYFbeRBF6nu+I6tr2Tf3u0q8RIEjNob/heKY/nh7drD/k7eeMFmSQgnTtCzLDcCu/XEnpW2wk4xCQ==}
engines: {node: '>=9.3.0 || >=8.10.0 <9.0.0'}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
reselect@4.1.8:
resolution: {integrity: sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ==}
2026-02-21 03:10:39 +00:00
resolve-pkg-maps@1.0.0:
resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
resolve@1.22.12:
resolution: {integrity: sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==}
engines: {node: '>= 0.4'}
hasBin: true
restore-cursor@4.0.0:
resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
2026-02-21 03:10:39 +00:00
ret@0.5.0:
resolution: {integrity: sha512-I1XxrZSQ+oErkRR4jYbAyEEu2I0avBvvMM5JN+6EBprOGRCs63ENqZ3vjavq8fBw2+62G5LF5XelKwuJpcvcxw==}
engines: {node: '>=10'}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
retry@0.12.0:
resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==}
engines: {node: '>= 4'}
retry@0.13.1:
resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==}
engines: {node: '>= 4'}
2026-02-21 03:10:39 +00:00
reusify@1.1.0:
resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==}
engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
rfc4648@1.5.4:
resolution: {integrity: sha512-rRg/6Lb+IGfJqO05HZkN50UtY7K/JhxJag1kP23+zyMfrvoB0B7RWv06MbOzoc79RgCdNTiUaNsTT1AJZ7Z+cg==}
2026-02-21 03:10:39 +00:00
rfdc@1.4.1:
resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==}
rimraf@3.0.2:
resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==}
deprecated: Rimraf versions prior to v4 are no longer supported
hasBin: true
2026-02-21 03:10:39 +00:00
rimraf@6.1.3:
resolution: {integrity: sha512-LKg+Cr2ZF61fkcaK1UdkH2yEBBKnYjTyWzTJT6KNPcSPaiT7HSdhtMXQuN5wkTX0Xu72KQ1l8S42rlmexS2hSA==}
engines: {node: 20 || >=22}
hasBin: true
rollup@4.58.0:
resolution: {integrity: sha512-wbT0mBmWbIvvq8NeEYWWvevvxnOyhKChir47S66WCxw1SXqhw7ssIYejnQEVt7XYQpsj2y8F9PM+Cr3SNEa0gw==}
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
hasBin: true
router@2.2.0:
resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==}
engines: {node: '>= 18'}
run-async@4.0.6:
resolution: {integrity: sha512-IoDlSLTs3Yq593mb3ZoKWKXMNu3UpObxhgA/Xuid5p4bbfi2jdY1Hj0m1K+0/tEuQTxIGMhQDqGjKb7RuxGpAQ==}
engines: {node: '>=0.12.0'}
rxjs@7.8.2:
resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
s-js@0.4.9:
resolution: {integrity: sha512-RtpOm+cM6O0sHg6IA70wH+UC3FZcND+rccBZpBAHzlUgNO2Bm5BN+FnM8+OBxzXdwpKWFwX11JGF0MFRkhSoIQ==}
safe-buffer@5.2.1:
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
2026-02-21 03:10:39 +00:00
safe-regex2@5.0.0:
resolution: {integrity: sha512-YwJwe5a51WlK7KbOJREPdjNrpViQBI3p4T50lfwPuDhZnE3XGVTlGvi+aolc5+RvxDD6bnUmjVsU9n1eboLUYw==}
safe-stable-stringify@2.5.0:
resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==}
engines: {node: '>=10'}
safer-buffer@2.1.2:
resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
saxes@6.0.0:
resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==}
engines: {node: '>=v12.22.7'}
scheduler@0.27.0:
resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==}
2026-02-21 03:10:39 +00:00
secure-json-parse@4.1.0:
resolution: {integrity: sha512-l4KnYfEyqYJxDwlNVyRfO2E4NTHfMKAWdUuA8J0yve2Dz/E/PdBepY03RvyJpssIpRFwJoCD55wA+mEDs6ByWA==}
semver@6.3.1:
resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
hasBin: true
2026-02-21 03:10:39 +00:00
semver@7.7.4:
resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==}
engines: {node: '>=10'}
hasBin: true
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
semver@7.8.0:
resolution: {integrity: sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==}
engines: {node: '>=10'}
hasBin: true
2026-02-21 03:10:39 +00:00
send@1.2.1:
resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==}
engines: {node: '>= 18'}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
seroval-plugins@1.5.6:
resolution: {integrity: sha512-HXuLAX2pu/UByPpaeo/TaMfvMIi+1QqIoPJYCcAtU8QkVNwgR6MPlGuCQTErV1JwraaMbYaWVIBX7mppzGLATQ==}
engines: {node: '>=10'}
peerDependencies:
seroval: ^1.0
seroval@1.5.6:
resolution: {integrity: sha512-rVQVWjjSvlINzaQPZH5JFqsqEsIWdTxY3iJZCnTL/5gQbXIRooVZKI60tVCkOVfzcRPejboxO2t0P89dg5mQaA==}
engines: {node: '>=10'}
2026-02-21 03:10:39 +00:00
serve-static@2.2.1:
resolution: {integrity: sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==}
engines: {node: '>= 18'}
set-blocking@2.0.0:
resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==}
2026-02-21 03:10:39 +00:00
set-cookie-parser@2.7.2:
resolution: {integrity: sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==}
setprototypeof@1.2.0:
resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==}
feat(web): bold redesign — Tailwind v4 + shadcn-style primitives + Skills/Proposals/Revisions UI Phase 6 of the Skills + Revisions + Proposals work. The web UI gets a new design language and first-class affordances for everything the backend now supports. ## Visual direction - Tailwind v4 with custom @theme block (oklch tokens). Dark-mode-only (internal tool — light mode doubles QA surface). - Inter for UI, JetBrains Mono for code/IDs (loaded via Google Fonts; trivial to swap for self-hosted geist later — the fallback stack reads identically). - Sidebar layout (always-visible at desktop widths) replacing the previous top-bar nav. Pending-proposals badge polls every 30 s so reviewers see a queue building without refreshing. - Lucide icons throughout. - Spacing and radii on Tailwind defaults. Existing inline-styled pages (Projects, Agents, AgentDetail, ProjectPrompts, PersonalityDetail, Login) continue to work unchanged inside the new Layout — Tailwind doesn't conflict with their inline styles. A follow-up can migrate them incrementally. ## What's added ### Build infra (src/web/) - package.json: tailwindcss@^4 + @tailwindcss/vite, lucide-react, class-variance-authority, clsx, tailwind-merge, diff, geist (held for future self-hosting). - vite.config.ts: registers the @tailwindcss/vite plugin. - src/index.css: Tailwind import + @theme tokens + @layer base. - src/main.tsx: imports index.css. - src/lib/utils.ts: shadcn-style cn() helper. ### shadcn-style primitives (src/components/ui/) Hand-written rather than generated via `npx shadcn` so the repo doesn't depend on a CLI tool that needs interactive runtime: - button.tsx — variants: primary / secondary / ghost / danger / link; sizes: sm / md / lg / icon. - card.tsx — Card + Header/Title/Description/Content/Footer subparts. - badge.tsx — variants: default / info / success / warning / danger / outline. - input.tsx — Input + Textarea + Label. - tabs.tsx — no-dep accessible Tabs (no Radix needed for our use). - separator.tsx — h/v separator with role=separator. ### Diff component (src/components/Diff.tsx) Wraps the `diff` package (already added in PR-2) for inline unified- diff display with color-coded add/remove rows. Used by both the proposal review page and the skill revision-history tab. ### New pages (src/pages/) - Dashboard.tsx — at-a-glance home. Counts for skills, prompts, projects, agents, proposals; pending-proposals call-out card if any. - Skills.tsx — list view, separated into Global vs Project/Agent- scoped sections. - SkillDetail.tsx — name + semver + description; tabs for SKILL.md / Files / Metadata / History. History tab shows revisions with click-to-diff against the live body. - Proposals.tsx — queue with Pending/Approved/Rejected tabs. Pending count is highlighted in amber. - ProposalDetail.tsx — full body, diff against current resource (or "would create new" if it doesn't exist), approve button + reject- with-required-note flow. ### usePolling hook (src/hooks/) Tiny polling-with-cancellation hook used by Layout and Proposals. ### Layout rewrite (src/components/Layout.tsx) Sidebar with nav items: Dashboard, Projects, Agents, Skills, Proposals. Lucide icons. Active-route highlighting via NavLink. Pending-proposals warning badge on the Proposals item. ### Routes (src/App.tsx) New routes: /dashboard, /skills, /skills/:name, /proposals, /proposals/:id. Default redirects to /dashboard. ### API types (src/api.ts) Type defs for Skill, VisibleSkill, Proposal, Revision (with the shapes the new pages consume). ## Tests Existing 7 web tests still pass (Login + api). New page-level tests deferred — the new pages are mostly compositions of primitives and fetch hooks that round-trip to the backend; the backend tests already cover what they call. PR-7 polish can add render-and-click tests if coverage drift surfaces. ## Verification - `pnpm --filter @mcpctl/web build` clean, no warnings. - `pnpm test:run` whole monorepo: 162 test files / 2157 tests green. - Visual smoke deferred — needs a running mcpd to populate the fixtures. Manual smoke tested locally is the next step. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:54:55 +01:00
sharp@0.34.5:
resolution: {integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
2026-02-21 03:10:39 +00:00
shebang-command@2.0.0:
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
engines: {node: '>=8'}
shebang-regex@3.0.0:
resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
engines: {node: '>=8'}
side-channel-list@1.0.0:
resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==}
engines: {node: '>= 0.4'}
side-channel-map@1.0.1:
resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==}
engines: {node: '>= 0.4'}
side-channel-weakmap@1.0.2:
resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==}
engines: {node: '>= 0.4'}
side-channel@1.1.0:
resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==}
engines: {node: '>= 0.4'}
siginfo@2.0.0:
resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==}
signal-exit@3.0.7:
resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
2026-02-21 03:10:39 +00:00
signal-exit@4.1.0:
resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
engines: {node: '>=14'}
sigstore@4.1.1:
resolution: {integrity: sha512-endqECJkfhozrXMK5ngu/UAA0xVcVEFdnHJCElGaExypjW+HK5i6zu3NteLoaX/iFbRUbC3+DjttQs0GARr+5w==}
engines: {node: ^20.17.0 || >=22.9.0}
slice-ansi@7.1.2:
resolution: {integrity: sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==}
engines: {node: '>=18'}
slice-ansi@8.0.0:
resolution: {integrity: sha512-stxByr12oeeOyY2BlviTNQlYV5xOj47GirPr4yA1hE9JCtxfQN0+tVbkxwCtYDQWhEKWFHsEK48ORg5jrouCAg==}
engines: {node: '>=20'}
smart-buffer@4.2.0:
resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==}
engines: {node: '>= 6.0.0', npm: '>= 3.0.0'}
socks-proxy-agent@8.0.5:
resolution: {integrity: sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==}
engines: {node: '>= 14'}
socks@2.8.7:
resolution: {integrity: sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==}
engines: {node: '>= 10.0.0', npm: '>= 3.0.0'}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
solid-js@1.9.12:
resolution: {integrity: sha512-QzKaSJq2/iDrWR1As6MHZQ8fQkdOBf8GReYb7L5iKwMGceg7HxDcaOHk0at66tNgn9U2U7dXo8ZZpLIAmGMzgw==}
2026-02-21 03:10:39 +00:00
sonic-boom@4.2.1:
resolution: {integrity: sha512-w6AxtubXa2wTXAUsZMMWERrsIRAdrK0Sc+FUytWvYAhBJLyuI4llrMIC1DtlNSdI99EI86KZum2MMq3EAZlF9Q==}
source-map-js@1.2.1:
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
engines: {node: '>=0.10.0'}
source-map-support@0.5.21:
resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==}
source-map@0.6.1:
resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
engines: {node: '>=0.10.0'}
spdx-correct@3.2.0:
resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==}
spdx-exceptions@2.5.0:
resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==}
spdx-expression-parse@3.0.1:
resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==}
spdx-expression-parse@4.0.0:
resolution: {integrity: sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==}
spdx-license-ids@3.0.23:
resolution: {integrity: sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==}
split-ca@1.0.1:
resolution: {integrity: sha512-Q5thBSxp5t8WPTTJQS59LrGqOZqOsrhDGDVm8azCqIBjSBd7nd9o2PM+mDulQQkh8h//4U6hFZnc/mul8t5pWQ==}
2026-02-21 03:10:39 +00:00
split2@4.2.0:
resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==}
engines: {node: '>= 10.x'}
ssh2@1.17.0:
resolution: {integrity: sha512-wPldCk3asibAjQ/kziWQQt1Wh3PgDFpC0XpwclzKcdT1vql6KeYxf5LIt4nlFkUeR8WuphYMKqUA56X4rjbfgQ==}
engines: {node: '>=10.16.0'}
ssri@13.0.1:
resolution: {integrity: sha512-QUiRf1+u9wPTL/76GTYlKttDEBWV1ga9ZXW8BG6kfdeyyM8LGPix9gROyg9V2+P0xNyF3X2Go526xKFdMZrHSQ==}
engines: {node: ^20.17.0 || >=22.9.0}
stack-utils@2.0.6:
resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==}
engines: {node: '>=10'}
2026-02-21 03:10:39 +00:00
stackback@0.0.2:
resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
state-local@1.0.7:
resolution: {integrity: sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==}
2026-02-21 03:10:39 +00:00
statuses@2.0.2:
resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==}
engines: {node: '>= 0.8'}
std-env@3.10.0:
resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==}
stream-buffers@3.0.3:
resolution: {integrity: sha512-pqMqwQCso0PBJt2PQmDO0cFj0lyqmiwOMiMSkVtRokl7e+ZTRYgDHKnuZNbqjiJXgsg4nuqtD/zxuo9KqTp0Yw==}
engines: {node: '>= 0.10.0'}
streamx@2.25.0:
resolution: {integrity: sha512-0nQuG6jf1w+wddNEEXCF4nTg3LtufWINB5eFEN+5TNZW7KWJp6x87+JFL43vaAUPyCfH1wID+mNVyW6OHtFamg==}
2026-02-21 03:10:39 +00:00
string-width@4.2.3:
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
engines: {node: '>=8'}
string-width@7.2.0:
resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==}
engines: {node: '>=18'}
string-width@8.2.0:
resolution: {integrity: sha512-6hJPQ8N0V0P3SNmP6h2J99RLuzrWz2gvT7VnK5tKvrNqJoyS9W4/Fb8mo31UiPvy00z7DQXkP2hnKBVav76thw==}
engines: {node: '>=20'}
string_decoder@1.3.0:
resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==}
2026-02-21 03:10:39 +00:00
strip-ansi@6.0.1:
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
engines: {node: '>=8'}
strip-ansi@7.1.2:
resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==}
engines: {node: '>=12'}
strip-final-newline@2.0.0:
resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==}
engines: {node: '>=6'}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
strip-indent@3.0.0:
resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==}
engines: {node: '>=8'}
feat(web): bold redesign — Tailwind v4 + shadcn-style primitives + Skills/Proposals/Revisions UI Phase 6 of the Skills + Revisions + Proposals work. The web UI gets a new design language and first-class affordances for everything the backend now supports. ## Visual direction - Tailwind v4 with custom @theme block (oklch tokens). Dark-mode-only (internal tool — light mode doubles QA surface). - Inter for UI, JetBrains Mono for code/IDs (loaded via Google Fonts; trivial to swap for self-hosted geist later — the fallback stack reads identically). - Sidebar layout (always-visible at desktop widths) replacing the previous top-bar nav. Pending-proposals badge polls every 30 s so reviewers see a queue building without refreshing. - Lucide icons throughout. - Spacing and radii on Tailwind defaults. Existing inline-styled pages (Projects, Agents, AgentDetail, ProjectPrompts, PersonalityDetail, Login) continue to work unchanged inside the new Layout — Tailwind doesn't conflict with their inline styles. A follow-up can migrate them incrementally. ## What's added ### Build infra (src/web/) - package.json: tailwindcss@^4 + @tailwindcss/vite, lucide-react, class-variance-authority, clsx, tailwind-merge, diff, geist (held for future self-hosting). - vite.config.ts: registers the @tailwindcss/vite plugin. - src/index.css: Tailwind import + @theme tokens + @layer base. - src/main.tsx: imports index.css. - src/lib/utils.ts: shadcn-style cn() helper. ### shadcn-style primitives (src/components/ui/) Hand-written rather than generated via `npx shadcn` so the repo doesn't depend on a CLI tool that needs interactive runtime: - button.tsx — variants: primary / secondary / ghost / danger / link; sizes: sm / md / lg / icon. - card.tsx — Card + Header/Title/Description/Content/Footer subparts. - badge.tsx — variants: default / info / success / warning / danger / outline. - input.tsx — Input + Textarea + Label. - tabs.tsx — no-dep accessible Tabs (no Radix needed for our use). - separator.tsx — h/v separator with role=separator. ### Diff component (src/components/Diff.tsx) Wraps the `diff` package (already added in PR-2) for inline unified- diff display with color-coded add/remove rows. Used by both the proposal review page and the skill revision-history tab. ### New pages (src/pages/) - Dashboard.tsx — at-a-glance home. Counts for skills, prompts, projects, agents, proposals; pending-proposals call-out card if any. - Skills.tsx — list view, separated into Global vs Project/Agent- scoped sections. - SkillDetail.tsx — name + semver + description; tabs for SKILL.md / Files / Metadata / History. History tab shows revisions with click-to-diff against the live body. - Proposals.tsx — queue with Pending/Approved/Rejected tabs. Pending count is highlighted in amber. - ProposalDetail.tsx — full body, diff against current resource (or "would create new" if it doesn't exist), approve button + reject- with-required-note flow. ### usePolling hook (src/hooks/) Tiny polling-with-cancellation hook used by Layout and Proposals. ### Layout rewrite (src/components/Layout.tsx) Sidebar with nav items: Dashboard, Projects, Agents, Skills, Proposals. Lucide icons. Active-route highlighting via NavLink. Pending-proposals warning badge on the Proposals item. ### Routes (src/App.tsx) New routes: /dashboard, /skills, /skills/:name, /proposals, /proposals/:id. Default redirects to /dashboard. ### API types (src/api.ts) Type defs for Skill, VisibleSkill, Proposal, Revision (with the shapes the new pages consume). ## Tests Existing 7 web tests still pass (Login + api). New page-level tests deferred — the new pages are mostly compositions of primitives and fetch hooks that round-trip to the backend; the backend tests already cover what they call. PR-7 polish can add render-and-click tests if coverage drift surfaces. ## Verification - `pnpm --filter @mcpctl/web build` clean, no warnings. - `pnpm test:run` whole monorepo: 162 test files / 2157 tests green. - Visual smoke deferred — needs a running mcpd to populate the fixtures. Manual smoke tested locally is the next step. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:54:55 +01:00
styled-jsx@5.1.6:
resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==}
engines: {node: '>= 12.0.0'}
peerDependencies:
'@babel/core': '*'
babel-plugin-macros: '*'
react: '>= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0'
peerDependenciesMeta:
'@babel/core':
optional: true
babel-plugin-macros:
optional: true
2026-02-21 03:10:39 +00:00
supports-color@7.2.0:
resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
engines: {node: '>=8'}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
supports-preserve-symlinks-flag@1.0.0:
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
engines: {node: '>= 0.4'}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
symbol-tree@3.2.4:
resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==}
tagged-tag@1.0.0:
resolution: {integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==}
engines: {node: '>=20'}
feat(web): bold redesign — Tailwind v4 + shadcn-style primitives + Skills/Proposals/Revisions UI Phase 6 of the Skills + Revisions + Proposals work. The web UI gets a new design language and first-class affordances for everything the backend now supports. ## Visual direction - Tailwind v4 with custom @theme block (oklch tokens). Dark-mode-only (internal tool — light mode doubles QA surface). - Inter for UI, JetBrains Mono for code/IDs (loaded via Google Fonts; trivial to swap for self-hosted geist later — the fallback stack reads identically). - Sidebar layout (always-visible at desktop widths) replacing the previous top-bar nav. Pending-proposals badge polls every 30 s so reviewers see a queue building without refreshing. - Lucide icons throughout. - Spacing and radii on Tailwind defaults. Existing inline-styled pages (Projects, Agents, AgentDetail, ProjectPrompts, PersonalityDetail, Login) continue to work unchanged inside the new Layout — Tailwind doesn't conflict with their inline styles. A follow-up can migrate them incrementally. ## What's added ### Build infra (src/web/) - package.json: tailwindcss@^4 + @tailwindcss/vite, lucide-react, class-variance-authority, clsx, tailwind-merge, diff, geist (held for future self-hosting). - vite.config.ts: registers the @tailwindcss/vite plugin. - src/index.css: Tailwind import + @theme tokens + @layer base. - src/main.tsx: imports index.css. - src/lib/utils.ts: shadcn-style cn() helper. ### shadcn-style primitives (src/components/ui/) Hand-written rather than generated via `npx shadcn` so the repo doesn't depend on a CLI tool that needs interactive runtime: - button.tsx — variants: primary / secondary / ghost / danger / link; sizes: sm / md / lg / icon. - card.tsx — Card + Header/Title/Description/Content/Footer subparts. - badge.tsx — variants: default / info / success / warning / danger / outline. - input.tsx — Input + Textarea + Label. - tabs.tsx — no-dep accessible Tabs (no Radix needed for our use). - separator.tsx — h/v separator with role=separator. ### Diff component (src/components/Diff.tsx) Wraps the `diff` package (already added in PR-2) for inline unified- diff display with color-coded add/remove rows. Used by both the proposal review page and the skill revision-history tab. ### New pages (src/pages/) - Dashboard.tsx — at-a-glance home. Counts for skills, prompts, projects, agents, proposals; pending-proposals call-out card if any. - Skills.tsx — list view, separated into Global vs Project/Agent- scoped sections. - SkillDetail.tsx — name + semver + description; tabs for SKILL.md / Files / Metadata / History. History tab shows revisions with click-to-diff against the live body. - Proposals.tsx — queue with Pending/Approved/Rejected tabs. Pending count is highlighted in amber. - ProposalDetail.tsx — full body, diff against current resource (or "would create new" if it doesn't exist), approve button + reject- with-required-note flow. ### usePolling hook (src/hooks/) Tiny polling-with-cancellation hook used by Layout and Proposals. ### Layout rewrite (src/components/Layout.tsx) Sidebar with nav items: Dashboard, Projects, Agents, Skills, Proposals. Lucide icons. Active-route highlighting via NavLink. Pending-proposals warning badge on the Proposals item. ### Routes (src/App.tsx) New routes: /dashboard, /skills, /skills/:name, /proposals, /proposals/:id. Default redirects to /dashboard. ### API types (src/api.ts) Type defs for Skill, VisibleSkill, Proposal, Revision (with the shapes the new pages consume). ## Tests Existing 7 web tests still pass (Login + api). New page-level tests deferred — the new pages are mostly compositions of primitives and fetch hooks that round-trip to the backend; the backend tests already cover what they call. PR-7 polish can add render-and-click tests if coverage drift surfaces. ## Verification - `pnpm --filter @mcpctl/web build` clean, no warnings. - `pnpm test:run` whole monorepo: 162 test files / 2157 tests green. - Visual smoke deferred — needs a running mcpd to populate the fixtures. Manual smoke tested locally is the next step. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:54:55 +01:00
tailwind-merge@3.5.0:
resolution: {integrity: sha512-I8K9wewnVDkL1NTGoqWmVEIlUcB9gFriAEkXkfCjX5ib8ezGxtR3xD7iZIxrfArjEsH7F1CHD4RFUtxefdqV/A==}
tailwindcss@4.2.4:
resolution: {integrity: sha512-HhKppgO81FQof5m6TEnuBWCZGgfRAWbaeOaGT00KOy/Pf/j6oUihdvBpA7ltCeAvZpFhW3j0PTclkxsd4IXYDA==}
tapable@2.3.3:
resolution: {integrity: sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==}
engines: {node: '>=6'}
tar-fs@2.1.4:
resolution: {integrity: sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==}
tar-fs@3.1.2:
resolution: {integrity: sha512-QGxxTxxyleAdyM3kpFs14ymbYmNFrfY+pHj7Z8FgtbZ7w2//VAgLMac7sT6nRpIHjppXO2AwwEOg0bPFVRcmXw==}
tar-stream@2.2.0:
resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==}
engines: {node: '>=6'}
tar-stream@3.1.8:
resolution: {integrity: sha512-U6QpVRyCGHva435KoNWy9PRoi2IFYCgtEhq9nmrPPpbRacPs9IH4aJ3gbrFC8dPcXvdSZ4XXfXT5Fshbp2MtlQ==}
tar@6.2.1:
resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==}
engines: {node: '>=10'}
deprecated: Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
tar@7.5.20:
resolution: {integrity: sha512-9FcyK4PA6+WbzlTM9WhQm6vB5W7cP7dUiPsv1g7YDwEQnQ1CGpK3MGlKk/ITVWMk05kHZuBhmVhiv8LZoy/PFQ==}
engines: {node: '>=18'}
teex@1.0.1:
resolution: {integrity: sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==}
terminal-size@4.0.1:
resolution: {integrity: sha512-avMLDQpUI9I5XFrklECw1ZEUPJhqzcwSWsyyI8blhRLT+8N1jLJWLWWYQpB2q2xthq8xDvjZPISVh53T/+CLYQ==}
engines: {node: '>=18'}
text-decoder@1.2.7:
resolution: {integrity: sha512-vlLytXkeP4xvEq2otHeJfSQIRyWxo/oZGEbXrtEEF9Hnmrdly59sUbzZ/QgyWuLYHctCHxFF4tRQZNQ9k60ExQ==}
2026-02-21 03:10:39 +00:00
thread-stream@4.0.0:
resolution: {integrity: sha512-4iMVL6HAINXWf1ZKZjIPcz5wYaOdPhtO8ATvZ+Xqp3BTdaqtAwQkNmKORqcIo5YkQqGXq5cwfswDwMqqQNrpJA==}
engines: {node: '>=20'}
tinybench@2.9.0:
resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==}
tinyexec@1.0.2:
resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==}
engines: {node: '>=18'}
tinyglobby@0.2.15:
resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==}
engines: {node: '>=12.0.0'}
tinyrainbow@3.0.3:
resolution: {integrity: sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==}
engines: {node: '>=14.0.0'}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
tldts-core@7.0.28:
resolution: {integrity: sha512-7W5Efjhsc3chVdFhqtaU0KtK32J37Zcr9RKtID54nG+tIpcY79CQK/veYPODxtD/LJ4Lue66jvrQzIX2Z2/pUQ==}
tldts@7.0.28:
resolution: {integrity: sha512-+Zg3vWhRUv8B1maGSTFdev9mjoo8Etn2Ayfs4cnjlD3CsGkxXX4QyW3j2WJ0wdjYcYmy7Lx2RDsZMhgCWafKIw==}
hasBin: true
2026-02-21 03:10:39 +00:00
toad-cache@3.7.0:
resolution: {integrity: sha512-/m8M+2BJUpoJdgAHoG+baCwBT+tf2VraSfkBgl0Y00qIWt41DJ8R5B8nsEw0I58YwF5IZH6z24/2TobDKnqSWw==}
engines: {node: '>=12'}
toidentifier@1.0.1:
resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==}
engines: {node: '>=0.6'}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
toml@4.3.0:
resolution: {integrity: sha512-lVb8X9BsPVuH0M4BKeS91tXAmJvCjQ5UIyAbQFaxkKGyUFK2RPkhwaFSQH8vbpl1d23eu/IBH+dwVMHWaq9A5A==}
engines: {node: '>=20'}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
tough-cookie@6.0.1:
resolution: {integrity: sha512-LktZQb3IeoUWB9lqR5EWTHgW/VTITCXg4D21M+lvybRVdylLrRMnqaIONLVb5mav8vM19m44HIcGq4qASeu2Qw==}
engines: {node: '>=16'}
tr46@0.0.3:
resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
tr46@6.0.0:
resolution: {integrity: sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==}
engines: {node: '>=20'}
treeverse@3.0.0:
resolution: {integrity: sha512-gcANaAnd2QDZFmHFEOF4k7uc1J/6a6z3DJMd/QwEyxLoKGiptJRwid582r7QIsFlFMIZ3SnxfS52S4hm2DHkuQ==}
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
ts-algebra@2.0.0:
resolution: {integrity: sha512-FPAhNPFMrkwz76P7cdjdmiShwMynZYN6SgOujD1urY4oNm80Ou9oMdmbR45LotcKOXoy7wSmHkRFE6Mxbrhefw==}
2026-02-21 03:10:39 +00:00
ts-api-utils@2.4.0:
resolution: {integrity: sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==}
engines: {node: '>=18.12'}
peerDependencies:
typescript: '>=4.8.4'
tslib@2.8.1:
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
tsx@4.21.0:
resolution: {integrity: sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==}
engines: {node: '>=18.0.0'}
hasBin: true
tuf-js@4.1.0:
resolution: {integrity: sha512-50QV99kCKH5P/Vs4E2Gzp7BopNV+KzTXqWeaxrfu5IQJBOULRsTIS9seSsOVT8ZnGXzCyx55nYWAi4qJzpZKEQ==}
engines: {node: ^20.17.0 || >=22.9.0}
tweetnacl@0.14.5:
resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==}
2026-02-21 03:10:39 +00:00
type-check@0.4.0:
resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
engines: {node: '>= 0.8.0'}
type-fest@5.4.4:
resolution: {integrity: sha512-JnTrzGu+zPV3aXIUhnyWJj4z/wigMsdYajGLIYakqyOW1nPllzXEJee0QQbHj+CTIQtXGlAjuK0UY+2xTyjVAw==}
engines: {node: '>=20'}
2026-02-21 03:10:39 +00:00
type-is@2.0.1:
resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==}
engines: {node: '>= 0.6'}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
typebox@1.3.11:
resolution: {integrity: sha512-tZGKIS02Opbh4EYMmAEVuXl+y3EQJ9ZlkitLZ1CmFCY4ZOqr/xWR9dDSCFmIjNDICGMWkOqMh6WxGTyRXqcSGQ==}
typebox@1.3.7:
resolution: {integrity: sha512-meKuifc33Pccx0O6PdIzYMq3Og8zvP4TIi/a+Bw3AEMZMxOD0+RHGQvpglEe6Zdy3wZ8nqn/j95h8LUZLk/6Hg==}
2026-02-21 03:10:39 +00:00
typescript@5.9.3:
resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==}
engines: {node: '>=14.17'}
hasBin: true
undici-types@5.26.5:
resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==}
undici-types@7.16.0:
resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==}
undici-types@7.18.2:
resolution: {integrity: sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==}
undici@6.27.0:
resolution: {integrity: sha512-YmfV3YnEDzXRC5lZ2jWtWWHKGUm1zIt8AhesR1tens+HTNv+YZlN/dp6G727LOvMJ8xjP9Be7Y2Sdr96LDm+pg==}
engines: {node: '>=18.17'}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
undici@7.25.0:
resolution: {integrity: sha512-xXnp4kTyor2Zq+J1FfPI6Eq3ew5h6Vl0F/8d9XU5zZQf1tX9s2Su1/3PiMmUANFULpmksxkClamIZcaUqryHsQ==}
engines: {node: '>=20.18.1'}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
undici@8.9.0:
resolution: {integrity: sha512-aWZpUj7XoGonMClx4gdDRfgBjqeA+F473aDmROQQbM9n6PRfK/u1q/a0X4wMTgcHfT8H6fpbt98PFuDUwFg2YA==}
engines: {node: '>=22.19.0'}
2026-02-21 03:10:39 +00:00
unpipe@1.0.0:
resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==}
engines: {node: '>= 0.8'}
upath@1.2.0:
resolution: {integrity: sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==}
engines: {node: '>=4'}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
update-browserslist-db@1.2.3:
resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==}
hasBin: true
peerDependencies:
browserslist: '>= 4.21.0'
2026-02-21 03:10:39 +00:00
uri-js@4.4.1:
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
util-deprecate@1.0.2:
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
uuid@10.0.0:
resolution: {integrity: sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
deprecated: uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).
hasBin: true
uuid@14.0.1:
resolution: {integrity: sha512-6ZxzVpzDXDa3bJWaHilVayA+BH/1zmxCJoVgvmqJnid/gPoKHxUrS/aC/T6LGQtNHT+XHG9fXPJB4d+IrU30Ew==}
hasBin: true
validate-npm-package-license@3.0.4:
resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==}
validate-npm-package-name@7.0.2:
resolution: {integrity: sha512-hVDIBwsRruT73PbK7uP5ebUt+ezEtCmzZz3F59BSr2F6OVFnJ/6h8liuvdLrQ88Xmnk6/+xGGuq+pG9WwTuy3A==}
engines: {node: ^20.17.0 || >=22.9.0}
2026-02-21 03:10:39 +00:00
vary@1.1.2:
resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==}
engines: {node: '>= 0.8'}
vite@7.3.1:
resolution: {integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==}
engines: {node: ^20.19.0 || >=22.12.0}
hasBin: true
peerDependencies:
'@types/node': ^20.19.0 || >=22.12.0
jiti: '>=1.21.0'
less: ^4.0.0
lightningcss: ^1.21.0
sass: ^1.70.0
sass-embedded: ^1.70.0
stylus: '>=0.54.8'
sugarss: ^5.0.0
terser: ^5.16.0
tsx: ^4.8.1
yaml: ^2.4.2
peerDependenciesMeta:
'@types/node':
optional: true
jiti:
optional: true
less:
optional: true
lightningcss:
optional: true
sass:
optional: true
sass-embedded:
optional: true
stylus:
optional: true
sugarss:
optional: true
terser:
optional: true
tsx:
optional: true
yaml:
optional: true
vitest@4.0.18:
resolution: {integrity: sha512-hOQuK7h0FGKgBAas7v0mSAsnvrIgAvWmRFjmzpJ7SwFHH3g1k2u37JtYwOwmEKhK6ZO3v9ggDBBm0La1LCK4uQ==}
engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0}
hasBin: true
peerDependencies:
'@edge-runtime/vm': '*'
'@opentelemetry/api': ^1.9.0
'@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0
'@vitest/browser-playwright': 4.0.18
'@vitest/browser-preview': 4.0.18
'@vitest/browser-webdriverio': 4.0.18
'@vitest/ui': 4.0.18
happy-dom: '*'
jsdom: '*'
peerDependenciesMeta:
'@edge-runtime/vm':
optional: true
'@opentelemetry/api':
optional: true
'@types/node':
optional: true
'@vitest/browser-playwright':
optional: true
'@vitest/browser-preview':
optional: true
'@vitest/browser-webdriverio':
optional: true
'@vitest/ui':
optional: true
happy-dom:
optional: true
jsdom:
optional: true
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
w3c-xmlserializer@5.0.0:
resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==}
engines: {node: '>=18'}
walk-up-path@4.0.0:
resolution: {integrity: sha512-3hu+tD8YzSLGuFYtPRb48vdhKMi0KQV5sn+uWr8+7dMEq/2G/dtLrdDinkLjqq5TIbIBjYJ4Ax/n3YiaW7QM8A==}
engines: {node: 20 || >=22}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
web-streams-polyfill@3.3.3:
resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==}
engines: {node: '>= 8'}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
web-tree-sitter@0.25.10:
resolution: {integrity: sha512-Y09sF44/13XvgVKgO2cNDw5rGk6s26MgoZPXLESvMXeefBf7i6/73eFurre0IsTW6E14Y0ArIzhUMmjoc7xyzA==}
peerDependencies:
'@types/emscripten': ^1.40.0
peerDependenciesMeta:
'@types/emscripten':
optional: true
webidl-conversions@3.0.1:
resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
webidl-conversions@8.0.1:
resolution: {integrity: sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==}
engines: {node: '>=20'}
whatwg-mimetype@5.0.0:
resolution: {integrity: sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==}
engines: {node: '>=20'}
whatwg-url@16.0.1:
resolution: {integrity: sha512-1to4zXBxmXHV3IiSSEInrreIlu02vUOvrhxJJH5vcxYTBDAx51cqZiKdyTxlecdKNSjj8EcxGBxNf6Vg+945gw==}
engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0}
whatwg-url@5.0.0:
resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==}
2026-02-21 03:10:39 +00:00
which@2.0.2:
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
engines: {node: '>= 8'}
hasBin: true
which@6.0.1:
resolution: {integrity: sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg==}
engines: {node: ^20.17.0 || >=22.9.0}
hasBin: true
2026-02-21 03:10:39 +00:00
why-is-node-running@2.3.0:
resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==}
engines: {node: '>=8'}
hasBin: true
wide-align@1.1.5:
resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==}
widest-line@6.0.0:
resolution: {integrity: sha512-U89AsyEeAsyoF0zVJBkG9zBgekjgjK7yk9sje3F4IQpXBJ10TF6ByLlIfjMhcmHMJgHZI4KHt4rdNfktzxIAMA==}
engines: {node: '>=20'}
2026-02-21 03:10:39 +00:00
word-wrap@1.2.5:
resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
engines: {node: '>=0.10.0'}
wrap-ansi@6.2.0:
resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==}
engines: {node: '>=8'}
wrap-ansi@7.0.0:
resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
engines: {node: '>=10'}
wrap-ansi@9.0.2:
resolution: {integrity: sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==}
engines: {node: '>=18'}
2026-02-21 03:10:39 +00:00
wrappy@1.0.2:
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
write-file-atomic@7.0.1:
resolution: {integrity: sha512-OTIk8iR8/aCRWBqvxrzxR0hgxWpnYBblY1S5hDWBQfk/VFmJwzmJgQFN3WsoUKHISv2eAwe+PpbUzyL1CKTLXg==}
engines: {node: ^20.17.0 || >=22.9.0}
ws@8.19.0:
resolution: {integrity: sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==}
engines: {node: '>=10.0.0'}
peerDependencies:
bufferutil: ^4.0.1
utf-8-validate: '>=5.0.2'
peerDependenciesMeta:
bufferutil:
optional: true
utf-8-validate:
optional: true
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
xml-name-validator@5.0.0:
resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==}
engines: {node: '>=18'}
xmlchars@2.2.0:
resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==}
y18n@5.0.8:
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
engines: {node: '>=10'}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
yallist@3.1.1:
resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
yallist@4.0.0:
resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
yallist@5.0.0:
resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==}
engines: {node: '>=18'}
yaml@2.8.2:
resolution: {integrity: sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==}
engines: {node: '>= 14.6'}
hasBin: true
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
yaml@2.9.0:
resolution: {integrity: sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==}
engines: {node: '>= 14.6'}
hasBin: true
yargs-parser@21.1.1:
resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
engines: {node: '>=12'}
yargs@17.7.2:
resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==}
engines: {node: '>=12'}
2026-02-21 03:10:39 +00:00
yocto-queue@0.1.0:
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
engines: {node: '>=10'}
yoctocolors-cjs@2.1.3:
resolution: {integrity: sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==}
engines: {node: '>=18'}
yoga-layout@3.2.1:
resolution: {integrity: sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ==}
2026-02-21 03:10:39 +00:00
zod-to-json-schema@3.25.1:
resolution: {integrity: sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA==}
peerDependencies:
zod: ^3.25 || ^4
zod@3.25.76:
resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
zod@4.1.8:
resolution: {integrity: sha512-5R1P+WwQqmmMIEACyzSvo4JXHY5WiAFHRMg+zBZKgKS+Q1viRa0C1hmUKtHltoIFKtIdki3pRxkmpP74jnNYHQ==}
2026-02-21 03:10:39 +00:00
snapshots:
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
'@acemir/cssom@0.9.31': {}
'@adobe/css-tools@4.4.4': {}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
'@ai-sdk/provider@3.0.8':
dependencies:
json-schema: 0.4.0
'@alcalzone/ansi-tokenize@0.2.5':
dependencies:
ansi-styles: 6.2.3
is-fullwidth-code-point: 5.1.0
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
'@ampproject/remapping@2.3.0':
dependencies:
'@jridgewell/gen-mapping': 0.3.13
'@jridgewell/trace-mapping': 0.3.31
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
'@anthropic-ai/sdk@0.91.1(zod@3.25.76)':
dependencies:
json-schema-to-ts: 3.1.1
optionalDependencies:
zod: 3.25.76
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
'@asamuzakjp/css-color@5.1.11':
dependencies:
'@asamuzakjp/generational-cache': 1.0.1
'@csstools/css-calc': 3.2.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)
'@csstools/css-color-parser': 4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)
'@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0)
'@csstools/css-tokenizer': 4.0.0
'@asamuzakjp/dom-selector@6.8.1':
dependencies:
'@asamuzakjp/nwsapi': 2.3.9
bidi-js: 1.0.3
css-tree: 3.2.1
is-potential-custom-element-name: 1.0.1
lru-cache: 11.2.6
'@asamuzakjp/generational-cache@1.0.1': {}
'@asamuzakjp/nwsapi@2.3.9': {}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
'@aws-crypto/sha256-browser@5.2.0':
dependencies:
'@aws-crypto/sha256-js': 5.2.0
'@aws-crypto/supports-web-crypto': 5.2.0
'@aws-crypto/util': 5.2.0
'@aws-sdk/types': 3.974.2
'@aws-sdk/util-locate-window': 3.965.8
'@smithy/util-utf8': 2.3.0
tslib: 2.8.1
'@aws-crypto/sha256-js@5.2.0':
dependencies:
'@aws-crypto/util': 5.2.0
'@aws-sdk/types': 3.974.2
tslib: 2.8.1
'@aws-crypto/supports-web-crypto@5.2.0':
dependencies:
tslib: 2.8.1
'@aws-crypto/util@5.2.0':
dependencies:
'@aws-sdk/types': 3.974.2
'@smithy/util-utf8': 2.3.0
tslib: 2.8.1
'@aws-sdk/client-bedrock-runtime@3.1048.0':
dependencies:
'@aws-crypto/sha256-browser': 5.2.0
'@aws-crypto/sha256-js': 5.2.0
'@aws-sdk/core': 3.977.6
'@aws-sdk/credential-provider-node': 3.972.78
'@aws-sdk/eventstream-handler-node': 3.972.31
'@aws-sdk/middleware-eventstream': 3.972.26
'@aws-sdk/middleware-websocket': 3.972.49
'@aws-sdk/token-providers': 3.1048.0
'@aws-sdk/types': 3.974.2
'@smithy/core': 3.31.1
'@smithy/fetch-http-handler': 5.6.13
'@smithy/node-http-handler': 4.9.13
'@smithy/types': 4.16.1
tslib: 2.8.1
'@aws-sdk/core@3.977.6':
dependencies:
'@aws-sdk/types': 3.974.2
'@aws-sdk/xml-builder': 3.972.37
'@aws/lambda-invoke-store': 0.3.0
'@smithy/core': 3.31.1
'@smithy/signature-v4': 5.6.12
'@smithy/types': 4.16.1
bowser: 2.14.1
tslib: 2.8.1
'@aws-sdk/credential-provider-env@3.972.67':
dependencies:
'@aws-sdk/core': 3.977.6
'@aws-sdk/types': 3.974.2
'@smithy/core': 3.31.1
'@smithy/types': 4.16.1
tslib: 2.8.1
'@aws-sdk/credential-provider-http@3.972.69':
dependencies:
'@aws-sdk/core': 3.977.6
'@aws-sdk/types': 3.974.2
'@smithy/core': 3.31.1
'@smithy/fetch-http-handler': 5.6.13
'@smithy/node-http-handler': 4.9.13
'@smithy/types': 4.16.1
tslib: 2.8.1
'@aws-sdk/credential-provider-ini@3.973.12':
dependencies:
'@aws-sdk/core': 3.977.6
'@aws-sdk/credential-provider-env': 3.972.67
'@aws-sdk/credential-provider-http': 3.972.69
'@aws-sdk/credential-provider-login': 3.972.74
'@aws-sdk/credential-provider-process': 3.972.67
'@aws-sdk/credential-provider-sso': 3.973.11
'@aws-sdk/credential-provider-web-identity': 3.972.73
'@aws-sdk/nested-clients': 3.997.41
'@aws-sdk/types': 3.974.2
'@smithy/core': 3.31.1
'@smithy/credential-provider-imds': 4.4.16
'@smithy/types': 4.16.1
tslib: 2.8.1
'@aws-sdk/credential-provider-login@3.972.74':
dependencies:
'@aws-sdk/core': 3.977.6
'@aws-sdk/nested-clients': 3.997.41
'@aws-sdk/types': 3.974.2
'@smithy/core': 3.31.1
'@smithy/types': 4.16.1
tslib: 2.8.1
'@aws-sdk/credential-provider-node@3.972.78':
dependencies:
'@aws-sdk/credential-provider-env': 3.972.67
'@aws-sdk/credential-provider-http': 3.972.69
'@aws-sdk/credential-provider-ini': 3.973.12
'@aws-sdk/credential-provider-process': 3.972.67
'@aws-sdk/credential-provider-sso': 3.973.11
'@aws-sdk/credential-provider-web-identity': 3.972.73
'@aws-sdk/types': 3.974.2
'@smithy/core': 3.31.1
'@smithy/credential-provider-imds': 4.4.16
'@smithy/types': 4.16.1
tslib: 2.8.1
'@aws-sdk/credential-provider-process@3.972.67':
dependencies:
'@aws-sdk/core': 3.977.6
'@aws-sdk/types': 3.974.2
'@smithy/core': 3.31.1
'@smithy/types': 4.16.1
tslib: 2.8.1
'@aws-sdk/credential-provider-sso@3.973.11':
dependencies:
'@aws-sdk/core': 3.977.6
'@aws-sdk/nested-clients': 3.997.41
'@aws-sdk/token-providers': 3.1103.0
'@aws-sdk/types': 3.974.2
'@smithy/core': 3.31.1
'@smithy/types': 4.16.1
tslib: 2.8.1
'@aws-sdk/credential-provider-web-identity@3.972.73':
dependencies:
'@aws-sdk/core': 3.977.6
'@aws-sdk/nested-clients': 3.997.41
'@aws-sdk/types': 3.974.2
'@smithy/core': 3.31.1
'@smithy/types': 4.16.1
tslib: 2.8.1
'@aws-sdk/eventstream-handler-node@3.972.31':
dependencies:
'@aws-sdk/types': 3.974.2
'@smithy/core': 3.31.1
'@smithy/types': 4.16.1
tslib: 2.8.1
'@aws-sdk/middleware-eventstream@3.972.26':
dependencies:
'@aws-sdk/types': 3.974.2
'@smithy/core': 3.31.1
'@smithy/types': 4.16.1
tslib: 2.8.1
'@aws-sdk/middleware-websocket@3.972.49':
dependencies:
'@aws-sdk/core': 3.977.6
'@aws-sdk/types': 3.974.2
'@smithy/core': 3.31.1
'@smithy/fetch-http-handler': 5.6.13
'@smithy/signature-v4': 5.6.12
'@smithy/types': 4.16.1
tslib: 2.8.1
'@aws-sdk/nested-clients@3.997.41':
dependencies:
'@aws-sdk/core': 3.977.6
'@aws-sdk/signature-v4-multi-region': 3.996.43
'@aws-sdk/types': 3.974.2
'@smithy/core': 3.31.1
'@smithy/fetch-http-handler': 5.6.13
'@smithy/node-http-handler': 4.9.13
'@smithy/types': 4.16.1
tslib: 2.8.1
'@aws-sdk/signature-v4-multi-region@3.996.43':
dependencies:
'@aws-sdk/types': 3.974.2
'@smithy/signature-v4': 5.6.12
'@smithy/types': 4.16.1
tslib: 2.8.1
'@aws-sdk/token-providers@3.1048.0':
dependencies:
'@aws-sdk/core': 3.977.6
'@aws-sdk/nested-clients': 3.997.41
'@aws-sdk/types': 3.974.2
'@smithy/core': 3.31.1
'@smithy/types': 4.16.1
tslib: 2.8.1
'@aws-sdk/token-providers@3.1103.0':
dependencies:
'@aws-sdk/core': 3.977.6
'@aws-sdk/nested-clients': 3.997.41
'@aws-sdk/types': 3.974.2
'@smithy/core': 3.31.1
'@smithy/types': 4.16.1
tslib: 2.8.1
'@aws-sdk/types@3.974.2':
dependencies:
'@smithy/types': 4.16.1
tslib: 2.8.1
'@aws-sdk/util-locate-window@3.965.8':
dependencies:
tslib: 2.8.1
'@aws-sdk/xml-builder@3.972.37':
dependencies:
'@smithy/types': 4.16.1
tslib: 2.8.1
'@aws/lambda-invoke-store@0.3.0': {}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
'@babel/code-frame@7.29.0':
dependencies:
'@babel/helper-validator-identifier': 7.28.5
js-tokens: 4.0.0
picocolors: 1.1.1
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
'@babel/code-frame@7.29.7':
dependencies:
'@babel/helper-validator-identifier': 7.29.7
js-tokens: 4.0.0
picocolors: 1.1.1
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
'@babel/compat-data@7.29.0': {}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
'@babel/core@7.28.0':
dependencies:
'@ampproject/remapping': 2.3.0
'@babel/code-frame': 7.29.7
'@babel/generator': 7.29.8
'@babel/helper-compilation-targets': 7.28.6
'@babel/helper-module-transforms': 7.29.7(@babel/core@7.28.0)
'@babel/helpers': 7.29.2
'@babel/parser': 7.29.8
'@babel/template': 7.29.7
'@babel/traverse': 7.29.8
'@babel/types': 7.29.8
convert-source-map: 2.0.0
debug: 4.4.3
gensync: 1.0.0-beta.2
json5: 2.2.3
semver: 6.3.1
transitivePeerDependencies:
- supports-color
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
'@babel/core@7.29.0':
dependencies:
'@babel/code-frame': 7.29.0
'@babel/generator': 7.29.1
'@babel/helper-compilation-targets': 7.28.6
'@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0)
'@babel/helpers': 7.29.2
'@babel/parser': 7.29.0
'@babel/template': 7.28.6
'@babel/traverse': 7.29.0
'@babel/types': 7.29.0
'@jridgewell/remapping': 2.3.5
convert-source-map: 2.0.0
debug: 4.4.3
gensync: 1.0.0-beta.2
json5: 2.2.3
semver: 6.3.1
transitivePeerDependencies:
- supports-color
'@babel/generator@7.29.1':
dependencies:
'@babel/parser': 7.29.0
'@babel/types': 7.29.0
'@jridgewell/gen-mapping': 0.3.13
'@jridgewell/trace-mapping': 0.3.31
jsesc: 3.1.0
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
'@babel/generator@7.29.8':
dependencies:
'@babel/parser': 7.29.8
'@babel/types': 7.29.8
'@jridgewell/gen-mapping': 0.3.13
'@jridgewell/trace-mapping': 0.3.31
jsesc: 3.1.0
'@babel/helper-annotate-as-pure@7.29.7':
dependencies:
'@babel/types': 7.29.8
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
'@babel/helper-compilation-targets@7.28.6':
dependencies:
'@babel/compat-data': 7.29.0
'@babel/helper-validator-option': 7.27.1
browserslist: 4.28.2
lru-cache: 5.1.1
semver: 6.3.1
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
'@babel/helper-create-class-features-plugin@7.29.7(@babel/core@7.28.0)':
dependencies:
'@babel/core': 7.28.0
'@babel/helper-annotate-as-pure': 7.29.7
'@babel/helper-member-expression-to-functions': 7.29.7
'@babel/helper-optimise-call-expression': 7.29.7
'@babel/helper-replace-supers': 7.29.7(@babel/core@7.28.0)
'@babel/helper-skip-transparent-expression-wrappers': 7.29.7
'@babel/traverse': 7.29.8
semver: 6.3.1
transitivePeerDependencies:
- supports-color
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
'@babel/helper-globals@7.28.0': {}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
'@babel/helper-globals@7.29.7': {}
'@babel/helper-member-expression-to-functions@7.29.7':
dependencies:
'@babel/traverse': 7.29.8
'@babel/types': 7.29.8
transitivePeerDependencies:
- supports-color
'@babel/helper-module-imports@7.18.6':
dependencies:
'@babel/types': 7.29.8
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
'@babel/helper-module-imports@7.28.6':
dependencies:
'@babel/traverse': 7.29.0
'@babel/types': 7.29.0
transitivePeerDependencies:
- supports-color
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
'@babel/helper-module-imports@7.29.7':
dependencies:
'@babel/traverse': 7.29.8
'@babel/types': 7.29.8
transitivePeerDependencies:
- supports-color
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
'@babel/helper-module-transforms@7.28.6(@babel/core@7.29.0)':
dependencies:
'@babel/core': 7.29.0
'@babel/helper-module-imports': 7.28.6
'@babel/helper-validator-identifier': 7.28.5
'@babel/traverse': 7.29.0
transitivePeerDependencies:
- supports-color
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
'@babel/helper-module-transforms@7.29.7(@babel/core@7.28.0)':
dependencies:
'@babel/core': 7.28.0
'@babel/helper-module-imports': 7.29.7
'@babel/helper-validator-identifier': 7.29.7
'@babel/traverse': 7.29.8
transitivePeerDependencies:
- supports-color
'@babel/helper-optimise-call-expression@7.29.7':
dependencies:
'@babel/types': 7.29.8
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
'@babel/helper-plugin-utils@7.28.6': {}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
'@babel/helper-plugin-utils@7.29.7': {}
'@babel/helper-replace-supers@7.29.7(@babel/core@7.28.0)':
dependencies:
'@babel/core': 7.28.0
'@babel/helper-member-expression-to-functions': 7.29.7
'@babel/helper-optimise-call-expression': 7.29.7
'@babel/traverse': 7.29.8
transitivePeerDependencies:
- supports-color
'@babel/helper-skip-transparent-expression-wrappers@7.29.7':
dependencies:
'@babel/traverse': 7.29.8
'@babel/types': 7.29.8
transitivePeerDependencies:
- supports-color
2026-02-21 03:10:39 +00:00
'@babel/helper-string-parser@7.27.1': {}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
'@babel/helper-string-parser@7.29.7': {}
2026-02-21 03:10:39 +00:00
'@babel/helper-validator-identifier@7.28.5': {}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
'@babel/helper-validator-identifier@7.29.7': {}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
'@babel/helper-validator-option@7.27.1': {}
'@babel/helpers@7.29.2':
dependencies:
'@babel/template': 7.28.6
'@babel/types': 7.29.0
2026-02-21 03:10:39 +00:00
'@babel/parser@7.29.0':
dependencies:
'@babel/types': 7.29.0
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
'@babel/parser@7.29.8':
dependencies:
'@babel/types': 7.29.8
'@babel/plugin-syntax-jsx@7.29.7(@babel/core@7.28.0)':
dependencies:
'@babel/core': 7.28.0
'@babel/helper-plugin-utils': 7.29.7
'@babel/plugin-syntax-typescript@7.29.7(@babel/core@7.28.0)':
dependencies:
'@babel/core': 7.28.0
'@babel/helper-plugin-utils': 7.29.7
'@babel/plugin-transform-modules-commonjs@7.29.7(@babel/core@7.28.0)':
dependencies:
'@babel/core': 7.28.0
'@babel/helper-module-transforms': 7.29.7(@babel/core@7.28.0)
'@babel/helper-plugin-utils': 7.29.7
transitivePeerDependencies:
- supports-color
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
'@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.29.0)':
dependencies:
'@babel/core': 7.29.0
'@babel/helper-plugin-utils': 7.28.6
'@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.29.0)':
dependencies:
'@babel/core': 7.29.0
'@babel/helper-plugin-utils': 7.28.6
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
'@babel/plugin-transform-typescript@7.29.7(@babel/core@7.28.0)':
dependencies:
'@babel/core': 7.28.0
'@babel/helper-annotate-as-pure': 7.29.7
'@babel/helper-create-class-features-plugin': 7.29.7(@babel/core@7.28.0)
'@babel/helper-plugin-utils': 7.29.7
'@babel/helper-skip-transparent-expression-wrappers': 7.29.7
'@babel/plugin-syntax-typescript': 7.29.7(@babel/core@7.28.0)
transitivePeerDependencies:
- supports-color
'@babel/preset-typescript@7.27.1(@babel/core@7.28.0)':
dependencies:
'@babel/core': 7.28.0
'@babel/helper-plugin-utils': 7.29.7
'@babel/helper-validator-option': 7.27.1
'@babel/plugin-syntax-jsx': 7.29.7(@babel/core@7.28.0)
'@babel/plugin-transform-modules-commonjs': 7.29.7(@babel/core@7.28.0)
'@babel/plugin-transform-typescript': 7.29.7(@babel/core@7.28.0)
transitivePeerDependencies:
- supports-color
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
'@babel/runtime@7.29.2': {}
'@babel/template@7.28.6':
dependencies:
'@babel/code-frame': 7.29.0
'@babel/parser': 7.29.0
'@babel/types': 7.29.0
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
'@babel/template@7.29.7':
dependencies:
'@babel/code-frame': 7.29.7
'@babel/parser': 7.29.8
'@babel/types': 7.29.8
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
'@babel/traverse@7.29.0':
dependencies:
'@babel/code-frame': 7.29.0
'@babel/generator': 7.29.1
'@babel/helper-globals': 7.28.0
'@babel/parser': 7.29.0
'@babel/template': 7.28.6
'@babel/types': 7.29.0
debug: 4.4.3
transitivePeerDependencies:
- supports-color
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
'@babel/traverse@7.29.8':
dependencies:
'@babel/code-frame': 7.29.7
'@babel/generator': 7.29.8
'@babel/helper-globals': 7.29.7
'@babel/parser': 7.29.8
'@babel/template': 7.29.7
'@babel/types': 7.29.8
debug: 4.4.3
transitivePeerDependencies:
- supports-color
2026-02-21 03:10:39 +00:00
'@babel/types@7.29.0':
dependencies:
'@babel/helper-string-parser': 7.27.1
'@babel/helper-validator-identifier': 7.28.5
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
'@babel/types@7.29.8':
dependencies:
'@babel/helper-string-parser': 7.29.7
'@babel/helper-validator-identifier': 7.29.7
'@balena/dockerignore@1.0.2': {}
2026-02-21 03:10:39 +00:00
'@bcoe/v8-coverage@1.0.2': {}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
'@bramus/specificity@2.4.2':
dependencies:
css-tree: 3.2.1
'@csstools/color-helpers@6.0.2': {}
'@csstools/css-calc@3.2.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)':
dependencies:
'@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0)
'@csstools/css-tokenizer': 4.0.0
'@csstools/css-color-parser@4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)':
dependencies:
'@csstools/color-helpers': 6.0.2
'@csstools/css-calc': 3.2.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)
'@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0)
'@csstools/css-tokenizer': 4.0.0
'@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0)':
dependencies:
'@csstools/css-tokenizer': 4.0.0
'@csstools/css-syntax-patches-for-csstree@1.1.3(css-tree@3.2.1)':
optionalDependencies:
css-tree: 3.2.1
'@csstools/css-tokenizer@4.0.0': {}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
'@earendil-works/pi-agent-core@0.84.1(@modelcontextprotocol/sdk@1.26.0(zod@3.25.76))(ws@8.19.0)(zod@3.25.76)':
dependencies:
'@earendil-works/pi-ai': 0.84.1(@modelcontextprotocol/sdk@1.26.0(zod@3.25.76))(ws@8.19.0)(zod@3.25.76)
'@earendil-works/pi-telemetry': 0.84.1
diff: 8.0.4
ignore: 7.0.5
typebox: 1.3.7
yaml: 2.9.0
transitivePeerDependencies:
- '@modelcontextprotocol/sdk'
- bufferutil
- supports-color
- utf-8-validate
- ws
- zod
'@earendil-works/pi-ai@0.84.1(@modelcontextprotocol/sdk@1.26.0(zod@3.25.76))(ws@8.19.0)(zod@3.25.76)':
dependencies:
'@anthropic-ai/sdk': 0.91.1(zod@3.25.76)
'@aws-sdk/client-bedrock-runtime': 3.1048.0
'@earendil-works/pi-telemetry': 0.84.1
'@google/genai': 1.52.0(@modelcontextprotocol/sdk@1.26.0(zod@3.25.76))
'@mistralai/mistralai': 2.2.6(@opentelemetry/api@1.9.0)
'@opentelemetry/api': 1.9.0
'@smithy/node-http-handler': 4.7.3
http-proxy-agent: 7.0.2
https-proxy-agent: 7.0.6
openai: 6.26.0(ws@8.19.0)(zod@3.25.76)
partial-json: 0.1.7
typebox: 1.3.7
transitivePeerDependencies:
- '@modelcontextprotocol/sdk'
- bufferutil
- supports-color
- utf-8-validate
- ws
- zod
'@earendil-works/pi-client@0.84.1':
dependencies:
'@earendil-works/pi-protocol': 0.84.1
'@earendil-works/pi-coding-agent@0.84.1(@modelcontextprotocol/sdk@1.26.0(zod@3.25.76))(ws@8.19.0)(zod@3.25.76)':
dependencies:
'@earendil-works/pi-agent-core': 0.84.1(@modelcontextprotocol/sdk@1.26.0(zod@3.25.76))(ws@8.19.0)(zod@3.25.76)
'@earendil-works/pi-ai': 0.84.1(@modelcontextprotocol/sdk@1.26.0(zod@3.25.76))(ws@8.19.0)(zod@3.25.76)
'@earendil-works/pi-client': 0.84.1
'@earendil-works/pi-protocol': 0.84.1
'@earendil-works/pi-tui': 0.84.1
'@silvia-odwyer/photon-node': 0.3.4
chalk: 5.6.2
cross-spawn: 7.0.6
diff: 8.0.4
glob: 13.0.6
grok-mermaid: 0.2.2
highlight.js: 10.7.3
hosted-git-info: 9.0.3
ignore: 7.0.5
jiti: 2.7.0
minimatch: 10.2.5
proper-lockfile: 4.1.2
semver: 7.8.0
typebox: 1.3.7
undici: 8.9.0
yaml: 2.9.0
optionalDependencies:
'@mariozechner/clipboard': 0.3.9
transitivePeerDependencies:
- '@modelcontextprotocol/sdk'
- bufferutil
- supports-color
- utf-8-validate
- ws
- zod
'@earendil-works/pi-protocol@0.84.1':
dependencies:
typebox: 1.3.7
'@earendil-works/pi-telemetry@0.84.1': {}
'@earendil-works/pi-tui@0.84.1':
dependencies:
get-east-asian-width: 1.6.0
marked: 18.0.5
feat(web): bold redesign — Tailwind v4 + shadcn-style primitives + Skills/Proposals/Revisions UI Phase 6 of the Skills + Revisions + Proposals work. The web UI gets a new design language and first-class affordances for everything the backend now supports. ## Visual direction - Tailwind v4 with custom @theme block (oklch tokens). Dark-mode-only (internal tool — light mode doubles QA surface). - Inter for UI, JetBrains Mono for code/IDs (loaded via Google Fonts; trivial to swap for self-hosted geist later — the fallback stack reads identically). - Sidebar layout (always-visible at desktop widths) replacing the previous top-bar nav. Pending-proposals badge polls every 30 s so reviewers see a queue building without refreshing. - Lucide icons throughout. - Spacing and radii on Tailwind defaults. Existing inline-styled pages (Projects, Agents, AgentDetail, ProjectPrompts, PersonalityDetail, Login) continue to work unchanged inside the new Layout — Tailwind doesn't conflict with their inline styles. A follow-up can migrate them incrementally. ## What's added ### Build infra (src/web/) - package.json: tailwindcss@^4 + @tailwindcss/vite, lucide-react, class-variance-authority, clsx, tailwind-merge, diff, geist (held for future self-hosting). - vite.config.ts: registers the @tailwindcss/vite plugin. - src/index.css: Tailwind import + @theme tokens + @layer base. - src/main.tsx: imports index.css. - src/lib/utils.ts: shadcn-style cn() helper. ### shadcn-style primitives (src/components/ui/) Hand-written rather than generated via `npx shadcn` so the repo doesn't depend on a CLI tool that needs interactive runtime: - button.tsx — variants: primary / secondary / ghost / danger / link; sizes: sm / md / lg / icon. - card.tsx — Card + Header/Title/Description/Content/Footer subparts. - badge.tsx — variants: default / info / success / warning / danger / outline. - input.tsx — Input + Textarea + Label. - tabs.tsx — no-dep accessible Tabs (no Radix needed for our use). - separator.tsx — h/v separator with role=separator. ### Diff component (src/components/Diff.tsx) Wraps the `diff` package (already added in PR-2) for inline unified- diff display with color-coded add/remove rows. Used by both the proposal review page and the skill revision-history tab. ### New pages (src/pages/) - Dashboard.tsx — at-a-glance home. Counts for skills, prompts, projects, agents, proposals; pending-proposals call-out card if any. - Skills.tsx — list view, separated into Global vs Project/Agent- scoped sections. - SkillDetail.tsx — name + semver + description; tabs for SKILL.md / Files / Metadata / History. History tab shows revisions with click-to-diff against the live body. - Proposals.tsx — queue with Pending/Approved/Rejected tabs. Pending count is highlighted in amber. - ProposalDetail.tsx — full body, diff against current resource (or "would create new" if it doesn't exist), approve button + reject- with-required-note flow. ### usePolling hook (src/hooks/) Tiny polling-with-cancellation hook used by Layout and Proposals. ### Layout rewrite (src/components/Layout.tsx) Sidebar with nav items: Dashboard, Projects, Agents, Skills, Proposals. Lucide icons. Active-route highlighting via NavLink. Pending-proposals warning badge on the Proposals item. ### Routes (src/App.tsx) New routes: /dashboard, /skills, /skills/:name, /proposals, /proposals/:id. Default redirects to /dashboard. ### API types (src/api.ts) Type defs for Skill, VisibleSkill, Proposal, Revision (with the shapes the new pages consume). ## Tests Existing 7 web tests still pass (Login + api). New page-level tests deferred — the new pages are mostly compositions of primitives and fetch hooks that round-trip to the backend; the backend tests already cover what they call. PR-7 polish can add render-and-click tests if coverage drift surfaces. ## Verification - `pnpm --filter @mcpctl/web build` clean, no warnings. - `pnpm test:run` whole monorepo: 162 test files / 2157 tests green. - Visual smoke deferred — needs a running mcpd to populate the fixtures. Manual smoke tested locally is the next step. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:54:55 +01:00
'@emnapi/runtime@1.10.0':
dependencies:
tslib: 2.8.1
optional: true
2026-02-21 03:10:39 +00:00
'@esbuild/aix-ppc64@0.27.3':
optional: true
'@esbuild/android-arm64@0.27.3':
optional: true
'@esbuild/android-arm@0.27.3':
optional: true
'@esbuild/android-x64@0.27.3':
optional: true
'@esbuild/darwin-arm64@0.27.3':
optional: true
'@esbuild/darwin-x64@0.27.3':
optional: true
'@esbuild/freebsd-arm64@0.27.3':
optional: true
'@esbuild/freebsd-x64@0.27.3':
optional: true
'@esbuild/linux-arm64@0.27.3':
optional: true
'@esbuild/linux-arm@0.27.3':
optional: true
'@esbuild/linux-ia32@0.27.3':
optional: true
'@esbuild/linux-loong64@0.27.3':
optional: true
'@esbuild/linux-mips64el@0.27.3':
optional: true
'@esbuild/linux-ppc64@0.27.3':
optional: true
'@esbuild/linux-riscv64@0.27.3':
optional: true
'@esbuild/linux-s390x@0.27.3':
optional: true
'@esbuild/linux-x64@0.27.3':
optional: true
'@esbuild/netbsd-arm64@0.27.3':
optional: true
'@esbuild/netbsd-x64@0.27.3':
optional: true
'@esbuild/openbsd-arm64@0.27.3':
optional: true
'@esbuild/openbsd-x64@0.27.3':
optional: true
'@esbuild/openharmony-arm64@0.27.3':
optional: true
'@esbuild/sunos-x64@0.27.3':
optional: true
'@esbuild/win32-arm64@0.27.3':
optional: true
'@esbuild/win32-ia32@0.27.3':
optional: true
'@esbuild/win32-x64@0.27.3':
optional: true
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
'@eslint-community/eslint-utils@4.9.1(eslint@10.0.1(jiti@2.7.0))':
2026-02-21 03:10:39 +00:00
dependencies:
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
eslint: 10.0.1(jiti@2.7.0)
2026-02-21 03:10:39 +00:00
eslint-visitor-keys: 3.4.3
'@eslint-community/regexpp@4.12.2': {}
'@eslint/config-array@0.23.2':
dependencies:
'@eslint/object-schema': 3.0.2
debug: 4.4.3
minimatch: 10.2.2
transitivePeerDependencies:
- supports-color
'@eslint/config-helpers@0.5.2':
dependencies:
'@eslint/core': 1.1.0
'@eslint/core@1.1.0':
dependencies:
'@types/json-schema': 7.0.15
'@eslint/object-schema@3.0.2': {}
'@eslint/plugin-kit@0.6.0':
dependencies:
'@eslint/core': 1.1.0
levn: 0.4.1
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
'@exodus/bytes@1.15.0': {}
feat(mcpd+deploy): serve web UI at /ui + smoke tests + docs (Stage 6) The closing stage. mcpd now hosts the Stage 5 SPA, the Docker image bundles the build artifact, a smoke test exercises the personality HTTP surface end-to-end, and the user-facing docs spell out the mental model. mcpd: - Add @fastify/static dep. - New routes/web-ui.ts: registers /ui/* against a static bundle. Looks for the bundle at $MCPD_WEB_ROOT, then /usr/share/mcpd/web (the Docker image path), then a dev-tree fallback. Logs and skips cleanly if missing — API-only deploys keep working. - SPA fallback: any /ui/<path> that doesn't match a file falls through to index.html so direct hits to react-router URLs work. - /ui/* falls through to `kind: skip` in mapUrlToPermission, so the static assets are served unauthenticated. Each API call from the SPA still carries the bearer token. Deploy: - Dockerfile.mcpd builds the @mcpctl/web bundle in the same builder stage and copies dist/ to /usr/share/mcpd/web in the runtime image. Smoke (personality.smoke.test.ts): - Live mcpd flow: create secret/llm/agent/personality, attach an agent-direct prompt, verify the binding listing, reject double- attach (409) + foreign-agent prompt (400), set defaultPersonality by name, detach + delete cleanup. Docs: - New docs/personalities.md: VLAN-on-ethernet model, system-block ordering table, three prompt scopes, CLI walkthrough, web UI walkthrough, full API surface, RBAC notes. - agents.md and chat.md cross-link. - README's Agents section gains a Personalities subsection. Test count after Stage 6: mcpd: 801/801 cli: 430/430 web: 7/7 db: 58/62 (4 pre-existing) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:48:43 +01:00
'@fastify/accept-negotiator@2.0.1': {}
2026-02-21 03:10:39 +00:00
'@fastify/ajv-compiler@4.0.5':
dependencies:
ajv: 8.18.0
ajv-formats: 3.0.1(ajv@8.18.0)
fast-uri: 3.1.0
'@fastify/cors@10.1.0':
dependencies:
fastify-plugin: 5.1.0
mnemonist: 0.40.0
'@fastify/error@4.2.0': {}
'@fastify/fast-json-stringify-compiler@5.0.3':
dependencies:
fast-json-stringify: 6.3.0
'@fastify/forwarded@3.0.1': {}
'@fastify/helmet@12.0.1':
dependencies:
fastify-plugin: 5.1.0
helmet: 7.2.0
'@fastify/merge-json-schemas@0.2.1':
dependencies:
dequal: 2.0.3
'@fastify/proxy-addr@5.1.0':
dependencies:
'@fastify/forwarded': 3.0.1
ipaddr.js: 2.3.0
'@fastify/rate-limit@10.3.0':
dependencies:
'@lukeed/ms': 2.0.2
fastify-plugin: 5.1.0
toad-cache: 3.7.0
feat(mcpd+deploy): serve web UI at /ui + smoke tests + docs (Stage 6) The closing stage. mcpd now hosts the Stage 5 SPA, the Docker image bundles the build artifact, a smoke test exercises the personality HTTP surface end-to-end, and the user-facing docs spell out the mental model. mcpd: - Add @fastify/static dep. - New routes/web-ui.ts: registers /ui/* against a static bundle. Looks for the bundle at $MCPD_WEB_ROOT, then /usr/share/mcpd/web (the Docker image path), then a dev-tree fallback. Logs and skips cleanly if missing — API-only deploys keep working. - SPA fallback: any /ui/<path> that doesn't match a file falls through to index.html so direct hits to react-router URLs work. - /ui/* falls through to `kind: skip` in mapUrlToPermission, so the static assets are served unauthenticated. Each API call from the SPA still carries the bearer token. Deploy: - Dockerfile.mcpd builds the @mcpctl/web bundle in the same builder stage and copies dist/ to /usr/share/mcpd/web in the runtime image. Smoke (personality.smoke.test.ts): - Live mcpd flow: create secret/llm/agent/personality, attach an agent-direct prompt, verify the binding listing, reject double- attach (409) + foreign-agent prompt (400), set defaultPersonality by name, detach + delete cleanup. Docs: - New docs/personalities.md: VLAN-on-ethernet model, system-block ordering table, three prompt scopes, CLI walkthrough, web UI walkthrough, full API surface, RBAC notes. - agents.md and chat.md cross-link. - README's Agents section gains a Personalities subsection. Test count after Stage 6: mcpd: 801/801 cli: 430/430 web: 7/7 db: 58/62 (4 pre-existing) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:48:43 +01:00
'@fastify/send@4.1.0':
dependencies:
'@lukeed/ms': 2.0.2
escape-html: 1.0.3
fast-decode-uri-component: 1.0.1
http-errors: 2.0.1
mime: 3.0.0
'@fastify/static@8.3.0':
dependencies:
'@fastify/accept-negotiator': 2.0.1
'@fastify/send': 4.1.0
content-disposition: 0.5.4
fastify-plugin: 5.1.0
fastq: 1.20.1
glob: 11.1.0
'@gar/promise-retry@1.0.3': {}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
'@google/genai@1.52.0(@modelcontextprotocol/sdk@1.26.0(zod@3.25.76))':
dependencies:
google-auth-library: 10.9.1
p-retry: 4.6.2
protobufjs: 7.5.4
ws: 8.19.0
optionalDependencies:
'@modelcontextprotocol/sdk': 1.26.0(zod@3.25.76)
transitivePeerDependencies:
- bufferutil
- supports-color
- utf-8-validate
'@grpc/grpc-js@1.14.3':
dependencies:
'@grpc/proto-loader': 0.8.0
'@js-sdsl/ordered-map': 4.4.2
'@grpc/proto-loader@0.7.15':
dependencies:
lodash.camelcase: 4.3.0
long: 5.3.2
protobufjs: 7.5.4
yargs: 17.7.2
'@grpc/proto-loader@0.8.0':
dependencies:
lodash.camelcase: 4.3.0
long: 5.3.2
protobufjs: 7.5.4
yargs: 17.7.2
2026-02-21 03:10:39 +00:00
'@hono/node-server@1.19.9(hono@4.12.0)':
dependencies:
hono: 4.12.0
'@humanfs/core@0.19.1': {}
'@humanfs/node@0.16.7':
dependencies:
'@humanfs/core': 0.19.1
'@humanwhocodes/retry': 0.4.3
'@humanwhocodes/module-importer@1.0.1': {}
'@humanwhocodes/retry@0.4.3': {}
feat(web): bold redesign — Tailwind v4 + shadcn-style primitives + Skills/Proposals/Revisions UI Phase 6 of the Skills + Revisions + Proposals work. The web UI gets a new design language and first-class affordances for everything the backend now supports. ## Visual direction - Tailwind v4 with custom @theme block (oklch tokens). Dark-mode-only (internal tool — light mode doubles QA surface). - Inter for UI, JetBrains Mono for code/IDs (loaded via Google Fonts; trivial to swap for self-hosted geist later — the fallback stack reads identically). - Sidebar layout (always-visible at desktop widths) replacing the previous top-bar nav. Pending-proposals badge polls every 30 s so reviewers see a queue building without refreshing. - Lucide icons throughout. - Spacing and radii on Tailwind defaults. Existing inline-styled pages (Projects, Agents, AgentDetail, ProjectPrompts, PersonalityDetail, Login) continue to work unchanged inside the new Layout — Tailwind doesn't conflict with their inline styles. A follow-up can migrate them incrementally. ## What's added ### Build infra (src/web/) - package.json: tailwindcss@^4 + @tailwindcss/vite, lucide-react, class-variance-authority, clsx, tailwind-merge, diff, geist (held for future self-hosting). - vite.config.ts: registers the @tailwindcss/vite plugin. - src/index.css: Tailwind import + @theme tokens + @layer base. - src/main.tsx: imports index.css. - src/lib/utils.ts: shadcn-style cn() helper. ### shadcn-style primitives (src/components/ui/) Hand-written rather than generated via `npx shadcn` so the repo doesn't depend on a CLI tool that needs interactive runtime: - button.tsx — variants: primary / secondary / ghost / danger / link; sizes: sm / md / lg / icon. - card.tsx — Card + Header/Title/Description/Content/Footer subparts. - badge.tsx — variants: default / info / success / warning / danger / outline. - input.tsx — Input + Textarea + Label. - tabs.tsx — no-dep accessible Tabs (no Radix needed for our use). - separator.tsx — h/v separator with role=separator. ### Diff component (src/components/Diff.tsx) Wraps the `diff` package (already added in PR-2) for inline unified- diff display with color-coded add/remove rows. Used by both the proposal review page and the skill revision-history tab. ### New pages (src/pages/) - Dashboard.tsx — at-a-glance home. Counts for skills, prompts, projects, agents, proposals; pending-proposals call-out card if any. - Skills.tsx — list view, separated into Global vs Project/Agent- scoped sections. - SkillDetail.tsx — name + semver + description; tabs for SKILL.md / Files / Metadata / History. History tab shows revisions with click-to-diff against the live body. - Proposals.tsx — queue with Pending/Approved/Rejected tabs. Pending count is highlighted in amber. - ProposalDetail.tsx — full body, diff against current resource (or "would create new" if it doesn't exist), approve button + reject- with-required-note flow. ### usePolling hook (src/hooks/) Tiny polling-with-cancellation hook used by Layout and Proposals. ### Layout rewrite (src/components/Layout.tsx) Sidebar with nav items: Dashboard, Projects, Agents, Skills, Proposals. Lucide icons. Active-route highlighting via NavLink. Pending-proposals warning badge on the Proposals item. ### Routes (src/App.tsx) New routes: /dashboard, /skills, /skills/:name, /proposals, /proposals/:id. Default redirects to /dashboard. ### API types (src/api.ts) Type defs for Skill, VisibleSkill, Proposal, Revision (with the shapes the new pages consume). ## Tests Existing 7 web tests still pass (Login + api). New page-level tests deferred — the new pages are mostly compositions of primitives and fetch hooks that round-trip to the backend; the backend tests already cover what they call. PR-7 polish can add render-and-click tests if coverage drift surfaces. ## Verification - `pnpm --filter @mcpctl/web build` clean, no warnings. - `pnpm test:run` whole monorepo: 162 test files / 2157 tests green. - Visual smoke deferred — needs a running mcpd to populate the fixtures. Manual smoke tested locally is the next step. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:54:55 +01:00
'@img/colour@1.1.0':
optional: true
'@img/sharp-darwin-arm64@0.34.5':
optionalDependencies:
'@img/sharp-libvips-darwin-arm64': 1.2.4
optional: true
'@img/sharp-darwin-x64@0.34.5':
optionalDependencies:
'@img/sharp-libvips-darwin-x64': 1.2.4
optional: true
'@img/sharp-libvips-darwin-arm64@1.2.4':
optional: true
'@img/sharp-libvips-darwin-x64@1.2.4':
optional: true
'@img/sharp-libvips-linux-arm64@1.2.4':
optional: true
'@img/sharp-libvips-linux-arm@1.2.4':
optional: true
'@img/sharp-libvips-linux-ppc64@1.2.4':
optional: true
'@img/sharp-libvips-linux-riscv64@1.2.4':
optional: true
'@img/sharp-libvips-linux-s390x@1.2.4':
optional: true
'@img/sharp-libvips-linux-x64@1.2.4':
optional: true
'@img/sharp-libvips-linuxmusl-arm64@1.2.4':
optional: true
'@img/sharp-libvips-linuxmusl-x64@1.2.4':
optional: true
'@img/sharp-linux-arm64@0.34.5':
optionalDependencies:
'@img/sharp-libvips-linux-arm64': 1.2.4
optional: true
'@img/sharp-linux-arm@0.34.5':
optionalDependencies:
'@img/sharp-libvips-linux-arm': 1.2.4
optional: true
'@img/sharp-linux-ppc64@0.34.5':
optionalDependencies:
'@img/sharp-libvips-linux-ppc64': 1.2.4
optional: true
'@img/sharp-linux-riscv64@0.34.5':
optionalDependencies:
'@img/sharp-libvips-linux-riscv64': 1.2.4
optional: true
'@img/sharp-linux-s390x@0.34.5':
optionalDependencies:
'@img/sharp-libvips-linux-s390x': 1.2.4
optional: true
'@img/sharp-linux-x64@0.34.5':
optionalDependencies:
'@img/sharp-libvips-linux-x64': 1.2.4
optional: true
'@img/sharp-linuxmusl-arm64@0.34.5':
optionalDependencies:
'@img/sharp-libvips-linuxmusl-arm64': 1.2.4
optional: true
'@img/sharp-linuxmusl-x64@0.34.5':
optionalDependencies:
'@img/sharp-libvips-linuxmusl-x64': 1.2.4
optional: true
'@img/sharp-wasm32@0.34.5':
dependencies:
'@emnapi/runtime': 1.10.0
optional: true
'@img/sharp-win32-arm64@0.34.5':
optional: true
'@img/sharp-win32-ia32@0.34.5':
optional: true
'@img/sharp-win32-x64@0.34.5':
optional: true
'@inkjs/ui@2.0.0(ink@6.8.0(@types/react@19.2.14)(react@19.2.4))':
dependencies:
chalk: 5.6.2
cli-spinners: 3.4.0
deepmerge: 4.3.1
figures: 6.1.0
ink: 6.8.0(@types/react@19.2.14)(react@19.2.4)
2026-02-21 03:10:39 +00:00
'@inquirer/ansi@1.0.2': {}
'@inquirer/checkbox@4.3.2(@types/node@25.3.0)':
2026-02-21 03:10:39 +00:00
dependencies:
'@inquirer/ansi': 1.0.2
'@inquirer/core': 10.3.2(@types/node@25.3.0)
2026-02-21 03:10:39 +00:00
'@inquirer/figures': 1.0.15
'@inquirer/type': 3.0.10(@types/node@25.3.0)
2026-02-21 03:10:39 +00:00
yoctocolors-cjs: 2.1.3
optionalDependencies:
'@types/node': 25.3.0
2026-02-21 03:10:39 +00:00
'@inquirer/confirm@5.1.21(@types/node@25.3.0)':
2026-02-21 03:10:39 +00:00
dependencies:
'@inquirer/core': 10.3.2(@types/node@25.3.0)
'@inquirer/type': 3.0.10(@types/node@25.3.0)
optionalDependencies:
'@types/node': 25.3.0
2026-02-21 03:10:39 +00:00
'@inquirer/core@10.3.2(@types/node@25.3.0)':
2026-02-21 03:10:39 +00:00
dependencies:
'@inquirer/ansi': 1.0.2
'@inquirer/figures': 1.0.15
'@inquirer/type': 3.0.10(@types/node@25.3.0)
2026-02-21 03:10:39 +00:00
cli-width: 4.1.0
mute-stream: 2.0.0
signal-exit: 4.1.0
wrap-ansi: 6.2.0
yoctocolors-cjs: 2.1.3
optionalDependencies:
'@types/node': 25.3.0
2026-02-21 03:10:39 +00:00
'@inquirer/editor@4.2.23(@types/node@25.3.0)':
2026-02-21 03:10:39 +00:00
dependencies:
'@inquirer/core': 10.3.2(@types/node@25.3.0)
'@inquirer/external-editor': 1.0.3(@types/node@25.3.0)
'@inquirer/type': 3.0.10(@types/node@25.3.0)
optionalDependencies:
'@types/node': 25.3.0
2026-02-21 03:10:39 +00:00
'@inquirer/expand@4.0.23(@types/node@25.3.0)':
2026-02-21 03:10:39 +00:00
dependencies:
'@inquirer/core': 10.3.2(@types/node@25.3.0)
'@inquirer/type': 3.0.10(@types/node@25.3.0)
2026-02-21 03:10:39 +00:00
yoctocolors-cjs: 2.1.3
optionalDependencies:
'@types/node': 25.3.0
2026-02-21 03:10:39 +00:00
'@inquirer/external-editor@1.0.3(@types/node@25.3.0)':
2026-02-21 03:10:39 +00:00
dependencies:
chardet: 2.1.1
iconv-lite: 0.7.2
optionalDependencies:
'@types/node': 25.3.0
2026-02-21 03:10:39 +00:00
'@inquirer/figures@1.0.15': {}
'@inquirer/input@4.3.1(@types/node@25.3.0)':
2026-02-21 03:10:39 +00:00
dependencies:
'@inquirer/core': 10.3.2(@types/node@25.3.0)
'@inquirer/type': 3.0.10(@types/node@25.3.0)
optionalDependencies:
'@types/node': 25.3.0
2026-02-21 03:10:39 +00:00
'@inquirer/number@3.0.23(@types/node@25.3.0)':
2026-02-21 03:10:39 +00:00
dependencies:
'@inquirer/core': 10.3.2(@types/node@25.3.0)
'@inquirer/type': 3.0.10(@types/node@25.3.0)
optionalDependencies:
'@types/node': 25.3.0
2026-02-21 03:10:39 +00:00
'@inquirer/password@4.0.23(@types/node@25.3.0)':
2026-02-21 03:10:39 +00:00
dependencies:
'@inquirer/ansi': 1.0.2
'@inquirer/core': 10.3.2(@types/node@25.3.0)
'@inquirer/type': 3.0.10(@types/node@25.3.0)
optionalDependencies:
'@types/node': 25.3.0
'@inquirer/prompts@7.10.1(@types/node@25.3.0)':
dependencies:
'@inquirer/checkbox': 4.3.2(@types/node@25.3.0)
'@inquirer/confirm': 5.1.21(@types/node@25.3.0)
'@inquirer/editor': 4.2.23(@types/node@25.3.0)
'@inquirer/expand': 4.0.23(@types/node@25.3.0)
'@inquirer/input': 4.3.1(@types/node@25.3.0)
'@inquirer/number': 3.0.23(@types/node@25.3.0)
'@inquirer/password': 4.0.23(@types/node@25.3.0)
'@inquirer/rawlist': 4.1.11(@types/node@25.3.0)
'@inquirer/search': 3.2.2(@types/node@25.3.0)
'@inquirer/select': 4.4.2(@types/node@25.3.0)
optionalDependencies:
'@types/node': 25.3.0
2026-02-21 03:10:39 +00:00
'@inquirer/rawlist@4.1.11(@types/node@25.3.0)':
2026-02-21 03:10:39 +00:00
dependencies:
'@inquirer/core': 10.3.2(@types/node@25.3.0)
'@inquirer/type': 3.0.10(@types/node@25.3.0)
2026-02-21 03:10:39 +00:00
yoctocolors-cjs: 2.1.3
optionalDependencies:
'@types/node': 25.3.0
2026-02-21 03:10:39 +00:00
'@inquirer/search@3.2.2(@types/node@25.3.0)':
2026-02-21 03:10:39 +00:00
dependencies:
'@inquirer/core': 10.3.2(@types/node@25.3.0)
2026-02-21 03:10:39 +00:00
'@inquirer/figures': 1.0.15
'@inquirer/type': 3.0.10(@types/node@25.3.0)
2026-02-21 03:10:39 +00:00
yoctocolors-cjs: 2.1.3
optionalDependencies:
'@types/node': 25.3.0
2026-02-21 03:10:39 +00:00
'@inquirer/select@4.4.2(@types/node@25.3.0)':
2026-02-21 03:10:39 +00:00
dependencies:
'@inquirer/ansi': 1.0.2
'@inquirer/core': 10.3.2(@types/node@25.3.0)
2026-02-21 03:10:39 +00:00
'@inquirer/figures': 1.0.15
'@inquirer/type': 3.0.10(@types/node@25.3.0)
2026-02-21 03:10:39 +00:00
yoctocolors-cjs: 2.1.3
optionalDependencies:
'@types/node': 25.3.0
2026-02-21 03:10:39 +00:00
'@inquirer/type@3.0.10(@types/node@25.3.0)':
optionalDependencies:
'@types/node': 25.3.0
2026-02-21 03:10:39 +00:00
feat(mcpd+deploy): serve web UI at /ui + smoke tests + docs (Stage 6) The closing stage. mcpd now hosts the Stage 5 SPA, the Docker image bundles the build artifact, a smoke test exercises the personality HTTP surface end-to-end, and the user-facing docs spell out the mental model. mcpd: - Add @fastify/static dep. - New routes/web-ui.ts: registers /ui/* against a static bundle. Looks for the bundle at $MCPD_WEB_ROOT, then /usr/share/mcpd/web (the Docker image path), then a dev-tree fallback. Logs and skips cleanly if missing — API-only deploys keep working. - SPA fallback: any /ui/<path> that doesn't match a file falls through to index.html so direct hits to react-router URLs work. - /ui/* falls through to `kind: skip` in mapUrlToPermission, so the static assets are served unauthenticated. Each API call from the SPA still carries the bearer token. Deploy: - Dockerfile.mcpd builds the @mcpctl/web bundle in the same builder stage and copies dist/ to /usr/share/mcpd/web in the runtime image. Smoke (personality.smoke.test.ts): - Live mcpd flow: create secret/llm/agent/personality, attach an agent-direct prompt, verify the binding listing, reject double- attach (409) + foreign-agent prompt (400), set defaultPersonality by name, detach + delete cleanup. Docs: - New docs/personalities.md: VLAN-on-ethernet model, system-block ordering table, three prompt scopes, CLI walkthrough, web UI walkthrough, full API surface, RBAC notes. - agents.md and chat.md cross-link. - README's Agents section gains a Personalities subsection. Test count after Stage 6: mcpd: 801/801 cli: 430/430 web: 7/7 db: 58/62 (4 pre-existing) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:48:43 +01:00
'@isaacs/cliui@9.0.0': {}
'@isaacs/fs-minipass@4.0.1':
dependencies:
minipass: 7.1.3
'@isaacs/string-locale-compare@1.1.0': {}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
'@jridgewell/gen-mapping@0.3.13':
dependencies:
'@jridgewell/sourcemap-codec': 1.5.5
'@jridgewell/trace-mapping': 0.3.31
'@jridgewell/remapping@2.3.5':
dependencies:
'@jridgewell/gen-mapping': 0.3.13
'@jridgewell/trace-mapping': 0.3.31
2026-02-21 03:10:39 +00:00
'@jridgewell/resolve-uri@3.1.2': {}
'@jridgewell/sourcemap-codec@1.5.5': {}
'@jridgewell/trace-mapping@0.3.31':
dependencies:
'@jridgewell/resolve-uri': 3.1.2
'@jridgewell/sourcemap-codec': 1.5.5
'@js-sdsl/ordered-map@4.4.2': {}
'@jsep-plugin/assignment@1.3.0(jsep@1.4.0)':
dependencies:
jsep: 1.4.0
'@jsep-plugin/regex@1.0.4(jsep@1.4.0)':
dependencies:
jsep: 1.4.0
'@kubernetes/client-node@1.4.0':
dependencies:
'@types/js-yaml': 4.0.9
'@types/node': 24.12.2
'@types/node-fetch': 2.6.13
'@types/stream-buffers': 3.0.8
form-data: 4.0.5
hpagent: 1.2.0
isomorphic-ws: 5.0.0(ws@8.19.0)
js-yaml: 4.1.1
jsonpath-plus: 10.4.0
node-fetch: 2.7.0
openid-client: 6.8.2
rfc4648: 1.5.4
socks-proxy-agent: 8.0.5
stream-buffers: 3.0.3
tar-fs: 3.1.2
ws: 8.19.0
transitivePeerDependencies:
- bare-abort-controller
- bare-buffer
- bufferutil
- encoding
- react-native-b4a
- supports-color
- utf-8-validate
'@logdna/tail-file@2.2.0': {}
2026-02-21 03:10:39 +00:00
'@lukeed/ms@2.0.2': {}
'@mapbox/node-pre-gyp@1.0.11':
dependencies:
detect-libc: 2.1.2
https-proxy-agent: 5.0.1
make-dir: 3.1.0
node-fetch: 2.7.0
nopt: 5.0.0
npmlog: 5.0.1
rimraf: 3.0.2
semver: 7.7.4
tar: 6.2.1
transitivePeerDependencies:
- encoding
- supports-color
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
'@mariozechner/clipboard-darwin-arm64@0.3.9':
optional: true
'@mariozechner/clipboard-darwin-universal@0.3.9':
optional: true
'@mariozechner/clipboard-darwin-x64@0.3.9':
optional: true
'@mariozechner/clipboard-linux-arm64-gnu@0.3.9':
optional: true
'@mariozechner/clipboard-linux-arm64-musl@0.3.9':
optional: true
'@mariozechner/clipboard-linux-riscv64-gnu@0.3.9':
optional: true
'@mariozechner/clipboard-linux-x64-gnu@0.3.9':
optional: true
'@mariozechner/clipboard-linux-x64-musl@0.3.9':
optional: true
'@mariozechner/clipboard-win32-arm64-msvc@0.3.9':
optional: true
'@mariozechner/clipboard-win32-x64-msvc@0.3.9':
optional: true
'@mariozechner/clipboard@0.3.9':
optionalDependencies:
'@mariozechner/clipboard-darwin-arm64': 0.3.9
'@mariozechner/clipboard-darwin-universal': 0.3.9
'@mariozechner/clipboard-darwin-x64': 0.3.9
'@mariozechner/clipboard-linux-arm64-gnu': 0.3.9
'@mariozechner/clipboard-linux-arm64-musl': 0.3.9
'@mariozechner/clipboard-linux-riscv64-gnu': 0.3.9
'@mariozechner/clipboard-linux-x64-gnu': 0.3.9
'@mariozechner/clipboard-linux-x64-musl': 0.3.9
'@mariozechner/clipboard-win32-arm64-msvc': 0.3.9
'@mariozechner/clipboard-win32-x64-msvc': 0.3.9
optional: true
'@mistralai/mistralai@2.2.6(@opentelemetry/api@1.9.0)':
dependencies:
'@opentelemetry/semantic-conventions': 1.43.0
ws: 8.19.0
zod: 3.25.76
zod-to-json-schema: 3.25.1(zod@3.25.76)
optionalDependencies:
'@opentelemetry/api': 1.9.0
transitivePeerDependencies:
- bufferutil
- utf-8-validate
2026-02-21 03:10:39 +00:00
'@modelcontextprotocol/sdk@1.26.0(zod@3.25.76)':
dependencies:
'@hono/node-server': 1.19.9(hono@4.12.0)
ajv: 8.18.0
ajv-formats: 3.0.1(ajv@8.18.0)
content-type: 1.0.5
cors: 2.8.6
cross-spawn: 7.0.6
eventsource: 3.0.7
eventsource-parser: 3.0.6
express: 5.2.1
express-rate-limit: 8.2.1(express@5.2.1)
hono: 4.12.0
jose: 6.1.3
json-schema-typed: 8.0.2
pkce-challenge: 5.0.1
raw-body: 3.0.2
zod: 3.25.76
zod-to-json-schema: 3.25.1(zod@3.25.76)
transitivePeerDependencies:
- supports-color
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
optional: true
'@modelcontextprotocol/sdk@1.26.0(zod@4.1.8)':
dependencies:
'@hono/node-server': 1.19.9(hono@4.12.0)
ajv: 8.18.0
ajv-formats: 3.0.1(ajv@8.18.0)
content-type: 1.0.5
cors: 2.8.6
cross-spawn: 7.0.6
eventsource: 3.0.7
eventsource-parser: 3.0.6
express: 5.2.1
express-rate-limit: 8.2.1(express@5.2.1)
hono: 4.12.0
jose: 6.1.3
json-schema-typed: 8.0.2
pkce-challenge: 5.0.1
raw-body: 3.0.2
zod: 4.1.8
zod-to-json-schema: 3.25.1(zod@4.1.8)
transitivePeerDependencies:
- supports-color
2026-02-21 03:10:39 +00:00
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
'@monaco-editor/loader@1.7.0':
dependencies:
state-local: 1.0.7
'@monaco-editor/react@4.7.0(monaco-editor@0.55.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)':
dependencies:
'@monaco-editor/loader': 1.7.0
monaco-editor: 0.55.1
react: 19.2.5
react-dom: 19.2.5(react@19.2.5)
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
'@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.4':
optional: true
'@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.4':
optional: true
'@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.4':
optional: true
'@msgpackr-extract/msgpackr-extract-linux-arm@3.0.4':
optional: true
'@msgpackr-extract/msgpackr-extract-linux-x64@3.0.4':
optional: true
'@msgpackr-extract/msgpackr-extract-win32-x64@3.0.4':
optional: true
feat(web): bold redesign — Tailwind v4 + shadcn-style primitives + Skills/Proposals/Revisions UI Phase 6 of the Skills + Revisions + Proposals work. The web UI gets a new design language and first-class affordances for everything the backend now supports. ## Visual direction - Tailwind v4 with custom @theme block (oklch tokens). Dark-mode-only (internal tool — light mode doubles QA surface). - Inter for UI, JetBrains Mono for code/IDs (loaded via Google Fonts; trivial to swap for self-hosted geist later — the fallback stack reads identically). - Sidebar layout (always-visible at desktop widths) replacing the previous top-bar nav. Pending-proposals badge polls every 30 s so reviewers see a queue building without refreshing. - Lucide icons throughout. - Spacing and radii on Tailwind defaults. Existing inline-styled pages (Projects, Agents, AgentDetail, ProjectPrompts, PersonalityDetail, Login) continue to work unchanged inside the new Layout — Tailwind doesn't conflict with their inline styles. A follow-up can migrate them incrementally. ## What's added ### Build infra (src/web/) - package.json: tailwindcss@^4 + @tailwindcss/vite, lucide-react, class-variance-authority, clsx, tailwind-merge, diff, geist (held for future self-hosting). - vite.config.ts: registers the @tailwindcss/vite plugin. - src/index.css: Tailwind import + @theme tokens + @layer base. - src/main.tsx: imports index.css. - src/lib/utils.ts: shadcn-style cn() helper. ### shadcn-style primitives (src/components/ui/) Hand-written rather than generated via `npx shadcn` so the repo doesn't depend on a CLI tool that needs interactive runtime: - button.tsx — variants: primary / secondary / ghost / danger / link; sizes: sm / md / lg / icon. - card.tsx — Card + Header/Title/Description/Content/Footer subparts. - badge.tsx — variants: default / info / success / warning / danger / outline. - input.tsx — Input + Textarea + Label. - tabs.tsx — no-dep accessible Tabs (no Radix needed for our use). - separator.tsx — h/v separator with role=separator. ### Diff component (src/components/Diff.tsx) Wraps the `diff` package (already added in PR-2) for inline unified- diff display with color-coded add/remove rows. Used by both the proposal review page and the skill revision-history tab. ### New pages (src/pages/) - Dashboard.tsx — at-a-glance home. Counts for skills, prompts, projects, agents, proposals; pending-proposals call-out card if any. - Skills.tsx — list view, separated into Global vs Project/Agent- scoped sections. - SkillDetail.tsx — name + semver + description; tabs for SKILL.md / Files / Metadata / History. History tab shows revisions with click-to-diff against the live body. - Proposals.tsx — queue with Pending/Approved/Rejected tabs. Pending count is highlighted in amber. - ProposalDetail.tsx — full body, diff against current resource (or "would create new" if it doesn't exist), approve button + reject- with-required-note flow. ### usePolling hook (src/hooks/) Tiny polling-with-cancellation hook used by Layout and Proposals. ### Layout rewrite (src/components/Layout.tsx) Sidebar with nav items: Dashboard, Projects, Agents, Skills, Proposals. Lucide icons. Active-route highlighting via NavLink. Pending-proposals warning badge on the Proposals item. ### Routes (src/App.tsx) New routes: /dashboard, /skills, /skills/:name, /proposals, /proposals/:id. Default redirects to /dashboard. ### API types (src/api.ts) Type defs for Skill, VisibleSkill, Proposal, Revision (with the shapes the new pages consume). ## Tests Existing 7 web tests still pass (Login + api). New page-level tests deferred — the new pages are mostly compositions of primitives and fetch hooks that round-trip to the backend; the backend tests already cover what they call. PR-7 polish can add render-and-click tests if coverage drift surfaces. ## Verification - `pnpm --filter @mcpctl/web build` clean, no warnings. - `pnpm test:run` whole monorepo: 162 test files / 2157 tests green. - Visual smoke deferred — needs a running mcpd to populate the fixtures. Manual smoke tested locally is the next step. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:54:55 +01:00
'@next/env@16.2.5': {}
'@next/swc-darwin-arm64@16.2.5':
optional: true
'@next/swc-darwin-x64@16.2.5':
optional: true
'@next/swc-linux-arm64-gnu@16.2.5':
optional: true
'@next/swc-linux-arm64-musl@16.2.5':
optional: true
'@next/swc-linux-x64-gnu@16.2.5':
optional: true
'@next/swc-linux-x64-musl@16.2.5':
optional: true
'@next/swc-win32-arm64-msvc@16.2.5':
optional: true
'@next/swc-win32-x64-msvc@16.2.5':
optional: true
'@npmcli/agent@4.0.2':
dependencies:
agent-base: 7.1.4
http-proxy-agent: 7.0.2
https-proxy-agent: 7.0.6
lru-cache: 11.2.6
socks-proxy-agent: 8.0.5
transitivePeerDependencies:
- supports-color
'@npmcli/arborist@9.9.0':
dependencies:
'@gar/promise-retry': 1.0.3
'@isaacs/string-locale-compare': 1.1.0
'@npmcli/fs': 5.0.0
'@npmcli/installed-package-contents': 4.0.0
'@npmcli/map-workspaces': 5.0.3
'@npmcli/metavuln-calculator': 9.0.3
'@npmcli/name-from-folder': 4.0.0
'@npmcli/node-gyp': 5.0.0
'@npmcli/package-json': 7.0.5
'@npmcli/query': 5.0.0
'@npmcli/redact': 4.0.0
'@npmcli/run-script': 10.0.4
bin-links: 6.0.2
cacache: 20.0.4
common-ancestor-path: 2.0.0
hosted-git-info: 9.0.3
json-stringify-nice: 1.1.4
lru-cache: 11.2.6
minimatch: 10.2.2
nopt: 9.0.0
npm-install-checks: 8.0.0
npm-package-arg: 13.0.2
npm-pick-manifest: 11.0.3
npm-registry-fetch: 19.1.1
pacote: 21.5.1
parse-conflict-json: 5.0.1
proc-log: 6.1.0
proggy: 4.0.0
promise-all-reject-late: 1.0.1
promise-call-limit: 3.0.2
semver: 7.7.4
ssri: 13.0.1
treeverse: 3.0.0
walk-up-path: 4.0.0
transitivePeerDependencies:
- supports-color
'@npmcli/fs@5.0.0':
dependencies:
semver: 7.7.4
'@npmcli/git@7.0.2':
dependencies:
'@gar/promise-retry': 1.0.3
'@npmcli/promise-spawn': 9.0.1
ini: 6.0.0
lru-cache: 11.2.6
npm-pick-manifest: 11.0.3
proc-log: 6.1.0
semver: 7.7.4
which: 6.0.1
'@npmcli/installed-package-contents@4.0.0':
dependencies:
npm-bundled: 5.0.0
npm-normalize-package-bin: 5.0.0
'@npmcli/map-workspaces@5.0.3':
dependencies:
'@npmcli/name-from-folder': 4.0.0
'@npmcli/package-json': 7.0.5
glob: 13.0.6
minimatch: 10.2.2
'@npmcli/metavuln-calculator@9.0.3':
dependencies:
cacache: 20.0.4
json-parse-even-better-errors: 5.0.0
pacote: 21.5.1
proc-log: 6.1.0
semver: 7.7.4
transitivePeerDependencies:
- supports-color
'@npmcli/name-from-folder@4.0.0': {}
'@npmcli/node-gyp@5.0.0': {}
'@npmcli/package-json@7.0.5':
dependencies:
'@npmcli/git': 7.0.2
glob: 13.0.6
hosted-git-info: 9.0.3
json-parse-even-better-errors: 5.0.0
proc-log: 6.1.0
semver: 7.7.4
spdx-expression-parse: 4.0.0
'@npmcli/promise-spawn@9.0.1':
dependencies:
which: 6.0.1
'@npmcli/query@5.0.0':
dependencies:
postcss-selector-parser: 7.1.4
'@npmcli/redact@4.0.0': {}
'@npmcli/run-script@10.0.4':
dependencies:
'@npmcli/node-gyp': 5.0.0
'@npmcli/package-json': 7.0.5
'@npmcli/promise-spawn': 9.0.1
node-gyp: 12.4.0
proc-log: 6.1.0
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
'@opencode-ai/plugin@1.18.15(@opentui/core@0.4.5(typescript@5.9.3)(web-tree-sitter@0.25.10))(@opentui/keymap@0.4.5(@opentui/solid@0.4.5(solid-js@1.9.12)(typescript@5.9.3)(web-tree-sitter@0.25.10))(react@19.2.5)(solid-js@1.9.12)(typescript@5.9.3)(web-tree-sitter@0.25.10))(@opentui/solid@0.4.5(solid-js@1.9.12)(typescript@5.9.3)(web-tree-sitter@0.25.10))':
dependencies:
'@ai-sdk/provider': 3.0.8
'@opencode-ai/sdk': 1.18.15
effect: 4.0.0-beta.83
zod: 4.1.8
optionalDependencies:
'@opentui/core': 0.4.5(typescript@5.9.3)(web-tree-sitter@0.25.10)
'@opentui/keymap': 0.4.5(@opentui/solid@0.4.5(solid-js@1.9.12)(typescript@5.9.3)(web-tree-sitter@0.25.10))(react@19.2.5)(solid-js@1.9.12)(typescript@5.9.3)(web-tree-sitter@0.25.10)
'@opentui/solid': 0.4.5(solid-js@1.9.12)(typescript@5.9.3)(web-tree-sitter@0.25.10)
'@opencode-ai/sdk@1.18.15':
dependencies:
cross-spawn: 7.0.6
'@opentelemetry/api-logs@0.220.0':
dependencies:
'@opentelemetry/api': 1.9.1
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
'@opentelemetry/api@1.9.0': {}
'@opentelemetry/api@1.9.1': {}
'@opentelemetry/context-async-hooks@2.9.0(@opentelemetry/api@1.9.1)':
dependencies:
'@opentelemetry/api': 1.9.1
'@opentelemetry/core@2.9.0(@opentelemetry/api@1.9.1)':
dependencies:
'@opentelemetry/api': 1.9.1
'@opentelemetry/semantic-conventions': 1.43.0
'@opentelemetry/exporter-trace-otlp-grpc@0.220.0(@opentelemetry/api@1.9.1)':
dependencies:
'@grpc/grpc-js': 1.14.3
'@opentelemetry/api': 1.9.1
'@opentelemetry/otlp-exporter-base': 0.220.0(@opentelemetry/api@1.9.1)
'@opentelemetry/otlp-grpc-exporter-base': 0.220.0(@opentelemetry/api@1.9.1)
'@opentelemetry/otlp-transformer': 0.220.0(@opentelemetry/api@1.9.1)
'@opentelemetry/sdk-trace': 2.9.0(@opentelemetry/api@1.9.1)
'@opentelemetry/exporter-zipkin@2.9.0(@opentelemetry/api@1.9.1)':
dependencies:
'@opentelemetry/api': 1.9.1
'@opentelemetry/core': 2.9.0(@opentelemetry/api@1.9.1)
'@opentelemetry/resources': 2.9.0(@opentelemetry/api@1.9.1)
'@opentelemetry/sdk-trace': 2.9.0(@opentelemetry/api@1.9.1)
'@opentelemetry/semantic-conventions': 1.43.0
'@opentelemetry/instrumentation-grpc@0.220.0(@opentelemetry/api@1.9.1)':
dependencies:
'@opentelemetry/api': 1.9.1
'@opentelemetry/instrumentation': 0.220.0(@opentelemetry/api@1.9.1)
'@opentelemetry/semantic-conventions': 1.43.0
transitivePeerDependencies:
- supports-color
'@opentelemetry/instrumentation@0.220.0(@opentelemetry/api@1.9.1)':
dependencies:
'@opentelemetry/api': 1.9.1
'@opentelemetry/api-logs': 0.220.0
import-in-the-middle: 3.3.1
require-in-the-middle: 8.0.1
transitivePeerDependencies:
- supports-color
'@opentelemetry/otlp-exporter-base@0.220.0(@opentelemetry/api@1.9.1)':
dependencies:
'@opentelemetry/api': 1.9.1
'@opentelemetry/core': 2.9.0(@opentelemetry/api@1.9.1)
'@opentelemetry/otlp-transformer': 0.220.0(@opentelemetry/api@1.9.1)
'@opentelemetry/otlp-grpc-exporter-base@0.220.0(@opentelemetry/api@1.9.1)':
dependencies:
'@grpc/grpc-js': 1.14.3
'@opentelemetry/api': 1.9.1
'@opentelemetry/core': 2.9.0(@opentelemetry/api@1.9.1)
'@opentelemetry/otlp-exporter-base': 0.220.0(@opentelemetry/api@1.9.1)
'@opentelemetry/otlp-transformer': 0.220.0(@opentelemetry/api@1.9.1)
'@opentelemetry/otlp-transformer@0.220.0(@opentelemetry/api@1.9.1)':
dependencies:
'@opentelemetry/api': 1.9.1
'@opentelemetry/api-logs': 0.220.0
'@opentelemetry/core': 2.9.0(@opentelemetry/api@1.9.1)
'@opentelemetry/resources': 2.9.0(@opentelemetry/api@1.9.1)
'@opentelemetry/sdk-logs': 0.220.0(@opentelemetry/api@1.9.1)
'@opentelemetry/sdk-metrics': 2.9.0(@opentelemetry/api@1.9.1)
'@opentelemetry/sdk-trace': 2.9.0(@opentelemetry/api@1.9.1)
'@opentelemetry/resources@2.9.0(@opentelemetry/api@1.9.1)':
dependencies:
'@opentelemetry/api': 1.9.1
'@opentelemetry/core': 2.9.0(@opentelemetry/api@1.9.1)
'@opentelemetry/semantic-conventions': 1.43.0
'@opentelemetry/sdk-logs@0.220.0(@opentelemetry/api@1.9.1)':
dependencies:
'@opentelemetry/api': 1.9.1
'@opentelemetry/api-logs': 0.220.0
'@opentelemetry/core': 2.9.0(@opentelemetry/api@1.9.1)
'@opentelemetry/resources': 2.9.0(@opentelemetry/api@1.9.1)
'@opentelemetry/semantic-conventions': 1.43.0
'@opentelemetry/sdk-metrics@2.9.0(@opentelemetry/api@1.9.1)':
dependencies:
'@opentelemetry/api': 1.9.1
'@opentelemetry/core': 2.9.0(@opentelemetry/api@1.9.1)
'@opentelemetry/resources': 2.9.0(@opentelemetry/api@1.9.1)
'@opentelemetry/sdk-trace-base@2.9.0(@opentelemetry/api@1.9.1)':
dependencies:
'@opentelemetry/api': 1.9.1
'@opentelemetry/core': 2.9.0(@opentelemetry/api@1.9.1)
'@opentelemetry/resources': 2.9.0(@opentelemetry/api@1.9.1)
'@opentelemetry/sdk-trace': 2.9.0(@opentelemetry/api@1.9.1)
'@opentelemetry/semantic-conventions': 1.43.0
'@opentelemetry/sdk-trace-node@2.9.0(@opentelemetry/api@1.9.1)':
dependencies:
'@opentelemetry/api': 1.9.1
'@opentelemetry/context-async-hooks': 2.9.0(@opentelemetry/api@1.9.1)
'@opentelemetry/core': 2.9.0(@opentelemetry/api@1.9.1)
'@opentelemetry/sdk-trace-base': 2.9.0(@opentelemetry/api@1.9.1)
'@opentelemetry/sdk-trace@2.9.0(@opentelemetry/api@1.9.1)':
dependencies:
'@opentelemetry/api': 1.9.1
'@opentelemetry/core': 2.9.0(@opentelemetry/api@1.9.1)
'@opentelemetry/resources': 2.9.0(@opentelemetry/api@1.9.1)
'@opentelemetry/semantic-conventions': 1.43.0
'@opentelemetry/semantic-conventions@1.43.0': {}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
'@opentui/core-darwin-arm64@0.4.5':
optional: true
'@opentui/core-darwin-x64@0.4.5':
optional: true
'@opentui/core-linux-arm64-musl@0.4.5':
optional: true
'@opentui/core-linux-arm64@0.4.5':
optional: true
'@opentui/core-linux-x64-musl@0.4.5':
optional: true
'@opentui/core-linux-x64@0.4.5':
optional: true
'@opentui/core-win32-arm64@0.4.5':
optional: true
'@opentui/core-win32-x64@0.4.5':
optional: true
'@opentui/core@0.4.5(typescript@5.9.3)(web-tree-sitter@0.25.10)':
dependencies:
bun-ffi-structs: 0.2.4(typescript@5.9.3)
diff: 9.0.0
marked: 17.0.1
string-width: 7.2.0
strip-ansi: 7.1.2
web-tree-sitter: 0.25.10
optionalDependencies:
'@opentui/core-darwin-arm64': 0.4.5
'@opentui/core-darwin-x64': 0.4.5
'@opentui/core-linux-arm64': 0.4.5
'@opentui/core-linux-arm64-musl': 0.4.5
'@opentui/core-linux-x64': 0.4.5
'@opentui/core-linux-x64-musl': 0.4.5
'@opentui/core-win32-arm64': 0.4.5
'@opentui/core-win32-x64': 0.4.5
transitivePeerDependencies:
- typescript
'@opentui/keymap@0.4.5(@opentui/solid@0.4.5(solid-js@1.9.12)(typescript@5.9.3)(web-tree-sitter@0.25.10))(react@19.2.5)(solid-js@1.9.12)(typescript@5.9.3)(web-tree-sitter@0.25.10)':
dependencies:
'@opentui/core': 0.4.5(typescript@5.9.3)(web-tree-sitter@0.25.10)
optionalDependencies:
'@opentui/solid': 0.4.5(solid-js@1.9.12)(typescript@5.9.3)(web-tree-sitter@0.25.10)
react: 19.2.5
solid-js: 1.9.12
transitivePeerDependencies:
- typescript
- web-tree-sitter
'@opentui/solid@0.4.5(solid-js@1.9.12)(typescript@5.9.3)(web-tree-sitter@0.25.10)':
dependencies:
'@babel/core': 7.28.0
'@babel/preset-typescript': 7.27.1(@babel/core@7.28.0)
'@opentui/core': 0.4.5(typescript@5.9.3)(web-tree-sitter@0.25.10)
babel-plugin-module-resolver: 5.0.2
babel-preset-solid: 1.9.12(@babel/core@7.28.0)(solid-js@1.9.12)
entities: 7.0.1
s-js: 0.4.9
solid-js: 1.9.12
transitivePeerDependencies:
- supports-color
- typescript
- web-tree-sitter
2026-02-21 03:10:39 +00:00
'@pinojs/redact@0.4.0': {}
'@prisma/client@6.19.2(prisma@6.19.2(typescript@5.9.3))(typescript@5.9.3)':
optionalDependencies:
prisma: 6.19.2(typescript@5.9.3)
typescript: 5.9.3
'@prisma/config@6.19.2':
dependencies:
c12: 3.1.0
deepmerge-ts: 7.1.5
effect: 3.18.4
empathic: 2.0.0
transitivePeerDependencies:
- magicast
'@prisma/debug@6.19.2': {}
'@prisma/engines-version@7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7': {}
'@prisma/engines@6.19.2':
dependencies:
'@prisma/debug': 6.19.2
'@prisma/engines-version': 7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7
'@prisma/fetch-engine': 6.19.2
'@prisma/get-platform': 6.19.2
'@prisma/fetch-engine@6.19.2':
dependencies:
'@prisma/debug': 6.19.2
'@prisma/engines-version': 7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7
'@prisma/get-platform': 6.19.2
'@prisma/get-platform@6.19.2':
dependencies:
'@prisma/debug': 6.19.2
'@protobufjs/aspromise@1.1.2': {}
'@protobufjs/base64@1.1.2': {}
'@protobufjs/codegen@2.0.4': {}
'@protobufjs/eventemitter@1.1.0': {}
'@protobufjs/fetch@1.1.0':
dependencies:
'@protobufjs/aspromise': 1.1.2
'@protobufjs/inquire': 1.1.0
'@protobufjs/float@1.0.2': {}
'@protobufjs/inquire@1.1.0': {}
'@protobufjs/path@1.1.2': {}
'@protobufjs/pool@1.1.0': {}
'@protobufjs/utf8@1.1.0': {}
'@pulumi/pulumi@3.253.0(typescript@5.9.3)':
dependencies:
'@grpc/grpc-js': 1.14.3
'@logdna/tail-file': 2.2.0
'@npmcli/arborist': 9.9.0
'@opentelemetry/api': 1.9.1
'@opentelemetry/core': 2.9.0(@opentelemetry/api@1.9.1)
'@opentelemetry/exporter-trace-otlp-grpc': 0.220.0(@opentelemetry/api@1.9.1)
'@opentelemetry/exporter-zipkin': 2.9.0(@opentelemetry/api@1.9.1)
'@opentelemetry/instrumentation': 0.220.0(@opentelemetry/api@1.9.1)
'@opentelemetry/instrumentation-grpc': 0.220.0(@opentelemetry/api@1.9.1)
'@opentelemetry/resources': 2.9.0(@opentelemetry/api@1.9.1)
'@opentelemetry/sdk-trace-base': 2.9.0(@opentelemetry/api@1.9.1)
'@opentelemetry/sdk-trace-node': 2.9.0(@opentelemetry/api@1.9.1)
'@opentelemetry/semantic-conventions': 1.43.0
'@types/google-protobuf': 3.15.12
'@types/semver': 7.7.1
execa: 5.1.1
google-protobuf: 3.21.4
ini: 2.0.0
js-yaml: 4.1.1
minimist: 1.2.8
normalize-package-data: 6.0.2
require-from-string: 2.0.2
semver: 7.7.4
source-map-support: 0.5.21
upath: 1.2.0
optionalDependencies:
typescript: 5.9.3
transitivePeerDependencies:
- supports-color
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
'@rolldown/pluginutils@1.0.0-rc.3': {}
2026-02-21 03:10:39 +00:00
'@rollup/rollup-android-arm-eabi@4.58.0':
optional: true
'@rollup/rollup-android-arm64@4.58.0':
optional: true
'@rollup/rollup-darwin-arm64@4.58.0':
optional: true
'@rollup/rollup-darwin-x64@4.58.0':
optional: true
'@rollup/rollup-freebsd-arm64@4.58.0':
optional: true
'@rollup/rollup-freebsd-x64@4.58.0':
optional: true
'@rollup/rollup-linux-arm-gnueabihf@4.58.0':
optional: true
'@rollup/rollup-linux-arm-musleabihf@4.58.0':
optional: true
'@rollup/rollup-linux-arm64-gnu@4.58.0':
optional: true
'@rollup/rollup-linux-arm64-musl@4.58.0':
optional: true
'@rollup/rollup-linux-loong64-gnu@4.58.0':
optional: true
'@rollup/rollup-linux-loong64-musl@4.58.0':
optional: true
'@rollup/rollup-linux-ppc64-gnu@4.58.0':
optional: true
'@rollup/rollup-linux-ppc64-musl@4.58.0':
optional: true
'@rollup/rollup-linux-riscv64-gnu@4.58.0':
optional: true
'@rollup/rollup-linux-riscv64-musl@4.58.0':
optional: true
'@rollup/rollup-linux-s390x-gnu@4.58.0':
optional: true
'@rollup/rollup-linux-x64-gnu@4.58.0':
optional: true
'@rollup/rollup-linux-x64-musl@4.58.0':
optional: true
'@rollup/rollup-openbsd-x64@4.58.0':
optional: true
'@rollup/rollup-openharmony-arm64@4.58.0':
optional: true
'@rollup/rollup-win32-arm64-msvc@4.58.0':
optional: true
'@rollup/rollup-win32-ia32-msvc@4.58.0':
optional: true
'@rollup/rollup-win32-x64-gnu@4.58.0':
optional: true
'@rollup/rollup-win32-x64-msvc@4.58.0':
optional: true
'@sigstore/bundle@4.0.0':
dependencies:
'@sigstore/protobuf-specs': 0.5.1
'@sigstore/core@3.2.1': {}
'@sigstore/protobuf-specs@0.5.1': {}
'@sigstore/sign@4.1.1':
dependencies:
'@gar/promise-retry': 1.0.3
'@sigstore/bundle': 4.0.0
'@sigstore/core': 3.2.1
'@sigstore/protobuf-specs': 0.5.1
make-fetch-happen: 15.0.6
proc-log: 6.1.0
transitivePeerDependencies:
- supports-color
'@sigstore/tuf@4.0.2':
dependencies:
'@sigstore/protobuf-specs': 0.5.1
tuf-js: 4.1.0
transitivePeerDependencies:
- supports-color
'@sigstore/verify@3.1.1':
dependencies:
'@sigstore/bundle': 4.0.0
'@sigstore/core': 3.2.1
'@sigstore/protobuf-specs': 0.5.1
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
'@silvia-odwyer/photon-node@0.3.4': {}
'@smithy/core@3.31.1':
dependencies:
'@smithy/types': 4.16.1
tslib: 2.8.1
'@smithy/credential-provider-imds@4.4.16':
dependencies:
'@smithy/core': 3.31.1
'@smithy/types': 4.16.1
tslib: 2.8.1
'@smithy/fetch-http-handler@5.6.13':
dependencies:
'@smithy/core': 3.31.1
'@smithy/types': 4.16.1
tslib: 2.8.1
'@smithy/is-array-buffer@2.2.0':
dependencies:
tslib: 2.8.1
'@smithy/node-http-handler@4.7.3':
dependencies:
'@smithy/core': 3.31.1
'@smithy/types': 4.16.1
tslib: 2.8.1
'@smithy/node-http-handler@4.9.13':
dependencies:
'@smithy/core': 3.31.1
'@smithy/types': 4.16.1
tslib: 2.8.1
'@smithy/signature-v4@5.6.12':
dependencies:
'@smithy/core': 3.31.1
'@smithy/types': 4.16.1
tslib: 2.8.1
'@smithy/types@4.16.1':
dependencies:
tslib: 2.8.1
'@smithy/util-buffer-from@2.2.0':
dependencies:
'@smithy/is-array-buffer': 2.2.0
tslib: 2.8.1
'@smithy/util-utf8@2.3.0':
dependencies:
'@smithy/util-buffer-from': 2.2.0
tslib: 2.8.1
2026-02-21 03:10:39 +00:00
'@standard-schema/spec@1.1.0': {}
feat(web): bold redesign — Tailwind v4 + shadcn-style primitives + Skills/Proposals/Revisions UI Phase 6 of the Skills + Revisions + Proposals work. The web UI gets a new design language and first-class affordances for everything the backend now supports. ## Visual direction - Tailwind v4 with custom @theme block (oklch tokens). Dark-mode-only (internal tool — light mode doubles QA surface). - Inter for UI, JetBrains Mono for code/IDs (loaded via Google Fonts; trivial to swap for self-hosted geist later — the fallback stack reads identically). - Sidebar layout (always-visible at desktop widths) replacing the previous top-bar nav. Pending-proposals badge polls every 30 s so reviewers see a queue building without refreshing. - Lucide icons throughout. - Spacing and radii on Tailwind defaults. Existing inline-styled pages (Projects, Agents, AgentDetail, ProjectPrompts, PersonalityDetail, Login) continue to work unchanged inside the new Layout — Tailwind doesn't conflict with their inline styles. A follow-up can migrate them incrementally. ## What's added ### Build infra (src/web/) - package.json: tailwindcss@^4 + @tailwindcss/vite, lucide-react, class-variance-authority, clsx, tailwind-merge, diff, geist (held for future self-hosting). - vite.config.ts: registers the @tailwindcss/vite plugin. - src/index.css: Tailwind import + @theme tokens + @layer base. - src/main.tsx: imports index.css. - src/lib/utils.ts: shadcn-style cn() helper. ### shadcn-style primitives (src/components/ui/) Hand-written rather than generated via `npx shadcn` so the repo doesn't depend on a CLI tool that needs interactive runtime: - button.tsx — variants: primary / secondary / ghost / danger / link; sizes: sm / md / lg / icon. - card.tsx — Card + Header/Title/Description/Content/Footer subparts. - badge.tsx — variants: default / info / success / warning / danger / outline. - input.tsx — Input + Textarea + Label. - tabs.tsx — no-dep accessible Tabs (no Radix needed for our use). - separator.tsx — h/v separator with role=separator. ### Diff component (src/components/Diff.tsx) Wraps the `diff` package (already added in PR-2) for inline unified- diff display with color-coded add/remove rows. Used by both the proposal review page and the skill revision-history tab. ### New pages (src/pages/) - Dashboard.tsx — at-a-glance home. Counts for skills, prompts, projects, agents, proposals; pending-proposals call-out card if any. - Skills.tsx — list view, separated into Global vs Project/Agent- scoped sections. - SkillDetail.tsx — name + semver + description; tabs for SKILL.md / Files / Metadata / History. History tab shows revisions with click-to-diff against the live body. - Proposals.tsx — queue with Pending/Approved/Rejected tabs. Pending count is highlighted in amber. - ProposalDetail.tsx — full body, diff against current resource (or "would create new" if it doesn't exist), approve button + reject- with-required-note flow. ### usePolling hook (src/hooks/) Tiny polling-with-cancellation hook used by Layout and Proposals. ### Layout rewrite (src/components/Layout.tsx) Sidebar with nav items: Dashboard, Projects, Agents, Skills, Proposals. Lucide icons. Active-route highlighting via NavLink. Pending-proposals warning badge on the Proposals item. ### Routes (src/App.tsx) New routes: /dashboard, /skills, /skills/:name, /proposals, /proposals/:id. Default redirects to /dashboard. ### API types (src/api.ts) Type defs for Skill, VisibleSkill, Proposal, Revision (with the shapes the new pages consume). ## Tests Existing 7 web tests still pass (Login + api). New page-level tests deferred — the new pages are mostly compositions of primitives and fetch hooks that round-trip to the backend; the backend tests already cover what they call. PR-7 polish can add render-and-click tests if coverage drift surfaces. ## Verification - `pnpm --filter @mcpctl/web build` clean, no warnings. - `pnpm test:run` whole monorepo: 162 test files / 2157 tests green. - Visual smoke deferred — needs a running mcpd to populate the fixtures. Manual smoke tested locally is the next step. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:54:55 +01:00
'@swc/helpers@0.5.15':
dependencies:
tslib: 2.8.1
'@tailwindcss/node@4.2.4':
dependencies:
'@jridgewell/remapping': 2.3.5
enhanced-resolve: 5.21.0
jiti: 2.6.1
lightningcss: 1.32.0
magic-string: 0.30.21
source-map-js: 1.2.1
tailwindcss: 4.2.4
'@tailwindcss/oxide-android-arm64@4.2.4':
optional: true
'@tailwindcss/oxide-darwin-arm64@4.2.4':
optional: true
'@tailwindcss/oxide-darwin-x64@4.2.4':
optional: true
'@tailwindcss/oxide-freebsd-x64@4.2.4':
optional: true
'@tailwindcss/oxide-linux-arm-gnueabihf@4.2.4':
optional: true
'@tailwindcss/oxide-linux-arm64-gnu@4.2.4':
optional: true
'@tailwindcss/oxide-linux-arm64-musl@4.2.4':
optional: true
'@tailwindcss/oxide-linux-x64-gnu@4.2.4':
optional: true
'@tailwindcss/oxide-linux-x64-musl@4.2.4':
optional: true
'@tailwindcss/oxide-wasm32-wasi@4.2.4':
optional: true
'@tailwindcss/oxide-win32-arm64-msvc@4.2.4':
optional: true
'@tailwindcss/oxide-win32-x64-msvc@4.2.4':
optional: true
'@tailwindcss/oxide@4.2.4':
optionalDependencies:
'@tailwindcss/oxide-android-arm64': 4.2.4
'@tailwindcss/oxide-darwin-arm64': 4.2.4
'@tailwindcss/oxide-darwin-x64': 4.2.4
'@tailwindcss/oxide-freebsd-x64': 4.2.4
'@tailwindcss/oxide-linux-arm-gnueabihf': 4.2.4
'@tailwindcss/oxide-linux-arm64-gnu': 4.2.4
'@tailwindcss/oxide-linux-arm64-musl': 4.2.4
'@tailwindcss/oxide-linux-x64-gnu': 4.2.4
'@tailwindcss/oxide-linux-x64-musl': 4.2.4
'@tailwindcss/oxide-wasm32-wasi': 4.2.4
'@tailwindcss/oxide-win32-arm64-msvc': 4.2.4
'@tailwindcss/oxide-win32-x64-msvc': 4.2.4
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
'@tailwindcss/vite@4.2.4(vite@7.3.1(@types/node@25.3.0)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.21.0)(yaml@2.9.0))':
feat(web): bold redesign — Tailwind v4 + shadcn-style primitives + Skills/Proposals/Revisions UI Phase 6 of the Skills + Revisions + Proposals work. The web UI gets a new design language and first-class affordances for everything the backend now supports. ## Visual direction - Tailwind v4 with custom @theme block (oklch tokens). Dark-mode-only (internal tool — light mode doubles QA surface). - Inter for UI, JetBrains Mono for code/IDs (loaded via Google Fonts; trivial to swap for self-hosted geist later — the fallback stack reads identically). - Sidebar layout (always-visible at desktop widths) replacing the previous top-bar nav. Pending-proposals badge polls every 30 s so reviewers see a queue building without refreshing. - Lucide icons throughout. - Spacing and radii on Tailwind defaults. Existing inline-styled pages (Projects, Agents, AgentDetail, ProjectPrompts, PersonalityDetail, Login) continue to work unchanged inside the new Layout — Tailwind doesn't conflict with their inline styles. A follow-up can migrate them incrementally. ## What's added ### Build infra (src/web/) - package.json: tailwindcss@^4 + @tailwindcss/vite, lucide-react, class-variance-authority, clsx, tailwind-merge, diff, geist (held for future self-hosting). - vite.config.ts: registers the @tailwindcss/vite plugin. - src/index.css: Tailwind import + @theme tokens + @layer base. - src/main.tsx: imports index.css. - src/lib/utils.ts: shadcn-style cn() helper. ### shadcn-style primitives (src/components/ui/) Hand-written rather than generated via `npx shadcn` so the repo doesn't depend on a CLI tool that needs interactive runtime: - button.tsx — variants: primary / secondary / ghost / danger / link; sizes: sm / md / lg / icon. - card.tsx — Card + Header/Title/Description/Content/Footer subparts. - badge.tsx — variants: default / info / success / warning / danger / outline. - input.tsx — Input + Textarea + Label. - tabs.tsx — no-dep accessible Tabs (no Radix needed for our use). - separator.tsx — h/v separator with role=separator. ### Diff component (src/components/Diff.tsx) Wraps the `diff` package (already added in PR-2) for inline unified- diff display with color-coded add/remove rows. Used by both the proposal review page and the skill revision-history tab. ### New pages (src/pages/) - Dashboard.tsx — at-a-glance home. Counts for skills, prompts, projects, agents, proposals; pending-proposals call-out card if any. - Skills.tsx — list view, separated into Global vs Project/Agent- scoped sections. - SkillDetail.tsx — name + semver + description; tabs for SKILL.md / Files / Metadata / History. History tab shows revisions with click-to-diff against the live body. - Proposals.tsx — queue with Pending/Approved/Rejected tabs. Pending count is highlighted in amber. - ProposalDetail.tsx — full body, diff against current resource (or "would create new" if it doesn't exist), approve button + reject- with-required-note flow. ### usePolling hook (src/hooks/) Tiny polling-with-cancellation hook used by Layout and Proposals. ### Layout rewrite (src/components/Layout.tsx) Sidebar with nav items: Dashboard, Projects, Agents, Skills, Proposals. Lucide icons. Active-route highlighting via NavLink. Pending-proposals warning badge on the Proposals item. ### Routes (src/App.tsx) New routes: /dashboard, /skills, /skills/:name, /proposals, /proposals/:id. Default redirects to /dashboard. ### API types (src/api.ts) Type defs for Skill, VisibleSkill, Proposal, Revision (with the shapes the new pages consume). ## Tests Existing 7 web tests still pass (Login + api). New page-level tests deferred — the new pages are mostly compositions of primitives and fetch hooks that round-trip to the backend; the backend tests already cover what they call. PR-7 polish can add render-and-click tests if coverage drift surfaces. ## Verification - `pnpm --filter @mcpctl/web build` clean, no warnings. - `pnpm test:run` whole monorepo: 162 test files / 2157 tests green. - Visual smoke deferred — needs a running mcpd to populate the fixtures. Manual smoke tested locally is the next step. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:54:55 +01:00
dependencies:
'@tailwindcss/node': 4.2.4
'@tailwindcss/oxide': 4.2.4
tailwindcss: 4.2.4
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
vite: 7.3.1(@types/node@25.3.0)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.21.0)(yaml@2.9.0)
feat(web): bold redesign — Tailwind v4 + shadcn-style primitives + Skills/Proposals/Revisions UI Phase 6 of the Skills + Revisions + Proposals work. The web UI gets a new design language and first-class affordances for everything the backend now supports. ## Visual direction - Tailwind v4 with custom @theme block (oklch tokens). Dark-mode-only (internal tool — light mode doubles QA surface). - Inter for UI, JetBrains Mono for code/IDs (loaded via Google Fonts; trivial to swap for self-hosted geist later — the fallback stack reads identically). - Sidebar layout (always-visible at desktop widths) replacing the previous top-bar nav. Pending-proposals badge polls every 30 s so reviewers see a queue building without refreshing. - Lucide icons throughout. - Spacing and radii on Tailwind defaults. Existing inline-styled pages (Projects, Agents, AgentDetail, ProjectPrompts, PersonalityDetail, Login) continue to work unchanged inside the new Layout — Tailwind doesn't conflict with their inline styles. A follow-up can migrate them incrementally. ## What's added ### Build infra (src/web/) - package.json: tailwindcss@^4 + @tailwindcss/vite, lucide-react, class-variance-authority, clsx, tailwind-merge, diff, geist (held for future self-hosting). - vite.config.ts: registers the @tailwindcss/vite plugin. - src/index.css: Tailwind import + @theme tokens + @layer base. - src/main.tsx: imports index.css. - src/lib/utils.ts: shadcn-style cn() helper. ### shadcn-style primitives (src/components/ui/) Hand-written rather than generated via `npx shadcn` so the repo doesn't depend on a CLI tool that needs interactive runtime: - button.tsx — variants: primary / secondary / ghost / danger / link; sizes: sm / md / lg / icon. - card.tsx — Card + Header/Title/Description/Content/Footer subparts. - badge.tsx — variants: default / info / success / warning / danger / outline. - input.tsx — Input + Textarea + Label. - tabs.tsx — no-dep accessible Tabs (no Radix needed for our use). - separator.tsx — h/v separator with role=separator. ### Diff component (src/components/Diff.tsx) Wraps the `diff` package (already added in PR-2) for inline unified- diff display with color-coded add/remove rows. Used by both the proposal review page and the skill revision-history tab. ### New pages (src/pages/) - Dashboard.tsx — at-a-glance home. Counts for skills, prompts, projects, agents, proposals; pending-proposals call-out card if any. - Skills.tsx — list view, separated into Global vs Project/Agent- scoped sections. - SkillDetail.tsx — name + semver + description; tabs for SKILL.md / Files / Metadata / History. History tab shows revisions with click-to-diff against the live body. - Proposals.tsx — queue with Pending/Approved/Rejected tabs. Pending count is highlighted in amber. - ProposalDetail.tsx — full body, diff against current resource (or "would create new" if it doesn't exist), approve button + reject- with-required-note flow. ### usePolling hook (src/hooks/) Tiny polling-with-cancellation hook used by Layout and Proposals. ### Layout rewrite (src/components/Layout.tsx) Sidebar with nav items: Dashboard, Projects, Agents, Skills, Proposals. Lucide icons. Active-route highlighting via NavLink. Pending-proposals warning badge on the Proposals item. ### Routes (src/App.tsx) New routes: /dashboard, /skills, /skills/:name, /proposals, /proposals/:id. Default redirects to /dashboard. ### API types (src/api.ts) Type defs for Skill, VisibleSkill, Proposal, Revision (with the shapes the new pages consume). ## Tests Existing 7 web tests still pass (Login + api). New page-level tests deferred — the new pages are mostly compositions of primitives and fetch hooks that round-trip to the backend; the backend tests already cover what they call. PR-7 polish can add render-and-click tests if coverage drift surfaces. ## Verification - `pnpm --filter @mcpctl/web build` clean, no warnings. - `pnpm test:run` whole monorepo: 162 test files / 2157 tests green. - Visual smoke deferred — needs a running mcpd to populate the fixtures. Manual smoke tested locally is the next step. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:54:55 +01:00
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
'@testing-library/dom@10.4.1':
dependencies:
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
'@babel/code-frame': 7.29.7
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
'@babel/runtime': 7.29.2
'@types/aria-query': 5.0.4
aria-query: 5.3.0
dom-accessibility-api: 0.5.16
lz-string: 1.5.0
picocolors: 1.1.1
pretty-format: 27.5.1
'@testing-library/jest-dom@6.9.1':
dependencies:
'@adobe/css-tools': 4.4.4
aria-query: 5.3.2
css.escape: 1.5.1
dom-accessibility-api: 0.6.3
picocolors: 1.1.1
redent: 3.0.0
'@testing-library/react@16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)':
dependencies:
'@babel/runtime': 7.29.2
'@testing-library/dom': 10.4.1
react: 19.2.5
react-dom: 19.2.5(react@19.2.5)
optionalDependencies:
'@types/react': 19.2.14
'@types/react-dom': 19.2.3(@types/react@19.2.14)
'@tufjs/canonical-json@2.0.0': {}
'@tufjs/models@4.1.0':
dependencies:
'@tufjs/canonical-json': 2.0.0
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
minimatch: 10.2.5
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
'@types/aria-query@5.0.4': {}
'@types/babel__core@7.20.5':
dependencies:
'@babel/parser': 7.29.0
'@babel/types': 7.29.0
'@types/babel__generator': 7.27.0
'@types/babel__template': 7.4.4
'@types/babel__traverse': 7.28.0
'@types/babel__generator@7.27.0':
dependencies:
'@babel/types': 7.29.0
'@types/babel__template@7.4.4':
dependencies:
'@babel/parser': 7.29.0
'@babel/types': 7.29.0
'@types/babel__traverse@7.28.0':
dependencies:
'@babel/types': 7.29.0
'@types/bcrypt@5.0.2':
dependencies:
'@types/node': 25.3.0
2026-02-21 03:10:39 +00:00
'@types/chai@5.2.3':
dependencies:
'@types/deep-eql': 4.0.2
assertion-error: 2.0.1
'@types/deep-eql@4.0.2': {}
feat(mcpd): ResourceRevision + ResourceProposal services + Prompt revision integration Phase 2 of the Skills + Revisions + Proposals work. Stands up the generic revision/proposal layer and wires Prompt into it. Skills will plug into the same infrastructure in PR-3 with no further service changes required. This PR is intentionally additive: PromptRequest table and routes are unchanged. The /api/v1/proposals API runs side-by-side with the legacy /api/v1/promptrequests API. The PromptRequest cutover (rename + backfill + mcplocal rewire) is deferred to a later PR so this one stays reviewable. ## What's added ### Repositories (src/mcpd/src/repositories/) - resource-revision.repository.ts — append-only revision log keyed by (resourceType, resourceId). Soft FK; no relations declared. Supports history listing, semver lookup, and contentHash cross-resource search. - resource-proposal.repository.ts — generic propose queue. Status lifecycle pending → approved | rejected. Mirrors Prompt's `?? ''` workaround for nullable-FK compound lookups. ### Services (src/mcpd/src/services/) - resource-revision.service.ts — record() inserts a revision with a stable sha256 contentHash computed from canonicalised JSON (key-sorted at every level so reordered objects produce the same hash). Caller passes a pre-computed semver; service does NOT decide bump policy. - resource-proposal.service.ts — propose / approve / reject / list, with a per-resourceType handler registry. PromptService registers the 'prompt' handler at construction; the SkillService will register 'skill' in PR-3. approve() runs in a Prisma $transaction so the resource update + revision insert + proposal status flip are atomic. ### Pure utility (src/mcpd/src/utils/semver.ts) - bumpSemver(current, kind) for major / minor / patch - compareSemver(a, b) — numeric, not lex (10 > 9) - isValidSemver(s) - Invalid input falls back to '0.1.0' rather than throwing — keeps the audit-write path from blowing up the prompt update if a row's semver ever drifts out of MAJOR.MINOR.PATCH shape. ### Routes (src/mcpd/src/routes/) - revisions.ts — GET /api/v1/revisions?resourceType=&resourceId=, GET /api/v1/revisions/:id, GET /api/v1/revisions/:id/diff?against=<id|live> (unified-format diff via the `diff` package), and POST /api/v1/prompts/:id/restore-revision { revisionId, note? }. - proposals.ts — GET / POST /api/v1/proposals, GET /api/v1/proposals/:id, PUT for body updates, POST .../approve and POST .../reject, plus DELETE. ## What's changed - PromptService.create / update now record a ResourceRevision when the revision service is wired. Update auto-bumps patch on content change; authors can override via `--bump major|minor|patch` or `--semver X.Y.Z` on the CLI (forwarded into the PUT body). Best-effort: revision write failures are swallowed so the prompt save still succeeds (revision is audit, not source of truth). - PromptService.setProposalService registers a 'prompt' approval handler with the proposal service. Approval runs in a Prisma transaction: upsert prompt → record revision → update currentRevisionId → flip proposal status. semver bumps to 0.1.0 on first approval, patch thereafter. - New CLI flags on `mcpctl edit prompt`: --bump, --semver, --note. They're prompt-only (validated client-side); other resources reject them. - Aliases in shared.ts: `proposal`/`prop` → proposals, `revision`/`rev` → revisions. - diff dependency added to mcpd. ## Tests - src/mcpd/tests/utils/semver.test.ts — covers bump/compare/validate including numeric (not lex) semver compare and invalid-input fallback. - prompt-service.test.ts updated: makePrompt fixture now sets semver + agentId + currentRevisionId; updatePrompt assertion expects the auto-bumped patch in the same update call. - prompt-routes.test.ts updated symmetrically. ## RBAC `proposals` and `revisions` URL segments map to the existing `prompts` permission for now. PR-7 may split if a "reviewer" role becomes useful. ## Verification Full suite: 158 test files / 2127 tests green. `pnpm build` clean across all 6 workspace packages. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 00:38:35 +01:00
'@types/diff@5.2.3': {}
'@types/diff@8.0.0':
dependencies:
diff: 8.0.3
'@types/docker-modem@3.0.6':
dependencies:
'@types/node': 25.3.0
'@types/ssh2': 1.15.5
'@types/dockerode@4.0.1':
dependencies:
'@types/docker-modem': 3.0.6
'@types/node': 25.3.0
'@types/ssh2': 1.15.5
2026-02-21 03:10:39 +00:00
'@types/esrecurse@4.3.1': {}
'@types/estree@1.0.8': {}
'@types/google-protobuf@3.15.12': {}
'@types/js-yaml@4.0.9': {}
2026-02-21 03:10:39 +00:00
'@types/json-schema@7.0.15': {}
'@types/node-fetch@2.6.13':
dependencies:
'@types/node': 25.3.0
form-data: 4.0.5
'@types/node@18.19.130':
dependencies:
undici-types: 5.26.5
'@types/node@24.12.2':
dependencies:
undici-types: 7.16.0
'@types/node@25.3.0':
dependencies:
undici-types: 7.18.2
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
'@types/react-dom@19.2.3(@types/react@19.2.14)':
dependencies:
'@types/react': 19.2.14
'@types/react@19.2.14':
dependencies:
csstype: 3.2.3
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
'@types/retry@0.12.0': {}
'@types/semver@7.7.1': {}
'@types/ssh2@1.15.5':
dependencies:
'@types/node': 18.19.130
'@types/stream-buffers@3.0.8':
dependencies:
'@types/node': 25.3.0
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
'@types/trusted-types@2.0.7':
optional: true
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
'@typescript-eslint/eslint-plugin@8.56.0(@typescript-eslint/parser@8.56.0(eslint@10.0.1(jiti@2.7.0))(typescript@5.9.3))(eslint@10.0.1(jiti@2.7.0))(typescript@5.9.3)':
2026-02-21 03:10:39 +00:00
dependencies:
'@eslint-community/regexpp': 4.12.2
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
'@typescript-eslint/parser': 8.56.0(eslint@10.0.1(jiti@2.7.0))(typescript@5.9.3)
2026-02-21 03:10:39 +00:00
'@typescript-eslint/scope-manager': 8.56.0
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
'@typescript-eslint/type-utils': 8.56.0(eslint@10.0.1(jiti@2.7.0))(typescript@5.9.3)
'@typescript-eslint/utils': 8.56.0(eslint@10.0.1(jiti@2.7.0))(typescript@5.9.3)
2026-02-21 03:10:39 +00:00
'@typescript-eslint/visitor-keys': 8.56.0
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
eslint: 10.0.1(jiti@2.7.0)
2026-02-21 03:10:39 +00:00
ignore: 7.0.5
natural-compare: 1.4.0
ts-api-utils: 2.4.0(typescript@5.9.3)
typescript: 5.9.3
transitivePeerDependencies:
- supports-color
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
'@typescript-eslint/parser@8.56.0(eslint@10.0.1(jiti@2.7.0))(typescript@5.9.3)':
2026-02-21 03:10:39 +00:00
dependencies:
'@typescript-eslint/scope-manager': 8.56.0
'@typescript-eslint/types': 8.56.0
'@typescript-eslint/typescript-estree': 8.56.0(typescript@5.9.3)
'@typescript-eslint/visitor-keys': 8.56.0
debug: 4.4.3
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
eslint: 10.0.1(jiti@2.7.0)
2026-02-21 03:10:39 +00:00
typescript: 5.9.3
transitivePeerDependencies:
- supports-color
'@typescript-eslint/project-service@8.56.0(typescript@5.9.3)':
dependencies:
'@typescript-eslint/tsconfig-utils': 8.56.0(typescript@5.9.3)
'@typescript-eslint/types': 8.56.0
debug: 4.4.3
typescript: 5.9.3
transitivePeerDependencies:
- supports-color
'@typescript-eslint/scope-manager@8.56.0':
dependencies:
'@typescript-eslint/types': 8.56.0
'@typescript-eslint/visitor-keys': 8.56.0
'@typescript-eslint/tsconfig-utils@8.56.0(typescript@5.9.3)':
dependencies:
typescript: 5.9.3
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
'@typescript-eslint/type-utils@8.56.0(eslint@10.0.1(jiti@2.7.0))(typescript@5.9.3)':
2026-02-21 03:10:39 +00:00
dependencies:
'@typescript-eslint/types': 8.56.0
'@typescript-eslint/typescript-estree': 8.56.0(typescript@5.9.3)
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
'@typescript-eslint/utils': 8.56.0(eslint@10.0.1(jiti@2.7.0))(typescript@5.9.3)
2026-02-21 03:10:39 +00:00
debug: 4.4.3
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
eslint: 10.0.1(jiti@2.7.0)
2026-02-21 03:10:39 +00:00
ts-api-utils: 2.4.0(typescript@5.9.3)
typescript: 5.9.3
transitivePeerDependencies:
- supports-color
'@typescript-eslint/types@8.56.0': {}
'@typescript-eslint/typescript-estree@8.56.0(typescript@5.9.3)':
dependencies:
'@typescript-eslint/project-service': 8.56.0(typescript@5.9.3)
'@typescript-eslint/tsconfig-utils': 8.56.0(typescript@5.9.3)
'@typescript-eslint/types': 8.56.0
'@typescript-eslint/visitor-keys': 8.56.0
debug: 4.4.3
minimatch: 9.0.5
semver: 7.7.4
tinyglobby: 0.2.15
ts-api-utils: 2.4.0(typescript@5.9.3)
typescript: 5.9.3
transitivePeerDependencies:
- supports-color
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
'@typescript-eslint/utils@8.56.0(eslint@10.0.1(jiti@2.7.0))(typescript@5.9.3)':
2026-02-21 03:10:39 +00:00
dependencies:
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
'@eslint-community/eslint-utils': 4.9.1(eslint@10.0.1(jiti@2.7.0))
2026-02-21 03:10:39 +00:00
'@typescript-eslint/scope-manager': 8.56.0
'@typescript-eslint/types': 8.56.0
'@typescript-eslint/typescript-estree': 8.56.0(typescript@5.9.3)
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
eslint: 10.0.1(jiti@2.7.0)
2026-02-21 03:10:39 +00:00
typescript: 5.9.3
transitivePeerDependencies:
- supports-color
'@typescript-eslint/visitor-keys@8.56.0':
dependencies:
'@typescript-eslint/types': 8.56.0
eslint-visitor-keys: 5.0.1
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
'@vitejs/plugin-react@5.2.0(vite@7.3.1(@types/node@25.3.0)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.21.0)(yaml@2.9.0))':
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
dependencies:
'@babel/core': 7.29.0
'@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.29.0)
'@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.29.0)
'@rolldown/pluginutils': 1.0.0-rc.3
'@types/babel__core': 7.20.5
react-refresh: 0.18.0
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
vite: 7.3.1(@types/node@25.3.0)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.21.0)(yaml@2.9.0)
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
transitivePeerDependencies:
- supports-color
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
'@vitest/coverage-v8@4.0.18(vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@25.3.0)(jiti@2.7.0)(jsdom@28.1.0)(lightningcss@1.32.0)(tsx@4.21.0)(yaml@2.9.0))':
2026-02-21 03:10:39 +00:00
dependencies:
'@bcoe/v8-coverage': 1.0.2
'@vitest/utils': 4.0.18
ast-v8-to-istanbul: 0.3.11
istanbul-lib-coverage: 3.2.2
istanbul-lib-report: 3.0.1
istanbul-reports: 3.2.0
magicast: 0.5.2
obug: 2.1.1
std-env: 3.10.0
tinyrainbow: 3.0.3
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
vitest: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@25.3.0)(jiti@2.7.0)(jsdom@28.1.0)(lightningcss@1.32.0)(tsx@4.21.0)(yaml@2.9.0)
2026-02-21 03:10:39 +00:00
'@vitest/expect@4.0.18':
dependencies:
'@standard-schema/spec': 1.1.0
'@types/chai': 5.2.3
'@vitest/spy': 4.0.18
'@vitest/utils': 4.0.18
chai: 6.2.2
tinyrainbow: 3.0.3
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
'@vitest/mocker@4.0.18(vite@7.3.1(@types/node@25.3.0)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.21.0)(yaml@2.9.0))':
2026-02-21 03:10:39 +00:00
dependencies:
'@vitest/spy': 4.0.18
estree-walker: 3.0.3
magic-string: 0.30.21
optionalDependencies:
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
vite: 7.3.1(@types/node@25.3.0)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.21.0)(yaml@2.9.0)
2026-02-21 03:10:39 +00:00
'@vitest/pretty-format@4.0.18':
dependencies:
tinyrainbow: 3.0.3
'@vitest/runner@4.0.18':
dependencies:
'@vitest/utils': 4.0.18
pathe: 2.0.3
'@vitest/snapshot@4.0.18':
dependencies:
'@vitest/pretty-format': 4.0.18
magic-string: 0.30.21
pathe: 2.0.3
'@vitest/spy@4.0.18': {}
'@vitest/utils@4.0.18':
dependencies:
'@vitest/pretty-format': 4.0.18
tinyrainbow: 3.0.3
abbrev@1.1.1: {}
abbrev@4.0.0: {}
2026-02-21 03:10:39 +00:00
abstract-logging@2.0.1: {}
accepts@2.0.0:
dependencies:
mime-types: 3.0.2
negotiator: 1.0.0
acorn-jsx@5.3.2(acorn@8.16.0):
dependencies:
acorn: 8.16.0
acorn@8.16.0: {}
agent-base@6.0.2:
dependencies:
debug: 4.4.3
transitivePeerDependencies:
- supports-color
agent-base@7.1.4: {}
2026-02-21 03:10:39 +00:00
ajv-formats@3.0.1(ajv@8.18.0):
optionalDependencies:
ajv: 8.18.0
ajv@6.14.0:
dependencies:
fast-deep-equal: 3.1.3
fast-json-stable-stringify: 2.1.0
json-schema-traverse: 0.4.1
uri-js: 4.4.1
ajv@8.18.0:
dependencies:
fast-deep-equal: 3.1.3
fast-uri: 3.1.0
json-schema-traverse: 1.0.0
require-from-string: 2.0.2
ansi-escapes@7.3.0:
dependencies:
environment: 1.1.0
2026-02-21 03:10:39 +00:00
ansi-regex@5.0.1: {}
ansi-regex@6.2.2: {}
2026-02-21 03:10:39 +00:00
ansi-styles@4.3.0:
dependencies:
color-convert: 2.0.1
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
ansi-styles@5.2.0: {}
ansi-styles@6.2.3: {}
aproba@2.1.0: {}
are-we-there-yet@2.0.0:
dependencies:
delegates: 1.0.0
readable-stream: 3.6.2
2026-02-21 03:10:39 +00:00
argparse@2.0.1: {}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
aria-query@5.3.0:
dependencies:
dequal: 2.0.3
aria-query@5.3.2: {}
asn1@0.2.6:
dependencies:
safer-buffer: 2.1.2
2026-02-21 03:10:39 +00:00
assertion-error@2.0.1: {}
ast-v8-to-istanbul@0.3.11:
dependencies:
'@jridgewell/trace-mapping': 0.3.31
estree-walker: 3.0.3
js-tokens: 10.0.0
asynckit@0.4.0: {}
2026-02-21 03:10:39 +00:00
atomic-sleep@1.0.0: {}
auto-bind@5.0.1: {}
2026-02-21 03:10:39 +00:00
avvio@9.2.0:
dependencies:
'@fastify/error': 4.2.0
fastq: 1.20.1
b4a@1.8.0: {}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
babel-plugin-jsx-dom-expressions@0.40.7(@babel/core@7.28.0):
dependencies:
'@babel/core': 7.28.0
'@babel/helper-module-imports': 7.18.6
'@babel/plugin-syntax-jsx': 7.29.7(@babel/core@7.28.0)
'@babel/types': 7.29.8
html-entities: 2.3.3
parse5: 7.3.0
babel-plugin-module-resolver@5.0.2:
dependencies:
find-babel-config: 2.1.2
glob: 9.3.5
pkg-up: 3.1.0
reselect: 4.1.8
resolve: 1.22.12
babel-preset-solid@1.9.12(@babel/core@7.28.0)(solid-js@1.9.12):
dependencies:
'@babel/core': 7.28.0
babel-plugin-jsx-dom-expressions: 0.40.7(@babel/core@7.28.0)
optionalDependencies:
solid-js: 1.9.12
2026-02-21 03:10:39 +00:00
balanced-match@1.0.2: {}
balanced-match@4.0.3: {}
bare-events@2.8.2: {}
bare-fs@4.6.0:
dependencies:
bare-events: 2.8.2
bare-path: 3.0.0
bare-stream: 2.12.0(bare-events@2.8.2)
bare-url: 2.4.0
fast-fifo: 1.3.2
transitivePeerDependencies:
- bare-abort-controller
- react-native-b4a
bare-os@3.8.7: {}
bare-path@3.0.0:
dependencies:
bare-os: 3.8.7
bare-stream@2.12.0(bare-events@2.8.2):
dependencies:
streamx: 2.25.0
teex: 1.0.1
optionalDependencies:
bare-events: 2.8.2
transitivePeerDependencies:
- react-native-b4a
bare-url@2.4.0:
dependencies:
bare-path: 3.0.0
base64-js@1.5.1: {}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
baseline-browser-mapping@2.10.23: {}
bcrypt-pbkdf@1.0.2:
dependencies:
tweetnacl: 0.14.5
bcrypt@5.1.1:
dependencies:
'@mapbox/node-pre-gyp': 1.0.11
node-addon-api: 5.1.0
transitivePeerDependencies:
- encoding
- supports-color
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
bidi-js@1.0.3:
dependencies:
require-from-string: 2.0.2
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
bignumber.js@9.3.1: {}
bin-links@6.0.2:
dependencies:
cmd-shim: 8.0.0
npm-normalize-package-bin: 5.0.0
proc-log: 6.1.0
read-cmd-shim: 6.0.0
write-file-atomic: 7.0.1
bl@4.1.0:
dependencies:
buffer: 5.7.1
inherits: 2.0.4
readable-stream: 3.6.2
2026-02-21 03:10:39 +00:00
body-parser@2.2.2:
dependencies:
bytes: 3.1.2
content-type: 1.0.5
debug: 4.4.3
http-errors: 2.0.1
iconv-lite: 0.7.2
on-finished: 2.4.1
qs: 6.15.0
raw-body: 3.0.2
type-is: 2.0.1
transitivePeerDependencies:
- supports-color
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
bowser@2.14.1: {}
brace-expansion@1.1.12:
dependencies:
balanced-match: 1.0.2
concat-map: 0.0.1
2026-02-21 03:10:39 +00:00
brace-expansion@2.0.2:
dependencies:
balanced-match: 1.0.2
brace-expansion@5.0.2:
dependencies:
balanced-match: 4.0.3
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
brace-expansion@5.0.9:
dependencies:
balanced-match: 4.0.3
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
browserslist@4.28.2:
dependencies:
baseline-browser-mapping: 2.10.23
caniuse-lite: 1.0.30001791
electron-to-chromium: 1.5.344
node-releases: 2.0.38
update-browserslist-db: 1.2.3(browserslist@4.28.2)
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
buffer-equal-constant-time@1.0.1: {}
buffer-from@1.1.2: {}
buffer@5.7.1:
dependencies:
base64-js: 1.5.1
ieee754: 1.2.1
buildcheck@0.0.7:
optional: true
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
bun-ffi-structs@0.2.4(typescript@5.9.3):
dependencies:
typescript: 5.9.3
2026-02-21 03:10:39 +00:00
bytes@3.1.2: {}
c12@3.1.0:
dependencies:
chokidar: 4.0.3
confbox: 0.2.4
defu: 6.1.4
dotenv: 16.6.1
exsolve: 1.0.8
giget: 2.0.0
jiti: 2.6.1
ohash: 2.0.11
pathe: 2.0.3
perfect-debounce: 1.0.0
pkg-types: 2.3.0
rc9: 2.1.2
cacache@20.0.4:
dependencies:
'@npmcli/fs': 5.0.0
fs-minipass: 3.0.3
glob: 13.0.6
lru-cache: 11.2.6
minipass: 7.1.3
minipass-collect: 2.0.1
minipass-flush: 1.0.7
minipass-pipeline: 1.2.4
p-map: 7.0.5
ssri: 13.0.1
2026-02-21 03:10:39 +00:00
call-bind-apply-helpers@1.0.2:
dependencies:
es-errors: 1.3.0
function-bind: 1.1.2
call-bound@1.0.4:
dependencies:
call-bind-apply-helpers: 1.0.2
get-intrinsic: 1.3.0
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
caniuse-lite@1.0.30001791: {}
2026-02-21 03:10:39 +00:00
chai@6.2.2: {}
chalk@5.6.2: {}
chardet@2.1.1: {}
chokidar@4.0.3:
dependencies:
readdirp: 4.1.2
chownr@1.1.4: {}
chownr@2.0.0: {}
chownr@3.0.0: {}
2026-02-21 03:10:39 +00:00
citty@0.1.6:
dependencies:
consola: 3.4.2
citty@0.2.1: {}
cjs-module-lexer@2.2.0: {}
feat(web): bold redesign — Tailwind v4 + shadcn-style primitives + Skills/Proposals/Revisions UI Phase 6 of the Skills + Revisions + Proposals work. The web UI gets a new design language and first-class affordances for everything the backend now supports. ## Visual direction - Tailwind v4 with custom @theme block (oklch tokens). Dark-mode-only (internal tool — light mode doubles QA surface). - Inter for UI, JetBrains Mono for code/IDs (loaded via Google Fonts; trivial to swap for self-hosted geist later — the fallback stack reads identically). - Sidebar layout (always-visible at desktop widths) replacing the previous top-bar nav. Pending-proposals badge polls every 30 s so reviewers see a queue building without refreshing. - Lucide icons throughout. - Spacing and radii on Tailwind defaults. Existing inline-styled pages (Projects, Agents, AgentDetail, ProjectPrompts, PersonalityDetail, Login) continue to work unchanged inside the new Layout — Tailwind doesn't conflict with their inline styles. A follow-up can migrate them incrementally. ## What's added ### Build infra (src/web/) - package.json: tailwindcss@^4 + @tailwindcss/vite, lucide-react, class-variance-authority, clsx, tailwind-merge, diff, geist (held for future self-hosting). - vite.config.ts: registers the @tailwindcss/vite plugin. - src/index.css: Tailwind import + @theme tokens + @layer base. - src/main.tsx: imports index.css. - src/lib/utils.ts: shadcn-style cn() helper. ### shadcn-style primitives (src/components/ui/) Hand-written rather than generated via `npx shadcn` so the repo doesn't depend on a CLI tool that needs interactive runtime: - button.tsx — variants: primary / secondary / ghost / danger / link; sizes: sm / md / lg / icon. - card.tsx — Card + Header/Title/Description/Content/Footer subparts. - badge.tsx — variants: default / info / success / warning / danger / outline. - input.tsx — Input + Textarea + Label. - tabs.tsx — no-dep accessible Tabs (no Radix needed for our use). - separator.tsx — h/v separator with role=separator. ### Diff component (src/components/Diff.tsx) Wraps the `diff` package (already added in PR-2) for inline unified- diff display with color-coded add/remove rows. Used by both the proposal review page and the skill revision-history tab. ### New pages (src/pages/) - Dashboard.tsx — at-a-glance home. Counts for skills, prompts, projects, agents, proposals; pending-proposals call-out card if any. - Skills.tsx — list view, separated into Global vs Project/Agent- scoped sections. - SkillDetail.tsx — name + semver + description; tabs for SKILL.md / Files / Metadata / History. History tab shows revisions with click-to-diff against the live body. - Proposals.tsx — queue with Pending/Approved/Rejected tabs. Pending count is highlighted in amber. - ProposalDetail.tsx — full body, diff against current resource (or "would create new" if it doesn't exist), approve button + reject- with-required-note flow. ### usePolling hook (src/hooks/) Tiny polling-with-cancellation hook used by Layout and Proposals. ### Layout rewrite (src/components/Layout.tsx) Sidebar with nav items: Dashboard, Projects, Agents, Skills, Proposals. Lucide icons. Active-route highlighting via NavLink. Pending-proposals warning badge on the Proposals item. ### Routes (src/App.tsx) New routes: /dashboard, /skills, /skills/:name, /proposals, /proposals/:id. Default redirects to /dashboard. ### API types (src/api.ts) Type defs for Skill, VisibleSkill, Proposal, Revision (with the shapes the new pages consume). ## Tests Existing 7 web tests still pass (Login + api). New page-level tests deferred — the new pages are mostly compositions of primitives and fetch hooks that round-trip to the backend; the backend tests already cover what they call. PR-7 polish can add render-and-click tests if coverage drift surfaces. ## Verification - `pnpm --filter @mcpctl/web build` clean, no warnings. - `pnpm test:run` whole monorepo: 162 test files / 2157 tests green. - Visual smoke deferred — needs a running mcpd to populate the fixtures. Manual smoke tested locally is the next step. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:54:55 +01:00
class-variance-authority@0.7.1:
dependencies:
clsx: 2.1.1
cli-boxes@3.0.0: {}
cli-cursor@4.0.0:
dependencies:
restore-cursor: 4.0.0
cli-spinners@3.4.0: {}
cli-truncate@5.1.1:
dependencies:
slice-ansi: 7.1.2
string-width: 8.2.0
2026-02-21 03:10:39 +00:00
cli-width@4.1.0: {}
feat(web): bold redesign — Tailwind v4 + shadcn-style primitives + Skills/Proposals/Revisions UI Phase 6 of the Skills + Revisions + Proposals work. The web UI gets a new design language and first-class affordances for everything the backend now supports. ## Visual direction - Tailwind v4 with custom @theme block (oklch tokens). Dark-mode-only (internal tool — light mode doubles QA surface). - Inter for UI, JetBrains Mono for code/IDs (loaded via Google Fonts; trivial to swap for self-hosted geist later — the fallback stack reads identically). - Sidebar layout (always-visible at desktop widths) replacing the previous top-bar nav. Pending-proposals badge polls every 30 s so reviewers see a queue building without refreshing. - Lucide icons throughout. - Spacing and radii on Tailwind defaults. Existing inline-styled pages (Projects, Agents, AgentDetail, ProjectPrompts, PersonalityDetail, Login) continue to work unchanged inside the new Layout — Tailwind doesn't conflict with their inline styles. A follow-up can migrate them incrementally. ## What's added ### Build infra (src/web/) - package.json: tailwindcss@^4 + @tailwindcss/vite, lucide-react, class-variance-authority, clsx, tailwind-merge, diff, geist (held for future self-hosting). - vite.config.ts: registers the @tailwindcss/vite plugin. - src/index.css: Tailwind import + @theme tokens + @layer base. - src/main.tsx: imports index.css. - src/lib/utils.ts: shadcn-style cn() helper. ### shadcn-style primitives (src/components/ui/) Hand-written rather than generated via `npx shadcn` so the repo doesn't depend on a CLI tool that needs interactive runtime: - button.tsx — variants: primary / secondary / ghost / danger / link; sizes: sm / md / lg / icon. - card.tsx — Card + Header/Title/Description/Content/Footer subparts. - badge.tsx — variants: default / info / success / warning / danger / outline. - input.tsx — Input + Textarea + Label. - tabs.tsx — no-dep accessible Tabs (no Radix needed for our use). - separator.tsx — h/v separator with role=separator. ### Diff component (src/components/Diff.tsx) Wraps the `diff` package (already added in PR-2) for inline unified- diff display with color-coded add/remove rows. Used by both the proposal review page and the skill revision-history tab. ### New pages (src/pages/) - Dashboard.tsx — at-a-glance home. Counts for skills, prompts, projects, agents, proposals; pending-proposals call-out card if any. - Skills.tsx — list view, separated into Global vs Project/Agent- scoped sections. - SkillDetail.tsx — name + semver + description; tabs for SKILL.md / Files / Metadata / History. History tab shows revisions with click-to-diff against the live body. - Proposals.tsx — queue with Pending/Approved/Rejected tabs. Pending count is highlighted in amber. - ProposalDetail.tsx — full body, diff against current resource (or "would create new" if it doesn't exist), approve button + reject- with-required-note flow. ### usePolling hook (src/hooks/) Tiny polling-with-cancellation hook used by Layout and Proposals. ### Layout rewrite (src/components/Layout.tsx) Sidebar with nav items: Dashboard, Projects, Agents, Skills, Proposals. Lucide icons. Active-route highlighting via NavLink. Pending-proposals warning badge on the Proposals item. ### Routes (src/App.tsx) New routes: /dashboard, /skills, /skills/:name, /proposals, /proposals/:id. Default redirects to /dashboard. ### API types (src/api.ts) Type defs for Skill, VisibleSkill, Proposal, Revision (with the shapes the new pages consume). ## Tests Existing 7 web tests still pass (Login + api). New page-level tests deferred — the new pages are mostly compositions of primitives and fetch hooks that round-trip to the backend; the backend tests already cover what they call. PR-7 polish can add render-and-click tests if coverage drift surfaces. ## Verification - `pnpm --filter @mcpctl/web build` clean, no warnings. - `pnpm test:run` whole monorepo: 162 test files / 2157 tests green. - Visual smoke deferred — needs a running mcpd to populate the fixtures. Manual smoke tested locally is the next step. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:54:55 +01:00
client-only@0.0.1: {}
cliui@8.0.1:
dependencies:
string-width: 4.2.3
strip-ansi: 6.0.1
wrap-ansi: 7.0.0
feat(web): bold redesign — Tailwind v4 + shadcn-style primitives + Skills/Proposals/Revisions UI Phase 6 of the Skills + Revisions + Proposals work. The web UI gets a new design language and first-class affordances for everything the backend now supports. ## Visual direction - Tailwind v4 with custom @theme block (oklch tokens). Dark-mode-only (internal tool — light mode doubles QA surface). - Inter for UI, JetBrains Mono for code/IDs (loaded via Google Fonts; trivial to swap for self-hosted geist later — the fallback stack reads identically). - Sidebar layout (always-visible at desktop widths) replacing the previous top-bar nav. Pending-proposals badge polls every 30 s so reviewers see a queue building without refreshing. - Lucide icons throughout. - Spacing and radii on Tailwind defaults. Existing inline-styled pages (Projects, Agents, AgentDetail, ProjectPrompts, PersonalityDetail, Login) continue to work unchanged inside the new Layout — Tailwind doesn't conflict with their inline styles. A follow-up can migrate them incrementally. ## What's added ### Build infra (src/web/) - package.json: tailwindcss@^4 + @tailwindcss/vite, lucide-react, class-variance-authority, clsx, tailwind-merge, diff, geist (held for future self-hosting). - vite.config.ts: registers the @tailwindcss/vite plugin. - src/index.css: Tailwind import + @theme tokens + @layer base. - src/main.tsx: imports index.css. - src/lib/utils.ts: shadcn-style cn() helper. ### shadcn-style primitives (src/components/ui/) Hand-written rather than generated via `npx shadcn` so the repo doesn't depend on a CLI tool that needs interactive runtime: - button.tsx — variants: primary / secondary / ghost / danger / link; sizes: sm / md / lg / icon. - card.tsx — Card + Header/Title/Description/Content/Footer subparts. - badge.tsx — variants: default / info / success / warning / danger / outline. - input.tsx — Input + Textarea + Label. - tabs.tsx — no-dep accessible Tabs (no Radix needed for our use). - separator.tsx — h/v separator with role=separator. ### Diff component (src/components/Diff.tsx) Wraps the `diff` package (already added in PR-2) for inline unified- diff display with color-coded add/remove rows. Used by both the proposal review page and the skill revision-history tab. ### New pages (src/pages/) - Dashboard.tsx — at-a-glance home. Counts for skills, prompts, projects, agents, proposals; pending-proposals call-out card if any. - Skills.tsx — list view, separated into Global vs Project/Agent- scoped sections. - SkillDetail.tsx — name + semver + description; tabs for SKILL.md / Files / Metadata / History. History tab shows revisions with click-to-diff against the live body. - Proposals.tsx — queue with Pending/Approved/Rejected tabs. Pending count is highlighted in amber. - ProposalDetail.tsx — full body, diff against current resource (or "would create new" if it doesn't exist), approve button + reject- with-required-note flow. ### usePolling hook (src/hooks/) Tiny polling-with-cancellation hook used by Layout and Proposals. ### Layout rewrite (src/components/Layout.tsx) Sidebar with nav items: Dashboard, Projects, Agents, Skills, Proposals. Lucide icons. Active-route highlighting via NavLink. Pending-proposals warning badge on the Proposals item. ### Routes (src/App.tsx) New routes: /dashboard, /skills, /skills/:name, /proposals, /proposals/:id. Default redirects to /dashboard. ### API types (src/api.ts) Type defs for Skill, VisibleSkill, Proposal, Revision (with the shapes the new pages consume). ## Tests Existing 7 web tests still pass (Login + api). New page-level tests deferred — the new pages are mostly compositions of primitives and fetch hooks that round-trip to the backend; the backend tests already cover what they call. PR-7 polish can add render-and-click tests if coverage drift surfaces. ## Verification - `pnpm --filter @mcpctl/web build` clean, no warnings. - `pnpm test:run` whole monorepo: 162 test files / 2157 tests green. - Visual smoke deferred — needs a running mcpd to populate the fixtures. Manual smoke tested locally is the next step. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:54:55 +01:00
clsx@2.1.1: {}
cmd-shim@8.0.0: {}
code-excerpt@4.0.0:
dependencies:
convert-to-spaces: 2.0.1
2026-02-21 03:10:39 +00:00
color-convert@2.0.1:
dependencies:
color-name: 1.1.4
color-name@1.1.4: {}
color-support@1.1.3: {}
combined-stream@1.0.8:
dependencies:
delayed-stream: 1.0.0
2026-02-21 03:10:39 +00:00
commander@13.1.0: {}
common-ancestor-path@2.0.0: {}
concat-map@0.0.1: {}
2026-02-21 03:10:39 +00:00
confbox@0.2.4: {}
consola@3.4.2: {}
console-control-strings@1.1.0: {}
feat(mcpd+deploy): serve web UI at /ui + smoke tests + docs (Stage 6) The closing stage. mcpd now hosts the Stage 5 SPA, the Docker image bundles the build artifact, a smoke test exercises the personality HTTP surface end-to-end, and the user-facing docs spell out the mental model. mcpd: - Add @fastify/static dep. - New routes/web-ui.ts: registers /ui/* against a static bundle. Looks for the bundle at $MCPD_WEB_ROOT, then /usr/share/mcpd/web (the Docker image path), then a dev-tree fallback. Logs and skips cleanly if missing — API-only deploys keep working. - SPA fallback: any /ui/<path> that doesn't match a file falls through to index.html so direct hits to react-router URLs work. - /ui/* falls through to `kind: skip` in mapUrlToPermission, so the static assets are served unauthenticated. Each API call from the SPA still carries the bearer token. Deploy: - Dockerfile.mcpd builds the @mcpctl/web bundle in the same builder stage and copies dist/ to /usr/share/mcpd/web in the runtime image. Smoke (personality.smoke.test.ts): - Live mcpd flow: create secret/llm/agent/personality, attach an agent-direct prompt, verify the binding listing, reject double- attach (409) + foreign-agent prompt (400), set defaultPersonality by name, detach + delete cleanup. Docs: - New docs/personalities.md: VLAN-on-ethernet model, system-block ordering table, three prompt scopes, CLI walkthrough, web UI walkthrough, full API surface, RBAC notes. - agents.md and chat.md cross-link. - README's Agents section gains a Personalities subsection. Test count after Stage 6: mcpd: 801/801 cli: 430/430 web: 7/7 db: 58/62 (4 pre-existing) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:48:43 +01:00
content-disposition@0.5.4:
dependencies:
safe-buffer: 5.2.1
2026-02-21 03:10:39 +00:00
content-disposition@1.0.1: {}
content-type@1.0.5: {}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
convert-source-map@2.0.0: {}
convert-to-spaces@2.0.1: {}
2026-02-21 03:10:39 +00:00
cookie-signature@1.2.2: {}
cookie@0.7.2: {}
cookie@1.1.1: {}
cors@2.8.6:
dependencies:
object-assign: 4.1.1
vary: 1.1.2
cpu-features@0.0.10:
dependencies:
buildcheck: 0.0.7
nan: 2.25.0
optional: true
2026-02-21 03:10:39 +00:00
cross-spawn@7.0.6:
dependencies:
path-key: 3.1.1
shebang-command: 2.0.0
which: 2.0.2
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
css-tree@3.2.1:
dependencies:
mdn-data: 2.27.1
source-map-js: 1.2.1
css.escape@1.5.1: {}
cssesc@3.0.0: {}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
cssstyle@6.2.0:
dependencies:
'@asamuzakjp/css-color': 5.1.11
'@csstools/css-syntax-patches-for-csstree': 1.1.3(css-tree@3.2.1)
css-tree: 3.2.1
lru-cache: 11.2.6
csstype@3.2.3: {}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
data-uri-to-buffer@4.0.1: {}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
data-urls@7.0.0:
dependencies:
whatwg-mimetype: 5.0.0
whatwg-url: 16.0.1
transitivePeerDependencies:
- '@noble/hashes'
2026-02-21 03:10:39 +00:00
debug@4.4.3:
dependencies:
ms: 2.1.3
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
decimal.js@10.6.0: {}
2026-02-21 03:10:39 +00:00
deep-is@0.1.4: {}
deepmerge-ts@7.1.5: {}
deepmerge@4.3.1: {}
2026-02-21 03:10:39 +00:00
defu@6.1.4: {}
delayed-stream@1.0.0: {}
delegates@1.0.0: {}
2026-02-21 03:10:39 +00:00
depd@2.0.0: {}
dequal@2.0.3: {}
destr@2.0.5: {}
detect-libc@2.1.2: {}
feat(mcpd): ResourceRevision + ResourceProposal services + Prompt revision integration Phase 2 of the Skills + Revisions + Proposals work. Stands up the generic revision/proposal layer and wires Prompt into it. Skills will plug into the same infrastructure in PR-3 with no further service changes required. This PR is intentionally additive: PromptRequest table and routes are unchanged. The /api/v1/proposals API runs side-by-side with the legacy /api/v1/promptrequests API. The PromptRequest cutover (rename + backfill + mcplocal rewire) is deferred to a later PR so this one stays reviewable. ## What's added ### Repositories (src/mcpd/src/repositories/) - resource-revision.repository.ts — append-only revision log keyed by (resourceType, resourceId). Soft FK; no relations declared. Supports history listing, semver lookup, and contentHash cross-resource search. - resource-proposal.repository.ts — generic propose queue. Status lifecycle pending → approved | rejected. Mirrors Prompt's `?? ''` workaround for nullable-FK compound lookups. ### Services (src/mcpd/src/services/) - resource-revision.service.ts — record() inserts a revision with a stable sha256 contentHash computed from canonicalised JSON (key-sorted at every level so reordered objects produce the same hash). Caller passes a pre-computed semver; service does NOT decide bump policy. - resource-proposal.service.ts — propose / approve / reject / list, with a per-resourceType handler registry. PromptService registers the 'prompt' handler at construction; the SkillService will register 'skill' in PR-3. approve() runs in a Prisma $transaction so the resource update + revision insert + proposal status flip are atomic. ### Pure utility (src/mcpd/src/utils/semver.ts) - bumpSemver(current, kind) for major / minor / patch - compareSemver(a, b) — numeric, not lex (10 > 9) - isValidSemver(s) - Invalid input falls back to '0.1.0' rather than throwing — keeps the audit-write path from blowing up the prompt update if a row's semver ever drifts out of MAJOR.MINOR.PATCH shape. ### Routes (src/mcpd/src/routes/) - revisions.ts — GET /api/v1/revisions?resourceType=&resourceId=, GET /api/v1/revisions/:id, GET /api/v1/revisions/:id/diff?against=<id|live> (unified-format diff via the `diff` package), and POST /api/v1/prompts/:id/restore-revision { revisionId, note? }. - proposals.ts — GET / POST /api/v1/proposals, GET /api/v1/proposals/:id, PUT for body updates, POST .../approve and POST .../reject, plus DELETE. ## What's changed - PromptService.create / update now record a ResourceRevision when the revision service is wired. Update auto-bumps patch on content change; authors can override via `--bump major|minor|patch` or `--semver X.Y.Z` on the CLI (forwarded into the PUT body). Best-effort: revision write failures are swallowed so the prompt save still succeeds (revision is audit, not source of truth). - PromptService.setProposalService registers a 'prompt' approval handler with the proposal service. Approval runs in a Prisma transaction: upsert prompt → record revision → update currentRevisionId → flip proposal status. semver bumps to 0.1.0 on first approval, patch thereafter. - New CLI flags on `mcpctl edit prompt`: --bump, --semver, --note. They're prompt-only (validated client-side); other resources reject them. - Aliases in shared.ts: `proposal`/`prop` → proposals, `revision`/`rev` → revisions. - diff dependency added to mcpd. ## Tests - src/mcpd/tests/utils/semver.test.ts — covers bump/compare/validate including numeric (not lex) semver compare and invalid-input fallback. - prompt-service.test.ts updated: makePrompt fixture now sets semver + agentId + currentRevisionId; updatePrompt assertion expects the auto-bumped patch in the same update call. - prompt-routes.test.ts updated symmetrically. ## RBAC `proposals` and `revisions` URL segments map to the existing `prompts` permission for now. PR-7 may split if a "reviewer" role becomes useful. ## Verification Full suite: 158 test files / 2127 tests green. `pnpm build` clean across all 6 workspace packages. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 00:38:35 +01:00
diff@5.2.2: {}
diff@8.0.3: {}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
diff@8.0.4: {}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
diff@9.0.0: {}
docker-modem@5.0.6:
dependencies:
debug: 4.4.3
readable-stream: 3.6.2
split-ca: 1.0.1
ssh2: 1.17.0
transitivePeerDependencies:
- supports-color
dockerode@4.0.9:
dependencies:
'@balena/dockerignore': 1.0.2
'@grpc/grpc-js': 1.14.3
'@grpc/proto-loader': 0.7.15
docker-modem: 5.0.6
protobufjs: 7.5.4
tar-fs: 2.1.4
uuid: 10.0.0
transitivePeerDependencies:
- supports-color
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
dom-accessibility-api@0.5.16: {}
dom-accessibility-api@0.6.3: {}
dompurify@3.2.7:
optionalDependencies:
'@types/trusted-types': 2.0.7
2026-02-21 03:10:39 +00:00
dotenv@16.6.1: {}
dunder-proto@1.0.1:
dependencies:
call-bind-apply-helpers: 1.0.2
es-errors: 1.3.0
gopd: 1.2.0
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
ecdsa-sig-formatter@1.0.11:
dependencies:
safe-buffer: 5.2.1
2026-02-21 03:10:39 +00:00
ee-first@1.1.1: {}
effect@3.18.4:
dependencies:
'@standard-schema/spec': 1.1.0
fast-check: 3.23.2
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
effect@4.0.0-beta.83:
dependencies:
'@standard-schema/spec': 1.1.0
fast-check: 4.9.0
find-my-way-ts: 0.1.6
ini: 7.0.0
kubernetes-types: 1.30.0
msgpackr: 2.0.5
multipasta: 0.2.8
toml: 4.3.0
uuid: 14.0.1
yaml: 2.9.0
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
electron-to-chromium@1.5.344: {}
emoji-regex@10.6.0: {}
2026-02-21 03:10:39 +00:00
emoji-regex@8.0.0: {}
empathic@2.0.0: {}
encodeurl@2.0.0: {}
end-of-stream@1.4.5:
dependencies:
once: 1.4.0
feat(web): bold redesign — Tailwind v4 + shadcn-style primitives + Skills/Proposals/Revisions UI Phase 6 of the Skills + Revisions + Proposals work. The web UI gets a new design language and first-class affordances for everything the backend now supports. ## Visual direction - Tailwind v4 with custom @theme block (oklch tokens). Dark-mode-only (internal tool — light mode doubles QA surface). - Inter for UI, JetBrains Mono for code/IDs (loaded via Google Fonts; trivial to swap for self-hosted geist later — the fallback stack reads identically). - Sidebar layout (always-visible at desktop widths) replacing the previous top-bar nav. Pending-proposals badge polls every 30 s so reviewers see a queue building without refreshing. - Lucide icons throughout. - Spacing and radii on Tailwind defaults. Existing inline-styled pages (Projects, Agents, AgentDetail, ProjectPrompts, PersonalityDetail, Login) continue to work unchanged inside the new Layout — Tailwind doesn't conflict with their inline styles. A follow-up can migrate them incrementally. ## What's added ### Build infra (src/web/) - package.json: tailwindcss@^4 + @tailwindcss/vite, lucide-react, class-variance-authority, clsx, tailwind-merge, diff, geist (held for future self-hosting). - vite.config.ts: registers the @tailwindcss/vite plugin. - src/index.css: Tailwind import + @theme tokens + @layer base. - src/main.tsx: imports index.css. - src/lib/utils.ts: shadcn-style cn() helper. ### shadcn-style primitives (src/components/ui/) Hand-written rather than generated via `npx shadcn` so the repo doesn't depend on a CLI tool that needs interactive runtime: - button.tsx — variants: primary / secondary / ghost / danger / link; sizes: sm / md / lg / icon. - card.tsx — Card + Header/Title/Description/Content/Footer subparts. - badge.tsx — variants: default / info / success / warning / danger / outline. - input.tsx — Input + Textarea + Label. - tabs.tsx — no-dep accessible Tabs (no Radix needed for our use). - separator.tsx — h/v separator with role=separator. ### Diff component (src/components/Diff.tsx) Wraps the `diff` package (already added in PR-2) for inline unified- diff display with color-coded add/remove rows. Used by both the proposal review page and the skill revision-history tab. ### New pages (src/pages/) - Dashboard.tsx — at-a-glance home. Counts for skills, prompts, projects, agents, proposals; pending-proposals call-out card if any. - Skills.tsx — list view, separated into Global vs Project/Agent- scoped sections. - SkillDetail.tsx — name + semver + description; tabs for SKILL.md / Files / Metadata / History. History tab shows revisions with click-to-diff against the live body. - Proposals.tsx — queue with Pending/Approved/Rejected tabs. Pending count is highlighted in amber. - ProposalDetail.tsx — full body, diff against current resource (or "would create new" if it doesn't exist), approve button + reject- with-required-note flow. ### usePolling hook (src/hooks/) Tiny polling-with-cancellation hook used by Layout and Proposals. ### Layout rewrite (src/components/Layout.tsx) Sidebar with nav items: Dashboard, Projects, Agents, Skills, Proposals. Lucide icons. Active-route highlighting via NavLink. Pending-proposals warning badge on the Proposals item. ### Routes (src/App.tsx) New routes: /dashboard, /skills, /skills/:name, /proposals, /proposals/:id. Default redirects to /dashboard. ### API types (src/api.ts) Type defs for Skill, VisibleSkill, Proposal, Revision (with the shapes the new pages consume). ## Tests Existing 7 web tests still pass (Login + api). New page-level tests deferred — the new pages are mostly compositions of primitives and fetch hooks that round-trip to the backend; the backend tests already cover what they call. PR-7 polish can add render-and-click tests if coverage drift surfaces. ## Verification - `pnpm --filter @mcpctl/web build` clean, no warnings. - `pnpm test:run` whole monorepo: 162 test files / 2157 tests green. - Visual smoke deferred — needs a running mcpd to populate the fixtures. Manual smoke tested locally is the next step. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:54:55 +01:00
enhanced-resolve@5.21.0:
dependencies:
graceful-fs: 4.2.11
tapable: 2.3.3
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
entities@6.0.1: {}
entities@7.0.1: {}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
entities@8.0.0: {}
env-paths@2.2.1: {}
environment@1.1.0: {}
2026-02-21 03:10:39 +00:00
es-define-property@1.0.1: {}
es-errors@1.3.0: {}
es-module-lexer@1.7.0: {}
es-module-lexer@2.3.1: {}
2026-02-21 03:10:39 +00:00
es-object-atoms@1.1.1:
dependencies:
es-errors: 1.3.0
es-set-tostringtag@2.1.0:
dependencies:
es-errors: 1.3.0
get-intrinsic: 1.3.0
has-tostringtag: 1.0.2
hasown: 2.0.2
es-toolkit@1.44.0: {}
2026-02-21 03:10:39 +00:00
esbuild@0.27.3:
optionalDependencies:
'@esbuild/aix-ppc64': 0.27.3
'@esbuild/android-arm': 0.27.3
'@esbuild/android-arm64': 0.27.3
'@esbuild/android-x64': 0.27.3
'@esbuild/darwin-arm64': 0.27.3
'@esbuild/darwin-x64': 0.27.3
'@esbuild/freebsd-arm64': 0.27.3
'@esbuild/freebsd-x64': 0.27.3
'@esbuild/linux-arm': 0.27.3
'@esbuild/linux-arm64': 0.27.3
'@esbuild/linux-ia32': 0.27.3
'@esbuild/linux-loong64': 0.27.3
'@esbuild/linux-mips64el': 0.27.3
'@esbuild/linux-ppc64': 0.27.3
'@esbuild/linux-riscv64': 0.27.3
'@esbuild/linux-s390x': 0.27.3
'@esbuild/linux-x64': 0.27.3
'@esbuild/netbsd-arm64': 0.27.3
'@esbuild/netbsd-x64': 0.27.3
'@esbuild/openbsd-arm64': 0.27.3
'@esbuild/openbsd-x64': 0.27.3
'@esbuild/openharmony-arm64': 0.27.3
'@esbuild/sunos-x64': 0.27.3
'@esbuild/win32-arm64': 0.27.3
'@esbuild/win32-ia32': 0.27.3
'@esbuild/win32-x64': 0.27.3
escalade@3.2.0: {}
2026-02-21 03:10:39 +00:00
escape-html@1.0.3: {}
escape-string-regexp@2.0.0: {}
2026-02-21 03:10:39 +00:00
escape-string-regexp@4.0.0: {}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
eslint-config-prettier@10.1.8(eslint@10.0.1(jiti@2.7.0)):
2026-02-21 03:10:39 +00:00
dependencies:
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
eslint: 10.0.1(jiti@2.7.0)
2026-02-21 03:10:39 +00:00
eslint-scope@9.1.1:
dependencies:
'@types/esrecurse': 4.3.1
'@types/estree': 1.0.8
esrecurse: 4.3.0
estraverse: 5.3.0
eslint-visitor-keys@3.4.3: {}
eslint-visitor-keys@5.0.1: {}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
eslint@10.0.1(jiti@2.7.0):
2026-02-21 03:10:39 +00:00
dependencies:
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
'@eslint-community/eslint-utils': 4.9.1(eslint@10.0.1(jiti@2.7.0))
2026-02-21 03:10:39 +00:00
'@eslint-community/regexpp': 4.12.2
'@eslint/config-array': 0.23.2
'@eslint/config-helpers': 0.5.2
'@eslint/core': 1.1.0
'@eslint/plugin-kit': 0.6.0
'@humanfs/node': 0.16.7
'@humanwhocodes/module-importer': 1.0.1
'@humanwhocodes/retry': 0.4.3
'@types/estree': 1.0.8
ajv: 6.14.0
cross-spawn: 7.0.6
debug: 4.4.3
escape-string-regexp: 4.0.0
eslint-scope: 9.1.1
eslint-visitor-keys: 5.0.1
espree: 11.1.1
esquery: 1.7.0
esutils: 2.0.3
fast-deep-equal: 3.1.3
file-entry-cache: 8.0.0
find-up: 5.0.0
glob-parent: 6.0.2
ignore: 5.3.2
imurmurhash: 0.1.4
is-glob: 4.0.3
json-stable-stringify-without-jsonify: 1.0.1
minimatch: 10.2.2
natural-compare: 1.4.0
optionator: 0.9.4
optionalDependencies:
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
jiti: 2.7.0
2026-02-21 03:10:39 +00:00
transitivePeerDependencies:
- supports-color
espree@11.1.1:
dependencies:
acorn: 8.16.0
acorn-jsx: 5.3.2(acorn@8.16.0)
eslint-visitor-keys: 5.0.1
esquery@1.7.0:
dependencies:
estraverse: 5.3.0
esrecurse@4.3.0:
dependencies:
estraverse: 5.3.0
estraverse@5.3.0: {}
estree-walker@3.0.3:
dependencies:
'@types/estree': 1.0.8
esutils@2.0.3: {}
etag@1.8.1: {}
events-universal@1.0.1:
dependencies:
bare-events: 2.8.2
transitivePeerDependencies:
- bare-abort-controller
2026-02-21 03:10:39 +00:00
eventsource-parser@3.0.6: {}
eventsource@3.0.7:
dependencies:
eventsource-parser: 3.0.6
execa@5.1.1:
dependencies:
cross-spawn: 7.0.6
get-stream: 6.0.1
human-signals: 2.1.0
is-stream: 2.0.1
merge-stream: 2.0.0
npm-run-path: 4.0.1
onetime: 5.1.2
signal-exit: 3.0.7
strip-final-newline: 2.0.0
2026-02-21 03:10:39 +00:00
expect-type@1.3.0: {}
exponential-backoff@3.1.3: {}
2026-02-21 03:10:39 +00:00
express-rate-limit@8.2.1(express@5.2.1):
dependencies:
express: 5.2.1
ip-address: 10.0.1
express@5.2.1:
dependencies:
accepts: 2.0.0
body-parser: 2.2.2
content-disposition: 1.0.1
content-type: 1.0.5
cookie: 0.7.2
cookie-signature: 1.2.2
debug: 4.4.3
depd: 2.0.0
encodeurl: 2.0.0
escape-html: 1.0.3
etag: 1.8.1
finalhandler: 2.1.1
fresh: 2.0.0
http-errors: 2.0.1
merge-descriptors: 2.0.0
mime-types: 3.0.2
on-finished: 2.4.1
once: 1.4.0
parseurl: 1.3.3
proxy-addr: 2.0.7
qs: 6.15.0
range-parser: 1.2.1
router: 2.2.0
send: 1.2.1
serve-static: 2.2.1
statuses: 2.0.2
type-is: 2.0.1
vary: 1.1.2
transitivePeerDependencies:
- supports-color
exsolve@1.0.8: {}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
extend@3.0.2: {}
2026-02-21 03:10:39 +00:00
fast-check@3.23.2:
dependencies:
pure-rand: 6.1.0
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
fast-check@4.9.0:
dependencies:
pure-rand: 8.4.2
2026-02-21 03:10:39 +00:00
fast-decode-uri-component@1.0.1: {}
fast-deep-equal@3.1.3: {}
fast-fifo@1.3.2: {}
2026-02-21 03:10:39 +00:00
fast-json-stable-stringify@2.1.0: {}
fast-json-stringify@6.3.0:
dependencies:
'@fastify/merge-json-schemas': 0.2.1
ajv: 8.18.0
ajv-formats: 3.0.1(ajv@8.18.0)
fast-uri: 3.1.0
json-schema-ref-resolver: 3.0.0
rfdc: 1.4.1
fast-levenshtein@2.0.6: {}
fast-querystring@1.1.2:
dependencies:
fast-decode-uri-component: 1.0.1
fast-uri@3.1.0: {}
fastify-plugin@5.1.0: {}
fastify@5.7.4:
dependencies:
'@fastify/ajv-compiler': 4.0.5
'@fastify/error': 4.2.0
'@fastify/fast-json-stringify-compiler': 5.0.3
'@fastify/proxy-addr': 5.1.0
abstract-logging: 2.0.1
avvio: 9.2.0
fast-json-stringify: 6.3.0
find-my-way: 9.4.0
light-my-request: 6.6.0
pino: 10.3.1
process-warning: 5.0.0
rfdc: 1.4.1
secure-json-parse: 4.1.0
semver: 7.7.4
toad-cache: 3.7.0
fastq@1.20.1:
dependencies:
reusify: 1.1.0
fdir@6.5.0(picomatch@4.0.3):
optionalDependencies:
picomatch: 4.0.3
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
fetch-blob@3.2.0:
dependencies:
node-domexception: 1.0.0
web-streams-polyfill: 3.3.3
figures@6.1.0:
dependencies:
is-unicode-supported: 2.1.0
2026-02-21 03:10:39 +00:00
file-entry-cache@8.0.0:
dependencies:
flat-cache: 4.0.1
finalhandler@2.1.1:
dependencies:
debug: 4.4.3
encodeurl: 2.0.0
escape-html: 1.0.3
on-finished: 2.4.1
parseurl: 1.3.3
statuses: 2.0.2
transitivePeerDependencies:
- supports-color
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
find-babel-config@2.1.2:
dependencies:
json5: 2.2.3
find-my-way-ts@0.1.6: {}
2026-02-21 03:10:39 +00:00
find-my-way@9.4.0:
dependencies:
fast-deep-equal: 3.1.3
fast-querystring: 1.1.2
safe-regex2: 5.0.0
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
find-up@3.0.0:
dependencies:
locate-path: 3.0.0
2026-02-21 03:10:39 +00:00
find-up@5.0.0:
dependencies:
locate-path: 6.0.0
path-exists: 4.0.0
flat-cache@4.0.1:
dependencies:
flatted: 3.3.3
keyv: 4.5.4
flatted@3.3.3: {}
feat(mcpd+deploy): serve web UI at /ui + smoke tests + docs (Stage 6) The closing stage. mcpd now hosts the Stage 5 SPA, the Docker image bundles the build artifact, a smoke test exercises the personality HTTP surface end-to-end, and the user-facing docs spell out the mental model. mcpd: - Add @fastify/static dep. - New routes/web-ui.ts: registers /ui/* against a static bundle. Looks for the bundle at $MCPD_WEB_ROOT, then /usr/share/mcpd/web (the Docker image path), then a dev-tree fallback. Logs and skips cleanly if missing — API-only deploys keep working. - SPA fallback: any /ui/<path> that doesn't match a file falls through to index.html so direct hits to react-router URLs work. - /ui/* falls through to `kind: skip` in mapUrlToPermission, so the static assets are served unauthenticated. Each API call from the SPA still carries the bearer token. Deploy: - Dockerfile.mcpd builds the @mcpctl/web bundle in the same builder stage and copies dist/ to /usr/share/mcpd/web in the runtime image. Smoke (personality.smoke.test.ts): - Live mcpd flow: create secret/llm/agent/personality, attach an agent-direct prompt, verify the binding listing, reject double- attach (409) + foreign-agent prompt (400), set defaultPersonality by name, detach + delete cleanup. Docs: - New docs/personalities.md: VLAN-on-ethernet model, system-block ordering table, three prompt scopes, CLI walkthrough, web UI walkthrough, full API surface, RBAC notes. - agents.md and chat.md cross-link. - README's Agents section gains a Personalities subsection. Test count after Stage 6: mcpd: 801/801 cli: 430/430 web: 7/7 db: 58/62 (4 pre-existing) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:48:43 +01:00
foreground-child@3.3.1:
dependencies:
cross-spawn: 7.0.6
signal-exit: 4.1.0
form-data@4.0.5:
dependencies:
asynckit: 0.4.0
combined-stream: 1.0.8
es-set-tostringtag: 2.1.0
hasown: 2.0.2
mime-types: 2.1.35
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
formdata-polyfill@4.0.10:
dependencies:
fetch-blob: 3.2.0
2026-02-21 03:10:39 +00:00
forwarded@0.2.0: {}
fresh@2.0.0: {}
fs-constants@1.0.0: {}
fs-minipass@2.1.0:
dependencies:
minipass: 3.3.6
fs-minipass@3.0.3:
dependencies:
minipass: 7.1.3
fs.realpath@1.0.0: {}
2026-02-21 03:10:39 +00:00
fsevents@2.3.3:
optional: true
function-bind@1.1.2: {}
gauge@3.0.2:
dependencies:
aproba: 2.1.0
color-support: 1.1.3
console-control-strings: 1.1.0
has-unicode: 2.0.1
object-assign: 4.1.1
signal-exit: 3.0.7
string-width: 4.2.3
strip-ansi: 6.0.1
wide-align: 1.1.5
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
gaxios@7.3.0:
dependencies:
extend: 3.0.2
https-proxy-agent: 7.0.6
node-fetch: 3.3.2
transitivePeerDependencies:
- supports-color
gcp-metadata@8.1.2:
dependencies:
gaxios: 7.3.0
google-logging-utils: 1.1.3
json-bigint: 1.0.0
transitivePeerDependencies:
- supports-color
geist@1.7.0(next@16.2.5(@babel/core@7.29.0)(@opentelemetry/api@1.9.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)):
feat(web): bold redesign — Tailwind v4 + shadcn-style primitives + Skills/Proposals/Revisions UI Phase 6 of the Skills + Revisions + Proposals work. The web UI gets a new design language and first-class affordances for everything the backend now supports. ## Visual direction - Tailwind v4 with custom @theme block (oklch tokens). Dark-mode-only (internal tool — light mode doubles QA surface). - Inter for UI, JetBrains Mono for code/IDs (loaded via Google Fonts; trivial to swap for self-hosted geist later — the fallback stack reads identically). - Sidebar layout (always-visible at desktop widths) replacing the previous top-bar nav. Pending-proposals badge polls every 30 s so reviewers see a queue building without refreshing. - Lucide icons throughout. - Spacing and radii on Tailwind defaults. Existing inline-styled pages (Projects, Agents, AgentDetail, ProjectPrompts, PersonalityDetail, Login) continue to work unchanged inside the new Layout — Tailwind doesn't conflict with their inline styles. A follow-up can migrate them incrementally. ## What's added ### Build infra (src/web/) - package.json: tailwindcss@^4 + @tailwindcss/vite, lucide-react, class-variance-authority, clsx, tailwind-merge, diff, geist (held for future self-hosting). - vite.config.ts: registers the @tailwindcss/vite plugin. - src/index.css: Tailwind import + @theme tokens + @layer base. - src/main.tsx: imports index.css. - src/lib/utils.ts: shadcn-style cn() helper. ### shadcn-style primitives (src/components/ui/) Hand-written rather than generated via `npx shadcn` so the repo doesn't depend on a CLI tool that needs interactive runtime: - button.tsx — variants: primary / secondary / ghost / danger / link; sizes: sm / md / lg / icon. - card.tsx — Card + Header/Title/Description/Content/Footer subparts. - badge.tsx — variants: default / info / success / warning / danger / outline. - input.tsx — Input + Textarea + Label. - tabs.tsx — no-dep accessible Tabs (no Radix needed for our use). - separator.tsx — h/v separator with role=separator. ### Diff component (src/components/Diff.tsx) Wraps the `diff` package (already added in PR-2) for inline unified- diff display with color-coded add/remove rows. Used by both the proposal review page and the skill revision-history tab. ### New pages (src/pages/) - Dashboard.tsx — at-a-glance home. Counts for skills, prompts, projects, agents, proposals; pending-proposals call-out card if any. - Skills.tsx — list view, separated into Global vs Project/Agent- scoped sections. - SkillDetail.tsx — name + semver + description; tabs for SKILL.md / Files / Metadata / History. History tab shows revisions with click-to-diff against the live body. - Proposals.tsx — queue with Pending/Approved/Rejected tabs. Pending count is highlighted in amber. - ProposalDetail.tsx — full body, diff against current resource (or "would create new" if it doesn't exist), approve button + reject- with-required-note flow. ### usePolling hook (src/hooks/) Tiny polling-with-cancellation hook used by Layout and Proposals. ### Layout rewrite (src/components/Layout.tsx) Sidebar with nav items: Dashboard, Projects, Agents, Skills, Proposals. Lucide icons. Active-route highlighting via NavLink. Pending-proposals warning badge on the Proposals item. ### Routes (src/App.tsx) New routes: /dashboard, /skills, /skills/:name, /proposals, /proposals/:id. Default redirects to /dashboard. ### API types (src/api.ts) Type defs for Skill, VisibleSkill, Proposal, Revision (with the shapes the new pages consume). ## Tests Existing 7 web tests still pass (Login + api). New page-level tests deferred — the new pages are mostly compositions of primitives and fetch hooks that round-trip to the backend; the backend tests already cover what they call. PR-7 polish can add render-and-click tests if coverage drift surfaces. ## Verification - `pnpm --filter @mcpctl/web build` clean, no warnings. - `pnpm test:run` whole monorepo: 162 test files / 2157 tests green. - Visual smoke deferred — needs a running mcpd to populate the fixtures. Manual smoke tested locally is the next step. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:54:55 +01:00
dependencies:
next: 16.2.5(@babel/core@7.29.0)(@opentelemetry/api@1.9.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
feat(web): bold redesign — Tailwind v4 + shadcn-style primitives + Skills/Proposals/Revisions UI Phase 6 of the Skills + Revisions + Proposals work. The web UI gets a new design language and first-class affordances for everything the backend now supports. ## Visual direction - Tailwind v4 with custom @theme block (oklch tokens). Dark-mode-only (internal tool — light mode doubles QA surface). - Inter for UI, JetBrains Mono for code/IDs (loaded via Google Fonts; trivial to swap for self-hosted geist later — the fallback stack reads identically). - Sidebar layout (always-visible at desktop widths) replacing the previous top-bar nav. Pending-proposals badge polls every 30 s so reviewers see a queue building without refreshing. - Lucide icons throughout. - Spacing and radii on Tailwind defaults. Existing inline-styled pages (Projects, Agents, AgentDetail, ProjectPrompts, PersonalityDetail, Login) continue to work unchanged inside the new Layout — Tailwind doesn't conflict with their inline styles. A follow-up can migrate them incrementally. ## What's added ### Build infra (src/web/) - package.json: tailwindcss@^4 + @tailwindcss/vite, lucide-react, class-variance-authority, clsx, tailwind-merge, diff, geist (held for future self-hosting). - vite.config.ts: registers the @tailwindcss/vite plugin. - src/index.css: Tailwind import + @theme tokens + @layer base. - src/main.tsx: imports index.css. - src/lib/utils.ts: shadcn-style cn() helper. ### shadcn-style primitives (src/components/ui/) Hand-written rather than generated via `npx shadcn` so the repo doesn't depend on a CLI tool that needs interactive runtime: - button.tsx — variants: primary / secondary / ghost / danger / link; sizes: sm / md / lg / icon. - card.tsx — Card + Header/Title/Description/Content/Footer subparts. - badge.tsx — variants: default / info / success / warning / danger / outline. - input.tsx — Input + Textarea + Label. - tabs.tsx — no-dep accessible Tabs (no Radix needed for our use). - separator.tsx — h/v separator with role=separator. ### Diff component (src/components/Diff.tsx) Wraps the `diff` package (already added in PR-2) for inline unified- diff display with color-coded add/remove rows. Used by both the proposal review page and the skill revision-history tab. ### New pages (src/pages/) - Dashboard.tsx — at-a-glance home. Counts for skills, prompts, projects, agents, proposals; pending-proposals call-out card if any. - Skills.tsx — list view, separated into Global vs Project/Agent- scoped sections. - SkillDetail.tsx — name + semver + description; tabs for SKILL.md / Files / Metadata / History. History tab shows revisions with click-to-diff against the live body. - Proposals.tsx — queue with Pending/Approved/Rejected tabs. Pending count is highlighted in amber. - ProposalDetail.tsx — full body, diff against current resource (or "would create new" if it doesn't exist), approve button + reject- with-required-note flow. ### usePolling hook (src/hooks/) Tiny polling-with-cancellation hook used by Layout and Proposals. ### Layout rewrite (src/components/Layout.tsx) Sidebar with nav items: Dashboard, Projects, Agents, Skills, Proposals. Lucide icons. Active-route highlighting via NavLink. Pending-proposals warning badge on the Proposals item. ### Routes (src/App.tsx) New routes: /dashboard, /skills, /skills/:name, /proposals, /proposals/:id. Default redirects to /dashboard. ### API types (src/api.ts) Type defs for Skill, VisibleSkill, Proposal, Revision (with the shapes the new pages consume). ## Tests Existing 7 web tests still pass (Login + api). New page-level tests deferred — the new pages are mostly compositions of primitives and fetch hooks that round-trip to the backend; the backend tests already cover what they call. PR-7 polish can add render-and-click tests if coverage drift surfaces. ## Verification - `pnpm --filter @mcpctl/web build` clean, no warnings. - `pnpm test:run` whole monorepo: 162 test files / 2157 tests green. - Visual smoke deferred — needs a running mcpd to populate the fixtures. Manual smoke tested locally is the next step. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:54:55 +01:00
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
gensync@1.0.0-beta.2: {}
get-caller-file@2.0.5: {}
get-east-asian-width@1.5.0: {}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
get-east-asian-width@1.6.0: {}
2026-02-21 03:10:39 +00:00
get-intrinsic@1.3.0:
dependencies:
call-bind-apply-helpers: 1.0.2
es-define-property: 1.0.1
es-errors: 1.3.0
es-object-atoms: 1.1.1
function-bind: 1.1.2
get-proto: 1.0.1
gopd: 1.2.0
has-symbols: 1.1.0
hasown: 2.0.2
math-intrinsics: 1.1.0
get-proto@1.0.1:
dependencies:
dunder-proto: 1.0.1
es-object-atoms: 1.1.1
get-stream@6.0.1: {}
2026-02-21 03:10:39 +00:00
get-tsconfig@4.13.6:
dependencies:
resolve-pkg-maps: 1.0.0
giget@2.0.0:
dependencies:
citty: 0.1.6
consola: 3.4.2
defu: 6.1.4
node-fetch-native: 1.6.7
nypm: 0.6.5
pathe: 2.0.3
glob-parent@6.0.2:
dependencies:
is-glob: 4.0.3
feat(mcpd+deploy): serve web UI at /ui + smoke tests + docs (Stage 6) The closing stage. mcpd now hosts the Stage 5 SPA, the Docker image bundles the build artifact, a smoke test exercises the personality HTTP surface end-to-end, and the user-facing docs spell out the mental model. mcpd: - Add @fastify/static dep. - New routes/web-ui.ts: registers /ui/* against a static bundle. Looks for the bundle at $MCPD_WEB_ROOT, then /usr/share/mcpd/web (the Docker image path), then a dev-tree fallback. Logs and skips cleanly if missing — API-only deploys keep working. - SPA fallback: any /ui/<path> that doesn't match a file falls through to index.html so direct hits to react-router URLs work. - /ui/* falls through to `kind: skip` in mapUrlToPermission, so the static assets are served unauthenticated. Each API call from the SPA still carries the bearer token. Deploy: - Dockerfile.mcpd builds the @mcpctl/web bundle in the same builder stage and copies dist/ to /usr/share/mcpd/web in the runtime image. Smoke (personality.smoke.test.ts): - Live mcpd flow: create secret/llm/agent/personality, attach an agent-direct prompt, verify the binding listing, reject double- attach (409) + foreign-agent prompt (400), set defaultPersonality by name, detach + delete cleanup. Docs: - New docs/personalities.md: VLAN-on-ethernet model, system-block ordering table, three prompt scopes, CLI walkthrough, web UI walkthrough, full API surface, RBAC notes. - agents.md and chat.md cross-link. - README's Agents section gains a Personalities subsection. Test count after Stage 6: mcpd: 801/801 cli: 430/430 web: 7/7 db: 58/62 (4 pre-existing) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:48:43 +01:00
glob@11.1.0:
dependencies:
foreground-child: 3.3.1
jackspeak: 4.2.3
minimatch: 10.2.2
minipass: 7.1.3
package-json-from-dist: 1.0.1
path-scurry: 2.0.2
2026-02-21 03:10:39 +00:00
glob@13.0.6:
dependencies:
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
minimatch: 10.2.5
2026-02-21 03:10:39 +00:00
minipass: 7.1.3
path-scurry: 2.0.2
glob@7.2.3:
dependencies:
fs.realpath: 1.0.0
inflight: 1.0.6
inherits: 2.0.4
minimatch: 3.1.2
once: 1.4.0
path-is-absolute: 1.0.1
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
glob@9.3.5:
dependencies:
fs.realpath: 1.0.0
minimatch: 8.0.7
minipass: 4.2.8
path-scurry: 1.11.1
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
google-auth-library@10.9.1:
dependencies:
base64-js: 1.5.1
ecdsa-sig-formatter: 1.0.11
gaxios: 7.3.0
gcp-metadata: 8.1.2
google-logging-utils: 1.1.3
jws: 4.0.1
transitivePeerDependencies:
- supports-color
google-logging-utils@1.1.3: {}
google-protobuf@3.21.4: {}
2026-02-21 03:10:39 +00:00
gopd@1.2.0: {}
feat(web): bold redesign — Tailwind v4 + shadcn-style primitives + Skills/Proposals/Revisions UI Phase 6 of the Skills + Revisions + Proposals work. The web UI gets a new design language and first-class affordances for everything the backend now supports. ## Visual direction - Tailwind v4 with custom @theme block (oklch tokens). Dark-mode-only (internal tool — light mode doubles QA surface). - Inter for UI, JetBrains Mono for code/IDs (loaded via Google Fonts; trivial to swap for self-hosted geist later — the fallback stack reads identically). - Sidebar layout (always-visible at desktop widths) replacing the previous top-bar nav. Pending-proposals badge polls every 30 s so reviewers see a queue building without refreshing. - Lucide icons throughout. - Spacing and radii on Tailwind defaults. Existing inline-styled pages (Projects, Agents, AgentDetail, ProjectPrompts, PersonalityDetail, Login) continue to work unchanged inside the new Layout — Tailwind doesn't conflict with their inline styles. A follow-up can migrate them incrementally. ## What's added ### Build infra (src/web/) - package.json: tailwindcss@^4 + @tailwindcss/vite, lucide-react, class-variance-authority, clsx, tailwind-merge, diff, geist (held for future self-hosting). - vite.config.ts: registers the @tailwindcss/vite plugin. - src/index.css: Tailwind import + @theme tokens + @layer base. - src/main.tsx: imports index.css. - src/lib/utils.ts: shadcn-style cn() helper. ### shadcn-style primitives (src/components/ui/) Hand-written rather than generated via `npx shadcn` so the repo doesn't depend on a CLI tool that needs interactive runtime: - button.tsx — variants: primary / secondary / ghost / danger / link; sizes: sm / md / lg / icon. - card.tsx — Card + Header/Title/Description/Content/Footer subparts. - badge.tsx — variants: default / info / success / warning / danger / outline. - input.tsx — Input + Textarea + Label. - tabs.tsx — no-dep accessible Tabs (no Radix needed for our use). - separator.tsx — h/v separator with role=separator. ### Diff component (src/components/Diff.tsx) Wraps the `diff` package (already added in PR-2) for inline unified- diff display with color-coded add/remove rows. Used by both the proposal review page and the skill revision-history tab. ### New pages (src/pages/) - Dashboard.tsx — at-a-glance home. Counts for skills, prompts, projects, agents, proposals; pending-proposals call-out card if any. - Skills.tsx — list view, separated into Global vs Project/Agent- scoped sections. - SkillDetail.tsx — name + semver + description; tabs for SKILL.md / Files / Metadata / History. History tab shows revisions with click-to-diff against the live body. - Proposals.tsx — queue with Pending/Approved/Rejected tabs. Pending count is highlighted in amber. - ProposalDetail.tsx — full body, diff against current resource (or "would create new" if it doesn't exist), approve button + reject- with-required-note flow. ### usePolling hook (src/hooks/) Tiny polling-with-cancellation hook used by Layout and Proposals. ### Layout rewrite (src/components/Layout.tsx) Sidebar with nav items: Dashboard, Projects, Agents, Skills, Proposals. Lucide icons. Active-route highlighting via NavLink. Pending-proposals warning badge on the Proposals item. ### Routes (src/App.tsx) New routes: /dashboard, /skills, /skills/:name, /proposals, /proposals/:id. Default redirects to /dashboard. ### API types (src/api.ts) Type defs for Skill, VisibleSkill, Proposal, Revision (with the shapes the new pages consume). ## Tests Existing 7 web tests still pass (Login + api). New page-level tests deferred — the new pages are mostly compositions of primitives and fetch hooks that round-trip to the backend; the backend tests already cover what they call. PR-7 polish can add render-and-click tests if coverage drift surfaces. ## Verification - `pnpm --filter @mcpctl/web build` clean, no warnings. - `pnpm test:run` whole monorepo: 162 test files / 2157 tests green. - Visual smoke deferred — needs a running mcpd to populate the fixtures. Manual smoke tested locally is the next step. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:54:55 +01:00
graceful-fs@4.2.11: {}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
grok-mermaid@0.2.2: {}
2026-02-21 03:10:39 +00:00
has-flag@4.0.0: {}
has-symbols@1.1.0: {}
has-tostringtag@1.0.2:
dependencies:
has-symbols: 1.1.0
has-unicode@2.0.1: {}
2026-02-21 03:10:39 +00:00
hasown@2.0.2:
dependencies:
function-bind: 1.1.2
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
hasown@2.0.4:
dependencies:
function-bind: 1.1.2
2026-02-21 03:10:39 +00:00
helmet@7.2.0: {}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
highlight.js@10.7.3: {}
2026-02-21 03:10:39 +00:00
hono@4.12.0: {}
hosted-git-info@7.0.2:
dependencies:
lru-cache: 10.4.3
hosted-git-info@9.0.3:
dependencies:
lru-cache: 11.2.6
hpagent@1.2.0: {}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
html-encoding-sniffer@6.0.0:
dependencies:
'@exodus/bytes': 1.15.0
transitivePeerDependencies:
- '@noble/hashes'
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
html-entities@2.3.3: {}
2026-02-21 03:10:39 +00:00
html-escaper@2.0.2: {}
http-cache-semantics@4.2.0: {}
2026-02-21 03:10:39 +00:00
http-errors@2.0.1:
dependencies:
depd: 2.0.0
inherits: 2.0.4
setprototypeof: 1.2.0
statuses: 2.0.2
toidentifier: 1.0.1
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
http-proxy-agent@7.0.2:
dependencies:
agent-base: 7.1.4
debug: 4.4.3
transitivePeerDependencies:
- supports-color
https-proxy-agent@5.0.1:
dependencies:
agent-base: 6.0.2
debug: 4.4.3
transitivePeerDependencies:
- supports-color
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
https-proxy-agent@7.0.6:
dependencies:
agent-base: 7.1.4
debug: 4.4.3
transitivePeerDependencies:
- supports-color
human-signals@2.1.0: {}
2026-02-21 03:10:39 +00:00
iconv-lite@0.7.2:
dependencies:
safer-buffer: 2.1.2
ieee754@1.2.1: {}
ignore-walk@8.0.0:
dependencies:
minimatch: 10.2.2
2026-02-21 03:10:39 +00:00
ignore@5.3.2: {}
ignore@7.0.5: {}
import-in-the-middle@3.3.1:
dependencies:
cjs-module-lexer: 2.2.0
es-module-lexer: 2.3.1
module-details-from-path: 1.0.4
2026-02-21 03:10:39 +00:00
imurmurhash@0.1.4: {}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
indent-string@4.0.0: {}
indent-string@5.0.0: {}
inflight@1.0.6:
dependencies:
once: 1.4.0
wrappy: 1.0.2
2026-02-21 03:10:39 +00:00
inherits@2.0.4: {}
ini@2.0.0: {}
ini@6.0.0: {}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
ini@7.0.0: {}
ink@6.8.0(@types/react@19.2.14)(react@19.2.4):
dependencies:
'@alcalzone/ansi-tokenize': 0.2.5
ansi-escapes: 7.3.0
ansi-styles: 6.2.3
auto-bind: 5.0.1
chalk: 5.6.2
cli-boxes: 3.0.0
cli-cursor: 4.0.0
cli-truncate: 5.1.1
code-excerpt: 4.0.0
es-toolkit: 1.44.0
indent-string: 5.0.0
is-in-ci: 2.0.0
patch-console: 2.0.0
react: 19.2.4
react-reconciler: 0.33.0(react@19.2.4)
scheduler: 0.27.0
signal-exit: 3.0.7
slice-ansi: 8.0.0
stack-utils: 2.0.6
string-width: 8.2.0
terminal-size: 4.0.1
type-fest: 5.4.4
widest-line: 6.0.0
wrap-ansi: 9.0.2
ws: 8.19.0
yoga-layout: 3.2.1
optionalDependencies:
'@types/react': 19.2.14
transitivePeerDependencies:
- bufferutil
- utf-8-validate
inquirer@12.11.1(@types/node@25.3.0):
2026-02-21 03:10:39 +00:00
dependencies:
'@inquirer/ansi': 1.0.2
'@inquirer/core': 10.3.2(@types/node@25.3.0)
'@inquirer/prompts': 7.10.1(@types/node@25.3.0)
'@inquirer/type': 3.0.10(@types/node@25.3.0)
2026-02-21 03:10:39 +00:00
mute-stream: 2.0.0
run-async: 4.0.6
rxjs: 7.8.2
optionalDependencies:
'@types/node': 25.3.0
2026-02-21 03:10:39 +00:00
ip-address@10.0.1: {}
ipaddr.js@1.9.1: {}
ipaddr.js@2.3.0: {}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
is-core-module@2.16.2:
dependencies:
hasown: 2.0.4
2026-02-21 03:10:39 +00:00
is-extglob@2.1.1: {}
is-fullwidth-code-point@3.0.0: {}
is-fullwidth-code-point@5.1.0:
dependencies:
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
get-east-asian-width: 1.6.0
2026-02-21 03:10:39 +00:00
is-glob@4.0.3:
dependencies:
is-extglob: 2.1.1
is-in-ci@2.0.0: {}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
is-potential-custom-element-name@1.0.1: {}
2026-02-21 03:10:39 +00:00
is-promise@4.0.0: {}
is-stream@2.0.1: {}
is-unicode-supported@2.1.0: {}
2026-02-21 03:10:39 +00:00
isexe@2.0.0: {}
isexe@4.0.0: {}
isomorphic-ws@5.0.0(ws@8.19.0):
dependencies:
ws: 8.19.0
2026-02-21 03:10:39 +00:00
istanbul-lib-coverage@3.2.2: {}
istanbul-lib-report@3.0.1:
dependencies:
istanbul-lib-coverage: 3.2.2
make-dir: 4.0.0
supports-color: 7.2.0
istanbul-reports@3.2.0:
dependencies:
html-escaper: 2.0.2
istanbul-lib-report: 3.0.1
feat(mcpd+deploy): serve web UI at /ui + smoke tests + docs (Stage 6) The closing stage. mcpd now hosts the Stage 5 SPA, the Docker image bundles the build artifact, a smoke test exercises the personality HTTP surface end-to-end, and the user-facing docs spell out the mental model. mcpd: - Add @fastify/static dep. - New routes/web-ui.ts: registers /ui/* against a static bundle. Looks for the bundle at $MCPD_WEB_ROOT, then /usr/share/mcpd/web (the Docker image path), then a dev-tree fallback. Logs and skips cleanly if missing — API-only deploys keep working. - SPA fallback: any /ui/<path> that doesn't match a file falls through to index.html so direct hits to react-router URLs work. - /ui/* falls through to `kind: skip` in mapUrlToPermission, so the static assets are served unauthenticated. Each API call from the SPA still carries the bearer token. Deploy: - Dockerfile.mcpd builds the @mcpctl/web bundle in the same builder stage and copies dist/ to /usr/share/mcpd/web in the runtime image. Smoke (personality.smoke.test.ts): - Live mcpd flow: create secret/llm/agent/personality, attach an agent-direct prompt, verify the binding listing, reject double- attach (409) + foreign-agent prompt (400), set defaultPersonality by name, detach + delete cleanup. Docs: - New docs/personalities.md: VLAN-on-ethernet model, system-block ordering table, three prompt scopes, CLI walkthrough, web UI walkthrough, full API surface, RBAC notes. - agents.md and chat.md cross-link. - README's Agents section gains a Personalities subsection. Test count after Stage 6: mcpd: 801/801 cli: 430/430 web: 7/7 db: 58/62 (4 pre-existing) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:48:43 +01:00
jackspeak@4.2.3:
dependencies:
'@isaacs/cliui': 9.0.0
2026-02-21 03:10:39 +00:00
jiti@2.6.1: {}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
jiti@2.7.0: {}
2026-02-21 03:10:39 +00:00
jose@6.1.3: {}
js-tokens@10.0.0: {}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
js-tokens@4.0.0: {}
2026-02-21 03:10:39 +00:00
js-yaml@4.1.1:
dependencies:
argparse: 2.0.1
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
jsdom@28.1.0:
dependencies:
'@acemir/cssom': 0.9.31
'@asamuzakjp/dom-selector': 6.8.1
'@bramus/specificity': 2.4.2
'@exodus/bytes': 1.15.0
cssstyle: 6.2.0
data-urls: 7.0.0
decimal.js: 10.6.0
html-encoding-sniffer: 6.0.0
http-proxy-agent: 7.0.2
https-proxy-agent: 7.0.6
is-potential-custom-element-name: 1.0.1
parse5: 8.0.1
saxes: 6.0.0
symbol-tree: 3.2.4
tough-cookie: 6.0.1
undici: 7.25.0
w3c-xmlserializer: 5.0.0
webidl-conversions: 8.0.1
whatwg-mimetype: 5.0.0
whatwg-url: 16.0.1
xml-name-validator: 5.0.0
transitivePeerDependencies:
- '@noble/hashes'
- supports-color
jsep@1.4.0: {}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
jsesc@3.1.0: {}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
json-bigint@1.0.0:
dependencies:
bignumber.js: 9.3.1
2026-02-21 03:10:39 +00:00
json-buffer@3.0.1: {}
json-parse-even-better-errors@5.0.0: {}
2026-02-21 03:10:39 +00:00
json-schema-ref-resolver@3.0.0:
dependencies:
dequal: 2.0.3
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
json-schema-to-ts@3.1.1:
dependencies:
'@babel/runtime': 7.29.2
ts-algebra: 2.0.0
2026-02-21 03:10:39 +00:00
json-schema-traverse@0.4.1: {}
json-schema-traverse@1.0.0: {}
json-schema-typed@8.0.2: {}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
json-schema@0.4.0: {}
2026-02-21 03:10:39 +00:00
json-stable-stringify-without-jsonify@1.0.1: {}
json-stringify-nice@1.1.4: {}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
json5@2.2.3: {}
jsonparse@1.3.1: {}
jsonpath-plus@10.4.0:
dependencies:
'@jsep-plugin/assignment': 1.3.0(jsep@1.4.0)
'@jsep-plugin/regex': 1.0.4(jsep@1.4.0)
jsep: 1.4.0
just-diff-apply@5.5.0: {}
just-diff@6.0.2: {}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
jwa@2.0.1:
dependencies:
buffer-equal-constant-time: 1.0.1
ecdsa-sig-formatter: 1.0.11
safe-buffer: 5.2.1
jws@4.0.1:
dependencies:
jwa: 2.0.1
safe-buffer: 5.2.1
2026-02-21 03:10:39 +00:00
keyv@4.5.4:
dependencies:
json-buffer: 3.0.1
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
kubernetes-types@1.30.0: {}
2026-02-21 03:10:39 +00:00
levn@0.4.1:
dependencies:
prelude-ls: 1.2.1
type-check: 0.4.0
light-my-request@6.6.0:
dependencies:
cookie: 1.1.1
process-warning: 4.0.1
set-cookie-parser: 2.7.2
feat(web): bold redesign — Tailwind v4 + shadcn-style primitives + Skills/Proposals/Revisions UI Phase 6 of the Skills + Revisions + Proposals work. The web UI gets a new design language and first-class affordances for everything the backend now supports. ## Visual direction - Tailwind v4 with custom @theme block (oklch tokens). Dark-mode-only (internal tool — light mode doubles QA surface). - Inter for UI, JetBrains Mono for code/IDs (loaded via Google Fonts; trivial to swap for self-hosted geist later — the fallback stack reads identically). - Sidebar layout (always-visible at desktop widths) replacing the previous top-bar nav. Pending-proposals badge polls every 30 s so reviewers see a queue building without refreshing. - Lucide icons throughout. - Spacing and radii on Tailwind defaults. Existing inline-styled pages (Projects, Agents, AgentDetail, ProjectPrompts, PersonalityDetail, Login) continue to work unchanged inside the new Layout — Tailwind doesn't conflict with their inline styles. A follow-up can migrate them incrementally. ## What's added ### Build infra (src/web/) - package.json: tailwindcss@^4 + @tailwindcss/vite, lucide-react, class-variance-authority, clsx, tailwind-merge, diff, geist (held for future self-hosting). - vite.config.ts: registers the @tailwindcss/vite plugin. - src/index.css: Tailwind import + @theme tokens + @layer base. - src/main.tsx: imports index.css. - src/lib/utils.ts: shadcn-style cn() helper. ### shadcn-style primitives (src/components/ui/) Hand-written rather than generated via `npx shadcn` so the repo doesn't depend on a CLI tool that needs interactive runtime: - button.tsx — variants: primary / secondary / ghost / danger / link; sizes: sm / md / lg / icon. - card.tsx — Card + Header/Title/Description/Content/Footer subparts. - badge.tsx — variants: default / info / success / warning / danger / outline. - input.tsx — Input + Textarea + Label. - tabs.tsx — no-dep accessible Tabs (no Radix needed for our use). - separator.tsx — h/v separator with role=separator. ### Diff component (src/components/Diff.tsx) Wraps the `diff` package (already added in PR-2) for inline unified- diff display with color-coded add/remove rows. Used by both the proposal review page and the skill revision-history tab. ### New pages (src/pages/) - Dashboard.tsx — at-a-glance home. Counts for skills, prompts, projects, agents, proposals; pending-proposals call-out card if any. - Skills.tsx — list view, separated into Global vs Project/Agent- scoped sections. - SkillDetail.tsx — name + semver + description; tabs for SKILL.md / Files / Metadata / History. History tab shows revisions with click-to-diff against the live body. - Proposals.tsx — queue with Pending/Approved/Rejected tabs. Pending count is highlighted in amber. - ProposalDetail.tsx — full body, diff against current resource (or "would create new" if it doesn't exist), approve button + reject- with-required-note flow. ### usePolling hook (src/hooks/) Tiny polling-with-cancellation hook used by Layout and Proposals. ### Layout rewrite (src/components/Layout.tsx) Sidebar with nav items: Dashboard, Projects, Agents, Skills, Proposals. Lucide icons. Active-route highlighting via NavLink. Pending-proposals warning badge on the Proposals item. ### Routes (src/App.tsx) New routes: /dashboard, /skills, /skills/:name, /proposals, /proposals/:id. Default redirects to /dashboard. ### API types (src/api.ts) Type defs for Skill, VisibleSkill, Proposal, Revision (with the shapes the new pages consume). ## Tests Existing 7 web tests still pass (Login + api). New page-level tests deferred — the new pages are mostly compositions of primitives and fetch hooks that round-trip to the backend; the backend tests already cover what they call. PR-7 polish can add render-and-click tests if coverage drift surfaces. ## Verification - `pnpm --filter @mcpctl/web build` clean, no warnings. - `pnpm test:run` whole monorepo: 162 test files / 2157 tests green. - Visual smoke deferred — needs a running mcpd to populate the fixtures. Manual smoke tested locally is the next step. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:54:55 +01:00
lightningcss-android-arm64@1.32.0:
optional: true
lightningcss-darwin-arm64@1.32.0:
optional: true
lightningcss-darwin-x64@1.32.0:
optional: true
lightningcss-freebsd-x64@1.32.0:
optional: true
lightningcss-linux-arm-gnueabihf@1.32.0:
optional: true
lightningcss-linux-arm64-gnu@1.32.0:
optional: true
lightningcss-linux-arm64-musl@1.32.0:
optional: true
lightningcss-linux-x64-gnu@1.32.0:
optional: true
lightningcss-linux-x64-musl@1.32.0:
optional: true
lightningcss-win32-arm64-msvc@1.32.0:
optional: true
lightningcss-win32-x64-msvc@1.32.0:
optional: true
lightningcss@1.32.0:
dependencies:
detect-libc: 2.1.2
optionalDependencies:
lightningcss-android-arm64: 1.32.0
lightningcss-darwin-arm64: 1.32.0
lightningcss-darwin-x64: 1.32.0
lightningcss-freebsd-x64: 1.32.0
lightningcss-linux-arm-gnueabihf: 1.32.0
lightningcss-linux-arm64-gnu: 1.32.0
lightningcss-linux-arm64-musl: 1.32.0
lightningcss-linux-x64-gnu: 1.32.0
lightningcss-linux-x64-musl: 1.32.0
lightningcss-win32-arm64-msvc: 1.32.0
lightningcss-win32-x64-msvc: 1.32.0
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
locate-path@3.0.0:
dependencies:
p-locate: 3.0.0
path-exists: 3.0.0
2026-02-21 03:10:39 +00:00
locate-path@6.0.0:
dependencies:
p-locate: 5.0.0
lodash.camelcase@4.3.0: {}
long@5.3.2: {}
lru-cache@10.4.3: {}
2026-02-21 03:10:39 +00:00
lru-cache@11.2.6: {}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
lru-cache@5.1.1:
dependencies:
yallist: 3.1.1
feat(web): bold redesign — Tailwind v4 + shadcn-style primitives + Skills/Proposals/Revisions UI Phase 6 of the Skills + Revisions + Proposals work. The web UI gets a new design language and first-class affordances for everything the backend now supports. ## Visual direction - Tailwind v4 with custom @theme block (oklch tokens). Dark-mode-only (internal tool — light mode doubles QA surface). - Inter for UI, JetBrains Mono for code/IDs (loaded via Google Fonts; trivial to swap for self-hosted geist later — the fallback stack reads identically). - Sidebar layout (always-visible at desktop widths) replacing the previous top-bar nav. Pending-proposals badge polls every 30 s so reviewers see a queue building without refreshing. - Lucide icons throughout. - Spacing and radii on Tailwind defaults. Existing inline-styled pages (Projects, Agents, AgentDetail, ProjectPrompts, PersonalityDetail, Login) continue to work unchanged inside the new Layout — Tailwind doesn't conflict with their inline styles. A follow-up can migrate them incrementally. ## What's added ### Build infra (src/web/) - package.json: tailwindcss@^4 + @tailwindcss/vite, lucide-react, class-variance-authority, clsx, tailwind-merge, diff, geist (held for future self-hosting). - vite.config.ts: registers the @tailwindcss/vite plugin. - src/index.css: Tailwind import + @theme tokens + @layer base. - src/main.tsx: imports index.css. - src/lib/utils.ts: shadcn-style cn() helper. ### shadcn-style primitives (src/components/ui/) Hand-written rather than generated via `npx shadcn` so the repo doesn't depend on a CLI tool that needs interactive runtime: - button.tsx — variants: primary / secondary / ghost / danger / link; sizes: sm / md / lg / icon. - card.tsx — Card + Header/Title/Description/Content/Footer subparts. - badge.tsx — variants: default / info / success / warning / danger / outline. - input.tsx — Input + Textarea + Label. - tabs.tsx — no-dep accessible Tabs (no Radix needed for our use). - separator.tsx — h/v separator with role=separator. ### Diff component (src/components/Diff.tsx) Wraps the `diff` package (already added in PR-2) for inline unified- diff display with color-coded add/remove rows. Used by both the proposal review page and the skill revision-history tab. ### New pages (src/pages/) - Dashboard.tsx — at-a-glance home. Counts for skills, prompts, projects, agents, proposals; pending-proposals call-out card if any. - Skills.tsx — list view, separated into Global vs Project/Agent- scoped sections. - SkillDetail.tsx — name + semver + description; tabs for SKILL.md / Files / Metadata / History. History tab shows revisions with click-to-diff against the live body. - Proposals.tsx — queue with Pending/Approved/Rejected tabs. Pending count is highlighted in amber. - ProposalDetail.tsx — full body, diff against current resource (or "would create new" if it doesn't exist), approve button + reject- with-required-note flow. ### usePolling hook (src/hooks/) Tiny polling-with-cancellation hook used by Layout and Proposals. ### Layout rewrite (src/components/Layout.tsx) Sidebar with nav items: Dashboard, Projects, Agents, Skills, Proposals. Lucide icons. Active-route highlighting via NavLink. Pending-proposals warning badge on the Proposals item. ### Routes (src/App.tsx) New routes: /dashboard, /skills, /skills/:name, /proposals, /proposals/:id. Default redirects to /dashboard. ### API types (src/api.ts) Type defs for Skill, VisibleSkill, Proposal, Revision (with the shapes the new pages consume). ## Tests Existing 7 web tests still pass (Login + api). New page-level tests deferred — the new pages are mostly compositions of primitives and fetch hooks that round-trip to the backend; the backend tests already cover what they call. PR-7 polish can add render-and-click tests if coverage drift surfaces. ## Verification - `pnpm --filter @mcpctl/web build` clean, no warnings. - `pnpm test:run` whole monorepo: 162 test files / 2157 tests green. - Visual smoke deferred — needs a running mcpd to populate the fixtures. Manual smoke tested locally is the next step. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:54:55 +01:00
lucide-react@0.487.0(react@19.2.5):
dependencies:
react: 19.2.5
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
lz-string@1.5.0: {}
2026-02-21 03:10:39 +00:00
magic-string@0.30.21:
dependencies:
'@jridgewell/sourcemap-codec': 1.5.5
magicast@0.5.2:
dependencies:
'@babel/parser': 7.29.0
'@babel/types': 7.29.0
source-map-js: 1.2.1
make-dir@3.1.0:
dependencies:
semver: 6.3.1
2026-02-21 03:10:39 +00:00
make-dir@4.0.0:
dependencies:
semver: 7.7.4
make-fetch-happen@15.0.6:
dependencies:
'@gar/promise-retry': 1.0.3
'@npmcli/agent': 4.0.2
'@npmcli/redact': 4.0.0
cacache: 20.0.4
http-cache-semantics: 4.2.0
minipass: 7.1.3
minipass-fetch: 5.0.2
minipass-flush: 1.0.7
minipass-pipeline: 1.2.4
negotiator: 1.0.0
proc-log: 6.1.0
ssri: 13.0.1
transitivePeerDependencies:
- supports-color
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
marked@14.0.0: {}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
marked@17.0.1: {}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
marked@18.0.5: {}
2026-02-21 03:10:39 +00:00
math-intrinsics@1.1.0: {}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
mdn-data@2.27.1: {}
2026-02-21 03:10:39 +00:00
media-typer@1.1.0: {}
merge-descriptors@2.0.0: {}
merge-stream@2.0.0: {}
mime-db@1.52.0: {}
2026-02-21 03:10:39 +00:00
mime-db@1.54.0: {}
mime-types@2.1.35:
dependencies:
mime-db: 1.52.0
2026-02-21 03:10:39 +00:00
mime-types@3.0.2:
dependencies:
mime-db: 1.54.0
feat(mcpd+deploy): serve web UI at /ui + smoke tests + docs (Stage 6) The closing stage. mcpd now hosts the Stage 5 SPA, the Docker image bundles the build artifact, a smoke test exercises the personality HTTP surface end-to-end, and the user-facing docs spell out the mental model. mcpd: - Add @fastify/static dep. - New routes/web-ui.ts: registers /ui/* against a static bundle. Looks for the bundle at $MCPD_WEB_ROOT, then /usr/share/mcpd/web (the Docker image path), then a dev-tree fallback. Logs and skips cleanly if missing — API-only deploys keep working. - SPA fallback: any /ui/<path> that doesn't match a file falls through to index.html so direct hits to react-router URLs work. - /ui/* falls through to `kind: skip` in mapUrlToPermission, so the static assets are served unauthenticated. Each API call from the SPA still carries the bearer token. Deploy: - Dockerfile.mcpd builds the @mcpctl/web bundle in the same builder stage and copies dist/ to /usr/share/mcpd/web in the runtime image. Smoke (personality.smoke.test.ts): - Live mcpd flow: create secret/llm/agent/personality, attach an agent-direct prompt, verify the binding listing, reject double- attach (409) + foreign-agent prompt (400), set defaultPersonality by name, detach + delete cleanup. Docs: - New docs/personalities.md: VLAN-on-ethernet model, system-block ordering table, three prompt scopes, CLI walkthrough, web UI walkthrough, full API surface, RBAC notes. - agents.md and chat.md cross-link. - README's Agents section gains a Personalities subsection. Test count after Stage 6: mcpd: 801/801 cli: 430/430 web: 7/7 db: 58/62 (4 pre-existing) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:48:43 +01:00
mime@3.0.0: {}
mimic-fn@2.1.0: {}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
min-indent@1.0.1: {}
2026-02-21 03:10:39 +00:00
minimatch@10.2.2:
dependencies:
brace-expansion: 5.0.2
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
minimatch@10.2.5:
dependencies:
brace-expansion: 5.0.9
minimatch@3.1.2:
dependencies:
brace-expansion: 1.1.12
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
minimatch@8.0.7:
dependencies:
brace-expansion: 2.0.2
2026-02-21 03:10:39 +00:00
minimatch@9.0.5:
dependencies:
brace-expansion: 2.0.2
minimist@1.2.8: {}
minipass-collect@2.0.1:
dependencies:
minipass: 7.1.3
minipass-fetch@5.0.2:
dependencies:
minipass: 7.1.3
minipass-sized: 2.0.0
minizlib: 3.1.0
optionalDependencies:
iconv-lite: 0.7.2
minipass-flush@1.0.7:
dependencies:
minipass: 3.3.6
minipass-pipeline@1.2.4:
dependencies:
minipass: 3.3.6
minipass-sized@2.0.0:
dependencies:
minipass: 7.1.3
minipass@3.3.6:
dependencies:
yallist: 4.0.0
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
minipass@4.2.8: {}
minipass@5.0.0: {}
2026-02-21 03:10:39 +00:00
minipass@7.1.3: {}
minizlib@2.1.2:
dependencies:
minipass: 3.3.6
yallist: 4.0.0
minizlib@3.1.0:
dependencies:
minipass: 7.1.3
mkdirp-classic@0.5.3: {}
mkdirp@1.0.4: {}
2026-02-21 03:10:39 +00:00
mnemonist@0.40.0:
dependencies:
obliterator: 2.0.5
module-details-from-path@1.0.4: {}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
monaco-editor@0.55.1:
dependencies:
dompurify: 3.2.7
marked: 14.0.0
2026-02-21 03:10:39 +00:00
ms@2.1.3: {}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
msgpackr-extract@3.0.4:
dependencies:
node-gyp-build-optional-packages: 5.2.2
optionalDependencies:
'@msgpackr-extract/msgpackr-extract-darwin-arm64': 3.0.4
'@msgpackr-extract/msgpackr-extract-darwin-x64': 3.0.4
'@msgpackr-extract/msgpackr-extract-linux-arm': 3.0.4
'@msgpackr-extract/msgpackr-extract-linux-arm64': 3.0.4
'@msgpackr-extract/msgpackr-extract-linux-x64': 3.0.4
'@msgpackr-extract/msgpackr-extract-win32-x64': 3.0.4
optional: true
msgpackr@2.0.5:
optionalDependencies:
msgpackr-extract: 3.0.4
multipasta@0.2.8: {}
2026-02-21 03:10:39 +00:00
mute-stream@2.0.0: {}
nan@2.25.0:
optional: true
2026-02-21 03:10:39 +00:00
nanoid@3.3.11: {}
natural-compare@1.4.0: {}
negotiator@1.0.0: {}
next@16.2.5(@babel/core@7.29.0)(@opentelemetry/api@1.9.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5):
feat(web): bold redesign — Tailwind v4 + shadcn-style primitives + Skills/Proposals/Revisions UI Phase 6 of the Skills + Revisions + Proposals work. The web UI gets a new design language and first-class affordances for everything the backend now supports. ## Visual direction - Tailwind v4 with custom @theme block (oklch tokens). Dark-mode-only (internal tool — light mode doubles QA surface). - Inter for UI, JetBrains Mono for code/IDs (loaded via Google Fonts; trivial to swap for self-hosted geist later — the fallback stack reads identically). - Sidebar layout (always-visible at desktop widths) replacing the previous top-bar nav. Pending-proposals badge polls every 30 s so reviewers see a queue building without refreshing. - Lucide icons throughout. - Spacing and radii on Tailwind defaults. Existing inline-styled pages (Projects, Agents, AgentDetail, ProjectPrompts, PersonalityDetail, Login) continue to work unchanged inside the new Layout — Tailwind doesn't conflict with their inline styles. A follow-up can migrate them incrementally. ## What's added ### Build infra (src/web/) - package.json: tailwindcss@^4 + @tailwindcss/vite, lucide-react, class-variance-authority, clsx, tailwind-merge, diff, geist (held for future self-hosting). - vite.config.ts: registers the @tailwindcss/vite plugin. - src/index.css: Tailwind import + @theme tokens + @layer base. - src/main.tsx: imports index.css. - src/lib/utils.ts: shadcn-style cn() helper. ### shadcn-style primitives (src/components/ui/) Hand-written rather than generated via `npx shadcn` so the repo doesn't depend on a CLI tool that needs interactive runtime: - button.tsx — variants: primary / secondary / ghost / danger / link; sizes: sm / md / lg / icon. - card.tsx — Card + Header/Title/Description/Content/Footer subparts. - badge.tsx — variants: default / info / success / warning / danger / outline. - input.tsx — Input + Textarea + Label. - tabs.tsx — no-dep accessible Tabs (no Radix needed for our use). - separator.tsx — h/v separator with role=separator. ### Diff component (src/components/Diff.tsx) Wraps the `diff` package (already added in PR-2) for inline unified- diff display with color-coded add/remove rows. Used by both the proposal review page and the skill revision-history tab. ### New pages (src/pages/) - Dashboard.tsx — at-a-glance home. Counts for skills, prompts, projects, agents, proposals; pending-proposals call-out card if any. - Skills.tsx — list view, separated into Global vs Project/Agent- scoped sections. - SkillDetail.tsx — name + semver + description; tabs for SKILL.md / Files / Metadata / History. History tab shows revisions with click-to-diff against the live body. - Proposals.tsx — queue with Pending/Approved/Rejected tabs. Pending count is highlighted in amber. - ProposalDetail.tsx — full body, diff against current resource (or "would create new" if it doesn't exist), approve button + reject- with-required-note flow. ### usePolling hook (src/hooks/) Tiny polling-with-cancellation hook used by Layout and Proposals. ### Layout rewrite (src/components/Layout.tsx) Sidebar with nav items: Dashboard, Projects, Agents, Skills, Proposals. Lucide icons. Active-route highlighting via NavLink. Pending-proposals warning badge on the Proposals item. ### Routes (src/App.tsx) New routes: /dashboard, /skills, /skills/:name, /proposals, /proposals/:id. Default redirects to /dashboard. ### API types (src/api.ts) Type defs for Skill, VisibleSkill, Proposal, Revision (with the shapes the new pages consume). ## Tests Existing 7 web tests still pass (Login + api). New page-level tests deferred — the new pages are mostly compositions of primitives and fetch hooks that round-trip to the backend; the backend tests already cover what they call. PR-7 polish can add render-and-click tests if coverage drift surfaces. ## Verification - `pnpm --filter @mcpctl/web build` clean, no warnings. - `pnpm test:run` whole monorepo: 162 test files / 2157 tests green. - Visual smoke deferred — needs a running mcpd to populate the fixtures. Manual smoke tested locally is the next step. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:54:55 +01:00
dependencies:
'@next/env': 16.2.5
'@swc/helpers': 0.5.15
baseline-browser-mapping: 2.10.23
caniuse-lite: 1.0.30001791
postcss: 8.4.31
react: 19.2.5
react-dom: 19.2.5(react@19.2.5)
styled-jsx: 5.1.6(@babel/core@7.29.0)(react@19.2.5)
optionalDependencies:
'@next/swc-darwin-arm64': 16.2.5
'@next/swc-darwin-x64': 16.2.5
'@next/swc-linux-arm64-gnu': 16.2.5
'@next/swc-linux-arm64-musl': 16.2.5
'@next/swc-linux-x64-gnu': 16.2.5
'@next/swc-linux-x64-musl': 16.2.5
'@next/swc-win32-arm64-msvc': 16.2.5
'@next/swc-win32-x64-msvc': 16.2.5
'@opentelemetry/api': 1.9.1
feat(web): bold redesign — Tailwind v4 + shadcn-style primitives + Skills/Proposals/Revisions UI Phase 6 of the Skills + Revisions + Proposals work. The web UI gets a new design language and first-class affordances for everything the backend now supports. ## Visual direction - Tailwind v4 with custom @theme block (oklch tokens). Dark-mode-only (internal tool — light mode doubles QA surface). - Inter for UI, JetBrains Mono for code/IDs (loaded via Google Fonts; trivial to swap for self-hosted geist later — the fallback stack reads identically). - Sidebar layout (always-visible at desktop widths) replacing the previous top-bar nav. Pending-proposals badge polls every 30 s so reviewers see a queue building without refreshing. - Lucide icons throughout. - Spacing and radii on Tailwind defaults. Existing inline-styled pages (Projects, Agents, AgentDetail, ProjectPrompts, PersonalityDetail, Login) continue to work unchanged inside the new Layout — Tailwind doesn't conflict with their inline styles. A follow-up can migrate them incrementally. ## What's added ### Build infra (src/web/) - package.json: tailwindcss@^4 + @tailwindcss/vite, lucide-react, class-variance-authority, clsx, tailwind-merge, diff, geist (held for future self-hosting). - vite.config.ts: registers the @tailwindcss/vite plugin. - src/index.css: Tailwind import + @theme tokens + @layer base. - src/main.tsx: imports index.css. - src/lib/utils.ts: shadcn-style cn() helper. ### shadcn-style primitives (src/components/ui/) Hand-written rather than generated via `npx shadcn` so the repo doesn't depend on a CLI tool that needs interactive runtime: - button.tsx — variants: primary / secondary / ghost / danger / link; sizes: sm / md / lg / icon. - card.tsx — Card + Header/Title/Description/Content/Footer subparts. - badge.tsx — variants: default / info / success / warning / danger / outline. - input.tsx — Input + Textarea + Label. - tabs.tsx — no-dep accessible Tabs (no Radix needed for our use). - separator.tsx — h/v separator with role=separator. ### Diff component (src/components/Diff.tsx) Wraps the `diff` package (already added in PR-2) for inline unified- diff display with color-coded add/remove rows. Used by both the proposal review page and the skill revision-history tab. ### New pages (src/pages/) - Dashboard.tsx — at-a-glance home. Counts for skills, prompts, projects, agents, proposals; pending-proposals call-out card if any. - Skills.tsx — list view, separated into Global vs Project/Agent- scoped sections. - SkillDetail.tsx — name + semver + description; tabs for SKILL.md / Files / Metadata / History. History tab shows revisions with click-to-diff against the live body. - Proposals.tsx — queue with Pending/Approved/Rejected tabs. Pending count is highlighted in amber. - ProposalDetail.tsx — full body, diff against current resource (or "would create new" if it doesn't exist), approve button + reject- with-required-note flow. ### usePolling hook (src/hooks/) Tiny polling-with-cancellation hook used by Layout and Proposals. ### Layout rewrite (src/components/Layout.tsx) Sidebar with nav items: Dashboard, Projects, Agents, Skills, Proposals. Lucide icons. Active-route highlighting via NavLink. Pending-proposals warning badge on the Proposals item. ### Routes (src/App.tsx) New routes: /dashboard, /skills, /skills/:name, /proposals, /proposals/:id. Default redirects to /dashboard. ### API types (src/api.ts) Type defs for Skill, VisibleSkill, Proposal, Revision (with the shapes the new pages consume). ## Tests Existing 7 web tests still pass (Login + api). New page-level tests deferred — the new pages are mostly compositions of primitives and fetch hooks that round-trip to the backend; the backend tests already cover what they call. PR-7 polish can add render-and-click tests if coverage drift surfaces. ## Verification - `pnpm --filter @mcpctl/web build` clean, no warnings. - `pnpm test:run` whole monorepo: 162 test files / 2157 tests green. - Visual smoke deferred — needs a running mcpd to populate the fixtures. Manual smoke tested locally is the next step. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:54:55 +01:00
sharp: 0.34.5
transitivePeerDependencies:
- '@babel/core'
- babel-plugin-macros
node-addon-api@5.1.0: {}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
node-domexception@1.0.0: {}
2026-02-21 03:10:39 +00:00
node-fetch-native@1.6.7: {}
node-fetch@2.7.0:
dependencies:
whatwg-url: 5.0.0
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
node-fetch@3.3.2:
dependencies:
data-uri-to-buffer: 4.0.1
fetch-blob: 3.2.0
formdata-polyfill: 4.0.10
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
node-gyp-build-optional-packages@5.2.2:
dependencies:
detect-libc: 2.1.2
optional: true
node-gyp@12.4.0:
dependencies:
env-paths: 2.2.1
exponential-backoff: 3.1.3
graceful-fs: 4.2.11
nopt: 9.0.0
proc-log: 6.1.0
semver: 7.7.4
tar: 7.5.20
tinyglobby: 0.2.15
undici: 6.27.0
which: 6.0.1
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
node-releases@2.0.38: {}
nopt@5.0.0:
dependencies:
abbrev: 1.1.1
nopt@9.0.0:
dependencies:
abbrev: 4.0.0
normalize-package-data@6.0.2:
dependencies:
hosted-git-info: 7.0.2
semver: 7.7.4
validate-npm-package-license: 3.0.4
npm-bundled@5.0.0:
dependencies:
npm-normalize-package-bin: 5.0.0
npm-install-checks@8.0.0:
dependencies:
semver: 7.7.4
npm-normalize-package-bin@5.0.0: {}
npm-package-arg@13.0.2:
dependencies:
hosted-git-info: 9.0.3
proc-log: 6.1.0
semver: 7.7.4
validate-npm-package-name: 7.0.2
npm-packlist@10.0.4:
dependencies:
ignore-walk: 8.0.0
proc-log: 6.1.0
npm-pick-manifest@11.0.3:
dependencies:
npm-install-checks: 8.0.0
npm-normalize-package-bin: 5.0.0
npm-package-arg: 13.0.2
semver: 7.7.4
npm-registry-fetch@19.1.1:
dependencies:
'@npmcli/redact': 4.0.0
jsonparse: 1.3.1
make-fetch-happen: 15.0.6
minipass: 7.1.3
minipass-fetch: 5.0.2
minizlib: 3.1.0
npm-package-arg: 13.0.2
proc-log: 6.1.0
transitivePeerDependencies:
- supports-color
npm-run-path@4.0.1:
dependencies:
path-key: 3.1.1
npmlog@5.0.1:
dependencies:
are-we-there-yet: 2.0.0
console-control-strings: 1.1.0
gauge: 3.0.2
set-blocking: 2.0.0
2026-02-21 03:10:39 +00:00
nypm@0.6.5:
dependencies:
citty: 0.2.1
pathe: 2.0.3
tinyexec: 1.0.2
oauth4webapi@3.8.5: {}
2026-02-21 03:10:39 +00:00
object-assign@4.1.1: {}
object-inspect@1.13.4: {}
obliterator@2.0.5: {}
obug@2.1.1: {}
ohash@2.0.11: {}
on-exit-leak-free@2.1.2: {}
on-finished@2.4.1:
dependencies:
ee-first: 1.1.1
once@1.4.0:
dependencies:
wrappy: 1.0.2
onetime@5.1.2:
dependencies:
mimic-fn: 2.1.0
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
openai@6.26.0(ws@8.19.0)(zod@3.25.76):
optionalDependencies:
ws: 8.19.0
zod: 3.25.76
openid-client@6.8.2:
dependencies:
jose: 6.1.3
oauth4webapi: 3.8.5
2026-02-21 03:10:39 +00:00
optionator@0.9.4:
dependencies:
deep-is: 0.1.4
fast-levenshtein: 2.0.6
levn: 0.4.1
prelude-ls: 1.2.1
type-check: 0.4.0
word-wrap: 1.2.5
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
p-limit@2.3.0:
dependencies:
p-try: 2.2.0
2026-02-21 03:10:39 +00:00
p-limit@3.1.0:
dependencies:
yocto-queue: 0.1.0
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
p-locate@3.0.0:
dependencies:
p-limit: 2.3.0
2026-02-21 03:10:39 +00:00
p-locate@5.0.0:
dependencies:
p-limit: 3.1.0
p-map@7.0.5: {}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
p-retry@4.6.2:
dependencies:
'@types/retry': 0.12.0
retry: 0.13.1
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
p-try@2.2.0: {}
2026-02-21 03:10:39 +00:00
package-json-from-dist@1.0.1: {}
pacote@21.5.1:
dependencies:
'@gar/promise-retry': 1.0.3
'@npmcli/git': 7.0.2
'@npmcli/installed-package-contents': 4.0.0
'@npmcli/package-json': 7.0.5
'@npmcli/promise-spawn': 9.0.1
'@npmcli/run-script': 10.0.4
cacache: 20.0.4
fs-minipass: 3.0.3
minipass: 7.1.3
npm-package-arg: 13.0.2
npm-packlist: 10.0.4
npm-pick-manifest: 11.0.3
npm-registry-fetch: 19.1.1
proc-log: 6.1.0
sigstore: 4.1.1
ssri: 13.0.1
tar: 7.5.20
transitivePeerDependencies:
- supports-color
parse-conflict-json@5.0.1:
dependencies:
json-parse-even-better-errors: 5.0.0
just-diff: 6.0.2
just-diff-apply: 5.5.0
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
parse5@7.3.0:
dependencies:
entities: 6.0.1
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
parse5@8.0.1:
dependencies:
entities: 8.0.0
2026-02-21 03:10:39 +00:00
parseurl@1.3.3: {}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
partial-json@0.1.7: {}
patch-console@2.0.0: {}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
path-exists@3.0.0: {}
2026-02-21 03:10:39 +00:00
path-exists@4.0.0: {}
path-is-absolute@1.0.1: {}
2026-02-21 03:10:39 +00:00
path-key@3.1.1: {}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
path-parse@1.0.7: {}
path-scurry@1.11.1:
dependencies:
lru-cache: 10.4.3
minipass: 7.1.3
2026-02-21 03:10:39 +00:00
path-scurry@2.0.2:
dependencies:
lru-cache: 11.2.6
minipass: 7.1.3
path-to-regexp@8.3.0: {}
pathe@2.0.3: {}
perfect-debounce@1.0.0: {}
picocolors@1.1.1: {}
picomatch@4.0.3: {}
pino-abstract-transport@3.0.0:
dependencies:
split2: 4.2.0
pino-std-serializers@7.1.0: {}
pino@10.3.1:
dependencies:
'@pinojs/redact': 0.4.0
atomic-sleep: 1.0.0
on-exit-leak-free: 2.1.2
pino-abstract-transport: 3.0.0
pino-std-serializers: 7.1.0
process-warning: 5.0.0
quick-format-unescaped: 4.0.4
real-require: 0.2.0
safe-stable-stringify: 2.5.0
sonic-boom: 4.2.1
thread-stream: 4.0.0
pkce-challenge@5.0.1: {}
pkg-types@2.3.0:
dependencies:
confbox: 0.2.4
exsolve: 1.0.8
pathe: 2.0.3
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
pkg-up@3.1.0:
dependencies:
find-up: 3.0.0
postcss-selector-parser@7.1.4:
dependencies:
cssesc: 3.0.0
util-deprecate: 1.0.2
feat(web): bold redesign — Tailwind v4 + shadcn-style primitives + Skills/Proposals/Revisions UI Phase 6 of the Skills + Revisions + Proposals work. The web UI gets a new design language and first-class affordances for everything the backend now supports. ## Visual direction - Tailwind v4 with custom @theme block (oklch tokens). Dark-mode-only (internal tool — light mode doubles QA surface). - Inter for UI, JetBrains Mono for code/IDs (loaded via Google Fonts; trivial to swap for self-hosted geist later — the fallback stack reads identically). - Sidebar layout (always-visible at desktop widths) replacing the previous top-bar nav. Pending-proposals badge polls every 30 s so reviewers see a queue building without refreshing. - Lucide icons throughout. - Spacing and radii on Tailwind defaults. Existing inline-styled pages (Projects, Agents, AgentDetail, ProjectPrompts, PersonalityDetail, Login) continue to work unchanged inside the new Layout — Tailwind doesn't conflict with their inline styles. A follow-up can migrate them incrementally. ## What's added ### Build infra (src/web/) - package.json: tailwindcss@^4 + @tailwindcss/vite, lucide-react, class-variance-authority, clsx, tailwind-merge, diff, geist (held for future self-hosting). - vite.config.ts: registers the @tailwindcss/vite plugin. - src/index.css: Tailwind import + @theme tokens + @layer base. - src/main.tsx: imports index.css. - src/lib/utils.ts: shadcn-style cn() helper. ### shadcn-style primitives (src/components/ui/) Hand-written rather than generated via `npx shadcn` so the repo doesn't depend on a CLI tool that needs interactive runtime: - button.tsx — variants: primary / secondary / ghost / danger / link; sizes: sm / md / lg / icon. - card.tsx — Card + Header/Title/Description/Content/Footer subparts. - badge.tsx — variants: default / info / success / warning / danger / outline. - input.tsx — Input + Textarea + Label. - tabs.tsx — no-dep accessible Tabs (no Radix needed for our use). - separator.tsx — h/v separator with role=separator. ### Diff component (src/components/Diff.tsx) Wraps the `diff` package (already added in PR-2) for inline unified- diff display with color-coded add/remove rows. Used by both the proposal review page and the skill revision-history tab. ### New pages (src/pages/) - Dashboard.tsx — at-a-glance home. Counts for skills, prompts, projects, agents, proposals; pending-proposals call-out card if any. - Skills.tsx — list view, separated into Global vs Project/Agent- scoped sections. - SkillDetail.tsx — name + semver + description; tabs for SKILL.md / Files / Metadata / History. History tab shows revisions with click-to-diff against the live body. - Proposals.tsx — queue with Pending/Approved/Rejected tabs. Pending count is highlighted in amber. - ProposalDetail.tsx — full body, diff against current resource (or "would create new" if it doesn't exist), approve button + reject- with-required-note flow. ### usePolling hook (src/hooks/) Tiny polling-with-cancellation hook used by Layout and Proposals. ### Layout rewrite (src/components/Layout.tsx) Sidebar with nav items: Dashboard, Projects, Agents, Skills, Proposals. Lucide icons. Active-route highlighting via NavLink. Pending-proposals warning badge on the Proposals item. ### Routes (src/App.tsx) New routes: /dashboard, /skills, /skills/:name, /proposals, /proposals/:id. Default redirects to /dashboard. ### API types (src/api.ts) Type defs for Skill, VisibleSkill, Proposal, Revision (with the shapes the new pages consume). ## Tests Existing 7 web tests still pass (Login + api). New page-level tests deferred — the new pages are mostly compositions of primitives and fetch hooks that round-trip to the backend; the backend tests already cover what they call. PR-7 polish can add render-and-click tests if coverage drift surfaces. ## Verification - `pnpm --filter @mcpctl/web build` clean, no warnings. - `pnpm test:run` whole monorepo: 162 test files / 2157 tests green. - Visual smoke deferred — needs a running mcpd to populate the fixtures. Manual smoke tested locally is the next step. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:54:55 +01:00
postcss@8.4.31:
dependencies:
nanoid: 3.3.11
picocolors: 1.1.1
source-map-js: 1.2.1
2026-02-21 03:10:39 +00:00
postcss@8.5.6:
dependencies:
nanoid: 3.3.11
picocolors: 1.1.1
source-map-js: 1.2.1
prelude-ls@1.2.1: {}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
pretty-format@27.5.1:
dependencies:
ansi-regex: 5.0.1
ansi-styles: 5.2.0
react-is: 17.0.2
2026-02-21 03:10:39 +00:00
prisma@6.19.2(typescript@5.9.3):
dependencies:
'@prisma/config': 6.19.2
'@prisma/engines': 6.19.2
optionalDependencies:
typescript: 5.9.3
transitivePeerDependencies:
- magicast
proc-log@6.1.0: {}
2026-02-21 03:10:39 +00:00
process-warning@4.0.1: {}
process-warning@5.0.0: {}
proggy@4.0.0: {}
promise-all-reject-late@1.0.1: {}
promise-call-limit@3.0.2: {}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
proper-lockfile@4.1.2:
dependencies:
graceful-fs: 4.2.11
retry: 0.12.0
signal-exit: 3.0.7
protobufjs@7.5.4:
dependencies:
'@protobufjs/aspromise': 1.1.2
'@protobufjs/base64': 1.1.2
'@protobufjs/codegen': 2.0.4
'@protobufjs/eventemitter': 1.1.0
'@protobufjs/fetch': 1.1.0
'@protobufjs/float': 1.0.2
'@protobufjs/inquire': 1.1.0
'@protobufjs/path': 1.1.2
'@protobufjs/pool': 1.1.0
'@protobufjs/utf8': 1.1.0
'@types/node': 25.3.0
long: 5.3.2
2026-02-21 03:10:39 +00:00
proxy-addr@2.0.7:
dependencies:
forwarded: 0.2.0
ipaddr.js: 1.9.1
pump@3.0.3:
dependencies:
end-of-stream: 1.4.5
once: 1.4.0
2026-02-21 03:10:39 +00:00
punycode@2.3.1: {}
pure-rand@6.1.0: {}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
pure-rand@8.4.2: {}
2026-02-21 03:10:39 +00:00
qs@6.15.0:
dependencies:
side-channel: 1.1.0
quick-format-unescaped@4.0.4: {}
range-parser@1.2.1: {}
raw-body@3.0.2:
dependencies:
bytes: 3.1.2
http-errors: 2.0.1
iconv-lite: 0.7.2
unpipe: 1.0.0
rc9@2.1.2:
dependencies:
defu: 6.1.4
destr: 2.0.5
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
react-dom@19.2.5(react@19.2.5):
dependencies:
react: 19.2.5
scheduler: 0.27.0
react-is@17.0.2: {}
react-reconciler@0.33.0(react@19.2.4):
dependencies:
react: 19.2.4
scheduler: 0.27.0
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
react-refresh@0.18.0: {}
react-router-dom@7.14.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5):
dependencies:
react: 19.2.5
react-dom: 19.2.5(react@19.2.5)
react-router: 7.14.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
react-router@7.14.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5):
dependencies:
cookie: 1.1.1
react: 19.2.5
set-cookie-parser: 2.7.2
optionalDependencies:
react-dom: 19.2.5(react@19.2.5)
react@19.2.4: {}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
react@19.2.5: {}
read-cmd-shim@6.0.0: {}
readable-stream@3.6.2:
dependencies:
inherits: 2.0.4
string_decoder: 1.3.0
util-deprecate: 1.0.2
2026-02-21 03:10:39 +00:00
readdirp@4.1.2: {}
real-require@0.2.0: {}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
redent@3.0.0:
dependencies:
indent-string: 4.0.0
strip-indent: 3.0.0
require-directory@2.1.1: {}
2026-02-21 03:10:39 +00:00
require-from-string@2.0.2: {}
require-in-the-middle@8.0.1:
dependencies:
debug: 4.4.3
module-details-from-path: 1.0.4
transitivePeerDependencies:
- supports-color
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
reselect@4.1.8: {}
2026-02-21 03:10:39 +00:00
resolve-pkg-maps@1.0.0: {}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
resolve@1.22.12:
dependencies:
es-errors: 1.3.0
is-core-module: 2.16.2
path-parse: 1.0.7
supports-preserve-symlinks-flag: 1.0.0
restore-cursor@4.0.0:
dependencies:
onetime: 5.1.2
signal-exit: 3.0.7
2026-02-21 03:10:39 +00:00
ret@0.5.0: {}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
retry@0.12.0: {}
retry@0.13.1: {}
2026-02-21 03:10:39 +00:00
reusify@1.1.0: {}
rfc4648@1.5.4: {}
2026-02-21 03:10:39 +00:00
rfdc@1.4.1: {}
rimraf@3.0.2:
dependencies:
glob: 7.2.3
2026-02-21 03:10:39 +00:00
rimraf@6.1.3:
dependencies:
glob: 13.0.6
package-json-from-dist: 1.0.1
rollup@4.58.0:
dependencies:
'@types/estree': 1.0.8
optionalDependencies:
'@rollup/rollup-android-arm-eabi': 4.58.0
'@rollup/rollup-android-arm64': 4.58.0
'@rollup/rollup-darwin-arm64': 4.58.0
'@rollup/rollup-darwin-x64': 4.58.0
'@rollup/rollup-freebsd-arm64': 4.58.0
'@rollup/rollup-freebsd-x64': 4.58.0
'@rollup/rollup-linux-arm-gnueabihf': 4.58.0
'@rollup/rollup-linux-arm-musleabihf': 4.58.0
'@rollup/rollup-linux-arm64-gnu': 4.58.0
'@rollup/rollup-linux-arm64-musl': 4.58.0
'@rollup/rollup-linux-loong64-gnu': 4.58.0
'@rollup/rollup-linux-loong64-musl': 4.58.0
'@rollup/rollup-linux-ppc64-gnu': 4.58.0
'@rollup/rollup-linux-ppc64-musl': 4.58.0
'@rollup/rollup-linux-riscv64-gnu': 4.58.0
'@rollup/rollup-linux-riscv64-musl': 4.58.0
'@rollup/rollup-linux-s390x-gnu': 4.58.0
'@rollup/rollup-linux-x64-gnu': 4.58.0
'@rollup/rollup-linux-x64-musl': 4.58.0
'@rollup/rollup-openbsd-x64': 4.58.0
'@rollup/rollup-openharmony-arm64': 4.58.0
'@rollup/rollup-win32-arm64-msvc': 4.58.0
'@rollup/rollup-win32-ia32-msvc': 4.58.0
'@rollup/rollup-win32-x64-gnu': 4.58.0
'@rollup/rollup-win32-x64-msvc': 4.58.0
fsevents: 2.3.3
router@2.2.0:
dependencies:
debug: 4.4.3
depd: 2.0.0
is-promise: 4.0.0
parseurl: 1.3.3
path-to-regexp: 8.3.0
transitivePeerDependencies:
- supports-color
run-async@4.0.6: {}
rxjs@7.8.2:
dependencies:
tslib: 2.8.1
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
s-js@0.4.9: {}
safe-buffer@5.2.1: {}
2026-02-21 03:10:39 +00:00
safe-regex2@5.0.0:
dependencies:
ret: 0.5.0
safe-stable-stringify@2.5.0: {}
safer-buffer@2.1.2: {}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
saxes@6.0.0:
dependencies:
xmlchars: 2.2.0
scheduler@0.27.0: {}
2026-02-21 03:10:39 +00:00
secure-json-parse@4.1.0: {}
semver@6.3.1: {}
2026-02-21 03:10:39 +00:00
semver@7.7.4: {}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
semver@7.8.0: {}
2026-02-21 03:10:39 +00:00
send@1.2.1:
dependencies:
debug: 4.4.3
encodeurl: 2.0.0
escape-html: 1.0.3
etag: 1.8.1
fresh: 2.0.0
http-errors: 2.0.1
mime-types: 3.0.2
ms: 2.1.3
on-finished: 2.4.1
range-parser: 1.2.1
statuses: 2.0.2
transitivePeerDependencies:
- supports-color
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
seroval-plugins@1.5.6(seroval@1.5.6):
dependencies:
seroval: 1.5.6
seroval@1.5.6: {}
2026-02-21 03:10:39 +00:00
serve-static@2.2.1:
dependencies:
encodeurl: 2.0.0
escape-html: 1.0.3
parseurl: 1.3.3
send: 1.2.1
transitivePeerDependencies:
- supports-color
set-blocking@2.0.0: {}
2026-02-21 03:10:39 +00:00
set-cookie-parser@2.7.2: {}
setprototypeof@1.2.0: {}
feat(web): bold redesign — Tailwind v4 + shadcn-style primitives + Skills/Proposals/Revisions UI Phase 6 of the Skills + Revisions + Proposals work. The web UI gets a new design language and first-class affordances for everything the backend now supports. ## Visual direction - Tailwind v4 with custom @theme block (oklch tokens). Dark-mode-only (internal tool — light mode doubles QA surface). - Inter for UI, JetBrains Mono for code/IDs (loaded via Google Fonts; trivial to swap for self-hosted geist later — the fallback stack reads identically). - Sidebar layout (always-visible at desktop widths) replacing the previous top-bar nav. Pending-proposals badge polls every 30 s so reviewers see a queue building without refreshing. - Lucide icons throughout. - Spacing and radii on Tailwind defaults. Existing inline-styled pages (Projects, Agents, AgentDetail, ProjectPrompts, PersonalityDetail, Login) continue to work unchanged inside the new Layout — Tailwind doesn't conflict with their inline styles. A follow-up can migrate them incrementally. ## What's added ### Build infra (src/web/) - package.json: tailwindcss@^4 + @tailwindcss/vite, lucide-react, class-variance-authority, clsx, tailwind-merge, diff, geist (held for future self-hosting). - vite.config.ts: registers the @tailwindcss/vite plugin. - src/index.css: Tailwind import + @theme tokens + @layer base. - src/main.tsx: imports index.css. - src/lib/utils.ts: shadcn-style cn() helper. ### shadcn-style primitives (src/components/ui/) Hand-written rather than generated via `npx shadcn` so the repo doesn't depend on a CLI tool that needs interactive runtime: - button.tsx — variants: primary / secondary / ghost / danger / link; sizes: sm / md / lg / icon. - card.tsx — Card + Header/Title/Description/Content/Footer subparts. - badge.tsx — variants: default / info / success / warning / danger / outline. - input.tsx — Input + Textarea + Label. - tabs.tsx — no-dep accessible Tabs (no Radix needed for our use). - separator.tsx — h/v separator with role=separator. ### Diff component (src/components/Diff.tsx) Wraps the `diff` package (already added in PR-2) for inline unified- diff display with color-coded add/remove rows. Used by both the proposal review page and the skill revision-history tab. ### New pages (src/pages/) - Dashboard.tsx — at-a-glance home. Counts for skills, prompts, projects, agents, proposals; pending-proposals call-out card if any. - Skills.tsx — list view, separated into Global vs Project/Agent- scoped sections. - SkillDetail.tsx — name + semver + description; tabs for SKILL.md / Files / Metadata / History. History tab shows revisions with click-to-diff against the live body. - Proposals.tsx — queue with Pending/Approved/Rejected tabs. Pending count is highlighted in amber. - ProposalDetail.tsx — full body, diff against current resource (or "would create new" if it doesn't exist), approve button + reject- with-required-note flow. ### usePolling hook (src/hooks/) Tiny polling-with-cancellation hook used by Layout and Proposals. ### Layout rewrite (src/components/Layout.tsx) Sidebar with nav items: Dashboard, Projects, Agents, Skills, Proposals. Lucide icons. Active-route highlighting via NavLink. Pending-proposals warning badge on the Proposals item. ### Routes (src/App.tsx) New routes: /dashboard, /skills, /skills/:name, /proposals, /proposals/:id. Default redirects to /dashboard. ### API types (src/api.ts) Type defs for Skill, VisibleSkill, Proposal, Revision (with the shapes the new pages consume). ## Tests Existing 7 web tests still pass (Login + api). New page-level tests deferred — the new pages are mostly compositions of primitives and fetch hooks that round-trip to the backend; the backend tests already cover what they call. PR-7 polish can add render-and-click tests if coverage drift surfaces. ## Verification - `pnpm --filter @mcpctl/web build` clean, no warnings. - `pnpm test:run` whole monorepo: 162 test files / 2157 tests green. - Visual smoke deferred — needs a running mcpd to populate the fixtures. Manual smoke tested locally is the next step. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:54:55 +01:00
sharp@0.34.5:
dependencies:
'@img/colour': 1.1.0
detect-libc: 2.1.2
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
semver: 7.8.0
feat(web): bold redesign — Tailwind v4 + shadcn-style primitives + Skills/Proposals/Revisions UI Phase 6 of the Skills + Revisions + Proposals work. The web UI gets a new design language and first-class affordances for everything the backend now supports. ## Visual direction - Tailwind v4 with custom @theme block (oklch tokens). Dark-mode-only (internal tool — light mode doubles QA surface). - Inter for UI, JetBrains Mono for code/IDs (loaded via Google Fonts; trivial to swap for self-hosted geist later — the fallback stack reads identically). - Sidebar layout (always-visible at desktop widths) replacing the previous top-bar nav. Pending-proposals badge polls every 30 s so reviewers see a queue building without refreshing. - Lucide icons throughout. - Spacing and radii on Tailwind defaults. Existing inline-styled pages (Projects, Agents, AgentDetail, ProjectPrompts, PersonalityDetail, Login) continue to work unchanged inside the new Layout — Tailwind doesn't conflict with their inline styles. A follow-up can migrate them incrementally. ## What's added ### Build infra (src/web/) - package.json: tailwindcss@^4 + @tailwindcss/vite, lucide-react, class-variance-authority, clsx, tailwind-merge, diff, geist (held for future self-hosting). - vite.config.ts: registers the @tailwindcss/vite plugin. - src/index.css: Tailwind import + @theme tokens + @layer base. - src/main.tsx: imports index.css. - src/lib/utils.ts: shadcn-style cn() helper. ### shadcn-style primitives (src/components/ui/) Hand-written rather than generated via `npx shadcn` so the repo doesn't depend on a CLI tool that needs interactive runtime: - button.tsx — variants: primary / secondary / ghost / danger / link; sizes: sm / md / lg / icon. - card.tsx — Card + Header/Title/Description/Content/Footer subparts. - badge.tsx — variants: default / info / success / warning / danger / outline. - input.tsx — Input + Textarea + Label. - tabs.tsx — no-dep accessible Tabs (no Radix needed for our use). - separator.tsx — h/v separator with role=separator. ### Diff component (src/components/Diff.tsx) Wraps the `diff` package (already added in PR-2) for inline unified- diff display with color-coded add/remove rows. Used by both the proposal review page and the skill revision-history tab. ### New pages (src/pages/) - Dashboard.tsx — at-a-glance home. Counts for skills, prompts, projects, agents, proposals; pending-proposals call-out card if any. - Skills.tsx — list view, separated into Global vs Project/Agent- scoped sections. - SkillDetail.tsx — name + semver + description; tabs for SKILL.md / Files / Metadata / History. History tab shows revisions with click-to-diff against the live body. - Proposals.tsx — queue with Pending/Approved/Rejected tabs. Pending count is highlighted in amber. - ProposalDetail.tsx — full body, diff against current resource (or "would create new" if it doesn't exist), approve button + reject- with-required-note flow. ### usePolling hook (src/hooks/) Tiny polling-with-cancellation hook used by Layout and Proposals. ### Layout rewrite (src/components/Layout.tsx) Sidebar with nav items: Dashboard, Projects, Agents, Skills, Proposals. Lucide icons. Active-route highlighting via NavLink. Pending-proposals warning badge on the Proposals item. ### Routes (src/App.tsx) New routes: /dashboard, /skills, /skills/:name, /proposals, /proposals/:id. Default redirects to /dashboard. ### API types (src/api.ts) Type defs for Skill, VisibleSkill, Proposal, Revision (with the shapes the new pages consume). ## Tests Existing 7 web tests still pass (Login + api). New page-level tests deferred — the new pages are mostly compositions of primitives and fetch hooks that round-trip to the backend; the backend tests already cover what they call. PR-7 polish can add render-and-click tests if coverage drift surfaces. ## Verification - `pnpm --filter @mcpctl/web build` clean, no warnings. - `pnpm test:run` whole monorepo: 162 test files / 2157 tests green. - Visual smoke deferred — needs a running mcpd to populate the fixtures. Manual smoke tested locally is the next step. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:54:55 +01:00
optionalDependencies:
'@img/sharp-darwin-arm64': 0.34.5
'@img/sharp-darwin-x64': 0.34.5
'@img/sharp-libvips-darwin-arm64': 1.2.4
'@img/sharp-libvips-darwin-x64': 1.2.4
'@img/sharp-libvips-linux-arm': 1.2.4
'@img/sharp-libvips-linux-arm64': 1.2.4
'@img/sharp-libvips-linux-ppc64': 1.2.4
'@img/sharp-libvips-linux-riscv64': 1.2.4
'@img/sharp-libvips-linux-s390x': 1.2.4
'@img/sharp-libvips-linux-x64': 1.2.4
'@img/sharp-libvips-linuxmusl-arm64': 1.2.4
'@img/sharp-libvips-linuxmusl-x64': 1.2.4
'@img/sharp-linux-arm': 0.34.5
'@img/sharp-linux-arm64': 0.34.5
'@img/sharp-linux-ppc64': 0.34.5
'@img/sharp-linux-riscv64': 0.34.5
'@img/sharp-linux-s390x': 0.34.5
'@img/sharp-linux-x64': 0.34.5
'@img/sharp-linuxmusl-arm64': 0.34.5
'@img/sharp-linuxmusl-x64': 0.34.5
'@img/sharp-wasm32': 0.34.5
'@img/sharp-win32-arm64': 0.34.5
'@img/sharp-win32-ia32': 0.34.5
'@img/sharp-win32-x64': 0.34.5
optional: true
2026-02-21 03:10:39 +00:00
shebang-command@2.0.0:
dependencies:
shebang-regex: 3.0.0
shebang-regex@3.0.0: {}
side-channel-list@1.0.0:
dependencies:
es-errors: 1.3.0
object-inspect: 1.13.4
side-channel-map@1.0.1:
dependencies:
call-bound: 1.0.4
es-errors: 1.3.0
get-intrinsic: 1.3.0
object-inspect: 1.13.4
side-channel-weakmap@1.0.2:
dependencies:
call-bound: 1.0.4
es-errors: 1.3.0
get-intrinsic: 1.3.0
object-inspect: 1.13.4
side-channel-map: 1.0.1
side-channel@1.1.0:
dependencies:
es-errors: 1.3.0
object-inspect: 1.13.4
side-channel-list: 1.0.0
side-channel-map: 1.0.1
side-channel-weakmap: 1.0.2
siginfo@2.0.0: {}
signal-exit@3.0.7: {}
2026-02-21 03:10:39 +00:00
signal-exit@4.1.0: {}
sigstore@4.1.1:
dependencies:
'@sigstore/bundle': 4.0.0
'@sigstore/core': 3.2.1
'@sigstore/protobuf-specs': 0.5.1
'@sigstore/sign': 4.1.1
'@sigstore/tuf': 4.0.2
'@sigstore/verify': 3.1.1
transitivePeerDependencies:
- supports-color
slice-ansi@7.1.2:
dependencies:
ansi-styles: 6.2.3
is-fullwidth-code-point: 5.1.0
slice-ansi@8.0.0:
dependencies:
ansi-styles: 6.2.3
is-fullwidth-code-point: 5.1.0
smart-buffer@4.2.0: {}
socks-proxy-agent@8.0.5:
dependencies:
agent-base: 7.1.4
debug: 4.4.3
socks: 2.8.7
transitivePeerDependencies:
- supports-color
socks@2.8.7:
dependencies:
ip-address: 10.0.1
smart-buffer: 4.2.0
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
solid-js@1.9.12:
dependencies:
csstype: 3.2.3
seroval: 1.5.6
seroval-plugins: 1.5.6(seroval@1.5.6)
2026-02-21 03:10:39 +00:00
sonic-boom@4.2.1:
dependencies:
atomic-sleep: 1.0.0
source-map-js@1.2.1: {}
source-map-support@0.5.21:
dependencies:
buffer-from: 1.1.2
source-map: 0.6.1
source-map@0.6.1: {}
spdx-correct@3.2.0:
dependencies:
spdx-expression-parse: 3.0.1
spdx-license-ids: 3.0.23
spdx-exceptions@2.5.0: {}
spdx-expression-parse@3.0.1:
dependencies:
spdx-exceptions: 2.5.0
spdx-license-ids: 3.0.23
spdx-expression-parse@4.0.0:
dependencies:
spdx-exceptions: 2.5.0
spdx-license-ids: 3.0.23
spdx-license-ids@3.0.23: {}
split-ca@1.0.1: {}
2026-02-21 03:10:39 +00:00
split2@4.2.0: {}
ssh2@1.17.0:
dependencies:
asn1: 0.2.6
bcrypt-pbkdf: 1.0.2
optionalDependencies:
cpu-features: 0.0.10
nan: 2.25.0
ssri@13.0.1:
dependencies:
minipass: 7.1.3
stack-utils@2.0.6:
dependencies:
escape-string-regexp: 2.0.0
2026-02-21 03:10:39 +00:00
stackback@0.0.2: {}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
state-local@1.0.7: {}
2026-02-21 03:10:39 +00:00
statuses@2.0.2: {}
std-env@3.10.0: {}
stream-buffers@3.0.3: {}
streamx@2.25.0:
dependencies:
events-universal: 1.0.1
fast-fifo: 1.3.2
text-decoder: 1.2.7
transitivePeerDependencies:
- bare-abort-controller
- react-native-b4a
2026-02-21 03:10:39 +00:00
string-width@4.2.3:
dependencies:
emoji-regex: 8.0.0
is-fullwidth-code-point: 3.0.0
strip-ansi: 6.0.1
string-width@7.2.0:
dependencies:
emoji-regex: 10.6.0
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
get-east-asian-width: 1.6.0
strip-ansi: 7.1.2
string-width@8.2.0:
dependencies:
get-east-asian-width: 1.5.0
strip-ansi: 7.1.2
string_decoder@1.3.0:
dependencies:
safe-buffer: 5.2.1
2026-02-21 03:10:39 +00:00
strip-ansi@6.0.1:
dependencies:
ansi-regex: 5.0.1
strip-ansi@7.1.2:
dependencies:
ansi-regex: 6.2.2
strip-final-newline@2.0.0: {}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
strip-indent@3.0.0:
dependencies:
min-indent: 1.0.1
feat(web): bold redesign — Tailwind v4 + shadcn-style primitives + Skills/Proposals/Revisions UI Phase 6 of the Skills + Revisions + Proposals work. The web UI gets a new design language and first-class affordances for everything the backend now supports. ## Visual direction - Tailwind v4 with custom @theme block (oklch tokens). Dark-mode-only (internal tool — light mode doubles QA surface). - Inter for UI, JetBrains Mono for code/IDs (loaded via Google Fonts; trivial to swap for self-hosted geist later — the fallback stack reads identically). - Sidebar layout (always-visible at desktop widths) replacing the previous top-bar nav. Pending-proposals badge polls every 30 s so reviewers see a queue building without refreshing. - Lucide icons throughout. - Spacing and radii on Tailwind defaults. Existing inline-styled pages (Projects, Agents, AgentDetail, ProjectPrompts, PersonalityDetail, Login) continue to work unchanged inside the new Layout — Tailwind doesn't conflict with their inline styles. A follow-up can migrate them incrementally. ## What's added ### Build infra (src/web/) - package.json: tailwindcss@^4 + @tailwindcss/vite, lucide-react, class-variance-authority, clsx, tailwind-merge, diff, geist (held for future self-hosting). - vite.config.ts: registers the @tailwindcss/vite plugin. - src/index.css: Tailwind import + @theme tokens + @layer base. - src/main.tsx: imports index.css. - src/lib/utils.ts: shadcn-style cn() helper. ### shadcn-style primitives (src/components/ui/) Hand-written rather than generated via `npx shadcn` so the repo doesn't depend on a CLI tool that needs interactive runtime: - button.tsx — variants: primary / secondary / ghost / danger / link; sizes: sm / md / lg / icon. - card.tsx — Card + Header/Title/Description/Content/Footer subparts. - badge.tsx — variants: default / info / success / warning / danger / outline. - input.tsx — Input + Textarea + Label. - tabs.tsx — no-dep accessible Tabs (no Radix needed for our use). - separator.tsx — h/v separator with role=separator. ### Diff component (src/components/Diff.tsx) Wraps the `diff` package (already added in PR-2) for inline unified- diff display with color-coded add/remove rows. Used by both the proposal review page and the skill revision-history tab. ### New pages (src/pages/) - Dashboard.tsx — at-a-glance home. Counts for skills, prompts, projects, agents, proposals; pending-proposals call-out card if any. - Skills.tsx — list view, separated into Global vs Project/Agent- scoped sections. - SkillDetail.tsx — name + semver + description; tabs for SKILL.md / Files / Metadata / History. History tab shows revisions with click-to-diff against the live body. - Proposals.tsx — queue with Pending/Approved/Rejected tabs. Pending count is highlighted in amber. - ProposalDetail.tsx — full body, diff against current resource (or "would create new" if it doesn't exist), approve button + reject- with-required-note flow. ### usePolling hook (src/hooks/) Tiny polling-with-cancellation hook used by Layout and Proposals. ### Layout rewrite (src/components/Layout.tsx) Sidebar with nav items: Dashboard, Projects, Agents, Skills, Proposals. Lucide icons. Active-route highlighting via NavLink. Pending-proposals warning badge on the Proposals item. ### Routes (src/App.tsx) New routes: /dashboard, /skills, /skills/:name, /proposals, /proposals/:id. Default redirects to /dashboard. ### API types (src/api.ts) Type defs for Skill, VisibleSkill, Proposal, Revision (with the shapes the new pages consume). ## Tests Existing 7 web tests still pass (Login + api). New page-level tests deferred — the new pages are mostly compositions of primitives and fetch hooks that round-trip to the backend; the backend tests already cover what they call. PR-7 polish can add render-and-click tests if coverage drift surfaces. ## Verification - `pnpm --filter @mcpctl/web build` clean, no warnings. - `pnpm test:run` whole monorepo: 162 test files / 2157 tests green. - Visual smoke deferred — needs a running mcpd to populate the fixtures. Manual smoke tested locally is the next step. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:54:55 +01:00
styled-jsx@5.1.6(@babel/core@7.29.0)(react@19.2.5):
dependencies:
client-only: 0.0.1
react: 19.2.5
optionalDependencies:
'@babel/core': 7.29.0
2026-02-21 03:10:39 +00:00
supports-color@7.2.0:
dependencies:
has-flag: 4.0.0
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
supports-preserve-symlinks-flag@1.0.0: {}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
symbol-tree@3.2.4: {}
tagged-tag@1.0.0: {}
feat(web): bold redesign — Tailwind v4 + shadcn-style primitives + Skills/Proposals/Revisions UI Phase 6 of the Skills + Revisions + Proposals work. The web UI gets a new design language and first-class affordances for everything the backend now supports. ## Visual direction - Tailwind v4 with custom @theme block (oklch tokens). Dark-mode-only (internal tool — light mode doubles QA surface). - Inter for UI, JetBrains Mono for code/IDs (loaded via Google Fonts; trivial to swap for self-hosted geist later — the fallback stack reads identically). - Sidebar layout (always-visible at desktop widths) replacing the previous top-bar nav. Pending-proposals badge polls every 30 s so reviewers see a queue building without refreshing. - Lucide icons throughout. - Spacing and radii on Tailwind defaults. Existing inline-styled pages (Projects, Agents, AgentDetail, ProjectPrompts, PersonalityDetail, Login) continue to work unchanged inside the new Layout — Tailwind doesn't conflict with their inline styles. A follow-up can migrate them incrementally. ## What's added ### Build infra (src/web/) - package.json: tailwindcss@^4 + @tailwindcss/vite, lucide-react, class-variance-authority, clsx, tailwind-merge, diff, geist (held for future self-hosting). - vite.config.ts: registers the @tailwindcss/vite plugin. - src/index.css: Tailwind import + @theme tokens + @layer base. - src/main.tsx: imports index.css. - src/lib/utils.ts: shadcn-style cn() helper. ### shadcn-style primitives (src/components/ui/) Hand-written rather than generated via `npx shadcn` so the repo doesn't depend on a CLI tool that needs interactive runtime: - button.tsx — variants: primary / secondary / ghost / danger / link; sizes: sm / md / lg / icon. - card.tsx — Card + Header/Title/Description/Content/Footer subparts. - badge.tsx — variants: default / info / success / warning / danger / outline. - input.tsx — Input + Textarea + Label. - tabs.tsx — no-dep accessible Tabs (no Radix needed for our use). - separator.tsx — h/v separator with role=separator. ### Diff component (src/components/Diff.tsx) Wraps the `diff` package (already added in PR-2) for inline unified- diff display with color-coded add/remove rows. Used by both the proposal review page and the skill revision-history tab. ### New pages (src/pages/) - Dashboard.tsx — at-a-glance home. Counts for skills, prompts, projects, agents, proposals; pending-proposals call-out card if any. - Skills.tsx — list view, separated into Global vs Project/Agent- scoped sections. - SkillDetail.tsx — name + semver + description; tabs for SKILL.md / Files / Metadata / History. History tab shows revisions with click-to-diff against the live body. - Proposals.tsx — queue with Pending/Approved/Rejected tabs. Pending count is highlighted in amber. - ProposalDetail.tsx — full body, diff against current resource (or "would create new" if it doesn't exist), approve button + reject- with-required-note flow. ### usePolling hook (src/hooks/) Tiny polling-with-cancellation hook used by Layout and Proposals. ### Layout rewrite (src/components/Layout.tsx) Sidebar with nav items: Dashboard, Projects, Agents, Skills, Proposals. Lucide icons. Active-route highlighting via NavLink. Pending-proposals warning badge on the Proposals item. ### Routes (src/App.tsx) New routes: /dashboard, /skills, /skills/:name, /proposals, /proposals/:id. Default redirects to /dashboard. ### API types (src/api.ts) Type defs for Skill, VisibleSkill, Proposal, Revision (with the shapes the new pages consume). ## Tests Existing 7 web tests still pass (Login + api). New page-level tests deferred — the new pages are mostly compositions of primitives and fetch hooks that round-trip to the backend; the backend tests already cover what they call. PR-7 polish can add render-and-click tests if coverage drift surfaces. ## Verification - `pnpm --filter @mcpctl/web build` clean, no warnings. - `pnpm test:run` whole monorepo: 162 test files / 2157 tests green. - Visual smoke deferred — needs a running mcpd to populate the fixtures. Manual smoke tested locally is the next step. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:54:55 +01:00
tailwind-merge@3.5.0: {}
tailwindcss@4.2.4: {}
tapable@2.3.3: {}
tar-fs@2.1.4:
dependencies:
chownr: 1.1.4
mkdirp-classic: 0.5.3
pump: 3.0.3
tar-stream: 2.2.0
tar-fs@3.1.2:
dependencies:
pump: 3.0.3
tar-stream: 3.1.8
optionalDependencies:
bare-fs: 4.6.0
bare-path: 3.0.0
transitivePeerDependencies:
- bare-abort-controller
- bare-buffer
- react-native-b4a
tar-stream@2.2.0:
dependencies:
bl: 4.1.0
end-of-stream: 1.4.5
fs-constants: 1.0.0
inherits: 2.0.4
readable-stream: 3.6.2
tar-stream@3.1.8:
dependencies:
b4a: 1.8.0
bare-fs: 4.6.0
fast-fifo: 1.3.2
streamx: 2.25.0
transitivePeerDependencies:
- bare-abort-controller
- bare-buffer
- react-native-b4a
tar@6.2.1:
dependencies:
chownr: 2.0.0
fs-minipass: 2.1.0
minipass: 5.0.0
minizlib: 2.1.2
mkdirp: 1.0.4
yallist: 4.0.0
tar@7.5.20:
dependencies:
'@isaacs/fs-minipass': 4.0.1
chownr: 3.0.0
minipass: 7.1.3
minizlib: 3.1.0
yallist: 5.0.0
teex@1.0.1:
dependencies:
streamx: 2.25.0
transitivePeerDependencies:
- bare-abort-controller
- react-native-b4a
terminal-size@4.0.1: {}
text-decoder@1.2.7:
dependencies:
b4a: 1.8.0
transitivePeerDependencies:
- react-native-b4a
2026-02-21 03:10:39 +00:00
thread-stream@4.0.0:
dependencies:
real-require: 0.2.0
tinybench@2.9.0: {}
tinyexec@1.0.2: {}
tinyglobby@0.2.15:
dependencies:
fdir: 6.5.0(picomatch@4.0.3)
picomatch: 4.0.3
tinyrainbow@3.0.3: {}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
tldts-core@7.0.28: {}
tldts@7.0.28:
dependencies:
tldts-core: 7.0.28
2026-02-21 03:10:39 +00:00
toad-cache@3.7.0: {}
toidentifier@1.0.1: {}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
toml@4.3.0: {}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
tough-cookie@6.0.1:
dependencies:
tldts: 7.0.28
tr46@0.0.3: {}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
tr46@6.0.0:
dependencies:
punycode: 2.3.1
treeverse@3.0.0: {}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
ts-algebra@2.0.0: {}
2026-02-21 03:10:39 +00:00
ts-api-utils@2.4.0(typescript@5.9.3):
dependencies:
typescript: 5.9.3
tslib@2.8.1: {}
tsx@4.21.0:
dependencies:
esbuild: 0.27.3
get-tsconfig: 4.13.6
optionalDependencies:
fsevents: 2.3.3
tuf-js@4.1.0:
dependencies:
'@tufjs/models': 4.1.0
debug: 4.4.3
make-fetch-happen: 15.0.6
transitivePeerDependencies:
- supports-color
tweetnacl@0.14.5: {}
2026-02-21 03:10:39 +00:00
type-check@0.4.0:
dependencies:
prelude-ls: 1.2.1
type-fest@5.4.4:
dependencies:
tagged-tag: 1.0.0
2026-02-21 03:10:39 +00:00
type-is@2.0.1:
dependencies:
content-type: 1.0.5
media-typer: 1.1.0
mime-types: 3.0.2
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
typebox@1.3.11: {}
typebox@1.3.7: {}
2026-02-21 03:10:39 +00:00
typescript@5.9.3: {}
undici-types@5.26.5: {}
undici-types@7.16.0: {}
undici-types@7.18.2: {}
undici@6.27.0: {}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
undici@7.25.0: {}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
undici@8.9.0: {}
2026-02-21 03:10:39 +00:00
unpipe@1.0.0: {}
upath@1.2.0: {}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
update-browserslist-db@1.2.3(browserslist@4.28.2):
dependencies:
browserslist: 4.28.2
escalade: 3.2.0
picocolors: 1.1.1
2026-02-21 03:10:39 +00:00
uri-js@4.4.1:
dependencies:
punycode: 2.3.1
util-deprecate@1.0.2: {}
uuid@10.0.0: {}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
uuid@14.0.1: {}
validate-npm-package-license@3.0.4:
dependencies:
spdx-correct: 3.2.0
spdx-expression-parse: 3.0.1
validate-npm-package-name@7.0.2: {}
2026-02-21 03:10:39 +00:00
vary@1.1.2: {}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
vite@7.3.1(@types/node@25.3.0)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.21.0)(yaml@2.9.0):
2026-02-21 03:10:39 +00:00
dependencies:
esbuild: 0.27.3
fdir: 6.5.0(picomatch@4.0.3)
picomatch: 4.0.3
postcss: 8.5.6
rollup: 4.58.0
tinyglobby: 0.2.15
optionalDependencies:
'@types/node': 25.3.0
2026-02-21 03:10:39 +00:00
fsevents: 2.3.3
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
jiti: 2.7.0
feat(web): bold redesign — Tailwind v4 + shadcn-style primitives + Skills/Proposals/Revisions UI Phase 6 of the Skills + Revisions + Proposals work. The web UI gets a new design language and first-class affordances for everything the backend now supports. ## Visual direction - Tailwind v4 with custom @theme block (oklch tokens). Dark-mode-only (internal tool — light mode doubles QA surface). - Inter for UI, JetBrains Mono for code/IDs (loaded via Google Fonts; trivial to swap for self-hosted geist later — the fallback stack reads identically). - Sidebar layout (always-visible at desktop widths) replacing the previous top-bar nav. Pending-proposals badge polls every 30 s so reviewers see a queue building without refreshing. - Lucide icons throughout. - Spacing and radii on Tailwind defaults. Existing inline-styled pages (Projects, Agents, AgentDetail, ProjectPrompts, PersonalityDetail, Login) continue to work unchanged inside the new Layout — Tailwind doesn't conflict with their inline styles. A follow-up can migrate them incrementally. ## What's added ### Build infra (src/web/) - package.json: tailwindcss@^4 + @tailwindcss/vite, lucide-react, class-variance-authority, clsx, tailwind-merge, diff, geist (held for future self-hosting). - vite.config.ts: registers the @tailwindcss/vite plugin. - src/index.css: Tailwind import + @theme tokens + @layer base. - src/main.tsx: imports index.css. - src/lib/utils.ts: shadcn-style cn() helper. ### shadcn-style primitives (src/components/ui/) Hand-written rather than generated via `npx shadcn` so the repo doesn't depend on a CLI tool that needs interactive runtime: - button.tsx — variants: primary / secondary / ghost / danger / link; sizes: sm / md / lg / icon. - card.tsx — Card + Header/Title/Description/Content/Footer subparts. - badge.tsx — variants: default / info / success / warning / danger / outline. - input.tsx — Input + Textarea + Label. - tabs.tsx — no-dep accessible Tabs (no Radix needed for our use). - separator.tsx — h/v separator with role=separator. ### Diff component (src/components/Diff.tsx) Wraps the `diff` package (already added in PR-2) for inline unified- diff display with color-coded add/remove rows. Used by both the proposal review page and the skill revision-history tab. ### New pages (src/pages/) - Dashboard.tsx — at-a-glance home. Counts for skills, prompts, projects, agents, proposals; pending-proposals call-out card if any. - Skills.tsx — list view, separated into Global vs Project/Agent- scoped sections. - SkillDetail.tsx — name + semver + description; tabs for SKILL.md / Files / Metadata / History. History tab shows revisions with click-to-diff against the live body. - Proposals.tsx — queue with Pending/Approved/Rejected tabs. Pending count is highlighted in amber. - ProposalDetail.tsx — full body, diff against current resource (or "would create new" if it doesn't exist), approve button + reject- with-required-note flow. ### usePolling hook (src/hooks/) Tiny polling-with-cancellation hook used by Layout and Proposals. ### Layout rewrite (src/components/Layout.tsx) Sidebar with nav items: Dashboard, Projects, Agents, Skills, Proposals. Lucide icons. Active-route highlighting via NavLink. Pending-proposals warning badge on the Proposals item. ### Routes (src/App.tsx) New routes: /dashboard, /skills, /skills/:name, /proposals, /proposals/:id. Default redirects to /dashboard. ### API types (src/api.ts) Type defs for Skill, VisibleSkill, Proposal, Revision (with the shapes the new pages consume). ## Tests Existing 7 web tests still pass (Login + api). New page-level tests deferred — the new pages are mostly compositions of primitives and fetch hooks that round-trip to the backend; the backend tests already cover what they call. PR-7 polish can add render-and-click tests if coverage drift surfaces. ## Verification - `pnpm --filter @mcpctl/web build` clean, no warnings. - `pnpm test:run` whole monorepo: 162 test files / 2157 tests green. - Visual smoke deferred — needs a running mcpd to populate the fixtures. Manual smoke tested locally is the next step. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:54:55 +01:00
lightningcss: 1.32.0
2026-02-21 03:10:39 +00:00
tsx: 4.21.0
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
yaml: 2.9.0
2026-02-21 03:10:39 +00:00
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@25.3.0)(jiti@2.7.0)(jsdom@28.1.0)(lightningcss@1.32.0)(tsx@4.21.0)(yaml@2.9.0):
2026-02-21 03:10:39 +00:00
dependencies:
'@vitest/expect': 4.0.18
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
'@vitest/mocker': 4.0.18(vite@7.3.1(@types/node@25.3.0)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.21.0)(yaml@2.9.0))
2026-02-21 03:10:39 +00:00
'@vitest/pretty-format': 4.0.18
'@vitest/runner': 4.0.18
'@vitest/snapshot': 4.0.18
'@vitest/spy': 4.0.18
'@vitest/utils': 4.0.18
es-module-lexer: 1.7.0
expect-type: 1.3.0
magic-string: 0.30.21
obug: 2.1.1
pathe: 2.0.3
picomatch: 4.0.3
std-env: 3.10.0
tinybench: 2.9.0
tinyexec: 1.0.2
tinyglobby: 0.2.15
tinyrainbow: 3.0.3
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
vite: 7.3.1(@types/node@25.3.0)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.21.0)(yaml@2.9.0)
2026-02-21 03:10:39 +00:00
why-is-node-running: 2.3.0
optionalDependencies:
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
'@opentelemetry/api': 1.9.0
'@types/node': 25.3.0
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
jsdom: 28.1.0
2026-02-21 03:10:39 +00:00
transitivePeerDependencies:
- jiti
- less
- lightningcss
- msw
- sass
- sass-embedded
- stylus
- sugarss
- terser
- tsx
- yaml
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
w3c-xmlserializer@5.0.0:
dependencies:
xml-name-validator: 5.0.0
walk-up-path@4.0.0: {}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
web-streams-polyfill@3.3.3: {}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
web-tree-sitter@0.25.10: {}
webidl-conversions@3.0.1: {}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
webidl-conversions@8.0.1: {}
whatwg-mimetype@5.0.0: {}
whatwg-url@16.0.1:
dependencies:
'@exodus/bytes': 1.15.0
tr46: 6.0.0
webidl-conversions: 8.0.1
transitivePeerDependencies:
- '@noble/hashes'
whatwg-url@5.0.0:
dependencies:
tr46: 0.0.3
webidl-conversions: 3.0.1
2026-02-21 03:10:39 +00:00
which@2.0.2:
dependencies:
isexe: 2.0.0
which@6.0.1:
dependencies:
isexe: 4.0.0
2026-02-21 03:10:39 +00:00
why-is-node-running@2.3.0:
dependencies:
siginfo: 2.0.0
stackback: 0.0.2
wide-align@1.1.5:
dependencies:
string-width: 4.2.3
widest-line@6.0.0:
dependencies:
string-width: 8.2.0
2026-02-21 03:10:39 +00:00
word-wrap@1.2.5: {}
wrap-ansi@6.2.0:
dependencies:
ansi-styles: 4.3.0
string-width: 4.2.3
strip-ansi: 6.0.1
wrap-ansi@7.0.0:
dependencies:
ansi-styles: 4.3.0
string-width: 4.2.3
strip-ansi: 6.0.1
wrap-ansi@9.0.2:
dependencies:
ansi-styles: 6.2.3
string-width: 7.2.0
strip-ansi: 7.1.2
2026-02-21 03:10:39 +00:00
wrappy@1.0.2: {}
write-file-atomic@7.0.1:
dependencies:
signal-exit: 4.1.0
ws@8.19.0: {}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
xml-name-validator@5.0.0: {}
xmlchars@2.2.0: {}
y18n@5.0.8: {}
feat(web): browser-based prompt + personality editor (Stage 5) New workspace package @mcpctl/web — a Vite + React 19 SPA that talks to mcpd's existing HTTP API. Bundles to a static dist/ which Stage 6 will bake into the RPM and serve from mcpd at /ui via @fastify/static. Pages: /ui/projects list projects /ui/projects/:name/prompts CRUD project prompts (Monaco editor) /ui/agents list agents /ui/agents/:name tabs: Direct prompts | Personalities /ui/personalities/:id bind/unbind prompts to a personality Auth: paste a session token (mcpctl auth login) or PAT (mcpctl_pat_*) once on a login screen, kept in localStorage; logout clears it. API client: 60-line fetch wrapper, attaches the bearer header from storage, throws an ApiError with status + parsed body on non-2xx. A 200-line useFetch hook provides loading/error/data without a state-management library — we are not building Notion. UX: - Dark terminal-adjacent theme so the page feels like the CLI. - Monaco @monaco-editor/react for prompt content (markdown mode, word-wrap, search, multi-cursor). - Personality detail's "attach prompt" picker filters in-scope candidates: agent-direct + same-project + globals. Dev loop: pnpm --filter @mcpctl/web dev (vite at :5173, proxies /api to https://mcpctl.ad.itaz.eu — override with MCPCTL_API_URL). Build: pnpm --filter @mcpctl/web build → src/web/dist/. Tests: 7 vitest cases covering the bearer header / 4xx body / 204 no-content path on the api wrapper, and the login storage round-trip + help toggle. Production build green: 269 KB JS / 84 KB gzipped. Typecheck clean (TS strict + exactOptionalPropertyTypes carried over). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:41:57 +01:00
yallist@3.1.1: {}
yallist@4.0.0: {}
yallist@5.0.0: {}
yaml@2.8.2: {}
fix(pi): repair the /mcpctl menu, skills target, and typecheck the extension The pi extension shipped in `src/pi-ext/` was covered by no tsconfig and no eslint config, so nothing ever checked it against pi's API. Pointing tsc at the published @earendil-works/pi-coding-agent types found the command surface to be inert. Fixes: - `/mcpctl` did nothing. `ctx.ui.select` takes `string[]` and returns the chosen string; it was called with `{value,label}` objects, so the menu rendered five `[object Object]` rows and `choice === "status"` never matched any branch. Labels are now plain strings mapped back to actions. - The headless branch returned a status string from a handler typed `Promise<void>`; pi drops it. Reports via notify instead. - "Sync skills" omitted `--agent pi`, writing into ~/.claude/skills — in an integration whose stated purpose is to not depend on ~/.claude — and said so in its own success message. It also ran execSync with `stdio: "inherit"`, painting raw output over pi's TUI, and interpolated the project name into a shell string. Now execFile with `--agent pi` and captured output. - Tool results typed `content[].type` as `string`; pi's AgentToolResult wants the `"text"` literal. - `callTool` asserted `Promise<unknown>` to `ToolCallResult`. - Sanitising MCP tool names to `[a-z0-9_]` can collide (`docs.search` vs `docs-search`). The colliding tool was silently never registered but still reported active, so its calls were forwarded to the first tool. Names are now disambiguated and tracked with the MCP tool they forward to. - `registerWithPi` rewrote settings.json even when nothing changed. Since parsing strips `//` comments, a no-op run destroyed them. Guards, so this class of bug can't return: - `src/pi-ext/tsconfig.json` checks the extension against the real published pi types (dev dependency, not a shim — a shim drifting from the published API is the exact failure being guarded). Wired into `pnpm typecheck`. - eslint now covers `src/pi-ext/*.ts` like every other source file. - A test fails if the embedded copy in `config/pi-extension.ts` is stale; editing the sources without regenerating silently shipped old code. Also: the branch added `config pi` without regenerating shell completions (the committed-completions test was failing), and the doc advertised `mcpctl pi sync-skills`, which does not exist. Both corrected, plus a note on the session-token vs `mcpctl_pat_` bearer difference that would bite against an authenticated `mcplocal serve`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017BMXdb2qZbPSh8Q7XpTyjB
2026-08-08 17:30:42 +01:00
yaml@2.9.0: {}
yargs-parser@21.1.1: {}
yargs@17.7.2:
dependencies:
cliui: 8.0.1
escalade: 3.2.0
get-caller-file: 2.0.5
require-directory: 2.1.1
string-width: 4.2.3
y18n: 5.0.8
yargs-parser: 21.1.1
2026-02-21 03:10:39 +00:00
yocto-queue@0.1.0: {}
yoctocolors-cjs@2.1.3: {}
yoga-layout@3.2.1: {}
2026-02-21 03:10:39 +00:00
zod-to-json-schema@3.25.1(zod@3.25.76):
dependencies:
zod: 3.25.76
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
zod-to-json-schema@3.25.1(zod@4.1.8):
dependencies:
zod: 4.1.8
2026-02-21 03:10:39 +00:00
zod@3.25.76: {}
feat(opencode): native opencode integration — /mcpctl switcher, live project switching, footer indicator Adds `mcpctl config opencode`, two opencode plugins and an `opencode` skills sync target, so an mcpctl project can be switched from inside opencode's TUI and the active one is visible at a glance. Unlike `config claude` / `config prime-agent`, this writes NO MCP entry into the host's config. opencode exposes an HTTP API for its own MCP registry (`POST /mcp`), so the project is mounted through the running app: - the token stays in ~/.mcpctl/opencode-state.json (0600) instead of a mode-0644 opencode.json users paste into bug reports; - switching projects takes effect on the next turn, with no restart. Inside opencode: /mcpctl filterable project picker; switches live /mcpctl-status active project, mount state, gateway URL /mcpctl-skills re-sync this project's skills plus a `mcpctl:<project>` indicator in the prompt footer, next to the model name and one line above the token counter. Design notes: - the MCP server is registered under a constant name, so tools keep a stable `mcpctl_*` prefix and opencode's per-request tool resolution shows the new project's tools by itself — no "your old tool names are dead" message to the model, unlike the pi extension; - an unchanged mount is never re-registered: mcp.add rebuilds the connection and mcplocal binds a gated project's unlocked state to that connection's mcp-session-id, so re-adding would re-lock a project begin_session had just opened; - the server plugin does not mount during setup — setup runs before the server accepts connections and mcp.add calls back into it, which hangs opencode on a blank screen before the TUI draws; - the switcher shells out to this CLI (--skip-plugin --skip-marker) so token minting, state and skills stay in one place; - no usable credential aborts non-zero with the state file untouched, so a failed switch leaves the previous project working rather than swapping it for a mount that 401s. `skills sync --agent opencode` installs into ~/.config/opencode/skill (XDG aware) with the same shared-tree semantics as pi and prime-agent. The credential plumbing shared with `config prime-agent` is lifted to one place and parameterised by agent rather than copied. The plugin sources are embedded in the CLI (generated, freshness-tested) so an installed binary with no source tree can provision them, and are typechecked against the real @opencode-ai/plugin types. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
2026-08-08 21:03:53 +01:00
zod@4.1.8: {}