gsd-pi 2.41.0-dev.0acbce9 → 2.41.0-dev.5a170d0
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/README.md +1 -1
- package/dist/cli-web-branch.d.ts +6 -0
- package/dist/cli-web-branch.js +17 -0
- package/dist/onboarding.js +2 -1
- package/dist/resources/extensions/gsd/auto/loop.js +89 -1
- package/dist/resources/extensions/gsd/auto/phases.js +28 -10
- package/dist/resources/extensions/gsd/auto/session.js +6 -0
- package/dist/resources/extensions/gsd/auto-dashboard.js +8 -2
- package/dist/resources/extensions/gsd/auto-dispatch.js +19 -2
- package/dist/resources/extensions/gsd/auto-post-unit.js +7 -0
- package/dist/resources/extensions/gsd/auto-recovery.js +12 -4
- package/dist/resources/extensions/gsd/auto-start.js +8 -3
- package/dist/resources/extensions/gsd/auto-worktree.js +147 -13
- package/dist/resources/extensions/gsd/auto.js +64 -2
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +199 -164
- package/dist/resources/extensions/gsd/bootstrap/journal-tools.js +62 -0
- package/dist/resources/extensions/gsd/bootstrap/register-extension.js +2 -0
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +16 -0
- package/dist/resources/extensions/gsd/bootstrap/tool-call-loop-guard.js +7 -2
- package/dist/resources/extensions/gsd/commands/catalog.js +40 -1
- package/dist/resources/extensions/gsd/commands/handlers/core.js +1 -0
- package/dist/resources/extensions/gsd/commands/handlers/ops.js +5 -0
- package/dist/resources/extensions/gsd/commands/handlers/workflow.js +146 -0
- package/dist/resources/extensions/gsd/context-injector.js +74 -0
- package/dist/resources/extensions/gsd/context-store.js +4 -3
- package/dist/resources/extensions/gsd/custom-execution-policy.js +47 -0
- package/dist/resources/extensions/gsd/custom-verification.js +145 -0
- package/dist/resources/extensions/gsd/custom-workflow-engine.js +164 -0
- package/dist/resources/extensions/gsd/dashboard-overlay.js +1 -0
- package/dist/resources/extensions/gsd/db-writer.js +5 -2
- package/dist/resources/extensions/gsd/definition-loader.js +352 -0
- package/dist/resources/extensions/gsd/detection.js +1 -1
- package/dist/resources/extensions/gsd/dev-execution-policy.js +24 -0
- package/dist/resources/extensions/gsd/dev-workflow-engine.js +82 -0
- package/dist/resources/extensions/gsd/doctor.js +11 -1
- package/dist/resources/extensions/gsd/engine-resolver.js +40 -0
- package/dist/resources/extensions/gsd/engine-types.js +8 -0
- package/dist/resources/extensions/gsd/execution-policy.js +8 -0
- package/dist/resources/extensions/gsd/exit-command.js +12 -2
- package/dist/resources/extensions/gsd/export.js +9 -13
- package/dist/resources/extensions/gsd/extension-manifest.json +2 -2
- package/dist/resources/extensions/gsd/files.js +28 -11
- package/dist/resources/extensions/gsd/forensics.js +10 -3
- package/dist/resources/extensions/gsd/git-service.js +5 -1
- package/dist/resources/extensions/gsd/graph.js +225 -0
- package/dist/resources/extensions/gsd/gsd-db.js +25 -8
- package/dist/resources/extensions/gsd/guided-flow-queue.js +1 -1
- package/dist/resources/extensions/gsd/guided-flow.js +7 -3
- package/dist/resources/extensions/gsd/journal.js +85 -0
- package/dist/resources/extensions/gsd/md-importer.js +5 -0
- package/dist/resources/extensions/gsd/milestone-ids.js +1 -1
- package/dist/resources/extensions/gsd/native-git-bridge.js +2 -2
- package/dist/resources/extensions/gsd/post-unit-hooks.js +24 -412
- package/dist/resources/extensions/gsd/preferences-types.js +1 -0
- package/dist/resources/extensions/gsd/preferences.js +1 -0
- package/dist/resources/extensions/gsd/prompt-loader.js +34 -4
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +11 -10
- package/dist/resources/extensions/gsd/prompts/discuss-headless.md +2 -2
- package/dist/resources/extensions/gsd/prompts/discuss.md +1 -1
- package/dist/resources/extensions/gsd/prompts/queue.md +1 -1
- package/dist/resources/extensions/gsd/repo-identity.js +46 -2
- package/dist/resources/extensions/gsd/rule-registry.js +489 -0
- package/dist/resources/extensions/gsd/rule-types.js +6 -0
- package/dist/resources/extensions/gsd/run-manager.js +134 -0
- package/dist/resources/extensions/gsd/service-tier.js +138 -0
- package/dist/resources/extensions/gsd/structured-data-formatter.js +2 -1
- package/dist/resources/extensions/gsd/templates/decisions.md +2 -2
- package/dist/resources/extensions/gsd/workflow-engine.js +7 -0
- package/dist/resources/extensions/gsd/workflow-templates.js +13 -1
- package/dist/resources/extensions/gsd/worktree-manager.js +20 -6
- package/dist/resources/extensions/gsd/worktree-resolver.js +19 -2
- package/dist/resources/extensions/subagent/index.js +7 -3
- package/dist/resources/extensions/voice/index.js +4 -4
- package/dist/resources/skills/create-workflow/SKILL.md +103 -0
- package/dist/resources/skills/create-workflow/references/feature-patterns.md +128 -0
- package/dist/resources/skills/create-workflow/references/verification-policies.md +76 -0
- package/dist/resources/skills/create-workflow/references/yaml-schema-v1.md +46 -0
- package/dist/resources/skills/create-workflow/templates/blog-post-pipeline.yaml +60 -0
- package/dist/resources/skills/create-workflow/templates/code-audit.yaml +60 -0
- package/dist/resources/skills/create-workflow/templates/release-checklist.yaml +66 -0
- package/dist/resources/skills/create-workflow/templates/workflow-definition.yaml +32 -0
- package/dist/resources/skills/create-workflow/workflows/create-from-scratch.md +104 -0
- package/dist/resources/skills/create-workflow/workflows/create-from-template.md +72 -0
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +16 -16
- 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/react-loadable-manifest.json +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
- 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.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- 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 +1 -1
- 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/captures/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.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/forensics/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.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/skill-health/route.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/resize/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
- 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 +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +16 -16
- package/dist/web/standalone/.next/server/chunks/229.js +3 -3
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +2 -2
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/4024.c195dc1fdd2adbea.js +9 -0
- package/dist/web/standalone/.next/static/chunks/{webpack-9afaaebf6042a1d7.js → webpack-fa307370fcf9fb2c.js} +1 -1
- package/dist/web-mode.d.ts +2 -0
- package/dist/web-mode.js +29 -7
- package/package.json +1 -1
- package/packages/native/src/__tests__/text.test.mjs +33 -0
- package/packages/pi-coding-agent/dist/core/discovery-cache.test.js +3 -1
- package/packages/pi-coding-agent/dist/core/discovery-cache.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.js +10 -7
- package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +4 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/src/core/discovery-cache.test.ts +4 -2
- package/packages/pi-coding-agent/src/modes/interactive/components/login-dialog.ts +11 -7
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +5 -0
- package/src/resources/extensions/gsd/auto/loop-deps.ts +5 -1
- package/src/resources/extensions/gsd/auto/loop.ts +101 -1
- package/src/resources/extensions/gsd/auto/phases.ts +30 -10
- package/src/resources/extensions/gsd/auto/session.ts +6 -0
- package/src/resources/extensions/gsd/auto/types.ts +4 -0
- package/src/resources/extensions/gsd/auto-dashboard.ts +9 -2
- package/src/resources/extensions/gsd/auto-dispatch.ts +25 -5
- package/src/resources/extensions/gsd/auto-post-unit.ts +8 -0
- package/src/resources/extensions/gsd/auto-recovery.ts +12 -4
- package/src/resources/extensions/gsd/auto-start.ts +8 -3
- package/src/resources/extensions/gsd/auto-worktree.ts +162 -18
- package/src/resources/extensions/gsd/auto.ts +71 -2
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +209 -162
- package/src/resources/extensions/gsd/bootstrap/journal-tools.ts +62 -0
- package/src/resources/extensions/gsd/bootstrap/register-extension.ts +2 -0
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +13 -0
- package/src/resources/extensions/gsd/bootstrap/tool-call-loop-guard.ts +9 -2
- package/src/resources/extensions/gsd/commands/catalog.ts +40 -1
- package/src/resources/extensions/gsd/commands/handlers/core.ts +1 -0
- package/src/resources/extensions/gsd/commands/handlers/ops.ts +5 -0
- package/src/resources/extensions/gsd/commands/handlers/workflow.ts +164 -0
- package/src/resources/extensions/gsd/context-injector.ts +100 -0
- package/src/resources/extensions/gsd/context-store.ts +4 -3
- package/src/resources/extensions/gsd/custom-execution-policy.ts +73 -0
- package/src/resources/extensions/gsd/custom-verification.ts +180 -0
- package/src/resources/extensions/gsd/custom-workflow-engine.ts +216 -0
- package/src/resources/extensions/gsd/dashboard-overlay.ts +1 -0
- package/src/resources/extensions/gsd/db-writer.ts +6 -2
- package/src/resources/extensions/gsd/definition-loader.ts +462 -0
- package/src/resources/extensions/gsd/detection.ts +1 -1
- package/src/resources/extensions/gsd/dev-execution-policy.ts +51 -0
- package/src/resources/extensions/gsd/dev-workflow-engine.ts +110 -0
- package/src/resources/extensions/gsd/doctor.ts +12 -1
- package/src/resources/extensions/gsd/engine-resolver.ts +57 -0
- package/src/resources/extensions/gsd/engine-types.ts +71 -0
- package/src/resources/extensions/gsd/execution-policy.ts +43 -0
- package/src/resources/extensions/gsd/exit-command.ts +14 -2
- package/src/resources/extensions/gsd/export.ts +8 -15
- package/src/resources/extensions/gsd/extension-manifest.json +2 -2
- package/src/resources/extensions/gsd/files.ts +29 -12
- package/src/resources/extensions/gsd/forensics.ts +9 -3
- package/src/resources/extensions/gsd/git-service.ts +5 -4
- package/src/resources/extensions/gsd/graph.ts +312 -0
- package/src/resources/extensions/gsd/gsd-db.ts +37 -8
- package/src/resources/extensions/gsd/guided-flow-queue.ts +1 -1
- package/src/resources/extensions/gsd/guided-flow.ts +7 -3
- package/src/resources/extensions/gsd/journal.ts +134 -0
- package/src/resources/extensions/gsd/md-importer.ts +6 -0
- package/src/resources/extensions/gsd/milestone-ids.ts +1 -1
- package/src/resources/extensions/gsd/native-git-bridge.ts +2 -2
- package/src/resources/extensions/gsd/post-unit-hooks.ts +24 -462
- package/src/resources/extensions/gsd/preferences-types.ts +3 -0
- package/src/resources/extensions/gsd/preferences.ts +1 -0
- package/src/resources/extensions/gsd/prompt-loader.ts +35 -4
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +11 -10
- package/src/resources/extensions/gsd/prompts/discuss-headless.md +2 -2
- package/src/resources/extensions/gsd/prompts/discuss.md +1 -1
- package/src/resources/extensions/gsd/prompts/queue.md +1 -1
- package/src/resources/extensions/gsd/repo-identity.ts +47 -2
- package/src/resources/extensions/gsd/rule-registry.ts +599 -0
- package/src/resources/extensions/gsd/rule-types.ts +68 -0
- package/src/resources/extensions/gsd/run-manager.ts +180 -0
- package/src/resources/extensions/gsd/service-tier.ts +171 -0
- package/src/resources/extensions/gsd/structured-data-formatter.ts +3 -1
- package/src/resources/extensions/gsd/templates/decisions.md +2 -2
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +103 -120
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +85 -0
- package/src/resources/extensions/gsd/tests/auto-secrets-gate.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/auto-worktree-milestone-merge.test.ts +202 -0
- package/src/resources/extensions/gsd/tests/bundled-workflow-defs.test.ts +180 -0
- package/src/resources/extensions/gsd/tests/captures.test.ts +12 -1
- package/src/resources/extensions/gsd/tests/commands-workflow-custom.test.ts +283 -0
- package/src/resources/extensions/gsd/tests/context-injector.test.ts +313 -0
- package/src/resources/extensions/gsd/tests/context-store.test.ts +10 -5
- package/src/resources/extensions/gsd/tests/continue-here.test.ts +20 -20
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +540 -0
- package/src/resources/extensions/gsd/tests/custom-verification.test.ts +382 -0
- package/src/resources/extensions/gsd/tests/custom-workflow-engine.test.ts +339 -0
- package/src/resources/extensions/gsd/tests/dashboard-custom-engine.test.ts +87 -0
- package/src/resources/extensions/gsd/tests/db-writer.test.ts +10 -0
- package/src/resources/extensions/gsd/tests/definition-loader.test.ts +778 -0
- package/src/resources/extensions/gsd/tests/dev-engine-wrapper.test.ts +318 -0
- package/src/resources/extensions/gsd/tests/doctor-completion-deferral.test.ts +15 -10
- package/src/resources/extensions/gsd/tests/doctor-fixlevel.test.ts +5 -4
- package/src/resources/extensions/gsd/tests/doctor-roadmap-summary-atomicity.test.ts +167 -0
- package/src/resources/extensions/gsd/tests/doctor-task-done-missing-summary-slice-loop.test.ts +174 -0
- package/src/resources/extensions/gsd/tests/e2e-workflow-pipeline-integration.test.ts +476 -0
- package/src/resources/extensions/gsd/tests/engine-interfaces-contract.test.ts +271 -0
- package/src/resources/extensions/gsd/tests/exit-command.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/graph-operations.test.ts +599 -0
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +8 -1
- package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +7 -7
- package/src/resources/extensions/gsd/tests/iterate-engine-integration.test.ts +429 -0
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +513 -0
- package/src/resources/extensions/gsd/tests/journal-query-tool.test.ts +147 -0
- package/src/resources/extensions/gsd/tests/journal.test.ts +386 -0
- package/src/resources/extensions/gsd/tests/md-importer.test.ts +31 -1
- package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/milestone-id-reservation.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/parsers.test.ts +110 -0
- package/src/resources/extensions/gsd/tests/preferences.test.ts +47 -25
- package/src/resources/extensions/gsd/tests/prompt-db.test.ts +3 -1
- package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +61 -1
- package/src/resources/extensions/gsd/tests/routing-history.test.ts +11 -22
- package/src/resources/extensions/gsd/tests/rule-registry.test.ts +413 -0
- package/src/resources/extensions/gsd/tests/run-manager.test.ts +229 -0
- package/src/resources/extensions/gsd/tests/service-tier.test.ts +98 -0
- package/src/resources/extensions/gsd/tests/skill-lifecycle.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +102 -0
- package/src/resources/extensions/gsd/tests/structured-data-formatter.test.ts +4 -3
- package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +45 -0
- package/src/resources/extensions/gsd/tests/tool-naming.test.ts +117 -0
- package/src/resources/extensions/gsd/tests/triage-dispatch.test.ts +6 -1
- package/src/resources/extensions/gsd/tests/windows-path-normalization.test.ts +99 -0
- package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/worktree-db.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +178 -0
- package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +195 -105
- package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +78 -3
- package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +140 -0
- package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +74 -0
- package/src/resources/extensions/gsd/types.ts +3 -0
- package/src/resources/extensions/gsd/workflow-engine.ts +38 -0
- package/src/resources/extensions/gsd/workflow-templates.ts +12 -1
- package/src/resources/extensions/gsd/worktree-manager.ts +21 -6
- package/src/resources/extensions/gsd/worktree-resolver.ts +30 -9
- package/src/resources/extensions/subagent/index.ts +7 -3
- package/src/resources/extensions/voice/index.ts +4 -4
- package/src/resources/skills/create-workflow/SKILL.md +103 -0
- package/src/resources/skills/create-workflow/references/feature-patterns.md +128 -0
- package/src/resources/skills/create-workflow/references/verification-policies.md +76 -0
- package/src/resources/skills/create-workflow/references/yaml-schema-v1.md +46 -0
- package/src/resources/skills/create-workflow/templates/blog-post-pipeline.yaml +60 -0
- package/src/resources/skills/create-workflow/templates/code-audit.yaml +60 -0
- package/src/resources/skills/create-workflow/templates/release-checklist.yaml +66 -0
- package/src/resources/skills/create-workflow/templates/workflow-definition.yaml +32 -0
- package/src/resources/skills/create-workflow/workflows/create-from-scratch.md +104 -0
- package/src/resources/skills/create-workflow/workflows/create-from-template.md +72 -0
- package/dist/web/standalone/.next/static/chunks/4024.279c423e4661ece1.js +0 -9
- /package/dist/web/standalone/.next/static/{SwbKZ7JPNFlEmU4f8pKEv → K7GYOOPvQWX6TKYEKhODM}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{SwbKZ7JPNFlEmU4f8pKEv → K7GYOOPvQWX6TKYEKhODM}/_ssgManifest.js +0 -0
|
@@ -5,19 +5,71 @@ import { findMilestoneIds, nextMilestoneId, claimReservedId, getReservedMileston
|
|
|
5
5
|
import { loadEffectiveGSDPreferences } from "../preferences.js";
|
|
6
6
|
import { ensureDbOpen } from "./dynamic-tools.js";
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Register an alias tool that shares the same execute function as its canonical counterpart.
|
|
10
|
+
* The alias description and promptGuidelines direct the LLM to prefer the canonical name.
|
|
11
|
+
*/
|
|
12
|
+
function registerAlias(pi: ExtensionAPI, toolDef: any, aliasName: string, canonicalName: string): void {
|
|
9
13
|
pi.registerTool({
|
|
10
|
-
|
|
14
|
+
...toolDef,
|
|
15
|
+
name: aliasName,
|
|
16
|
+
description: toolDef.description + ` (alias for ${canonicalName} — prefer the canonical name)`,
|
|
17
|
+
promptGuidelines: [`Alias for ${canonicalName} — prefer the canonical name.`],
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function registerDbTools(pi: ExtensionAPI): void {
|
|
22
|
+
// ─── gsd_decision_save (formerly gsd_save_decision) ─────────────────────
|
|
23
|
+
|
|
24
|
+
const decisionSaveExecute = async (_toolCallId: any, params: any, _signal: any, _onUpdate: any, _ctx: any) => {
|
|
25
|
+
const dbAvailable = await ensureDbOpen();
|
|
26
|
+
if (!dbAvailable) {
|
|
27
|
+
return {
|
|
28
|
+
content: [{ type: "text" as const, text: "Error: GSD database is not available. Cannot save decision." }],
|
|
29
|
+
details: { operation: "save_decision", error: "db_unavailable" } as any,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
try {
|
|
33
|
+
const { saveDecisionToDb } = await import("../db-writer.js");
|
|
34
|
+
const { id } = await saveDecisionToDb(
|
|
35
|
+
{
|
|
36
|
+
scope: params.scope,
|
|
37
|
+
decision: params.decision,
|
|
38
|
+
choice: params.choice,
|
|
39
|
+
rationale: params.rationale,
|
|
40
|
+
revisable: params.revisable,
|
|
41
|
+
when_context: params.when_context,
|
|
42
|
+
made_by: params.made_by,
|
|
43
|
+
},
|
|
44
|
+
process.cwd(),
|
|
45
|
+
);
|
|
46
|
+
return {
|
|
47
|
+
content: [{ type: "text" as const, text: `Saved decision ${id}` }],
|
|
48
|
+
details: { operation: "save_decision", id } as any,
|
|
49
|
+
};
|
|
50
|
+
} catch (err) {
|
|
51
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
52
|
+
process.stderr.write(`gsd-db: gsd_decision_save tool failed: ${msg}\n`);
|
|
53
|
+
return {
|
|
54
|
+
content: [{ type: "text" as const, text: `Error saving decision: ${msg}` }],
|
|
55
|
+
details: { operation: "save_decision", error: msg } as any,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const decisionSaveTool = {
|
|
61
|
+
name: "gsd_decision_save",
|
|
11
62
|
label: "Save Decision",
|
|
12
63
|
description:
|
|
13
64
|
"Record a project decision to the GSD database and regenerate DECISIONS.md. " +
|
|
14
65
|
"Decision IDs are auto-assigned — never provide an ID manually.",
|
|
15
66
|
promptSnippet: "Record a project decision to the GSD database (auto-assigns ID, regenerates DECISIONS.md)",
|
|
16
67
|
promptGuidelines: [
|
|
17
|
-
"Use
|
|
68
|
+
"Use gsd_decision_save when recording an architectural, pattern, library, or observability decision.",
|
|
18
69
|
"Decision IDs are auto-assigned (D001, D002, ...) — never guess or provide an ID.",
|
|
19
|
-
"All fields except revisable and
|
|
70
|
+
"All fields except revisable, when_context, and made_by are required.",
|
|
20
71
|
"The tool writes to the DB and regenerates .gsd/DECISIONS.md automatically.",
|
|
72
|
+
"Set made_by to 'human' when the user explicitly directed the decision, 'agent' when the LLM chose autonomously (default), or 'collaborative' when it was discussed and agreed together.",
|
|
21
73
|
],
|
|
22
74
|
parameters: Type.Object({
|
|
23
75
|
scope: Type.String({ description: "Scope of the decision (e.g. 'architecture', 'library', 'observability')" }),
|
|
@@ -26,52 +78,69 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|
|
26
78
|
rationale: Type.String({ description: "Why this choice was made" }),
|
|
27
79
|
revisable: Type.Optional(Type.String({ description: "Whether this can be revisited (default: 'Yes')" })),
|
|
28
80
|
when_context: Type.Optional(Type.String({ description: "When/context for the decision (e.g. milestone ID)" })),
|
|
81
|
+
made_by: Type.Optional(Type.Union([
|
|
82
|
+
Type.Literal("human"),
|
|
83
|
+
Type.Literal("agent"),
|
|
84
|
+
Type.Literal("collaborative"),
|
|
85
|
+
], { description: "Who made this decision: 'human' (user directed), 'agent' (LLM decided autonomously), or 'collaborative' (discussed and agreed). Default: 'agent'" })),
|
|
29
86
|
}),
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
);
|
|
51
|
-
return {
|
|
52
|
-
content: [{ type: "text" as const, text: `Saved decision ${id}` }],
|
|
53
|
-
details: { operation: "save_decision", id } as any,
|
|
54
|
-
};
|
|
55
|
-
} catch (err) {
|
|
56
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
57
|
-
process.stderr.write(`gsd-db: gsd_save_decision tool failed: ${msg}\n`);
|
|
87
|
+
execute: decisionSaveExecute,
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
pi.registerTool(decisionSaveTool);
|
|
91
|
+
registerAlias(pi, decisionSaveTool, "gsd_save_decision", "gsd_decision_save");
|
|
92
|
+
|
|
93
|
+
// ─── gsd_requirement_update (formerly gsd_update_requirement) ───────────
|
|
94
|
+
|
|
95
|
+
const requirementUpdateExecute = async (_toolCallId: any, params: any, _signal: any, _onUpdate: any, _ctx: any) => {
|
|
96
|
+
const dbAvailable = await ensureDbOpen();
|
|
97
|
+
if (!dbAvailable) {
|
|
98
|
+
return {
|
|
99
|
+
content: [{ type: "text" as const, text: "Error: GSD database is not available. Cannot update requirement." }],
|
|
100
|
+
details: { operation: "update_requirement", id: params.id, error: "db_unavailable" } as any,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
try {
|
|
104
|
+
const db = await import("../gsd-db.js");
|
|
105
|
+
const existing = db.getRequirementById(params.id);
|
|
106
|
+
if (!existing) {
|
|
58
107
|
return {
|
|
59
|
-
content: [{ type: "text" as const, text: `Error
|
|
60
|
-
details: { operation: "
|
|
108
|
+
content: [{ type: "text" as const, text: `Error: Requirement ${params.id} not found.` }],
|
|
109
|
+
details: { operation: "update_requirement", id: params.id, error: "not_found" } as any,
|
|
61
110
|
};
|
|
62
111
|
}
|
|
63
|
-
|
|
64
|
-
|
|
112
|
+
const { updateRequirementInDb } = await import("../db-writer.js");
|
|
113
|
+
const updates: Record<string, string | undefined> = {};
|
|
114
|
+
if (params.status !== undefined) updates.status = params.status;
|
|
115
|
+
if (params.validation !== undefined) updates.validation = params.validation;
|
|
116
|
+
if (params.notes !== undefined) updates.notes = params.notes;
|
|
117
|
+
if (params.description !== undefined) updates.description = params.description;
|
|
118
|
+
if (params.primary_owner !== undefined) updates.primary_owner = params.primary_owner;
|
|
119
|
+
if (params.supporting_slices !== undefined) updates.supporting_slices = params.supporting_slices;
|
|
120
|
+
await updateRequirementInDb(params.id, updates, process.cwd());
|
|
121
|
+
return {
|
|
122
|
+
content: [{ type: "text" as const, text: `Updated requirement ${params.id}` }],
|
|
123
|
+
details: { operation: "update_requirement", id: params.id } as any,
|
|
124
|
+
};
|
|
125
|
+
} catch (err) {
|
|
126
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
127
|
+
process.stderr.write(`gsd-db: gsd_requirement_update tool failed: ${msg}\n`);
|
|
128
|
+
return {
|
|
129
|
+
content: [{ type: "text" as const, text: `Error updating requirement: ${msg}` }],
|
|
130
|
+
details: { operation: "update_requirement", id: params.id, error: msg } as any,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
};
|
|
65
134
|
|
|
66
|
-
|
|
67
|
-
name: "
|
|
135
|
+
const requirementUpdateTool = {
|
|
136
|
+
name: "gsd_requirement_update",
|
|
68
137
|
label: "Update Requirement",
|
|
69
138
|
description:
|
|
70
139
|
"Update an existing requirement in the GSD database and regenerate REQUIREMENTS.md. " +
|
|
71
140
|
"Provide the requirement ID (e.g. R001) and any fields to update.",
|
|
72
141
|
promptSnippet: "Update an existing GSD requirement by ID (regenerates REQUIREMENTS.md)",
|
|
73
142
|
promptGuidelines: [
|
|
74
|
-
"Use
|
|
143
|
+
"Use gsd_requirement_update to change status, validation, notes, or other fields on an existing requirement.",
|
|
75
144
|
"The id parameter is required — it must be an existing RXXX identifier.",
|
|
76
145
|
"All other fields are optional — only provided fields are updated.",
|
|
77
146
|
"The tool verifies the requirement exists before updating.",
|
|
@@ -85,56 +154,73 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|
|
85
154
|
primary_owner: Type.Optional(Type.String({ description: "Primary owning slice" })),
|
|
86
155
|
supporting_slices: Type.Optional(Type.String({ description: "Supporting slices" })),
|
|
87
156
|
}),
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
120
|
-
process.stderr.write(`gsd-db: gsd_update_requirement tool failed: ${msg}\n`);
|
|
121
|
-
return {
|
|
122
|
-
content: [{ type: "text" as const, text: `Error updating requirement: ${msg}` }],
|
|
123
|
-
details: { operation: "update_requirement", id: params.id, error: msg } as any,
|
|
124
|
-
};
|
|
157
|
+
execute: requirementUpdateExecute,
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
pi.registerTool(requirementUpdateTool);
|
|
161
|
+
registerAlias(pi, requirementUpdateTool, "gsd_update_requirement", "gsd_requirement_update");
|
|
162
|
+
|
|
163
|
+
// ─── gsd_summary_save (formerly gsd_save_summary) ──────────────────────
|
|
164
|
+
|
|
165
|
+
const summarySaveExecute = async (_toolCallId: any, params: any, _signal: any, _onUpdate: any, _ctx: any) => {
|
|
166
|
+
const dbAvailable = await ensureDbOpen();
|
|
167
|
+
if (!dbAvailable) {
|
|
168
|
+
return {
|
|
169
|
+
content: [{ type: "text" as const, text: "Error: GSD database is not available. Cannot save artifact." }],
|
|
170
|
+
details: { operation: "save_summary", error: "db_unavailable" } as any,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
const validTypes = ["SUMMARY", "RESEARCH", "CONTEXT", "ASSESSMENT"];
|
|
174
|
+
if (!validTypes.includes(params.artifact_type)) {
|
|
175
|
+
return {
|
|
176
|
+
content: [{ type: "text" as const, text: `Error: Invalid artifact_type "${params.artifact_type}". Must be one of: ${validTypes.join(", ")}` }],
|
|
177
|
+
details: { operation: "save_summary", error: "invalid_artifact_type" } as any,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
try {
|
|
181
|
+
let relativePath: string;
|
|
182
|
+
if (params.task_id && params.slice_id) {
|
|
183
|
+
relativePath = `milestones/${params.milestone_id}/slices/${params.slice_id}/tasks/${params.task_id}-${params.artifact_type}.md`;
|
|
184
|
+
} else if (params.slice_id) {
|
|
185
|
+
relativePath = `milestones/${params.milestone_id}/slices/${params.slice_id}/${params.slice_id}-${params.artifact_type}.md`;
|
|
186
|
+
} else {
|
|
187
|
+
relativePath = `milestones/${params.milestone_id}/${params.milestone_id}-${params.artifact_type}.md`;
|
|
125
188
|
}
|
|
126
|
-
|
|
127
|
-
|
|
189
|
+
const { saveArtifactToDb } = await import("../db-writer.js");
|
|
190
|
+
await saveArtifactToDb(
|
|
191
|
+
{
|
|
192
|
+
path: relativePath,
|
|
193
|
+
artifact_type: params.artifact_type,
|
|
194
|
+
content: params.content,
|
|
195
|
+
milestone_id: params.milestone_id,
|
|
196
|
+
slice_id: params.slice_id,
|
|
197
|
+
task_id: params.task_id,
|
|
198
|
+
},
|
|
199
|
+
process.cwd(),
|
|
200
|
+
);
|
|
201
|
+
return {
|
|
202
|
+
content: [{ type: "text" as const, text: `Saved ${params.artifact_type} artifact to ${relativePath}` }],
|
|
203
|
+
details: { operation: "save_summary", path: relativePath, artifact_type: params.artifact_type } as any,
|
|
204
|
+
};
|
|
205
|
+
} catch (err) {
|
|
206
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
207
|
+
process.stderr.write(`gsd-db: gsd_summary_save tool failed: ${msg}\n`);
|
|
208
|
+
return {
|
|
209
|
+
content: [{ type: "text" as const, text: `Error saving artifact: ${msg}` }],
|
|
210
|
+
details: { operation: "save_summary", error: msg } as any,
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
};
|
|
128
214
|
|
|
129
|
-
|
|
130
|
-
name: "
|
|
215
|
+
const summarySaveTool = {
|
|
216
|
+
name: "gsd_summary_save",
|
|
131
217
|
label: "Save Summary",
|
|
132
218
|
description:
|
|
133
219
|
"Save a summary, research, context, or assessment artifact to the GSD database and write it to disk. " +
|
|
134
220
|
"Computes the file path from milestone/slice/task IDs automatically.",
|
|
135
221
|
promptSnippet: "Save a GSD artifact (summary/research/context/assessment) to DB and disk",
|
|
136
222
|
promptGuidelines: [
|
|
137
|
-
"Use
|
|
223
|
+
"Use gsd_summary_save to persist structured artifacts (SUMMARY, RESEARCH, CONTEXT, ASSESSMENT).",
|
|
138
224
|
"milestone_id is required. slice_id and task_id are optional — they determine the file path.",
|
|
139
225
|
"The tool computes the relative path automatically: milestones/M001/M001-SUMMARY.md, milestones/M001/slices/S01/S01-SUMMARY.md, etc.",
|
|
140
226
|
"artifact_type must be one of: SUMMARY, RESEARCH, CONTEXT, ASSESSMENT.",
|
|
@@ -146,59 +232,46 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|
|
146
232
|
artifact_type: Type.String({ description: "One of: SUMMARY, RESEARCH, CONTEXT, ASSESSMENT" }),
|
|
147
233
|
content: Type.String({ description: "The full markdown content of the artifact" }),
|
|
148
234
|
}),
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
}
|
|
164
|
-
try {
|
|
165
|
-
let relativePath: string;
|
|
166
|
-
if (params.task_id && params.slice_id) {
|
|
167
|
-
relativePath = `milestones/${params.milestone_id}/slices/${params.slice_id}/tasks/${params.task_id}-${params.artifact_type}.md`;
|
|
168
|
-
} else if (params.slice_id) {
|
|
169
|
-
relativePath = `milestones/${params.milestone_id}/slices/${params.slice_id}/${params.slice_id}-${params.artifact_type}.md`;
|
|
170
|
-
} else {
|
|
171
|
-
relativePath = `milestones/${params.milestone_id}/${params.milestone_id}-${params.artifact_type}.md`;
|
|
172
|
-
}
|
|
173
|
-
const { saveArtifactToDb } = await import("../db-writer.js");
|
|
174
|
-
await saveArtifactToDb(
|
|
175
|
-
{
|
|
176
|
-
path: relativePath,
|
|
177
|
-
artifact_type: params.artifact_type,
|
|
178
|
-
content: params.content,
|
|
179
|
-
milestone_id: params.milestone_id,
|
|
180
|
-
slice_id: params.slice_id,
|
|
181
|
-
task_id: params.task_id,
|
|
182
|
-
},
|
|
183
|
-
process.cwd(),
|
|
184
|
-
);
|
|
185
|
-
return {
|
|
186
|
-
content: [{ type: "text" as const, text: `Saved ${params.artifact_type} artifact to ${relativePath}` }],
|
|
187
|
-
details: { operation: "save_summary", path: relativePath, artifact_type: params.artifact_type } as any,
|
|
188
|
-
};
|
|
189
|
-
} catch (err) {
|
|
190
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
191
|
-
process.stderr.write(`gsd-db: gsd_save_summary tool failed: ${msg}\n`);
|
|
235
|
+
execute: summarySaveExecute,
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
pi.registerTool(summarySaveTool);
|
|
239
|
+
registerAlias(pi, summarySaveTool, "gsd_save_summary", "gsd_summary_save");
|
|
240
|
+
|
|
241
|
+
// ─── gsd_milestone_generate_id (formerly gsd_generate_milestone_id) ────
|
|
242
|
+
|
|
243
|
+
const milestoneGenerateIdExecute = async (_toolCallId: any, _params: any, _signal: any, _onUpdate: any, _ctx: any) => {
|
|
244
|
+
try {
|
|
245
|
+
// Claim a reserved ID if the guided-flow already previewed one to the user.
|
|
246
|
+
// This guarantees the ID shown in the UI matches the one materialised on disk.
|
|
247
|
+
const reserved = claimReservedId();
|
|
248
|
+
if (reserved) {
|
|
192
249
|
return {
|
|
193
|
-
content: [{ type: "text" as const, text:
|
|
194
|
-
details: { operation: "
|
|
250
|
+
content: [{ type: "text" as const, text: reserved }],
|
|
251
|
+
details: { operation: "generate_milestone_id", id: reserved, source: "reserved" } as any,
|
|
195
252
|
};
|
|
196
253
|
}
|
|
197
|
-
},
|
|
198
|
-
});
|
|
199
254
|
|
|
200
|
-
|
|
201
|
-
|
|
255
|
+
const basePath = process.cwd();
|
|
256
|
+
const existingIds = findMilestoneIds(basePath);
|
|
257
|
+
const uniqueEnabled = !!loadEffectiveGSDPreferences()?.preferences?.unique_milestone_ids;
|
|
258
|
+
const allIds = [...new Set([...existingIds, ...getReservedMilestoneIds()])];
|
|
259
|
+
const newId = nextMilestoneId(allIds, uniqueEnabled);
|
|
260
|
+
return {
|
|
261
|
+
content: [{ type: "text" as const, text: newId }],
|
|
262
|
+
details: { operation: "generate_milestone_id", id: newId, existingCount: existingIds.length, uniqueEnabled } as any,
|
|
263
|
+
};
|
|
264
|
+
} catch (err) {
|
|
265
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
266
|
+
return {
|
|
267
|
+
content: [{ type: "text" as const, text: `Error generating milestone ID: ${msg}` }],
|
|
268
|
+
details: { operation: "generate_milestone_id", error: msg } as any,
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
};
|
|
272
|
+
|
|
273
|
+
const milestoneGenerateIdTool = {
|
|
274
|
+
name: "gsd_milestone_generate_id",
|
|
202
275
|
label: "Generate Milestone ID",
|
|
203
276
|
description:
|
|
204
277
|
"Generate the next milestone ID for a new GSD milestone. " +
|
|
@@ -206,41 +279,15 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|
|
206
279
|
"Always use this tool when creating a new milestone — never invent milestone IDs manually.",
|
|
207
280
|
promptSnippet: "Generate a valid milestone ID (respects unique_milestone_ids preference)",
|
|
208
281
|
promptGuidelines: [
|
|
209
|
-
"ALWAYS call
|
|
282
|
+
"ALWAYS call gsd_milestone_generate_id before creating a new milestone directory or writing milestone files.",
|
|
210
283
|
"Never invent or hardcode milestone IDs like M001, M002 — always use this tool.",
|
|
211
284
|
"Call it once per milestone you need to create. For multi-milestone projects, call it once for each milestone in sequence.",
|
|
212
285
|
"The tool returns the correct format based on project preferences (e.g. M001 or M001-r5jzab).",
|
|
213
286
|
],
|
|
214
287
|
parameters: Type.Object({}),
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
// Claim a reserved ID if the guided-flow already previewed one to the user.
|
|
218
|
-
// This guarantees the ID shown in the UI matches the one materialised on disk.
|
|
219
|
-
const reserved = claimReservedId();
|
|
220
|
-
if (reserved) {
|
|
221
|
-
return {
|
|
222
|
-
content: [{ type: "text" as const, text: reserved }],
|
|
223
|
-
details: { operation: "generate_milestone_id", id: reserved, source: "reserved" } as any,
|
|
224
|
-
};
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
const basePath = process.cwd();
|
|
228
|
-
const existingIds = findMilestoneIds(basePath);
|
|
229
|
-
const uniqueEnabled = !!loadEffectiveGSDPreferences()?.preferences?.unique_milestone_ids;
|
|
230
|
-
const allIds = [...new Set([...existingIds, ...getReservedMilestoneIds()])];
|
|
231
|
-
const newId = nextMilestoneId(allIds, uniqueEnabled);
|
|
232
|
-
return {
|
|
233
|
-
content: [{ type: "text" as const, text: newId }],
|
|
234
|
-
details: { operation: "generate_milestone_id", id: newId, existingCount: existingIds.length, uniqueEnabled } as any,
|
|
235
|
-
};
|
|
236
|
-
} catch (err) {
|
|
237
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
238
|
-
return {
|
|
239
|
-
content: [{ type: "text" as const, text: `Error generating milestone ID: ${msg}` }],
|
|
240
|
-
details: { operation: "generate_milestone_id", error: msg } as any,
|
|
241
|
-
};
|
|
242
|
-
}
|
|
243
|
-
},
|
|
244
|
-
});
|
|
245
|
-
}
|
|
288
|
+
execute: milestoneGenerateIdExecute,
|
|
289
|
+
};
|
|
246
290
|
|
|
291
|
+
pi.registerTool(milestoneGenerateIdTool);
|
|
292
|
+
registerAlias(pi, milestoneGenerateIdTool, "gsd_generate_milestone_id", "gsd_milestone_generate_id");
|
|
293
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { Type } from "@sinclair/typebox";
|
|
2
|
+
import type { ExtensionAPI } from "@gsd/pi-coding-agent";
|
|
3
|
+
|
|
4
|
+
import { queryJournal } from "../journal.js";
|
|
5
|
+
|
|
6
|
+
export function registerJournalTools(pi: ExtensionAPI): void {
|
|
7
|
+
pi.registerTool({
|
|
8
|
+
name: "gsd_journal_query",
|
|
9
|
+
label: "Query Journal",
|
|
10
|
+
description:
|
|
11
|
+
"Query the structured event journal for auto-mode iterations. " +
|
|
12
|
+
"Returns matching journal entries filtered by flow ID, unit ID, rule name, event type, or time range.",
|
|
13
|
+
promptSnippet: "Query the GSD event journal with filters (flowId, unitId, rule, eventType, time range, limit)",
|
|
14
|
+
promptGuidelines: [
|
|
15
|
+
"Filter by flowId to trace all events from a single auto-mode iteration.",
|
|
16
|
+
"Filter by unitId to reconstruct the causal chain for a specific milestone/slice/task.",
|
|
17
|
+
"Use limit to control context size — default is 100 entries.",
|
|
18
|
+
],
|
|
19
|
+
parameters: Type.Object({
|
|
20
|
+
flowId: Type.Optional(Type.String({ description: "Filter by flow ID (UUID grouping one iteration)" })),
|
|
21
|
+
unitId: Type.Optional(Type.String({ description: "Filter by unit ID (e.g. M001/S01/T01) from event data" })),
|
|
22
|
+
rule: Type.Optional(Type.String({ description: "Filter by rule name from the unified registry" })),
|
|
23
|
+
eventType: Type.Optional(Type.String({ description: "Filter by event type (e.g. dispatch-match, unit-start)" })),
|
|
24
|
+
after: Type.Optional(Type.String({ description: "ISO-8601 lower bound (inclusive)" })),
|
|
25
|
+
before: Type.Optional(Type.String({ description: "ISO-8601 upper bound (inclusive)" })),
|
|
26
|
+
limit: Type.Optional(Type.Number({ description: "Maximum entries to return (default: 100)", default: 100 })),
|
|
27
|
+
}),
|
|
28
|
+
async execute(_toolCallId, params, _signal, _onUpdate, _ctx) {
|
|
29
|
+
try {
|
|
30
|
+
const filters: Record<string, string | undefined> = {};
|
|
31
|
+
if (params.flowId !== undefined) filters.flowId = params.flowId;
|
|
32
|
+
if (params.unitId !== undefined) filters.unitId = params.unitId;
|
|
33
|
+
if (params.rule !== undefined) filters.rule = params.rule;
|
|
34
|
+
if (params.eventType !== undefined) filters.eventType = params.eventType;
|
|
35
|
+
if (params.after !== undefined) filters.after = params.after;
|
|
36
|
+
if (params.before !== undefined) filters.before = params.before;
|
|
37
|
+
|
|
38
|
+
const entries = queryJournal(process.cwd(), filters);
|
|
39
|
+
const limited = entries.slice(0, params.limit ?? 100);
|
|
40
|
+
|
|
41
|
+
if (limited.length === 0) {
|
|
42
|
+
return {
|
|
43
|
+
content: [{ type: "text" as const, text: "No matching journal entries found." }],
|
|
44
|
+
details: { operation: "journal_query", count: 0 } as any,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return {
|
|
49
|
+
content: [{ type: "text" as const, text: JSON.stringify(limited, null, 2) }],
|
|
50
|
+
details: { operation: "journal_query", count: limited.length } as any,
|
|
51
|
+
};
|
|
52
|
+
} catch (err) {
|
|
53
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
54
|
+
process.stderr.write(`gsd-journal: gsd_journal_query tool failed: ${msg}\n`);
|
|
55
|
+
return {
|
|
56
|
+
content: [{ type: "text" as const, text: `Error querying journal: ${msg}` }],
|
|
57
|
+
details: { operation: "journal_query", error: msg } as any,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
}
|
|
@@ -5,6 +5,7 @@ import { registerExitCommand } from "../exit-command.js";
|
|
|
5
5
|
import { registerWorktreeCommand } from "../worktree-command.js";
|
|
6
6
|
import { registerDbTools } from "./db-tools.js";
|
|
7
7
|
import { registerDynamicTools } from "./dynamic-tools.js";
|
|
8
|
+
import { registerJournalTools } from "./journal-tools.js";
|
|
8
9
|
import { registerHooks } from "./register-hooks.js";
|
|
9
10
|
import { registerShortcuts } from "./register-shortcuts.js";
|
|
10
11
|
|
|
@@ -40,6 +41,7 @@ export function registerGsdExtension(pi: ExtensionAPI): void {
|
|
|
40
41
|
|
|
41
42
|
registerDynamicTools(pi);
|
|
42
43
|
registerDbTools(pi);
|
|
44
|
+
registerJournalTools(pi);
|
|
43
45
|
registerShortcuts(pi);
|
|
44
46
|
registerHooks(pi);
|
|
45
47
|
}
|
|
@@ -191,5 +191,18 @@ export function registerHooks(pi: ExtensionAPI): void {
|
|
|
191
191
|
pi.on("tool_execution_end", async (event) => {
|
|
192
192
|
markToolEnd(event.toolCallId);
|
|
193
193
|
});
|
|
194
|
+
|
|
195
|
+
pi.on("before_provider_request", async (event) => {
|
|
196
|
+
if (!isAutoActive()) return;
|
|
197
|
+
const modelId = event.model?.id;
|
|
198
|
+
if (!modelId) return;
|
|
199
|
+
const { getEffectiveServiceTier, supportsServiceTier } = await import("../service-tier.js");
|
|
200
|
+
const tier = getEffectiveServiceTier();
|
|
201
|
+
if (!tier || !supportsServiceTier(modelId)) return;
|
|
202
|
+
const payload = event.payload as Record<string, unknown> | null;
|
|
203
|
+
if (!payload || typeof payload !== "object") return;
|
|
204
|
+
payload.service_tier = tier;
|
|
205
|
+
return payload;
|
|
206
|
+
});
|
|
194
207
|
}
|
|
195
208
|
|
|
@@ -24,8 +24,15 @@ let enabled = true;
|
|
|
24
24
|
function hashToolCall(toolName: string, args: Record<string, unknown>): string {
|
|
25
25
|
const h = createHash("sha256");
|
|
26
26
|
h.update(toolName);
|
|
27
|
-
// Sort keys for deterministic hashing regardless of object key order
|
|
28
|
-
h.update(JSON.stringify(args,
|
|
27
|
+
// Sort keys recursively for deterministic hashing regardless of object key order
|
|
28
|
+
h.update(JSON.stringify(args, (_key, value) =>
|
|
29
|
+
value && typeof value === "object" && !Array.isArray(value)
|
|
30
|
+
? Object.keys(value).sort().reduce<Record<string, unknown>>((o, k) => {
|
|
31
|
+
o[k] = value[k];
|
|
32
|
+
return o;
|
|
33
|
+
}, {})
|
|
34
|
+
: value
|
|
35
|
+
));
|
|
29
36
|
return h.digest("hex").slice(0, 16);
|
|
30
37
|
}
|
|
31
38
|
|
|
@@ -3,6 +3,7 @@ import { homedir } from "node:os";
|
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
|
|
5
5
|
import { loadRegistry } from "../workflow-templates.js";
|
|
6
|
+
import { resolveProjectRoot } from "../worktree.js";
|
|
6
7
|
|
|
7
8
|
const gsdHome = process.env.GSD_HOME || join(homedir(), ".gsd");
|
|
8
9
|
|
|
@@ -14,7 +15,7 @@ export interface GsdCommandDefinition {
|
|
|
14
15
|
type CompletionMap = Record<string, readonly GsdCommandDefinition[]>;
|
|
15
16
|
|
|
16
17
|
export const GSD_COMMAND_DESCRIPTION =
|
|
17
|
-
"GSD — Get Shit Done: /gsd help|start|templates|next|auto|stop|pause|status|widget|visualize|queue|quick|discuss|capture|triage|dispatch|history|undo|rate|skip|export|cleanup|mode|prefs|config|keys|hooks|run-hook|skill-health|doctor|logs|forensics|changelog|migrate|remote|steer|knowledge|new-milestone|parallel|cmux|park|unpark|init|setup|inspect|extensions|update";
|
|
18
|
+
"GSD — Get Shit Done: /gsd help|start|templates|next|auto|stop|pause|status|widget|visualize|queue|quick|discuss|capture|triage|dispatch|history|undo|rate|skip|export|cleanup|mode|prefs|config|keys|hooks|run-hook|skill-health|doctor|logs|forensics|changelog|migrate|remote|steer|knowledge|new-milestone|parallel|cmux|park|unpark|init|setup|inspect|extensions|update|fast";
|
|
18
19
|
|
|
19
20
|
export const TOP_LEVEL_SUBCOMMANDS: readonly GsdCommandDefinition[] = [
|
|
20
21
|
{ cmd: "help", desc: "Categorized command reference with descriptions" },
|
|
@@ -64,6 +65,8 @@ export const TOP_LEVEL_SUBCOMMANDS: readonly GsdCommandDefinition[] = [
|
|
|
64
65
|
{ cmd: "start", desc: "Start a workflow template (bugfix, spike, feature, etc.)" },
|
|
65
66
|
{ cmd: "templates", desc: "List available workflow templates" },
|
|
66
67
|
{ cmd: "extensions", desc: "Manage extensions (list, enable, disable, info)" },
|
|
68
|
+
{ cmd: "fast", desc: "Toggle OpenAI service tier (on/off/flex/status)" },
|
|
69
|
+
{ cmd: "workflow", desc: "Custom workflow lifecycle (new, run, list, validate, pause, resume)" },
|
|
67
70
|
];
|
|
68
71
|
|
|
69
72
|
const NESTED_COMPLETIONS: CompletionMap = {
|
|
@@ -176,6 +179,12 @@ const NESTED_COMPLETIONS: CompletionMap = {
|
|
|
176
179
|
{ cmd: "disable", desc: "Disable an extension" },
|
|
177
180
|
{ cmd: "info", desc: "Show extension details" },
|
|
178
181
|
],
|
|
182
|
+
fast: [
|
|
183
|
+
{ cmd: "on", desc: "Priority tier (2x cost, faster)" },
|
|
184
|
+
{ cmd: "off", desc: "Disable service tier" },
|
|
185
|
+
{ cmd: "flex", desc: "Flex tier (0.5x cost, slower)" },
|
|
186
|
+
{ cmd: "status", desc: "Show current service tier setting" },
|
|
187
|
+
],
|
|
179
188
|
doctor: [
|
|
180
189
|
{ cmd: "fix", desc: "Auto-fix detected issues" },
|
|
181
190
|
{ cmd: "heal", desc: "AI-driven deep healing" },
|
|
@@ -199,6 +208,14 @@ const NESTED_COMPLETIONS: CompletionMap = {
|
|
|
199
208
|
{ cmd: "ok", desc: "Model was appropriate for this task" },
|
|
200
209
|
{ cmd: "under", desc: "Model was underqualified for this task" },
|
|
201
210
|
],
|
|
211
|
+
workflow: [
|
|
212
|
+
{ cmd: "new", desc: "Create a new workflow definition (via skill)" },
|
|
213
|
+
{ cmd: "run", desc: "Create a run and start auto-mode" },
|
|
214
|
+
{ cmd: "list", desc: "List workflow runs" },
|
|
215
|
+
{ cmd: "validate", desc: "Validate a workflow definition YAML" },
|
|
216
|
+
{ cmd: "pause", desc: "Pause custom workflow auto-mode" },
|
|
217
|
+
{ cmd: "resume", desc: "Resume paused custom workflow auto-mode" },
|
|
218
|
+
],
|
|
202
219
|
};
|
|
203
220
|
|
|
204
221
|
function filterOptions(
|
|
@@ -302,6 +319,28 @@ export function getGsdArgumentCompletions(prefix: string) {
|
|
|
302
319
|
return [{ value: "undo --force", label: "--force", description: "Skip confirmation prompt" }];
|
|
303
320
|
}
|
|
304
321
|
|
|
322
|
+
// Workflow definition-name completion for `workflow run <name>` and `workflow validate <name>`
|
|
323
|
+
if (command === "workflow" && (subcommand === "run" || subcommand === "validate") && parts.length <= 3) {
|
|
324
|
+
try {
|
|
325
|
+
const defsDir = join(resolveProjectRoot(process.cwd()), ".gsd", "workflow-defs");
|
|
326
|
+
if (existsSync(defsDir)) {
|
|
327
|
+
return readdirSync(defsDir)
|
|
328
|
+
.filter((f) => f.endsWith(".yaml") && f.startsWith(third))
|
|
329
|
+
.map((f) => {
|
|
330
|
+
const name = f.replace(/\.yaml$/, "");
|
|
331
|
+
return {
|
|
332
|
+
value: `workflow ${subcommand} ${name}`,
|
|
333
|
+
label: name,
|
|
334
|
+
description: `Workflow definition: ${name}`,
|
|
335
|
+
};
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
} catch {
|
|
339
|
+
// ignore filesystem errors during completion
|
|
340
|
+
}
|
|
341
|
+
return [];
|
|
342
|
+
}
|
|
343
|
+
|
|
305
344
|
const nested = NESTED_COMPLETIONS[command];
|
|
306
345
|
if (nested && parts.length <= 2) {
|
|
307
346
|
return filterOptions(subcommand, nested, command);
|
|
@@ -52,6 +52,7 @@ export function showHelp(ctx: ExtensionCommandContext): void {
|
|
|
52
52
|
" /gsd keys API key manager [list|add|remove|test|rotate|doctor]",
|
|
53
53
|
" /gsd hooks Show post-unit hook configuration",
|
|
54
54
|
" /gsd extensions Manage extensions [list|enable|disable|info]",
|
|
55
|
+
" /gsd fast Toggle OpenAI service tier [on|off|flex|status]",
|
|
55
56
|
"",
|
|
56
57
|
"MAINTENANCE",
|
|
57
58
|
" /gsd doctor Diagnose and repair .gsd/ state [audit|fix|heal] [scope]",
|