Files
mcpctl/pnpm-lock.yaml

7176 lines
227 KiB
YAML
Raw Normal View History

2026-02-21 03:10:39 +00:00
lockfileVersion: '9.0'
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
importers:
.:
devDependencies:
'@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
version: 8.56.0(@typescript-eslint/parser@8.56.0(eslint@10.0.1(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.1(jiti@2.6.1))(typescript@5.9.3)
'@typescript-eslint/parser':
specifier: ^8.56.0
version: 8.56.0(eslint@10.0.1(jiti@2.6.1))(typescript@5.9.3)
'@vitest/coverage-v8':
specifier: ^4.0.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
version: 4.0.18(vitest@4.0.18(@types/node@25.3.0)(jiti@2.6.1)(jsdom@28.1.0)(lightningcss@1.32.0)(tsx@4.21.0)(yaml@2.8.2))
2026-02-21 03:10:39 +00:00
eslint:
specifier: ^10.0.1
version: 10.0.1(jiti@2.6.1)
eslint-config-prettier:
specifier: ^10.1.8
version: 10.1.8(eslint@10.0.1(jiti@2.6.1))
rimraf:
specifier: ^6.1.3
version: 6.1.3
tsx:
specifier: ^4.21.0
version: 4.21.0
typescript:
specifier: ^5.9.3
version: 5.9.3
vitest:
specifier: ^4.0.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
version: 4.0.18(@types/node@25.3.0)(jiti@2.6.1)(jsdom@28.1.0)(lightningcss@1.32.0)(tsx@4.21.0)(yaml@2.8.2)
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
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
version: 1.26.0(zod@3.25.76)
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
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)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))
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
version: 4.2.4(vite@7.3.1(@types/node@25.3.0)(jiti@2.6.1)(lightningcss@1.32.0)(tsx@4.21.0)(yaml@2.8.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
'@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
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
version: 5.2.0(vite@7.3.1(@types/node@25.3.0)(jiti@2.6.1)(lightningcss@1.32.0)(tsx@4.21.0)(yaml@2.8.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
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
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
version: 7.3.1(@types/node@25.3.0)(jiti@2.6.1)(lightningcss@1.32.0)(tsx@4.21.0)(yaml@2.8.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
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==}
'@alcalzone/ansi-tokenize@0.2.5':
resolution: {integrity: sha512-3NX/MpTdroi0aKz134A6RC2Gb2iXVECN4QaAXnvCIxxIm3C3AVB1mkUe8NaaiyvOpDfsrqWhYtj+Q6a62RrTsw==}
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
'@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==}
'@babel/code-frame@7.29.0':
resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==}
engines: {node: '>=6.9.0'}
'@babel/compat-data@7.29.0':
resolution: {integrity: sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==}
engines: {node: '>=6.9.0'}
'@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'}
'@babel/helper-compilation-targets@7.28.6':
resolution: {integrity: sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==}
engines: {node: '>=6.9.0'}
'@babel/helper-globals@7.28.0':
resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==}
engines: {node: '>=6.9.0'}
'@babel/helper-module-imports@7.28.6':
resolution: {integrity: sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==}
engines: {node: '>=6.9.0'}
'@babel/helper-module-transforms@7.28.6':
resolution: {integrity: sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0
'@babel/helper-plugin-utils@7.28.6':
resolution: {integrity: sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==}
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'}
'@babel/helper-validator-identifier@7.28.5':
resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==}
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(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
'@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'}
'@babel/traverse@7.29.0':
resolution: {integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==}
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'}
'@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'}
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==}
'@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'}
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==}
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
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(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]
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==}
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]
'@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
'@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/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==}
'@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==}
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
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==}
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'}
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}
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
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'}
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
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'}
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==}
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'}
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'}
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==}
cssstyle@6.2.0:
resolution: {integrity: sha512-Fm5NvhYathRnXNVndkUsCCuR63DCLVVwGOOwQw782coXFi5HhkXdu289l59HlXZBawsyNccXfWRYvLzcDCdDig==}
engines: {node: '>=20'}
csstype@3.2.3:
resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==}
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'}
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'}
ee-first@1.1.1:
resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
effect@3.18.4:
resolution: {integrity: sha512-b1LXQJLe9D11wfnOKAk3PKxuqYshQ0Heez+y5pnkd3jLj1yx9QhM72zZ9uUrOQyNvrs2GZZd/3maL0ZV18YuDA==}
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(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'}
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-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'}
expect-type@1.3.0:
resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==}
engines: {node: '>=12.0.0'}
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==}
fast-check@3.23.2:
resolution: {integrity: sha512-h5+1OzzfCC3Ef7VbtKdcv7zsstUQwUDlYpUTvjeUsJAssPgLn7QzbboPtL5ro04Mq0rPOsMzl7q5hIbRs2wD1A==}
engines: {node: '>=8.0.0'}
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
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'}
find-my-way@9.4.0:
resolution: {integrity: sha512-5Ye4vHsypZRYtS01ob/iwHzGRUDELlsoCftI/OZFhcLs1M0tkGPcXldE80TAZC5yYuJMBPJQQ43UHlqbJWiX2w==}
engines: {node: '>=20'}
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'}
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.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.
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'}
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-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
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==}
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'}
helmet@7.2.0:
resolution: {integrity: sha512-ZRiwvN089JfMXokizgqEPXsl2Guk094yExfoDXR0cBYWxtBbaSww/w+vT4WEJsBW2iTUi1GgZ6swmoug3Oy4Xw==}
engines: {node: '>=16.0.0'}
hono@4.12.0:
resolution: {integrity: sha512-NekXntS5M94pUfiVZ8oXXK/kkri+5WpX2/Ik+LVsl+uvw+soj4roXIsPqO+XsWrAw20mOzaXOZf3Q7PfB9A/IA==}
engines: {node: '>=16.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}
2026-02-21 03:10:39 +00:00
html-escaper@2.0.2:
resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==}
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'}
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==}
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'}
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==}
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'}
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-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==}
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
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
2026-02-21 03:10:39 +00:00
json-buffer@3.0.1:
resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==}
json-schema-ref-resolver@3.0.0:
resolution: {integrity: sha512-hOrZIVL5jyYFjzk7+y7n5JDzGlU8rfWDuYyHwGa2WA8/pcmMHezp2xsVwxrebD/Q9t8Nc5DboieySDpCp4WG4A==}
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==}
json-stable-stringify-without-jsonify@1.0.1:
resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
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
jsonpath-plus@10.4.0:
resolution: {integrity: sha512-T92WWatJXmhBbKsgH/0hl+jxjdXrifi5IKeMY02DWggRxX0UElcbVzPlmgLTbvsPeW1PasQ6xE2Q75stkhGbsA==}
engines: {node: '>=18.0.0'}
hasBin: true
2026-02-21 03:10:39 +00:00
keyv@4.5.4:
resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
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'}
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==}
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'}
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
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'}
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}
minimatch@3.1.2:
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
2026-02-21 03:10:39 +00:00
minimatch@9.0.5:
resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
engines: {node: '>=16 || 14 >=14.17'}
minipass@3.3.6:
resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==}
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'}
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==}
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==}
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==}
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
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
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'}
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'}
p-limit@3.1.0:
resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
engines: {node: '>=10'}
p-locate@5.0.0:
resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
engines: {node: '>=10'}
package-json-from-dist@1.0.1:
resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==}
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'}
patch-console@2.0.0:
resolution: {integrity: sha512-0YNdUceMdaQwoKce1gatDScmMo5pu/tfABfnzEqeG0gtTmd7mh/WcwgUjtAeOU7N8nFFlbQBnFK2gXW5fGvmMA==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
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'}
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(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
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==}
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==}
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'}
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'}
resolve-pkg-maps@1.0.0:
resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
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'}
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==}
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
send@1.2.1:
resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==}
engines: {node: '>= 18'}
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'}
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'}
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'}
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'}
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'}
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(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
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(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'}
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
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'}
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==}
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'}
2026-02-21 03:10:39 +00:00
unpipe@1.0.0:
resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==}
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
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==}
hasBin: true
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'}
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
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==}
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==}
yaml@2.8.2:
resolution: {integrity: sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==}
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==}
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': {}
'@alcalzone/ansi-tokenize@0.2.5':
dependencies:
ansi-styles: 6.2.3
is-fullwidth-code-point: 5.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
'@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': {}
'@babel/code-frame@7.29.0':
dependencies:
'@babel/helper-validator-identifier': 7.28.5
js-tokens: 4.0.0
picocolors: 1.1.1
'@babel/compat-data@7.29.0': {}
'@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
'@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
'@babel/helper-globals@7.28.0': {}
'@babel/helper-module-imports@7.28.6':
dependencies:
'@babel/traverse': 7.29.0
'@babel/types': 7.29.0
transitivePeerDependencies:
- supports-color
'@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
'@babel/helper-plugin-utils@7.28.6': {}
2026-02-21 03:10:39 +00:00
'@babel/helper-string-parser@7.27.1': {}
'@babel/helper-validator-identifier@7.28.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
'@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(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
'@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
'@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
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
'@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': {}
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
'@eslint-community/eslint-utils@4.9.1(eslint@10.0.1(jiti@2.6.1))':
dependencies:
eslint: 10.0.1(jiti@2.6.1)
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
'@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': {}
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
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
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(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(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
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': {}
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
'@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
'@tailwindcss/vite@4.2.4(vite@7.3.1(@types/node@25.3.0)(jiti@2.6.1)(lightningcss@1.32.0)(tsx@4.21.0)(yaml@2.8.2))':
dependencies:
'@tailwindcss/node': 4.2.4
'@tailwindcss/oxide': 4.2.4
tailwindcss: 4.2.4
vite: 7.3.1(@types/node@25.3.0)(jiti@2.6.1)(lightningcss@1.32.0)(tsx@4.21.0)(yaml@2.8.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
'@testing-library/dom@10.4.1':
dependencies:
'@babel/code-frame': 7.29.0
'@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)
'@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/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
'@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
2026-02-21 03:10:39 +00:00
'@typescript-eslint/eslint-plugin@8.56.0(@typescript-eslint/parser@8.56.0(eslint@10.0.1(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.1(jiti@2.6.1))(typescript@5.9.3)':
dependencies:
'@eslint-community/regexpp': 4.12.2
'@typescript-eslint/parser': 8.56.0(eslint@10.0.1(jiti@2.6.1))(typescript@5.9.3)
'@typescript-eslint/scope-manager': 8.56.0
'@typescript-eslint/type-utils': 8.56.0(eslint@10.0.1(jiti@2.6.1))(typescript@5.9.3)
'@typescript-eslint/utils': 8.56.0(eslint@10.0.1(jiti@2.6.1))(typescript@5.9.3)
'@typescript-eslint/visitor-keys': 8.56.0
eslint: 10.0.1(jiti@2.6.1)
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
'@typescript-eslint/parser@8.56.0(eslint@10.0.1(jiti@2.6.1))(typescript@5.9.3)':
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
eslint: 10.0.1(jiti@2.6.1)
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
'@typescript-eslint/type-utils@8.56.0(eslint@10.0.1(jiti@2.6.1))(typescript@5.9.3)':
dependencies:
'@typescript-eslint/types': 8.56.0
'@typescript-eslint/typescript-estree': 8.56.0(typescript@5.9.3)
'@typescript-eslint/utils': 8.56.0(eslint@10.0.1(jiti@2.6.1))(typescript@5.9.3)
debug: 4.4.3
eslint: 10.0.1(jiti@2.6.1)
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
'@typescript-eslint/utils@8.56.0(eslint@10.0.1(jiti@2.6.1))(typescript@5.9.3)':
dependencies:
'@eslint-community/eslint-utils': 4.9.1(eslint@10.0.1(jiti@2.6.1))
'@typescript-eslint/scope-manager': 8.56.0
'@typescript-eslint/types': 8.56.0
'@typescript-eslint/typescript-estree': 8.56.0(typescript@5.9.3)
eslint: 10.0.1(jiti@2.6.1)
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
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
'@vitejs/plugin-react@5.2.0(vite@7.3.1(@types/node@25.3.0)(jiti@2.6.1)(lightningcss@1.32.0)(tsx@4.21.0)(yaml@2.8.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
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
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
vite: 7.3.1(@types/node@25.3.0)(jiti@2.6.1)(lightningcss@1.32.0)(tsx@4.21.0)(yaml@2.8.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
transitivePeerDependencies:
- supports-color
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
'@vitest/coverage-v8@4.0.18(vitest@4.0.18(@types/node@25.3.0)(jiti@2.6.1)(jsdom@28.1.0)(lightningcss@1.32.0)(tsx@4.21.0)(yaml@2.8.2))':
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
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
vitest: 4.0.18(@types/node@25.3.0)(jiti@2.6.1)(jsdom@28.1.0)(lightningcss@1.32.0)(tsx@4.21.0)(yaml@2.8.2)
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
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
'@vitest/mocker@4.0.18(vite@7.3.1(@types/node@25.3.0)(jiti@2.6.1)(lightningcss@1.32.0)(tsx@4.21.0)(yaml@2.8.2))':
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:
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
vite: 7.3.1(@types/node@25.3.0)(jiti@2.6.1)(lightningcss@1.32.0)(tsx@4.21.0)(yaml@2.8.2)
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: {}
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: {}
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
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
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
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)
buffer@5.7.1:
dependencies:
base64-js: 1.5.1
ieee754: 1.2.1
buildcheck@0.0.7:
optional: true
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
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: {}
2026-02-21 03:10:39 +00:00
citty@0.1.6:
dependencies:
consola: 3.4.2
citty@0.2.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
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: {}
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: {}
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: {}
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: {}
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: {}
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
ee-first@1.1.1: {}
effect@3.18.4:
dependencies:
'@standard-schema/spec': 1.1.0
fast-check: 3.23.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
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(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: {}
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-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: {}
eslint-config-prettier@10.1.8(eslint@10.0.1(jiti@2.6.1)):
dependencies:
eslint: 10.0.1(jiti@2.6.1)
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: {}
eslint@10.0.1(jiti@2.6.1):
dependencies:
'@eslint-community/eslint-utils': 4.9.1(eslint@10.0.1(jiti@2.6.1))
'@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:
jiti: 2.6.1
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
expect-type@1.3.0: {}
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: {}
fast-check@3.23.2:
dependencies:
pure-rand: 6.1.0
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
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
find-my-way@9.4.0:
dependencies:
fast-deep-equal: 3.1.3
fast-querystring: 1.1.2
safe-regex2: 5.0.0
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
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.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
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(next@16.2.5(@babel/core@7.29.0)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)):
dependencies:
next: 16.2.5(@babel/core@7.29.0)(react-dom@19.2.5(react@19.2.5))(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
gensync@1.0.0-beta.2: {}
get-caller-file@2.0.5: {}
get-east-asian-width@1.5.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-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:
minimatch: 10.2.2
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
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: {}
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
helmet@7.2.0: {}
hono@4.12.0: {}
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'
2026-02-21 03:10:39 +00:00
html-escaper@2.0.2: {}
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
2026-02-21 03:10:39 +00:00
iconv-lite@0.7.2:
dependencies:
safer-buffer: 2.1.2
ieee754@1.2.1: {}
2026-02-21 03:10:39 +00:00
ignore@5.3.2: {}
ignore@7.0.5: {}
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: {}
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: {}
is-extglob@2.1.1: {}
is-fullwidth-code-point@3.0.0: {}
is-fullwidth-code-point@5.1.0:
dependencies:
get-east-asian-width: 1.5.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-unicode-supported@2.1.0: {}
2026-02-21 03:10:39 +00:00
isexe@2.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: {}
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: {}
2026-02-21 03:10:39 +00:00
json-buffer@3.0.1: {}
json-schema-ref-resolver@3.0.0:
dependencies:
dequal: 2.0.3
json-schema-traverse@0.4.1: {}
json-schema-traverse@1.0.0: {}
json-schema-typed@8.0.2: {}
json-stable-stringify-without-jsonify@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
json5@2.2.3: {}
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
2026-02-21 03:10:39 +00:00
keyv@4.5.4:
dependencies:
json-buffer: 3.0.1
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
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: {}
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
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: {}
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: {}
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
minimatch@3.1.2:
dependencies:
brace-expansion: 1.1.12
2026-02-21 03:10:39 +00:00
minimatch@9.0.5:
dependencies:
brace-expansion: 2.0.2
minipass@3.3.6:
dependencies:
yallist: 4.0.0
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
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
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: {}
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: {}
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(@babel/core@7.29.0)(react-dom@19.2.5(react@19.2.5))(react@19.2.5):
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
sharp: 0.34.5
transitivePeerDependencies:
- '@babel/core'
- babel-plugin-macros
node-addon-api@5.1.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
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
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
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
p-limit@3.1.0:
dependencies:
yocto-queue: 0.1.0
p-locate@5.0.0:
dependencies:
p-limit: 3.1.0
package-json-from-dist@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
parse5@8.0.1:
dependencies:
entities: 8.0.0
2026-02-21 03:10:39 +00:00
parseurl@1.3.3: {}
patch-console@2.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: {}
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(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
process-warning@4.0.1: {}
process-warning@5.0.0: {}
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: {}
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: {}
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: {}
resolve-pkg-maps@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: {}
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
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: {}
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
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
semver: 7.7.4
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: {}
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
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: {}
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
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
get-east-asian-width: 1.5.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
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(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
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(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
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
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
typescript@5.9.3: {}
undici-types@5.26.5: {}
undici-types@7.16.0: {}
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
undici@7.25.0: {}
2026-02-21 03:10:39 +00:00
unpipe@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
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: {}
2026-02-21 03:10:39 +00:00
vary@1.1.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
vite@7.3.1(@types/node@25.3.0)(jiti@2.6.1)(lightningcss@1.32.0)(tsx@4.21.0)(yaml@2.8.2):
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
jiti: 2.6.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
lightningcss: 1.32.0
2026-02-21 03:10:39 +00:00
tsx: 4.21.0
yaml: 2.8.2
2026-02-21 03:10:39 +00:00
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
vitest@4.0.18(@types/node@25.3.0)(jiti@2.6.1)(jsdom@28.1.0)(lightningcss@1.32.0)(tsx@4.21.0)(yaml@2.8.2):
2026-02-21 03:10:39 +00:00
dependencies:
'@vitest/expect': 4.0.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
'@vitest/mocker': 4.0.18(vite@7.3.1(@types/node@25.3.0)(jiti@2.6.1)(lightningcss@1.32.0)(tsx@4.21.0)(yaml@2.8.2))
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
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
vite: 7.3.1(@types/node@25.3.0)(jiti@2.6.1)(lightningcss@1.32.0)(tsx@4.21.0)(yaml@2.8.2)
2026-02-21 03:10:39 +00:00
why-is-node-running: 2.3.0
optionalDependencies:
'@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
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
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: {}
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: {}
yaml@2.8.2: {}
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
zod@3.25.76: {}