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
|
@@ -249,19 +249,41 @@ test("all wizard fields together produce no errors", () => {
|
|
|
249
249
|
|
|
250
250
|
// ── Hook config ──────────────────────────────────────────────────────────────
|
|
251
251
|
|
|
252
|
-
test("post-unit hook max_cycles clamping", () => {
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
assert.equal(
|
|
252
|
+
test("post-unit hook max_cycles clamping via validatePreferences", () => {
|
|
253
|
+
const base = { name: "h", after: ["execute-task"], prompt: "do something" };
|
|
254
|
+
|
|
255
|
+
const { preferences: p1 } = validatePreferences({ post_unit_hooks: [{ ...base, max_cycles: 15 }] } as any);
|
|
256
|
+
assert.equal(p1.post_unit_hooks![0].max_cycles, 10, "clamps to 10");
|
|
257
|
+
|
|
258
|
+
const { preferences: p2 } = validatePreferences({ post_unit_hooks: [{ ...base, max_cycles: 0 }] } as any);
|
|
259
|
+
assert.equal(p2.post_unit_hooks![0].max_cycles, 1, "clamps to 1");
|
|
260
|
+
|
|
261
|
+
const { preferences: p3 } = validatePreferences({ post_unit_hooks: [{ ...base, max_cycles: -5 }] } as any);
|
|
262
|
+
assert.equal(p3.post_unit_hooks![0].max_cycles, 1, "negative clamps to 1");
|
|
263
|
+
|
|
264
|
+
const { preferences: p4 } = validatePreferences({ post_unit_hooks: [{ ...base, max_cycles: 3 }] } as any);
|
|
265
|
+
assert.equal(p4.post_unit_hooks![0].max_cycles, 3, "valid value passes through");
|
|
257
266
|
});
|
|
258
267
|
|
|
259
|
-
test("pre-dispatch hook action validation", () => {
|
|
260
|
-
const
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
268
|
+
test("pre-dispatch hook action validation via validatePreferences", () => {
|
|
269
|
+
const base = { name: "h", before: ["execute-task"] };
|
|
270
|
+
|
|
271
|
+
const { preferences, errors: e1 } = validatePreferences({
|
|
272
|
+
pre_dispatch_hooks: [{ ...base, action: "skip" }],
|
|
273
|
+
} as any);
|
|
274
|
+
assert.equal(e1.length, 0);
|
|
275
|
+
assert.equal(preferences.pre_dispatch_hooks![0].action, "skip");
|
|
276
|
+
|
|
277
|
+
const { preferences: p2, errors: e2 } = validatePreferences({
|
|
278
|
+
pre_dispatch_hooks: [{ ...base, action: "modify", prepend: "note: " }],
|
|
279
|
+
} as any);
|
|
280
|
+
assert.equal(e2.length, 0);
|
|
281
|
+
assert.equal(p2.pre_dispatch_hooks![0].action, "modify");
|
|
282
|
+
|
|
283
|
+
const { errors: e3 } = validatePreferences({
|
|
284
|
+
pre_dispatch_hooks: [{ ...base, action: "delete" }],
|
|
285
|
+
} as any);
|
|
286
|
+
assert.ok(e3.some(e => e.includes("invalid action")));
|
|
265
287
|
});
|
|
266
288
|
|
|
267
289
|
// ── Model config parsing ─────────────────────────────────────────────────────
|
|
@@ -269,8 +291,8 @@ test("pre-dispatch hook action validation", () => {
|
|
|
269
291
|
test("parses OpenRouter model config with org/model IDs and fallbacks", () => {
|
|
270
292
|
const content = `---\nversion: 1\nmodels:\n research:\n model: moonshotai/kimi-k2.5\n fallbacks:\n - qwen/qwen3.5-397b-a17b\n planning:\n model: deepseek/deepseek-r1-0528\n fallbacks:\n - moonshotai/kimi-k2.5\n - deepseek/deepseek-v3.2\n execution:\n model: qwen/qwen3-coder\n fallbacks:\n - qwen/qwen3-coder-next\n---\n`;
|
|
271
293
|
const prefs = parsePreferencesMarkdown(content);
|
|
272
|
-
assert.
|
|
273
|
-
const models = prefs
|
|
294
|
+
assert.notEqual(prefs, null);
|
|
295
|
+
const models = prefs!.models as GSDModelConfigV2;
|
|
274
296
|
const research = models.research as GSDPhaseModelConfig;
|
|
275
297
|
assert.equal(research.model, "moonshotai/kimi-k2.5");
|
|
276
298
|
assert.deepEqual(research.fallbacks, ["qwen/qwen3.5-397b-a17b"]);
|
|
@@ -281,8 +303,8 @@ test("parses OpenRouter model config with org/model IDs and fallbacks", () => {
|
|
|
281
303
|
test("parses model IDs with colons (OpenRouter :free, :exacto)", () => {
|
|
282
304
|
const content = `---\nmodels:\n execution:\n model: qwen/qwen3-coder\n fallbacks:\n - qwen/qwen3-coder:free\n - qwen/qwen3-coder:exacto\n---\n`;
|
|
283
305
|
const prefs = parsePreferencesMarkdown(content);
|
|
284
|
-
assert.
|
|
285
|
-
const models = prefs
|
|
306
|
+
assert.notEqual(prefs, null);
|
|
307
|
+
const models = prefs!.models as GSDModelConfigV2;
|
|
286
308
|
const execution = models.execution as GSDPhaseModelConfig;
|
|
287
309
|
assert.deepEqual(execution.fallbacks, ["qwen/qwen3-coder:free", "qwen/qwen3-coder:exacto"]);
|
|
288
310
|
});
|
|
@@ -290,8 +312,8 @@ test("parses model IDs with colons (OpenRouter :free, :exacto)", () => {
|
|
|
290
312
|
test("parses legacy string-per-phase model config", () => {
|
|
291
313
|
const content = `---\nmodels:\n research: claude-opus-4-6\n execution: claude-sonnet-4-6\n---\n`;
|
|
292
314
|
const prefs = parsePreferencesMarkdown(content);
|
|
293
|
-
assert.
|
|
294
|
-
const models = prefs
|
|
315
|
+
assert.notEqual(prefs, null);
|
|
316
|
+
const models = prefs!.models as GSDModelConfigV2;
|
|
295
317
|
assert.equal(models.research, "claude-opus-4-6");
|
|
296
318
|
assert.equal(models.execution, "claude-sonnet-4-6");
|
|
297
319
|
});
|
|
@@ -299,8 +321,8 @@ test("parses legacy string-per-phase model config", () => {
|
|
|
299
321
|
test("strips inline YAML comments from values", () => {
|
|
300
322
|
const content = `---\nmodels:\n execution:\n model: qwen/qwen3-coder # fast\n fallbacks:\n - minimax/minimax-m2.5 # backup\n---\n`;
|
|
301
323
|
const prefs = parsePreferencesMarkdown(content);
|
|
302
|
-
assert.
|
|
303
|
-
const models = prefs
|
|
324
|
+
assert.notEqual(prefs, null);
|
|
325
|
+
const models = prefs!.models as GSDModelConfigV2;
|
|
304
326
|
const execution = models.execution as GSDPhaseModelConfig;
|
|
305
327
|
assert.equal(execution.model, "qwen/qwen3-coder");
|
|
306
328
|
assert.deepEqual(execution.fallbacks, ["minimax/minimax-m2.5"]);
|
|
@@ -309,8 +331,8 @@ test("strips inline YAML comments from values", () => {
|
|
|
309
331
|
test("handles Windows CRLF line endings", () => {
|
|
310
332
|
const content = "---\r\nmodels:\r\n execution:\r\n model: qwen/qwen3-coder\r\n---\r\n";
|
|
311
333
|
const prefs = parsePreferencesMarkdown(content);
|
|
312
|
-
assert.
|
|
313
|
-
const models = prefs
|
|
334
|
+
assert.notEqual(prefs, null);
|
|
335
|
+
const models = prefs!.models as GSDModelConfigV2;
|
|
314
336
|
const execution = models.execution as GSDPhaseModelConfig;
|
|
315
337
|
assert.equal(execution.model, "qwen/qwen3-coder");
|
|
316
338
|
});
|
|
@@ -318,8 +340,8 @@ test("handles Windows CRLF line endings", () => {
|
|
|
318
340
|
test("handles model config with explicit provider field", () => {
|
|
319
341
|
const content = `---\nmodels:\n execution:\n model: claude-opus-4-6\n provider: bedrock\n fallbacks:\n - claude-sonnet-4-6\n---\n`;
|
|
320
342
|
const prefs = parsePreferencesMarkdown(content);
|
|
321
|
-
assert.
|
|
322
|
-
const models = prefs
|
|
343
|
+
assert.notEqual(prefs, null);
|
|
344
|
+
const models = prefs!.models as GSDModelConfigV2;
|
|
323
345
|
const execution = models.execution as GSDPhaseModelConfig;
|
|
324
346
|
assert.equal(execution.model, "claude-opus-4-6");
|
|
325
347
|
assert.equal(execution.provider, "bedrock");
|
|
@@ -327,6 +349,6 @@ test("handles model config with explicit provider field", () => {
|
|
|
327
349
|
|
|
328
350
|
test("handles empty models config", () => {
|
|
329
351
|
const prefs = parsePreferencesMarkdown("---\nversion: 1\n---\n");
|
|
330
|
-
assert.
|
|
331
|
-
assert.equal(prefs
|
|
352
|
+
assert.notEqual(prefs, null);
|
|
353
|
+
assert.equal(prefs!.models, undefined);
|
|
332
354
|
});
|
|
@@ -43,6 +43,7 @@ console.log('\n=== prompt-db: scoped decisions from DB ===');
|
|
|
43
43
|
choice: `choice ${i}`,
|
|
44
44
|
rationale: `rationale ${i}`,
|
|
45
45
|
revisable: 'yes',
|
|
46
|
+
made_by: 'agent',
|
|
46
47
|
superseded_by: null,
|
|
47
48
|
});
|
|
48
49
|
}
|
|
@@ -201,6 +202,7 @@ console.log('\n=== prompt-db: scoped filtering reduces content ===');
|
|
|
201
202
|
choice: `choice ${i}`,
|
|
202
203
|
rationale: `rationale ${i} with additional context`,
|
|
203
204
|
revisable: 'yes',
|
|
205
|
+
made_by: 'agent',
|
|
204
206
|
superseded_by: null,
|
|
205
207
|
});
|
|
206
208
|
}
|
|
@@ -269,7 +271,7 @@ console.log('\n=== prompt-db: DB helpers wrapper format matches expected pattern
|
|
|
269
271
|
insertDecision({
|
|
270
272
|
id: 'D001', when_context: 'M001/S01', scope: 'architecture',
|
|
271
273
|
decision: 'use SQLite', choice: 'better-sqlite3', rationale: 'fast',
|
|
272
|
-
revisable: 'yes', superseded_by: null,
|
|
274
|
+
revisable: 'yes', made_by: 'agent', superseded_by: null,
|
|
273
275
|
});
|
|
274
276
|
|
|
275
277
|
insertRequirement({
|
|
@@ -3,7 +3,7 @@ import { join } from "node:path";
|
|
|
3
3
|
import { tmpdir } from "node:os";
|
|
4
4
|
import { execSync } from "node:child_process";
|
|
5
5
|
|
|
6
|
-
import { repoIdentity, externalGsdRoot, ensureGsdSymlink, validateProjectId, readRepoMeta } from "../repo-identity.ts";
|
|
6
|
+
import { repoIdentity, externalGsdRoot, ensureGsdSymlink, validateProjectId, readRepoMeta, isInheritedRepo } from "../repo-identity.ts";
|
|
7
7
|
import { createTestContext } from "./test-helpers.ts";
|
|
8
8
|
|
|
9
9
|
const { assertEq, assertTrue, report } = createTestContext();
|
|
@@ -118,6 +118,66 @@ async function main(): Promise<void> {
|
|
|
118
118
|
delete process.env.GSD_PROJECT_ID;
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
+
console.log("\n=== isInheritedRepo detects subdirectory of parent repo without .gsd (#1639) ===");
|
|
122
|
+
{
|
|
123
|
+
const parentRepo = realpathSync(mkdtempSync(join(tmpdir(), "gsd-inherited-parent-")));
|
|
124
|
+
run("git init -b main", parentRepo);
|
|
125
|
+
run('git config user.name "Pi Test"', parentRepo);
|
|
126
|
+
run('git config user.email "pi@example.com"', parentRepo);
|
|
127
|
+
writeFileSync(join(parentRepo, "README.md"), "# Parent\n", "utf-8");
|
|
128
|
+
run("git add README.md", parentRepo);
|
|
129
|
+
run('git commit -m "init"', parentRepo);
|
|
130
|
+
|
|
131
|
+
// Create a subdirectory — no .gsd at parent
|
|
132
|
+
const subdir = join(parentRepo, "newproject");
|
|
133
|
+
mkdirSync(subdir, { recursive: true });
|
|
134
|
+
assertTrue(isInheritedRepo(subdir), "subdirectory of parent repo without .gsd is inherited");
|
|
135
|
+
|
|
136
|
+
// After adding .gsd at parent, subdirectory is a legitimate child
|
|
137
|
+
mkdirSync(join(parentRepo, ".gsd"), { recursive: true });
|
|
138
|
+
assertTrue(!isInheritedRepo(subdir), "subdirectory of parent repo WITH .gsd is NOT inherited");
|
|
139
|
+
|
|
140
|
+
// The git root itself is never inherited
|
|
141
|
+
assertTrue(!isInheritedRepo(parentRepo), "git root is not inherited");
|
|
142
|
+
|
|
143
|
+
// A standalone repo (not a subdir) is not inherited
|
|
144
|
+
const standaloneRepo = realpathSync(mkdtempSync(join(tmpdir(), "gsd-inherited-standalone-")));
|
|
145
|
+
run("git init -b main", standaloneRepo);
|
|
146
|
+
run('git config user.name "Pi Test"', standaloneRepo);
|
|
147
|
+
run('git config user.email "pi@example.com"', standaloneRepo);
|
|
148
|
+
assertTrue(!isInheritedRepo(standaloneRepo), "standalone repo is not inherited");
|
|
149
|
+
|
|
150
|
+
rmSync(parentRepo, { recursive: true, force: true });
|
|
151
|
+
rmSync(standaloneRepo, { recursive: true, force: true });
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
console.log("\n=== subdirectory of parent repo gets unique identity after git init (#1639) ===");
|
|
155
|
+
{
|
|
156
|
+
const parentRepo = realpathSync(mkdtempSync(join(tmpdir(), "gsd-identity-parent-")));
|
|
157
|
+
run("git init -b main", parentRepo);
|
|
158
|
+
run('git config user.name "Pi Test"', parentRepo);
|
|
159
|
+
run('git config user.email "pi@example.com"', parentRepo);
|
|
160
|
+
run('git remote add origin git@github.com:example/parent-project.git', parentRepo);
|
|
161
|
+
writeFileSync(join(parentRepo, "README.md"), "# Parent\n", "utf-8");
|
|
162
|
+
run("git add README.md", parentRepo);
|
|
163
|
+
run('git commit -m "init"', parentRepo);
|
|
164
|
+
|
|
165
|
+
const subdir = join(parentRepo, "childproject");
|
|
166
|
+
mkdirSync(subdir, { recursive: true });
|
|
167
|
+
|
|
168
|
+
// Before git init, subdirectory shares parent's identity
|
|
169
|
+
const parentIdentity = repoIdentity(parentRepo);
|
|
170
|
+
const subdirIdentityBefore = repoIdentity(subdir);
|
|
171
|
+
assertEq(subdirIdentityBefore, parentIdentity, "subdirectory shares parent identity before its own git init");
|
|
172
|
+
|
|
173
|
+
// After git init, subdirectory gets its own identity
|
|
174
|
+
run("git init -b main", subdir);
|
|
175
|
+
const subdirIdentityAfter = repoIdentity(subdir);
|
|
176
|
+
assertTrue(subdirIdentityAfter !== parentIdentity, "subdirectory gets unique identity after git init");
|
|
177
|
+
|
|
178
|
+
rmSync(parentRepo, { recursive: true, force: true });
|
|
179
|
+
}
|
|
180
|
+
|
|
121
181
|
console.log("\n=== validateProjectId rejects invalid values ===");
|
|
122
182
|
for (const invalid of ["has spaces", "path/traversal", "dot..dot", "back\\slash"]) {
|
|
123
183
|
assertTrue(!validateProjectId(invalid), `validateProjectId rejects invalid value: "${invalid}"`);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import test from "node:test";
|
|
2
2
|
import assert from "node:assert/strict";
|
|
3
|
-
import { mkdirSync, rmSync
|
|
3
|
+
import { mkdirSync, rmSync } from "node:fs";
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
import { tmpdir } from "node:os";
|
|
6
6
|
|
|
@@ -37,12 +37,9 @@ test("recordOutcome tracks success and failure counts", () => {
|
|
|
37
37
|
recordOutcome("execute-task", "standard", true);
|
|
38
38
|
recordOutcome("execute-task", "standard", false);
|
|
39
39
|
|
|
40
|
-
const history = getRoutingHistory()
|
|
41
|
-
assert.
|
|
42
|
-
|
|
43
|
-
assert.ok(pattern);
|
|
44
|
-
assert.equal(pattern.standard.success, 2);
|
|
45
|
-
assert.equal(pattern.standard.fail, 1);
|
|
40
|
+
const history = getRoutingHistory()!;
|
|
41
|
+
assert.equal(history.patterns["execute-task"].standard.success, 2);
|
|
42
|
+
assert.equal(history.patterns["execute-task"].standard.fail, 1);
|
|
46
43
|
} finally {
|
|
47
44
|
cleanup(dir);
|
|
48
45
|
}
|
|
@@ -54,9 +51,7 @@ test("recordOutcome tracks tag-specific patterns", () => {
|
|
|
54
51
|
initRoutingHistory(dir);
|
|
55
52
|
recordOutcome("execute-task", "light", true, ["docs"]);
|
|
56
53
|
|
|
57
|
-
const history = getRoutingHistory()
|
|
58
|
-
assert.ok(history);
|
|
59
|
-
assert.ok(history.patterns["execute-task:docs"]);
|
|
54
|
+
const history = getRoutingHistory()!;
|
|
60
55
|
assert.equal(history.patterns["execute-task:docs"].light.success, 1);
|
|
61
56
|
} finally {
|
|
62
57
|
cleanup(dir);
|
|
@@ -72,8 +67,7 @@ test("recordOutcome applies rolling window", () => {
|
|
|
72
67
|
recordOutcome("execute-task", "standard", true);
|
|
73
68
|
}
|
|
74
69
|
|
|
75
|
-
const history = getRoutingHistory()
|
|
76
|
-
assert.ok(history);
|
|
70
|
+
const history = getRoutingHistory()!;
|
|
77
71
|
const total = history.patterns["execute-task"].standard.success +
|
|
78
72
|
history.patterns["execute-task"].standard.fail;
|
|
79
73
|
assert.ok(total <= 50, `total ${total} should be <= 50`);
|
|
@@ -161,8 +155,7 @@ test("recordFeedback stores feedback entries", () => {
|
|
|
161
155
|
initRoutingHistory(dir);
|
|
162
156
|
recordFeedback("execute-task", "M001/S01/T01", "standard", "over");
|
|
163
157
|
|
|
164
|
-
const history = getRoutingHistory()
|
|
165
|
-
assert.ok(history);
|
|
158
|
+
const history = getRoutingHistory()!;
|
|
166
159
|
assert.equal(history.feedback.length, 1);
|
|
167
160
|
assert.equal(history.feedback[0].rating, "over");
|
|
168
161
|
assert.equal(history.feedback[0].tier, "standard");
|
|
@@ -177,8 +170,7 @@ test("recordFeedback 'under' increases failure count at tier", () => {
|
|
|
177
170
|
initRoutingHistory(dir);
|
|
178
171
|
recordFeedback("execute-task", "M001/S01/T01", "light", "under");
|
|
179
172
|
|
|
180
|
-
const history = getRoutingHistory()
|
|
181
|
-
assert.ok(history);
|
|
173
|
+
const history = getRoutingHistory()!;
|
|
182
174
|
// "under" adds 2 (FEEDBACK_WEIGHT) failures
|
|
183
175
|
assert.equal(history.patterns["execute-task"].light.fail, 2);
|
|
184
176
|
} finally {
|
|
@@ -192,8 +184,7 @@ test("recordFeedback 'over' increases success count at lower tier", () => {
|
|
|
192
184
|
initRoutingHistory(dir);
|
|
193
185
|
recordFeedback("execute-task", "M001/S01/T01", "standard", "over");
|
|
194
186
|
|
|
195
|
-
const history = getRoutingHistory()
|
|
196
|
-
assert.ok(history);
|
|
187
|
+
const history = getRoutingHistory()!;
|
|
197
188
|
// "over" at standard → adds 2 successes at light
|
|
198
189
|
assert.equal(history.patterns["execute-task"].light.success, 2);
|
|
199
190
|
} finally {
|
|
@@ -210,8 +201,7 @@ test("clearRoutingHistory resets all data", () => {
|
|
|
210
201
|
recordOutcome("execute-task", "light", true);
|
|
211
202
|
clearRoutingHistory(dir);
|
|
212
203
|
|
|
213
|
-
const history = getRoutingHistory()
|
|
214
|
-
assert.ok(history);
|
|
204
|
+
const history = getRoutingHistory()!;
|
|
215
205
|
assert.deepEqual(history.patterns, {});
|
|
216
206
|
assert.deepEqual(history.feedback, []);
|
|
217
207
|
} finally {
|
|
@@ -231,8 +221,7 @@ test("routing history persists to disk and reloads", () => {
|
|
|
231
221
|
|
|
232
222
|
// Reload from disk
|
|
233
223
|
initRoutingHistory(dir);
|
|
234
|
-
const history = getRoutingHistory()
|
|
235
|
-
assert.ok(history);
|
|
224
|
+
const history = getRoutingHistory()!;
|
|
236
225
|
assert.equal(history.patterns["execute-task"].standard.success, 2);
|
|
237
226
|
} finally {
|
|
238
227
|
cleanup(dir);
|