@deksden-com/dd-flow-cli 0.9.0-beta.7 → 0.9.0-beta.74
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 +396 -0
- package/README.md +65 -0
- package/dist/build-info.json +10 -10
- package/dist/cli/help.js +81 -9
- package/dist/cli/run-cli.js +442 -46
- package/dist/harness-runtime/bin/dd-agy.mjs +37 -0
- package/dist/harness-runtime/bin/dd-codex.mjs +25 -0
- package/dist/harness-runtime/bin/dd-droid.mjs +33 -0
- package/dist/harness-runtime/bin/dd-grok.mjs +30 -0
- package/dist/harness-runtime/bin/dd-opencode.mjs +21 -0
- package/dist/harness-runtime/bin/dd-zcode.mjs +83 -0
- package/dist/harness-runtime/lib/daemon-operations.mjs +215 -0
- package/dist/harness-runtime/lib/dd-agy-daemon.mjs +423 -0
- package/dist/harness-runtime/lib/dd-agy.mjs +59 -0
- package/dist/harness-runtime/lib/dd-codex-daemon.mjs +141 -0
- package/dist/harness-runtime/lib/dd-codex.mjs +438 -0
- package/dist/harness-runtime/lib/dd-droid-daemon.mjs +125 -0
- package/dist/harness-runtime/lib/dd-droid.mjs +470 -0
- package/dist/harness-runtime/lib/dd-grok-daemon.mjs +274 -0
- package/dist/harness-runtime/lib/dd-grok.mjs +174 -0
- package/dist/harness-runtime/lib/dd-opencode-daemon.mjs +198 -0
- package/dist/harness-runtime/lib/dd-opencode.mjs +98 -0
- package/dist/harness-runtime/lib/dd-zcode-daemon.mjs +644 -0
- package/dist/harness-runtime/lib/dd-zcode.mjs +910 -0
- package/dist/harness-runtime/lib/dispatch-fence.mjs +14 -0
- package/dist/harness-runtime/lib/driver-recovery.mjs +129 -0
- package/dist/harness-runtime/lib/droid-observation.mjs +66 -0
- package/dist/harness-runtime/lib/managed-daemon.mjs +260 -0
- package/dist/harness-runtime/lib/model-observations.mjs +77 -0
- package/dist/harness-runtime/lib/native-hook-command.mjs +34 -0
- package/dist/harness-runtime/lib/observation-clock.mjs +36 -0
- package/dist/harness-runtime/lib/operation-context.mjs +5 -0
- package/dist/harness-runtime/lib/operation-errors.mjs +19 -0
- package/dist/harness-runtime/lib/process-json.mjs +70 -0
- package/dist/harness-runtime/lib/process-snapshot.mjs +10 -0
- package/dist/harness-runtime/lib/runner-events.mjs +200 -0
- package/dist/harness-runtime/lib/runner-lock.mjs +42 -0
- package/dist/harness-runtime/lib/session-settlement.mjs +30 -0
- package/dist/harness-runtime/lib/tool-observations.d.mts +17 -0
- package/dist/harness-runtime/lib/tool-observations.mjs +153 -0
- package/dist/runtime/context.js +3 -1
- package/dist/schemas/agent-profile.schema.json +1 -1
- package/dist/schemas/code-review-result.schema.json +2 -2
- package/dist/schemas/code-work-batch.schema.json +4 -3
- package/dist/schemas/code-work-result.schema.json +4 -4
- package/dist/schemas/harness-config.schema.json +23 -0
- package/dist/schemas/plan-review-result.schema.json +2 -2
- package/dist/schemas/run-control-receipt.schema.json +99 -0
- package/dist/schemas/run-control-request.schema.json +36 -0
- package/dist/schemas/vnext-protocol-plan.schema.json +2 -2
- package/dist/services/cleanup.js +8 -5
- package/dist/services/cli-operation-classifier.js +11 -1
- package/dist/services/code-checks.js +543 -96
- package/dist/services/controller-fanout.js +120 -0
- package/dist/services/dashboard.js +9 -0
- package/dist/services/engines.js +50 -19
- package/dist/services/eval-snapshots.js +639 -60
- package/dist/services/execution-policy.js +177 -0
- package/dist/services/external-work-launch.js +110 -0
- package/dist/services/harness-adapter.js +147 -24
- package/dist/services/harness-config.js +68 -0
- package/dist/services/hooks.js +413 -168
- package/dist/services/lanes.js +1 -1
- package/dist/services/lifecycle-command.js +74 -6
- package/dist/services/lifecycle-invocations.js +637 -0
- package/dist/services/managed-daemon-binding.js +38 -0
- package/dist/services/managed-processes.js +138 -22
- package/dist/services/merge-queue.js +6 -6
- package/dist/services/merge-server.js +75 -29
- package/dist/services/migrations.js +1 -1
- package/dist/services/native-daemon-history.js +49 -0
- package/dist/services/native-session-control.js +39 -0
- package/dist/services/projects.js +7 -3
- package/dist/services/prompts.js +4 -2
- package/dist/services/protocols.js +11 -2
- package/dist/services/recovery-observation-budget.js +61 -0
- package/dist/services/recovery-snapshot-database.js +107 -0
- package/dist/services/run-control-receipt.js +56 -0
- package/dist/services/run-control-worker.js +363 -0
- package/dist/services/run-control.js +876 -0
- package/dist/services/run-controller-adapter.js +211 -0
- package/dist/services/run-controller-capture.js +134 -0
- package/dist/services/run-controller-process.js +189 -0
- package/dist/services/run-controller-recovery.js +222 -0
- package/dist/services/run-controller-state.js +31 -0
- package/dist/services/run-controller.js +733 -0
- package/dist/services/run-engine-bindings.js +20 -62
- package/dist/services/run-fork.js +124 -0
- package/dist/services/run-observations.js +112 -0
- package/dist/services/run-recovery-runtime.js +69 -0
- package/dist/services/run-recovery.js +327 -0
- package/dist/services/runs.js +280 -40
- package/dist/services/runtime-budget.js +362 -0
- package/dist/services/runtime-scope-capture.js +50 -0
- package/dist/services/runtime-scope-control.js +450 -0
- package/dist/services/runtime-scope-resume.js +543 -0
- package/dist/services/runtime-scope-stop.js +99 -0
- package/dist/services/runtime-scope-worker.js +210 -0
- package/dist/services/runtime-service.js +96 -0
- package/dist/services/schema-validation.js +12 -12
- package/dist/services/stage-context.js +2 -2
- package/dist/services/stage-lifecycle.js +32 -10
- package/dist/services/stage-pause.js +25 -13
- package/dist/services/usage.js +37 -93
- package/dist/services/vnext-code-review.js +149 -89
- package/dist/services/vnext-code.js +223 -215
- package/dist/services/vnext-execution-profile.js +5 -3
- package/dist/services/vnext-fanout.js +135 -21
- package/dist/services/vnext-merge.js +258 -89
- package/dist/services/vnext-plan-review.js +75 -64
- package/dist/services/vnext-plan.js +77 -29
- package/dist/services/vnext-protocolize.js +21 -14
- package/dist/services/vnext-specify.js +26 -16
- package/dist/services/work-registry.js +592 -154
- package/dist/services/workspace-bootstrap.js +76 -0
- package/dist/shared/errors.js +12 -0
- package/dist/storage/database.js +341 -31
- package/dist/storage/writer-contract.js +77 -0
- package/dist/storage/writer-migration.js +102 -0
- package/package.json +20 -13
- package/tools/repair-paused-run-status.mjs +59 -0
package/dist/services/lanes.js
CHANGED
|
@@ -515,7 +515,7 @@ function ensureQueuedLaneWaiter(context, input) {
|
|
|
515
515
|
function tryAcquireQueuedLaneLock(context, input) {
|
|
516
516
|
expireStaleLocks(context, input.projectId);
|
|
517
517
|
expireStaleWaiters(context, input.projectId);
|
|
518
|
-
context.db.
|
|
518
|
+
context.db.beginWriteTransaction();
|
|
519
519
|
try {
|
|
520
520
|
const existingLock = activeLaneLock(context, input.projectId, input.lane);
|
|
521
521
|
if (existingLock?.worker_id === input.workerId) {
|
|
@@ -32,7 +32,7 @@ function parseLifecycleCommandInner(command, wrapped) {
|
|
|
32
32
|
const heredoc = stripHeredocBodies(command);
|
|
33
33
|
let entries;
|
|
34
34
|
try {
|
|
35
|
-
entries = parse(heredoc.command, (name) => `$${name}`);
|
|
35
|
+
entries = parse(withoutFileDescriptors(heredoc.command), (name) => `$${name}`);
|
|
36
36
|
}
|
|
37
37
|
catch {
|
|
38
38
|
// A command that cannot be tokenized cannot create a trusted claim. The
|
|
@@ -56,11 +56,11 @@ function parseLifecycleCommandInner(command, wrapped) {
|
|
|
56
56
|
if (!found.length)
|
|
57
57
|
return { kind: "none" };
|
|
58
58
|
const first = found[0];
|
|
59
|
-
if (found.length !== 1 || composed || first.nestedCompound) {
|
|
59
|
+
if (found.length !== 1 || composed || first.nestedCompound || (heredoc.present && !heredoc.safe)) {
|
|
60
60
|
return {
|
|
61
61
|
kind: "compound",
|
|
62
62
|
invocation: { ...first.invocation, rewriteSafe: false },
|
|
63
|
-
reason: found.length !== 1 ? "multiple_lifecycle_invocations" : first.nestedCompound ? "nested_compound_invocation" : "shell_composition"
|
|
63
|
+
reason: found.length !== 1 ? "multiple_lifecycle_invocations" : first.nestedCompound ? "nested_compound_invocation" : heredoc.present && !heredoc.safe ? "unsafe_heredoc" : "shell_composition"
|
|
64
64
|
};
|
|
65
65
|
}
|
|
66
66
|
return { kind: "standalone", invocation: first.invocation };
|
|
@@ -138,7 +138,7 @@ function invocationFromSegment(segment, heredoc, wrapped, inheritedEnv) {
|
|
|
138
138
|
executable,
|
|
139
139
|
argv,
|
|
140
140
|
env,
|
|
141
|
-
args: parseCommandArgs(argv.slice(2)),
|
|
141
|
+
args: parseCommandArgs(argv.slice(operation === "recovery_accept" ? 3 : 2)),
|
|
142
142
|
command: quote(segment.words),
|
|
143
143
|
rewriteSafe: !heredoc && !wrapped && !segment.dynamic,
|
|
144
144
|
wrapped,
|
|
@@ -170,15 +170,28 @@ function wrappedInvocationFromSegment(segment) {
|
|
|
170
170
|
return parseLifecycleCommandInner(payload, true);
|
|
171
171
|
}
|
|
172
172
|
function lifecycleOperation(argv) {
|
|
173
|
+
// The CLI handles help before dispatch, wherever the flag occurs.
|
|
174
|
+
if (argv.some(arg => arg === "--help" || arg === "-h"))
|
|
175
|
+
return null;
|
|
176
|
+
if (argv[0] === "run" && argv[1] === "recovery" && argv[2] === "accept")
|
|
177
|
+
return "recovery_accept";
|
|
173
178
|
const key = `${argv[0] ?? ""} ${argv[1] ?? ""}`;
|
|
174
179
|
if (key === "session register")
|
|
175
180
|
return "session_register";
|
|
176
181
|
if (key === "stage start")
|
|
177
182
|
return "stage_start";
|
|
183
|
+
if (key === "stage finish")
|
|
184
|
+
return "stage_finish";
|
|
185
|
+
if (key === "stage pause")
|
|
186
|
+
return "stage_pause";
|
|
178
187
|
if (key === "stage resume")
|
|
179
188
|
return "stage_resume";
|
|
180
189
|
if (key === "work start")
|
|
181
190
|
return "work_start";
|
|
191
|
+
if (key === "work finish")
|
|
192
|
+
return "work_finish";
|
|
193
|
+
if (key === "work fail")
|
|
194
|
+
return "work_fail";
|
|
182
195
|
return null;
|
|
183
196
|
}
|
|
184
197
|
export function parseCommandArgs(argv) {
|
|
@@ -213,6 +226,58 @@ export function commandPosition(invocation, index) {
|
|
|
213
226
|
function assignment(word) {
|
|
214
227
|
return /^[A-Za-z_][A-Za-z0-9_]*=/.test(word);
|
|
215
228
|
}
|
|
229
|
+
/** Source offsets matter: shell-quote loses the difference between `2>&1`
|
|
230
|
+
* and the literal argument `2 >&1`. Only inspect unquoted shell syntax. */
|
|
231
|
+
function shellSyntaxOffsets(command) {
|
|
232
|
+
const offsets = [];
|
|
233
|
+
let quoted = null, escaped = false;
|
|
234
|
+
for (let i = 0; i < command.length; i++) {
|
|
235
|
+
const char = command[i];
|
|
236
|
+
if (escaped) {
|
|
237
|
+
escaped = false;
|
|
238
|
+
continue;
|
|
239
|
+
}
|
|
240
|
+
if (char === "\\" && quoted !== "'") {
|
|
241
|
+
escaped = true;
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
if (quoted) {
|
|
245
|
+
if (char === quoted)
|
|
246
|
+
quoted = null;
|
|
247
|
+
continue;
|
|
248
|
+
}
|
|
249
|
+
if (char === "'" || char === '"') {
|
|
250
|
+
quoted = char;
|
|
251
|
+
continue;
|
|
252
|
+
}
|
|
253
|
+
if (char === "#" && (i === 0 || /\s/.test(command[i - 1]))) {
|
|
254
|
+
offsets.push(i);
|
|
255
|
+
break;
|
|
256
|
+
}
|
|
257
|
+
if (char === "<" || char === ">")
|
|
258
|
+
offsets.push(i);
|
|
259
|
+
}
|
|
260
|
+
return offsets;
|
|
261
|
+
}
|
|
262
|
+
function descriptorStart(command, index) {
|
|
263
|
+
let start = index;
|
|
264
|
+
while (start > 0 && /[0-9]/.test(command[start - 1]))
|
|
265
|
+
start--;
|
|
266
|
+
return start === 0 || /[\s;&|]/.test(command[start - 1]) ? start : index;
|
|
267
|
+
}
|
|
268
|
+
export function shellSuffixOffset(command) {
|
|
269
|
+
const offset = shellSyntaxOffsets(command)[0];
|
|
270
|
+
return offset === undefined ? command.length : descriptorStart(command, offset);
|
|
271
|
+
}
|
|
272
|
+
function withoutFileDescriptors(command) {
|
|
273
|
+
for (const index of shellSyntaxOffsets(command).reverse()) {
|
|
274
|
+
if (command[index] === "#")
|
|
275
|
+
continue;
|
|
276
|
+
const start = descriptorStart(command, index);
|
|
277
|
+
command = command.slice(0, start) + command.slice(index);
|
|
278
|
+
}
|
|
279
|
+
return command;
|
|
280
|
+
}
|
|
216
281
|
function addAssignment(env, word) {
|
|
217
282
|
const separator = word.indexOf("=");
|
|
218
283
|
env[word.slice(0, separator)] = word.slice(separator + 1);
|
|
@@ -223,6 +288,7 @@ function stripHeredocBodies(command) {
|
|
|
223
288
|
const pending = [];
|
|
224
289
|
let active;
|
|
225
290
|
let present = false;
|
|
291
|
+
let count = 0, quoted = true;
|
|
226
292
|
for (const line of lines) {
|
|
227
293
|
if (active) {
|
|
228
294
|
const candidate = active.stripTabs ? line.replace(/^\t+/, "") : line;
|
|
@@ -233,13 +299,15 @@ function stripHeredocBodies(command) {
|
|
|
233
299
|
if (line.trim())
|
|
234
300
|
output.push(line);
|
|
235
301
|
const found = heredocDelimiters(line);
|
|
302
|
+
count += found.length;
|
|
303
|
+
quoted &&= found.every(item => item.quoted);
|
|
236
304
|
if (found.length) {
|
|
237
305
|
present = true;
|
|
238
306
|
active = found[0];
|
|
239
307
|
pending.push(...found.slice(1));
|
|
240
308
|
}
|
|
241
309
|
}
|
|
242
|
-
return { command: output.join(" ; "), present };
|
|
310
|
+
return { command: output.join(" ; "), present, safe: count === 1 && quoted && !active && pending.length === 0 };
|
|
243
311
|
}
|
|
244
312
|
function heredocDelimiters(line) {
|
|
245
313
|
const result = [];
|
|
@@ -282,7 +350,7 @@ function heredocDelimiters(line) {
|
|
|
282
350
|
index += 1;
|
|
283
351
|
const delimiter = line.slice(start, index);
|
|
284
352
|
if (delimiter)
|
|
285
|
-
result.push({ delimiter, stripTabs });
|
|
353
|
+
result.push({ delimiter, stripTabs, quoted: delimiterQuote !== null });
|
|
286
354
|
}
|
|
287
355
|
return result;
|
|
288
356
|
}
|