gsd-pi 2.28.0-dev.e19bf89 → 2.29.0-dev.23d50d0
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 +24 -17
- package/dist/cli.js +15 -9
- package/dist/headless.js +4 -0
- package/dist/resource-loader.js +80 -8
- package/dist/resources/extensions/bg-shell/process-manager.ts +13 -0
- package/dist/resources/extensions/gsd/auto-dashboard.ts +217 -65
- package/dist/resources/extensions/gsd/auto-dispatch.ts +2 -2
- package/dist/resources/extensions/gsd/auto-post-unit.ts +53 -6
- package/dist/resources/extensions/gsd/auto-prompts.ts +27 -14
- package/dist/resources/extensions/gsd/auto-recovery.ts +33 -23
- package/dist/resources/extensions/gsd/auto-start.ts +25 -10
- package/dist/resources/extensions/gsd/auto-verification.ts +41 -7
- package/dist/resources/extensions/gsd/auto-worktree-sync.ts +21 -6
- package/dist/resources/extensions/gsd/auto-worktree.ts +9 -0
- package/dist/resources/extensions/gsd/auto.ts +67 -22
- package/dist/resources/extensions/gsd/commands-handlers.ts +3 -11
- package/dist/resources/extensions/gsd/commands-logs.ts +536 -0
- package/dist/resources/extensions/gsd/commands-prefs-wizard.ts +90 -47
- package/dist/resources/extensions/gsd/commands-workflow-templates.ts +544 -0
- package/dist/resources/extensions/gsd/commands.ts +75 -29
- package/dist/resources/extensions/gsd/dashboard-overlay.ts +2 -1
- package/dist/resources/extensions/gsd/doctor-types.ts +13 -0
- package/dist/resources/extensions/gsd/doctor.ts +2 -6
- package/dist/resources/extensions/gsd/export.ts +28 -2
- package/dist/resources/extensions/gsd/gsd-db.ts +19 -0
- package/dist/resources/extensions/gsd/index.ts +2 -1
- package/dist/resources/extensions/gsd/json-persistence.ts +67 -0
- package/dist/resources/extensions/gsd/mechanical-completion.ts +430 -0
- package/dist/resources/extensions/gsd/metrics.ts +17 -31
- package/dist/resources/extensions/gsd/paths.ts +17 -8
- package/dist/resources/extensions/gsd/preferences-models.ts +7 -1
- package/dist/resources/extensions/gsd/preferences-validation.ts +2 -1
- package/dist/resources/extensions/gsd/prompts/discuss-headless.md +4 -2
- package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/plan-milestone.md +26 -2
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +15 -1
- package/dist/resources/extensions/gsd/prompts/workflow-start.md +28 -0
- package/dist/resources/extensions/gsd/queue-order.ts +10 -11
- package/dist/resources/extensions/gsd/routing-history.ts +13 -17
- package/dist/resources/extensions/gsd/session-lock.ts +284 -0
- package/dist/resources/extensions/gsd/session-status-io.ts +23 -41
- package/dist/resources/extensions/gsd/tests/auto-budget-alerts.test.ts +1 -1
- package/dist/resources/extensions/gsd/tests/auto-skip-loop.test.ts +1 -1
- package/dist/resources/extensions/gsd/tests/commands-logs.test.ts +241 -0
- package/dist/resources/extensions/gsd/tests/extension-selector-separator.test.ts +60 -38
- package/dist/resources/extensions/gsd/tests/gsd-inspect.test.ts +1 -1
- package/dist/resources/extensions/gsd/tests/mechanical-completion.test.ts +356 -0
- package/dist/resources/extensions/gsd/tests/parallel-workers-multi-milestone-e2e.test.ts +1 -1
- package/dist/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +1 -0
- package/dist/resources/extensions/gsd/tests/session-lock.test.ts +315 -0
- package/dist/resources/extensions/gsd/tests/token-profile.test.ts +14 -16
- package/dist/resources/extensions/gsd/tests/validate-milestone.test.ts +55 -0
- package/dist/resources/extensions/gsd/tests/verification-evidence.test.ts +26 -24
- package/dist/resources/extensions/gsd/tests/verification-gate.test.ts +136 -7
- package/dist/resources/extensions/gsd/tests/workflow-templates.test.ts +173 -0
- package/dist/resources/extensions/gsd/types.ts +3 -0
- package/dist/resources/extensions/gsd/unit-runtime.ts +16 -13
- package/dist/resources/extensions/gsd/verification-evidence.ts +2 -0
- package/dist/resources/extensions/gsd/verification-gate.ts +13 -2
- package/dist/resources/extensions/gsd/workflow-templates/bugfix.md +87 -0
- package/dist/resources/extensions/gsd/workflow-templates/dep-upgrade.md +74 -0
- package/dist/resources/extensions/gsd/workflow-templates/full-project.md +41 -0
- package/dist/resources/extensions/gsd/workflow-templates/hotfix.md +45 -0
- package/dist/resources/extensions/gsd/workflow-templates/refactor.md +83 -0
- package/dist/resources/extensions/gsd/workflow-templates/registry.json +85 -0
- package/dist/resources/extensions/gsd/workflow-templates/security-audit.md +73 -0
- package/dist/resources/extensions/gsd/workflow-templates/small-feature.md +81 -0
- package/dist/resources/extensions/gsd/workflow-templates/spike.md +69 -0
- package/dist/resources/extensions/gsd/workflow-templates.ts +241 -0
- package/dist/resources/extensions/mcp-client/index.ts +459 -0
- package/dist/resources/extensions/remote-questions/discord-adapter.ts +9 -20
- package/dist/resources/extensions/remote-questions/http-client.ts +76 -0
- package/dist/resources/extensions/remote-questions/notify.ts +1 -2
- package/dist/resources/extensions/remote-questions/slack-adapter.ts +11 -18
- package/dist/resources/extensions/remote-questions/telegram-adapter.ts +8 -20
- package/dist/resources/extensions/remote-questions/types.ts +3 -0
- package/dist/resources/extensions/shared/mod.ts +3 -0
- package/dist/resources/skills/create-gsd-extension/SKILL.md +87 -0
- package/dist/resources/skills/create-gsd-extension/references/compaction-session-control.md +77 -0
- package/dist/resources/skills/create-gsd-extension/references/custom-commands.md +139 -0
- package/dist/resources/skills/create-gsd-extension/references/custom-rendering.md +108 -0
- package/dist/resources/skills/create-gsd-extension/references/custom-tools.md +183 -0
- package/dist/resources/skills/create-gsd-extension/references/custom-ui.md +490 -0
- package/dist/resources/skills/create-gsd-extension/references/events-reference.md +126 -0
- package/dist/resources/skills/create-gsd-extension/references/extension-lifecycle.md +64 -0
- package/dist/resources/skills/create-gsd-extension/references/extensionapi-reference.md +75 -0
- package/dist/resources/skills/create-gsd-extension/references/extensioncontext-reference.md +53 -0
- package/dist/resources/skills/create-gsd-extension/references/key-rules-gotchas.md +36 -0
- package/dist/resources/skills/create-gsd-extension/references/mode-behavior.md +32 -0
- package/dist/resources/skills/create-gsd-extension/references/model-provider-management.md +89 -0
- package/dist/resources/skills/create-gsd-extension/references/packaging-distribution.md +55 -0
- package/dist/resources/skills/create-gsd-extension/references/remote-execution-overrides.md +90 -0
- package/dist/resources/skills/create-gsd-extension/references/state-management.md +70 -0
- package/dist/resources/skills/create-gsd-extension/references/system-prompt-modification.md +52 -0
- package/dist/resources/skills/create-gsd-extension/templates/extension-skeleton.ts +51 -0
- package/dist/resources/skills/create-gsd-extension/templates/stateful-tool-skeleton.ts +143 -0
- package/dist/resources/skills/create-gsd-extension/workflows/add-capability.md +57 -0
- package/dist/resources/skills/create-gsd-extension/workflows/create-extension.md +156 -0
- package/dist/resources/skills/create-gsd-extension/workflows/debug-extension.md +74 -0
- package/dist/resources/skills/create-skill/SKILL.md +184 -0
- package/dist/resources/skills/create-skill/references/api-security.md +226 -0
- package/dist/resources/skills/create-skill/references/be-clear-and-direct.md +531 -0
- package/dist/resources/skills/create-skill/references/common-patterns.md +595 -0
- package/dist/resources/skills/create-skill/references/core-principles.md +437 -0
- package/dist/resources/skills/create-skill/references/executable-code.md +175 -0
- package/dist/resources/skills/create-skill/references/gsd-skill-ecosystem.md +68 -0
- package/dist/resources/skills/create-skill/references/iteration-and-testing.md +474 -0
- package/dist/resources/skills/create-skill/references/recommended-structure.md +168 -0
- package/dist/resources/skills/create-skill/references/skill-structure.md +372 -0
- package/dist/resources/skills/create-skill/references/use-xml-tags.md +466 -0
- package/dist/resources/skills/create-skill/references/using-scripts.md +113 -0
- package/dist/resources/skills/create-skill/references/using-templates.md +112 -0
- package/dist/resources/skills/create-skill/references/workflows-and-validation.md +510 -0
- package/dist/resources/skills/create-skill/templates/router-skill.md +73 -0
- package/dist/resources/skills/create-skill/templates/simple-skill.md +33 -0
- package/dist/resources/skills/create-skill/workflows/add-reference.md +96 -0
- package/dist/resources/skills/create-skill/workflows/add-script.md +93 -0
- package/dist/resources/skills/create-skill/workflows/add-template.md +74 -0
- package/dist/resources/skills/create-skill/workflows/add-workflow.md +120 -0
- package/dist/resources/skills/create-skill/workflows/audit-skill.md +148 -0
- package/dist/resources/skills/create-skill/workflows/create-new-skill.md +196 -0
- package/dist/resources/skills/create-skill/workflows/get-guidance.md +121 -0
- package/dist/resources/skills/create-skill/workflows/upgrade-to-router.md +161 -0
- package/dist/resources/skills/create-skill/workflows/verify-skill.md +204 -0
- package/package.json +6 -3
- package/packages/native/dist/native.d.ts +2 -0
- package/packages/native/dist/native.js +19 -5
- package/packages/native/src/native.ts +23 -9
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.js +13 -0
- package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/client.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/client.js +3 -0
- package/packages/pi-coding-agent/dist/core/lsp/client.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +3 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.js +8 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/system-prompt.js +10 -0
- package/packages/pi-coding-agent/dist/core/system-prompt.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 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/scripts/copy-assets.cjs +39 -8
- package/packages/pi-coding-agent/src/core/extensions/loader.ts +13 -0
- package/packages/pi-coding-agent/src/core/lsp/client.ts +3 -0
- package/packages/pi-coding-agent/src/core/settings-manager.ts +11 -0
- package/packages/pi-coding-agent/src/core/system-prompt.ts +11 -0
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +4 -1
- package/packages/pi-tui/dist/autocomplete.d.ts +3 -0
- package/packages/pi-tui/dist/autocomplete.d.ts.map +1 -1
- package/packages/pi-tui/dist/autocomplete.js +14 -0
- package/packages/pi-tui/dist/autocomplete.js.map +1 -1
- package/packages/pi-tui/src/autocomplete.ts +19 -1
- package/pkg/package.json +1 -1
- package/src/resources/extensions/bg-shell/process-manager.ts +13 -0
- package/src/resources/extensions/gsd/auto-dashboard.ts +217 -65
- package/src/resources/extensions/gsd/auto-dispatch.ts +2 -2
- package/src/resources/extensions/gsd/auto-post-unit.ts +53 -6
- package/src/resources/extensions/gsd/auto-prompts.ts +27 -14
- package/src/resources/extensions/gsd/auto-recovery.ts +33 -23
- package/src/resources/extensions/gsd/auto-start.ts +25 -10
- package/src/resources/extensions/gsd/auto-verification.ts +41 -7
- package/src/resources/extensions/gsd/auto-worktree-sync.ts +21 -6
- package/src/resources/extensions/gsd/auto-worktree.ts +9 -0
- package/src/resources/extensions/gsd/auto.ts +67 -22
- package/src/resources/extensions/gsd/commands-handlers.ts +3 -11
- package/src/resources/extensions/gsd/commands-logs.ts +536 -0
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +90 -47
- package/src/resources/extensions/gsd/commands-workflow-templates.ts +544 -0
- package/src/resources/extensions/gsd/commands.ts +75 -29
- package/src/resources/extensions/gsd/dashboard-overlay.ts +2 -1
- package/src/resources/extensions/gsd/doctor-types.ts +13 -0
- package/src/resources/extensions/gsd/doctor.ts +2 -6
- package/src/resources/extensions/gsd/export.ts +28 -2
- package/src/resources/extensions/gsd/gsd-db.ts +19 -0
- package/src/resources/extensions/gsd/index.ts +2 -1
- package/src/resources/extensions/gsd/json-persistence.ts +67 -0
- package/src/resources/extensions/gsd/mechanical-completion.ts +430 -0
- package/src/resources/extensions/gsd/metrics.ts +17 -31
- package/src/resources/extensions/gsd/paths.ts +17 -8
- package/src/resources/extensions/gsd/preferences-models.ts +7 -1
- package/src/resources/extensions/gsd/preferences-validation.ts +2 -1
- package/src/resources/extensions/gsd/prompts/discuss-headless.md +4 -2
- package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/plan-milestone.md +26 -2
- package/src/resources/extensions/gsd/prompts/plan-slice.md +15 -1
- package/src/resources/extensions/gsd/prompts/workflow-start.md +28 -0
- package/src/resources/extensions/gsd/queue-order.ts +10 -11
- package/src/resources/extensions/gsd/routing-history.ts +13 -17
- package/src/resources/extensions/gsd/session-lock.ts +284 -0
- package/src/resources/extensions/gsd/session-status-io.ts +23 -41
- package/src/resources/extensions/gsd/tests/auto-budget-alerts.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/auto-skip-loop.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/commands-logs.test.ts +241 -0
- package/src/resources/extensions/gsd/tests/extension-selector-separator.test.ts +60 -38
- package/src/resources/extensions/gsd/tests/gsd-inspect.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/mechanical-completion.test.ts +356 -0
- package/src/resources/extensions/gsd/tests/parallel-workers-multi-milestone-e2e.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/session-lock.test.ts +315 -0
- package/src/resources/extensions/gsd/tests/token-profile.test.ts +14 -16
- package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/verification-evidence.test.ts +26 -24
- package/src/resources/extensions/gsd/tests/verification-gate.test.ts +136 -7
- package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +173 -0
- package/src/resources/extensions/gsd/types.ts +3 -0
- package/src/resources/extensions/gsd/unit-runtime.ts +16 -13
- package/src/resources/extensions/gsd/verification-evidence.ts +2 -0
- package/src/resources/extensions/gsd/verification-gate.ts +13 -2
- package/src/resources/extensions/gsd/workflow-templates/bugfix.md +87 -0
- package/src/resources/extensions/gsd/workflow-templates/dep-upgrade.md +74 -0
- package/src/resources/extensions/gsd/workflow-templates/full-project.md +41 -0
- package/src/resources/extensions/gsd/workflow-templates/hotfix.md +45 -0
- package/src/resources/extensions/gsd/workflow-templates/refactor.md +83 -0
- package/src/resources/extensions/gsd/workflow-templates/registry.json +85 -0
- package/src/resources/extensions/gsd/workflow-templates/security-audit.md +73 -0
- package/src/resources/extensions/gsd/workflow-templates/small-feature.md +81 -0
- package/src/resources/extensions/gsd/workflow-templates/spike.md +69 -0
- package/src/resources/extensions/gsd/workflow-templates.ts +241 -0
- package/src/resources/extensions/mcp-client/index.ts +459 -0
- package/src/resources/extensions/remote-questions/discord-adapter.ts +9 -20
- package/src/resources/extensions/remote-questions/http-client.ts +76 -0
- package/src/resources/extensions/remote-questions/notify.ts +1 -2
- package/src/resources/extensions/remote-questions/slack-adapter.ts +11 -18
- package/src/resources/extensions/remote-questions/telegram-adapter.ts +8 -20
- package/src/resources/extensions/remote-questions/types.ts +3 -0
- package/src/resources/extensions/shared/mod.ts +3 -0
- package/src/resources/skills/create-gsd-extension/SKILL.md +87 -0
- package/src/resources/skills/create-gsd-extension/references/compaction-session-control.md +77 -0
- package/src/resources/skills/create-gsd-extension/references/custom-commands.md +139 -0
- package/src/resources/skills/create-gsd-extension/references/custom-rendering.md +108 -0
- package/src/resources/skills/create-gsd-extension/references/custom-tools.md +183 -0
- package/src/resources/skills/create-gsd-extension/references/custom-ui.md +490 -0
- package/src/resources/skills/create-gsd-extension/references/events-reference.md +126 -0
- package/src/resources/skills/create-gsd-extension/references/extension-lifecycle.md +64 -0
- package/src/resources/skills/create-gsd-extension/references/extensionapi-reference.md +75 -0
- package/src/resources/skills/create-gsd-extension/references/extensioncontext-reference.md +53 -0
- package/src/resources/skills/create-gsd-extension/references/key-rules-gotchas.md +36 -0
- package/src/resources/skills/create-gsd-extension/references/mode-behavior.md +32 -0
- package/src/resources/skills/create-gsd-extension/references/model-provider-management.md +89 -0
- package/src/resources/skills/create-gsd-extension/references/packaging-distribution.md +55 -0
- package/src/resources/skills/create-gsd-extension/references/remote-execution-overrides.md +90 -0
- package/src/resources/skills/create-gsd-extension/references/state-management.md +70 -0
- package/src/resources/skills/create-gsd-extension/references/system-prompt-modification.md +52 -0
- package/src/resources/skills/create-gsd-extension/templates/extension-skeleton.ts +51 -0
- package/src/resources/skills/create-gsd-extension/templates/stateful-tool-skeleton.ts +143 -0
- package/src/resources/skills/create-gsd-extension/workflows/add-capability.md +57 -0
- package/src/resources/skills/create-gsd-extension/workflows/create-extension.md +156 -0
- package/src/resources/skills/create-gsd-extension/workflows/debug-extension.md +74 -0
- package/src/resources/skills/create-skill/SKILL.md +184 -0
- package/src/resources/skills/create-skill/references/api-security.md +226 -0
- package/src/resources/skills/create-skill/references/be-clear-and-direct.md +531 -0
- package/src/resources/skills/create-skill/references/common-patterns.md +595 -0
- package/src/resources/skills/create-skill/references/core-principles.md +437 -0
- package/src/resources/skills/create-skill/references/executable-code.md +175 -0
- package/src/resources/skills/create-skill/references/gsd-skill-ecosystem.md +68 -0
- package/src/resources/skills/create-skill/references/iteration-and-testing.md +474 -0
- package/src/resources/skills/create-skill/references/recommended-structure.md +168 -0
- package/src/resources/skills/create-skill/references/skill-structure.md +372 -0
- package/src/resources/skills/create-skill/references/use-xml-tags.md +466 -0
- package/src/resources/skills/create-skill/references/using-scripts.md +113 -0
- package/src/resources/skills/create-skill/references/using-templates.md +112 -0
- package/src/resources/skills/create-skill/references/workflows-and-validation.md +510 -0
- package/src/resources/skills/create-skill/templates/router-skill.md +73 -0
- package/src/resources/skills/create-skill/templates/simple-skill.md +33 -0
- package/src/resources/skills/create-skill/workflows/add-reference.md +96 -0
- package/src/resources/skills/create-skill/workflows/add-script.md +93 -0
- package/src/resources/skills/create-skill/workflows/add-template.md +74 -0
- package/src/resources/skills/create-skill/workflows/add-workflow.md +120 -0
- package/src/resources/skills/create-skill/workflows/audit-skill.md +148 -0
- package/src/resources/skills/create-skill/workflows/create-new-skill.md +196 -0
- package/src/resources/skills/create-skill/workflows/get-guidance.md +121 -0
- package/src/resources/skills/create-skill/workflows/upgrade-to-router.md +161 -0
- package/src/resources/skills/create-skill/workflows/verify-skill.md +204 -0
- package/dist/resources/extensions/gsd/preferences-hooks.ts +0 -10
- package/dist/resources/extensions/mcporter/index.ts +0 -525
- package/dist/resources/extensions/shared/progress-widget.ts +0 -282
- package/dist/resources/extensions/shared/thinking-widget.ts +0 -107
- package/src/resources/extensions/gsd/preferences-hooks.ts +0 -10
- package/src/resources/extensions/mcporter/index.ts +0 -525
- package/src/resources/extensions/shared/progress-widget.ts +0 -282
- package/src/resources/extensions/shared/thinking-widget.ts +0 -107
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import test from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { mkdirSync, mkdtempSync, writeFileSync, rmSync, existsSync, utimesSync } from "node:fs";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { tmpdir } from "node:os";
|
|
6
|
+
|
|
7
|
+
import { handleLogs } from "../commands-logs.ts";
|
|
8
|
+
|
|
9
|
+
// ─── Test helpers ───────────────────────────────────────────────────────────
|
|
10
|
+
|
|
11
|
+
function createTestDir(): string {
|
|
12
|
+
const dir = mkdtempSync(join(tmpdir(), "gsd-logs-test-"));
|
|
13
|
+
mkdirSync(join(dir, ".gsd", "activity"), { recursive: true });
|
|
14
|
+
mkdirSync(join(dir, ".gsd", "debug"), { recursive: true });
|
|
15
|
+
return dir;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function createMockCtx(): { notifications: Array<{ msg: string; level: string }>; ui: any } {
|
|
19
|
+
const notifications: Array<{ msg: string; level: string }> = [];
|
|
20
|
+
return {
|
|
21
|
+
notifications,
|
|
22
|
+
ui: {
|
|
23
|
+
notify(msg: string, level: string) { notifications.push({ msg, level }); },
|
|
24
|
+
setStatus() {},
|
|
25
|
+
setWidget() {},
|
|
26
|
+
setFooter() {},
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function writeActivityLog(dir: string, seq: number, unitType: string, unitId: string, entries: Record<string, unknown>[]): void {
|
|
32
|
+
const safeId = unitId.replace(/\//g, "-");
|
|
33
|
+
const filename = `${String(seq).padStart(3, "0")}-${unitType}-${safeId}.jsonl`;
|
|
34
|
+
const content = entries.map(e => JSON.stringify(e)).join("\n") + "\n";
|
|
35
|
+
writeFileSync(join(dir, ".gsd", "activity", filename), content);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function writeDebugLog(dir: string, name: string, entries: Record<string, unknown>[]): void {
|
|
39
|
+
const content = entries.map(e => JSON.stringify(e)).join("\n") + "\n";
|
|
40
|
+
writeFileSync(join(dir, ".gsd", "debug", name), content);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// ─── Tests ──────────────────────────────────────────────────────────────────
|
|
44
|
+
|
|
45
|
+
test("logs shows empty state message when no logs exist", async () => {
|
|
46
|
+
const dir = createTestDir();
|
|
47
|
+
const ctx = createMockCtx();
|
|
48
|
+
const origCwd = process.cwd();
|
|
49
|
+
process.chdir(dir);
|
|
50
|
+
try {
|
|
51
|
+
await handleLogs("", ctx as any);
|
|
52
|
+
assert.equal(ctx.notifications.length, 1);
|
|
53
|
+
assert.ok(ctx.notifications[0].msg.includes("No logs found"));
|
|
54
|
+
} finally {
|
|
55
|
+
process.chdir(origCwd);
|
|
56
|
+
rmSync(dir, { recursive: true, force: true });
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
test("logs lists activity logs", async () => {
|
|
61
|
+
const dir = createTestDir();
|
|
62
|
+
const ctx = createMockCtx();
|
|
63
|
+
const origCwd = process.cwd();
|
|
64
|
+
process.chdir(dir);
|
|
65
|
+
|
|
66
|
+
writeActivityLog(dir, 1, "execute-task", "M001/S01/T01", [
|
|
67
|
+
{ type: "toolCall", name: "bash", arguments: { command: "npm test" } },
|
|
68
|
+
{ role: "toolResult", toolCallId: "1", toolName: "bash", isError: false },
|
|
69
|
+
]);
|
|
70
|
+
writeActivityLog(dir, 2, "complete-slice", "M001/S01", [
|
|
71
|
+
{ role: "assistant", content: "Completing slice S01" },
|
|
72
|
+
]);
|
|
73
|
+
|
|
74
|
+
try {
|
|
75
|
+
await handleLogs("", ctx as any);
|
|
76
|
+
assert.equal(ctx.notifications.length, 1);
|
|
77
|
+
const msg = ctx.notifications[0].msg;
|
|
78
|
+
assert.ok(msg.includes("Activity Logs"), "should show activity logs header");
|
|
79
|
+
assert.ok(msg.includes("execute-task"), "should show unit type");
|
|
80
|
+
assert.ok(msg.includes("complete-slice"), "should show second log");
|
|
81
|
+
assert.ok(msg.includes("/gsd logs <#>"), "should show usage hint");
|
|
82
|
+
} finally {
|
|
83
|
+
process.chdir(origCwd);
|
|
84
|
+
rmSync(dir, { recursive: true, force: true });
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
test("logs <N> shows activity log details", async () => {
|
|
89
|
+
const dir = createTestDir();
|
|
90
|
+
const ctx = createMockCtx();
|
|
91
|
+
const origCwd = process.cwd();
|
|
92
|
+
process.chdir(dir);
|
|
93
|
+
|
|
94
|
+
writeActivityLog(dir, 1, "execute-task", "M001/S01/T01", [
|
|
95
|
+
{ type: "toolCall", name: "bash", arguments: { command: "npm test" } },
|
|
96
|
+
{ type: "toolCall", name: "write", arguments: { file_path: "/tmp/test.ts" } },
|
|
97
|
+
{ role: "toolResult", toolCallId: "1", toolName: "bash", isError: false },
|
|
98
|
+
{ role: "toolResult", toolCallId: "2", toolName: "write", isError: true },
|
|
99
|
+
{ role: "assistant", content: "I ran the tests and wrote a file" },
|
|
100
|
+
]);
|
|
101
|
+
|
|
102
|
+
try {
|
|
103
|
+
await handleLogs("1", ctx as any);
|
|
104
|
+
assert.equal(ctx.notifications.length, 1);
|
|
105
|
+
const msg = ctx.notifications[0].msg;
|
|
106
|
+
assert.ok(msg.includes("Activity Log #1"), "should show log number");
|
|
107
|
+
assert.ok(msg.includes("execute-task"), "should show unit type");
|
|
108
|
+
assert.ok(msg.includes("Tool calls: 2"), "should count tool calls");
|
|
109
|
+
assert.ok(msg.includes("Errors: 1"), "should count errors");
|
|
110
|
+
assert.ok(msg.includes("/tmp/test.ts"), "should show files written");
|
|
111
|
+
assert.ok(msg.includes("npm test"), "should show commands run");
|
|
112
|
+
} finally {
|
|
113
|
+
process.chdir(origCwd);
|
|
114
|
+
rmSync(dir, { recursive: true, force: true });
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
test("logs <N> shows not found for invalid seq", async () => {
|
|
119
|
+
const dir = createTestDir();
|
|
120
|
+
const ctx = createMockCtx();
|
|
121
|
+
const origCwd = process.cwd();
|
|
122
|
+
process.chdir(dir);
|
|
123
|
+
|
|
124
|
+
try {
|
|
125
|
+
await handleLogs("999", ctx as any);
|
|
126
|
+
assert.equal(ctx.notifications.length, 1);
|
|
127
|
+
assert.ok(ctx.notifications[0].msg.includes("not found"));
|
|
128
|
+
assert.equal(ctx.notifications[0].level, "warning");
|
|
129
|
+
} finally {
|
|
130
|
+
process.chdir(origCwd);
|
|
131
|
+
rmSync(dir, { recursive: true, force: true });
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
test("logs debug lists debug logs", async () => {
|
|
136
|
+
const dir = createTestDir();
|
|
137
|
+
const ctx = createMockCtx();
|
|
138
|
+
const origCwd = process.cwd();
|
|
139
|
+
process.chdir(dir);
|
|
140
|
+
|
|
141
|
+
writeDebugLog(dir, "debug-2026-03-18T10-30-00.log", [
|
|
142
|
+
{ ts: "2026-03-18T10:30:00Z", event: "debug-start", platform: "darwin" },
|
|
143
|
+
{ ts: "2026-03-18T10:35:00Z", event: "debug-summary", dispatches: 5 },
|
|
144
|
+
]);
|
|
145
|
+
|
|
146
|
+
try {
|
|
147
|
+
await handleLogs("debug", ctx as any);
|
|
148
|
+
assert.equal(ctx.notifications.length, 1);
|
|
149
|
+
const msg = ctx.notifications[0].msg;
|
|
150
|
+
assert.ok(msg.includes("Debug Logs"), "should show debug logs header");
|
|
151
|
+
assert.ok(msg.includes("debug-2026-03-18T10-30-00.log"), "should show filename");
|
|
152
|
+
} finally {
|
|
153
|
+
process.chdir(origCwd);
|
|
154
|
+
rmSync(dir, { recursive: true, force: true });
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
test("logs debug <N> shows debug log summary", async () => {
|
|
159
|
+
const dir = createTestDir();
|
|
160
|
+
const ctx = createMockCtx();
|
|
161
|
+
const origCwd = process.cwd();
|
|
162
|
+
process.chdir(dir);
|
|
163
|
+
|
|
164
|
+
writeDebugLog(dir, "debug-2026-03-18T10-30-00.log", [
|
|
165
|
+
{ ts: "2026-03-18T10:30:00Z", event: "debug-start", platform: "darwin" },
|
|
166
|
+
{ ts: "2026-03-18T10:30:05Z", event: "dispatch-error", error: "missing plan" },
|
|
167
|
+
{ ts: "2026-03-18T10:35:00Z", event: "debug-summary", dispatches: 5 },
|
|
168
|
+
]);
|
|
169
|
+
|
|
170
|
+
try {
|
|
171
|
+
await handleLogs("debug 1", ctx as any);
|
|
172
|
+
assert.equal(ctx.notifications.length, 1);
|
|
173
|
+
const msg = ctx.notifications[0].msg;
|
|
174
|
+
assert.ok(msg.includes("Debug Log:"), "should show debug log header");
|
|
175
|
+
assert.ok(msg.includes("Events: 3"), "should count events");
|
|
176
|
+
assert.ok(msg.includes("Dispatches: 5"), "should show dispatch count");
|
|
177
|
+
assert.ok(msg.includes("dispatch-error"), "should show errors");
|
|
178
|
+
} finally {
|
|
179
|
+
process.chdir(origCwd);
|
|
180
|
+
rmSync(dir, { recursive: true, force: true });
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
test("logs tail shows recent activity summaries", async () => {
|
|
185
|
+
const dir = createTestDir();
|
|
186
|
+
const ctx = createMockCtx();
|
|
187
|
+
const origCwd = process.cwd();
|
|
188
|
+
process.chdir(dir);
|
|
189
|
+
|
|
190
|
+
writeActivityLog(dir, 1, "execute-task", "M001/S01/T01", [
|
|
191
|
+
{ type: "toolCall", name: "bash", arguments: { command: "npm test" } },
|
|
192
|
+
]);
|
|
193
|
+
writeActivityLog(dir, 2, "execute-task", "M001/S01/T02", [
|
|
194
|
+
{ type: "toolCall", name: "bash", arguments: { command: "npm build" } },
|
|
195
|
+
{ role: "toolResult", toolCallId: "1", toolName: "bash", isError: true },
|
|
196
|
+
]);
|
|
197
|
+
|
|
198
|
+
try {
|
|
199
|
+
await handleLogs("tail 2", ctx as any);
|
|
200
|
+
assert.equal(ctx.notifications.length, 1);
|
|
201
|
+
const msg = ctx.notifications[0].msg;
|
|
202
|
+
assert.ok(msg.includes("Last 2 activity log(s)"), "should show count");
|
|
203
|
+
assert.ok(msg.includes("#1"), "should show first log");
|
|
204
|
+
assert.ok(msg.includes("#2"), "should show second log");
|
|
205
|
+
} finally {
|
|
206
|
+
process.chdir(origCwd);
|
|
207
|
+
rmSync(dir, { recursive: true, force: true });
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
test("logs clear removes old logs", async () => {
|
|
212
|
+
const dir = createTestDir();
|
|
213
|
+
const ctx = createMockCtx();
|
|
214
|
+
const origCwd = process.cwd();
|
|
215
|
+
process.chdir(dir);
|
|
216
|
+
|
|
217
|
+
// Create an old activity log (modify mtime to 10 days ago)
|
|
218
|
+
writeActivityLog(dir, 1, "execute-task", "M001/S01/T01", [{ type: "toolCall" }]);
|
|
219
|
+
const oldFile = join(dir, ".gsd", "activity", "001-execute-task-M001-S01-T01.jsonl");
|
|
220
|
+
const oldTime = new Date(Date.now() - 10 * 24 * 60 * 60 * 1000);
|
|
221
|
+
utimesSync(oldFile, oldTime, oldTime);
|
|
222
|
+
|
|
223
|
+
// Create 6 recent activity logs so the old one is outside the "keep 5" window
|
|
224
|
+
for (let i = 2; i <= 7; i++) {
|
|
225
|
+
writeActivityLog(dir, i, "execute-task", `M001/S01/T0${i}`, [{ type: "toolCall" }]);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
try {
|
|
229
|
+
await handleLogs("clear", ctx as any);
|
|
230
|
+
assert.equal(ctx.notifications.length, 1);
|
|
231
|
+
// Old log should be removed, recent ones kept
|
|
232
|
+
assert.ok(!existsSync(oldFile), "old log should be removed");
|
|
233
|
+
assert.ok(
|
|
234
|
+
existsSync(join(dir, ".gsd", "activity", "007-execute-task-M001-S01-T07.jsonl")),
|
|
235
|
+
"most recent log should be kept",
|
|
236
|
+
);
|
|
237
|
+
} finally {
|
|
238
|
+
process.chdir(origCwd);
|
|
239
|
+
rmSync(dir, { recursive: true, force: true });
|
|
240
|
+
}
|
|
241
|
+
});
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
// Tests for the SEPARATOR_PREFIX convention used by ExtensionSelectorComponent
|
|
1
|
+
// Tests for the SEPARATOR_PREFIX convention used by ExtensionSelectorComponent
|
|
2
|
+
// and the two-step provider→model picker in configureModels.
|
|
3
|
+
//
|
|
2
4
|
// We cannot import the component directly in node:test because its transitive
|
|
3
5
|
// dependency (countdown-timer.ts) uses TypeScript parameter properties which
|
|
4
6
|
// are unsupported under --experimental-strip-types. Instead we duplicate the
|
|
@@ -69,16 +71,17 @@ describe("separator detection", () => {
|
|
|
69
71
|
});
|
|
70
72
|
});
|
|
71
73
|
|
|
72
|
-
describe("model
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
74
|
+
describe("two-step provider→model picker", () => {
|
|
75
|
+
// Simulate the grouping logic from configureModels
|
|
76
|
+
const availableModels = [
|
|
77
|
+
{ id: "claude-opus-4-6", provider: "anthropic" },
|
|
78
|
+
{ id: "gpt-4o", provider: "openai" },
|
|
79
|
+
{ id: "claude-sonnet-4-5", provider: "anthropic" },
|
|
80
|
+
{ id: "o3-mini", provider: "openai" },
|
|
81
|
+
{ id: "claude-haiku-4-5", provider: "anthropic" },
|
|
82
|
+
];
|
|
81
83
|
|
|
84
|
+
function buildProviderGroups() {
|
|
82
85
|
const byProvider = new Map<string, typeof availableModels>();
|
|
83
86
|
for (const m of availableModels) {
|
|
84
87
|
let group = byProvider.get(m.provider);
|
|
@@ -89,34 +92,53 @@ describe("model grouping", () => {
|
|
|
89
92
|
group.push(m);
|
|
90
93
|
}
|
|
91
94
|
const providers = Array.from(byProvider.keys()).sort((a, b) => a.localeCompare(b));
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
for (const provider of providers) {
|
|
95
|
-
const group = byProvider.get(provider)!;
|
|
96
|
-
modelOptions.push(`${SEPARATOR_PREFIX} ${provider} (${group.length}) ${SEPARATOR_PREFIX}`);
|
|
97
|
-
for (const m of group) {
|
|
98
|
-
modelOptions.push(`${m.id} · ${m.provider}`);
|
|
99
|
-
}
|
|
95
|
+
for (const group of byProvider.values()) {
|
|
96
|
+
group.sort((a, b) => a.id.localeCompare(b.id));
|
|
100
97
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
assert.
|
|
115
|
-
assert.
|
|
116
|
-
assert.
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
98
|
+
return { byProvider, providers };
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
test("provider menu lists providers with model counts", () => {
|
|
102
|
+
const { providers, byProvider } = buildProviderGroups();
|
|
103
|
+
const providerOptions = providers.map(p => {
|
|
104
|
+
const count = byProvider.get(p)!.length;
|
|
105
|
+
return `${p} (${count} models)`;
|
|
106
|
+
});
|
|
107
|
+
providerOptions.push("(keep current)", "(clear)", "(type manually)");
|
|
108
|
+
|
|
109
|
+
assert.strictEqual(providerOptions[0], "anthropic (3 models)");
|
|
110
|
+
assert.strictEqual(providerOptions[1], "openai (2 models)");
|
|
111
|
+
assert.strictEqual(providerOptions[2], "(keep current)");
|
|
112
|
+
assert.strictEqual(providerOptions[3], "(clear)");
|
|
113
|
+
assert.strictEqual(providerOptions[4], "(type manually)");
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
test("model menu for a provider is sorted alphabetically", () => {
|
|
117
|
+
const { byProvider } = buildProviderGroups();
|
|
118
|
+
const anthropicModels = byProvider.get("anthropic")!;
|
|
119
|
+
const modelOptions = anthropicModels.map(m => m.id);
|
|
120
|
+
|
|
121
|
+
assert.strictEqual(modelOptions[0], "claude-haiku-4-5");
|
|
122
|
+
assert.strictEqual(modelOptions[1], "claude-opus-4-6");
|
|
123
|
+
assert.strictEqual(modelOptions[2], "claude-sonnet-4-5");
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
test("provider name is extracted correctly from choice string", () => {
|
|
127
|
+
const choice = "anthropic (3 models)";
|
|
128
|
+
const providerName = choice.replace(/ \(\d+ models?\)$/, "");
|
|
129
|
+
assert.strictEqual(providerName, "anthropic");
|
|
130
|
+
|
|
131
|
+
const singleChoice = "ollama (1 model)";
|
|
132
|
+
const singleProvider = singleChoice.replace(/ \(\d+ models?\)$/, "");
|
|
133
|
+
assert.strictEqual(singleProvider, "ollama");
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
test("openai models are sorted within their group", () => {
|
|
137
|
+
const { byProvider } = buildProviderGroups();
|
|
138
|
+
const openaiModels = byProvider.get("openai")!;
|
|
139
|
+
const modelOptions = openaiModels.map(m => m.id);
|
|
140
|
+
|
|
141
|
+
assert.strictEqual(modelOptions[0], "gpt-4o");
|
|
142
|
+
assert.strictEqual(modelOptions[1], "o3-mini");
|
|
121
143
|
});
|
|
122
144
|
});
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// Tests the pure formatInspectOutput function with known data.
|
|
4
4
|
|
|
5
5
|
import { createTestContext } from './test-helpers.ts';
|
|
6
|
-
import { formatInspectOutput, type InspectData } from '../commands.ts';
|
|
6
|
+
import { formatInspectOutput, type InspectData } from '../commands-inspect.ts';
|
|
7
7
|
|
|
8
8
|
const { assertEq, assertTrue, assertMatch, report } = createTestContext();
|
|
9
9
|
|