gsd-pi 2.69.0 → 2.70.0-dev.7ebda5e
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/dist/loader.js +4 -0
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +150 -2
- package/dist/resources/extensions/gsd/auto-model-selection.js +33 -19
- package/dist/resources/extensions/gsd/auto-prompts.js +7 -3
- package/dist/resources/extensions/gsd/auto-start.js +25 -1
- package/dist/resources/extensions/gsd/auto.js +12 -8
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +6 -2
- package/dist/resources/extensions/gsd/commands-cmux.js +30 -1
- package/dist/resources/extensions/gsd/commands-handlers.js +22 -8
- package/dist/resources/extensions/gsd/doctor-engine-checks.js +12 -0
- package/dist/resources/extensions/gsd/doctor-format.js +2 -0
- package/dist/resources/extensions/gsd/guided-flow.js +21 -10
- package/dist/resources/extensions/gsd/pre-execution-checks.js +5 -3
- package/dist/resources/extensions/gsd/validate-directory.js +30 -12
- package/dist/resources/extensions/gsd/workflow-mcp.js +64 -6
- package/dist/resources/extensions/slash-commands/audit.js +2 -1
- package/dist/resources/extensions/subagent/isolation.js +4 -2
- package/dist/update-check.d.ts +1 -0
- package/dist/update-check.js +30 -27
- package/dist/update-cmd.js +3 -11
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +12 -12
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/required-server-files.json +4 -4
- package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
- package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +4 -4
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/page.js +2 -2
- package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +12 -12
- package/dist/web/standalone/.next/server/chunks/63.js +3 -3
- package/dist/web/standalone/.next/server/chunks/6897.js +3 -3
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware.js +2 -2
- package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
- package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/page-f1e30ab6bb269149.js +1 -0
- package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
- package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
- package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
- package/dist/web/standalone/server.js +1 -1
- package/dist/web-mode.js +4 -0
- package/package.json +11 -11
- package/packages/daemon/src/orchestrator.ts +9 -84
- package/packages/mcp-server/README.md +25 -3
- package/packages/mcp-server/dist/cli.d.ts +0 -1
- package/packages/mcp-server/dist/cli.d.ts.map +1 -1
- package/packages/mcp-server/dist/cli.js +4 -2
- package/packages/mcp-server/dist/cli.js.map +1 -1
- package/packages/mcp-server/dist/server.d.ts +32 -1
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +118 -1
- package/packages/mcp-server/dist/server.js.map +1 -1
- package/packages/mcp-server/dist/tool-credentials.d.ts +6 -0
- package/packages/mcp-server/dist/tool-credentials.d.ts.map +1 -0
- package/packages/mcp-server/dist/tool-credentials.js +90 -0
- package/packages/mcp-server/dist/tool-credentials.js.map +1 -0
- package/packages/mcp-server/dist/workflow-tools.d.ts +3 -0
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +308 -4
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/src/cli.ts +5 -3
- package/packages/mcp-server/src/import-candidates.test.ts +48 -0
- package/packages/mcp-server/src/mcp-server.test.ts +85 -1
- package/packages/mcp-server/src/server.ts +188 -1
- package/packages/mcp-server/src/tool-credentials.test.ts +95 -0
- package/packages/mcp-server/src/tool-credentials.ts +97 -0
- package/packages/mcp-server/src/workflow-tools.test.ts +32 -25
- package/packages/mcp-server/src/workflow-tools.ts +398 -2
- package/packages/pi-agent-core/dist/agent.d.ts +8 -0
- package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/agent.js +3 -0
- package/packages/pi-agent-core/dist/agent.js.map +1 -1
- package/packages/pi-agent-core/src/agent.test.ts +82 -0
- package/packages/pi-agent-core/src/agent.ts +12 -0
- package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.js +1 -23
- package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/index.d.ts +3 -2
- package/packages/pi-ai/dist/utils/oauth/index.d.ts.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/index.js +3 -5
- package/packages/pi-ai/dist/utils/oauth/index.js.map +1 -1
- package/packages/pi-ai/src/providers/anthropic.ts +1 -31
- package/packages/pi-ai/src/utils/oauth/index.ts +3 -5
- package/packages/pi-coding-agent/dist/core/lsp/config.d.ts +1 -0
- package/packages/pi-coding-agent/dist/core/lsp/config.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/config.js +38 -15
- package/packages/pi-coding-agent/dist/core/lsp/config.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.js +10 -0
- package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js +3 -1
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js.map +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/lsp/config.ts +43 -17
- package/packages/pi-coding-agent/src/core/sdk.ts +8 -0
- package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.ts +7 -5
- package/pkg/package.json +1 -1
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +227 -2
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +172 -0
- package/src/resources/extensions/gsd/auto-model-selection.ts +39 -25
- package/src/resources/extensions/gsd/auto-prompts.ts +7 -3
- package/src/resources/extensions/gsd/auto-start.ts +34 -1
- package/src/resources/extensions/gsd/auto.ts +12 -8
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +9 -5
- package/src/resources/extensions/gsd/commands-cmux.ts +32 -1
- package/src/resources/extensions/gsd/commands-handlers.ts +22 -7
- package/src/resources/extensions/gsd/doctor-engine-checks.ts +14 -0
- package/src/resources/extensions/gsd/doctor-format.ts +1 -0
- package/src/resources/extensions/gsd/doctor-types.ts +1 -0
- package/src/resources/extensions/gsd/guided-flow.ts +24 -8
- package/src/resources/extensions/gsd/pre-execution-checks.ts +6 -3
- package/src/resources/extensions/gsd/tests/cmux.test.ts +67 -1
- package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +43 -0
- package/src/resources/extensions/gsd/tests/interactive-routing-bypass.test.ts +207 -0
- package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +6 -2
- package/src/resources/extensions/gsd/tests/pre-exec-backtick-strip.test.ts +48 -1
- package/src/resources/extensions/gsd/tests/resource-loader-import-path.test.ts +8 -7
- package/src/resources/extensions/gsd/tests/validate-directory.test.ts +33 -1
- package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +87 -1
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +48 -7
- package/src/resources/extensions/gsd/validate-directory.ts +33 -11
- package/src/resources/extensions/gsd/workflow-mcp.ts +74 -5
- package/src/resources/extensions/slash-commands/audit.ts +2 -1
- package/src/resources/extensions/subagent/isolation.ts +4 -3
- package/dist/web/standalone/.next/static/chunks/app/page-7115e62689b5fd84.js +0 -1
- package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
- package/packages/pi-ai/dist/utils/oauth/anthropic.d.ts +0 -17
- package/packages/pi-ai/dist/utils/oauth/anthropic.d.ts.map +0 -1
- package/packages/pi-ai/dist/utils/oauth/anthropic.js +0 -106
- package/packages/pi-ai/dist/utils/oauth/anthropic.js.map +0 -1
- package/packages/pi-ai/src/utils/oauth/anthropic.ts +0 -140
- /package/dist/web/standalone/.next/static/{DrWdzskk28E5Qz-Wjw1mj → yvFbuOJuph5517lR7HBt2}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{DrWdzskk28E5Qz-Wjw1mj → yvFbuOJuph5517lR7HBt2}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
const AUTH_ENV_KEYS = [
|
|
5
|
+
["anthropic", "ANTHROPIC_API_KEY"],
|
|
6
|
+
["openai", "OPENAI_API_KEY"],
|
|
7
|
+
["github-copilot", "GITHUB_TOKEN"],
|
|
8
|
+
["google", "GEMINI_API_KEY"],
|
|
9
|
+
["groq", "GROQ_API_KEY"],
|
|
10
|
+
["xai", "XAI_API_KEY"],
|
|
11
|
+
["openrouter", "OPENROUTER_API_KEY"],
|
|
12
|
+
["mistral", "MISTRAL_API_KEY"],
|
|
13
|
+
["ollama-cloud", "OLLAMA_API_KEY"],
|
|
14
|
+
["custom-openai", "CUSTOM_OPENAI_API_KEY"],
|
|
15
|
+
["cerebras", "CEREBRAS_API_KEY"],
|
|
16
|
+
["azure-openai-responses", "AZURE_OPENAI_API_KEY"],
|
|
17
|
+
["vercel-ai-gateway", "AI_GATEWAY_API_KEY"],
|
|
18
|
+
["zai", "ZAI_API_KEY"],
|
|
19
|
+
["minimax", "MINIMAX_API_KEY"],
|
|
20
|
+
["minimax-cn", "MINIMAX_CN_API_KEY"],
|
|
21
|
+
["huggingface", "HF_TOKEN"],
|
|
22
|
+
["opencode", "OPENCODE_API_KEY"],
|
|
23
|
+
["opencode-go", "OPENCODE_API_KEY"],
|
|
24
|
+
["kimi-coding", "KIMI_API_KEY"],
|
|
25
|
+
["alibaba-coding-plan", "ALIBABA_API_KEY"],
|
|
26
|
+
["brave", "BRAVE_API_KEY"],
|
|
27
|
+
["brave_answers", "BRAVE_ANSWERS_KEY"],
|
|
28
|
+
["context7", "CONTEXT7_API_KEY"],
|
|
29
|
+
["jina", "JINA_API_KEY"],
|
|
30
|
+
["tavily", "TAVILY_API_KEY"],
|
|
31
|
+
["slack_bot", "SLACK_BOT_TOKEN"],
|
|
32
|
+
["discord_bot", "DISCORD_BOT_TOKEN"],
|
|
33
|
+
["telegram_bot", "TELEGRAM_BOT_TOKEN"],
|
|
34
|
+
];
|
|
35
|
+
function expandHome(pathValue) {
|
|
36
|
+
if (pathValue === "~")
|
|
37
|
+
return homedir();
|
|
38
|
+
if (pathValue.startsWith("~/"))
|
|
39
|
+
return join(homedir(), pathValue.slice(2));
|
|
40
|
+
return pathValue;
|
|
41
|
+
}
|
|
42
|
+
function getStoredApiKey(data, providerId) {
|
|
43
|
+
const raw = data[providerId];
|
|
44
|
+
const credentials = Array.isArray(raw) ? raw : raw ? [raw] : [];
|
|
45
|
+
for (const credential of credentials) {
|
|
46
|
+
if (credential?.type !== "api_key")
|
|
47
|
+
continue;
|
|
48
|
+
if (typeof credential.key !== "string")
|
|
49
|
+
continue;
|
|
50
|
+
if (credential.key.trim().length === 0)
|
|
51
|
+
continue;
|
|
52
|
+
return credential.key;
|
|
53
|
+
}
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
export function resolveAuthPath(env = process.env) {
|
|
57
|
+
const agentDir = env.GSD_CODING_AGENT_DIR?.trim();
|
|
58
|
+
if (agentDir)
|
|
59
|
+
return join(expandHome(agentDir), "auth.json");
|
|
60
|
+
return join(homedir(), ".gsd", "agent", "auth.json");
|
|
61
|
+
}
|
|
62
|
+
export function loadStoredCredentialEnvKeys(options = {}) {
|
|
63
|
+
const env = options.env ?? process.env;
|
|
64
|
+
const authPath = options.authPath ?? resolveAuthPath(env);
|
|
65
|
+
if (!existsSync(authPath))
|
|
66
|
+
return [];
|
|
67
|
+
let parsed;
|
|
68
|
+
try {
|
|
69
|
+
const raw = readFileSync(authPath, "utf-8");
|
|
70
|
+
const data = JSON.parse(raw);
|
|
71
|
+
if (!data || typeof data !== "object" || Array.isArray(data))
|
|
72
|
+
return [];
|
|
73
|
+
parsed = data;
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
return [];
|
|
77
|
+
}
|
|
78
|
+
const loaded = [];
|
|
79
|
+
for (const [providerId, envVar] of AUTH_ENV_KEYS) {
|
|
80
|
+
if (env[envVar])
|
|
81
|
+
continue;
|
|
82
|
+
const key = getStoredApiKey(parsed, providerId);
|
|
83
|
+
if (!key)
|
|
84
|
+
continue;
|
|
85
|
+
env[envVar] = key;
|
|
86
|
+
loaded.push(envVar);
|
|
87
|
+
}
|
|
88
|
+
return loaded;
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=tool-credentials.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-credentials.js","sourceRoot":"","sources":["../src/tool-credentials.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\ntype AuthCredential =\n | { type?: unknown; key?: unknown }\n | Array<{ type?: unknown; key?: unknown }>;\n\ntype AuthStorageData = Record<string, AuthCredential>;\n\nconst AUTH_ENV_KEYS = [\n [\"anthropic\", \"ANTHROPIC_API_KEY\"],\n [\"openai\", \"OPENAI_API_KEY\"],\n [\"github-copilot\", \"GITHUB_TOKEN\"],\n [\"google\", \"GEMINI_API_KEY\"],\n [\"groq\", \"GROQ_API_KEY\"],\n [\"xai\", \"XAI_API_KEY\"],\n [\"openrouter\", \"OPENROUTER_API_KEY\"],\n [\"mistral\", \"MISTRAL_API_KEY\"],\n [\"ollama-cloud\", \"OLLAMA_API_KEY\"],\n [\"custom-openai\", \"CUSTOM_OPENAI_API_KEY\"],\n [\"cerebras\", \"CEREBRAS_API_KEY\"],\n [\"azure-openai-responses\", \"AZURE_OPENAI_API_KEY\"],\n [\"vercel-ai-gateway\", \"AI_GATEWAY_API_KEY\"],\n [\"zai\", \"ZAI_API_KEY\"],\n [\"minimax\", \"MINIMAX_API_KEY\"],\n [\"minimax-cn\", \"MINIMAX_CN_API_KEY\"],\n [\"huggingface\", \"HF_TOKEN\"],\n [\"opencode\", \"OPENCODE_API_KEY\"],\n [\"opencode-go\", \"OPENCODE_API_KEY\"],\n [\"kimi-coding\", \"KIMI_API_KEY\"],\n [\"alibaba-coding-plan\", \"ALIBABA_API_KEY\"],\n [\"brave\", \"BRAVE_API_KEY\"],\n [\"brave_answers\", \"BRAVE_ANSWERS_KEY\"],\n [\"context7\", \"CONTEXT7_API_KEY\"],\n [\"jina\", \"JINA_API_KEY\"],\n [\"tavily\", \"TAVILY_API_KEY\"],\n [\"slack_bot\", \"SLACK_BOT_TOKEN\"],\n [\"discord_bot\", \"DISCORD_BOT_TOKEN\"],\n [\"telegram_bot\", \"TELEGRAM_BOT_TOKEN\"],\n] as const;\n\nfunction expandHome(pathValue: string): string {\n if (pathValue === \"~\") return homedir();\n if (pathValue.startsWith(\"~/\")) return join(homedir(), pathValue.slice(2));\n return pathValue;\n}\n\nfunction getStoredApiKey(data: AuthStorageData, providerId: string): string | undefined {\n const raw = data[providerId];\n const credentials = Array.isArray(raw) ? raw : raw ? [raw] : [];\n\n for (const credential of credentials) {\n if (credential?.type !== \"api_key\") continue;\n if (typeof credential.key !== \"string\") continue;\n if (credential.key.trim().length === 0) continue;\n return credential.key;\n }\n\n return undefined;\n}\n\nexport function resolveAuthPath(env: NodeJS.ProcessEnv = process.env): string {\n const agentDir = env.GSD_CODING_AGENT_DIR?.trim();\n if (agentDir) return join(expandHome(agentDir), \"auth.json\");\n return join(homedir(), \".gsd\", \"agent\", \"auth.json\");\n}\n\nexport function loadStoredCredentialEnvKeys(options: {\n env?: NodeJS.ProcessEnv;\n authPath?: string;\n} = {}): string[] {\n const env = options.env ?? process.env;\n const authPath = options.authPath ?? resolveAuthPath(env);\n if (!existsSync(authPath)) return [];\n\n let parsed: AuthStorageData;\n try {\n const raw = readFileSync(authPath, \"utf-8\");\n const data = JSON.parse(raw) as unknown;\n if (!data || typeof data !== \"object\" || Array.isArray(data)) return [];\n parsed = data as AuthStorageData;\n } catch {\n return [];\n }\n\n const loaded: string[] = [];\n for (const [providerId, envVar] of AUTH_ENV_KEYS) {\n if (env[envVar]) continue;\n const key = getStoredApiKey(parsed, providerId);\n if (!key) continue;\n env[envVar] = key;\n loaded.push(envVar);\n }\n\n return loaded;\n}\n"]}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Workflow MCP tools — exposes the core GSD mutation/read handlers over MCP.
|
|
3
3
|
*/
|
|
4
|
+
/** @internal — exported for testing only */
|
|
5
|
+
export declare function _buildImportCandidates(relativePath: string): string[];
|
|
4
6
|
interface McpToolServer {
|
|
5
7
|
tool(name: string, description: string, params: Record<string, unknown>, handler: (args: Record<string, unknown>) => Promise<unknown>): unknown;
|
|
6
8
|
}
|
|
9
|
+
export declare const WORKFLOW_TOOL_NAMES: readonly ["gsd_decision_save", "gsd_save_decision", "gsd_requirement_update", "gsd_update_requirement", "gsd_requirement_save", "gsd_save_requirement", "gsd_milestone_generate_id", "gsd_generate_milestone_id", "gsd_plan_milestone", "gsd_plan_slice", "gsd_plan_task", "gsd_task_plan", "gsd_replan_slice", "gsd_slice_replan", "gsd_slice_complete", "gsd_complete_slice", "gsd_skip_slice", "gsd_complete_milestone", "gsd_milestone_complete", "gsd_validate_milestone", "gsd_milestone_validate", "gsd_reassess_roadmap", "gsd_roadmap_reassess", "gsd_save_gate_result", "gsd_summary_save", "gsd_task_complete", "gsd_complete_task", "gsd_milestone_status", "gsd_journal_query"];
|
|
7
10
|
export declare function registerWorkflowTools(server: McpToolServer): void;
|
|
8
11
|
export {};
|
|
9
12
|
//# sourceMappingURL=workflow-tools.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workflow-tools.d.ts","sourceRoot":"","sources":["../src/workflow-tools.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"workflow-tools.d.ts","sourceRoot":"","sources":["../src/workflow-tools.ts"],"names":[],"mappings":"AAAA;;GAEG;AAiVH,4CAA4C;AAC5C,wBAAgB,sBAAsB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,EAAE,CAiBrE;AA6FD,UAAU,aAAa;IACrB,IAAI,CACF,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,GAC3D,OAAO,CAAC;CACZ;AAED,eAAO,MAAM,mBAAmB,8pBA8BtB,CAAC;AAydX,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CA8ajE"}
|
|
@@ -63,27 +63,62 @@ function getWriteGateModuleCandidates() {
|
|
|
63
63
|
const candidates = [];
|
|
64
64
|
const explicitModule = process.env.GSD_WORKFLOW_WRITE_GATE_MODULE?.trim();
|
|
65
65
|
if (explicitModule) {
|
|
66
|
-
if (/^[a-z]
|
|
66
|
+
if (/^[a-z]{2,}:/i.test(explicitModule) && !explicitModule.startsWith("file:")) {
|
|
67
67
|
throw new Error("GSD_WORKFLOW_WRITE_GATE_MODULE only supports file: URLs or filesystem paths.");
|
|
68
68
|
}
|
|
69
69
|
candidates.push(explicitModule.startsWith("file:") ? explicitModule : toFileUrl(explicitModule));
|
|
70
70
|
}
|
|
71
|
-
candidates.push(new URL("../../../src/resources/extensions/gsd/bootstrap/write-gate.js", import.meta.url).href, new URL("../../../src/resources/extensions/gsd/bootstrap/write-gate.ts", import.meta.url).href);
|
|
71
|
+
candidates.push(new URL("../../../src/resources/extensions/gsd/bootstrap/write-gate.js", import.meta.url).href, new URL("../../../dist/resources/extensions/gsd/bootstrap/write-gate.js", import.meta.url).href, new URL("../../../src/resources/extensions/gsd/bootstrap/write-gate.ts", import.meta.url).href);
|
|
72
72
|
return [...new Set(candidates)];
|
|
73
73
|
}
|
|
74
74
|
function toFileUrl(modulePath) {
|
|
75
75
|
return pathToFileURL(resolve(modulePath)).href;
|
|
76
76
|
}
|
|
77
|
+
/** @internal — exported for testing only */
|
|
78
|
+
export function _buildImportCandidates(relativePath) {
|
|
79
|
+
// Build candidate paths: try the given path first, then swap src/<->dist/
|
|
80
|
+
// and try .ts extension. This handles both dev (tsx from src/) and prod
|
|
81
|
+
// (compiled from dist/) execution contexts.
|
|
82
|
+
const candidates = [relativePath];
|
|
83
|
+
const swapped = relativePath.includes("/src/")
|
|
84
|
+
? relativePath.replace("/src/", "/dist/")
|
|
85
|
+
: relativePath.includes("/dist/")
|
|
86
|
+
? relativePath.replace("/dist/", "/src/")
|
|
87
|
+
: null;
|
|
88
|
+
if (swapped)
|
|
89
|
+
candidates.push(swapped);
|
|
90
|
+
// Also try .ts variants for dev-mode tsx execution
|
|
91
|
+
if (relativePath.endsWith(".js")) {
|
|
92
|
+
candidates.push(relativePath.replace(/\.js$/, ".ts"));
|
|
93
|
+
if (swapped)
|
|
94
|
+
candidates.push(swapped.replace(/\.js$/, ".ts"));
|
|
95
|
+
}
|
|
96
|
+
return candidates;
|
|
97
|
+
}
|
|
98
|
+
async function importLocalModule(relativePath) {
|
|
99
|
+
const candidates = _buildImportCandidates(relativePath)
|
|
100
|
+
.map((p) => new URL(p, import.meta.url).href);
|
|
101
|
+
let lastErr;
|
|
102
|
+
for (const candidate of candidates) {
|
|
103
|
+
try {
|
|
104
|
+
return await import(candidate);
|
|
105
|
+
}
|
|
106
|
+
catch (err) {
|
|
107
|
+
lastErr = err;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
throw lastErr;
|
|
111
|
+
}
|
|
77
112
|
function getWorkflowExecutorModuleCandidates(env = process.env) {
|
|
78
113
|
const candidates = [];
|
|
79
114
|
const explicitModule = env.GSD_WORKFLOW_EXECUTORS_MODULE?.trim();
|
|
80
115
|
if (explicitModule) {
|
|
81
|
-
if (/^[a-z]
|
|
116
|
+
if (/^[a-z]{2,}:/i.test(explicitModule) && !explicitModule.startsWith("file:")) {
|
|
82
117
|
throw new Error("GSD_WORKFLOW_EXECUTORS_MODULE only supports file: URLs or filesystem paths.");
|
|
83
118
|
}
|
|
84
119
|
candidates.push(explicitModule.startsWith("file:") ? explicitModule : toFileUrl(explicitModule));
|
|
85
120
|
}
|
|
86
|
-
candidates.push(new URL("../../../src/resources/extensions/gsd/tools/workflow-tool-executors.js", import.meta.url).href, new URL("../../../src/resources/extensions/gsd/tools/workflow-tool-executors.ts", import.meta.url).href);
|
|
121
|
+
candidates.push(new URL("../../../src/resources/extensions/gsd/tools/workflow-tool-executors.js", import.meta.url).href, new URL("../../../dist/resources/extensions/gsd/tools/workflow-tool-executors.js", import.meta.url).href, new URL("../../../src/resources/extensions/gsd/tools/workflow-tool-executors.ts", import.meta.url).href);
|
|
87
122
|
return [...new Set(candidates)];
|
|
88
123
|
}
|
|
89
124
|
async function getWorkflowToolExecutors() {
|
|
@@ -135,6 +170,37 @@ async function getWorkflowWriteGateModule() {
|
|
|
135
170
|
}
|
|
136
171
|
return workflowWriteGatePromise;
|
|
137
172
|
}
|
|
173
|
+
export const WORKFLOW_TOOL_NAMES = [
|
|
174
|
+
"gsd_decision_save",
|
|
175
|
+
"gsd_save_decision",
|
|
176
|
+
"gsd_requirement_update",
|
|
177
|
+
"gsd_update_requirement",
|
|
178
|
+
"gsd_requirement_save",
|
|
179
|
+
"gsd_save_requirement",
|
|
180
|
+
"gsd_milestone_generate_id",
|
|
181
|
+
"gsd_generate_milestone_id",
|
|
182
|
+
"gsd_plan_milestone",
|
|
183
|
+
"gsd_plan_slice",
|
|
184
|
+
"gsd_plan_task",
|
|
185
|
+
"gsd_task_plan",
|
|
186
|
+
"gsd_replan_slice",
|
|
187
|
+
"gsd_slice_replan",
|
|
188
|
+
"gsd_slice_complete",
|
|
189
|
+
"gsd_complete_slice",
|
|
190
|
+
"gsd_skip_slice",
|
|
191
|
+
"gsd_complete_milestone",
|
|
192
|
+
"gsd_milestone_complete",
|
|
193
|
+
"gsd_validate_milestone",
|
|
194
|
+
"gsd_milestone_validate",
|
|
195
|
+
"gsd_reassess_roadmap",
|
|
196
|
+
"gsd_roadmap_reassess",
|
|
197
|
+
"gsd_save_gate_result",
|
|
198
|
+
"gsd_summary_save",
|
|
199
|
+
"gsd_task_complete",
|
|
200
|
+
"gsd_complete_task",
|
|
201
|
+
"gsd_milestone_status",
|
|
202
|
+
"gsd_journal_query",
|
|
203
|
+
];
|
|
138
204
|
async function runSerializedWorkflowOperation(fn) {
|
|
139
205
|
// The shared DB adapter and workflow log base path are process-global, so
|
|
140
206
|
// workflow MCP mutations must not overlap within a single server process.
|
|
@@ -218,6 +284,15 @@ async function handleSaveGateResult(projectDir, args) {
|
|
|
218
284
|
const { projectDir: _projectDir, ...params } = args;
|
|
219
285
|
return runSerializedWorkflowOperation(() => executeSaveGateResult(params, projectDir));
|
|
220
286
|
}
|
|
287
|
+
async function ensureMilestoneDbRow(milestoneId) {
|
|
288
|
+
try {
|
|
289
|
+
const { insertMilestone } = await importLocalModule("../../../src/resources/extensions/gsd/gsd-db.js");
|
|
290
|
+
insertMilestone({ id: milestoneId, status: "queued" });
|
|
291
|
+
}
|
|
292
|
+
catch {
|
|
293
|
+
// Ignore pre-existing rows or transient DB availability issues.
|
|
294
|
+
}
|
|
295
|
+
}
|
|
221
296
|
const projectDirParam = z.string().describe("Absolute path to the project directory within the configured workflow root");
|
|
222
297
|
const planMilestoneParams = {
|
|
223
298
|
projectDir: projectDirParam,
|
|
@@ -413,6 +488,67 @@ const summarySaveParams = {
|
|
|
413
488
|
content: z.string().describe("The full markdown content of the artifact"),
|
|
414
489
|
};
|
|
415
490
|
const summarySaveSchema = z.object(summarySaveParams);
|
|
491
|
+
const decisionSaveParams = {
|
|
492
|
+
projectDir: projectDirParam,
|
|
493
|
+
scope: z.string().describe("Scope of the decision (e.g. architecture, library, observability)"),
|
|
494
|
+
decision: z.string().describe("What is being decided"),
|
|
495
|
+
choice: z.string().describe("The choice made"),
|
|
496
|
+
rationale: z.string().describe("Why this choice was made"),
|
|
497
|
+
revisable: z.string().optional().describe("Whether this can be revisited"),
|
|
498
|
+
when_context: z.string().optional().describe("When/context for the decision"),
|
|
499
|
+
made_by: z.enum(["human", "agent", "collaborative"]).optional().describe("Who made the decision"),
|
|
500
|
+
};
|
|
501
|
+
const decisionSaveSchema = z.object(decisionSaveParams);
|
|
502
|
+
const requirementUpdateParams = {
|
|
503
|
+
projectDir: projectDirParam,
|
|
504
|
+
id: z.string().describe("Requirement ID (e.g. R001)"),
|
|
505
|
+
status: z.string().optional().describe("New status"),
|
|
506
|
+
validation: z.string().optional().describe("Validation criteria or proof"),
|
|
507
|
+
notes: z.string().optional().describe("Additional notes"),
|
|
508
|
+
description: z.string().optional().describe("Updated description"),
|
|
509
|
+
primary_owner: z.string().optional().describe("Primary owning slice"),
|
|
510
|
+
supporting_slices: z.string().optional().describe("Supporting slices"),
|
|
511
|
+
};
|
|
512
|
+
const requirementUpdateSchema = z.object(requirementUpdateParams);
|
|
513
|
+
const requirementSaveParams = {
|
|
514
|
+
projectDir: projectDirParam,
|
|
515
|
+
class: z.string().describe("Requirement class"),
|
|
516
|
+
description: z.string().describe("Short description of the requirement"),
|
|
517
|
+
why: z.string().describe("Why this requirement matters"),
|
|
518
|
+
source: z.string().describe("Origin of the requirement"),
|
|
519
|
+
status: z.string().optional().describe("Requirement status"),
|
|
520
|
+
primary_owner: z.string().optional().describe("Primary owning slice"),
|
|
521
|
+
supporting_slices: z.string().optional().describe("Supporting slices"),
|
|
522
|
+
validation: z.string().optional().describe("Validation criteria"),
|
|
523
|
+
notes: z.string().optional().describe("Additional notes"),
|
|
524
|
+
};
|
|
525
|
+
const requirementSaveSchema = z.object(requirementSaveParams);
|
|
526
|
+
const milestoneGenerateIdParams = {
|
|
527
|
+
projectDir: projectDirParam,
|
|
528
|
+
};
|
|
529
|
+
const milestoneGenerateIdSchema = z.object(milestoneGenerateIdParams);
|
|
530
|
+
const planTaskParams = {
|
|
531
|
+
projectDir: projectDirParam,
|
|
532
|
+
milestoneId: z.string().describe("Milestone ID (e.g. M001)"),
|
|
533
|
+
sliceId: z.string().describe("Slice ID (e.g. S01)"),
|
|
534
|
+
taskId: z.string().describe("Task ID (e.g. T01)"),
|
|
535
|
+
title: z.string().describe("Task title"),
|
|
536
|
+
description: z.string().describe("Task description / steps block"),
|
|
537
|
+
estimate: z.string().describe("Task estimate"),
|
|
538
|
+
files: z.array(z.string()).describe("Files likely touched"),
|
|
539
|
+
verify: z.string().describe("Verification command or block"),
|
|
540
|
+
inputs: z.array(z.string()).describe("Input files or references"),
|
|
541
|
+
expectedOutput: z.array(z.string()).describe("Expected output files or artifacts"),
|
|
542
|
+
observabilityImpact: z.string().optional().describe("Task observability impact"),
|
|
543
|
+
};
|
|
544
|
+
const planTaskSchema = z.object(planTaskParams);
|
|
545
|
+
const skipSliceParams = {
|
|
546
|
+
projectDir: projectDirParam,
|
|
547
|
+
sliceId: z.string().describe("Slice ID (e.g. S02)"),
|
|
548
|
+
milestoneId: z.string().describe("Milestone ID (e.g. M003)"),
|
|
549
|
+
reason: z.string().optional().describe("Reason for skipping this slice"),
|
|
550
|
+
};
|
|
551
|
+
const skipSliceSchema = z.object(skipSliceParams);
|
|
416
552
|
const taskCompleteParams = {
|
|
417
553
|
projectDir: projectDirParam,
|
|
418
554
|
taskId: z.string().describe("Task ID (e.g. T01)"),
|
|
@@ -442,7 +578,112 @@ const milestoneStatusParams = {
|
|
|
442
578
|
milestoneId: z.string().describe("Milestone ID to query (e.g. M001)"),
|
|
443
579
|
};
|
|
444
580
|
const milestoneStatusSchema = z.object(milestoneStatusParams);
|
|
581
|
+
const journalQueryParams = {
|
|
582
|
+
projectDir: projectDirParam,
|
|
583
|
+
flowId: z.string().optional().describe("Filter by flow ID"),
|
|
584
|
+
unitId: z.string().optional().describe("Filter by unit ID"),
|
|
585
|
+
rule: z.string().optional().describe("Filter by rule name"),
|
|
586
|
+
eventType: z.string().optional().describe("Filter by event type"),
|
|
587
|
+
after: z.string().optional().describe("ISO-8601 lower bound (inclusive)"),
|
|
588
|
+
before: z.string().optional().describe("ISO-8601 upper bound (inclusive)"),
|
|
589
|
+
limit: z.number().optional().describe("Maximum entries to return"),
|
|
590
|
+
};
|
|
591
|
+
const journalQuerySchema = z.object(journalQueryParams);
|
|
445
592
|
export function registerWorkflowTools(server) {
|
|
593
|
+
server.tool("gsd_decision_save", "Record a project decision to the GSD database and regenerate DECISIONS.md.", decisionSaveParams, async (args) => {
|
|
594
|
+
const parsed = parseWorkflowArgs(decisionSaveSchema, args);
|
|
595
|
+
const { projectDir, ...params } = parsed;
|
|
596
|
+
await enforceWorkflowWriteGate("gsd_decision_save", projectDir);
|
|
597
|
+
const result = await runSerializedWorkflowOperation(async () => {
|
|
598
|
+
const { saveDecisionToDb } = await importLocalModule("../../../src/resources/extensions/gsd/db-writer.js");
|
|
599
|
+
return saveDecisionToDb(params, projectDir);
|
|
600
|
+
});
|
|
601
|
+
return { content: [{ type: "text", text: `Saved decision ${result.id}` }] };
|
|
602
|
+
});
|
|
603
|
+
server.tool("gsd_save_decision", "Alias for gsd_decision_save. Record a project decision to the GSD database and regenerate DECISIONS.md.", decisionSaveParams, async (args) => {
|
|
604
|
+
const parsed = parseWorkflowArgs(decisionSaveSchema, args);
|
|
605
|
+
const { projectDir, ...params } = parsed;
|
|
606
|
+
await enforceWorkflowWriteGate("gsd_decision_save", projectDir);
|
|
607
|
+
const result = await runSerializedWorkflowOperation(async () => {
|
|
608
|
+
const { saveDecisionToDb } = await importLocalModule("../../../src/resources/extensions/gsd/db-writer.js");
|
|
609
|
+
return saveDecisionToDb(params, projectDir);
|
|
610
|
+
});
|
|
611
|
+
return { content: [{ type: "text", text: `Saved decision ${result.id}` }] };
|
|
612
|
+
});
|
|
613
|
+
server.tool("gsd_requirement_update", "Update an existing requirement in the GSD database and regenerate REQUIREMENTS.md.", requirementUpdateParams, async (args) => {
|
|
614
|
+
const parsed = parseWorkflowArgs(requirementUpdateSchema, args);
|
|
615
|
+
const { projectDir, id, ...updates } = parsed;
|
|
616
|
+
await enforceWorkflowWriteGate("gsd_requirement_update", projectDir);
|
|
617
|
+
await runSerializedWorkflowOperation(async () => {
|
|
618
|
+
const { updateRequirementInDb } = await importLocalModule("../../../src/resources/extensions/gsd/db-writer.js");
|
|
619
|
+
return updateRequirementInDb(id, updates, projectDir);
|
|
620
|
+
});
|
|
621
|
+
return { content: [{ type: "text", text: `Updated requirement ${id}` }] };
|
|
622
|
+
});
|
|
623
|
+
server.tool("gsd_update_requirement", "Alias for gsd_requirement_update. Update an existing requirement in the GSD database and regenerate REQUIREMENTS.md.", requirementUpdateParams, async (args) => {
|
|
624
|
+
const parsed = parseWorkflowArgs(requirementUpdateSchema, args);
|
|
625
|
+
const { projectDir, id, ...updates } = parsed;
|
|
626
|
+
await enforceWorkflowWriteGate("gsd_requirement_update", projectDir);
|
|
627
|
+
await runSerializedWorkflowOperation(async () => {
|
|
628
|
+
const { updateRequirementInDb } = await importLocalModule("../../../src/resources/extensions/gsd/db-writer.js");
|
|
629
|
+
return updateRequirementInDb(id, updates, projectDir);
|
|
630
|
+
});
|
|
631
|
+
return { content: [{ type: "text", text: `Updated requirement ${id}` }] };
|
|
632
|
+
});
|
|
633
|
+
server.tool("gsd_requirement_save", "Record a new requirement to the GSD database and regenerate REQUIREMENTS.md.", requirementSaveParams, async (args) => {
|
|
634
|
+
const parsed = parseWorkflowArgs(requirementSaveSchema, args);
|
|
635
|
+
const { projectDir, ...params } = parsed;
|
|
636
|
+
await enforceWorkflowWriteGate("gsd_requirement_save", projectDir);
|
|
637
|
+
const result = await runSerializedWorkflowOperation(async () => {
|
|
638
|
+
const { saveRequirementToDb } = await importLocalModule("../../../src/resources/extensions/gsd/db-writer.js");
|
|
639
|
+
return saveRequirementToDb(params, projectDir);
|
|
640
|
+
});
|
|
641
|
+
return { content: [{ type: "text", text: `Saved requirement ${result.id}` }] };
|
|
642
|
+
});
|
|
643
|
+
server.tool("gsd_save_requirement", "Alias for gsd_requirement_save. Record a new requirement to the GSD database and regenerate REQUIREMENTS.md.", requirementSaveParams, async (args) => {
|
|
644
|
+
const parsed = parseWorkflowArgs(requirementSaveSchema, args);
|
|
645
|
+
const { projectDir, ...params } = parsed;
|
|
646
|
+
await enforceWorkflowWriteGate("gsd_requirement_save", projectDir);
|
|
647
|
+
const result = await runSerializedWorkflowOperation(async () => {
|
|
648
|
+
const { saveRequirementToDb } = await importLocalModule("../../../src/resources/extensions/gsd/db-writer.js");
|
|
649
|
+
return saveRequirementToDb(params, projectDir);
|
|
650
|
+
});
|
|
651
|
+
return { content: [{ type: "text", text: `Saved requirement ${result.id}` }] };
|
|
652
|
+
});
|
|
653
|
+
server.tool("gsd_milestone_generate_id", "Generate the next milestone ID for a new GSD milestone.", milestoneGenerateIdParams, async (args) => {
|
|
654
|
+
const { projectDir } = parseWorkflowArgs(milestoneGenerateIdSchema, args);
|
|
655
|
+
await enforceWorkflowWriteGate("gsd_milestone_generate_id", projectDir);
|
|
656
|
+
const id = await runSerializedWorkflowOperation(async () => {
|
|
657
|
+
const { claimReservedId, findMilestoneIds, getReservedMilestoneIds, nextMilestoneId, } = await importLocalModule("../../../src/resources/extensions/gsd/milestone-ids.js");
|
|
658
|
+
const reserved = claimReservedId();
|
|
659
|
+
if (reserved) {
|
|
660
|
+
await ensureMilestoneDbRow(reserved);
|
|
661
|
+
return reserved;
|
|
662
|
+
}
|
|
663
|
+
const allIds = [...new Set([...findMilestoneIds(projectDir), ...getReservedMilestoneIds()])];
|
|
664
|
+
const nextId = nextMilestoneId(allIds);
|
|
665
|
+
await ensureMilestoneDbRow(nextId);
|
|
666
|
+
return nextId;
|
|
667
|
+
});
|
|
668
|
+
return { content: [{ type: "text", text: id }] };
|
|
669
|
+
});
|
|
670
|
+
server.tool("gsd_generate_milestone_id", "Alias for gsd_milestone_generate_id. Generate the next milestone ID for a new GSD milestone.", milestoneGenerateIdParams, async (args) => {
|
|
671
|
+
const { projectDir } = parseWorkflowArgs(milestoneGenerateIdSchema, args);
|
|
672
|
+
await enforceWorkflowWriteGate("gsd_milestone_generate_id", projectDir);
|
|
673
|
+
const id = await runSerializedWorkflowOperation(async () => {
|
|
674
|
+
const { claimReservedId, findMilestoneIds, getReservedMilestoneIds, nextMilestoneId, } = await importLocalModule("../../../src/resources/extensions/gsd/milestone-ids.js");
|
|
675
|
+
const reserved = claimReservedId();
|
|
676
|
+
if (reserved) {
|
|
677
|
+
await ensureMilestoneDbRow(reserved);
|
|
678
|
+
return reserved;
|
|
679
|
+
}
|
|
680
|
+
const allIds = [...new Set([...findMilestoneIds(projectDir), ...getReservedMilestoneIds()])];
|
|
681
|
+
const nextId = nextMilestoneId(allIds);
|
|
682
|
+
await ensureMilestoneDbRow(nextId);
|
|
683
|
+
return nextId;
|
|
684
|
+
});
|
|
685
|
+
return { content: [{ type: "text", text: id }] };
|
|
686
|
+
});
|
|
446
687
|
server.tool("gsd_plan_milestone", "Write milestone planning state to the GSD database and render ROADMAP.md from DB.", planMilestoneParams, async (args) => {
|
|
447
688
|
const parsed = parseWorkflowArgs(planMilestoneSchema, args);
|
|
448
689
|
const { projectDir, ...params } = parsed;
|
|
@@ -457,6 +698,36 @@ export function registerWorkflowTools(server) {
|
|
|
457
698
|
const { executePlanSlice } = await getWorkflowToolExecutors();
|
|
458
699
|
return runSerializedWorkflowOperation(() => executePlanSlice(params, projectDir));
|
|
459
700
|
});
|
|
701
|
+
server.tool("gsd_plan_task", "Write task planning state to the GSD database and render tasks/T##-PLAN.md from DB.", planTaskParams, async (args) => {
|
|
702
|
+
const parsed = parseWorkflowArgs(planTaskSchema, args);
|
|
703
|
+
const { projectDir, ...params } = parsed;
|
|
704
|
+
await enforceWorkflowWriteGate("gsd_plan_task", projectDir, params.milestoneId);
|
|
705
|
+
const result = await runSerializedWorkflowOperation(async () => {
|
|
706
|
+
const { handlePlanTask } = await importLocalModule("../../../src/resources/extensions/gsd/tools/plan-task.js");
|
|
707
|
+
return handlePlanTask(params, projectDir);
|
|
708
|
+
});
|
|
709
|
+
if ("error" in result) {
|
|
710
|
+
throw new Error(result.error);
|
|
711
|
+
}
|
|
712
|
+
return {
|
|
713
|
+
content: [{ type: "text", text: `Planned task ${result.taskId} (${result.sliceId}/${result.milestoneId})` }],
|
|
714
|
+
};
|
|
715
|
+
});
|
|
716
|
+
server.tool("gsd_task_plan", "Alias for gsd_plan_task. Write task planning state to the GSD database and render tasks/T##-PLAN.md from DB.", planTaskParams, async (args) => {
|
|
717
|
+
const parsed = parseWorkflowArgs(planTaskSchema, args);
|
|
718
|
+
const { projectDir, ...params } = parsed;
|
|
719
|
+
await enforceWorkflowWriteGate("gsd_plan_task", projectDir, params.milestoneId);
|
|
720
|
+
const result = await runSerializedWorkflowOperation(async () => {
|
|
721
|
+
const { handlePlanTask } = await importLocalModule("../../../src/resources/extensions/gsd/tools/plan-task.js");
|
|
722
|
+
return handlePlanTask(params, projectDir);
|
|
723
|
+
});
|
|
724
|
+
if ("error" in result) {
|
|
725
|
+
throw new Error(result.error);
|
|
726
|
+
}
|
|
727
|
+
return {
|
|
728
|
+
content: [{ type: "text", text: `Planned task ${result.taskId} (${result.sliceId}/${result.milestoneId})` }],
|
|
729
|
+
};
|
|
730
|
+
});
|
|
460
731
|
server.tool("gsd_replan_slice", "Replan a slice after a blocker is discovered, preserving completed tasks and re-rendering PLAN.md + REPLAN.md.", replanSliceParams, async (args) => {
|
|
461
732
|
const parsed = parseWorkflowArgs(replanSliceSchema, args);
|
|
462
733
|
return handleReplanSlice(parsed.projectDir, parsed);
|
|
@@ -473,6 +744,30 @@ export function registerWorkflowTools(server) {
|
|
|
473
744
|
const parsed = parseWorkflowArgs(sliceCompleteSchema, args);
|
|
474
745
|
return handleSliceComplete(parsed.projectDir, parsed);
|
|
475
746
|
});
|
|
747
|
+
server.tool("gsd_skip_slice", "Mark a slice as skipped so auto-mode advances past it without executing.", skipSliceParams, async (args) => {
|
|
748
|
+
const { projectDir, milestoneId, sliceId, reason } = parseWorkflowArgs(skipSliceSchema, args);
|
|
749
|
+
await enforceWorkflowWriteGate("gsd_skip_slice", projectDir, milestoneId);
|
|
750
|
+
await runSerializedWorkflowOperation(async () => {
|
|
751
|
+
const { getSlice, updateSliceStatus } = await importLocalModule("../../../src/resources/extensions/gsd/gsd-db.js");
|
|
752
|
+
const { invalidateStateCache } = await importLocalModule("../../../src/resources/extensions/gsd/state.js");
|
|
753
|
+
const { rebuildState } = await importLocalModule("../../../src/resources/extensions/gsd/doctor.js");
|
|
754
|
+
const slice = getSlice(milestoneId, sliceId);
|
|
755
|
+
if (!slice) {
|
|
756
|
+
throw new Error(`Slice ${sliceId} not found in milestone ${milestoneId}`);
|
|
757
|
+
}
|
|
758
|
+
if (slice.status === "complete" || slice.status === "done") {
|
|
759
|
+
throw new Error(`Slice ${sliceId} is already complete and cannot be skipped`);
|
|
760
|
+
}
|
|
761
|
+
if (slice.status !== "skipped") {
|
|
762
|
+
updateSliceStatus(milestoneId, sliceId, "skipped");
|
|
763
|
+
invalidateStateCache();
|
|
764
|
+
await rebuildState(projectDir);
|
|
765
|
+
}
|
|
766
|
+
});
|
|
767
|
+
return {
|
|
768
|
+
content: [{ type: "text", text: `Skipped slice ${sliceId} (${milestoneId}). Reason: ${reason ?? "User-directed skip"}.` }],
|
|
769
|
+
};
|
|
770
|
+
});
|
|
476
771
|
server.tool("gsd_complete_milestone", "Record a completed milestone to the GSD database and render its SUMMARY.md.", completeMilestoneParams, async (args) => {
|
|
477
772
|
const parsed = parseWorkflowArgs(completeMilestoneSchema, args);
|
|
478
773
|
return handleCompleteMilestone(parsed.projectDir, parsed);
|
|
@@ -528,5 +823,14 @@ export function registerWorkflowTools(server) {
|
|
|
528
823
|
const { executeMilestoneStatus } = await getWorkflowToolExecutors();
|
|
529
824
|
return runSerializedWorkflowOperation(() => executeMilestoneStatus({ milestoneId }, projectDir));
|
|
530
825
|
});
|
|
826
|
+
server.tool("gsd_journal_query", "Query the structured event journal for auto-mode iterations.", journalQueryParams, async (args) => {
|
|
827
|
+
const { projectDir, limit, ...filters } = parseWorkflowArgs(journalQuerySchema, args);
|
|
828
|
+
const { queryJournal } = await importLocalModule("../../../src/resources/extensions/gsd/journal.js");
|
|
829
|
+
const entries = queryJournal(projectDir, filters).slice(0, limit ?? 100);
|
|
830
|
+
if (entries.length === 0) {
|
|
831
|
+
return { content: [{ type: "text", text: "No matching journal entries found." }] };
|
|
832
|
+
}
|
|
833
|
+
return { content: [{ type: "text", text: JSON.stringify(entries, null, 2) }] };
|
|
834
|
+
});
|
|
531
835
|
}
|
|
532
836
|
//# sourceMappingURL=workflow-tools.js.map
|