gsd-pi 2.71.0-dev.977c553 → 2.71.0-dev.d4d916a
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +12 -3
- package/dist/headless-events.d.ts +2 -0
- package/dist/headless-events.js +7 -0
- package/dist/headless.js +16 -3
- package/dist/mcp-server.js +6 -6
- package/dist/provider-migrations.d.ts +10 -0
- package/dist/provider-migrations.js +12 -0
- package/dist/resource-loader.js +139 -13
- package/dist/resources/GSD-WORKFLOW.md +1 -1
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +10 -4
- package/dist/resources/extensions/gsd/auto/infra-errors.js +34 -0
- package/dist/resources/extensions/gsd/auto/loop.js +32 -1
- package/dist/resources/extensions/gsd/auto/phases.js +1 -1
- package/dist/resources/extensions/gsd/auto/session.js +11 -0
- package/dist/resources/extensions/gsd/auto-dashboard.js +22 -16
- package/dist/resources/extensions/gsd/auto-model-selection.js +10 -2
- package/dist/resources/extensions/gsd/auto-start.js +31 -7
- package/dist/resources/extensions/gsd/auto-tool-tracking.js +1 -1
- package/dist/resources/extensions/gsd/auto-worktree.js +1 -1
- package/dist/resources/extensions/gsd/auto.js +52 -0
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +2 -0
- package/dist/resources/extensions/gsd/bootstrap/register-shortcuts.js +63 -51
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +6 -0
- package/dist/resources/extensions/gsd/commands/context.js +15 -6
- package/dist/resources/extensions/gsd/commands/dispatcher.js +12 -2
- package/dist/resources/extensions/gsd/commands/handlers/auto.js +10 -33
- package/dist/resources/extensions/gsd/commands/handlers/core.js +56 -11
- package/dist/resources/extensions/gsd/commands/handlers/notifications-handler.js +15 -6
- package/dist/resources/extensions/gsd/commands/handlers/workflow.js +4 -10
- package/dist/resources/extensions/gsd/dashboard-overlay.js +8 -3
- package/dist/resources/extensions/gsd/dispatch-guard.js +18 -1
- package/dist/resources/extensions/gsd/error-classifier.js +1 -1
- package/dist/resources/extensions/gsd/forensics.js +19 -6
- package/dist/resources/extensions/gsd/guided-flow.js +5 -10
- package/dist/resources/extensions/gsd/metrics.js +1 -0
- package/dist/resources/extensions/gsd/milestone-actions.js +10 -4
- package/dist/resources/extensions/gsd/notification-overlay.js +42 -13
- package/dist/resources/extensions/gsd/notification-store.js +56 -5
- package/dist/resources/extensions/gsd/notification-widget.js +5 -13
- package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +8 -3
- package/dist/resources/extensions/gsd/pre-execution-checks.js +35 -2
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +2 -2
- package/dist/resources/extensions/gsd/prompts/discuss.md +2 -0
- package/dist/resources/extensions/gsd/prompts/execute-task.md +20 -19
- package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +2 -0
- package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +2 -0
- package/dist/resources/extensions/gsd/prompts/guided-resume-task.md +1 -1
- package/dist/resources/extensions/gsd/prompts/queue.md +3 -2
- package/dist/resources/extensions/gsd/prompts/system.md +1 -0
- package/dist/resources/extensions/gsd/prompts/validate-milestone.md +2 -1
- package/dist/resources/extensions/gsd/session-model-override.js +25 -0
- package/dist/resources/extensions/gsd/shortcut-defs.js +40 -0
- package/dist/resources/extensions/ollama/index.js +13 -5
- package/dist/resources/skills/create-skill/SKILL.md +2 -0
- package/dist/startup-model-validation.d.ts +0 -1
- package/dist/startup-model-validation.js +6 -2
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +14 -14
- package/dist/web/standalone/.next/build-manifest.json +2 -2
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/required-server-files.json +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.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/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 +14 -14
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/server.js +1 -1
- package/package.json +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +21 -11
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/src/workflow-tools.test.ts +110 -0
- package/packages/mcp-server/src/workflow-tools.ts +31 -11
- package/packages/pi-ai/dist/providers/amazon-bedrock.js +11 -2
- package/packages/pi-ai/dist/providers/amazon-bedrock.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-auth.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/anthropic-auth.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/anthropic-auth.test.js +20 -0
- package/packages/pi-ai/dist/providers/anthropic-auth.test.js.map +1 -0
- package/packages/pi-ai/dist/providers/anthropic-shared.d.ts +4 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.js +8 -3
- package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.test.js +44 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.test.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.d.ts +2 -1
- package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.js +7 -4
- package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/openai-completions.js +11 -0
- package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
- package/packages/pi-ai/src/providers/amazon-bedrock.ts +13 -1
- package/packages/pi-ai/src/providers/anthropic-auth.test.ts +32 -0
- package/packages/pi-ai/src/providers/anthropic-shared.test.ts +55 -1
- package/packages/pi-ai/src/providers/anthropic-shared.ts +14 -3
- package/packages/pi-ai/src/providers/anthropic.ts +8 -4
- package/packages/pi-ai/src/providers/openai-completions.ts +14 -0
- package/packages/pi-coding-agent/dist/core/agent-session-renderable-tools.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/agent-session-renderable-tools.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/agent-session-renderable-tools.test.js +61 -0
- package/packages/pi-coding-agent/dist/core/agent-session-renderable-tools.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js +2 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +10 -0
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.js +27 -0
- package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.test.js +85 -0
- package/packages/pi-coding-agent/dist/core/auth-storage.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-resolver-initial-model-auth.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/model-resolver-initial-model-auth.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-resolver-initial-model-auth.test.js +64 -0
- package/packages/pi-coding-agent/dist/core/model-resolver-initial-model-auth.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-resolver.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-resolver.js +22 -18
- package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-resolver.test.d.ts +8 -0
- package/packages/pi-coding-agent/dist/core/model-resolver.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-resolver.test.js +75 -0
- package/packages/pi-coding-agent/dist/core/model-resolver.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/sdk.d.ts +11 -0
- package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.js +38 -5
- package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/sdk.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/sdk.test.js +71 -0
- package/packages/pi-coding-agent/dist/core/sdk.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/index.d.ts +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/index.js +1 -1
- package/packages/pi-coding-agent/dist/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/login-dialog.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/login-dialog.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/login-dialog.test.js +13 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/login-dialog.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.d.ts +4 -0
- 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 +24 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.js +9 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +4 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +43 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +7 -2
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/model-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/model-controller.js +6 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/model-controller.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 -3
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js +4 -2
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js.map +1 -1
- package/packages/pi-coding-agent/src/core/agent-session-renderable-tools.test.ts +70 -0
- package/packages/pi-coding-agent/src/core/agent-session.ts +2 -1
- package/packages/pi-coding-agent/src/core/auth-storage.test.ts +108 -0
- package/packages/pi-coding-agent/src/core/auth-storage.ts +30 -0
- package/packages/pi-coding-agent/src/core/model-resolver-initial-model-auth.test.ts +78 -0
- package/packages/pi-coding-agent/src/core/model-resolver.test.ts +85 -0
- package/packages/pi-coding-agent/src/core/model-resolver.ts +22 -18
- package/packages/pi-coding-agent/src/core/sdk.test.ts +89 -0
- package/packages/pi-coding-agent/src/core/sdk.ts +45 -9
- package/packages/pi-coding-agent/src/index.ts +1 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/login-dialog.test.ts +24 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/login-dialog.ts +30 -2
- package/packages/pi-coding-agent/src/modes/interactive/components/model-selector.ts +15 -6
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +47 -0
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +7 -2
- package/packages/pi-coding-agent/src/modes/interactive/controllers/model-controller.ts +6 -1
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +4 -3
- package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.ts +4 -2
- package/src/resources/GSD-WORKFLOW.md +1 -1
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +13 -5
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +56 -4
- package/src/resources/extensions/gsd/auto/infra-errors.ts +38 -0
- package/src/resources/extensions/gsd/auto/loop-deps.ts +2 -0
- package/src/resources/extensions/gsd/auto/loop.ts +45 -1
- package/src/resources/extensions/gsd/auto/phases.ts +2 -0
- package/src/resources/extensions/gsd/auto/session.ts +11 -0
- package/src/resources/extensions/gsd/auto-dashboard.ts +29 -18
- package/src/resources/extensions/gsd/auto-model-selection.ts +9 -1
- package/src/resources/extensions/gsd/auto-start.ts +38 -7
- package/src/resources/extensions/gsd/auto-tool-tracking.ts +1 -1
- package/src/resources/extensions/gsd/auto-worktree.ts +1 -1
- package/src/resources/extensions/gsd/auto.ts +68 -0
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +2 -0
- package/src/resources/extensions/gsd/bootstrap/register-shortcuts.ts +79 -60
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +7 -0
- package/src/resources/extensions/gsd/commands/context.ts +16 -5
- package/src/resources/extensions/gsd/commands/dispatcher.ts +14 -2
- package/src/resources/extensions/gsd/commands/handlers/auto.ts +10 -36
- package/src/resources/extensions/gsd/commands/handlers/core.ts +58 -11
- package/src/resources/extensions/gsd/commands/handlers/notifications-handler.ts +17 -7
- package/src/resources/extensions/gsd/commands/handlers/workflow.ts +4 -10
- package/src/resources/extensions/gsd/dashboard-overlay.ts +10 -3
- package/src/resources/extensions/gsd/dispatch-guard.ts +18 -1
- package/src/resources/extensions/gsd/error-classifier.ts +1 -1
- package/src/resources/extensions/gsd/forensics.ts +23 -7
- package/src/resources/extensions/gsd/guided-flow.ts +5 -10
- package/src/resources/extensions/gsd/interrupted-session.ts +1 -0
- package/src/resources/extensions/gsd/metrics.ts +12 -1
- package/src/resources/extensions/gsd/milestone-actions.ts +10 -3
- package/src/resources/extensions/gsd/notification-overlay.ts +47 -14
- package/src/resources/extensions/gsd/notification-store.ts +54 -5
- package/src/resources/extensions/gsd/notification-widget.ts +5 -14
- package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +10 -3
- package/src/resources/extensions/gsd/pre-execution-checks.ts +39 -2
- package/src/resources/extensions/gsd/prompts/complete-slice.md +2 -2
- package/src/resources/extensions/gsd/prompts/discuss.md +2 -0
- package/src/resources/extensions/gsd/prompts/execute-task.md +20 -19
- package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +2 -0
- package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +2 -0
- package/src/resources/extensions/gsd/prompts/guided-resume-task.md +1 -1
- package/src/resources/extensions/gsd/prompts/queue.md +3 -2
- package/src/resources/extensions/gsd/prompts/system.md +1 -0
- package/src/resources/extensions/gsd/prompts/validate-milestone.md +2 -1
- package/src/resources/extensions/gsd/session-model-override.ts +36 -0
- package/src/resources/extensions/gsd/shortcut-defs.ts +56 -0
- package/src/resources/extensions/gsd/tests/auto-start-model-capture.test.ts +25 -9
- package/src/resources/extensions/gsd/tests/auto-start-worktree-db-path.test.ts +28 -0
- package/src/resources/extensions/gsd/tests/bootstrap-derive-state-db-open.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/complete-slice-prompt-task-summary-layout.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/execute-task-prompt-existing-artifact-guard.test.ts +33 -0
- package/src/resources/extensions/gsd/tests/forensics-stuck-loops.test.ts +62 -0
- package/src/resources/extensions/gsd/tests/format-shortcut.test.ts +31 -0
- package/src/resources/extensions/gsd/tests/gsd-no-project-error.test.ts +73 -0
- package/src/resources/extensions/gsd/tests/infra-errors-cooldown.test.ts +180 -0
- package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +66 -1
- package/src/resources/extensions/gsd/tests/model-isolation.test.ts +36 -51
- package/src/resources/extensions/gsd/tests/notification-store.test.ts +35 -0
- package/src/resources/extensions/gsd/tests/notification-widget.test.ts +26 -0
- package/src/resources/extensions/gsd/tests/notifications-handler.test.ts +90 -0
- package/src/resources/extensions/gsd/tests/parallel-monitor-overlay.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/park-db-sync.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +49 -0
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +19 -0
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +7 -0
- package/src/resources/extensions/gsd/tests/register-shortcuts.test.ts +63 -5
- package/src/resources/extensions/gsd/tests/session-model-override.test.ts +35 -0
- package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +90 -0
- package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +7 -0
- package/src/resources/extensions/gsd/tests/validate-milestone-prompt-verification-classes.test.ts +18 -0
- package/src/resources/extensions/ollama/index.ts +13 -3
- package/src/resources/extensions/ollama/ollama-status-indicator.test.ts +28 -0
- package/src/resources/skills/create-skill/SKILL.md +2 -0
- /package/dist/web/standalone/.next/static/{4xyaXTn7-shVHaGMcl75o → IRnpNeY-_eO7SxKBIkTbL}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{4xyaXTn7-shVHaGMcl75o → IRnpNeY-_eO7SxKBIkTbL}/_ssgManifest.js +0 -0
|
@@ -1107,6 +1107,38 @@ describe("checkTaskOrdering false positive regression (#3677)", () => {
|
|
|
1107
1107
|
assert.equal(results[0].target, "`later.ts` — needed first");
|
|
1108
1108
|
assert.ok(results[0].message.includes("sequence violation"));
|
|
1109
1109
|
});
|
|
1110
|
+
|
|
1111
|
+
test("existing on-disk files do not trigger ordering violations just because a later task modifies them", () => {
|
|
1112
|
+
const tempDir = join(tmpdir(), `pre-exec-ordering-existing-file-${Date.now()}`);
|
|
1113
|
+
const existingFile = "frontend/src/__tests__/ProcurementPage29.test.tsx";
|
|
1114
|
+
|
|
1115
|
+
mkdirSync(join(tempDir, "frontend", "src", "__tests__"), { recursive: true });
|
|
1116
|
+
writeFileSync(join(tempDir, existingFile), "// existing file");
|
|
1117
|
+
|
|
1118
|
+
try {
|
|
1119
|
+
const tasks = [
|
|
1120
|
+
createTask({
|
|
1121
|
+
id: "T01",
|
|
1122
|
+
sequence: 0,
|
|
1123
|
+
files: [],
|
|
1124
|
+
inputs: ["`frontend/src/__tests__/ProcurementPage29.test.tsx` — contains matchMedia stub to remove"],
|
|
1125
|
+
expected_output: [],
|
|
1126
|
+
}),
|
|
1127
|
+
createTask({
|
|
1128
|
+
id: "T03",
|
|
1129
|
+
sequence: 2,
|
|
1130
|
+
files: [],
|
|
1131
|
+
inputs: [],
|
|
1132
|
+
expected_output: ["frontend/src/__tests__/ProcurementPage29.test.tsx"],
|
|
1133
|
+
}),
|
|
1134
|
+
];
|
|
1135
|
+
|
|
1136
|
+
const results = checkTaskOrdering(tasks, tempDir);
|
|
1137
|
+
assert.equal(results.length, 0, "Pre-existing files should not be treated as created by later tasks");
|
|
1138
|
+
} finally {
|
|
1139
|
+
rmSync(tempDir, { recursive: true, force: true });
|
|
1140
|
+
}
|
|
1141
|
+
});
|
|
1110
1142
|
});
|
|
1111
1143
|
|
|
1112
1144
|
// ─── checkFilePathConsistency additional edge cases ──────────────────────────
|
|
@@ -1175,6 +1207,23 @@ describe("checkFilePathConsistency additional edge cases", () => {
|
|
|
1175
1207
|
assert.equal(results![0].blocking, true);
|
|
1176
1208
|
});
|
|
1177
1209
|
|
|
1210
|
+
test("multi-word prose inputs are ignored by path consistency checks", () => {
|
|
1211
|
+
const tasks = [
|
|
1212
|
+
createTask({
|
|
1213
|
+
id: "T01",
|
|
1214
|
+
files: [],
|
|
1215
|
+
inputs: [
|
|
1216
|
+
"Current WIZARD_PRODUCTS enum",
|
|
1217
|
+
"Existing test patterns in wizard.test.ts",
|
|
1218
|
+
],
|
|
1219
|
+
expected_output: [],
|
|
1220
|
+
}),
|
|
1221
|
+
];
|
|
1222
|
+
|
|
1223
|
+
const results = checkFilePathConsistency(tasks, "/tmp");
|
|
1224
|
+
assert.equal(results.length, 0, "Prose planning hints should not be treated as missing file paths");
|
|
1225
|
+
});
|
|
1226
|
+
|
|
1178
1227
|
test("empty inputs array produces no results", () => {
|
|
1179
1228
|
// A task with no inputs and only files should produce zero results from
|
|
1180
1229
|
// consistency check — files are not checked (#3626).
|
|
@@ -42,9 +42,19 @@ test("system prompt references CODEBASE.md and /gsd codebase", () => {
|
|
|
42
42
|
assert.match(prompt, /auto-refreshes it when tracked files change/i);
|
|
43
43
|
});
|
|
44
44
|
|
|
45
|
+
test("system prompt hard rules forbid fabricating user responses", () => {
|
|
46
|
+
const prompt = readPrompt("system");
|
|
47
|
+
assert.match(prompt, /never fabricate, simulate, or role-play user responses/i);
|
|
48
|
+
assert.match(prompt, /never generate markers like `?\[User\]`?, `?\[Human\]`?, `?User:`?/i);
|
|
49
|
+
assert.match(prompt, /ask one question round \(1-3 questions\), then stop and wait for the user's actual response/i);
|
|
50
|
+
assert.match(prompt, /ask_user_questions.*only valid structured user input/i);
|
|
51
|
+
});
|
|
52
|
+
|
|
45
53
|
test("discuss prompt allows implementation questions when they materially matter", () => {
|
|
46
54
|
const prompt = readPrompt("discuss");
|
|
47
55
|
assert.match(prompt, /Lead with experience, but ask implementation when it materially matters/i);
|
|
56
|
+
assert.match(prompt, /Never fabricate, simulate, or role-play user responses/i);
|
|
57
|
+
assert.match(prompt, /Ask one question round \(1-3 questions\) per turn, then stop and wait for the user's actual response/i);
|
|
48
58
|
assert.match(prompt, /one gate, not two/i);
|
|
49
59
|
assert.doesNotMatch(prompt, /Questions must be about the experience, not the implementation/i);
|
|
50
60
|
});
|
|
@@ -56,6 +66,8 @@ test("guided discussion prompts avoid wrap-up prompts after every round", () =>
|
|
|
56
66
|
assert.match(slicePrompt, /Do \*\*not\*\* ask a meta "ready to wrap up\?" question after every round/i);
|
|
57
67
|
assert.doesNotMatch(milestonePrompt, /I think I have a solid picture of this milestone\. Ready to wrap up/i);
|
|
58
68
|
assert.doesNotMatch(slicePrompt, /I think I have a solid picture of this slice\. Ready to wrap up/i);
|
|
69
|
+
assert.match(milestonePrompt, /Never fabricate or simulate user input/i);
|
|
70
|
+
assert.match(slicePrompt, /Never fabricate or simulate user input/i);
|
|
59
71
|
});
|
|
60
72
|
|
|
61
73
|
test("guided milestone discussion scopes depth verification to the milestone id", () => {
|
|
@@ -64,6 +76,13 @@ test("guided milestone discussion scopes depth verification to the milestone id"
|
|
|
64
76
|
assert.doesNotMatch(prompt, /depth_verification_confirm" — this enables the write-gate downstream/i, "legacy global depth gate wording should be gone");
|
|
65
77
|
});
|
|
66
78
|
|
|
79
|
+
test("queue prompt requires waiting for user response between rounds", () => {
|
|
80
|
+
const prompt = readPrompt("queue");
|
|
81
|
+
assert.match(prompt, /Never fabricate or simulate user input during this discussion/i);
|
|
82
|
+
assert.match(prompt, /Ask 1-3 questions per round, then wait for the user's response before asking the next round\./i);
|
|
83
|
+
assert.doesNotMatch(prompt, /treat that as permission to continue/i);
|
|
84
|
+
});
|
|
85
|
+
|
|
67
86
|
test("guided-resume-task prompt preserves recovery state until work is superseded", () => {
|
|
68
87
|
const prompt = readPrompt("guided-resume-task");
|
|
69
88
|
assert.match(prompt, /Do \*\*not\*\* delete the continue file immediately/i);
|
|
@@ -101,6 +101,13 @@ test("classifyError detects quota exceeded as permanent", () => {
|
|
|
101
101
|
assert.ok(!isTransient(result));
|
|
102
102
|
});
|
|
103
103
|
|
|
104
|
+
test("classifyError treats plain 'Connection error.' as transient connection failure (#3594)", () => {
|
|
105
|
+
const result = classifyError("Connection error.");
|
|
106
|
+
assert.ok(isTransient(result));
|
|
107
|
+
assert.equal(result.kind, "connection");
|
|
108
|
+
assert.ok("retryAfterMs" in result && result.retryAfterMs === 15_000);
|
|
109
|
+
});
|
|
110
|
+
|
|
104
111
|
test("classifyError treats unknown error as not transient", () => {
|
|
105
112
|
const result = classifyError("something went wrong");
|
|
106
113
|
assert.ok(!isTransient(result));
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import test from "node:test";
|
|
2
2
|
import assert from "node:assert/strict";
|
|
3
|
-
import { mkdirSync, rmSync } from "node:fs";
|
|
3
|
+
import { mkdirSync, realpathSync, rmSync } from "node:fs";
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
import { tmpdir } from "node:os";
|
|
6
6
|
|
|
@@ -37,10 +37,10 @@ test("dashboard shortcut resolves the project root instead of the current worktr
|
|
|
37
37
|
});
|
|
38
38
|
|
|
39
39
|
let capturedHandler: ((ctx: any) => Promise<void>) | null = null;
|
|
40
|
-
const shortcuts: Array<{ description: string; handler: (ctx: any) => Promise<void> }> = [];
|
|
40
|
+
const shortcuts: Array<{ key: string; description: string; handler: (ctx: any) => Promise<void> }> = [];
|
|
41
41
|
const pi = {
|
|
42
|
-
registerShortcut: (
|
|
43
|
-
shortcuts.push(shortcut);
|
|
42
|
+
registerShortcut: (key: unknown, shortcut: { description: string; handler: (ctx: any) => Promise<void> }) => {
|
|
43
|
+
shortcuts.push({ key: String(key), ...shortcut });
|
|
44
44
|
if (!capturedHandler) {
|
|
45
45
|
capturedHandler = shortcut.handler;
|
|
46
46
|
}
|
|
@@ -69,5 +69,63 @@ test("dashboard shortcut resolves the project root instead of the current worktr
|
|
|
69
69
|
|
|
70
70
|
assert.ok(customCalls > 0, "shortcut opens the dashboard overlay when project root is resolved");
|
|
71
71
|
assert.equal(notices.length, 0, "shortcut does not fall back to the missing-.gsd warning");
|
|
72
|
-
assert.equal(shortcuts.length,
|
|
72
|
+
assert.equal(shortcuts.length, 5, "all GSD shortcuts are still registered");
|
|
73
|
+
const keys = shortcuts.map((shortcut) => shortcut.key);
|
|
74
|
+
assert.ok(keys.includes("ctrl+alt+g"), "primary dashboard shortcut is registered");
|
|
75
|
+
assert.ok(keys.includes("ctrl+shift+g"), "fallback dashboard shortcut is registered");
|
|
76
|
+
assert.ok(keys.includes("ctrl+alt+n"), "primary notifications shortcut is registered");
|
|
77
|
+
assert.ok(keys.includes("ctrl+shift+n"), "fallback notifications shortcut is registered");
|
|
78
|
+
assert.ok(keys.includes("ctrl+alt+p"), "primary parallel shortcut is registered");
|
|
79
|
+
// No Ctrl+Shift+P fallback — conflicts with cycleModelBackward (shift+ctrl+p)
|
|
80
|
+
assert.ok(!keys.includes("ctrl+shift+p"), "parallel fallback must not be registered (conflicts with cycleModelBackward)");
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
test("parallel shortcut passes resolved project root into overlay", async (t) => {
|
|
84
|
+
const base = makeTempDir("parallel-root");
|
|
85
|
+
const worktreeRoot = join(base, ".gsd", "worktrees", "M001");
|
|
86
|
+
mkdirSync(join(base, ".gsd", "parallel"), { recursive: true });
|
|
87
|
+
mkdirSync(worktreeRoot, { recursive: true });
|
|
88
|
+
|
|
89
|
+
const originalCwd = process.cwd();
|
|
90
|
+
process.chdir(worktreeRoot);
|
|
91
|
+
t.after(() => {
|
|
92
|
+
process.chdir(originalCwd);
|
|
93
|
+
cleanup(base);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
const shortcuts: Array<{ key: string; description: string; handler: (ctx: any) => Promise<void> }> = [];
|
|
97
|
+
registerShortcuts({
|
|
98
|
+
registerShortcut: (key: unknown, shortcut: { description: string; handler: (ctx: any) => Promise<void> }) => {
|
|
99
|
+
shortcuts.push({ key: String(key), ...shortcut });
|
|
100
|
+
},
|
|
101
|
+
} as any);
|
|
102
|
+
|
|
103
|
+
const parallelShortcut = shortcuts.find((shortcut) => shortcut.key === "ctrl+alt+p");
|
|
104
|
+
assert.ok(parallelShortcut, "parallel shortcut is registered");
|
|
105
|
+
|
|
106
|
+
let capturedBasePath: string | undefined;
|
|
107
|
+
await parallelShortcut!.handler({
|
|
108
|
+
hasUI: true,
|
|
109
|
+
ui: {
|
|
110
|
+
custom: async (factory: any) => {
|
|
111
|
+
const overlay = factory(
|
|
112
|
+
{ requestRender() {} },
|
|
113
|
+
{ fg: (_color: string, text: string) => text, bold: (text: string) => text },
|
|
114
|
+
null,
|
|
115
|
+
() => {},
|
|
116
|
+
);
|
|
117
|
+
capturedBasePath = (overlay as any).basePath;
|
|
118
|
+
overlay.dispose?.();
|
|
119
|
+
return true;
|
|
120
|
+
},
|
|
121
|
+
notify: () => {},
|
|
122
|
+
},
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
assert.ok(capturedBasePath, "parallel shortcut should construct overlay with a basePath");
|
|
126
|
+
assert.equal(
|
|
127
|
+
realpathSync(capturedBasePath),
|
|
128
|
+
realpathSync(base),
|
|
129
|
+
"parallel overlay should use the resolved project root, not the worktree cwd",
|
|
130
|
+
);
|
|
73
131
|
});
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import test from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { readFileSync } from "node:fs";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
clearSessionModelOverride,
|
|
8
|
+
getSessionModelOverride,
|
|
9
|
+
setSessionModelOverride,
|
|
10
|
+
} from "../session-model-override.js";
|
|
11
|
+
|
|
12
|
+
const phasesSource = readFileSync(join(import.meta.dirname, "..", "auto", "phases.ts"), "utf-8");
|
|
13
|
+
|
|
14
|
+
test("setSessionModelOverride stores provider/model for the session", () => {
|
|
15
|
+
const sessionId = `session-override-${Date.now()}`;
|
|
16
|
+
setSessionModelOverride(sessionId, { provider: "openai-codex", id: "gpt-5.4" });
|
|
17
|
+
|
|
18
|
+
const override = getSessionModelOverride(sessionId);
|
|
19
|
+
assert.equal(override?.provider, "openai-codex");
|
|
20
|
+
assert.equal(override?.id, "gpt-5.4");
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
test("clearSessionModelOverride removes the session override", () => {
|
|
24
|
+
const sessionId = `session-clear-${Date.now()}`;
|
|
25
|
+
setSessionModelOverride(sessionId, { provider: "anthropic", id: "claude-sonnet-4-6" });
|
|
26
|
+
clearSessionModelOverride(sessionId);
|
|
27
|
+
assert.equal(getSessionModelOverride(sessionId), undefined);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
test("auto dispatch threads manual session model override into selectAndApplyModel", () => {
|
|
31
|
+
assert.ok(
|
|
32
|
+
phasesSource.includes("s.manualSessionModelOverride"),
|
|
33
|
+
"auto/phases.ts should pass s.manualSessionModelOverride into selectAndApplyModel",
|
|
34
|
+
);
|
|
35
|
+
});
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import test from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { readFileSync } from "node:fs";
|
|
4
|
+
import { resolve } from "node:path";
|
|
5
|
+
|
|
6
|
+
const gsdDir = resolve(import.meta.dirname, "..");
|
|
7
|
+
|
|
8
|
+
function readGsdFile(relativePath: string): string {
|
|
9
|
+
return readFileSync(resolve(gsdDir, relativePath), "utf-8");
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
test("command entrypoints use startAutoDetached instead of awaiting startAuto (#3733)", () => {
|
|
13
|
+
const autoHandlerSrc = readGsdFile("commands/handlers/auto.ts");
|
|
14
|
+
const workflowHandlerSrc = readGsdFile("commands/handlers/workflow.ts");
|
|
15
|
+
const guidedFlowSrc = readGsdFile("guided-flow.ts");
|
|
16
|
+
|
|
17
|
+
assert.ok(
|
|
18
|
+
!autoHandlerSrc.includes("await startAuto("),
|
|
19
|
+
"auto command handler should not await startAuto from the active agent turn",
|
|
20
|
+
);
|
|
21
|
+
assert.ok(
|
|
22
|
+
!workflowHandlerSrc.includes("await startAuto("),
|
|
23
|
+
"workflow command handler should not await startAuto from the active agent turn",
|
|
24
|
+
);
|
|
25
|
+
assert.ok(
|
|
26
|
+
!guidedFlowSrc.includes("await startAuto("),
|
|
27
|
+
"guided flow should not await startAuto from the active agent turn",
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
assert.ok(
|
|
31
|
+
autoHandlerSrc.includes("startAutoDetached("),
|
|
32
|
+
"auto command handler should launch auto-mode through startAutoDetached",
|
|
33
|
+
);
|
|
34
|
+
assert.ok(
|
|
35
|
+
workflowHandlerSrc.includes("startAutoDetached("),
|
|
36
|
+
"workflow handler should launch auto-mode through startAutoDetached",
|
|
37
|
+
);
|
|
38
|
+
assert.ok(
|
|
39
|
+
guidedFlowSrc.includes("startAutoDetached("),
|
|
40
|
+
"guided flow should launch auto-mode through startAutoDetached",
|
|
41
|
+
);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
test("startAutoDetached reports failures asynchronously (#3733)", () => {
|
|
45
|
+
const autoSrc = readGsdFile("auto.ts");
|
|
46
|
+
|
|
47
|
+
assert.ok(
|
|
48
|
+
autoSrc.includes("export function startAutoDetached"),
|
|
49
|
+
"auto.ts should export startAutoDetached",
|
|
50
|
+
);
|
|
51
|
+
assert.ok(
|
|
52
|
+
autoSrc.includes("void startAuto(ctx, pi, base, verboseMode, options).catch"),
|
|
53
|
+
"startAutoDetached should launch startAuto without awaiting it",
|
|
54
|
+
);
|
|
55
|
+
assert.ok(
|
|
56
|
+
autoSrc.includes("ctx.ui.notify(`Auto-start failed: ${message}`, \"error\")"),
|
|
57
|
+
"startAutoDetached should surface async startup failures to the user",
|
|
58
|
+
);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test("detached auto-start preserves milestone lock across pause/stop cleanup (#3733)", () => {
|
|
62
|
+
const autoSrc = readGsdFile("auto.ts");
|
|
63
|
+
const sessionSrc = readGsdFile("auto/session.ts");
|
|
64
|
+
|
|
65
|
+
assert.ok(
|
|
66
|
+
autoSrc.includes("milestoneLock?: string | null"),
|
|
67
|
+
"startAuto/startAutoDetached options should carry an explicit milestone lock",
|
|
68
|
+
);
|
|
69
|
+
assert.ok(
|
|
70
|
+
autoSrc.includes("s.sessionMilestoneLock = options.milestoneLock ?? null;"),
|
|
71
|
+
"startAuto should capture the requested milestone lock before async work begins",
|
|
72
|
+
);
|
|
73
|
+
assert.ok(
|
|
74
|
+
autoSrc.includes("milestoneLock: s.sessionMilestoneLock ?? undefined"),
|
|
75
|
+
"pause metadata should persist the detached milestone lock for resume",
|
|
76
|
+
);
|
|
77
|
+
assert.ok(
|
|
78
|
+
autoSrc.includes("s.sessionMilestoneLock = meta.milestoneLock ?? null;"),
|
|
79
|
+
"resume should restore the persisted milestone lock",
|
|
80
|
+
);
|
|
81
|
+
assert.ok(
|
|
82
|
+
autoSrc.includes("restoreMilestoneLockEnv();"),
|
|
83
|
+
"auto cleanup should restore the previous process milestone-lock env",
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
assert.ok(
|
|
87
|
+
sessionSrc.includes("sessionMilestoneLock: string | null = null;"),
|
|
88
|
+
"AutoSession should track the detached milestone lock explicitly",
|
|
89
|
+
);
|
|
90
|
+
});
|
|
@@ -61,6 +61,13 @@ describe("#2883: isToolInvocationError classification", () => {
|
|
|
61
61
|
);
|
|
62
62
|
});
|
|
63
63
|
|
|
64
|
+
test("detects Node v18+ JSON parse variant with property-value text", () => {
|
|
65
|
+
assert.equal(
|
|
66
|
+
isToolInvocationError("Expected ',' or '}' after property value in JSON at position 4096"),
|
|
67
|
+
true,
|
|
68
|
+
);
|
|
69
|
+
});
|
|
70
|
+
|
|
64
71
|
test("detects Unexpected end of JSON input", () => {
|
|
65
72
|
assert.equal(
|
|
66
73
|
isToolInvocationError("Unexpected end of JSON input"),
|
package/src/resources/extensions/gsd/tests/validate-milestone-prompt-verification-classes.test.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import test from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { readFileSync } from "node:fs";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
|
|
6
|
+
const promptPath = join(process.cwd(), "src/resources/extensions/gsd/prompts/validate-milestone.md");
|
|
7
|
+
const prompt = readFileSync(promptPath, "utf-8");
|
|
8
|
+
|
|
9
|
+
test("validate-milestone reviewer C requires canonical verification class names", () => {
|
|
10
|
+
assert.match(prompt, /\*\*Reviewer C[\s\S]*Verification Classes/i);
|
|
11
|
+
assert.match(prompt, /exact class names [`']?Contract[`']?, [`']?Integration[`']?, [`']?Operational[`']?, and [`']?UAT[`']?/i);
|
|
12
|
+
assert.match(prompt, /If no verification classes were planned, say that explicitly/i);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
test("validate-milestone prompt routes verification class analysis into verificationClasses", () => {
|
|
16
|
+
assert.match(prompt, /pass it in `verificationClasses`/i);
|
|
17
|
+
assert.match(prompt, /Extract the `Verification Classes` subsection from Reviewer C and pass it verbatim in `verificationClasses`/);
|
|
18
|
+
});
|
|
@@ -57,7 +57,15 @@ async function probeAndRegister(pi: ExtensionAPI): Promise<boolean> {
|
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
const models = await discoverModels();
|
|
60
|
-
if (models.length === 0)
|
|
60
|
+
if (models.length === 0) {
|
|
61
|
+
// No local models means there's nothing usable to register in GSD.
|
|
62
|
+
// Keep the footer/status clean instead of advertising Ollama availability.
|
|
63
|
+
if (providerRegistered) {
|
|
64
|
+
pi.unregisterProvider("ollama");
|
|
65
|
+
providerRegistered = false;
|
|
66
|
+
}
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
61
69
|
|
|
62
70
|
const baseUrl = client.getOllamaHost();
|
|
63
71
|
|
|
@@ -115,9 +123,11 @@ export default function ollama(pi: ExtensionAPI) {
|
|
|
115
123
|
} else {
|
|
116
124
|
probeAndRegister(pi)
|
|
117
125
|
.then((found) => {
|
|
118
|
-
|
|
126
|
+
ctx.ui.setStatus("ollama", found ? "Ollama" : undefined);
|
|
119
127
|
})
|
|
120
|
-
.catch(() => {
|
|
128
|
+
.catch(() => {
|
|
129
|
+
ctx.ui.setStatus("ollama", undefined);
|
|
130
|
+
});
|
|
121
131
|
}
|
|
122
132
|
});
|
|
123
133
|
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Regression test: don't show an Ollama footer status unless Ollama is
|
|
3
|
+
* actually usable (running with at least one discovered model).
|
|
4
|
+
*/
|
|
5
|
+
import { test } from "node:test";
|
|
6
|
+
import assert from "node:assert/strict";
|
|
7
|
+
import { readFileSync } from "node:fs";
|
|
8
|
+
import { join, dirname } from "node:path";
|
|
9
|
+
import { fileURLToPath } from "node:url";
|
|
10
|
+
|
|
11
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
12
|
+
const src = readFileSync(join(__dirname, "index.ts"), "utf-8");
|
|
13
|
+
|
|
14
|
+
test("probeAndRegister returns false when no Ollama models are discovered", () => {
|
|
15
|
+
assert.match(
|
|
16
|
+
src,
|
|
17
|
+
/if \(models\.length === 0\)[\s\S]*return false;/,
|
|
18
|
+
"running-without-models should not be treated as available",
|
|
19
|
+
);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
test("interactive session clears ollama footer status when unavailable", () => {
|
|
23
|
+
assert.match(
|
|
24
|
+
src,
|
|
25
|
+
/ctx\.ui\.setStatus\("ollama", found \? "Ollama" : undefined\)/,
|
|
26
|
+
"status should be cleared when probeAndRegister reports unavailable",
|
|
27
|
+
);
|
|
28
|
+
});
|
|
@@ -78,6 +78,8 @@ Based on the user's message, route directly to the appropriate workflow:
|
|
|
78
78
|
**If user intent is unclear, ask minimal clarifying questions:**
|
|
79
79
|
- "Create a MIDI skill" → "Task-execution skill (does MIDI tasks) or domain expertise (complete MIDI knowledge base)?"
|
|
80
80
|
- "Work on my skill" → "Which skill? What do you want to do with it?"
|
|
81
|
+
- Ask one clarifying question round at a time, then wait for the user's actual response before asking another.
|
|
82
|
+
- Never fabricate or simulate user responses while clarifying (for example, fake `[User]` markers or imagined answers).
|
|
81
83
|
|
|
82
84
|
Then proceed directly to the workflow.
|
|
83
85
|
</routing>
|
|
File without changes
|
|
File without changes
|