gsd-lite 0.4.0 → 0.4.1
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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/install.js +1 -1
- package/package.json +3 -2
- package/src/schema.js +31 -0
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"name": "gsd",
|
|
14
14
|
"source": "./",
|
|
15
15
|
"description": "AI orchestration tool — GSD management shell + Superpowers quality core. 5 commands, 4 agents, 5 workflows, MCP server, context monitoring.",
|
|
16
|
-
"version": "0.4.
|
|
16
|
+
"version": "0.4.1",
|
|
17
17
|
"keywords": [
|
|
18
18
|
"orchestration",
|
|
19
19
|
"mcp",
|
package/install.js
CHANGED
|
@@ -136,7 +136,7 @@ export function main() {
|
|
|
136
136
|
copyDir(localNM, join(RUNTIME_DIR, 'node_modules'), 'runtime/node_modules (copied)');
|
|
137
137
|
} else if (!DRY_RUN) {
|
|
138
138
|
log(' ⧗ Installing runtime dependencies...');
|
|
139
|
-
execSync('npm
|
|
139
|
+
execSync('npm ci --omit=dev', { cwd: RUNTIME_DIR, stdio: 'pipe' });
|
|
140
140
|
log(' ✓ runtime dependencies installed');
|
|
141
141
|
} else {
|
|
142
142
|
log(' [dry-run] Would install runtime dependencies');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gsd-lite",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "AI orchestration tool for Claude Code — GSD management shell + Superpowers quality core",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -39,7 +39,8 @@
|
|
|
39
39
|
"cli.js",
|
|
40
40
|
"launcher.js",
|
|
41
41
|
"install.js",
|
|
42
|
-
"uninstall.js"
|
|
42
|
+
"uninstall.js",
|
|
43
|
+
"package-lock.json"
|
|
43
44
|
],
|
|
44
45
|
"engines": {
|
|
45
46
|
"node": ">=20.0.0"
|
package/src/schema.js
CHANGED
|
@@ -387,6 +387,37 @@ export function validateState(state) {
|
|
|
387
387
|
}
|
|
388
388
|
}
|
|
389
389
|
}
|
|
390
|
+
// P2-9: workflow_mode consistency — reviewing modes require matching current_review
|
|
391
|
+
if (state.workflow_mode === 'reviewing_phase' || state.workflow_mode === 'reviewing_task') {
|
|
392
|
+
const expectedScope = state.workflow_mode === 'reviewing_phase' ? 'phase' : 'task';
|
|
393
|
+
if (!state.current_review || state.current_review.scope !== expectedScope) {
|
|
394
|
+
errors.push(`workflow_mode "${state.workflow_mode}" requires current_review with scope="${expectedScope}"`);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
// P2-9: current_review.scope_id must reference an existing phase or task
|
|
398
|
+
if (state.current_review && state.current_review.scope_id != null && Array.isArray(state.phases)) {
|
|
399
|
+
if (state.current_review.scope === 'phase') {
|
|
400
|
+
if (!state.phases.some(p => p.id === state.current_review.scope_id)) {
|
|
401
|
+
errors.push(`current_review.scope_id ${state.current_review.scope_id} references non-existent phase`);
|
|
402
|
+
}
|
|
403
|
+
} else if (state.current_review.scope === 'task') {
|
|
404
|
+
const curPhase = state.phases.find(p => p.id === state.current_phase);
|
|
405
|
+
if (curPhase && Array.isArray(curPhase.todo) && !curPhase.todo.some(t => t.id === state.current_review.scope_id)) {
|
|
406
|
+
errors.push(`current_review.scope_id "${state.current_review.scope_id}" references non-existent task in phase ${state.current_phase}`);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
// P2-9: accepted phase must not contain non-accepted tasks
|
|
411
|
+
if (Array.isArray(state.phases)) {
|
|
412
|
+
for (const phase of state.phases) {
|
|
413
|
+
if (phase.lifecycle === 'accepted' && Array.isArray(phase.todo)) {
|
|
414
|
+
const nonAccepted = phase.todo.filter(t => t.lifecycle !== 'accepted');
|
|
415
|
+
if (nonAccepted.length > 0) {
|
|
416
|
+
errors.push(`Accepted phase ${phase.id} contains non-accepted tasks: ${nonAccepted.map(t => `${t.id}:${t.lifecycle}`).join(', ')}`);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
}
|
|
390
421
|
if (Array.isArray(state.phases)) {
|
|
391
422
|
if (typeof state.total_phases === 'number' && state.total_phases !== state.phases.length) {
|
|
392
423
|
errors.push(`total_phases (${state.total_phases}) does not match phases.length (${state.phases.length})`);
|