@hegemonart/get-design-done 1.20.0 → 1.22.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/.claude-plugin/marketplace.json +9 -12
- package/.claude-plugin/plugin.json +8 -31
- package/CHANGELOG.md +200 -0
- package/README.md +48 -7
- package/bin/gdd-sdk +55 -0
- package/hooks/_hook-emit.js +81 -0
- package/hooks/gdd-bash-guard.js +8 -0
- package/hooks/gdd-decision-injector.js +2 -0
- package/hooks/gdd-protected-paths.js +8 -0
- package/hooks/gdd-trajectory-capture.js +64 -0
- package/hooks/hooks.json +9 -0
- package/package.json +19 -47
- package/reference/codex-tools.md +53 -0
- package/reference/gemini-tools.md +53 -0
- package/reference/registry.json +14 -0
- package/scripts/cli/gdd-events.mjs +283 -0
- package/scripts/e2e/run-headless.ts +514 -0
- package/scripts/lib/cli/commands/audit.ts +382 -0
- package/scripts/lib/cli/commands/init.ts +217 -0
- package/scripts/lib/cli/commands/query.ts +329 -0
- package/scripts/lib/cli/commands/run.ts +656 -0
- package/scripts/lib/cli/commands/stage.ts +468 -0
- package/scripts/lib/cli/index.ts +167 -0
- package/scripts/lib/cli/parse-args.ts +336 -0
- package/scripts/lib/connection-probe/index.cjs +263 -0
- package/scripts/lib/context-engine/index.ts +116 -0
- package/scripts/lib/context-engine/manifest.ts +69 -0
- package/scripts/lib/context-engine/truncate.ts +282 -0
- package/scripts/lib/context-engine/types.ts +59 -0
- package/scripts/lib/discuss-parallel-runner/aggregator.ts +448 -0
- package/scripts/lib/discuss-parallel-runner/discussants.ts +430 -0
- package/scripts/lib/discuss-parallel-runner/index.ts +223 -0
- package/scripts/lib/discuss-parallel-runner/types.ts +184 -0
- package/scripts/lib/event-chain.cjs +177 -0
- package/scripts/lib/event-stream/index.ts +31 -1
- package/scripts/lib/event-stream/reader.ts +139 -0
- package/scripts/lib/event-stream/types.ts +155 -1
- package/scripts/lib/event-stream/writer.ts +65 -8
- package/scripts/lib/explore-parallel-runner/index.ts +294 -0
- package/scripts/lib/explore-parallel-runner/mappers.ts +290 -0
- package/scripts/lib/explore-parallel-runner/synthesizer.ts +295 -0
- package/scripts/lib/explore-parallel-runner/types.ts +139 -0
- package/scripts/lib/harness/detect.ts +90 -0
- package/scripts/lib/harness/index.ts +64 -0
- package/scripts/lib/harness/tool-map.ts +142 -0
- package/scripts/lib/init-runner/index.ts +396 -0
- package/scripts/lib/init-runner/researchers.ts +245 -0
- package/scripts/lib/init-runner/scaffold.ts +224 -0
- package/scripts/lib/init-runner/synthesizer.ts +224 -0
- package/scripts/lib/init-runner/types.ts +143 -0
- package/scripts/lib/logger/index.ts +251 -0
- package/scripts/lib/logger/sinks.ts +269 -0
- package/scripts/lib/logger/types.ts +110 -0
- package/scripts/lib/pipeline-runner/human-gate.ts +134 -0
- package/scripts/lib/pipeline-runner/index.ts +527 -0
- package/scripts/lib/pipeline-runner/stage-handlers.ts +339 -0
- package/scripts/lib/pipeline-runner/state-machine.ts +144 -0
- package/scripts/lib/pipeline-runner/types.ts +183 -0
- package/scripts/lib/redact.cjs +122 -0
- package/scripts/lib/session-runner/errors.ts +406 -0
- package/scripts/lib/session-runner/index.ts +715 -0
- package/scripts/lib/session-runner/transcript.ts +189 -0
- package/scripts/lib/session-runner/types.ts +144 -0
- package/scripts/lib/tool-scoping/index.ts +219 -0
- package/scripts/lib/tool-scoping/parse-agent-tools.ts +207 -0
- package/scripts/lib/tool-scoping/stage-scopes.ts +139 -0
- package/scripts/lib/tool-scoping/types.ts +77 -0
- package/scripts/lib/trajectory/index.cjs +126 -0
- package/scripts/lib/transports/ws.cjs +179 -0
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* transports/ws.cjs — WebSocket event-stream transport (Plan 22-07).
|
|
3
|
+
*
|
|
4
|
+
* Optional dep: requires `ws`. probeOptional() returns null if absent;
|
|
5
|
+
* importer renders a clear install hint.
|
|
6
|
+
*
|
|
7
|
+
* Wire format:
|
|
8
|
+
* * One event per WebSocket text frame, JSON-encoded.
|
|
9
|
+
* * If `tailFrom` is supplied at startup, replay that file's contents
|
|
10
|
+
* to each new connection BEFORE subscribing to live events.
|
|
11
|
+
* * Live events come from a caller-supplied `subscribe(handler) →
|
|
12
|
+
* unsub` — typically the event-stream bus's subscribeAll. Decoupling
|
|
13
|
+
* keeps this CommonJS module independent of the TS bus implementation.
|
|
14
|
+
*
|
|
15
|
+
* Auth:
|
|
16
|
+
* * `Authorization: Bearer <token>` header required on the upgrade.
|
|
17
|
+
* * Mismatched / missing token → HTTP 401 close on the upgrade socket.
|
|
18
|
+
*
|
|
19
|
+
* Backpressure:
|
|
20
|
+
* * Fire-and-forget. If a client's socket is not in OPEN state we drop
|
|
21
|
+
* the event for that client and log a warning. No queue.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
'use strict';
|
|
25
|
+
|
|
26
|
+
const http = require('node:http');
|
|
27
|
+
const { readFileSync, existsSync } = require('node:fs');
|
|
28
|
+
const { probeOptional } = require('../probe-optional.cjs');
|
|
29
|
+
|
|
30
|
+
const ws = probeOptional('ws');
|
|
31
|
+
if (!ws) {
|
|
32
|
+
// Importer (gdd-events.mjs) handles this throw and renders the hint.
|
|
33
|
+
throw new Error(
|
|
34
|
+
"ws module not installed (optional dep). Install via: npm i -D ws",
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
const { WebSocketServer } = ws;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Synchronously read a JSONL events file and yield parsed objects.
|
|
41
|
+
* Matches reader.ts line semantics: skip blank lines + invalid JSON.
|
|
42
|
+
*
|
|
43
|
+
* @param {string} path
|
|
44
|
+
* @returns {Generator<Record<string, unknown>>}
|
|
45
|
+
*/
|
|
46
|
+
function* readEventsSync(path) {
|
|
47
|
+
if (!existsSync(path)) return;
|
|
48
|
+
const raw = readFileSync(path, 'utf8');
|
|
49
|
+
for (const line of raw.split('\n')) {
|
|
50
|
+
if (line.trim() === '') continue;
|
|
51
|
+
try {
|
|
52
|
+
yield JSON.parse(line);
|
|
53
|
+
} catch {
|
|
54
|
+
/* skip invalid */
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Start the WebSocket server. Returns a handle with `close()`.
|
|
61
|
+
*
|
|
62
|
+
* @param {{
|
|
63
|
+
* port: number,
|
|
64
|
+
* token: string,
|
|
65
|
+
* tailFrom?: string,
|
|
66
|
+
* subscribe?: (handler: (ev: unknown) => void) => () => void,
|
|
67
|
+
* }} opts
|
|
68
|
+
* @returns {Promise<{close: () => void, port: number}>}
|
|
69
|
+
*/
|
|
70
|
+
async function startServer(opts) {
|
|
71
|
+
if (typeof opts.port !== 'number' || !Number.isFinite(opts.port)) {
|
|
72
|
+
throw new TypeError('startServer: port (number) required');
|
|
73
|
+
}
|
|
74
|
+
if (typeof opts.token !== 'string' || opts.token.length < 8) {
|
|
75
|
+
throw new TypeError('startServer: token (string, ≥8 chars) required');
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const httpServer = http.createServer((_req, res) => {
|
|
79
|
+
res.statusCode = 426; // Upgrade Required
|
|
80
|
+
res.setHeader('Content-Type', 'text/plain');
|
|
81
|
+
res.end('upgrade required');
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
const wss = new WebSocketServer({ noServer: true });
|
|
85
|
+
|
|
86
|
+
/** @type {Set<import('ws').WebSocket>} */
|
|
87
|
+
const clients = new Set();
|
|
88
|
+
|
|
89
|
+
/** @type {() => void} */
|
|
90
|
+
let unsub = () => {};
|
|
91
|
+
if (typeof opts.subscribe === 'function') {
|
|
92
|
+
unsub = opts.subscribe((ev) => {
|
|
93
|
+
const frame = JSON.stringify(ev);
|
|
94
|
+
for (const client of clients) {
|
|
95
|
+
if (client.readyState === ws.OPEN) {
|
|
96
|
+
try {
|
|
97
|
+
client.send(frame);
|
|
98
|
+
} catch (err) {
|
|
99
|
+
try {
|
|
100
|
+
process.stderr.write(`[ws] send failed: ${err.message}\n`);
|
|
101
|
+
} catch {
|
|
102
|
+
/* swallow */
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
httpServer.on('upgrade', (req, socket, head) => {
|
|
111
|
+
const auth = req.headers['authorization'];
|
|
112
|
+
if (!auth || auth !== `Bearer ${opts.token}`) {
|
|
113
|
+
socket.write('HTTP/1.1 401 Unauthorized\r\nConnection: close\r\n\r\n');
|
|
114
|
+
socket.destroy();
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
wss.handleUpgrade(req, socket, head, (client) => {
|
|
118
|
+
clients.add(client);
|
|
119
|
+
|
|
120
|
+
if (opts.tailFrom) {
|
|
121
|
+
try {
|
|
122
|
+
for (const ev of readEventsSync(opts.tailFrom)) {
|
|
123
|
+
try {
|
|
124
|
+
client.send(JSON.stringify(ev));
|
|
125
|
+
} catch {
|
|
126
|
+
break;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
} catch (err) {
|
|
130
|
+
try {
|
|
131
|
+
process.stderr.write(`[ws] replay failed: ${err.message}\n`);
|
|
132
|
+
} catch {
|
|
133
|
+
/* swallow */
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
client.on('close', () => clients.delete(client));
|
|
139
|
+
client.on('error', () => clients.delete(client));
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
await new Promise((resolve, reject) => {
|
|
144
|
+
httpServer.once('error', reject);
|
|
145
|
+
httpServer.listen(opts.port, () => resolve(undefined));
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
const addr = httpServer.address();
|
|
149
|
+
return {
|
|
150
|
+
port: typeof addr === 'object' && addr ? addr.port : opts.port,
|
|
151
|
+
close() {
|
|
152
|
+
try {
|
|
153
|
+
unsub();
|
|
154
|
+
} catch {
|
|
155
|
+
/* swallow */
|
|
156
|
+
}
|
|
157
|
+
for (const c of clients) {
|
|
158
|
+
try {
|
|
159
|
+
c.close();
|
|
160
|
+
} catch {
|
|
161
|
+
/* swallow */
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
clients.clear();
|
|
165
|
+
try {
|
|
166
|
+
wss.close();
|
|
167
|
+
} catch {
|
|
168
|
+
/* swallow */
|
|
169
|
+
}
|
|
170
|
+
try {
|
|
171
|
+
httpServer.close();
|
|
172
|
+
} catch {
|
|
173
|
+
/* swallow */
|
|
174
|
+
}
|
|
175
|
+
},
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
module.exports = { startServer, readEventsSync };
|