@tekyzinc/gsd-t 3.12.15 → 3.13.10
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 +32 -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 +78 -2
- 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 +1 -1
- 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-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.10",
|
|
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 };
|