gsd-pi 2.39.0 → 2.40.0-dev.4a93031
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/resource-loader.js +66 -2
- package/dist/resources/extensions/async-jobs/index.js +10 -0
- package/dist/resources/extensions/get-secrets-from-user.js +1 -1
- package/dist/resources/extensions/gsd/auto-dashboard.js +7 -0
- package/dist/resources/extensions/gsd/auto-loop.js +761 -673
- package/dist/resources/extensions/gsd/auto-post-unit.js +10 -2
- package/dist/resources/extensions/gsd/auto-prompts.js +3 -3
- package/dist/resources/extensions/gsd/auto-start.js +6 -1
- package/dist/resources/extensions/gsd/auto.js +6 -4
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +126 -0
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +233 -0
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +59 -0
- package/dist/resources/extensions/gsd/bootstrap/register-extension.js +38 -0
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +156 -0
- package/dist/resources/extensions/gsd/bootstrap/register-shortcuts.js +46 -0
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +300 -0
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +38 -0
- package/dist/resources/extensions/gsd/commands/catalog.js +278 -0
- package/dist/resources/extensions/gsd/commands/context.js +84 -0
- package/dist/resources/extensions/gsd/commands/dispatcher.js +21 -0
- package/dist/resources/extensions/gsd/commands/handlers/auto.js +72 -0
- package/dist/resources/extensions/gsd/commands/handlers/core.js +246 -0
- package/dist/resources/extensions/gsd/commands/handlers/ops.js +166 -0
- package/dist/resources/extensions/gsd/commands/handlers/parallel.js +94 -0
- package/dist/resources/extensions/gsd/commands/handlers/workflow.js +102 -0
- package/dist/resources/extensions/gsd/commands/index.js +11 -0
- package/dist/resources/extensions/gsd/commands-handlers.js +1 -1
- package/dist/resources/extensions/gsd/commands.js +8 -1190
- package/dist/resources/extensions/gsd/dashboard-overlay.js +9 -0
- package/dist/resources/extensions/gsd/doctor-proactive.js +80 -10
- package/dist/resources/extensions/gsd/doctor.js +32 -2
- package/dist/resources/extensions/gsd/export-html.js +46 -0
- package/dist/resources/extensions/gsd/files.js +1 -1
- package/dist/resources/extensions/gsd/health-widget.js +1 -1
- package/dist/resources/extensions/gsd/index.js +4 -1115
- package/dist/resources/extensions/gsd/progress-score.js +20 -1
- package/dist/resources/extensions/gsd/prompts/forensics.md +121 -46
- package/dist/resources/extensions/gsd/visualizer-data.js +26 -1
- package/dist/resources/extensions/gsd/visualizer-views.js +52 -0
- package/dist/welcome-screen.d.ts +3 -2
- package/dist/welcome-screen.js +66 -22
- package/package.json +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts +12 -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 +107 -24
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/skill-tool.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/skill-tool.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/skill-tool.test.js +70 -0
- package/packages/pi-coding-agent/dist/core/skill-tool.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/skills.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/skills.js +2 -1
- package/packages/pi-coding-agent/dist/core/skills.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts +17 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +244 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/extension-ui-controller.d.ts +3 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/extension-ui-controller.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/extension-ui-controller.js +58 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/extension-ui-controller.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.d.ts +12 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +54 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/model-controller.d.ts +6 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/model-controller.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/model-controller.js +63 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/model-controller.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts +38 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.js +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +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 +15 -457
- 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/src/core/agent-session.ts +122 -23
- package/packages/pi-coding-agent/src/core/skill-tool.test.ts +89 -0
- package/packages/pi-coding-agent/src/core/skills.ts +2 -1
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +302 -0
- package/packages/pi-coding-agent/src/modes/interactive/controllers/extension-ui-controller.ts +59 -0
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +68 -0
- package/packages/pi-coding-agent/src/modes/interactive/controllers/model-controller.ts +71 -0
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-state.ts +37 -0
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +18 -510
- package/pkg/package.json +1 -1
- package/src/resources/extensions/async-jobs/index.ts +11 -0
- package/src/resources/extensions/get-secrets-from-user.ts +1 -1
- package/src/resources/extensions/gsd/auto-dashboard.ts +10 -0
- package/src/resources/extensions/gsd/auto-loop.ts +1075 -921
- package/src/resources/extensions/gsd/auto-post-unit.ts +10 -2
- package/src/resources/extensions/gsd/auto-prompts.ts +3 -3
- package/src/resources/extensions/gsd/auto-start.ts +6 -1
- package/src/resources/extensions/gsd/auto.ts +13 -10
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +142 -0
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +238 -0
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +90 -0
- package/src/resources/extensions/gsd/bootstrap/register-extension.ts +46 -0
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +167 -0
- package/src/resources/extensions/gsd/bootstrap/register-shortcuts.ts +55 -0
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +340 -0
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +51 -0
- package/src/resources/extensions/gsd/commands/catalog.ts +301 -0
- package/src/resources/extensions/gsd/commands/context.ts +101 -0
- package/src/resources/extensions/gsd/commands/dispatcher.ts +32 -0
- package/src/resources/extensions/gsd/commands/handlers/auto.ts +74 -0
- package/src/resources/extensions/gsd/commands/handlers/core.ts +274 -0
- package/src/resources/extensions/gsd/commands/handlers/ops.ts +169 -0
- package/src/resources/extensions/gsd/commands/handlers/parallel.ts +118 -0
- package/src/resources/extensions/gsd/commands/handlers/workflow.ts +109 -0
- package/src/resources/extensions/gsd/commands/index.ts +14 -0
- package/src/resources/extensions/gsd/commands-handlers.ts +1 -1
- package/src/resources/extensions/gsd/commands.ts +10 -1329
- package/src/resources/extensions/gsd/dashboard-overlay.ts +10 -0
- package/src/resources/extensions/gsd/doctor-proactive.ts +106 -10
- package/src/resources/extensions/gsd/doctor.ts +47 -3
- package/src/resources/extensions/gsd/export-html.ts +51 -0
- package/src/resources/extensions/gsd/files.ts +1 -1
- package/src/resources/extensions/gsd/health-widget.ts +2 -1
- package/src/resources/extensions/gsd/index.ts +12 -1314
- package/src/resources/extensions/gsd/progress-score.ts +23 -0
- package/src/resources/extensions/gsd/prompts/forensics.md +121 -46
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +13 -9
- package/src/resources/extensions/gsd/tests/doctor-proactive.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +16 -16
- package/src/resources/extensions/gsd/tests/skill-activation.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/visualizer-data.test.ts +10 -10
- package/src/resources/extensions/gsd/visualizer-data.ts +51 -1
- package/src/resources/extensions/gsd/visualizer-views.ts +58 -0
- /package/dist/resources/extensions/{env-utils.js → gsd/env-utils.js} +0 -0
- /package/src/resources/extensions/{env-utils.ts → gsd/env-utils.ts} +0 -0
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { loadRegistry } from "../workflow-templates.js";
|
|
5
|
+
const gsdHome = process.env.GSD_HOME || join(homedir(), ".gsd");
|
|
6
|
+
export const GSD_COMMAND_DESCRIPTION = "GSD — Get Shit Done: /gsd help|start|templates|next|auto|stop|pause|status|widget|visualize|queue|quick|capture|triage|dispatch|history|undo|rate|skip|export|cleanup|mode|prefs|config|keys|hooks|run-hook|skill-health|doctor|logs|forensics|changelog|migrate|remote|steer|knowledge|new-milestone|parallel|cmux|park|unpark|init|setup|inspect|extensions|update";
|
|
7
|
+
export const TOP_LEVEL_SUBCOMMANDS = [
|
|
8
|
+
{ cmd: "help", desc: "Categorized command reference with descriptions" },
|
|
9
|
+
{ cmd: "next", desc: "Explicit step mode (same as /gsd)" },
|
|
10
|
+
{ cmd: "auto", desc: "Autonomous mode — research, plan, execute, commit, repeat" },
|
|
11
|
+
{ cmd: "stop", desc: "Stop auto mode gracefully" },
|
|
12
|
+
{ cmd: "pause", desc: "Pause auto-mode (preserves state, /gsd auto to resume)" },
|
|
13
|
+
{ cmd: "status", desc: "Progress dashboard" },
|
|
14
|
+
{ cmd: "widget", desc: "Cycle widget: full → small → min → off" },
|
|
15
|
+
{ cmd: "visualize", desc: "Open 10-tab workflow visualizer (progress, timeline, deps, metrics, health, agent, changes, knowledge, captures, export)" },
|
|
16
|
+
{ cmd: "queue", desc: "Queue and reorder future milestones" },
|
|
17
|
+
{ cmd: "quick", desc: "Execute a quick task without full planning overhead" },
|
|
18
|
+
{ cmd: "discuss", desc: "Discuss architecture and decisions" },
|
|
19
|
+
{ cmd: "capture", desc: "Fire-and-forget thought capture" },
|
|
20
|
+
{ cmd: "changelog", desc: "Show categorized release notes" },
|
|
21
|
+
{ cmd: "triage", desc: "Manually trigger triage of pending captures" },
|
|
22
|
+
{ cmd: "dispatch", desc: "Dispatch a specific phase directly" },
|
|
23
|
+
{ cmd: "history", desc: "View execution history" },
|
|
24
|
+
{ cmd: "undo", desc: "Revert last completed unit" },
|
|
25
|
+
{ cmd: "rate", desc: "Rate last unit's model tier (over/ok/under) — improves adaptive routing" },
|
|
26
|
+
{ cmd: "skip", desc: "Prevent a unit from auto-mode dispatch" },
|
|
27
|
+
{ cmd: "export", desc: "Export milestone/slice results" },
|
|
28
|
+
{ cmd: "cleanup", desc: "Remove merged branches or snapshots" },
|
|
29
|
+
{ cmd: "mode", desc: "Switch workflow mode (solo/team)" },
|
|
30
|
+
{ cmd: "prefs", desc: "Manage preferences (model selection, timeouts, etc.)" },
|
|
31
|
+
{ cmd: "config", desc: "Set API keys for external tools" },
|
|
32
|
+
{ cmd: "keys", desc: "API key manager — list, add, remove, test, rotate, doctor" },
|
|
33
|
+
{ cmd: "hooks", desc: "Show configured post-unit and pre-dispatch hooks" },
|
|
34
|
+
{ cmd: "run-hook", desc: "Manually trigger a specific hook" },
|
|
35
|
+
{ cmd: "skill-health", desc: "Skill lifecycle dashboard" },
|
|
36
|
+
{ cmd: "doctor", desc: "Runtime health checks with auto-fix" },
|
|
37
|
+
{ cmd: "logs", desc: "Browse activity logs, debug logs, and metrics" },
|
|
38
|
+
{ cmd: "forensics", desc: "Examine execution logs" },
|
|
39
|
+
{ cmd: "init", desc: "Project init wizard — detect, configure, bootstrap .gsd/" },
|
|
40
|
+
{ cmd: "setup", desc: "Global setup status and configuration" },
|
|
41
|
+
{ cmd: "migrate", desc: "Migrate a v1 .planning directory to .gsd format" },
|
|
42
|
+
{ cmd: "remote", desc: "Control remote auto-mode" },
|
|
43
|
+
{ cmd: "steer", desc: "Hard-steer plan documents during execution" },
|
|
44
|
+
{ cmd: "inspect", desc: "Show SQLite DB diagnostics" },
|
|
45
|
+
{ cmd: "knowledge", desc: "Add persistent project knowledge (rule, pattern, or lesson)" },
|
|
46
|
+
{ cmd: "new-milestone", desc: "Create a milestone from a specification document (headless)" },
|
|
47
|
+
{ cmd: "parallel", desc: "Parallel milestone orchestration (start, status, stop, merge)" },
|
|
48
|
+
{ cmd: "cmux", desc: "Manage cmux integration (status, sidebar, notifications, splits)" },
|
|
49
|
+
{ cmd: "park", desc: "Park a milestone — skip without deleting" },
|
|
50
|
+
{ cmd: "unpark", desc: "Reactivate a parked milestone" },
|
|
51
|
+
{ cmd: "update", desc: "Update GSD to the latest version" },
|
|
52
|
+
{ cmd: "start", desc: "Start a workflow template (bugfix, spike, feature, etc.)" },
|
|
53
|
+
{ cmd: "templates", desc: "List available workflow templates" },
|
|
54
|
+
{ cmd: "extensions", desc: "Manage extensions (list, enable, disable, info)" },
|
|
55
|
+
];
|
|
56
|
+
const NESTED_COMPLETIONS = {
|
|
57
|
+
auto: [
|
|
58
|
+
{ cmd: "--verbose", desc: "Show detailed execution output" },
|
|
59
|
+
{ cmd: "--debug", desc: "Enable debug logging" },
|
|
60
|
+
],
|
|
61
|
+
next: [
|
|
62
|
+
{ cmd: "--verbose", desc: "Show detailed step output" },
|
|
63
|
+
{ cmd: "--dry-run", desc: "Preview next step without executing" },
|
|
64
|
+
],
|
|
65
|
+
mode: [
|
|
66
|
+
{ cmd: "global", desc: "Edit global workflow mode" },
|
|
67
|
+
{ cmd: "project", desc: "Edit project-specific workflow mode" },
|
|
68
|
+
],
|
|
69
|
+
parallel: [
|
|
70
|
+
{ cmd: "start", desc: "Start parallel milestone orchestration" },
|
|
71
|
+
{ cmd: "status", desc: "Show parallel worker statuses" },
|
|
72
|
+
{ cmd: "stop", desc: "Stop all parallel workers" },
|
|
73
|
+
{ cmd: "pause", desc: "Pause a specific worker" },
|
|
74
|
+
{ cmd: "resume", desc: "Resume a paused worker" },
|
|
75
|
+
{ cmd: "merge", desc: "Merge completed milestone branches" },
|
|
76
|
+
],
|
|
77
|
+
setup: [
|
|
78
|
+
{ cmd: "llm", desc: "Configure LLM provider settings" },
|
|
79
|
+
{ cmd: "search", desc: "Configure web search provider" },
|
|
80
|
+
{ cmd: "remote", desc: "Configure remote integrations" },
|
|
81
|
+
{ cmd: "keys", desc: "Manage API keys" },
|
|
82
|
+
{ cmd: "prefs", desc: "Configure global preferences" },
|
|
83
|
+
],
|
|
84
|
+
logs: [
|
|
85
|
+
{ cmd: "debug", desc: "List or view debug log files" },
|
|
86
|
+
{ cmd: "tail", desc: "Show last N activity log summaries" },
|
|
87
|
+
{ cmd: "clear", desc: "Remove old activity and debug logs" },
|
|
88
|
+
],
|
|
89
|
+
keys: [
|
|
90
|
+
{ cmd: "list", desc: "Show key status dashboard" },
|
|
91
|
+
{ cmd: "add", desc: "Add a key for a provider" },
|
|
92
|
+
{ cmd: "remove", desc: "Remove a key" },
|
|
93
|
+
{ cmd: "test", desc: "Validate key(s) with API call" },
|
|
94
|
+
{ cmd: "rotate", desc: "Replace an existing key" },
|
|
95
|
+
{ cmd: "doctor", desc: "Health check all keys" },
|
|
96
|
+
],
|
|
97
|
+
prefs: [
|
|
98
|
+
{ cmd: "global", desc: "Edit global preferences file" },
|
|
99
|
+
{ cmd: "project", desc: "Edit project preferences file" },
|
|
100
|
+
{ cmd: "status", desc: "Show effective preferences" },
|
|
101
|
+
{ cmd: "wizard", desc: "Interactive preferences wizard" },
|
|
102
|
+
{ cmd: "setup", desc: "First-time preferences setup" },
|
|
103
|
+
{ cmd: "import-claude", desc: "Import settings from Claude Code" },
|
|
104
|
+
],
|
|
105
|
+
remote: [
|
|
106
|
+
{ cmd: "slack", desc: "Configure Slack integration" },
|
|
107
|
+
{ cmd: "discord", desc: "Configure Discord integration" },
|
|
108
|
+
{ cmd: "status", desc: "Show remote connection status" },
|
|
109
|
+
{ cmd: "disconnect", desc: "Disconnect remote integrations" },
|
|
110
|
+
],
|
|
111
|
+
history: [
|
|
112
|
+
{ cmd: "--cost", desc: "Show cost breakdown per entry" },
|
|
113
|
+
{ cmd: "--phase", desc: "Filter by phase type" },
|
|
114
|
+
{ cmd: "--model", desc: "Filter by model used" },
|
|
115
|
+
{ cmd: "10", desc: "Show last 10 entries" },
|
|
116
|
+
{ cmd: "20", desc: "Show last 20 entries" },
|
|
117
|
+
{ cmd: "50", desc: "Show last 50 entries" },
|
|
118
|
+
],
|
|
119
|
+
export: [
|
|
120
|
+
{ cmd: "--json", desc: "Export as JSON" },
|
|
121
|
+
{ cmd: "--markdown", desc: "Export as Markdown" },
|
|
122
|
+
{ cmd: "--html", desc: "Export as HTML" },
|
|
123
|
+
{ cmd: "--html --all", desc: "Export all milestones as HTML" },
|
|
124
|
+
],
|
|
125
|
+
cleanup: [
|
|
126
|
+
{ cmd: "branches", desc: "Remove merged milestone branches" },
|
|
127
|
+
{ cmd: "snapshots", desc: "Remove old execution snapshots" },
|
|
128
|
+
],
|
|
129
|
+
knowledge: [
|
|
130
|
+
{ cmd: "rule", desc: "Add a project rule (always/never do X)" },
|
|
131
|
+
{ cmd: "pattern", desc: "Add a code pattern to follow" },
|
|
132
|
+
{ cmd: "lesson", desc: "Record a lesson learned" },
|
|
133
|
+
],
|
|
134
|
+
start: [
|
|
135
|
+
{ cmd: "bugfix", desc: "Triage, fix, test, and ship a bug fix" },
|
|
136
|
+
{ cmd: "small-feature", desc: "Lightweight feature with optional discussion" },
|
|
137
|
+
{ cmd: "spike", desc: "Research, prototype, and document findings" },
|
|
138
|
+
{ cmd: "hotfix", desc: "Minimal: fix it, test it, ship it" },
|
|
139
|
+
{ cmd: "refactor", desc: "Inventory, plan waves, migrate, verify" },
|
|
140
|
+
{ cmd: "security-audit", desc: "Scan, triage, remediate, re-scan" },
|
|
141
|
+
{ cmd: "dep-upgrade", desc: "Assess, upgrade, fix breaks, verify" },
|
|
142
|
+
{ cmd: "full-project", desc: "Complete GSD workflow with full ceremony" },
|
|
143
|
+
{ cmd: "resume", desc: "Resume an in-progress workflow" },
|
|
144
|
+
{ cmd: "--list", desc: "List all available templates" },
|
|
145
|
+
{ cmd: "--dry-run", desc: "Preview workflow without executing" },
|
|
146
|
+
],
|
|
147
|
+
templates: [
|
|
148
|
+
{ cmd: "info", desc: "Show detailed template info" },
|
|
149
|
+
],
|
|
150
|
+
extensions: [
|
|
151
|
+
{ cmd: "list", desc: "List all extensions and their status" },
|
|
152
|
+
{ cmd: "enable", desc: "Enable a disabled extension" },
|
|
153
|
+
{ cmd: "disable", desc: "Disable an extension" },
|
|
154
|
+
{ cmd: "info", desc: "Show extension details" },
|
|
155
|
+
],
|
|
156
|
+
doctor: [
|
|
157
|
+
{ cmd: "fix", desc: "Auto-fix detected issues" },
|
|
158
|
+
{ cmd: "heal", desc: "AI-driven deep healing" },
|
|
159
|
+
{ cmd: "audit", desc: "Run health audit without fixing" },
|
|
160
|
+
{ cmd: "--dry-run", desc: "Show what --fix would change without applying" },
|
|
161
|
+
{ cmd: "--json", desc: "Output report as JSON (CI/tooling friendly)" },
|
|
162
|
+
{ cmd: "--build", desc: "Include slow build health check (npm run build)" },
|
|
163
|
+
{ cmd: "--test", desc: "Include slow test health check (npm test)" },
|
|
164
|
+
],
|
|
165
|
+
dispatch: [
|
|
166
|
+
{ cmd: "research", desc: "Run research phase" },
|
|
167
|
+
{ cmd: "plan", desc: "Run planning phase" },
|
|
168
|
+
{ cmd: "execute", desc: "Run execution phase" },
|
|
169
|
+
{ cmd: "complete", desc: "Run completion phase" },
|
|
170
|
+
{ cmd: "reassess", desc: "Reassess current progress" },
|
|
171
|
+
{ cmd: "uat", desc: "Run user acceptance testing" },
|
|
172
|
+
{ cmd: "replan", desc: "Replan the current slice" },
|
|
173
|
+
],
|
|
174
|
+
rate: [
|
|
175
|
+
{ cmd: "over", desc: "Model was overqualified for this task" },
|
|
176
|
+
{ cmd: "ok", desc: "Model was appropriate for this task" },
|
|
177
|
+
{ cmd: "under", desc: "Model was underqualified for this task" },
|
|
178
|
+
],
|
|
179
|
+
};
|
|
180
|
+
function filterOptions(partial, options, prefix = "") {
|
|
181
|
+
const normalizedPrefix = prefix ? `${prefix} ` : "";
|
|
182
|
+
return options
|
|
183
|
+
.filter((option) => option.cmd.startsWith(partial))
|
|
184
|
+
.map((option) => ({
|
|
185
|
+
value: `${normalizedPrefix}${option.cmd}`,
|
|
186
|
+
label: option.cmd,
|
|
187
|
+
description: option.desc,
|
|
188
|
+
}));
|
|
189
|
+
}
|
|
190
|
+
function getExtensionCompletions(prefix, action) {
|
|
191
|
+
try {
|
|
192
|
+
const extDir = join(gsdHome, "agent", "extensions");
|
|
193
|
+
const ids = [];
|
|
194
|
+
for (const entry of readdirSync(extDir, { withFileTypes: true })) {
|
|
195
|
+
if (!entry.isDirectory())
|
|
196
|
+
continue;
|
|
197
|
+
const manifestPath = join(extDir, entry.name, "extension-manifest.json");
|
|
198
|
+
if (!existsSync(manifestPath))
|
|
199
|
+
continue;
|
|
200
|
+
try {
|
|
201
|
+
const manifest = JSON.parse(readFileSync(manifestPath, "utf-8"));
|
|
202
|
+
if (typeof manifest?.id === "string") {
|
|
203
|
+
ids.push({ id: manifest.id, name: manifest.name ?? manifest.id });
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
catch {
|
|
207
|
+
// ignore malformed manifests
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return ids
|
|
211
|
+
.filter((entry) => entry.id.startsWith(prefix))
|
|
212
|
+
.map((entry) => ({
|
|
213
|
+
value: `extensions ${action} ${entry.id}`,
|
|
214
|
+
label: entry.id,
|
|
215
|
+
description: entry.name,
|
|
216
|
+
}));
|
|
217
|
+
}
|
|
218
|
+
catch {
|
|
219
|
+
return [];
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
export function getGsdArgumentCompletions(prefix) {
|
|
223
|
+
const hasTrailingSpace = prefix.endsWith(" ");
|
|
224
|
+
const parts = prefix.trim().split(/\s+/);
|
|
225
|
+
if (hasTrailingSpace && parts.length >= 1) {
|
|
226
|
+
parts.push("");
|
|
227
|
+
}
|
|
228
|
+
if (parts.length <= 1) {
|
|
229
|
+
return filterOptions(parts[0] ?? "", TOP_LEVEL_SUBCOMMANDS);
|
|
230
|
+
}
|
|
231
|
+
const [command, subcommand = "", third = ""] = parts;
|
|
232
|
+
if (command === "cmux") {
|
|
233
|
+
if (parts.length <= 2) {
|
|
234
|
+
return filterOptions(subcommand, [
|
|
235
|
+
{ cmd: "status", desc: "Show cmux detection, prefs, and capabilities" },
|
|
236
|
+
{ cmd: "on", desc: "Enable cmux integration" },
|
|
237
|
+
{ cmd: "off", desc: "Disable cmux integration" },
|
|
238
|
+
{ cmd: "notifications", desc: "Toggle cmux desktop notifications" },
|
|
239
|
+
{ cmd: "sidebar", desc: "Toggle cmux sidebar metadata" },
|
|
240
|
+
{ cmd: "splits", desc: "Toggle cmux visual subagent splits" },
|
|
241
|
+
{ cmd: "browser", desc: "Toggle future browser integration flag" },
|
|
242
|
+
], "cmux");
|
|
243
|
+
}
|
|
244
|
+
if (parts.length <= 3 && ["notifications", "sidebar", "splits", "browser"].includes(subcommand)) {
|
|
245
|
+
return filterOptions(third, [
|
|
246
|
+
{ cmd: "on", desc: "Enable this cmux area" },
|
|
247
|
+
{ cmd: "off", desc: "Disable this cmux area" },
|
|
248
|
+
], `cmux ${subcommand}`);
|
|
249
|
+
}
|
|
250
|
+
return [];
|
|
251
|
+
}
|
|
252
|
+
if (command === "templates" && subcommand === "info" && parts.length <= 3) {
|
|
253
|
+
try {
|
|
254
|
+
const registry = loadRegistry();
|
|
255
|
+
return Object.entries(registry.templates)
|
|
256
|
+
.filter(([id]) => id.startsWith(third))
|
|
257
|
+
.map(([id, entry]) => ({
|
|
258
|
+
value: `templates info ${id}`,
|
|
259
|
+
label: id,
|
|
260
|
+
description: entry.description,
|
|
261
|
+
}));
|
|
262
|
+
}
|
|
263
|
+
catch {
|
|
264
|
+
return [];
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
if (command === "extensions" && parts.length === 3 && ["enable", "disable", "info"].includes(subcommand)) {
|
|
268
|
+
return getExtensionCompletions(third, subcommand);
|
|
269
|
+
}
|
|
270
|
+
if (command === "undo" && parts.length <= 2) {
|
|
271
|
+
return [{ value: "undo --force", label: "--force", description: "Skip confirmation prompt" }];
|
|
272
|
+
}
|
|
273
|
+
const nested = NESTED_COMPLETIONS[command];
|
|
274
|
+
if (nested && parts.length <= 2) {
|
|
275
|
+
return filterOptions(subcommand, nested, command);
|
|
276
|
+
}
|
|
277
|
+
return [];
|
|
278
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { checkRemoteAutoSession, isAutoActive, isAutoPaused, stopAutoRemote } from "../auto.js";
|
|
2
|
+
import { assertSafeDirectory } from "../validate-directory.js";
|
|
3
|
+
import { resolveProjectRoot } from "../worktree.js";
|
|
4
|
+
import { showNextAction } from "../../shared/mod.js";
|
|
5
|
+
import { handleStatus } from "./handlers/core.js";
|
|
6
|
+
export function projectRoot() {
|
|
7
|
+
const cwd = process.cwd();
|
|
8
|
+
const root = resolveProjectRoot(cwd);
|
|
9
|
+
if (root !== cwd) {
|
|
10
|
+
assertSafeDirectory(cwd);
|
|
11
|
+
}
|
|
12
|
+
else {
|
|
13
|
+
assertSafeDirectory(root);
|
|
14
|
+
}
|
|
15
|
+
return root;
|
|
16
|
+
}
|
|
17
|
+
export async function guardRemoteSession(ctx, pi) {
|
|
18
|
+
if (isAutoActive() || isAutoPaused())
|
|
19
|
+
return true;
|
|
20
|
+
const remote = checkRemoteAutoSession(projectRoot());
|
|
21
|
+
if (!remote.running || !remote.pid)
|
|
22
|
+
return true;
|
|
23
|
+
const unitLabel = remote.unitType && remote.unitId
|
|
24
|
+
? `${remote.unitType} (${remote.unitId})`
|
|
25
|
+
: "unknown unit";
|
|
26
|
+
const unitsMsg = remote.completedUnits != null
|
|
27
|
+
? `${remote.completedUnits} units completed`
|
|
28
|
+
: "";
|
|
29
|
+
const choice = await showNextAction(ctx, {
|
|
30
|
+
title: `Auto-mode is running in another terminal (PID ${remote.pid})`,
|
|
31
|
+
summary: [
|
|
32
|
+
`Currently executing: ${unitLabel}`,
|
|
33
|
+
...(unitsMsg ? [unitsMsg] : []),
|
|
34
|
+
...(remote.startedAt ? [`Started: ${remote.startedAt}`] : []),
|
|
35
|
+
],
|
|
36
|
+
actions: [
|
|
37
|
+
{
|
|
38
|
+
id: "status",
|
|
39
|
+
label: "View status",
|
|
40
|
+
description: "Show the current GSD progress dashboard.",
|
|
41
|
+
recommended: true,
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
id: "steer",
|
|
45
|
+
label: "Steer the session",
|
|
46
|
+
description: "Use /gsd steer <instruction> to redirect the running session.",
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
id: "stop",
|
|
50
|
+
label: "Stop remote session",
|
|
51
|
+
description: `Send SIGTERM to PID ${remote.pid} to stop it gracefully.`,
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
id: "force",
|
|
55
|
+
label: "Force start (steal lock)",
|
|
56
|
+
description: "Start a new session, terminating the existing one.",
|
|
57
|
+
},
|
|
58
|
+
],
|
|
59
|
+
notYetMessage: "Run /gsd when ready.",
|
|
60
|
+
});
|
|
61
|
+
if (choice === "status") {
|
|
62
|
+
await handleStatus(ctx);
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
if (choice === "steer") {
|
|
66
|
+
ctx.ui.notify("Use /gsd steer <instruction> to redirect the running auto-mode session.\n" +
|
|
67
|
+
"Example: /gsd steer Use Postgres instead of SQLite", "info");
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
if (choice === "stop") {
|
|
71
|
+
const result = stopAutoRemote(projectRoot());
|
|
72
|
+
if (result.found) {
|
|
73
|
+
ctx.ui.notify(`Sent stop signal to auto-mode session (PID ${result.pid}). It will shut down gracefully.`, "info");
|
|
74
|
+
}
|
|
75
|
+
else if (result.error) {
|
|
76
|
+
ctx.ui.notify(`Failed to stop remote auto-mode: ${result.error}`, "error");
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
ctx.ui.notify("Remote session is no longer running.", "info");
|
|
80
|
+
}
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
return choice === "force";
|
|
84
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { handleAutoCommand } from "./handlers/auto.js";
|
|
2
|
+
import { handleCoreCommand } from "./handlers/core.js";
|
|
3
|
+
import { handleOpsCommand } from "./handlers/ops.js";
|
|
4
|
+
import { handleParallelCommand } from "./handlers/parallel.js";
|
|
5
|
+
import { handleWorkflowCommand } from "./handlers/workflow.js";
|
|
6
|
+
export async function handleGSDCommand(args, ctx, pi) {
|
|
7
|
+
const trimmed = (typeof args === "string" ? args : "").trim();
|
|
8
|
+
const handlers = [
|
|
9
|
+
() => handleCoreCommand(trimmed, ctx),
|
|
10
|
+
() => handleAutoCommand(trimmed, ctx, pi),
|
|
11
|
+
() => handleParallelCommand(trimmed, ctx, pi),
|
|
12
|
+
() => handleWorkflowCommand(trimmed, ctx, pi),
|
|
13
|
+
() => handleOpsCommand(trimmed, ctx, pi),
|
|
14
|
+
];
|
|
15
|
+
for (const handler of handlers) {
|
|
16
|
+
if (await handler()) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
ctx.ui.notify(`Unknown: /gsd ${trimmed}. Run /gsd help for available commands.`, "warning");
|
|
21
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { enableDebug } from "../../debug-logger.js";
|
|
2
|
+
import { isAutoActive, isAutoPaused, pauseAuto, startAuto, stopAuto, stopAutoRemote } from "../../auto.js";
|
|
3
|
+
import { handleRate } from "../../commands-rate.js";
|
|
4
|
+
import { guardRemoteSession, projectRoot } from "../context.js";
|
|
5
|
+
export async function handleAutoCommand(trimmed, ctx, pi) {
|
|
6
|
+
if (trimmed === "next" || trimmed.startsWith("next ")) {
|
|
7
|
+
if (trimmed.includes("--dry-run")) {
|
|
8
|
+
const { handleDryRun } = await import("../../commands-maintenance.js");
|
|
9
|
+
await handleDryRun(ctx, projectRoot());
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
const verboseMode = trimmed.includes("--verbose");
|
|
13
|
+
const debugMode = trimmed.includes("--debug");
|
|
14
|
+
if (debugMode)
|
|
15
|
+
enableDebug(projectRoot());
|
|
16
|
+
if (!(await guardRemoteSession(ctx, pi)))
|
|
17
|
+
return true;
|
|
18
|
+
await startAuto(ctx, pi, projectRoot(), verboseMode, { step: true });
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
if (trimmed === "auto" || trimmed.startsWith("auto ")) {
|
|
22
|
+
const verboseMode = trimmed.includes("--verbose");
|
|
23
|
+
const debugMode = trimmed.includes("--debug");
|
|
24
|
+
if (debugMode)
|
|
25
|
+
enableDebug(projectRoot());
|
|
26
|
+
if (!(await guardRemoteSession(ctx, pi)))
|
|
27
|
+
return true;
|
|
28
|
+
await startAuto(ctx, pi, projectRoot(), verboseMode);
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
if (trimmed === "stop") {
|
|
32
|
+
if (!isAutoActive() && !isAutoPaused()) {
|
|
33
|
+
const result = stopAutoRemote(projectRoot());
|
|
34
|
+
if (result.found) {
|
|
35
|
+
ctx.ui.notify(`Sent stop signal to auto-mode session (PID ${result.pid}). It will shut down gracefully.`, "info");
|
|
36
|
+
}
|
|
37
|
+
else if (result.error) {
|
|
38
|
+
ctx.ui.notify(`Failed to stop remote auto-mode: ${result.error}`, "error");
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
ctx.ui.notify("Auto-mode is not running.", "info");
|
|
42
|
+
}
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
await stopAuto(ctx, pi, "User requested stop");
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
if (trimmed === "pause") {
|
|
49
|
+
if (!isAutoActive()) {
|
|
50
|
+
if (isAutoPaused()) {
|
|
51
|
+
ctx.ui.notify("Auto-mode is already paused. /gsd auto to resume.", "info");
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
ctx.ui.notify("Auto-mode is not running.", "info");
|
|
55
|
+
}
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
await pauseAuto(ctx, pi);
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
if (trimmed === "rate" || trimmed.startsWith("rate ")) {
|
|
62
|
+
await handleRate(trimmed.replace(/^rate\s*/, "").trim(), ctx, projectRoot());
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
if (trimmed === "") {
|
|
66
|
+
if (!(await guardRemoteSession(ctx, pi)))
|
|
67
|
+
return true;
|
|
68
|
+
await startAuto(ctx, pi, projectRoot(), false, { step: true });
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
return false;
|
|
72
|
+
}
|