@chorus-aidlc/chorus 0.21.0 → 0.21.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/standalone/.next/BUILD_ID +1 -1
- package/.next/standalone/.next/app-build-manifest.json +213 -213
- package/.next/standalone/.next/app-path-routes-manifest.json +38 -38
- package/.next/standalone/.next/build-manifest.json +2 -2
- package/.next/standalone/.next/prerender-manifest.json +42 -42
- package/.next/standalone/.next/server/app/(dashboard)/project-groups/[uuid]/page.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/project-groups/[uuid]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/project-groups/[uuid]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/activity/page.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/activity/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/[ideaUuid]/page.js +2 -2
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/[ideaUuid]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/page.js +2 -2
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/documents/page.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/documents/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/graph/page.js +2 -2
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/graph/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/graph/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page.js +2 -2
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/new/page.js +2 -2
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/new/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/page.js +2 -2
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/[taskUuid]/page.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/[taskUuid]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/[taskUuid]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/page.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/page.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/settings/page.js +2 -2
- package/.next/standalone/.next/server/app/(dashboard)/settings/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/settings/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_not-found.html +2 -2
- package/.next/standalone/.next/server/app/_not-found.rsc +1 -1
- package/.next/standalone/.next/server/app/admin/companies/[uuid]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/admin/companies/new/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/admin/companies/new.html +2 -2
- package/.next/standalone/.next/server/app/admin/companies/new.rsc +1 -1
- package/.next/standalone/.next/server/app/admin/companies/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/admin/companies.html +2 -2
- package/.next/standalone/.next/server/app/admin/companies.rsc +1 -1
- package/.next/standalone/.next/server/app/admin/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/admin.html +2 -2
- package/.next/standalone/.next/server/app/admin.rsc +1 -1
- package/.next/standalone/.next/server/app/api/admin/companies/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/admin/companies/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/admin/login/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/admin/session/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/agent-connections/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/agents/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/agents/[uuid]/sessions/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/agents/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/api-keys/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/api-keys/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/auth/callback/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/auth/check-default/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/auth/company-oidc/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/auth/default-login/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/auth/identify/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/auth/logout/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/auth/me/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/auth/sync-token/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/comments/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/connection-heartbeat/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/control/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/directory-request/report/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/execution-state/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/executions/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/pending-turns/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/report-interrupt/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/resume/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/transcript/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/turn-advance/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-directory-requests/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-directory-requests/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/instruction/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/repoint/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/ad-hoc/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/documents/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/entities/[type]/[uuid]/root-idea/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/events/notifications/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/events/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/health/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/claim/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/move/preview/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/move/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/parent/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/release/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/wake-preview/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/conversational/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/mcp/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/me/assignments/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/mentionables/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/notifications/[uuid]/archive/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/notifications/[uuid]/read/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/notifications/preferences/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/notifications/read-all/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/notifications/unread-count/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/project-groups/[uuid]/access-preview/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/project-groups/[uuid]/dashboard/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/project-groups/[uuid]/members/[userUuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/project-groups/[uuid]/members/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/project-groups/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/project-groups/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/project-visits/pin/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/project-visits/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/project-visits/visit/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/access-preview/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/activity/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/agent-cwds/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/available/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/documents/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/group/preview/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/group/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/tracker/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/members/[userUuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/members/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/proposals/[proposalUuid]/validate/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/proposals/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/proposals/summary/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/resource-graph/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/stats/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/tasks/dependencies/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/tasks/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/agent-cwd-options/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/proposals/[uuid]/approve/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/proposals/[uuid]/close/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/proposals/[uuid]/reject/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/proposals/[uuid]/revoke/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/proposals/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/references/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/references/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/search/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/session/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/sessions/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/claim/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/dependencies/[dependsOnUuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/dependencies/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/release/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/sessions/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/index.html +2 -2
- package/.next/standalone/.next/server/app/index.rsc +1 -1
- package/.next/standalone/.next/server/app/login/admin/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/login/admin.html +2 -2
- package/.next/standalone/.next/server/app/login/admin.rsc +1 -1
- package/.next/standalone/.next/server/app/login/callback/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/login/callback.html +2 -2
- package/.next/standalone/.next/server/app/login/callback.rsc +1 -1
- package/.next/standalone/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/login/pick-workspace/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/login/pick-workspace.html +2 -2
- package/.next/standalone/.next/server/app/login/pick-workspace.rsc +1 -1
- package/.next/standalone/.next/server/app/login.html +2 -2
- package/.next/standalone/.next/server/app/login.rsc +1 -1
- package/.next/standalone/.next/server/app/onboarding/page.js +2 -2
- package/.next/standalone/.next/server/app/onboarding/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/onboarding/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/onboarding.html +2 -2
- package/.next/standalone/.next/server/app/onboarding.rsc +2 -2
- package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/projects.html +2 -2
- package/.next/standalone/.next/server/app/projects.rsc +2 -2
- package/.next/standalone/.next/server/app/settings.html +2 -2
- package/.next/standalone/.next/server/app/settings.rsc +3 -3
- package/.next/standalone/.next/server/app-paths-manifest.json +38 -38
- package/.next/standalone/.next/server/chunks/1855.js +2 -2
- package/.next/standalone/.next/server/chunks/2689.js +2 -2
- package/.next/standalone/.next/server/chunks/5212.js +1 -1
- package/.next/standalone/.next/server/chunks/5281.js +2 -2
- package/.next/standalone/.next/server/chunks/5647.js +1 -1
- package/.next/standalone/.next/server/chunks/5764.js +2 -2
- package/.next/standalone/.next/server/chunks/6493.js +1 -1
- package/.next/standalone/.next/server/chunks/6991.js +2 -2
- package/.next/standalone/.next/server/chunks/{9894.js → 7138.js} +1 -1
- package/.next/standalone/.next/server/chunks/{9583.js → 7169.js} +3 -3
- package/.next/standalone/.next/server/chunks/7425.js +1 -0
- package/.next/standalone/.next/server/chunks/7839.js +1 -1
- package/.next/standalone/.next/server/chunks/8692.js +1 -0
- package/.next/standalone/.next/server/chunks/87.js +1 -0
- package/.next/standalone/.next/server/chunks/8849.js +2 -2
- package/.next/standalone/.next/server/chunks/911.js +1 -0
- package/.next/standalone/.next/server/chunks/9295.js +1 -1
- package/.next/standalone/.next/server/middleware-manifest.json +5 -5
- package/.next/standalone/.next/server/pages/404.html +2 -2
- package/.next/standalone/.next/server/pages/500.html +1 -1
- package/.next/standalone/.next/server/pages-manifest.json +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/static/chunks/15638-e8566f8551988a0b.js +1 -0
- package/.next/standalone/.next/static/chunks/30187-8406d0b0e7582b4e.js +1 -0
- package/.next/standalone/.next/static/chunks/59480-03e05915e0f0f1e4.js +1 -0
- package/.next/standalone/.next/static/chunks/65833-d0a8d9023febc1ce.js +1 -0
- package/.next/standalone/.next/static/chunks/75844-ab7e24827a4875a0.js +1 -0
- package/.next/standalone/.next/static/chunks/88277-9563bd5857edfb08.js +1 -0
- package/.next/standalone/.next/static/chunks/91202-a6809360a6c58c9a.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/layout-9a0a7266bbc1498f.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/dashboard/{page-670eeb1a8007a20c.js → page-26aef423473209b6.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page-deb0615a19598fe6.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/page-cb20e73952b1d4ee.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/graph/{page-ed5fbcae30e875d1.js → page-c8af650e39ff3eac.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page-6bc33e1fb5e252dc.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/new/page-e622257cf6a2fe0c.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/{page-49b02e795c5b279c.js → page-2085f55b6cbd4d82.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/tasks/[taskUuid]/{page-f26cad3e8406ac07.js → page-2b9e6239037f79d5.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/tasks/{page-04a3fbabc7542960.js → page-7afc11846cb7aefc.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/settings/{page-d0c217c1e9a18433.js → page-406dbd7ae784ec2b.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/onboarding/page-bb641e258e90d08b.js +1 -0
- package/.next/standalone/package.json +1 -1
- package/.next/standalone/public/chorus-plugin/.claude-plugin/plugin.json +1 -1
- package/.next/standalone/public/chorus-plugin/bin/chorus-api.sh +1 -1
- package/.next/standalone/public/chorus-plugin/skills/brainstorm/SKILL.md +1 -1
- package/.next/standalone/public/chorus-plugin/skills/chorus/SKILL.md +1 -1
- package/.next/standalone/public/chorus-plugin/skills/chorus-cli/SKILL.md +1 -1
- package/.next/standalone/public/chorus-plugin/skills/develop/SKILL.md +1 -1
- package/.next/standalone/public/chorus-plugin/skills/docs/SKILL.md +1 -1
- package/.next/standalone/public/chorus-plugin/skills/idea/SKILL.md +1 -1
- package/.next/standalone/public/chorus-plugin/skills/openspec-aware/SKILL.md +1 -1
- package/.next/standalone/public/chorus-plugin/skills/orchestrate/SKILL.md +1 -1
- package/.next/standalone/public/chorus-plugin/skills/proposal/SKILL.md +1 -1
- package/.next/standalone/public/chorus-plugin/skills/quick-dev/SKILL.md +1 -1
- package/.next/standalone/public/chorus-plugin/skills/research/SKILL.md +1 -1
- package/.next/standalone/public/chorus-plugin/skills/review/SKILL.md +1 -1
- package/.next/standalone/public/chorus-plugin/skills/spec-lite/SKILL.md +1 -1
- package/.next/standalone/public/chorus-plugin/skills/yolo/SKILL.md +1 -1
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-brainstorm/SKILL.md +1 -1
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-cli/SKILL.md +1 -1
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-develop/SKILL.md +1 -1
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-docs/SKILL.md +1 -1
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-idea/SKILL.md +1 -1
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-openspec-aware/SKILL.md +1 -1
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-orchestrate/SKILL.md +1 -1
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-proposal/SKILL.md +1 -1
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-quick-dev/SKILL.md +1 -1
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-research/SKILL.md +1 -1
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-review/SKILL.md +1 -1
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-spec-lite/SKILL.md +1 -1
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-yolo/SKILL.md +1 -1
- package/.next/standalone/public/kiro-plugin/bin/chorus-api.sh +1 -1
- package/README.md +1 -1
- package/README.zh.md +1 -1
- package/cli/init/contracts.mjs +3 -0
- package/cli/init/install-methods.mjs +24 -113
- package/cli/init/pi-compatibility.mjs +5 -0
- package/cli/init/pi-mcp-backend.mjs +160 -0
- package/cli/init/pi-mcp-config.mjs +48 -64
- package/cli/init/registry.mjs +3 -2
- package/cli/init/run-command.mjs +3 -1
- package/cli/init/steps/codex-restart.mjs +95 -0
- package/cli/init/steps/credential-seed.mjs +18 -17
- package/cli/init.mjs +2 -2
- package/cli/upgrade-plugins.mjs +10 -45
- package/package.json +1 -1
- package/.next/standalone/.next/server/chunks/1443.js +0 -1
- package/.next/standalone/.next/server/chunks/2701.js +0 -1
- package/.next/standalone/.next/server/chunks/6666.js +0 -1
- package/.next/standalone/.next/server/chunks/7329.js +0 -1
- package/.next/standalone/.next/static/chunks/14891-8a7485231cdaf105.js +0 -1
- package/.next/standalone/.next/static/chunks/30187-12e26e880f7b6da7.js +0 -1
- package/.next/standalone/.next/static/chunks/36244-82317cfd58345146.js +0 -1
- package/.next/standalone/.next/static/chunks/40309-bedb6f19876265b4.js +0 -1
- package/.next/standalone/.next/static/chunks/56161-5d2f255f25dba375.js +0 -1
- package/.next/standalone/.next/static/chunks/6497-36958930c3e35070.js +0 -1
- package/.next/standalone/.next/static/chunks/70762-18006a86c770d908.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/layout-2f843ed9eb3944e4.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page-ed4d5692eac763c4.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/page-48b79f200d9f086c.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page-91e61264f483701b.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/new/page-cf90d562352224ec.js +0 -1
- package/.next/standalone/.next/static/chunks/app/onboarding/page-87d43a00d0a7b209.js +0 -1
- /package/.next/standalone/.next/static/{q_ngNQiWgbMewMxZKkQzM → -QBMDLYHMUleR_Nbp3gXV}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{q_ngNQiWgbMewMxZKkQzM → -QBMDLYHMUleR_Nbp3gXV}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { runCommand } from "./run-command.mjs";
|
|
5
|
+
import {
|
|
6
|
+
PI_SUPPORTED_RANGE, PI_MIN_SUPPORTED_VERSION, PI_MAX_SUPPORTED_MAJOR,
|
|
7
|
+
PI_NATIVE_MCP_MIN_VERSION, PI_LEGACY_ADAPTER_SPEC,
|
|
8
|
+
} from "./pi-compatibility.mjs";
|
|
9
|
+
|
|
10
|
+
export const PI_CHORUS_SPEC = "npm:@chorus-aidlc/chorus-pi";
|
|
11
|
+
const ADAPTER = "npm:pi-mcp-adapter";
|
|
12
|
+
const object = (value) => value && typeof value === "object" && !Array.isArray(value);
|
|
13
|
+
const compare = (left, right) => {
|
|
14
|
+
for (let index = 0; index < 3; index++) {
|
|
15
|
+
if (left[index] !== right[index]) return left[index] - right[index];
|
|
16
|
+
}
|
|
17
|
+
return 0;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export function parsePiVersion(output) {
|
|
21
|
+
const unknown = { mode: "unknown", version: null, supported: null,
|
|
22
|
+
reason: "Pi version unknown; run pi --version and confirm a stable supported host before completing MCP setup." };
|
|
23
|
+
if (typeof output !== "string") return unknown;
|
|
24
|
+
const matches = [...output.matchAll(/(?<![\w.+-])v?(\d+)\.(\d+)\.(\d+)(-[\w.-]+)?(?:\+[\w.-]+)?(?![\w.+-])/g)];
|
|
25
|
+
if (matches.length !== 1) return unknown;
|
|
26
|
+
const match = matches[0];
|
|
27
|
+
const parts = match.slice(1, 4).map(Number);
|
|
28
|
+
if (match[4] || parts.some((part) => !Number.isSafeInteger(part)) || match.slice(1, 4).some((part) => /^0\d/.test(part))) return unknown;
|
|
29
|
+
const version = parts.join(".");
|
|
30
|
+
const mode = compare(parts, PI_NATIVE_MCP_MIN_VERSION) >= 0 ? "native" : "legacy";
|
|
31
|
+
const supported = compare(parts, PI_MIN_SUPPORTED_VERSION) >= 0 && parts[0] < PI_MAX_SUPPORTED_MAJOR;
|
|
32
|
+
return { mode, version, supported, reason: supported ? `Pi ${version}: ${mode} MCP backend.`
|
|
33
|
+
: `Pi ${version} is unsupported; Chorus requires stable Pi ${PI_SUPPORTED_RANGE}. No package commands were run.` };
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function probePiBackend({ run = runCommand, env = process.env, cwd } = {}) {
|
|
37
|
+
try {
|
|
38
|
+
const result = run("pi", ["--version"], { env, cwd, timeoutMs: 5_000 });
|
|
39
|
+
return parsePiVersion(result?.ok ? result.stdout : undefined);
|
|
40
|
+
} catch {
|
|
41
|
+
return parsePiVersion(undefined);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function piAgentDir(env = process.env) {
|
|
46
|
+
return env.PI_CODING_AGENT_DIR?.trim() || join(env.HOME || homedir(), ".pi", "agent");
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function piPackageSource(entry, spec) {
|
|
50
|
+
const source = typeof entry === "string" ? entry : object(entry) ? entry.source : undefined;
|
|
51
|
+
return typeof source === "string" && (source === spec || (source.startsWith(`${spec}@`) && source.length > spec.length + 1)) ? source : undefined;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function readSettings(path) {
|
|
55
|
+
try { return JSON.parse(readFileSync(path, "utf8")); }
|
|
56
|
+
catch (error) { if (error.code === "ENOENT") return undefined; throw error; }
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export function inspectPiSettings({ env = process.env, cwd = process.cwd(), readJson = readSettings } = {}) {
|
|
60
|
+
const scopes = [
|
|
61
|
+
{ scope: "global", path: join(piAgentDir(env), "settings.json") },
|
|
62
|
+
{ scope: "current-project", path: join(cwd, ".pi", "settings.json") },
|
|
63
|
+
];
|
|
64
|
+
return scopes.map((entry) => {
|
|
65
|
+
try {
|
|
66
|
+
const settings = readJson(entry.path);
|
|
67
|
+
if (settings !== undefined && (!object(settings) ||
|
|
68
|
+
(settings.packages !== undefined && (!Array.isArray(settings.packages) || settings.packages.some((pkg) =>
|
|
69
|
+
typeof pkg !== "string" && !(object(pkg) && typeof pkg.source === "string")))) ||
|
|
70
|
+
(settings.extensions !== undefined && (!Array.isArray(settings.extensions) || settings.extensions.some((extension) => typeof extension !== "string"))))) throw new Error();
|
|
71
|
+
const packages = settings?.packages ?? [];
|
|
72
|
+
return { ...entry, packages, adapters: packages.map((pkg) => piPackageSource(pkg, ADAPTER)).filter(Boolean),
|
|
73
|
+
chorus: packages.map((pkg) => piPackageSource(pkg, PI_CHORUS_SPEC)).filter(Boolean),
|
|
74
|
+
nativeDisabled: settings?.extensions?.includes("-builtin:mcp") ?? false, uncertain: false };
|
|
75
|
+
} catch {
|
|
76
|
+
return { ...entry, packages: [], adapters: [], chorus: [], nativeDisabled: false, uncertain: true };
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export function piMigrationWarnings(backend, scopes) {
|
|
82
|
+
const warnings = [];
|
|
83
|
+
for (const entry of scopes) {
|
|
84
|
+
if (entry.uncertain) warnings.push(`Cannot safely read ${entry.scope} Pi settings; package/MCP conflict state is uncertain. Inspect that settings.json manually.`);
|
|
85
|
+
if (backend.mode !== "native" || backend.supported === false) continue;
|
|
86
|
+
if (entry.adapters.length) warnings.push(`The ${entry.scope} pi-mcp-adapter replaces native MCP. To use native MCP, manually remove its package entry from ${entry.scope} settings.json (preserve other packages and filters); no adapter was removed or updated.`);
|
|
87
|
+
if (entry.nativeDisabled) warnings.push(`Native MCP is disabled by -builtin:mcp in ${entry.scope} settings.json. Manually re-enable it before expecting native tools; the filter was preserved.`);
|
|
88
|
+
}
|
|
89
|
+
return warnings;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export function readPiPackageState(options = {}) {
|
|
93
|
+
const scopes = inspectPiSettings(options);
|
|
94
|
+
const global = scopes[0];
|
|
95
|
+
const backend = options.backend ?? probePiBackend(options);
|
|
96
|
+
const chorusPiInstalled = global.chorus.length > 0;
|
|
97
|
+
const adapterInstalled = global.adapters.length > 0;
|
|
98
|
+
const adapterCompatible = adapterInstalled && global.adapters.every((source) => source === PI_LEGACY_ADAPTER_SPEC);
|
|
99
|
+
return { marketplaceRegistered: false, chorusPiInstalled, adapterInstalled, adapterCompatible, backend, scopes,
|
|
100
|
+
pluginInstalled: backend.supported === true && chorusPiInstalled && (backend.mode === "native" || adapterCompatible) };
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export function managePiPackages({ backend, scopes, run = runCommand, env = process.env, cwd, update = false }) {
|
|
104
|
+
const warnings = piMigrationWarnings(backend, scopes);
|
|
105
|
+
const details = [backend.reason, ...warnings];
|
|
106
|
+
const global = scopes[0];
|
|
107
|
+
let complete = backend.supported === true, changed = false, failed = false;
|
|
108
|
+
const finish = () => ({ complete, changed, failed, warnings, detail: details.join(" ") });
|
|
109
|
+
if (backend.supported === false || global.uncertain) {
|
|
110
|
+
complete = false;
|
|
111
|
+
return finish();
|
|
112
|
+
}
|
|
113
|
+
const components = backend.mode === "legacy"
|
|
114
|
+
? [{ spec: PI_LEGACY_ADAPTER_SPEC, sources: global.adapters, adapter: true }, { spec: PI_CHORUS_SPEC, sources: global.chorus }]
|
|
115
|
+
: [{ spec: PI_CHORUS_SPEC, sources: global.chorus }];
|
|
116
|
+
const help = new Map();
|
|
117
|
+
for (const component of components) {
|
|
118
|
+
const { spec, sources, adapter } = component;
|
|
119
|
+
const present = sources.length > 0;
|
|
120
|
+
if (adapter && present && sources.some((source) => source !== PI_LEGACY_ADAPTER_SPEC)) {
|
|
121
|
+
complete = false;
|
|
122
|
+
details.push(`Legacy adapter constraints/source are not the verified ${PI_LEGACY_ADAPTER_SPEC} policy pin; settings preserved. Review compatibility manually; latest/ranges are not verified.`);
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
if (present && !update) continue;
|
|
126
|
+
if (adapter && present) {
|
|
127
|
+
details.push(`Retained verified compatibility pin ${PI_LEGACY_ADAPTER_SPEC}; no unbounded adapter update.`);
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
if (present && sources.some((source) => source !== spec && source !== `${spec}@latest`)) {
|
|
131
|
+
complete = false;
|
|
132
|
+
details.push("Chorus version constraints preserved; latest refresh incomplete. Other eligible components were attempted.");
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
const operation = present ? "update" : "install";
|
|
136
|
+
if (!help.has(operation)) {
|
|
137
|
+
const result = run("pi", [operation, "--help"], { env, cwd });
|
|
138
|
+
help.set(operation, result?.ok && /--no-approve\b/.test(result.stdout) &&
|
|
139
|
+
(operation !== "update" || /--extension\s+<source>/.test(result.stdout)));
|
|
140
|
+
}
|
|
141
|
+
if (!help.get(operation)) {
|
|
142
|
+
complete = false;
|
|
143
|
+
details.push(`Pi targeted ${operation} unsupported; no all-extension update was run.`);
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
const args = present ? ["update", "--extension", sources[0], "--no-approve"] : ["install", spec, "--no-approve"];
|
|
147
|
+
changed = true;
|
|
148
|
+
let result;
|
|
149
|
+
try { result = run("pi", args, { env, cwd }); } catch { result = { ok: false }; }
|
|
150
|
+
if (!result?.ok) {
|
|
151
|
+
complete = false;
|
|
152
|
+
failed = true;
|
|
153
|
+
details.push(`Pi ${operation} failed for ${adapter ? "the compatibility adapter" : "Chorus"}; setup incomplete.`);
|
|
154
|
+
if (adapter && !update) break;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
if (complete) details.push(`${changed ? "Refreshed" : "Already installed"} required ${backend.mode} packages only; MCP connectivity is not verified.`);
|
|
158
|
+
else details.push("MCP setup incomplete; resolve the diagnostics and rerun.");
|
|
159
|
+
return finish();
|
|
160
|
+
}
|
|
@@ -1,40 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
// (`~/.pi/agent/mcp.json` by default) so pi's `pi-mcp-adapter` exposes the
|
|
4
|
-
// `chorus_*` tools to the pi agent — the ADAPTER path (chorus.ts never registers
|
|
5
|
-
// tools itself). The Authorization header references the API key by ENV VAR
|
|
6
|
-
// (`Bearer ${CHORUS_API_KEY}`, which pi-mcp-adapter interpolates at connect time),
|
|
7
|
-
// so the `cho_` key lives in exactly ZERO files here — only the env-var reference.
|
|
8
|
-
// The URL is not a secret, so it is written as a resolved literal (an interactive pi
|
|
9
|
-
// then needs only CHORUS_API_KEY in its shell, not CHORUS_URL).
|
|
10
|
-
//
|
|
11
|
-
// This is the pi analogue of cli/init/codex-mcp-config.mjs (Codex's keyless
|
|
12
|
-
// `[mcp_servers.chorus] bearer_token_env_var`) and the CC plugin `.mcp.json`
|
|
13
|
-
// (`Authorization: Bearer ${CHORUS_URL}`-style ${VAR} interpolation). `pi install`
|
|
14
|
-
// does NOT write an mcp.json for us, so `chorus agents add` writes it here (from the
|
|
15
|
-
// credential-seed step, which already holds the resolved URL).
|
|
16
|
-
//
|
|
17
|
-
// CONFIG CONTRACT (VERIFIED against pi-mcp-adapter 2.32.1 npm readme, repo
|
|
18
|
-
// github.com/nicobailon/pi-mcp-adapter):
|
|
19
|
-
// - The adapter discovers a Pi GLOBAL override at `<Pi agent dir>/mcp.json`
|
|
20
|
-
// (`~/.pi/agent/mcp.json` by default, or `$PI_CODING_AGENT_DIR/mcp.json` when set)
|
|
21
|
-
// — the same file `pi-mcp-adapter init` writes to by default, and higher precedence
|
|
22
|
-
// than the tool-agnostic `~/.config/mcp/mcp.json`.
|
|
23
|
-
// - An `mcpServers.<name>` entry supports `type:"http"`, a `url` (raw `${VAR}` /
|
|
24
|
-
// `$env:VAR` interpolation) and `headers` (also `${VAR}` / `$env:VAR`
|
|
25
|
-
// interpolation). We use `headers.Authorization = "Bearer ${CHORUS_API_KEY}"` —
|
|
26
|
-
// the cleanest keyless form, and a one-token change from the literal-Bearer shape
|
|
27
|
-
// CONNECT_PI.md previously documented.
|
|
28
|
-
//
|
|
29
|
-
// Standard JSON merge (mcp.json is JSON, unlike Codex's TOML): every other top-level
|
|
30
|
-
// field and every OTHER `mcpServers.<name>` entry is preserved verbatim; only
|
|
31
|
-
// `mcpServers.chorus` is upserted. Any legacy literal `bearerToken` on the chorus
|
|
32
|
-
// entry is dropped and a literal `headers.Authorization` is replaced by the env-ref,
|
|
33
|
-
// so a re-run MIGRATES an old literal key off disk. Atomic 0600 temp+rename;
|
|
34
|
-
// idempotent (a re-run with the same url reproduces the file). IO is injectable for
|
|
35
|
-
// tests. The API key is NEVER written — only the env-var reference.
|
|
36
|
-
|
|
37
|
-
import { mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
|
|
1
|
+
import { closeSync, mkdirSync, openSync, readFileSync, renameSync, unlinkSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { randomUUID } from "node:crypto";
|
|
38
3
|
import { homedir } from "node:os";
|
|
39
4
|
import { dirname, join } from "node:path";
|
|
40
5
|
|
|
@@ -49,14 +14,13 @@ function nonEmpty(value) {
|
|
|
49
14
|
}
|
|
50
15
|
|
|
51
16
|
/**
|
|
52
|
-
* Resolve the
|
|
53
|
-
*
|
|
54
|
-
* the OS home dir — ending in `mcp.json`. VERIFIED default `~/.pi/agent/mcp.json`.
|
|
17
|
+
* Resolve the global native mcp.json or legacy adapter5 mcp-adapter.json path.
|
|
18
|
+
* Honors PI_CODING_AGENT_DIR, then HOME, then the OS home directory.
|
|
55
19
|
* @param {Record<string, string | undefined>} env
|
|
56
20
|
*/
|
|
57
|
-
export function resolvePiMcpConfigPath(env) {
|
|
21
|
+
export function resolvePiMcpConfigPath(env, backend = {}) {
|
|
58
22
|
const base = nonEmpty(env.PI_CODING_AGENT_DIR) ?? join(nonEmpty(env.HOME) ?? homedir(), ".pi", "agent");
|
|
59
|
-
return join(base, "mcp.json");
|
|
23
|
+
return join(base, backend.mode === "legacy" && backend.supported !== false ? "mcp-adapter.json" : "mcp.json");
|
|
60
24
|
}
|
|
61
25
|
|
|
62
26
|
/**
|
|
@@ -81,7 +45,7 @@ function isPlainObject(v) {
|
|
|
81
45
|
}
|
|
82
46
|
|
|
83
47
|
/**
|
|
84
|
-
* Upsert `mcpServers.chorus` in
|
|
48
|
+
* Upsert `mcpServers.chorus` in the selected backend's global config to
|
|
85
49
|
* { "type": "http", "url": "<mcp-endpoint>", "headers": { "Authorization": "Bearer ${CHORUS_API_KEY}" } }
|
|
86
50
|
* MERGE-SAFE: every other top-level field and every OTHER `mcpServers.<name>` entry is
|
|
87
51
|
* preserved verbatim; on the chorus entry itself every other key (e.g. `toolPrefix`,
|
|
@@ -94,16 +58,16 @@ function isPlainObject(v) {
|
|
|
94
58
|
* the caller treats a throw as a write failure). Atomic 0600 temp+rename; idempotent (a re-run
|
|
95
59
|
* with the same url reproduces the file). The API key is NEVER written — only the env-var
|
|
96
60
|
* reference `${CHORUS_API_KEY}`.
|
|
97
|
-
* @param {{ configPath: string, url: string }} args
|
|
61
|
+
* @param {{ configPath: string, url: string, backend?: object }} args
|
|
98
62
|
* @param {{
|
|
99
63
|
* read?: (p: string) => string,
|
|
100
|
-
* write?: (
|
|
64
|
+
* write?: (descriptor: number, content: string) => void,
|
|
101
65
|
* mkdir?: (p: string, o: object) => void,
|
|
102
66
|
* rename?: (from: string, to: string) => void,
|
|
103
67
|
* }} [deps]
|
|
104
|
-
* @returns {string} the
|
|
68
|
+
* @returns {string} the config path written
|
|
105
69
|
*/
|
|
106
|
-
export function writePiMcpServer({ configPath, url }, deps = {}) {
|
|
70
|
+
export function writePiMcpServer({ configPath, url, backend = {} }, deps = {}) {
|
|
107
71
|
const read = deps.read ?? ((p) => readFileSync(p, "utf8"));
|
|
108
72
|
const write = deps.write ?? writeFileSync;
|
|
109
73
|
const mkdir = deps.mkdir ?? mkdirSync;
|
|
@@ -112,24 +76,34 @@ export function writePiMcpServer({ configPath, url }, deps = {}) {
|
|
|
112
76
|
const mcpUrl = piMcpUrl(url);
|
|
113
77
|
if (!mcpUrl) throw new Error("writePiMcpServer requires a url");
|
|
114
78
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
raw = read(configPath);
|
|
118
|
-
} catch {
|
|
119
|
-
raw = undefined; // no file yet — start fresh
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
let parsed = {};
|
|
123
|
-
if (typeof raw === "string" && raw.trim()) {
|
|
79
|
+
function load(path) {
|
|
80
|
+
let raw;
|
|
124
81
|
try {
|
|
125
|
-
|
|
126
|
-
} catch (
|
|
127
|
-
|
|
82
|
+
raw = read(path);
|
|
83
|
+
} catch (error) {
|
|
84
|
+
if (error.code === "ENOENT") return undefined;
|
|
85
|
+
throw new Error(`cannot read ${path} safely — refusing to overwrite`);
|
|
86
|
+
}
|
|
87
|
+
let parsed;
|
|
88
|
+
try { parsed = JSON.parse(raw); } catch {
|
|
89
|
+
throw new Error(`existing ${path} is not valid JSON — refusing to overwrite`);
|
|
90
|
+
}
|
|
91
|
+
if (!isPlainObject(parsed)) throw new Error(`existing ${path} is not a JSON object — refusing to overwrite`);
|
|
92
|
+
if (parsed.mcpServers !== undefined && !isPlainObject(parsed.mcpServers)) {
|
|
93
|
+
throw new Error(`existing ${path} has a non-object "mcpServers" block — refusing to overwrite`);
|
|
128
94
|
}
|
|
129
|
-
if (!isPlainObject(parsed)) {
|
|
130
|
-
throw new Error(`existing ${
|
|
95
|
+
if (parsed.mcpServers?.chorus !== undefined && !isPlainObject(parsed.mcpServers.chorus)) {
|
|
96
|
+
throw new Error(`existing ${path} has a non-object Chorus server — refusing to overwrite`);
|
|
131
97
|
}
|
|
98
|
+
if (parsed.settings !== undefined && !isPlainObject(parsed.settings)) {
|
|
99
|
+
throw new Error(`existing ${path} has non-object settings — refusing to overwrite`);
|
|
100
|
+
}
|
|
101
|
+
return parsed;
|
|
132
102
|
}
|
|
103
|
+
const legacy = backend.mode === "legacy" && backend.supported !== false;
|
|
104
|
+
let parsed = load(configPath);
|
|
105
|
+
if (legacy && parsed === undefined) parsed = load(join(dirname(configPath), "mcp.json"));
|
|
106
|
+
parsed ??= {};
|
|
133
107
|
|
|
134
108
|
// Preserve an existing `mcpServers` object (and every server in it); a present-but-non-object
|
|
135
109
|
// `mcpServers` is unsafe to merge.
|
|
@@ -150,6 +124,7 @@ export function writePiMcpServer({ configPath, url }, deps = {}) {
|
|
|
150
124
|
|
|
151
125
|
servers.chorus = {
|
|
152
126
|
...chorusRest,
|
|
127
|
+
...(legacy && existingChorus.directTools === undefined && parsed.settings?.directTools === undefined ? { directTools: true } : {}),
|
|
153
128
|
type: "http",
|
|
154
129
|
url: mcpUrl,
|
|
155
130
|
headers: { ...existingHeaders, Authorization: AUTHORIZATION_ENV_REF },
|
|
@@ -159,8 +134,17 @@ export function writePiMcpServer({ configPath, url }, deps = {}) {
|
|
|
159
134
|
const content = `${JSON.stringify(parsed, null, 2)}\n`;
|
|
160
135
|
|
|
161
136
|
mkdir(dirname(configPath), { recursive: true });
|
|
162
|
-
const tmp = `${configPath}.tmp`;
|
|
163
|
-
|
|
164
|
-
|
|
137
|
+
const tmp = `${configPath}.${randomUUID()}.tmp`;
|
|
138
|
+
const descriptor = openSync(tmp, "wx", 0o600);
|
|
139
|
+
try {
|
|
140
|
+
try {
|
|
141
|
+
write(descriptor, content);
|
|
142
|
+
} finally {
|
|
143
|
+
closeSync(descriptor);
|
|
144
|
+
}
|
|
145
|
+
rename(tmp, configPath);
|
|
146
|
+
} finally {
|
|
147
|
+
try { unlinkSync(tmp); } catch (error) { if (error.code !== "ENOENT") throw error; }
|
|
148
|
+
}
|
|
165
149
|
return configPath;
|
|
166
150
|
}
|
package/cli/init/registry.mjs
CHANGED
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
import { ADAPTERS } from "./adapters.mjs";
|
|
18
18
|
import { credentialSeedStep } from "./steps/credential-seed.mjs";
|
|
19
19
|
import { pluginInstallStep } from "./steps/plugin-install.mjs";
|
|
20
|
+
import { codexRestartStep } from "./steps/codex-restart.mjs";
|
|
20
21
|
import { daemonSetupStep } from "./steps/daemon-setup.mjs";
|
|
21
22
|
|
|
22
23
|
/** @typedef {import("./contracts.mjs").AgentAdapter} AgentAdapter */
|
|
@@ -32,10 +33,10 @@ export const AGENT_REGISTRY = [...ADAPTERS];
|
|
|
32
33
|
|
|
33
34
|
/**
|
|
34
35
|
* Configuration steps, run in ascending `order`: credential-seed (10),
|
|
35
|
-
* plugin-install (20), daemon-setup (30).
|
|
36
|
+
* plugin-install (20), codex-restart (25), daemon-setup (30).
|
|
36
37
|
* @type {InitStep[]}
|
|
37
38
|
*/
|
|
38
|
-
export const STEP_REGISTRY = [credentialSeedStep, pluginInstallStep, daemonSetupStep];
|
|
39
|
+
export const STEP_REGISTRY = [credentialSeedStep, pluginInstallStep, codexRestartStep, daemonSetupStep];
|
|
39
40
|
|
|
40
41
|
/**
|
|
41
42
|
* Run every adapter's detection and return one AgentDetection per supported agent.
|
package/cli/init/run-command.mjs
CHANGED
|
@@ -9,7 +9,7 @@ import { spawnSync } from "node:child_process";
|
|
|
9
9
|
* Run a command synchronously.
|
|
10
10
|
* @param {string} cmd
|
|
11
11
|
* @param {string[]} args
|
|
12
|
-
* @param {{ env?: NodeJS.ProcessEnv, timeoutMs?: number, cwd?: string }} [opts]
|
|
12
|
+
* @param {{ env?: NodeJS.ProcessEnv, timeoutMs?: number, cwd?: string, maxBuffer?: number, killSignal?: string }} [opts]
|
|
13
13
|
* @returns {{ ok: boolean, code: number|null, stdout: string, stderr: string, error?: string }}
|
|
14
14
|
*/
|
|
15
15
|
export function runCommand(cmd, args = [], opts = {}) {
|
|
@@ -18,6 +18,8 @@ export function runCommand(cmd, args = [], opts = {}) {
|
|
|
18
18
|
env: opts.env ?? process.env,
|
|
19
19
|
cwd: opts.cwd,
|
|
20
20
|
timeout: opts.timeoutMs ?? 120_000,
|
|
21
|
+
maxBuffer: opts.maxBuffer,
|
|
22
|
+
killSignal: opts.killSignal,
|
|
21
23
|
encoding: "utf8",
|
|
22
24
|
});
|
|
23
25
|
if (r.error) {
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { dirname } from "node:path";
|
|
3
|
+
import { parseEnv } from "node:util";
|
|
4
|
+
import { OUTCOME_ACTIONS, STEP_SCOPES } from "../contracts.mjs";
|
|
5
|
+
import { runCommand } from "../run-command.mjs";
|
|
6
|
+
import { resolveCodexEnvPath } from "./credential-seed.mjs";
|
|
7
|
+
|
|
8
|
+
const MANAGED_KEYS = ["CHORUS_URL", "CHORUS_API_KEY", "CHORUS_AGENT_PROFILE"];
|
|
9
|
+
const MAX_OUTPUT = 64 * 1024;
|
|
10
|
+
|
|
11
|
+
export const codexRestartStep = {
|
|
12
|
+
id: "codex-restart",
|
|
13
|
+
order: 25,
|
|
14
|
+
scope: STEP_SCOPES.PER_AGENT,
|
|
15
|
+
async run(ctx) {
|
|
16
|
+
if (ctx.agentId !== "codex" || ctx.flags?.pluginOnly) return [];
|
|
17
|
+
|
|
18
|
+
const env = ctx.env ?? process.env;
|
|
19
|
+
const envPath = resolveCodexEnvPath(env);
|
|
20
|
+
const codexHome = dirname(envPath);
|
|
21
|
+
const guidance = `Configuration directory: ${JSON.stringify(codexHome)}. ` +
|
|
22
|
+
"For manual recovery, inspect `codex app-server daemon restart --help` for support first. " +
|
|
23
|
+
"Before restarting a running daemon, load CHORUS_URL, CHORUS_API_KEY and CHORUS_AGENT_PROFILE " +
|
|
24
|
+
"from that directory's .env as environment data (not shell code), using the same CODEX_HOME. " +
|
|
25
|
+
"Restarting can interrupt other Codex sessions; no daemon is started or upgraded by this step.";
|
|
26
|
+
const outcome = (action, detail) => ({ stepId: "codex-restart", agentId: "codex", action, detail });
|
|
27
|
+
const defer = (reason) => outcome(OUTCOME_ACTIONS.SKIPPED, `Codex App Server restart deferred: ${reason}. ${guidance}`);
|
|
28
|
+
const prior = ctx.priorOutcomes ?? [];
|
|
29
|
+
const seeded = prior.some((entry) => entry.stepId === "credential-seed" &&
|
|
30
|
+
[OUTCOME_ACTIONS.SEEDED, OUTCOME_ACTIONS.SKIPPED].includes(entry.action) && entry.codexEnvWritten === true);
|
|
31
|
+
const configured = prior.some((entry) => entry.stepId === "plugin-install" && entry.agentId === "codex" &&
|
|
32
|
+
[OUTCOME_ACTIONS.INSTALLED, OUTCOME_ACTIONS.REPAIRED, OUTCOME_ACTIONS.SKIPPED].includes(entry.action) &&
|
|
33
|
+
entry.codexMcpWritten === true);
|
|
34
|
+
if (!seeded || !configured) return defer("credential persistence or plugin configuration did not complete");
|
|
35
|
+
if (!ctx.io?.isTTY || ctx.flags?.yes || env.CHORUS_DAEMON_HEADLESS === "1" || typeof ctx.io?.ask !== "function") {
|
|
36
|
+
return defer("a dedicated interactive confirmation is required (--yes does not authorize restart)");
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
let childEnv;
|
|
40
|
+
try {
|
|
41
|
+
const persisted = parseEnv(readFileSync(envPath, "utf8"));
|
|
42
|
+
if (MANAGED_KEYS.some((key) => !persisted[key]?.trim())) return defer("saved environment is incomplete");
|
|
43
|
+
childEnv = { ...env, CODEX_HOME: codexHome };
|
|
44
|
+
for (const key of MANAGED_KEYS) childEnv[key] = persisted[key];
|
|
45
|
+
} catch {
|
|
46
|
+
return defer("saved environment could not be read");
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const run = ctx.run ?? runCommand;
|
|
50
|
+
const command = async (args, timeoutMs = 5_000) => {
|
|
51
|
+
try {
|
|
52
|
+
const result = await run("codex", ["app-server", "daemon", ...args], {
|
|
53
|
+
env: childEnv, timeoutMs, maxBuffer: MAX_OUTPUT, killSignal: "SIGKILL",
|
|
54
|
+
});
|
|
55
|
+
if (!result?.ok || typeof result.stdout !== "string" || result.stdout.length > MAX_OUTPUT ||
|
|
56
|
+
(result.stderr?.length ?? 0) > MAX_OUTPUT) return null;
|
|
57
|
+
return result;
|
|
58
|
+
} catch {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
const help = await command(["restart", "--help"]);
|
|
63
|
+
if (!help || !/\bUsage:\s+codex app-server daemon restart\b/.test(help.stdout)) {
|
|
64
|
+
return defer("restart support could not be confirmed (missing/older CLI or failed probe)");
|
|
65
|
+
}
|
|
66
|
+
const version = await command(["version"]);
|
|
67
|
+
let status;
|
|
68
|
+
try {
|
|
69
|
+
status = JSON.parse(version?.stdout).status;
|
|
70
|
+
} catch {
|
|
71
|
+
return defer("daemon state could not be determined");
|
|
72
|
+
}
|
|
73
|
+
if (status === "stopped") return defer("no running daemon; nothing was started");
|
|
74
|
+
if (status !== "running") return defer("daemon state is unknown");
|
|
75
|
+
|
|
76
|
+
let answer;
|
|
77
|
+
try {
|
|
78
|
+
answer = await ctx.io.ask(
|
|
79
|
+
"Restart the running Codex App Server with the saved Chorus environment? " +
|
|
80
|
+
"This can interrupt other Codex sessions and active work. [y/N] ",
|
|
81
|
+
);
|
|
82
|
+
} catch {
|
|
83
|
+
return defer("confirmation was unavailable");
|
|
84
|
+
}
|
|
85
|
+
if (typeof answer !== "string" || !/^(?:y|yes)$/i.test(answer.trim())) return defer("not explicitly confirmed");
|
|
86
|
+
|
|
87
|
+
const restarted = await command(["restart"], 30_000);
|
|
88
|
+
if (!restarted) {
|
|
89
|
+
return outcome(OUTCOME_ACTIONS.FAILED, "Codex App Server restart command failed or timed out; " +
|
|
90
|
+
`saved configuration remains in place. ${guidance}`);
|
|
91
|
+
}
|
|
92
|
+
return outcome(OUTCOME_ACTIONS.REPAIRED,
|
|
93
|
+
"Codex App Server restart command succeeded with the saved environment; credentials and MCP connectivity were not verified.");
|
|
94
|
+
},
|
|
95
|
+
};
|
|
@@ -54,6 +54,7 @@ import { resolveInstallCwds as defaultResolveInstallCwds } from "../../daemon-in
|
|
|
54
54
|
import { validateAndFetchIdentity } from "../../chorus-client.mjs";
|
|
55
55
|
import { agentTypeForSelection, isWakeableAgentType } from "../agent-type-map.mjs";
|
|
56
56
|
import { writePiMcpServer, resolvePiMcpConfigPath } from "../pi-mcp-config.mjs";
|
|
57
|
+
import { probePiBackend } from "../pi-mcp-backend.mjs";
|
|
57
58
|
|
|
58
59
|
const STEP_ID = "credential-seed";
|
|
59
60
|
const { SEEDED, SKIPPED, FAILED } = OUTCOME_ACTIONS;
|
|
@@ -356,7 +357,7 @@ function isCodexSelection(id) {
|
|
|
356
357
|
* literal `[mcp_servers.chorus]` Bearer lives separately in `config.toml` and is untouched.
|
|
357
358
|
* @param {Record<string, string | undefined>} env
|
|
358
359
|
*/
|
|
359
|
-
function resolveCodexEnvPath(env) {
|
|
360
|
+
export function resolveCodexEnvPath(env) {
|
|
360
361
|
const base = nonEmpty(env.CODEX_HOME) ?? join(nonEmpty(env.HOME) ?? homedir(), ".codex");
|
|
361
362
|
return join(base, ".env");
|
|
362
363
|
}
|
|
@@ -423,16 +424,13 @@ export function readCodexEnvProfile(envPath, deps = {}) {
|
|
|
423
424
|
}
|
|
424
425
|
|
|
425
426
|
/**
|
|
426
|
-
* Whether an init selection id is Pi (`pi`).
|
|
427
|
-
*
|
|
428
|
-
* — like Codex's `[mcp_servers.chorus]` — `chorus agents add` writes pi's global
|
|
429
|
-
* `~/.pi/agent/mcp.json` with an `mcpServers.chorus` entry whose Authorization references
|
|
427
|
+
* Whether an init selection id is Pi (`pi`). Native MCP or the legacy adapter reads
|
|
428
|
+
* the selected global config with an mcpServers.chorus entry whose Authorization references
|
|
430
429
|
* the API key by ENV VAR (`Bearer ${CHORUS_API_KEY}`), NO literal key on disk. Unlike dsh /
|
|
431
430
|
* Claude Code / Codex, pi has NO settings env-file to persist the key + profile into, so this
|
|
432
431
|
* write does NOT suppress the CHORUS_AGENT_PROFILE export hint: interactive pi still needs
|
|
433
432
|
* CHORUS_API_KEY (+ CHORUS_AGENT_PROFILE) exported in its shell. We gate on the selection id,
|
|
434
|
-
*
|
|
435
|
-
* out). Mirrors {@link isDshSelection} / {@link isClaudeSelection} / {@link isCodexSelection}.
|
|
433
|
+
* not other hosts. Mirrors {@link isDshSelection} / {@link isClaudeSelection} / {@link isCodexSelection}.
|
|
436
434
|
* @param {string} id
|
|
437
435
|
*/
|
|
438
436
|
function isPiSelection(id) {
|
|
@@ -706,8 +704,8 @@ export async function seedCredentials(ctx) {
|
|
|
706
704
|
// "start codex from an exporting shell", no wrapper. Key never echoed.
|
|
707
705
|
codexNote =
|
|
708
706
|
`; wrote CHORUS_URL/CHORUS_API_KEY/CHORUS_AGENT_PROFILE into ${p} (0600)${repointWarn} — ` +
|
|
709
|
-
"
|
|
710
|
-
"
|
|
707
|
+
"new Codex processes load this environment for plugin hooks and shell-tool `chorus` calls; " +
|
|
708
|
+
"running App Server sessions may still use the old environment. Your cho_ key is not shown here.";
|
|
711
709
|
} catch (err) {
|
|
712
710
|
// Write failed (locked/unwritable). Emit an actionable, non-secret WARNING; the export
|
|
713
711
|
// hint is still shown (codexEnvWritten stays false). No launcher wrapper.
|
|
@@ -727,8 +725,7 @@ export async function seedCredentials(ctx) {
|
|
|
727
725
|
}
|
|
728
726
|
}
|
|
729
727
|
|
|
730
|
-
// pi-only:
|
|
731
|
-
// chorus_* tools to the pi agent (the ADAPTER path — chorus.ts never registers tools). The
|
|
728
|
+
// pi-only: write the selected native or legacy backend's global MCP configuration. The
|
|
732
729
|
// Authorization header references the key by env var (`Bearer ${CHORUS_API_KEY}`), so NO
|
|
733
730
|
// literal cho_ key is written — the pi analogue of Codex's keyless [mcp_servers.chorus]
|
|
734
731
|
// bearer_token_env_var and CC's plugin .mcp.json ${VAR} interpolation. The URL is not a
|
|
@@ -741,18 +738,22 @@ export async function seedCredentials(ctx) {
|
|
|
741
738
|
let piNote = "";
|
|
742
739
|
let piMcpWritten = false;
|
|
743
740
|
if (isPiSelection(id)) {
|
|
744
|
-
const
|
|
741
|
+
const backend = probePiBackend({ run: ctx.run, env, cwd: ctx.cwd });
|
|
742
|
+
const configPath = resolvePiMcpConfigPath(env, backend);
|
|
745
743
|
try {
|
|
746
|
-
const p = writePiMcp({ configPath, url });
|
|
744
|
+
const p = writePiMcp({ configPath, url, backend });
|
|
747
745
|
piMcpWritten = true;
|
|
748
746
|
piNote =
|
|
749
747
|
`; wrote mcpServers.chorus (Authorization: Bearer \${CHORUS_API_KEY}) into ${p} (0600) — ` +
|
|
750
|
-
|
|
751
|
-
|
|
748
|
+
(backend.supported !== true ? `${backend.reason} MCP setup is incomplete. ` : backend.mode === "native"
|
|
749
|
+
? "native MCP uses its default codemode; no adapter is required. "
|
|
750
|
+
: "legacy pi-mcp-adapter 5.0.0 uses mcp-adapter.json (takes precedence over migrated mcp.json). Fresh Chorus configuration enables directTools:true; existing user choices are preserved. Direct tool exposure is required for workflow/reviewer tool names. ") +
|
|
751
|
+
"Package/configuration setup does not verify live MCP connectivity. No literal key is written. " +
|
|
752
|
+
"Interactive pi still needs CHORUS_API_KEY (+ CHORUS_AGENT_PROFILE) exported in its " +
|
|
752
753
|
"shell; the daemon injects them for the wake path. Your cho_ key is not shown here.";
|
|
753
|
-
} catch
|
|
754
|
+
} catch {
|
|
754
755
|
piNote =
|
|
755
|
-
`; WARNING: could not write ${configPath}
|
|
756
|
+
`; WARNING: could not write ${configPath} safely; inspect existing configuration without overwriting it. ` +
|
|
756
757
|
"pi will not reach Chorus MCP until an mcpServers.chorus entry with an env-referenced " +
|
|
757
758
|
`Authorization (Bearer \${CHORUS_API_KEY}) exists — add it to ${configPath}. ` +
|
|
758
759
|
"Your cho_ key is not shown here.";
|
package/cli/init.mjs
CHANGED
|
@@ -125,10 +125,10 @@ export async function runInit(argv = [], deps = {}) {
|
|
|
125
125
|
if (step.scope === STEP_SCOPES.PER_AGENT) {
|
|
126
126
|
for (const agentId of selectedIds) {
|
|
127
127
|
const adapter = adapters.get(agentId);
|
|
128
|
-
outcomes.push(await step.run({ ...baseCtx, agentId, adapter }));
|
|
128
|
+
outcomes.push(await step.run({ ...baseCtx, agentId, adapter, priorOutcomes: outcomes.flat() }));
|
|
129
129
|
}
|
|
130
130
|
} else {
|
|
131
|
-
outcomes.push(await step.run(baseCtx));
|
|
131
|
+
outcomes.push(await step.run({ ...baseCtx, priorOutcomes: outcomes.flat() }));
|
|
132
132
|
}
|
|
133
133
|
} catch (err) {
|
|
134
134
|
// A crashing step becomes a visible failed outcome, never a silent abort.
|
package/cli/upgrade-plugins.mjs
CHANGED
|
@@ -7,6 +7,7 @@ import { readClaudeInstallState } from "./init/adapters.mjs";
|
|
|
7
7
|
import { installClaude, installCodex, installKiro, readCodexInstallState } from "./init/install-methods.mjs";
|
|
8
8
|
import { normalizeAssetBase } from "./init/file-template.mjs";
|
|
9
9
|
import { runUpgradeCommand, sanitizeUpgradeOutput, upgradeFailure } from "./upgrade-process.mjs";
|
|
10
|
+
import { probePiBackend, inspectPiSettings, managePiPackages } from "./init/pi-mcp-backend.mjs";
|
|
10
11
|
|
|
11
12
|
const HOSTS = {
|
|
12
13
|
claude: { binary: "claude", variable: "CLAUDE_CONFIG_DIR", dir: [".claude"] },
|
|
@@ -86,47 +87,11 @@ function readJson(path, io) {
|
|
|
86
87
|
catch (e) { if (e.code === "ENOENT") return undefined; throw e; }
|
|
87
88
|
}
|
|
88
89
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
throw new Error("invalid Pi settings");
|
|
95
|
-
}
|
|
96
|
-
const packages = settings?.packages ?? [];
|
|
97
|
-
let complete = true, changed = false, constrained = false;
|
|
98
|
-
const help = run("pi", ["update", "--help"]);
|
|
99
|
-
const targeted = help.ok && /--extension\s+<source>/.test(help.stdout) && /--no-approve\b/.test(help.stdout);
|
|
100
|
-
let installHelp;
|
|
101
|
-
for (const spec of ["npm:pi-mcp-adapter", "npm:@chorus-aidlc/chorus-pi"]) {
|
|
102
|
-
const sources = packages.map((entry) => {
|
|
103
|
-
const source = typeof entry === "string" ? entry : entry?.source;
|
|
104
|
-
return source;
|
|
105
|
-
}).filter((source) => source === spec || (typeof source === "string" && source.startsWith(`${spec}@`)));
|
|
106
|
-
const present = sources.length > 0;
|
|
107
|
-
// Pi updates by identity but retains configured constraints. Pinned versions
|
|
108
|
-
// are a successful no-op; ranges/tags can also exclude the latest release.
|
|
109
|
-
// Preserve those settings and report incomplete rather than silently unpin.
|
|
110
|
-
if (sources.some((source) => source !== spec && source !== `${spec}@latest`)) {
|
|
111
|
-
complete = false;
|
|
112
|
-
constrained = true;
|
|
113
|
-
continue;
|
|
114
|
-
}
|
|
115
|
-
if (present && !targeted) { complete = false; continue; }
|
|
116
|
-
if (!present) {
|
|
117
|
-
installHelp ??= run("pi", ["install", "--help"]);
|
|
118
|
-
if (!installHelp.ok || !/--no-approve\b/.test(installHelp.stdout)) { complete = false; continue; }
|
|
119
|
-
}
|
|
120
|
-
const r = run("pi", present ? ["update", "--extension", spec, "--no-approve"] : ["install", spec, "--no-approve"]);
|
|
121
|
-
changed = true; // A failed command can still leave a partial change.
|
|
122
|
-
if (!r.ok) complete = false;
|
|
123
|
-
}
|
|
124
|
-
return {
|
|
125
|
-
complete, changed,
|
|
126
|
-
detail: complete ? "Refreshed Chorus and pi-mcp-adapter only."
|
|
127
|
-
: constrained ? "Pi refresh incomplete: configured package version constraints were preserved; remove those constraints to permit latest updates. Other eligible components were attempted."
|
|
128
|
-
: "Pi refresh incomplete: targeted update/install unsupported or failed; no all-extension update was run.",
|
|
129
|
-
};
|
|
90
|
+
export function upgradePi(target, { run, fs: io = fs, cwd = process.cwd() }) {
|
|
91
|
+
const env = { ...target.env, PI_CODING_AGENT_DIR: target.destination };
|
|
92
|
+
const backend = probePiBackend({ run, env });
|
|
93
|
+
const scopes = inspectPiSettings({ env, cwd, readJson: (path) => readJson(path, io) });
|
|
94
|
+
return managePiPackages({ backend, scopes, run, env, update: true });
|
|
130
95
|
}
|
|
131
96
|
|
|
132
97
|
export async function upgradePlugins(deps = {}) {
|
|
@@ -160,14 +125,14 @@ export async function upgradePlugins(deps = {}) {
|
|
|
160
125
|
try {
|
|
161
126
|
// Package commands must not discover project-local plugin configuration.
|
|
162
127
|
scratch = io.mkdtempSync(join(tmpdir(), "chorus-upgrade-"));
|
|
163
|
-
const run = (cmd, args) => {
|
|
164
|
-
if (!args.includes("--help")) changed = true;
|
|
165
|
-
const result = (deps.run ?? runUpgradeCommand)(cmd, args, { env: target.env, platform, cwd: scratch, timeoutMs: 120_000 });
|
|
128
|
+
const run = (cmd, args, options = {}) => {
|
|
129
|
+
if (!args.includes("--help") && !args.includes("--version")) changed = true;
|
|
130
|
+
const result = (deps.run ?? runUpgradeCommand)(cmd, args, { env: target.env, platform, cwd: scratch, timeoutMs: options.timeoutMs ?? 120_000 });
|
|
166
131
|
if (!result.ok) failures.push(`${cmd} ${args.slice(0, 2).join(" ")}: ${upgradeFailure(result, { env: target.env })}`);
|
|
167
132
|
return result;
|
|
168
133
|
};
|
|
169
134
|
if (target.type === "pi") {
|
|
170
|
-
const result = upgradePi(target, { run, fs: io });
|
|
135
|
+
const result = upgradePi(target, { run, fs: io, cwd: deps.cwd });
|
|
171
136
|
results.push({ target: label, ...result, detail: safe([result.detail, ...failures].join("\n")) });
|
|
172
137
|
continue;
|
|
173
138
|
}
|