gsd-opencode 1.22.0 → 1.30.0
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/agents/gsd-advisor-researcher.md +112 -0
- package/agents/gsd-assumptions-analyzer.md +110 -0
- package/agents/gsd-codebase-mapper.md +1 -2
- package/agents/gsd-debugger.md +119 -2
- package/agents/gsd-executor.md +25 -4
- package/agents/gsd-integration-checker.md +1 -2
- package/agents/gsd-nyquist-auditor.md +1 -2
- package/agents/gsd-phase-researcher.md +151 -5
- package/agents/gsd-plan-checker.md +71 -5
- package/agents/gsd-planner.md +50 -4
- package/agents/gsd-project-researcher.md +29 -3
- package/agents/gsd-research-synthesizer.md +1 -2
- package/agents/gsd-roadmapper.md +30 -2
- package/agents/gsd-ui-auditor.md +445 -0
- package/agents/gsd-ui-checker.md +305 -0
- package/agents/gsd-ui-researcher.md +368 -0
- package/agents/gsd-user-profiler.md +173 -0
- package/agents/gsd-verifier.md +124 -4
- package/commands/gsd/gsd-add-backlog.md +76 -0
- package/commands/gsd/gsd-audit-uat.md +24 -0
- package/commands/gsd/gsd-autonomous.md +41 -0
- package/commands/gsd/gsd-debug.md +5 -0
- package/commands/gsd/gsd-discuss-phase.md +10 -36
- package/commands/gsd/gsd-do.md +30 -0
- package/commands/gsd/gsd-execute-phase.md +20 -2
- package/commands/gsd/gsd-fast.md +30 -0
- package/commands/gsd/gsd-forensics.md +56 -0
- package/commands/gsd/gsd-list-workspaces.md +19 -0
- package/commands/gsd/gsd-manager.md +39 -0
- package/commands/gsd/gsd-milestone-summary.md +51 -0
- package/commands/gsd/gsd-new-workspace.md +44 -0
- package/commands/gsd/gsd-next.md +24 -0
- package/commands/gsd/gsd-note.md +34 -0
- package/commands/gsd/gsd-plan-phase.md +3 -1
- package/commands/gsd/gsd-plant-seed.md +28 -0
- package/commands/gsd/gsd-pr-branch.md +25 -0
- package/commands/gsd/gsd-profile-user.md +46 -0
- package/commands/gsd/gsd-quick.md +4 -2
- package/commands/gsd/gsd-reapply-patches.md +10 -6
- package/commands/gsd/gsd-remove-workspace.md +26 -0
- package/commands/gsd/gsd-research-phase.md +5 -0
- package/commands/gsd/gsd-resume-work.md +1 -1
- package/commands/gsd/gsd-review-backlog.md +61 -0
- package/commands/gsd/gsd-review.md +37 -0
- package/commands/gsd/gsd-session-report.md +19 -0
- package/commands/gsd/gsd-set-profile.md +24 -23
- package/commands/gsd/gsd-ship.md +23 -0
- package/commands/gsd/gsd-stats.md +18 -0
- package/commands/gsd/gsd-thread.md +127 -0
- package/commands/gsd/gsd-ui-phase.md +34 -0
- package/commands/gsd/gsd-ui-review.md +32 -0
- package/commands/gsd/gsd-workstreams.md +66 -0
- package/get-shit-done/bin/gsd-tools.cjs +410 -84
- package/get-shit-done/bin/lib/commands.cjs +429 -18
- package/get-shit-done/bin/lib/config.cjs +318 -45
- package/get-shit-done/bin/lib/core.cjs +822 -84
- package/get-shit-done/bin/lib/frontmatter.cjs +78 -41
- package/get-shit-done/bin/lib/init.cjs +836 -104
- package/get-shit-done/bin/lib/milestone.cjs +44 -33
- package/get-shit-done/bin/lib/model-profiles.cjs +68 -0
- package/get-shit-done/bin/lib/phase.cjs +293 -306
- package/get-shit-done/bin/lib/profile-output.cjs +952 -0
- package/get-shit-done/bin/lib/profile-pipeline.cjs +539 -0
- package/get-shit-done/bin/lib/roadmap.cjs +55 -24
- package/get-shit-done/bin/lib/security.cjs +382 -0
- package/get-shit-done/bin/lib/state.cjs +363 -53
- package/get-shit-done/bin/lib/template.cjs +2 -2
- package/get-shit-done/bin/lib/uat.cjs +282 -0
- package/get-shit-done/bin/lib/verify.cjs +104 -36
- package/get-shit-done/bin/lib/workstream.cjs +491 -0
- package/get-shit-done/references/checkpoints.md +12 -10
- package/get-shit-done/references/decimal-phase-calculation.md +2 -3
- package/get-shit-done/references/git-integration.md +47 -0
- package/get-shit-done/references/model-profile-resolution.md +2 -0
- package/get-shit-done/references/model-profiles.md +62 -16
- package/get-shit-done/references/phase-argument-parsing.md +2 -2
- package/get-shit-done/references/planning-config.md +3 -1
- package/get-shit-done/references/user-profiling.md +681 -0
- package/get-shit-done/references/workstream-flag.md +58 -0
- package/get-shit-done/templates/UAT.md +21 -3
- package/get-shit-done/templates/UI-SPEC.md +100 -0
- package/get-shit-done/templates/claude-md.md +122 -0
- package/get-shit-done/templates/config.json +10 -3
- package/get-shit-done/templates/context.md +61 -6
- package/get-shit-done/templates/dev-preferences.md +21 -0
- package/get-shit-done/templates/discussion-log.md +63 -0
- package/get-shit-done/templates/phase-prompt.md +46 -5
- package/get-shit-done/templates/project.md +2 -0
- package/get-shit-done/templates/state.md +2 -2
- package/get-shit-done/templates/user-profile.md +146 -0
- package/get-shit-done/workflows/add-phase.md +2 -2
- package/get-shit-done/workflows/add-tests.md +4 -4
- package/get-shit-done/workflows/add-todo.md +3 -3
- package/get-shit-done/workflows/audit-milestone.md +13 -5
- package/get-shit-done/workflows/audit-uat.md +109 -0
- package/get-shit-done/workflows/autonomous.md +891 -0
- package/get-shit-done/workflows/check-todos.md +2 -2
- package/get-shit-done/workflows/cleanup.md +4 -4
- package/get-shit-done/workflows/complete-milestone.md +9 -6
- package/get-shit-done/workflows/diagnose-issues.md +15 -3
- package/get-shit-done/workflows/discovery-phase.md +2 -2
- package/get-shit-done/workflows/discuss-phase-assumptions.md +653 -0
- package/get-shit-done/workflows/discuss-phase.md +411 -38
- package/get-shit-done/workflows/do.md +104 -0
- package/get-shit-done/workflows/execute-phase.md +405 -18
- package/get-shit-done/workflows/execute-plan.md +77 -12
- package/get-shit-done/workflows/fast.md +105 -0
- package/get-shit-done/workflows/forensics.md +265 -0
- package/get-shit-done/workflows/health.md +28 -6
- package/get-shit-done/workflows/help.md +124 -7
- package/get-shit-done/workflows/insert-phase.md +2 -2
- package/get-shit-done/workflows/list-phase-assumptions.md +2 -2
- package/get-shit-done/workflows/list-workspaces.md +56 -0
- package/get-shit-done/workflows/manager.md +362 -0
- package/get-shit-done/workflows/map-codebase.md +74 -13
- package/get-shit-done/workflows/milestone-summary.md +223 -0
- package/get-shit-done/workflows/new-milestone.md +120 -18
- package/get-shit-done/workflows/new-project.md +178 -39
- package/get-shit-done/workflows/new-workspace.md +237 -0
- package/get-shit-done/workflows/next.md +97 -0
- package/get-shit-done/workflows/node-repair.md +92 -0
- package/get-shit-done/workflows/note.md +156 -0
- package/get-shit-done/workflows/pause-work.md +62 -8
- package/get-shit-done/workflows/plan-milestone-gaps.md +4 -5
- package/get-shit-done/workflows/plan-phase.md +332 -33
- package/get-shit-done/workflows/plant-seed.md +169 -0
- package/get-shit-done/workflows/pr-branch.md +129 -0
- package/get-shit-done/workflows/profile-user.md +450 -0
- package/get-shit-done/workflows/progress.md +145 -20
- package/get-shit-done/workflows/quick.md +205 -49
- package/get-shit-done/workflows/remove-phase.md +2 -2
- package/get-shit-done/workflows/remove-workspace.md +90 -0
- package/get-shit-done/workflows/research-phase.md +11 -3
- package/get-shit-done/workflows/resume-project.md +35 -16
- package/get-shit-done/workflows/review.md +228 -0
- package/get-shit-done/workflows/session-report.md +146 -0
- package/get-shit-done/workflows/set-profile.md +2 -2
- package/get-shit-done/workflows/settings.md +80 -11
- package/get-shit-done/workflows/ship.md +228 -0
- package/get-shit-done/workflows/stats.md +60 -0
- package/get-shit-done/workflows/transition.md +147 -20
- package/get-shit-done/workflows/ui-phase.md +302 -0
- package/get-shit-done/workflows/ui-review.md +165 -0
- package/get-shit-done/workflows/update.md +108 -25
- package/get-shit-done/workflows/validate-phase.md +15 -8
- package/get-shit-done/workflows/verify-phase.md +16 -5
- package/get-shit-done/workflows/verify-work.md +72 -18
- package/package.json +1 -1
- package/skills/gsd-audit-milestone/SKILL.md +29 -0
- package/skills/gsd-cleanup/SKILL.md +19 -0
- package/skills/gsd-complete-milestone/SKILL.md +131 -0
- package/skills/gsd-discuss-phase/SKILL.md +54 -0
- package/skills/gsd-execute-phase/SKILL.md +49 -0
- package/skills/gsd-plan-phase/SKILL.md +37 -0
- package/skills/gsd-ui-phase/SKILL.md +24 -0
- package/skills/gsd-ui-review/SKILL.md +24 -0
- package/skills/gsd-verify-work/SKILL.md +30 -0
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* Replaces repetitive inline bash patterns across ~50 GSD command/workflow/agent files.
|
|
7
7
|
* Centralizes: config parsing, model resolution, phase lookup, git commits, summary verification.
|
|
8
8
|
*
|
|
9
|
-
* Usage: node gsd-tools.cjs <command> [args] [--raw]
|
|
9
|
+
* Usage: node gsd-tools.cjs <command> [args] [--raw] [--pick <field>]
|
|
10
10
|
*
|
|
11
11
|
* Atomic Commands:
|
|
12
12
|
* state load Load project config + state
|
|
@@ -14,9 +14,13 @@
|
|
|
14
14
|
* state update <field> <value> Update a STATE.md field
|
|
15
15
|
* state get [section] Get STATE.md content or section
|
|
16
16
|
* state patch --field val ... Batch update STATE.md fields
|
|
17
|
+
* state begin-phase --phase N --name S --plans C Update STATE.md for new phase start
|
|
18
|
+
* state signal-waiting --type T --question Q --options "A|B" --phase P write WAITING.json signal
|
|
19
|
+
* state signal-resume Remove WAITING.json signal
|
|
17
20
|
* resolve-model <agent-type> Get model for agent based on profile
|
|
18
21
|
* find-phase <phase> Find phase directory by number
|
|
19
|
-
* commit <message> [--files f1 f2] Commit planning docs
|
|
22
|
+
* commit <message> [--files f1 f2] [--no-verify] Commit planning docs
|
|
23
|
+
* commit-to-subrepo <msg> --files f1 f2 Route commits to sub-repos
|
|
20
24
|
* verify-summary <path> Verify a SUMMARY.md file
|
|
21
25
|
* generate-slug <text> Convert text to URL-safe slug
|
|
22
26
|
* current-timestamp [format] Get timestamp (full|date|filename)
|
|
@@ -32,7 +36,7 @@
|
|
|
32
36
|
*
|
|
33
37
|
* Phase Operations:
|
|
34
38
|
* phase next-decimal <phase> Calculate next decimal phase number
|
|
35
|
-
* phase add <description>
|
|
39
|
+
* phase add <description> [--id ID] Append new phase to roadmap + create dir
|
|
36
40
|
* phase insert <after> <description> Insert decimal phase after existing
|
|
37
41
|
* phase remove <phase> [--force] Remove phase, renumber all subsequent
|
|
38
42
|
* phase complete <phase> Mark phase done, update state + roadmap
|
|
@@ -54,6 +58,7 @@
|
|
|
54
58
|
* Validation:
|
|
55
59
|
* validate consistency Check phase numbering, disk/roadmap sync
|
|
56
60
|
* validate health [--repair] Check .planning/ integrity, optionally repair
|
|
61
|
+
* validate agents Check GSD agent installation status
|
|
57
62
|
*
|
|
58
63
|
* Progress:
|
|
59
64
|
* progress [json|table|bar] Render progress in various formats
|
|
@@ -61,6 +66,10 @@
|
|
|
61
66
|
* Todos:
|
|
62
67
|
* todo complete <filename> Move todo from pending to completed
|
|
63
68
|
*
|
|
69
|
+
* UAT Audit:
|
|
70
|
+
* audit-uat Scan all phases for unresolved UAT/verification items
|
|
71
|
+
* uat render-checkpoint --file <path> Render the current UAT checkpoint block
|
|
72
|
+
*
|
|
64
73
|
* Scaffolding:
|
|
65
74
|
* scaffold context --phase <N> Create CONTEXT.md template
|
|
66
75
|
* scaffold uat --phase <N> Create UAT.md template
|
|
@@ -128,7 +137,8 @@
|
|
|
128
137
|
|
|
129
138
|
const fs = require('fs');
|
|
130
139
|
const path = require('path');
|
|
131
|
-
const
|
|
140
|
+
const core = require('./lib/core.cjs');
|
|
141
|
+
const { error, findProjectRoot, getActiveWorkstream } = core;
|
|
132
142
|
const state = require('./lib/state.cjs');
|
|
133
143
|
const phase = require('./lib/phase.cjs');
|
|
134
144
|
const roadmap = require('./lib/roadmap.cjs');
|
|
@@ -139,6 +149,49 @@ const milestone = require('./lib/milestone.cjs');
|
|
|
139
149
|
const commands = require('./lib/commands.cjs');
|
|
140
150
|
const init = require('./lib/init.cjs');
|
|
141
151
|
const frontmatter = require('./lib/frontmatter.cjs');
|
|
152
|
+
const profilePipeline = require('./lib/profile-pipeline.cjs');
|
|
153
|
+
const profileOutput = require('./lib/profile-output.cjs');
|
|
154
|
+
const workstream = require('./lib/workstream.cjs');
|
|
155
|
+
|
|
156
|
+
// ─── Arg parsing helpers ──────────────────────────────────────────────────────
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Extract named --flag <value> pairs from an args array.
|
|
160
|
+
* Returns an object mapping flag names to their values (null if absent).
|
|
161
|
+
* Flags listed in `booleanFlags` are treated as boolean (no value consumed).
|
|
162
|
+
*
|
|
163
|
+
* parseNamedArgs(args, 'phase', 'plan') → { phase: '3', plan: '1' }
|
|
164
|
+
* parseNamedArgs(args, [], ['amend', 'force']) → { amend: true, force: false }
|
|
165
|
+
*/
|
|
166
|
+
function parseNamedArgs(args, valueFlags = [], booleanFlags = []) {
|
|
167
|
+
const result = {};
|
|
168
|
+
for (const flag of valueFlags) {
|
|
169
|
+
const idx = args.indexOf(`--${flag}`);
|
|
170
|
+
result[flag] = idx !== -1 && args[idx + 1] !== undefined && !args[idx + 1].startsWith('--')
|
|
171
|
+
? args[idx + 1]
|
|
172
|
+
: null;
|
|
173
|
+
}
|
|
174
|
+
for (const flag of booleanFlags) {
|
|
175
|
+
result[flag] = args.includes(`--${flag}`);
|
|
176
|
+
}
|
|
177
|
+
return result;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Collect all tokens after --flag until the next --flag or end of args.
|
|
182
|
+
* Handles multi-word values like --name Foo Bar Version 1.
|
|
183
|
+
* Returns null if the flag is absent.
|
|
184
|
+
*/
|
|
185
|
+
function parseMultiwordArg(args, flag) {
|
|
186
|
+
const idx = args.indexOf(`--${flag}`);
|
|
187
|
+
if (idx === -1) return null;
|
|
188
|
+
const tokens = [];
|
|
189
|
+
for (let i = idx + 1; i < args.length; i++) {
|
|
190
|
+
if (args[i].startsWith('--')) break;
|
|
191
|
+
tokens.push(args[i]);
|
|
192
|
+
}
|
|
193
|
+
return tokens.length > 0 ? tokens.join(' ') : null;
|
|
194
|
+
}
|
|
142
195
|
|
|
143
196
|
// ─── CLI Router ───────────────────────────────────────────────────────────────
|
|
144
197
|
|
|
@@ -165,16 +218,137 @@ async function main() {
|
|
|
165
218
|
error(`Invalid --cwd: ${cwd}`);
|
|
166
219
|
}
|
|
167
220
|
|
|
221
|
+
// Resolve worktree root: in a linked worktree, .planning/ lives in the main worktree.
|
|
222
|
+
// However, in monorepo worktrees where the subdirectory itself owns .planning/,
|
|
223
|
+
// skip worktree resolution — the CWD is already the correct project root.
|
|
224
|
+
const { resolveWorktreeRoot } = require('./lib/core.cjs');
|
|
225
|
+
if (!fs.existsSync(path.join(cwd, '.planning'))) {
|
|
226
|
+
const worktreeRoot = resolveWorktreeRoot(cwd);
|
|
227
|
+
if (worktreeRoot !== cwd) {
|
|
228
|
+
cwd = worktreeRoot;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// Optional workstream override for parallel milestone work.
|
|
233
|
+
// Priority: --ws flag > GSD_WORKSTREAM env var > active-workstream file > null (flat mode)
|
|
234
|
+
const wsEqArg = args.find(arg => arg.startsWith('--ws='));
|
|
235
|
+
const wsIdx = args.indexOf('--ws');
|
|
236
|
+
let ws = null;
|
|
237
|
+
if (wsEqArg) {
|
|
238
|
+
ws = wsEqArg.slice('--ws='.length).trim();
|
|
239
|
+
if (!ws) error('Missing value for --ws');
|
|
240
|
+
args.splice(args.indexOf(wsEqArg), 1);
|
|
241
|
+
} else if (wsIdx !== -1) {
|
|
242
|
+
ws = args[wsIdx + 1];
|
|
243
|
+
if (!ws || ws.startsWith('--')) error('Missing value for --ws');
|
|
244
|
+
args.splice(wsIdx, 2);
|
|
245
|
+
} else if (process.env.GSD_WORKSTREAM) {
|
|
246
|
+
ws = process.env.GSD_WORKSTREAM.trim();
|
|
247
|
+
} else {
|
|
248
|
+
ws = getActiveWorkstream(cwd);
|
|
249
|
+
}
|
|
250
|
+
// Validate workstream name to prevent path traversal attacks.
|
|
251
|
+
if (ws && !/^[a-zA-Z0-9_-]+$/.test(ws)) {
|
|
252
|
+
error('Invalid workstream name: must be alphanumeric, hyphens, and underscores only');
|
|
253
|
+
}
|
|
254
|
+
// Set env var so all modules (planningDir, planningPaths) auto-resolve workstream paths
|
|
255
|
+
if (ws) {
|
|
256
|
+
process.env.GSD_WORKSTREAM = ws;
|
|
257
|
+
}
|
|
258
|
+
|
|
168
259
|
const rawIndex = args.indexOf('--raw');
|
|
169
260
|
const raw = rawIndex !== -1;
|
|
170
261
|
if (rawIndex !== -1) args.splice(rawIndex, 1);
|
|
171
262
|
|
|
263
|
+
// --pick <name>: extract a single field from JSON output (replaces jq dependency).
|
|
264
|
+
// Supports dot-notation (e.g., --pick workflow.research) and bracket notation
|
|
265
|
+
// for arrays (e.g., --pick directories[-1]).
|
|
266
|
+
const pickIdx = args.indexOf('--pick');
|
|
267
|
+
let pickField = null;
|
|
268
|
+
if (pickIdx !== -1) {
|
|
269
|
+
pickField = args[pickIdx + 1];
|
|
270
|
+
if (!pickField || pickField.startsWith('--')) error('Missing value for --pick');
|
|
271
|
+
args.splice(pickIdx, 2);
|
|
272
|
+
}
|
|
273
|
+
|
|
172
274
|
const command = args[0];
|
|
173
275
|
|
|
174
276
|
if (!command) {
|
|
175
|
-
error('Usage: gsd-tools <command> [args] [--raw] [--cwd <path>]\nCommands: state, resolve-model, find-phase, commit, verify-summary, verify, frontmatter, template, generate-slug, current-timestamp, list-todos, verify-path-exists, config-ensure-section, init');
|
|
277
|
+
error('Usage: gsd-tools <command> [args] [--raw] [--pick <field>] [--cwd <path>] [--ws <name>]\nCommands: state, resolve-model, find-phase, commit, verify-summary, verify, frontmatter, template, generate-slug, current-timestamp, list-todos, verify-path-exists, config-ensure-section, config-new-project, init, workstream');
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// Multi-repo guard: resolve project root for commands that read/write .planning/.
|
|
281
|
+
// Skip for pure-utility commands that don't touch .planning/ to avoid unnecessary
|
|
282
|
+
// filesystem traversal on every invocation.
|
|
283
|
+
const SKIP_ROOT_RESOLUTION = new Set([
|
|
284
|
+
'generate-slug', 'current-timestamp', 'verify-path-exists',
|
|
285
|
+
'verify-summary', 'template', 'frontmatter',
|
|
286
|
+
]);
|
|
287
|
+
if (!SKIP_ROOT_RESOLUTION.has(command)) {
|
|
288
|
+
cwd = findProjectRoot(cwd);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// When --pick is active, intercept stdout to extract the requested field.
|
|
292
|
+
if (pickField) {
|
|
293
|
+
const origWriteSync = fs.writeSync;
|
|
294
|
+
const chunks = [];
|
|
295
|
+
fs.writeSync = function (fd, data, ...rest) {
|
|
296
|
+
if (fd === 1) { chunks.push(String(data)); return; }
|
|
297
|
+
return origWriteSync.call(fs, fd, data, ...rest);
|
|
298
|
+
};
|
|
299
|
+
const cleanup = () => {
|
|
300
|
+
fs.writeSync = origWriteSync;
|
|
301
|
+
const captured = chunks.join('');
|
|
302
|
+
let jsonStr = captured;
|
|
303
|
+
if (jsonStr.startsWith('@file:')) {
|
|
304
|
+
jsonStr = fs.readFileSync(jsonStr.slice(6), 'utf-8');
|
|
305
|
+
}
|
|
306
|
+
try {
|
|
307
|
+
const obj = JSON.parse(jsonStr);
|
|
308
|
+
const value = extractField(obj, pickField);
|
|
309
|
+
const result = value === null || value === undefined ? '' : String(value);
|
|
310
|
+
origWriteSync.call(fs, 1, result);
|
|
311
|
+
} catch {
|
|
312
|
+
origWriteSync.call(fs, 1, captured);
|
|
313
|
+
}
|
|
314
|
+
};
|
|
315
|
+
try {
|
|
316
|
+
await runCommand(command, args, cwd, raw);
|
|
317
|
+
cleanup();
|
|
318
|
+
} catch (e) {
|
|
319
|
+
fs.writeSync = origWriteSync;
|
|
320
|
+
throw e;
|
|
321
|
+
}
|
|
322
|
+
return;
|
|
176
323
|
}
|
|
177
324
|
|
|
325
|
+
await runCommand(command, args, cwd, raw);
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Extract a field from an object using dot-notation and bracket syntax.
|
|
330
|
+
* Supports: 'field', 'parent.child', 'arr[-1]', 'arr[0]'
|
|
331
|
+
*/
|
|
332
|
+
function extractField(obj, fieldPath) {
|
|
333
|
+
const parts = fieldPath.split('.');
|
|
334
|
+
let current = obj;
|
|
335
|
+
for (const part of parts) {
|
|
336
|
+
if (current === null || current === undefined) return undefined;
|
|
337
|
+
const bracketMatch = part.match(/^(.+?)\[(-?\d+)]$/);
|
|
338
|
+
if (bracketMatch) {
|
|
339
|
+
const key = bracketMatch[1];
|
|
340
|
+
const index = parseInt(bracketMatch[2], 10);
|
|
341
|
+
current = current[key];
|
|
342
|
+
if (!Array.isArray(current)) return undefined;
|
|
343
|
+
current = index < 0 ? current[current.length + index] : current[index];
|
|
344
|
+
} else {
|
|
345
|
+
current = current[part];
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
return current;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
async function runCommand(command, args, cwd, raw) {
|
|
178
352
|
switch (command) {
|
|
179
353
|
case 'state': {
|
|
180
354
|
const subcommand = args[1];
|
|
@@ -197,50 +371,29 @@ async function main() {
|
|
|
197
371
|
} else if (subcommand === 'advance-plan') {
|
|
198
372
|
state.cmdStateAdvancePlan(cwd, raw);
|
|
199
373
|
} else if (subcommand === 'record-metric') {
|
|
200
|
-
const
|
|
201
|
-
|
|
202
|
-
const durationIdx = args.indexOf('--duration');
|
|
203
|
-
const tasksIdx = args.indexOf('--tasks');
|
|
204
|
-
const filesIdx = args.indexOf('--files');
|
|
205
|
-
state.cmdStateRecordMetric(cwd, {
|
|
206
|
-
phase: phaseIdx !== -1 ? args[phaseIdx + 1] : null,
|
|
207
|
-
plan: planIdx !== -1 ? args[planIdx + 1] : null,
|
|
208
|
-
duration: durationIdx !== -1 ? args[durationIdx + 1] : null,
|
|
209
|
-
tasks: tasksIdx !== -1 ? args[tasksIdx + 1] : null,
|
|
210
|
-
files: filesIdx !== -1 ? args[filesIdx + 1] : null,
|
|
211
|
-
}, raw);
|
|
374
|
+
const { phase: p, plan, duration, tasks, files } = parseNamedArgs(args, ['phase', 'plan', 'duration', 'tasks', 'files']);
|
|
375
|
+
state.cmdStateRecordMetric(cwd, { phase: p, plan, duration, tasks, files }, raw);
|
|
212
376
|
} else if (subcommand === 'update-progress') {
|
|
213
377
|
state.cmdStateUpdateProgress(cwd, raw);
|
|
214
378
|
} else if (subcommand === 'add-decision') {
|
|
215
|
-
const
|
|
216
|
-
|
|
217
|
-
const summaryFileIdx = args.indexOf('--summary-file');
|
|
218
|
-
const rationaleIdx = args.indexOf('--rationale');
|
|
219
|
-
const rationaleFileIdx = args.indexOf('--rationale-file');
|
|
220
|
-
state.cmdStateAddDecision(cwd, {
|
|
221
|
-
phase: phaseIdx !== -1 ? args[phaseIdx + 1] : null,
|
|
222
|
-
summary: summaryIdx !== -1 ? args[summaryIdx + 1] : null,
|
|
223
|
-
summary_file: summaryFileIdx !== -1 ? args[summaryFileIdx + 1] : null,
|
|
224
|
-
rationale: rationaleIdx !== -1 ? args[rationaleIdx + 1] : '',
|
|
225
|
-
rationale_file: rationaleFileIdx !== -1 ? args[rationaleFileIdx + 1] : null,
|
|
226
|
-
}, raw);
|
|
379
|
+
const { phase: p, summary, 'summary-file': summary_file, rationale, 'rationale-file': rationale_file } = parseNamedArgs(args, ['phase', 'summary', 'summary-file', 'rationale', 'rationale-file']);
|
|
380
|
+
state.cmdStateAddDecision(cwd, { phase: p, summary, summary_file, rationale: rationale || '', rationale_file }, raw);
|
|
227
381
|
} else if (subcommand === 'add-blocker') {
|
|
228
|
-
const
|
|
229
|
-
|
|
230
|
-
state.cmdStateAddBlocker(cwd, {
|
|
231
|
-
text: textIdx !== -1 ? args[textIdx + 1] : null,
|
|
232
|
-
text_file: textFileIdx !== -1 ? args[textFileIdx + 1] : null,
|
|
233
|
-
}, raw);
|
|
382
|
+
const { text, 'text-file': text_file } = parseNamedArgs(args, ['text', 'text-file']);
|
|
383
|
+
state.cmdStateAddBlocker(cwd, { text, text_file }, raw);
|
|
234
384
|
} else if (subcommand === 'resolve-blocker') {
|
|
235
|
-
|
|
236
|
-
state.cmdStateResolveBlocker(cwd, textIdx !== -1 ? args[textIdx + 1] : null, raw);
|
|
385
|
+
state.cmdStateResolveBlocker(cwd, parseNamedArgs(args, ['text']).text, raw);
|
|
237
386
|
} else if (subcommand === 'record-session') {
|
|
238
|
-
const
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
387
|
+
const { 'stopped-at': stopped_at, 'resume-file': resume_file } = parseNamedArgs(args, ['stopped-at', 'resume-file']);
|
|
388
|
+
state.cmdStateRecordSession(cwd, { stopped_at, resume_file: resume_file || 'None' }, raw);
|
|
389
|
+
} else if (subcommand === 'begin-phase') {
|
|
390
|
+
const { phase: p, name, plans } = parseNamedArgs(args, ['phase', 'name', 'plans']);
|
|
391
|
+
state.cmdStateBeginPhase(cwd, p, name, plans !== null ? parseInt(plans, 10) : null, raw);
|
|
392
|
+
} else if (subcommand === 'signal-waiting') {
|
|
393
|
+
const { type, question, options, phase: p } = parseNamedArgs(args, ['type', 'question', 'options', 'phase']);
|
|
394
|
+
state.cmdSignalWaiting(cwd, type, question, options, p, raw);
|
|
395
|
+
} else if (subcommand === 'signal-resume') {
|
|
396
|
+
state.cmdSignalResume(cwd, raw);
|
|
244
397
|
} else {
|
|
245
398
|
state.cmdStateLoad(cwd, raw);
|
|
246
399
|
}
|
|
@@ -259,6 +412,7 @@ async function main() {
|
|
|
259
412
|
|
|
260
413
|
case 'commit': {
|
|
261
414
|
const amend = args.includes('--amend');
|
|
415
|
+
const noVerify = args.includes('--no-verify');
|
|
262
416
|
const filesIndex = args.indexOf('--files');
|
|
263
417
|
// Collect all positional args between command name and first flag,
|
|
264
418
|
// then join them — handles both quoted ("multi word msg") and
|
|
@@ -267,7 +421,15 @@ async function main() {
|
|
|
267
421
|
const messageArgs = args.slice(1, endIndex).filter(a => !a.startsWith('--'));
|
|
268
422
|
const message = messageArgs.join(' ') || undefined;
|
|
269
423
|
const files = filesIndex !== -1 ? args.slice(filesIndex + 1).filter(a => !a.startsWith('--')) : [];
|
|
270
|
-
commands.cmdCommit(cwd, message, files, raw, amend);
|
|
424
|
+
commands.cmdCommit(cwd, message, files, raw, amend, noVerify);
|
|
425
|
+
break;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
case 'commit-to-subrepo': {
|
|
429
|
+
const message = args[1];
|
|
430
|
+
const filesIndex = args.indexOf('--files');
|
|
431
|
+
const files = filesIndex !== -1 ? args.slice(filesIndex + 1).filter(a => !a.startsWith('--')) : [];
|
|
432
|
+
commands.cmdCommitToSubrepo(cwd, message, files, raw);
|
|
271
433
|
break;
|
|
272
434
|
}
|
|
273
435
|
|
|
@@ -285,19 +447,18 @@ async function main() {
|
|
|
285
447
|
template.cmdTemplateSelect(cwd, args[2], raw);
|
|
286
448
|
} else if (subcommand === 'fill') {
|
|
287
449
|
const templateType = args[2];
|
|
288
|
-
const
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
450
|
+
const { phase, plan, name, type, wave, fields: fieldsRaw } = parseNamedArgs(args, ['phase', 'plan', 'name', 'type', 'wave', 'fields']);
|
|
451
|
+
let fields = {};
|
|
452
|
+
if (fieldsRaw) {
|
|
453
|
+
const { safeJsonParse } = require('./lib/security.cjs');
|
|
454
|
+
const result = safeJsonParse(fieldsRaw, { label: '--fields' });
|
|
455
|
+
if (!result.ok) error(result.error);
|
|
456
|
+
fields = result.value;
|
|
457
|
+
}
|
|
294
458
|
template.cmdTemplateFill(cwd, templateType, {
|
|
295
|
-
phase
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
type: typeIdx !== -1 ? args[typeIdx + 1] : 'execute',
|
|
299
|
-
wave: waveIdx !== -1 ? args[waveIdx + 1] : '1',
|
|
300
|
-
fields: fieldsIdx !== -1 ? JSON.parse(args[fieldsIdx + 1]) : {},
|
|
459
|
+
phase, plan, name, fields,
|
|
460
|
+
type: type || 'execute',
|
|
461
|
+
wave: wave || '1',
|
|
301
462
|
}, raw);
|
|
302
463
|
} else {
|
|
303
464
|
error('Unknown template subcommand. Available: select, fill');
|
|
@@ -309,18 +470,14 @@ async function main() {
|
|
|
309
470
|
const subcommand = args[1];
|
|
310
471
|
const file = args[2];
|
|
311
472
|
if (subcommand === 'get') {
|
|
312
|
-
|
|
313
|
-
frontmatter.cmdFrontmatterGet(cwd, file, fieldIdx !== -1 ? args[fieldIdx + 1] : null, raw);
|
|
473
|
+
frontmatter.cmdFrontmatterGet(cwd, file, parseNamedArgs(args, ['field']).field, raw);
|
|
314
474
|
} else if (subcommand === 'set') {
|
|
315
|
-
const
|
|
316
|
-
|
|
317
|
-
frontmatter.cmdFrontmatterSet(cwd, file, fieldIdx !== -1 ? args[fieldIdx + 1] : null, valueIdx !== -1 ? args[valueIdx + 1] : undefined, raw);
|
|
475
|
+
const { field, value } = parseNamedArgs(args, ['field', 'value']);
|
|
476
|
+
frontmatter.cmdFrontmatterSet(cwd, file, field, value !== null ? value : undefined, raw);
|
|
318
477
|
} else if (subcommand === 'merge') {
|
|
319
|
-
|
|
320
|
-
frontmatter.cmdFrontmatterMerge(cwd, file, dataIdx !== -1 ? args[dataIdx + 1] : null, raw);
|
|
478
|
+
frontmatter.cmdFrontmatterMerge(cwd, file, parseNamedArgs(args, ['data']).data, raw);
|
|
321
479
|
} else if (subcommand === 'validate') {
|
|
322
|
-
|
|
323
|
-
frontmatter.cmdFrontmatterValidate(cwd, file, schemaIdx !== -1 ? args[schemaIdx + 1] : null, raw);
|
|
480
|
+
frontmatter.cmdFrontmatterValidate(cwd, file, parseNamedArgs(args, ['schema']).schema, raw);
|
|
324
481
|
} else {
|
|
325
482
|
error('Unknown frontmatter subcommand. Available: get, set, merge, validate');
|
|
326
483
|
}
|
|
@@ -377,11 +534,26 @@ async function main() {
|
|
|
377
534
|
break;
|
|
378
535
|
}
|
|
379
536
|
|
|
537
|
+
case "config-set-model-profile": {
|
|
538
|
+
config.cmdConfigSetModelProfile(cwd, args[1], raw);
|
|
539
|
+
break;
|
|
540
|
+
}
|
|
541
|
+
|
|
380
542
|
case 'config-get': {
|
|
381
543
|
config.cmdConfigGet(cwd, args[1], raw);
|
|
382
544
|
break;
|
|
383
545
|
}
|
|
384
546
|
|
|
547
|
+
case 'config-new-project': {
|
|
548
|
+
config.cmdConfigNewProject(cwd, args[1], raw);
|
|
549
|
+
break;
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
case 'agent-skills': {
|
|
553
|
+
init.cmdAgentSkills(cwd, args[1], raw);
|
|
554
|
+
break;
|
|
555
|
+
}
|
|
556
|
+
|
|
385
557
|
case 'history-digest': {
|
|
386
558
|
commands.cmdHistoryDigest(cwd, raw);
|
|
387
559
|
break;
|
|
@@ -433,7 +605,18 @@ async function main() {
|
|
|
433
605
|
if (subcommand === 'next-decimal') {
|
|
434
606
|
phase.cmdPhaseNextDecimal(cwd, args[2], raw);
|
|
435
607
|
} else if (subcommand === 'add') {
|
|
436
|
-
|
|
608
|
+
const idIdx = args.indexOf('--id');
|
|
609
|
+
let customId = null;
|
|
610
|
+
const descArgs = [];
|
|
611
|
+
for (let i = 2; i < args.length; i++) {
|
|
612
|
+
if (args[i] === '--id' && i + 1 < args.length) {
|
|
613
|
+
customId = args[i + 1];
|
|
614
|
+
i++; // skip value
|
|
615
|
+
} else {
|
|
616
|
+
descArgs.push(args[i]);
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
phase.cmdPhaseAdd(cwd, descArgs.join(' '), raw, customId);
|
|
437
620
|
} else if (subcommand === 'insert') {
|
|
438
621
|
phase.cmdPhaseInsert(cwd, args[2], args.slice(3).join(' '), raw);
|
|
439
622
|
} else if (subcommand === 'remove') {
|
|
@@ -450,18 +633,8 @@ async function main() {
|
|
|
450
633
|
case 'milestone': {
|
|
451
634
|
const subcommand = args[1];
|
|
452
635
|
if (subcommand === 'complete') {
|
|
453
|
-
const
|
|
636
|
+
const milestoneName = parseMultiwordArg(args, 'name');
|
|
454
637
|
const archivePhases = args.includes('--archive-phases');
|
|
455
|
-
// Collect --name value (everything after --name until next flag or end)
|
|
456
|
-
let milestoneName = null;
|
|
457
|
-
if (nameIndex !== -1) {
|
|
458
|
-
const nameArgs = [];
|
|
459
|
-
for (let i = nameIndex + 1; i < args.length; i++) {
|
|
460
|
-
if (args[i].startsWith('--')) break;
|
|
461
|
-
nameArgs.push(args[i]);
|
|
462
|
-
}
|
|
463
|
-
milestoneName = nameArgs.join(' ') || null;
|
|
464
|
-
}
|
|
465
638
|
milestone.cmdMilestoneComplete(cwd, args[2], { name: milestoneName, archivePhases }, raw);
|
|
466
639
|
} else {
|
|
467
640
|
error('Unknown milestone subcommand. Available: complete');
|
|
@@ -476,8 +649,10 @@ async function main() {
|
|
|
476
649
|
} else if (subcommand === 'health') {
|
|
477
650
|
const repairFlag = args.includes('--repair');
|
|
478
651
|
verify.cmdValidateHealth(cwd, { repair: repairFlag }, raw);
|
|
652
|
+
} else if (subcommand === 'agents') {
|
|
653
|
+
verify.cmdValidateAgents(cwd, raw);
|
|
479
654
|
} else {
|
|
480
|
-
error('Unknown validate subcommand. Available: consistency, health');
|
|
655
|
+
error('Unknown validate subcommand. Available: consistency, health, agents');
|
|
481
656
|
}
|
|
482
657
|
break;
|
|
483
658
|
}
|
|
@@ -488,23 +663,47 @@ async function main() {
|
|
|
488
663
|
break;
|
|
489
664
|
}
|
|
490
665
|
|
|
666
|
+
case 'audit-uat': {
|
|
667
|
+
const uat = require('./lib/uat.cjs');
|
|
668
|
+
uat.cmdAuditUat(cwd, raw);
|
|
669
|
+
break;
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
case 'uat': {
|
|
673
|
+
const subcommand = args[1];
|
|
674
|
+
const uat = require('./lib/uat.cjs');
|
|
675
|
+
if (subcommand === 'render-checkpoint') {
|
|
676
|
+
const options = parseNamedArgs(args, ['file']);
|
|
677
|
+
uat.cmdRenderCheckpoint(cwd, options, raw);
|
|
678
|
+
} else {
|
|
679
|
+
error('Unknown uat subcommand. Available: render-checkpoint');
|
|
680
|
+
}
|
|
681
|
+
break;
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
case 'stats': {
|
|
685
|
+
const subcommand = args[1] || 'json';
|
|
686
|
+
commands.cmdStats(cwd, subcommand, raw);
|
|
687
|
+
break;
|
|
688
|
+
}
|
|
689
|
+
|
|
491
690
|
case 'todo': {
|
|
492
691
|
const subcommand = args[1];
|
|
493
692
|
if (subcommand === 'complete') {
|
|
494
693
|
commands.cmdTodoComplete(cwd, args[2], raw);
|
|
694
|
+
} else if (subcommand === 'match-phase') {
|
|
695
|
+
commands.cmdTodoMatchPhase(cwd, args[2], raw);
|
|
495
696
|
} else {
|
|
496
|
-
error('Unknown todo subcommand. Available: complete');
|
|
697
|
+
error('Unknown todo subcommand. Available: complete, match-phase');
|
|
497
698
|
}
|
|
498
699
|
break;
|
|
499
700
|
}
|
|
500
701
|
|
|
501
702
|
case 'scaffold': {
|
|
502
703
|
const scaffoldType = args[1];
|
|
503
|
-
const phaseIndex = args.indexOf('--phase');
|
|
504
|
-
const nameIndex = args.indexOf('--name');
|
|
505
704
|
const scaffoldOptions = {
|
|
506
|
-
phase:
|
|
507
|
-
name:
|
|
705
|
+
phase: parseNamedArgs(args, ['phase']).phase,
|
|
706
|
+
name: parseMultiwordArg(args, 'name'),
|
|
508
707
|
};
|
|
509
708
|
commands.cmdScaffold(cwd, scaffoldType, scaffoldOptions, raw);
|
|
510
709
|
break;
|
|
@@ -549,8 +748,20 @@ async function main() {
|
|
|
549
748
|
case 'progress':
|
|
550
749
|
init.cmdInitProgress(cwd, raw);
|
|
551
750
|
break;
|
|
751
|
+
case 'manager':
|
|
752
|
+
init.cmdInitManager(cwd, raw);
|
|
753
|
+
break;
|
|
754
|
+
case 'new-workspace':
|
|
755
|
+
init.cmdInitNewWorkspace(cwd, raw);
|
|
756
|
+
break;
|
|
757
|
+
case 'list-workspaces':
|
|
758
|
+
init.cmdInitListWorkspaces(cwd, raw);
|
|
759
|
+
break;
|
|
760
|
+
case 'remove-workspace':
|
|
761
|
+
init.cmdInitRemoveWorkspace(cwd, args[2], raw);
|
|
762
|
+
break;
|
|
552
763
|
default:
|
|
553
|
-
error(`Unknown init workflow: ${workflow}\nAvailable: execute-phase, plan-phase, new-project, new-milestone, quick, resume, verify-work, phase-op, todos, milestone-op, map-codebase, progress`);
|
|
764
|
+
error(`Unknown init workflow: ${workflow}\nAvailable: execute-phase, plan-phase, new-project, new-milestone, quick, resume, verify-work, phase-op, todos, milestone-op, map-codebase, progress, manager, new-workspace, list-workspaces, remove-workspace`);
|
|
554
765
|
}
|
|
555
766
|
break;
|
|
556
767
|
}
|
|
@@ -584,6 +795,121 @@ async function main() {
|
|
|
584
795
|
break;
|
|
585
796
|
}
|
|
586
797
|
|
|
798
|
+
// ─── Profiling Pipeline ────────────────────────────────────────────────
|
|
799
|
+
|
|
800
|
+
case 'scan-sessions': {
|
|
801
|
+
const pathIdx = args.indexOf('--path');
|
|
802
|
+
const sessionsPath = pathIdx !== -1 ? args[pathIdx + 1] : null;
|
|
803
|
+
const verboseFlag = args.includes('--verbose');
|
|
804
|
+
const jsonFlag = args.includes('--json');
|
|
805
|
+
await profilePipeline.cmdScanSessions(sessionsPath, { verbose: verboseFlag, json: jsonFlag }, raw);
|
|
806
|
+
break;
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
case 'extract-messages': {
|
|
810
|
+
const sessionIdx = args.indexOf('--session');
|
|
811
|
+
const sessionId = sessionIdx !== -1 ? args[sessionIdx + 1] : null;
|
|
812
|
+
const limitIdx = args.indexOf('--limit');
|
|
813
|
+
const limit = limitIdx !== -1 ? parseInt(args[limitIdx + 1], 10) : null;
|
|
814
|
+
const pathIdx = args.indexOf('--path');
|
|
815
|
+
const sessionsPath = pathIdx !== -1 ? args[pathIdx + 1] : null;
|
|
816
|
+
const projectArg = args[1];
|
|
817
|
+
if (!projectArg || projectArg.startsWith('--')) {
|
|
818
|
+
error('Usage: gsd-tools extract-messages <project> [--session <id>] [--limit N] [--path <dir>]\nRun scan-sessions first to see available projects.');
|
|
819
|
+
}
|
|
820
|
+
await profilePipeline.cmdExtractMessages(projectArg, { sessionId, limit }, raw, sessionsPath);
|
|
821
|
+
break;
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
case 'profile-sample': {
|
|
825
|
+
const pathIdx = args.indexOf('--path');
|
|
826
|
+
const sessionsPath = pathIdx !== -1 ? args[pathIdx + 1] : null;
|
|
827
|
+
const limitIdx = args.indexOf('--limit');
|
|
828
|
+
const limit = limitIdx !== -1 ? parseInt(args[limitIdx + 1], 10) : 150;
|
|
829
|
+
const maxPerIdx = args.indexOf('--max-per-project');
|
|
830
|
+
const maxPerProject = maxPerIdx !== -1 ? parseInt(args[maxPerIdx + 1], 10) : null;
|
|
831
|
+
const maxCharsIdx = args.indexOf('--max-chars');
|
|
832
|
+
const maxChars = maxCharsIdx !== -1 ? parseInt(args[maxCharsIdx + 1], 10) : 500;
|
|
833
|
+
await profilePipeline.cmdProfileSample(sessionsPath, { limit, maxPerProject, maxChars }, raw);
|
|
834
|
+
break;
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
// ─── Profile Output ──────────────────────────────────────────────────
|
|
838
|
+
|
|
839
|
+
case 'write-profile': {
|
|
840
|
+
const inputIdx = args.indexOf('--input');
|
|
841
|
+
const inputPath = inputIdx !== -1 ? args[inputIdx + 1] : null;
|
|
842
|
+
if (!inputPath) error('--input <analysis-json-path> is required');
|
|
843
|
+
const outputIdx = args.indexOf('--output');
|
|
844
|
+
const outputPath = outputIdx !== -1 ? args[outputIdx + 1] : null;
|
|
845
|
+
profileOutput.cmdWriteProfile(cwd, { input: inputPath, output: outputPath }, raw);
|
|
846
|
+
break;
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
case 'profile-questionnaire': {
|
|
850
|
+
const answersIdx = args.indexOf('--answers');
|
|
851
|
+
const answers = answersIdx !== -1 ? args[answersIdx + 1] : null;
|
|
852
|
+
profileOutput.cmdProfileQuestionnaire({ answers }, raw);
|
|
853
|
+
break;
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
case 'generate-dev-preferences': {
|
|
857
|
+
const analysisIdx = args.indexOf('--analysis');
|
|
858
|
+
const analysisPath = analysisIdx !== -1 ? args[analysisIdx + 1] : null;
|
|
859
|
+
const outputIdx = args.indexOf('--output');
|
|
860
|
+
const outputPath = outputIdx !== -1 ? args[outputIdx + 1] : null;
|
|
861
|
+
const stackIdx = args.indexOf('--stack');
|
|
862
|
+
const stack = stackIdx !== -1 ? args[stackIdx + 1] : null;
|
|
863
|
+
profileOutput.cmdGenerateDevPreferences(cwd, { analysis: analysisPath, output: outputPath, stack }, raw);
|
|
864
|
+
break;
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
case 'generate-OpenCode-profile': {
|
|
868
|
+
const analysisIdx = args.indexOf('--analysis');
|
|
869
|
+
const analysisPath = analysisIdx !== -1 ? args[analysisIdx + 1] : null;
|
|
870
|
+
const outputIdx = args.indexOf('--output');
|
|
871
|
+
const outputPath = outputIdx !== -1 ? args[outputIdx + 1] : null;
|
|
872
|
+
const globalFlag = args.includes('--global');
|
|
873
|
+
profileOutput.cmdGenerateClaudeProfile(cwd, { analysis: analysisPath, output: outputPath, global: globalFlag }, raw);
|
|
874
|
+
break;
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
case 'generate-OpenCode-md': {
|
|
878
|
+
const outputIdx = args.indexOf('--output');
|
|
879
|
+
const outputPath = outputIdx !== -1 ? args[outputIdx + 1] : null;
|
|
880
|
+
const autoFlag = args.includes('--auto');
|
|
881
|
+
const forceFlag = args.includes('--force');
|
|
882
|
+
profileOutput.cmdGenerateClaudeMd(cwd, { output: outputPath, auto: autoFlag, force: forceFlag }, raw);
|
|
883
|
+
break;
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
case 'workstream': {
|
|
887
|
+
const subcommand = args[1];
|
|
888
|
+
if (subcommand === 'create') {
|
|
889
|
+
const migrateNameIdx = args.indexOf('--migrate-name');
|
|
890
|
+
const noMigrate = args.includes('--no-migrate');
|
|
891
|
+
workstream.cmdWorkstreamCreate(cwd, args[2], {
|
|
892
|
+
migrate: !noMigrate,
|
|
893
|
+
migrateName: migrateNameIdx !== -1 ? args[migrateNameIdx + 1] : null,
|
|
894
|
+
}, raw);
|
|
895
|
+
} else if (subcommand === 'list') {
|
|
896
|
+
workstream.cmdWorkstreamList(cwd, raw);
|
|
897
|
+
} else if (subcommand === 'status') {
|
|
898
|
+
workstream.cmdWorkstreamStatus(cwd, args[2], raw);
|
|
899
|
+
} else if (subcommand === 'complete') {
|
|
900
|
+
workstream.cmdWorkstreamComplete(cwd, args[2], {}, raw);
|
|
901
|
+
} else if (subcommand === 'set') {
|
|
902
|
+
workstream.cmdWorkstreamSet(cwd, args[2], raw);
|
|
903
|
+
} else if (subcommand === 'get') {
|
|
904
|
+
workstream.cmdWorkstreamGet(cwd, raw);
|
|
905
|
+
} else if (subcommand === 'progress') {
|
|
906
|
+
workstream.cmdWorkstreamProgress(cwd, raw);
|
|
907
|
+
} else {
|
|
908
|
+
error('Unknown workstream subcommand. Available: create, list, status, complete, set, get, progress');
|
|
909
|
+
}
|
|
910
|
+
break;
|
|
911
|
+
}
|
|
912
|
+
|
|
587
913
|
default:
|
|
588
914
|
error(`Unknown command: ${command}`);
|
|
589
915
|
}
|