@tekyzinc/gsd-t 3.12.15 → 3.13.11
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/CHANGELOG.md +58 -0
- package/bin/gsd-t-unattended-safety.cjs +1 -1
- package/bin/gsd-t-unattended-safety.js +1 -1
- package/bin/gsd-t-unattended.cjs +110 -3
- package/bin/gsd-t-unattended.js +5 -1
- package/bin/headless-auto-spawn.cjs +19 -0
- package/bin/unattended-watch-format.cjs +36 -12
- package/bin/watch-progress.js +155 -0
- package/commands/gsd-t-complete-milestone.md +88 -0
- package/commands/gsd-t-debug.md +52 -0
- package/commands/gsd-t-execute.md +48 -0
- package/commands/gsd-t-feature.md +44 -0
- package/commands/gsd-t-gap-analysis.md +40 -0
- package/commands/gsd-t-integrate.md +52 -0
- package/commands/gsd-t-milestone.md +28 -0
- package/commands/gsd-t-partition.md +52 -0
- package/commands/gsd-t-plan.md +44 -0
- package/commands/gsd-t-project.md +32 -0
- package/commands/gsd-t-quick.md +44 -0
- package/commands/gsd-t-resume.md +40 -0
- package/commands/gsd-t-scan.md +56 -0
- package/commands/gsd-t-test-sync.md +40 -0
- package/commands/gsd-t-unattended-watch.md +10 -3
- package/commands/gsd-t-unattended.md +20 -0
- package/commands/gsd-t-verify.md +48 -0
- package/commands/gsd-t-wave.md +28 -0
- package/package.json +1 -1
- package/scripts/gsd-t-watch-state.js +170 -0
package/commands/gsd-t-verify.md
CHANGED
|
@@ -23,6 +23,10 @@ Per `.gsd-t/contracts/model-selection-contract.md` v1.0.0.
|
|
|
23
23
|
|
|
24
24
|
## Step 1: Load State
|
|
25
25
|
|
|
26
|
+
```bash
|
|
27
|
+
node scripts/gsd-t-watch-state.js advance --agent-id "$GSD_T_AGENT_ID" --parent-id "${GSD_T_PARENT_AGENT_ID:-null}" --command gsd-t-verify --step 1 --step-label "Load State" 2>/dev/null || true
|
|
28
|
+
```
|
|
29
|
+
|
|
26
30
|
Read:
|
|
27
31
|
1. `CLAUDE.md`
|
|
28
32
|
2. `.gsd-t/progress.md` — confirm status is INTEGRATED
|
|
@@ -33,6 +37,10 @@ Read:
|
|
|
33
37
|
|
|
34
38
|
## Step 1.5: Graph-Enhanced Traceability Check
|
|
35
39
|
|
|
40
|
+
```bash
|
|
41
|
+
node scripts/gsd-t-watch-state.js advance --agent-id "$GSD_T_AGENT_ID" --parent-id "${GSD_T_PARENT_AGENT_ID:-null}" --command gsd-t-verify --step 1 --step-label ".5: Graph-Enhanced Traceability Check" 2>/dev/null || true
|
|
42
|
+
```
|
|
43
|
+
|
|
36
44
|
If `.gsd-t/graph/meta.json` exists (graph index is available):
|
|
37
45
|
1. Query `getRequirementFor` on implemented entities to build a requirement-to-code traceability chain — flag entities with no requirement mapping
|
|
38
46
|
2. Query `getDomainBoundaryViolations` to verify no cross-domain boundary violations exist in the final codebase
|
|
@@ -42,6 +50,10 @@ If graph is not available, skip this step.
|
|
|
42
50
|
|
|
43
51
|
## Step 2: Full Test Audit (Inline)
|
|
44
52
|
|
|
53
|
+
```bash
|
|
54
|
+
node scripts/gsd-t-watch-state.js advance --agent-id "$GSD_T_AGENT_ID" --parent-id "${GSD_T_PARENT_AGENT_ID:-null}" --command gsd-t-verify --step 2 --step-label "Full Test Audit (Inline)" 2>/dev/null || true
|
|
55
|
+
```
|
|
56
|
+
|
|
45
57
|
Run the full test audit directly:
|
|
46
58
|
|
|
47
59
|
1. Run the full test suite: `npm test` (or project equivalent) — record pass/fail counts
|
|
@@ -54,6 +66,10 @@ Verification cannot complete if any test fails or critical contract gaps remain.
|
|
|
54
66
|
|
|
55
67
|
## Step 2.5: High-Risk Domain Gate (MANDATORY — Categories 2 and 7)
|
|
56
68
|
|
|
69
|
+
```bash
|
|
70
|
+
node scripts/gsd-t-watch-state.js advance --agent-id "$GSD_T_AGENT_ID" --parent-id "${GSD_T_PARENT_AGENT_ID:-null}" --command gsd-t-verify --step 2 --step-label ".5: High-Risk Domain Gate (MANDATORY — Categories 2 and 7)" 2>/dev/null || true
|
|
71
|
+
```
|
|
72
|
+
|
|
57
73
|
Before running standard verification dimensions, check whether this milestone involves any high-risk domain:
|
|
58
74
|
|
|
59
75
|
**High-risk domains**: audio capture/playback, GPU/WebGPU/WebGL, ML/inference/model loading, background workers, native APIs (camera, bluetooth, filesystem), IPC, WebAssembly, real-time data streams.
|
|
@@ -85,6 +101,10 @@ For each such feature:
|
|
|
85
101
|
|
|
86
102
|
## Step 3: Define Verification Dimensions
|
|
87
103
|
|
|
104
|
+
```bash
|
|
105
|
+
node scripts/gsd-t-watch-state.js advance --agent-id "$GSD_T_AGENT_ID" --parent-id "${GSD_T_PARENT_AGENT_ID:-null}" --command gsd-t-verify --step 3 --step-label "Define Verification Dimensions" 2>/dev/null || true
|
|
106
|
+
```
|
|
107
|
+
|
|
88
108
|
Standard dimensions (adjust based on project):
|
|
89
109
|
|
|
90
110
|
1. **Functional Correctness**: Does it work per requirements?
|
|
@@ -115,6 +135,10 @@ Standard dimensions (adjust based on project):
|
|
|
115
135
|
|
|
116
136
|
## Step 4: Execute Verification
|
|
117
137
|
|
|
138
|
+
```bash
|
|
139
|
+
node scripts/gsd-t-watch-state.js advance --agent-id "$GSD_T_AGENT_ID" --parent-id "${GSD_T_PARENT_AGENT_ID:-null}" --command gsd-t-verify --step 4 --step-label "Execute Verification" 2>/dev/null || true
|
|
140
|
+
```
|
|
141
|
+
|
|
118
142
|
### Solo Mode (default)
|
|
119
143
|
Work through each dimension sequentially. For each:
|
|
120
144
|
1. Define what you're checking
|
|
@@ -188,6 +212,10 @@ Collect all reports, synthesize, create remediation plan.
|
|
|
188
212
|
|
|
189
213
|
## Step 5: Compile Verification Report
|
|
190
214
|
|
|
215
|
+
```bash
|
|
216
|
+
node scripts/gsd-t-watch-state.js advance --agent-id "$GSD_T_AGENT_ID" --parent-id "${GSD_T_PARENT_AGENT_ID:-null}" --command gsd-t-verify --step 5 --step-label "Compile Verification Report" 2>/dev/null || true
|
|
217
|
+
```
|
|
218
|
+
|
|
191
219
|
Create or update `.gsd-t/verify-report.md`:
|
|
192
220
|
|
|
193
221
|
```markdown
|
|
@@ -226,6 +254,10 @@ Create or update `.gsd-t/verify-report.md`:
|
|
|
226
254
|
|
|
227
255
|
## Step 5.25: Metrics Quality Budget Check
|
|
228
256
|
|
|
257
|
+
```bash
|
|
258
|
+
node scripts/gsd-t-watch-state.js advance --agent-id "$GSD_T_AGENT_ID" --parent-id "${GSD_T_PARENT_AGENT_ID:-null}" --command gsd-t-verify --step 5 --step-label ".25: Metrics Quality Budget Check" 2>/dev/null || true
|
|
259
|
+
```
|
|
260
|
+
|
|
229
261
|
Check task-metrics for the current milestone to detect quality budget violations:
|
|
230
262
|
|
|
231
263
|
1. Run via Bash:
|
|
@@ -241,6 +273,10 @@ Check task-metrics for the current milestone to detect quality budget violations
|
|
|
241
273
|
|
|
242
274
|
## Step 5.5: Goal-Backward Verification (Post-Gate Behavior Check)
|
|
243
275
|
|
|
276
|
+
```bash
|
|
277
|
+
node scripts/gsd-t-watch-state.js advance --agent-id "$GSD_T_AGENT_ID" --parent-id "${GSD_T_PARENT_AGENT_ID:-null}" --command gsd-t-verify --step 5 --step-label ".5: Goal-Backward Verification (Post-Gate Behavior Check)" 2>/dev/null || true
|
|
278
|
+
```
|
|
279
|
+
|
|
244
280
|
This step runs **after all 8 quality gates pass**. It verifies that milestone goals are actually achieved end-to-end — not just structurally present. It catches placeholder implementations that pass all structural gates.
|
|
245
281
|
|
|
246
282
|
Refer to `.gsd-t/contracts/goal-backward-contract.md` for the full verification flow, placeholder patterns, and findings report format.
|
|
@@ -315,6 +351,10 @@ Add a `Goal-Backward:` line to the Step 5 verification report summary:
|
|
|
315
351
|
|
|
316
352
|
## Step 6: Handle Remediation
|
|
317
353
|
|
|
354
|
+
```bash
|
|
355
|
+
node scripts/gsd-t-watch-state.js advance --agent-id "$GSD_T_AGENT_ID" --parent-id "${GSD_T_PARENT_AGENT_ID:-null}" --command gsd-t-verify --step 6 --step-label "Handle Remediation" 2>/dev/null || true
|
|
356
|
+
```
|
|
357
|
+
|
|
318
358
|
If there are CRITICAL findings:
|
|
319
359
|
1. Create remediation tasks in the affected domain's `tasks.md`
|
|
320
360
|
2. Execute fixes (solo — don't spawn teams for remediation)
|
|
@@ -323,6 +363,10 @@ If there are CRITICAL findings:
|
|
|
323
363
|
|
|
324
364
|
## Step 7: Update State
|
|
325
365
|
|
|
366
|
+
```bash
|
|
367
|
+
node scripts/gsd-t-watch-state.js advance --agent-id "$GSD_T_AGENT_ID" --parent-id "${GSD_T_PARENT_AGENT_ID:-null}" --command gsd-t-verify --step 7 --step-label "Update State" 2>/dev/null || true
|
|
368
|
+
```
|
|
369
|
+
|
|
326
370
|
Update `.gsd-t/progress.md`:
|
|
327
371
|
- If all PASS: Set status to `VERIFIED`
|
|
328
372
|
- If CONDITIONAL PASS: Set status to `VERIFIED-WITH-WARNINGS`, list warnings
|
|
@@ -353,6 +397,10 @@ Update `.gsd-t/progress.md`:
|
|
|
353
397
|
|
|
354
398
|
## Step 8: Auto-Invoke Complete-Milestone
|
|
355
399
|
|
|
400
|
+
```bash
|
|
401
|
+
node scripts/gsd-t-watch-state.js advance --agent-id "$GSD_T_AGENT_ID" --parent-id "${GSD_T_PARENT_AGENT_ID:-null}" --command gsd-t-verify --step 8 --step-label "Auto-Invoke Complete-Milestone" 2>/dev/null || true
|
|
402
|
+
```
|
|
403
|
+
|
|
356
404
|
**This step is MANDATORY and runs at ALL autonomy levels.** Completing a verified milestone is a mechanical operation (archive, tag, bump version, update docs). There is no decision that benefits from user review — the decision was made when verification passed.
|
|
357
405
|
|
|
358
406
|
If status is VERIFY-FAILED:
|
package/commands/gsd-t-wave.md
CHANGED
|
@@ -25,6 +25,10 @@ Per `.gsd-t/contracts/model-selection-contract.md` v1.0.0. Each phase spawn pick
|
|
|
25
25
|
|
|
26
26
|
## Step 0.1: Verify Context Gate Readiness (MANDATORY — first thing in a fresh session)
|
|
27
27
|
|
|
28
|
+
```bash
|
|
29
|
+
node scripts/gsd-t-watch-state.js advance --agent-id "$GSD_T_AGENT_ID" --parent-id "${GSD_T_PARENT_AGENT_ID:-null}" --command gsd-t-wave --step 0 --step-label ".1: Verify Context Gate Readiness (MANDATORY — first thing in a fresh session)" 2>/dev/null || true
|
|
30
|
+
```
|
|
31
|
+
|
|
28
32
|
Run via Bash:
|
|
29
33
|
|
|
30
34
|
```bash
|
|
@@ -35,6 +39,10 @@ This calls `getSessionStatus()` which reads `.gsd-t/.context-meter-state.json` p
|
|
|
35
39
|
|
|
36
40
|
## Step 1: Load State (Lightweight)
|
|
37
41
|
|
|
42
|
+
```bash
|
|
43
|
+
node scripts/gsd-t-watch-state.js advance --agent-id "$GSD_T_AGENT_ID" --parent-id "${GSD_T_PARENT_AGENT_ID:-null}" --command gsd-t-wave --step 1 --step-label "Load State (Lightweight)" 2>/dev/null || true
|
|
44
|
+
```
|
|
45
|
+
|
|
38
46
|
Read ONLY:
|
|
39
47
|
1. `.gsd-t/progress.md` — current status, milestone name, phase state
|
|
40
48
|
2. `CLAUDE.md` — autonomy level only (scan for Level 1/2/3)
|
|
@@ -54,6 +62,10 @@ Do NOT attempt to fix progress.md yourself — that risks data loss.
|
|
|
54
62
|
|
|
55
63
|
## Step 2: Determine Resume Point
|
|
56
64
|
|
|
65
|
+
```bash
|
|
66
|
+
node scripts/gsd-t-watch-state.js advance --agent-id "$GSD_T_AGENT_ID" --parent-id "${GSD_T_PARENT_AGENT_ID:-null}" --command gsd-t-wave --step 2 --step-label "Determine Resume Point" 2>/dev/null || true
|
|
67
|
+
```
|
|
68
|
+
|
|
57
69
|
From progress.md status, determine which phase to start from:
|
|
58
70
|
|
|
59
71
|
| Status | Next Phase |
|
|
@@ -72,6 +84,10 @@ From progress.md status, determine which phase to start from:
|
|
|
72
84
|
|
|
73
85
|
## Step 2.5: Token Budget Pre-Flight (if available)
|
|
74
86
|
|
|
87
|
+
```bash
|
|
88
|
+
node scripts/gsd-t-watch-state.js advance --agent-id "$GSD_T_AGENT_ID" --parent-id "${GSD_T_PARENT_AGENT_ID:-null}" --command gsd-t-wave --step 2 --step-label ".5: Token Budget Pre-Flight (if available)" 2>/dev/null || true
|
|
89
|
+
```
|
|
90
|
+
|
|
75
91
|
Before starting the phase loop, check the projected token cost for this milestone:
|
|
76
92
|
|
|
77
93
|
Run via Bash:
|
|
@@ -85,6 +101,10 @@ If the file doesn't exist or returns nothing, skip silently and proceed.
|
|
|
85
101
|
|
|
86
102
|
## Step 3: Phase Orchestration Loop
|
|
87
103
|
|
|
104
|
+
```bash
|
|
105
|
+
node scripts/gsd-t-watch-state.js advance --agent-id "$GSD_T_AGENT_ID" --parent-id "${GSD_T_PARENT_AGENT_ID:-null}" --command gsd-t-wave --step 3 --step-label "Phase Orchestration Loop" 2>/dev/null || true
|
|
106
|
+
```
|
|
107
|
+
|
|
88
108
|
For each remaining phase, spawn an **independent agent** using the Task tool. Each agent gets a fresh context window, loads its own state from files, and reports back.
|
|
89
109
|
|
|
90
110
|
### Graph Availability
|
|
@@ -275,6 +295,10 @@ After each agent completes, run this spot-check before proceeding:
|
|
|
275
295
|
|
|
276
296
|
## Step 4: Autonomy Behavior
|
|
277
297
|
|
|
298
|
+
```bash
|
|
299
|
+
node scripts/gsd-t-watch-state.js advance --agent-id "$GSD_T_AGENT_ID" --parent-id "${GSD_T_PARENT_AGENT_ID:-null}" --command gsd-t-wave --step 4 --step-label "Autonomy Behavior" 2>/dev/null || true
|
|
300
|
+
```
|
|
301
|
+
|
|
278
302
|
**Level 3 (Full Auto)**: Auto-advance to next phase after each agent completes. Only STOP for:
|
|
279
303
|
- Destructive Action Guard violations (reported by phase agent)
|
|
280
304
|
- Impact analysis BLOCK verdict
|
|
@@ -285,6 +309,10 @@ After each agent completes, run this spot-check before proceeding:
|
|
|
285
309
|
|
|
286
310
|
## Step 5: Completion
|
|
287
311
|
|
|
312
|
+
```bash
|
|
313
|
+
node scripts/gsd-t-watch-state.js advance --agent-id "$GSD_T_AGENT_ID" --parent-id "${GSD_T_PARENT_AGENT_ID:-null}" --command gsd-t-wave --step 5 --step-label "Completion" 2>/dev/null || true
|
|
314
|
+
```
|
|
315
|
+
|
|
288
316
|
When all phases are done:
|
|
289
317
|
```
|
|
290
318
|
═══════════════════════════════════════════════════════════════════════════════
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tekyzinc/gsd-t",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.13.11",
|
|
4
4
|
"description": "GSD-T: Contract-Driven Development for Claude Code — 54 slash commands with headless-by-default workflow spawning, unattended supervisor relay with event stream, graph-powered code analysis, real-time agent dashboard, task telemetry, doc-ripple enforcement, backlog management, impact analysis, test sync, milestone archival, and PRD generation",
|
|
5
5
|
"author": "Tekyz, Inc.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* scripts/gsd-t-watch-state.js — GSD-T Watch-State Writer CLI
|
|
4
|
+
*
|
|
5
|
+
* Records per-agent progress into `.gsd-t/.watch-state/{agent_id}.json` so
|
|
6
|
+
* the watch-progress renderer can reconstruct the workflow tree live.
|
|
7
|
+
*
|
|
8
|
+
* Contract: `.gsd-t/contracts/watch-progress-contract.md` v1.0.0
|
|
9
|
+
* Owner: D2 (M39 `d2-progress-watch`)
|
|
10
|
+
*
|
|
11
|
+
* Subcommands (contract §4):
|
|
12
|
+
* start — create/overwrite a new in-progress record
|
|
13
|
+
* advance — record current step (acts as start if no file exists)
|
|
14
|
+
* done — terminal: status=done, sets completed_at
|
|
15
|
+
* skip — terminal: status=skipped, sets completed_at
|
|
16
|
+
* fail — terminal: status=failed, sets completed_at
|
|
17
|
+
*
|
|
18
|
+
* Exit codes:
|
|
19
|
+
* 0 — success
|
|
20
|
+
* 1 — validation (bad args, unknown subcommand)
|
|
21
|
+
* 2 — filesystem (EACCES / ENOSPC / permission)
|
|
22
|
+
*
|
|
23
|
+
* Zero external deps (Node.js built-ins only).
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
"use strict";
|
|
27
|
+
|
|
28
|
+
const fs = require("fs");
|
|
29
|
+
const path = require("path");
|
|
30
|
+
const crypto = require("crypto");
|
|
31
|
+
|
|
32
|
+
const STATE_DIR_REL = path.join(".gsd-t", ".watch-state");
|
|
33
|
+
const VALID_SUB = new Set(["start", "advance", "done", "skip", "fail"]);
|
|
34
|
+
|
|
35
|
+
function _parseArgs(argv) {
|
|
36
|
+
const out = { _sub: argv[0] || null };
|
|
37
|
+
for (let i = 1; i < argv.length; i++) {
|
|
38
|
+
const a = argv[i];
|
|
39
|
+
if (!a.startsWith("--")) continue;
|
|
40
|
+
const key = a.slice(2);
|
|
41
|
+
const next = argv[i + 1];
|
|
42
|
+
if (next === undefined || next.startsWith("--")) {
|
|
43
|
+
out[key] = true;
|
|
44
|
+
} else {
|
|
45
|
+
out[key] = next;
|
|
46
|
+
i++;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return out;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function _validate(sub, args) {
|
|
53
|
+
if (!VALID_SUB.has(sub)) return `unknown subcommand: ${sub}`;
|
|
54
|
+
if (sub === "start" || sub === "advance") {
|
|
55
|
+
if (!args["command"]) return "--command is required";
|
|
56
|
+
if (!args["step"] || !/^-?\d+$/.test(String(args["step"]))) {
|
|
57
|
+
return "--step must be an integer";
|
|
58
|
+
}
|
|
59
|
+
if (!args["step-label"]) return "--step-label is required";
|
|
60
|
+
}
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function _resolveAgentId(args) {
|
|
65
|
+
const v = args["agent-id"];
|
|
66
|
+
if (v && typeof v === "string" && v !== "true") return v;
|
|
67
|
+
if (process.env.GSD_T_AGENT_ID) return process.env.GSD_T_AGENT_ID;
|
|
68
|
+
return `shell-${process.pid}-${Date.now()}`;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function _stateDir(cwd) {
|
|
72
|
+
return path.join(cwd || process.cwd(), STATE_DIR_REL);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function _readExisting(filePath) {
|
|
76
|
+
try {
|
|
77
|
+
return JSON.parse(fs.readFileSync(filePath, "utf8"));
|
|
78
|
+
} catch (_) {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function _atomicWrite(filePath, data) {
|
|
84
|
+
const dir = path.dirname(filePath);
|
|
85
|
+
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
86
|
+
const rand = crypto.randomBytes(4).toString("hex");
|
|
87
|
+
const tmp = `${filePath}.tmp-${process.pid}-${rand}`;
|
|
88
|
+
fs.writeFileSync(tmp, JSON.stringify(data, null, 2) + "\n");
|
|
89
|
+
fs.renameSync(tmp, filePath);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function _parseParentId(raw) {
|
|
93
|
+
if (raw === undefined || raw === null || raw === "null" || raw === "") return null;
|
|
94
|
+
return String(raw);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function _parseMetadata(raw) {
|
|
98
|
+
if (!raw || raw === true) return {};
|
|
99
|
+
try {
|
|
100
|
+
const parsed = JSON.parse(raw);
|
|
101
|
+
return parsed && typeof parsed === "object" ? parsed : {};
|
|
102
|
+
} catch (_) {
|
|
103
|
+
return {};
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function _buildRecord(sub, args, existing, resolvedAgentId) {
|
|
108
|
+
const now = new Date().toISOString();
|
|
109
|
+
const base = existing || {
|
|
110
|
+
agent_id: resolvedAgentId || args["agent-id"],
|
|
111
|
+
parent_agent_id: _parseParentId(args["parent-id"]),
|
|
112
|
+
command: "",
|
|
113
|
+
step: 0,
|
|
114
|
+
step_label: "",
|
|
115
|
+
status: "pending",
|
|
116
|
+
started_at: null,
|
|
117
|
+
completed_at: null,
|
|
118
|
+
metadata: {},
|
|
119
|
+
};
|
|
120
|
+
// Always sync parent_agent_id if explicitly provided (supports late lineage).
|
|
121
|
+
if (args["parent-id"] !== undefined) base.parent_agent_id = _parseParentId(args["parent-id"]);
|
|
122
|
+
const mergedMeta = Object.assign({}, base.metadata || {}, _parseMetadata(args["metadata"]));
|
|
123
|
+
base.metadata = mergedMeta;
|
|
124
|
+
if (sub === "start" || sub === "advance") {
|
|
125
|
+
base.command = String(args["command"]);
|
|
126
|
+
base.step = parseInt(args["step"], 10);
|
|
127
|
+
base.step_label = String(args["step-label"]);
|
|
128
|
+
base.status = "in_progress";
|
|
129
|
+
base.completed_at = null;
|
|
130
|
+
if (!base.started_at) base.started_at = now;
|
|
131
|
+
} else if (sub === "done") {
|
|
132
|
+
base.status = "done";
|
|
133
|
+
base.completed_at = now;
|
|
134
|
+
} else if (sub === "skip") {
|
|
135
|
+
base.status = "skipped";
|
|
136
|
+
base.completed_at = now;
|
|
137
|
+
} else if (sub === "fail") {
|
|
138
|
+
base.status = "failed";
|
|
139
|
+
base.completed_at = now;
|
|
140
|
+
}
|
|
141
|
+
return base;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function main(argv, cwd) {
|
|
145
|
+
const args = _parseArgs(argv);
|
|
146
|
+
const sub = args._sub;
|
|
147
|
+
const err = _validate(sub, args);
|
|
148
|
+
if (err) {
|
|
149
|
+
process.stderr.write(`[gsd-t-watch-state] ${err}\n`);
|
|
150
|
+
return 1;
|
|
151
|
+
}
|
|
152
|
+
const agentId = _resolveAgentId(args);
|
|
153
|
+
const filePath = path.join(_stateDir(cwd), `${agentId}.json`);
|
|
154
|
+
const existing = _readExisting(filePath);
|
|
155
|
+
const record = _buildRecord(sub, args, existing, agentId);
|
|
156
|
+
try {
|
|
157
|
+
_atomicWrite(filePath, record);
|
|
158
|
+
} catch (e) {
|
|
159
|
+
process.stderr.write(`[gsd-t-watch-state] fs error: ${e.message}\n`);
|
|
160
|
+
return 2;
|
|
161
|
+
}
|
|
162
|
+
return 0;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
if (require.main === module) {
|
|
166
|
+
const code = main(process.argv.slice(2));
|
|
167
|
+
process.exit(code);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
module.exports = { main, _parseArgs, _validate, _buildRecord, _stateDir };
|