@chorus-aidlc/chorus 0.8.2 → 0.9.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 +289 -289
- package/.next/standalone/.next/app-path-routes-manifest.json +36 -36
- package/.next/standalone/.next/build-manifest.json +5 -5
- package/.next/standalone/.next/prerender-manifest.json +48 -48
- 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.js.nft.json +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 +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/[ideaUuid]/page.js.nft.json +1 -1
- 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 +2 -2
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page.js.nft.json +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 +2 -2
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/documents/page.js.nft.json +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]/ideas/[ideaUuid]/page.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/ideas/[ideaUuid]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/ideas/[ideaUuid]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/ideas/page.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/ideas/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/ideas/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 +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/new/page.js.nft.json +1 -1
- 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 +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/page.js.nft.json +1 -1
- 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 +3 -3
- 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 +1 -1
- package/.next/standalone/.next/server/app/_not-found.rsc +2 -2
- 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 +1 -1
- package/.next/standalone/.next/server/app/admin/companies/new.rsc +2 -2
- package/.next/standalone/.next/server/app/admin/companies/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/admin/companies.html +1 -1
- package/.next/standalone/.next/server/app/admin/companies.rsc +2 -2
- package/.next/standalone/.next/server/app/admin/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/admin.html +1 -1
- package/.next/standalone/.next/server/app/admin.rsc +2 -2
- 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/agents/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/agents/[uuid]/sessions/route.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/refresh/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/auth/session/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/documents/[uuid]/route.js +1 -1
- package/.next/standalone/.next/server/app/api/documents/[uuid]/route.js.nft.json +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/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.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/claim/route.js.nft.json +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.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/move/preview/route.js.nft.json +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.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/move/route.js.nft.json +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]/release/route.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/release/route.js.nft.json +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.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/route.js.nft.json +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/mcp/route.js +5 -5
- 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.js +1 -1
- package/.next/standalone/.next/server/app/api/me/assignments/route.js.nft.json +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]/dashboard/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/projects/[uuid]/activity/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/available/route.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/available/route.js.nft.json +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.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/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/route.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/route.js.nft.json +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.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/tracker/route.js.nft.json +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]/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]/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/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/search/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/sessions/[uuid]/route.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.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 +1 -1
- package/.next/standalone/.next/server/app/index.rsc +2 -2
- package/.next/standalone/.next/server/app/login/admin/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/login/admin.html +1 -1
- package/.next/standalone/.next/server/app/login/admin.rsc +2 -2
- package/.next/standalone/.next/server/app/login/callback/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/login/callback.html +1 -1
- package/.next/standalone/.next/server/app/login/callback.rsc +2 -2
- 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 +1 -1
- package/.next/standalone/.next/server/app/login/pick-workspace.rsc +2 -2
- package/.next/standalone/.next/server/app/login/silent-refresh/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/login/silent-refresh.html +1 -1
- package/.next/standalone/.next/server/app/login/silent-refresh.rsc +2 -2
- package/.next/standalone/.next/server/app/login.html +1 -1
- package/.next/standalone/.next/server/app/login.rsc +2 -2
- package/.next/standalone/.next/server/app/onboarding/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/onboarding.html +1 -1
- 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 +1 -1
- package/.next/standalone/.next/server/app/projects.rsc +4 -4
- package/.next/standalone/.next/server/app/settings.html +1 -1
- package/.next/standalone/.next/server/app/settings.rsc +4 -4
- package/.next/standalone/.next/server/app-paths-manifest.json +36 -36
- package/.next/standalone/.next/server/chunks/162.js +16 -0
- package/.next/standalone/.next/server/chunks/1871.js +1 -1
- package/.next/standalone/.next/server/chunks/2618.js +1 -1
- package/.next/standalone/.next/server/chunks/2961.js +1 -1
- package/.next/standalone/.next/server/chunks/4043.js +1 -0
- package/.next/standalone/.next/server/chunks/4090.js +2 -2
- package/.next/standalone/.next/server/chunks/5044.js +1 -1
- package/.next/standalone/.next/server/chunks/6113.js +1 -1
- package/.next/standalone/.next/server/chunks/6207.js +1 -1
- package/.next/standalone/.next/server/chunks/6592.js +1 -0
- package/.next/standalone/.next/server/chunks/6643.js +1 -1
- package/.next/standalone/.next/server/chunks/7368.js +1 -1
- package/.next/standalone/.next/server/chunks/7578.js +2 -2
- package/.next/standalone/.next/server/chunks/8637.js +1 -1
- package/.next/standalone/.next/server/chunks/920.js +1 -1
- package/.next/standalone/.next/server/chunks/937.js +1 -1
- package/.next/standalone/.next/server/chunks/9508.js +2 -2
- package/.next/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/.next/standalone/.next/server/middleware-manifest.json +1 -1
- package/.next/standalone/.next/server/pages/404.html +1 -1
- package/.next/standalone/.next/server/pages/500.html +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/3853-f94afe2f83089c0d.js +1 -0
- package/.next/standalone/.next/static/chunks/44046-5c0f7f8c0914988a.js +1 -0
- package/.next/standalone/.next/static/chunks/{4860.4aa0288b2953186b.js → 4860.60152a625f2a714f.js} +1 -1
- package/.next/standalone/.next/static/chunks/6028-fe4175ea5e6241ed.js +1 -0
- package/.next/standalone/.next/static/chunks/93346-c4468893138daac7.js +1 -0
- package/.next/standalone/.next/static/chunks/{99373.00844a02fe44575b.js → 99373.4d93aaaf56fe7819.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/layout-8409ca03f132910b.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/dashboard/page-7f7a7f654cab4dc3.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/page-95cdcec5e6db551f.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/page-c36345b80cc5bf5c.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/settings/{page-a01b45dbe80aeecf.js → page-b153aa34b940a24c.js} +1 -1
- package/.next/standalone/.next/static/chunks/{webpack-b999409365c6a0aa.js → webpack-8e0df5e10bc6b98f.js} +1 -1
- package/.next/standalone/.next/static/css/ea3f196c7951f8d6.css +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/agents/proposal-reviewer.md +1 -1
- package/.next/standalone/public/chorus-plugin/agents/task-reviewer.md +1 -1
- package/.next/standalone/public/chorus-plugin/bin/on-post-verify-task.sh +198 -115
- package/.next/standalone/public/chorus-plugin/bin/tests/test-on-post-verify-task.sh +302 -50
- package/.next/standalone/public/chorus-plugin/skills/brainstorm/SKILL.md +166 -0
- package/.next/standalone/public/chorus-plugin/skills/chorus/SKILL.md +10 -6
- package/.next/standalone/public/chorus-plugin/skills/develop/SKILL.md +6 -2
- package/.next/standalone/public/chorus-plugin/skills/idea/SKILL.md +17 -1
- package/.next/standalone/public/chorus-plugin/skills/openspec-aware/SKILL.md +1 -1
- package/.next/standalone/public/chorus-plugin/skills/proposal/SKILL.md +6 -7
- package/.next/standalone/public/chorus-plugin/skills/quick-dev/SKILL.md +1 -1
- package/.next/standalone/public/chorus-plugin/skills/review/SKILL.md +1 -1
- package/.next/standalone/public/chorus-plugin/skills/yolo/SKILL.md +7 -1
- package/.next/standalone/public/skill/brainstorm-chorus/SKILL.md +166 -0
- package/.next/standalone/public/skill/chorus/SKILL.md +10 -6
- package/.next/standalone/public/skill/develop-chorus/SKILL.md +5 -1
- package/.next/standalone/public/skill/idea-chorus/SKILL.md +17 -1
- package/.next/standalone/public/skill/package.json +1 -1
- package/.next/standalone/public/skill/proposal-chorus/SKILL.md +6 -7
- package/.next/standalone/public/skill/quick-dev-chorus/SKILL.md +1 -1
- package/.next/standalone/public/skill/review-chorus/SKILL.md +1 -1
- package/README.md +2 -4
- package/README.zh.md +2 -4
- package/package.json +1 -1
- package/prisma/migrations/20260524144057_remove_session_expires_at/migration.sql +11 -0
- package/prisma/schema.prisma +2 -2
- package/.next/standalone/.next/server/chunks/554.js +0 -1
- package/.next/standalone/.next/server/chunks/5869.js +0 -16
- package/.next/standalone/.next/server/chunks/8163.js +0 -1
- package/.next/standalone/.next/static/chunks/25846-d1c43e3a187a0c82.js +0 -1
- package/.next/standalone/.next/static/chunks/44046-732e5888413d45df.js +0 -1
- package/.next/standalone/.next/static/chunks/6028-0fcaf8b495e9bfc8.js +0 -1
- package/.next/standalone/.next/static/chunks/93346-9258abbb12887208.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/layout-5e2b4f48ec70f0e8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/dashboard/page-ae96fc9386afff88.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/page-062c6fef8aef25a6.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/page-5326f2b34b200e50.js +0 -1
- package/.next/standalone/.next/static/css/a3f1e693b51f7540.css +0 -1
- /package/.next/standalone/.next/static/{3AEr6cS1BaPlwTuyPvMQF → yBxnuARbl0brBJS3_STaI}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{3AEr6cS1BaPlwTuyPvMQF → yBxnuARbl0brBJS3_STaI}/_ssgManifest.js +0 -0
|
@@ -12,7 +12,11 @@
|
|
|
12
12
|
# hook into a sandbox dir alongside our shim wrapper — the hook's
|
|
13
13
|
# `dirname "$0"` lookup then picks up our shim, not the real wrapper.
|
|
14
14
|
#
|
|
15
|
-
#
|
|
15
|
+
# Two independent reminder branches share the post-verify trigger:
|
|
16
|
+
# - Branch A (OpenSpec archive trigger) — emits `openspec archive`
|
|
17
|
+
# - Branch B (Idea-completion report) — emits `create idea-completion report`
|
|
18
|
+
#
|
|
19
|
+
# Fixtures for Branch A (legacy):
|
|
16
20
|
# positive — last task verified, slug present, openspec/ folder + CLI both present
|
|
17
21
|
# -> stdout MUST contain `openspec archive my-feature`
|
|
18
22
|
# not-last-task — slug present, both signals present, but one task still in_progress
|
|
@@ -26,6 +30,30 @@
|
|
|
26
30
|
# mode-off — CHORUS_OPENSPEC_MODE=off (explicit opt-out), even with both signals present
|
|
27
31
|
# -> stdout MUST NOT contain `openspec archive`
|
|
28
32
|
#
|
|
33
|
+
# Fixtures for Branch B (idea-completion report — see spec
|
|
34
|
+
# idea-completion-report scenarios "Hook injects a reminder ..."):
|
|
35
|
+
# report-positive — idea-rooted proposal, all its tasks are
|
|
36
|
+
# done|closed, no report Document on this proposal
|
|
37
|
+
# -> stdout MUST contain `create idea-completion report`
|
|
38
|
+
# report-existing — same as report-positive but a `type=report`
|
|
39
|
+
# Document already exists on this proposal
|
|
40
|
+
# -> stdout MUST NOT contain `create idea-completion report`
|
|
41
|
+
# report-not-last — idea-rooted, but one task is still in_progress
|
|
42
|
+
# -> stdout MUST NOT contain `create idea-completion report`
|
|
43
|
+
# report-quick-task — proposal's inputType is not "idea" (e.g. a
|
|
44
|
+
# non-idea-rooted proposal); branch B must skip
|
|
45
|
+
# regardless of task status
|
|
46
|
+
# -> stdout MUST NOT contain `create idea-completion report`
|
|
47
|
+
# report-task-overflow — chorus_list_tasks returns total > tasks.length
|
|
48
|
+
# (page-1 of a wider task set, all returned tasks
|
|
49
|
+
# are done but more remain). Hook MUST refuse to
|
|
50
|
+
# conclude "all done" — silent skip.
|
|
51
|
+
# -> stdout MUST NOT contain `create idea-completion report`
|
|
52
|
+
# report-doc-overflow — chorus_get_documents returns total > documents.length
|
|
53
|
+
# (existing report sits on a later page). Hook MUST
|
|
54
|
+
# refuse to conclude "no report" — silent skip.
|
|
55
|
+
# -> stdout MUST NOT contain `create idea-completion report`
|
|
56
|
+
#
|
|
29
57
|
# All fixtures must end with exit 0.
|
|
30
58
|
#
|
|
31
59
|
# Bash 3.2 compatible. Run:
|
|
@@ -90,11 +118,18 @@ case "$cmd" in
|
|
|
90
118
|
mode-off|no-folder|no-cli) fixture=positive ;;
|
|
91
119
|
esac
|
|
92
120
|
case "${fixture}:${tool}" in
|
|
121
|
+
# ----- Branch A fixtures (existing) -----
|
|
122
|
+
# NOTE: Branch B's idea-rooted check requires `inputType:"idea"`. We
|
|
123
|
+
# set it on the OpenSpec fixtures too because real proposals always
|
|
124
|
+
# carry inputType. To keep Branch A fixtures independent of Branch B,
|
|
125
|
+
# we deliberately DO NOT register chorus_get_proposals /
|
|
126
|
+
# chorus_get_documents responses for them — Branch B hits the default
|
|
127
|
+
# "unhandled" case (empty body) and silent-skips.
|
|
93
128
|
positive:chorus_get_task)
|
|
94
129
|
echo '{"uuid":"task-3","title":"Task 3","status":"done","proposalUuid":"prop-1","project":{"uuid":"proj-1","name":"P"}}'
|
|
95
130
|
;;
|
|
96
131
|
positive:chorus_get_proposal)
|
|
97
|
-
printf '%s' '{"uuid":"prop-1","title":"P1","description":"Some intro line.\nOpenSpec change slug: my-feature\nMore body.","inputUuids":["idea-1"]}'
|
|
132
|
+
printf '%s' '{"uuid":"prop-1","title":"P1","description":"Some intro line.\nOpenSpec change slug: my-feature\nMore body.","inputType":"idea","inputUuids":["idea-1"]}'
|
|
98
133
|
;;
|
|
99
134
|
positive:chorus_list_tasks)
|
|
100
135
|
echo '{"tasks":[{"uuid":"task-1","status":"done"},{"uuid":"task-2","status":"done"},{"uuid":"task-3","status":"done"}],"total":3,"page":1,"pageSize":200}'
|
|
@@ -103,7 +138,7 @@ case "$cmd" in
|
|
|
103
138
|
echo '{"uuid":"task-2","title":"Task 2","status":"done","proposalUuid":"prop-1","project":{"uuid":"proj-1","name":"P"}}'
|
|
104
139
|
;;
|
|
105
140
|
not-last-task:chorus_get_proposal)
|
|
106
|
-
printf '%s' '{"uuid":"prop-1","title":"P1","description":"Intro.\nOpenSpec change slug: my-feature\nMore.","inputUuids":["idea-1"]}'
|
|
141
|
+
printf '%s' '{"uuid":"prop-1","title":"P1","description":"Intro.\nOpenSpec change slug: my-feature\nMore.","inputType":"idea","inputUuids":["idea-1"]}'
|
|
107
142
|
;;
|
|
108
143
|
not-last-task:chorus_list_tasks)
|
|
109
144
|
echo '{"tasks":[{"uuid":"task-1","status":"done"},{"uuid":"task-2","status":"done"},{"uuid":"task-3","status":"in_progress"}],"total":3,"page":1,"pageSize":200}'
|
|
@@ -112,11 +147,104 @@ case "$cmd" in
|
|
|
112
147
|
echo '{"uuid":"task-3","title":"Task 3","status":"done","proposalUuid":"prop-2","project":{"uuid":"proj-1","name":"P"}}'
|
|
113
148
|
;;
|
|
114
149
|
no-slug:chorus_get_proposal)
|
|
115
|
-
printf '%s' '{"uuid":"prop-2","title":"P2","description":"Free-form proposal description with no slug marker.","inputUuids":["idea-2"]}'
|
|
150
|
+
printf '%s' '{"uuid":"prop-2","title":"P2","description":"Free-form proposal description with no slug marker.","inputType":"idea","inputUuids":["idea-2"]}'
|
|
116
151
|
;;
|
|
117
152
|
no-slug:chorus_list_tasks)
|
|
118
153
|
echo '{"tasks":[{"uuid":"task-1","status":"done"},{"uuid":"task-2","status":"done"},{"uuid":"task-3","status":"done"}],"total":3,"page":1,"pageSize":200}'
|
|
119
154
|
;;
|
|
155
|
+
|
|
156
|
+
# ----- Branch B fixtures (idea-completion report reminder) -----
|
|
157
|
+
# report-positive: idea-rooted proposal whose tasks are all
|
|
158
|
+
# done|closed, no report Document on it -> emit.
|
|
159
|
+
report-positive:chorus_get_task)
|
|
160
|
+
echo '{"uuid":"task-9","title":"Task 9","status":"done","proposalUuid":"prop-9","project":{"uuid":"proj-1","name":"P"}}'
|
|
161
|
+
;;
|
|
162
|
+
report-positive:chorus_get_proposal)
|
|
163
|
+
printf '%s' '{"uuid":"prop-9","title":"P9","description":"Free-form proposal — no OpenSpec slug here.","inputType":"idea","inputUuids":["idea-9"]}'
|
|
164
|
+
;;
|
|
165
|
+
report-positive:chorus_list_tasks)
|
|
166
|
+
echo '{"tasks":[{"uuid":"task-7","status":"done","proposalUuid":"prop-9"},{"uuid":"task-8","status":"closed","proposalUuid":"prop-9"},{"uuid":"task-9","status":"done","proposalUuid":"prop-9"}],"total":3,"page":1,"pageSize":200}'
|
|
167
|
+
;;
|
|
168
|
+
report-positive:chorus_get_documents)
|
|
169
|
+
echo '{"documents":[],"total":0,"page":1,"pageSize":200}'
|
|
170
|
+
;;
|
|
171
|
+
|
|
172
|
+
# report-existing: same as positive but a report Document already
|
|
173
|
+
# exists on this proposal -> silent skip.
|
|
174
|
+
report-existing:chorus_get_task)
|
|
175
|
+
echo '{"uuid":"task-9","title":"Task 9","status":"done","proposalUuid":"prop-9","project":{"uuid":"proj-1","name":"P"}}'
|
|
176
|
+
;;
|
|
177
|
+
report-existing:chorus_get_proposal)
|
|
178
|
+
printf '%s' '{"uuid":"prop-9","title":"P9","description":"Free-form proposal.","inputType":"idea","inputUuids":["idea-9"]}'
|
|
179
|
+
;;
|
|
180
|
+
report-existing:chorus_list_tasks)
|
|
181
|
+
echo '{"tasks":[{"uuid":"task-7","status":"done","proposalUuid":"prop-9"},{"uuid":"task-8","status":"closed","proposalUuid":"prop-9"},{"uuid":"task-9","status":"done","proposalUuid":"prop-9"}],"total":3,"page":1,"pageSize":200}'
|
|
182
|
+
;;
|
|
183
|
+
report-existing:chorus_get_documents)
|
|
184
|
+
echo '{"documents":[{"uuid":"doc-r1","type":"report","title":"Idea 9 — completion report","proposalUuid":"prop-9"}],"total":1,"page":1,"pageSize":200}'
|
|
185
|
+
;;
|
|
186
|
+
|
|
187
|
+
# report-not-last: a task is still in_progress -> silent skip.
|
|
188
|
+
report-not-last:chorus_get_task)
|
|
189
|
+
echo '{"uuid":"task-9","title":"Task 9","status":"done","proposalUuid":"prop-9","project":{"uuid":"proj-1","name":"P"}}'
|
|
190
|
+
;;
|
|
191
|
+
report-not-last:chorus_get_proposal)
|
|
192
|
+
printf '%s' '{"uuid":"prop-9","title":"P9","description":"Free-form proposal.","inputType":"idea","inputUuids":["idea-9"]}'
|
|
193
|
+
;;
|
|
194
|
+
report-not-last:chorus_list_tasks)
|
|
195
|
+
echo '{"tasks":[{"uuid":"task-7","status":"done","proposalUuid":"prop-9"},{"uuid":"task-8","status":"in_progress","proposalUuid":"prop-9"},{"uuid":"task-9","status":"done","proposalUuid":"prop-9"}],"total":3,"page":1,"pageSize":200}'
|
|
196
|
+
;;
|
|
197
|
+
report-not-last:chorus_get_documents)
|
|
198
|
+
echo '{"documents":[],"total":0,"page":1,"pageSize":200}'
|
|
199
|
+
;;
|
|
200
|
+
|
|
201
|
+
# report-quick-task: proposal.inputType != "idea" -> Branch B must
|
|
202
|
+
# skip at the first gate, before any further calls.
|
|
203
|
+
report-quick-task:chorus_get_task)
|
|
204
|
+
echo '{"uuid":"task-9","title":"Task 9","status":"done","proposalUuid":"prop-9","project":{"uuid":"proj-1","name":"P"}}'
|
|
205
|
+
;;
|
|
206
|
+
report-quick-task:chorus_get_proposal)
|
|
207
|
+
printf '%s' '{"uuid":"prop-9","title":"P9","description":"Free-form proposal.","inputType":"manual","inputUuids":[]}'
|
|
208
|
+
;;
|
|
209
|
+
report-quick-task:chorus_list_tasks)
|
|
210
|
+
echo '{"tasks":[{"uuid":"task-9","status":"done","proposalUuid":"prop-9"}],"total":1,"page":1,"pageSize":200}'
|
|
211
|
+
;;
|
|
212
|
+
report-quick-task:chorus_get_documents)
|
|
213
|
+
echo '{"documents":[],"total":0,"page":1,"pageSize":200}'
|
|
214
|
+
;;
|
|
215
|
+
|
|
216
|
+
# report-task-overflow: chorus_list_tasks returns 5 done tasks but
|
|
217
|
+
# total=25 — more tasks exist on later pages. Hook MUST refuse to
|
|
218
|
+
# conclude "all done" and silent-skip Branch B.
|
|
219
|
+
report-task-overflow:chorus_get_task)
|
|
220
|
+
echo '{"uuid":"task-9","title":"Task 9","status":"done","proposalUuid":"prop-9","project":{"uuid":"proj-1","name":"P"}}'
|
|
221
|
+
;;
|
|
222
|
+
report-task-overflow:chorus_get_proposal)
|
|
223
|
+
printf '%s' '{"uuid":"prop-9","title":"P9","description":"Free-form proposal.","inputType":"idea","inputUuids":["idea-9"]}'
|
|
224
|
+
;;
|
|
225
|
+
report-task-overflow:chorus_list_tasks)
|
|
226
|
+
echo '{"tasks":[{"uuid":"t1","status":"done","proposalUuid":"prop-9"},{"uuid":"t2","status":"done","proposalUuid":"prop-9"},{"uuid":"t3","status":"done","proposalUuid":"prop-9"},{"uuid":"t4","status":"done","proposalUuid":"prop-9"},{"uuid":"t5","status":"done","proposalUuid":"prop-9"}],"total":25,"page":1,"pageSize":200}'
|
|
227
|
+
;;
|
|
228
|
+
report-task-overflow:chorus_get_documents)
|
|
229
|
+
echo '{"documents":[],"total":0,"page":1,"pageSize":200}'
|
|
230
|
+
;;
|
|
231
|
+
|
|
232
|
+
# report-doc-overflow: chorus_get_documents returns 1 unrelated
|
|
233
|
+
# report but total=25 — this proposal's existing report sits on a
|
|
234
|
+
# later page. Hook MUST refuse to conclude "no report" and silent-skip.
|
|
235
|
+
report-doc-overflow:chorus_get_task)
|
|
236
|
+
echo '{"uuid":"task-9","title":"Task 9","status":"done","proposalUuid":"prop-9","project":{"uuid":"proj-1","name":"P"}}'
|
|
237
|
+
;;
|
|
238
|
+
report-doc-overflow:chorus_get_proposal)
|
|
239
|
+
printf '%s' '{"uuid":"prop-9","title":"P9","description":"Free-form proposal.","inputType":"idea","inputUuids":["idea-9"]}'
|
|
240
|
+
;;
|
|
241
|
+
report-doc-overflow:chorus_list_tasks)
|
|
242
|
+
echo '{"tasks":[{"uuid":"task-7","status":"done","proposalUuid":"prop-9"},{"uuid":"task-8","status":"closed","proposalUuid":"prop-9"},{"uuid":"task-9","status":"done","proposalUuid":"prop-9"}],"total":3,"page":1,"pageSize":200}'
|
|
243
|
+
;;
|
|
244
|
+
report-doc-overflow:chorus_get_documents)
|
|
245
|
+
echo '{"documents":[{"uuid":"doc-other","type":"report","title":"Some other report","proposalUuid":"prop-OTHER"}],"total":25,"page":1,"pageSize":200}'
|
|
246
|
+
;;
|
|
247
|
+
|
|
120
248
|
*)
|
|
121
249
|
# Unhandled (tool, fixture) — return empty, hook should silent-skip.
|
|
122
250
|
echo ""
|
|
@@ -153,11 +281,12 @@ case "$fixture" in
|
|
|
153
281
|
mode-off|no-folder|no-cli) fixture=positive ;;
|
|
154
282
|
esac
|
|
155
283
|
case "${fixture}:${tool}" in
|
|
284
|
+
# ----- Branch A fixtures (existing) -----
|
|
156
285
|
positive:chorus_get_task)
|
|
157
286
|
echo '{"uuid":"task-3","title":"Task 3","status":"done","proposalUuid":"prop-1","project":{"uuid":"proj-1","name":"P"}}'
|
|
158
287
|
;;
|
|
159
288
|
positive:chorus_get_proposal)
|
|
160
|
-
printf '%s' '{"uuid":"prop-1","title":"P1","description":"Some intro line.\nOpenSpec change slug: my-feature\nMore body.","inputUuids":["idea-1"]}'
|
|
289
|
+
printf '%s' '{"uuid":"prop-1","title":"P1","description":"Some intro line.\nOpenSpec change slug: my-feature\nMore body.","inputType":"idea","inputUuids":["idea-1"]}'
|
|
161
290
|
;;
|
|
162
291
|
positive:chorus_list_tasks)
|
|
163
292
|
echo '{"tasks":[{"uuid":"task-1","status":"done"},{"uuid":"task-2","status":"done"},{"uuid":"task-3","status":"done"}],"total":3,"page":1,"pageSize":200}'
|
|
@@ -166,7 +295,7 @@ case "${fixture}:${tool}" in
|
|
|
166
295
|
echo '{"uuid":"task-2","title":"Task 2","status":"done","proposalUuid":"prop-1","project":{"uuid":"proj-1","name":"P"}}'
|
|
167
296
|
;;
|
|
168
297
|
not-last-task:chorus_get_proposal)
|
|
169
|
-
printf '%s' '{"uuid":"prop-1","title":"P1","description":"Intro.\nOpenSpec change slug: my-feature\nMore.","inputUuids":["idea-1"]}'
|
|
298
|
+
printf '%s' '{"uuid":"prop-1","title":"P1","description":"Intro.\nOpenSpec change slug: my-feature\nMore.","inputType":"idea","inputUuids":["idea-1"]}'
|
|
170
299
|
;;
|
|
171
300
|
not-last-task:chorus_list_tasks)
|
|
172
301
|
echo '{"tasks":[{"uuid":"task-1","status":"done"},{"uuid":"task-2","status":"done"},{"uuid":"task-3","status":"in_progress"}],"total":3,"page":1,"pageSize":200}'
|
|
@@ -175,11 +304,93 @@ case "${fixture}:${tool}" in
|
|
|
175
304
|
echo '{"uuid":"task-3","title":"Task 3","status":"done","proposalUuid":"prop-2","project":{"uuid":"proj-1","name":"P"}}'
|
|
176
305
|
;;
|
|
177
306
|
no-slug:chorus_get_proposal)
|
|
178
|
-
printf '%s' '{"uuid":"prop-2","title":"P2","description":"Free-form proposal description with no slug marker.","inputUuids":["idea-2"]}'
|
|
307
|
+
printf '%s' '{"uuid":"prop-2","title":"P2","description":"Free-form proposal description with no slug marker.","inputType":"idea","inputUuids":["idea-2"]}'
|
|
179
308
|
;;
|
|
180
309
|
no-slug:chorus_list_tasks)
|
|
181
310
|
echo '{"tasks":[{"uuid":"task-1","status":"done"},{"uuid":"task-2","status":"done"},{"uuid":"task-3","status":"done"}],"total":3,"page":1,"pageSize":200}'
|
|
182
311
|
;;
|
|
312
|
+
|
|
313
|
+
# ----- Branch B fixtures (idea-completion report reminder) -----
|
|
314
|
+
report-positive:chorus_get_task)
|
|
315
|
+
echo '{"uuid":"task-9","title":"Task 9","status":"done","proposalUuid":"prop-9","project":{"uuid":"proj-1","name":"P"}}'
|
|
316
|
+
;;
|
|
317
|
+
report-positive:chorus_get_proposal)
|
|
318
|
+
printf '%s' '{"uuid":"prop-9","title":"P9","description":"Free-form proposal — no OpenSpec slug here.","inputType":"idea","inputUuids":["idea-9"]}'
|
|
319
|
+
;;
|
|
320
|
+
report-positive:chorus_list_tasks)
|
|
321
|
+
echo '{"tasks":[{"uuid":"task-7","status":"done","proposalUuid":"prop-9"},{"uuid":"task-8","status":"closed","proposalUuid":"prop-9"},{"uuid":"task-9","status":"done","proposalUuid":"prop-9"}],"total":3,"page":1,"pageSize":200}'
|
|
322
|
+
;;
|
|
323
|
+
report-positive:chorus_get_documents)
|
|
324
|
+
echo '{"documents":[],"total":0,"page":1,"pageSize":200}'
|
|
325
|
+
;;
|
|
326
|
+
|
|
327
|
+
report-existing:chorus_get_task)
|
|
328
|
+
echo '{"uuid":"task-9","title":"Task 9","status":"done","proposalUuid":"prop-9","project":{"uuid":"proj-1","name":"P"}}'
|
|
329
|
+
;;
|
|
330
|
+
report-existing:chorus_get_proposal)
|
|
331
|
+
printf '%s' '{"uuid":"prop-9","title":"P9","description":"Free-form proposal.","inputType":"idea","inputUuids":["idea-9"]}'
|
|
332
|
+
;;
|
|
333
|
+
report-existing:chorus_list_tasks)
|
|
334
|
+
echo '{"tasks":[{"uuid":"task-7","status":"done","proposalUuid":"prop-9"},{"uuid":"task-8","status":"closed","proposalUuid":"prop-9"},{"uuid":"task-9","status":"done","proposalUuid":"prop-9"}],"total":3,"page":1,"pageSize":200}'
|
|
335
|
+
;;
|
|
336
|
+
report-existing:chorus_get_documents)
|
|
337
|
+
echo '{"documents":[{"uuid":"doc-r1","type":"report","title":"Idea 9 — completion report","proposalUuid":"prop-9"}],"total":1,"page":1,"pageSize":200}'
|
|
338
|
+
;;
|
|
339
|
+
|
|
340
|
+
report-not-last:chorus_get_task)
|
|
341
|
+
echo '{"uuid":"task-9","title":"Task 9","status":"done","proposalUuid":"prop-9","project":{"uuid":"proj-1","name":"P"}}'
|
|
342
|
+
;;
|
|
343
|
+
report-not-last:chorus_get_proposal)
|
|
344
|
+
printf '%s' '{"uuid":"prop-9","title":"P9","description":"Free-form proposal.","inputType":"idea","inputUuids":["idea-9"]}'
|
|
345
|
+
;;
|
|
346
|
+
report-not-last:chorus_list_tasks)
|
|
347
|
+
echo '{"tasks":[{"uuid":"task-7","status":"done","proposalUuid":"prop-9"},{"uuid":"task-8","status":"in_progress","proposalUuid":"prop-9"},{"uuid":"task-9","status":"done","proposalUuid":"prop-9"}],"total":3,"page":1,"pageSize":200}'
|
|
348
|
+
;;
|
|
349
|
+
report-not-last:chorus_get_documents)
|
|
350
|
+
echo '{"documents":[],"total":0,"page":1,"pageSize":200}'
|
|
351
|
+
;;
|
|
352
|
+
|
|
353
|
+
report-quick-task:chorus_get_task)
|
|
354
|
+
echo '{"uuid":"task-9","title":"Task 9","status":"done","proposalUuid":"prop-9","project":{"uuid":"proj-1","name":"P"}}'
|
|
355
|
+
;;
|
|
356
|
+
report-quick-task:chorus_get_proposal)
|
|
357
|
+
printf '%s' '{"uuid":"prop-9","title":"P9","description":"Free-form proposal.","inputType":"manual","inputUuids":[]}'
|
|
358
|
+
;;
|
|
359
|
+
report-quick-task:chorus_list_tasks)
|
|
360
|
+
echo '{"tasks":[{"uuid":"task-9","status":"done","proposalUuid":"prop-9"}],"total":1,"page":1,"pageSize":200}'
|
|
361
|
+
;;
|
|
362
|
+
report-quick-task:chorus_get_documents)
|
|
363
|
+
echo '{"documents":[],"total":0,"page":1,"pageSize":200}'
|
|
364
|
+
;;
|
|
365
|
+
|
|
366
|
+
# report-task-overflow: tasks total > returned -> silent skip.
|
|
367
|
+
report-task-overflow:chorus_get_task)
|
|
368
|
+
echo '{"uuid":"task-9","title":"Task 9","status":"done","proposalUuid":"prop-9","project":{"uuid":"proj-1","name":"P"}}'
|
|
369
|
+
;;
|
|
370
|
+
report-task-overflow:chorus_get_proposal)
|
|
371
|
+
printf '%s' '{"uuid":"prop-9","title":"P9","description":"Free-form proposal.","inputType":"idea","inputUuids":["idea-9"]}'
|
|
372
|
+
;;
|
|
373
|
+
report-task-overflow:chorus_list_tasks)
|
|
374
|
+
echo '{"tasks":[{"uuid":"t1","status":"done","proposalUuid":"prop-9"},{"uuid":"t2","status":"done","proposalUuid":"prop-9"},{"uuid":"t3","status":"done","proposalUuid":"prop-9"},{"uuid":"t4","status":"done","proposalUuid":"prop-9"},{"uuid":"t5","status":"done","proposalUuid":"prop-9"}],"total":25,"page":1,"pageSize":200}'
|
|
375
|
+
;;
|
|
376
|
+
report-task-overflow:chorus_get_documents)
|
|
377
|
+
echo '{"documents":[],"total":0,"page":1,"pageSize":200}'
|
|
378
|
+
;;
|
|
379
|
+
|
|
380
|
+
# report-doc-overflow: docs total > returned -> silent skip.
|
|
381
|
+
report-doc-overflow:chorus_get_task)
|
|
382
|
+
echo '{"uuid":"task-9","title":"Task 9","status":"done","proposalUuid":"prop-9","project":{"uuid":"proj-1","name":"P"}}'
|
|
383
|
+
;;
|
|
384
|
+
report-doc-overflow:chorus_get_proposal)
|
|
385
|
+
printf '%s' '{"uuid":"prop-9","title":"P9","description":"Free-form proposal.","inputType":"idea","inputUuids":["idea-9"]}'
|
|
386
|
+
;;
|
|
387
|
+
report-doc-overflow:chorus_list_tasks)
|
|
388
|
+
echo '{"tasks":[{"uuid":"task-7","status":"done","proposalUuid":"prop-9"},{"uuid":"task-8","status":"closed","proposalUuid":"prop-9"},{"uuid":"task-9","status":"done","proposalUuid":"prop-9"}],"total":3,"page":1,"pageSize":200}'
|
|
389
|
+
;;
|
|
390
|
+
report-doc-overflow:chorus_get_documents)
|
|
391
|
+
echo '{"documents":[{"uuid":"doc-other","type":"report","title":"Some other report","proposalUuid":"prop-OTHER"}],"total":25,"page":1,"pageSize":200}'
|
|
392
|
+
;;
|
|
393
|
+
|
|
183
394
|
*)
|
|
184
395
|
echo "" ;;
|
|
185
396
|
esac
|
|
@@ -203,16 +414,20 @@ EVENT_JSON='{"tool_name":"chorus_admin_verify_task","tool_input":{"taskUuid":"ta
|
|
|
203
414
|
|
|
204
415
|
# ----- Test runner -----
|
|
205
416
|
|
|
206
|
-
# Args: name fixture variant expected_substring
|
|
417
|
+
# Args: name fixture variant assertion_mode expected_substring forbidden_substring
|
|
207
418
|
# variant in {claude, codex}
|
|
208
|
-
#
|
|
209
|
-
#
|
|
419
|
+
# assertion_mode:
|
|
420
|
+
# "must-contain" -> stdout MUST contain $expected_substring
|
|
421
|
+
# "must-not-contain" -> stdout MUST NOT contain $forbidden_substring
|
|
422
|
+
# (For Branch B fixtures, $forbidden_substring is `create idea-completion report`.
|
|
423
|
+
# For Branch A "no" fixtures, $forbidden_substring is `openspec archive`.)
|
|
210
424
|
run_one() {
|
|
211
425
|
local name="$1"
|
|
212
426
|
local fixture="$2"
|
|
213
427
|
local variant="$3"
|
|
214
|
-
local
|
|
428
|
+
local assertion_mode="$4"
|
|
215
429
|
local expected="$5"
|
|
430
|
+
local forbidden="${6:-openspec archive}"
|
|
216
431
|
|
|
217
432
|
local hook_dir
|
|
218
433
|
if [ "$variant" = "claude" ]; then
|
|
@@ -292,7 +507,7 @@ run_one() {
|
|
|
292
507
|
stdout=$(cat "$stdout_file")
|
|
293
508
|
rm -f "$stdout_file" "$stderr_file"
|
|
294
509
|
|
|
295
|
-
if [ "$
|
|
510
|
+
if [ "$assertion_mode" = "must-contain" ]; then
|
|
296
511
|
if printf '%s' "$stdout" | grep -q "$expected"; then
|
|
297
512
|
echo " PASS $name [$variant]"
|
|
298
513
|
PASS=$((PASS + 1))
|
|
@@ -303,9 +518,9 @@ run_one() {
|
|
|
303
518
|
FAILED="$FAILED $name[$variant]"
|
|
304
519
|
fi
|
|
305
520
|
else
|
|
306
|
-
#
|
|
307
|
-
if printf '%s' "$stdout" | grep -q "
|
|
308
|
-
echo " FAIL $name [$variant]: stdout unexpectedly contains '
|
|
521
|
+
# must-not-contain: $forbidden MUST be absent.
|
|
522
|
+
if printf '%s' "$stdout" | grep -q "$forbidden"; then
|
|
523
|
+
echo " FAIL $name [$variant]: stdout unexpectedly contains '$forbidden'"
|
|
309
524
|
printf '%s\n' "$stdout" | sed 's/^/ /'
|
|
310
525
|
FAIL=$((FAIL + 1))
|
|
311
526
|
FAILED="$FAILED $name[$variant]"
|
|
@@ -319,41 +534,78 @@ run_one() {
|
|
|
319
534
|
echo "Sandbox: $SANDBOX"
|
|
320
535
|
echo ""
|
|
321
536
|
|
|
322
|
-
#
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
run_one "
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
run_one "
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
#
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
#
|
|
344
|
-
#
|
|
345
|
-
# before reaching
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
#
|
|
355
|
-
|
|
356
|
-
|
|
537
|
+
# ===== Branch A: OpenSpec archive trigger fixtures =====
|
|
538
|
+
# (assertion: must-contain `openspec archive my-feature` / must-not-contain `openspec archive`)
|
|
539
|
+
|
|
540
|
+
# A1: positive (slug + last task + CLI)
|
|
541
|
+
run_one "positive" "positive" "claude" "must-contain" "openspec archive my-feature"
|
|
542
|
+
run_one "positive" "positive" "codex" "must-contain" "openspec archive my-feature"
|
|
543
|
+
|
|
544
|
+
# A2: not-last-task
|
|
545
|
+
run_one "not-last-task" "not-last-task" "claude" "must-not-contain" "" "openspec archive"
|
|
546
|
+
run_one "not-last-task" "not-last-task" "codex" "must-not-contain" "" "openspec archive"
|
|
547
|
+
|
|
548
|
+
# A3: no-slug (free-form proposal)
|
|
549
|
+
run_one "no-slug" "no-slug" "claude" "must-not-contain" "" "openspec archive"
|
|
550
|
+
run_one "no-slug" "no-slug" "codex" "must-not-contain" "" "openspec archive"
|
|
551
|
+
|
|
552
|
+
# A4: no-cli (folder present, CLI absent). Strip $SANDBOX/bin from PATH
|
|
553
|
+
# so `command -v openspec` fails. Folder is still there in
|
|
554
|
+
# $SANDBOX/project/openspec. Hook must short-circuit at the CLI gate.
|
|
555
|
+
run_one "no-cli" "no-cli" "claude" "must-not-contain" "" "openspec archive"
|
|
556
|
+
run_one "no-cli" "no-cli" "codex" "must-not-contain" "" "openspec archive"
|
|
557
|
+
|
|
558
|
+
# A5: no-folder (CLI present, folder absent). CLAUDE_PROJECT_DIR points
|
|
559
|
+
# at $SANDBOX (no openspec/ dir there). Hook must short-circuit at the
|
|
560
|
+
# folder gate before reaching any MCP call.
|
|
561
|
+
run_one "no-folder" "no-folder" "claude" "must-not-contain" "" "openspec archive"
|
|
562
|
+
run_one "no-folder" "no-folder" "codex" "must-not-contain" "" "openspec archive"
|
|
563
|
+
|
|
564
|
+
# A6: mode-off (explicit opt-out via env). Both folder and CLI are
|
|
565
|
+
# present, but CHORUS_OPENSPEC_MODE=off. Hook must honor the opt-out.
|
|
566
|
+
run_one "mode-off" "mode-off" "claude" "must-not-contain" "" "openspec archive"
|
|
567
|
+
run_one "mode-off" "mode-off" "codex" "must-not-contain" "" "openspec archive"
|
|
568
|
+
|
|
569
|
+
# ===== Branch B: Idea-completion report reminder fixtures =====
|
|
570
|
+
# (assertion: must-contain `create idea-completion report` /
|
|
571
|
+
# must-not-contain `create idea-completion report`)
|
|
572
|
+
# These fixtures all use a non-OpenSpec proposal description (no slug
|
|
573
|
+
# line), so Branch A silent-skips. The PATH still has the fake openspec
|
|
574
|
+
# CLI and the synthetic project dir still has openspec/ so Branch A's
|
|
575
|
+
# folder/CLI gates pass — the slug gate is what blocks Branch A here,
|
|
576
|
+
# isolating the assertion to Branch B's behavior.
|
|
577
|
+
|
|
578
|
+
# B1: report-positive — last task of an Idea verified, no report
|
|
579
|
+
# Document yet -> reminder MUST fire.
|
|
580
|
+
run_one "report-positive" "report-positive" "claude" "must-contain" "create idea-completion report"
|
|
581
|
+
run_one "report-positive" "report-positive" "codex" "must-contain" "create idea-completion report"
|
|
582
|
+
|
|
583
|
+
# B2: report-existing — same conditions but a report Document already
|
|
584
|
+
# exists for the Idea -> reminder MUST be silent.
|
|
585
|
+
run_one "report-existing" "report-existing" "claude" "must-not-contain" "" "create idea-completion report"
|
|
586
|
+
run_one "report-existing" "report-existing" "codex" "must-not-contain" "" "create idea-completion report"
|
|
587
|
+
|
|
588
|
+
# B3: report-not-last — at least one task is still in_progress
|
|
589
|
+
# (non-terminal) -> reminder MUST be silent.
|
|
590
|
+
run_one "report-not-last" "report-not-last" "claude" "must-not-contain" "" "create idea-completion report"
|
|
591
|
+
run_one "report-not-last" "report-not-last" "codex" "must-not-contain" "" "create idea-completion report"
|
|
592
|
+
|
|
593
|
+
# B4: report-quick-task — proposal.inputType != "idea" (e.g. a
|
|
594
|
+
# manually-created proposal) -> reminder MUST be silent at first gate.
|
|
595
|
+
run_one "report-quick-task" "report-quick-task" "claude" "must-not-contain" "" "create idea-completion report"
|
|
596
|
+
run_one "report-quick-task" "report-quick-task" "codex" "must-not-contain" "" "create idea-completion report"
|
|
597
|
+
|
|
598
|
+
# B5: report-task-overflow — chorus_list_tasks total > returned (more
|
|
599
|
+
# tasks remain on later pages). Hook must refuse to assume "all done"
|
|
600
|
+
# and silent-skip Branch B.
|
|
601
|
+
run_one "report-task-overflow" "report-task-overflow" "claude" "must-not-contain" "" "create idea-completion report"
|
|
602
|
+
run_one "report-task-overflow" "report-task-overflow" "codex" "must-not-contain" "" "create idea-completion report"
|
|
603
|
+
|
|
604
|
+
# B6: report-doc-overflow — chorus_get_documents total > returned (the
|
|
605
|
+
# proposal's existing report could be on a later page). Hook must refuse
|
|
606
|
+
# to assume "no report" and silent-skip Branch B.
|
|
607
|
+
run_one "report-doc-overflow" "report-doc-overflow" "claude" "must-not-contain" "" "create idea-completion report"
|
|
608
|
+
run_one "report-doc-overflow" "report-doc-overflow" "codex" "must-not-contain" "" "create idea-completion report"
|
|
357
609
|
|
|
358
610
|
echo ""
|
|
359
611
|
echo "Results: $PASS passed, $FAIL failed"
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: brainstorm
|
|
3
|
+
description: Optional divergent-then-convergent dialogue for fuzzy ideas. Invoked from the idea skill as a prelude to structured elaboration; produces one ElaborationRound of decision-point Q&A and returns control. Never writes files, never posts comments, never validates elaboration.
|
|
4
|
+
license: AGPL-3.0
|
|
5
|
+
metadata:
|
|
6
|
+
author: chorus
|
|
7
|
+
version: "0.9.0"
|
|
8
|
+
category: project-management
|
|
9
|
+
mcp_server: chorus
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Brainstorm Skill
|
|
13
|
+
|
|
14
|
+
A divergent-then-convergent dialogue cadence for ideas whose direction is still being formed. Compresses the conversation into one `ElaborationRound` of decision-point Q&A — same shape as a structured elaboration round, but the questions, options and answers are synthesized at the end of the conversation rather than asked up front.
|
|
15
|
+
|
|
16
|
+
This skill is a **producer** of one elaboration round; the **scheduler** decision (validate vs. follow-up) belongs to the calling idea skill.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## When invoked
|
|
21
|
+
|
|
22
|
+
Only as a sub-step of the idea skill, only after the user has explicitly opted in via `AskUserQuestion`. Never run standalone, never run without user opt-in. The expected entry point is the idea skill's "Step 4.5: Brainstorm Mode (Optional Prelude)" — see the idea skill for the surrounding flow.
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Hard rules
|
|
27
|
+
|
|
28
|
+
1. **One question at a time.** Each `AskUserQuestion` call MUST contain exactly one question entry. Wait for the answer before asking the next.
|
|
29
|
+
2. **Multi-choice preferred.** Frame each question as 2-4 options where possible. Open-ended is acceptable when options would be premature, but lean toward concrete choices.
|
|
30
|
+
3. **Propose 2-3 directions before stopping divergence.** Once the requirement direction is clear enough to enumerate, present 2-3 distinct approaches in a single `AskUserQuestion`. Mark exactly one as the recommended option per the host tool's `AskUserQuestion` recommendation convention (the spec does not dictate a specific marking format — follow the tool's documentation).
|
|
31
|
+
4. **Explicit user approval required to exit divergence.** Do NOT proceed to synthesis until the user has selected one of the proposed directions.
|
|
32
|
+
5. **No files written.** Do NOT write any markdown, design doc, scratch file, or any other file to disk. The conversation produces an `ElaborationRound` and nothing else on disk.
|
|
33
|
+
6. **No comments posted.** Do NOT call `chorus_add_comment` from this skill. Comments belong to the idea skill or the user, not to the brainstorm step.
|
|
34
|
+
7. **No design-doc handoff.** Do NOT invoke `writing-plans`, `writing-skills`, or any skill whose purpose is to produce a design document. The brainstorm output is the synthesized round — there is no separate doc.
|
|
35
|
+
8. **No `validate_elaboration` call.** Do NOT call `chorus_pm_validate_elaboration` from this skill. Whether to validate (resolve elaboration) or follow up (issues + followUpQuestions) is the calling idea skill's decision, not this skill's.
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Step-by-step
|
|
40
|
+
|
|
41
|
+
### 1. Gather context
|
|
42
|
+
|
|
43
|
+
Before asking the first divergent question, read the idea and surrounding project state. Mirror the idea skill's gather-context list:
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
chorus_get_idea({ ideaUuid })
|
|
47
|
+
chorus_get_documents({ projectUuid })
|
|
48
|
+
chorus_get_document({ documentUuid }) # for any document worth reading in full
|
|
49
|
+
chorus_get_proposals({ projectUuid, status: "approved" }) # to understand patterns
|
|
50
|
+
chorus_list_tasks({ projectUuid }) # to avoid duplicating existing work
|
|
51
|
+
chorus_get_comments({ targetType: "idea", targetUuid: ideaUuid })
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Skim each result for: stated background, stated requirements, stated constraints, and what is conspicuously NOT stated. The gaps are the questions worth asking.
|
|
55
|
+
|
|
56
|
+
### 2. Divergent Q&A
|
|
57
|
+
|
|
58
|
+
Ask one question at a time via `AskUserQuestion`. Aim to surface:
|
|
59
|
+
|
|
60
|
+
- The **goal** the idea is trying to serve (often more abstract than the idea statement).
|
|
61
|
+
- The **constraints** that exclude entire branches of solution space (deadlines, compatibility, scope).
|
|
62
|
+
- The **success criteria** — how will the user know this is done.
|
|
63
|
+
|
|
64
|
+
Keep each question single-purpose. If you need to ask three things, that is three rounds, not one combined `AskUserQuestion`.
|
|
65
|
+
|
|
66
|
+
### 3. Propose 2-3 directions
|
|
67
|
+
|
|
68
|
+
When the goal, constraints, and success criteria are clear enough that you can name distinct approaches, present them in a single `AskUserQuestion`:
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
AskUserQuestion({
|
|
72
|
+
questions: [
|
|
73
|
+
{
|
|
74
|
+
question: "<the convergence question>",
|
|
75
|
+
header: "<short header>",
|
|
76
|
+
options: [
|
|
77
|
+
{ label: "Option A (Recommended)", description: "<what + tradeoff>" },
|
|
78
|
+
{ label: "Option B", description: "<what + tradeoff>" },
|
|
79
|
+
{ label: "Option C", description: "<what + tradeoff>" }
|
|
80
|
+
],
|
|
81
|
+
multiSelect: false
|
|
82
|
+
}
|
|
83
|
+
]
|
|
84
|
+
})
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
The recommendation must be visibly marked to the user using the host tool's `AskUserQuestion` convention. State **why** you recommend it — usually a sentence about the dominant tradeoff.
|
|
88
|
+
|
|
89
|
+
### 4. Wait for explicit approval
|
|
90
|
+
|
|
91
|
+
Do not proceed to synthesis if the user has not selected one of the options. If the user picks "Other" with free text, treat that as a new constraint — go back to step 2 or step 3 with the refined direction.
|
|
92
|
+
|
|
93
|
+
### 5. Synthesize decision-point Q&A
|
|
94
|
+
|
|
95
|
+
For each material decision the user made during the conversation, build one `ElaborationQuestion`. A "material decision" is a moment where the user chose between alternatives or set scope explicitly. Map each decision per the synthesis spec below.
|
|
96
|
+
|
|
97
|
+
### 6. Persist the round
|
|
98
|
+
|
|
99
|
+
Call `chorus_pm_start_elaboration` with the synthesized questions:
|
|
100
|
+
|
|
101
|
+
```
|
|
102
|
+
chorus_pm_start_elaboration({
|
|
103
|
+
ideaUuid,
|
|
104
|
+
depth: "standard",
|
|
105
|
+
questions: [
|
|
106
|
+
{ id: "q1", text: "...", category: "...", options: [...] },
|
|
107
|
+
...
|
|
108
|
+
]
|
|
109
|
+
})
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Then submit the answers in one call:
|
|
113
|
+
|
|
114
|
+
```
|
|
115
|
+
chorus_answer_elaboration({
|
|
116
|
+
ideaUuid,
|
|
117
|
+
roundUuid,
|
|
118
|
+
answers: [
|
|
119
|
+
{ questionId: "q1", selectedOptionId: "...", customText: "<rationale>" },
|
|
120
|
+
...
|
|
121
|
+
]
|
|
122
|
+
})
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### 7. Return control
|
|
126
|
+
|
|
127
|
+
Stop here. Do **NOT** call `chorus_pm_validate_elaboration`. The idea skill's caller now decides:
|
|
128
|
+
|
|
129
|
+
- If the synthesized round answers cover everything → caller validates with `issues: []`.
|
|
130
|
+
- If gaps remain → caller validates with `issues + followUpQuestions` to start a structured Round 2.
|
|
131
|
+
|
|
132
|
+
The depth of any follow-up round is the caller's call, not yours.
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## Synthesis spec
|
|
137
|
+
|
|
138
|
+
Each material decision becomes exactly one `ElaborationQuestion` with these fields:
|
|
139
|
+
|
|
140
|
+
| Field | Source |
|
|
141
|
+
|---|---|
|
|
142
|
+
| `text` | The decision question, phrased neutrally. Example: "Which depth-model placement?" |
|
|
143
|
+
| `category` | `functional`, `non_functional`, `business_context`, `technical_context`, `user_scenario`, or `scope` — derived from the topic. |
|
|
144
|
+
| `options` | All directions that were considered, length 2-5. Collapse near-duplicates into one option. |
|
|
145
|
+
| `selectedOptionId` | The id of the option the user approved. |
|
|
146
|
+
| `customText` | A 1-3 sentence rationale capturing the constraint or tradeoff that drove the choice. Not a transcript dump. |
|
|
147
|
+
|
|
148
|
+
Rules:
|
|
149
|
+
|
|
150
|
+
- A `customText` longer than ~3 sentences is a sign you are summarizing transcript instead of capturing rationale. Cut.
|
|
151
|
+
- An `options` array of length 2 with binary "yes / no" framing is a sign you pre-narrowed alternatives. Re-examine — there are usually at least three meaningfully different paths, even if two of them get rejected quickly.
|
|
152
|
+
- Skip "decisions" that were never genuinely contested. If the user agreed instantly to the only proposal, that is information for the idea content, not a decision-point Q&A.
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## Anti-patterns
|
|
157
|
+
|
|
158
|
+
Do not do any of the following. Each has a specific failure mode that this skill must prevent:
|
|
159
|
+
|
|
160
|
+
- **Single-summary `customText` blob.** Compressing the entire conversation into one ElaborationQuestion with a long markdown summary in `customText`. The schema is multi-question for a reason — preserve the decision granularity.
|
|
161
|
+
- **Transcript-as-comment.** Posting the raw conversation log as a comment on the idea (or anywhere). The synthesized round IS the artifact. Raw transcripts pollute the audit trail with noise.
|
|
162
|
+
- **File writes.** Writing any markdown, design doc, plan, or scratch file to disk. There is no design doc in this flow. This is a deliberate divergence from the upstream `superpowers/brainstorming` cadence — read the design.md if confused.
|
|
163
|
+
- **`validate_elaboration` calls.** Closing the elaboration phase from this skill. The lifecycle decision belongs to the idea skill. Calling validate here strips the caller of its scheduler role.
|
|
164
|
+
- **`writing-plans` / design-doc handoff.** Invoking any skill that produces an implementation plan or design document. The Chorus pipeline already has Proposal → Document Drafts → Task Drafts for that — the brainstorm output feeds them through ElaborationRound, not through external doc skills.
|
|
165
|
+
- **Length-2 binary "yes / no" framings.** Reducing every decision to "do this thing — yes / no". Almost always the genuine alternatives are 3+ approaches with meaningfully different tradeoffs. Length-2 framings often mean the divergent phase ended too early.
|
|
166
|
+
- **Asking multiple questions in one `AskUserQuestion`.** The cadence is one question per turn during divergence, then one final convergence question with 2-3 options. Combining unrelated questions is a sign you are rushing.
|