harnery 0.31.6 → 0.33.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/README.md +2 -0
- package/dist/commander.d.ts.map +1 -1
- package/dist/commander.js +5 -1
- package/dist/commands/agents.d.ts +0 -9
- package/dist/commands/agents.d.ts.map +1 -1
- package/dist/commands/agents.js +280 -94
- package/dist/commands/browse-session.d.ts +21 -0
- package/dist/commands/browse-session.d.ts.map +1 -0
- package/dist/commands/browse-session.js +157 -0
- package/dist/commands/browse.d.ts.map +1 -1
- package/dist/commands/browse.js +205 -37
- package/dist/commands/checkpoint.js +1 -1
- package/dist/commands/claude-desktop.d.ts +2 -2
- package/dist/commands/claude-desktop.d.ts.map +1 -1
- package/dist/commands/claude-desktop.js +74 -3
- package/dist/commands/deinit.d.ts.map +1 -1
- package/dist/commands/deinit.js +4 -0
- package/dist/commands/docs.d.ts.map +1 -1
- package/dist/commands/docs.js +40 -0
- package/dist/commands/doctor.d.ts +4 -2
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +141 -19
- package/dist/commands/init.d.ts +2 -2
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +26 -5
- package/dist/commands/instructions.d.ts +4 -0
- package/dist/commands/instructions.d.ts.map +1 -0
- package/dist/commands/instructions.js +100 -0
- package/dist/commands/presence.d.ts.map +1 -1
- package/dist/commands/presence.js +4 -1
- package/dist/commands/tunnel.d.ts.map +1 -1
- package/dist/commands/tunnel.js +2 -3
- package/dist/core/agents/canonical-emit.d.ts +2 -3
- package/dist/core/agents/canonical-emit.d.ts.map +1 -1
- package/dist/core/agents/canonical-emit.js +6 -5
- package/dist/core/agents/cli.js +128 -89
- package/dist/core/agents/coord-client.d.ts +18 -3
- package/dist/core/agents/coord-client.d.ts.map +1 -1
- package/dist/core/agents/coord-client.js +5 -4
- package/dist/core/agents/finalization.d.ts +68 -0
- package/dist/core/agents/finalization.d.ts.map +1 -0
- package/dist/core/agents/finalization.js +443 -0
- package/dist/core/agents/git-hook.d.ts +51 -0
- package/dist/core/agents/git-hook.d.ts.map +1 -0
- package/dist/core/agents/git-hook.js +118 -0
- package/dist/core/agents/index.d.ts +1 -0
- package/dist/core/agents/index.d.ts.map +1 -1
- package/dist/core/agents/index.js +1 -0
- package/dist/core/agents/render/prompt-context.d.ts +12 -5
- package/dist/core/agents/render/prompt-context.d.ts.map +1 -1
- package/dist/core/agents/render/prompt-context.js +70 -16
- package/dist/core/agents/render/session-context.d.ts.map +1 -1
- package/dist/core/agents/render/session-context.js +23 -4
- package/dist/core/agents/rules/claim-conflict.js +3 -3
- package/dist/core/agents/rules/commit-conflict.d.ts +15 -6
- package/dist/core/agents/rules/commit-conflict.d.ts.map +1 -1
- package/dist/core/agents/rules/commit-conflict.js +21 -5
- package/dist/core/agents/rules/stop-hook.d.ts +3 -0
- package/dist/core/agents/rules/stop-hook.d.ts.map +1 -1
- package/dist/core/agents/rules/stop-hook.js +59 -23
- package/dist/core/agents/session-events.d.ts +8 -16
- package/dist/core/agents/session-events.d.ts.map +1 -1
- package/dist/core/agents/session-events.js +12 -26
- package/dist/core/agents/state/heartbeat-projector.d.ts +14 -0
- package/dist/core/agents/state/heartbeat-projector.d.ts.map +1 -1
- package/dist/core/agents/state/heartbeat-projector.js +98 -1
- package/dist/core/agents/state/heartbeat-writer.d.ts +47 -5
- package/dist/core/agents/state/heartbeat-writer.d.ts.map +1 -1
- package/dist/core/agents/state/heartbeat-writer.js +86 -17
- package/dist/core/agents/state/names.d.ts +22 -1
- package/dist/core/agents/state/names.d.ts.map +1 -1
- package/dist/core/agents/state/names.js +40 -2
- package/dist/core/agents/state/session-state.d.ts +44 -0
- package/dist/core/agents/state/session-state.d.ts.map +1 -0
- package/dist/core/agents/state/session-state.js +81 -0
- package/dist/core/config.d.ts +30 -2
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +74 -11
- package/dist/core/governor/planning.d.ts.map +1 -1
- package/dist/core/governor/planning.js +12 -13
- package/dist/core/hooks/adapter/detect.d.ts +2 -4
- package/dist/core/hooks/adapter/detect.d.ts.map +1 -1
- package/dist/core/hooks/adapter/detect.js +4 -14
- package/dist/core/hooks/adapter/events.d.ts.map +1 -1
- package/dist/core/hooks/adapter/events.js +1 -0
- package/dist/core/hooks/adapter/output.d.ts +1 -1
- package/dist/core/hooks/adapter/output.d.ts.map +1 -1
- package/dist/core/hooks/adapter/output.js +5 -4
- package/dist/core/hooks/adapter/parse.d.ts +1 -1
- package/dist/core/hooks/adapter/parse.d.ts.map +1 -1
- package/dist/core/hooks/adapter/parse.js +2 -0
- package/dist/core/hooks/adapter/wiring.d.ts +23 -0
- package/dist/core/hooks/adapter/wiring.d.ts.map +1 -1
- package/dist/core/hooks/adapter/wiring.js +32 -0
- package/dist/core/hooks/cli.d.ts +1 -2
- package/dist/core/hooks/cli.d.ts.map +1 -1
- package/dist/core/hooks/cli.js +258 -32
- package/dist/core/hooks/codex-authorization.d.ts +30 -0
- package/dist/core/hooks/codex-authorization.d.ts.map +1 -0
- package/dist/core/hooks/codex-authorization.js +199 -0
- package/dist/core/hooks/codex-wsl-bridge.d.ts +46 -0
- package/dist/core/hooks/codex-wsl-bridge.d.ts.map +1 -0
- package/dist/core/hooks/codex-wsl-bridge.js +137 -0
- package/dist/core/hooks/effects/index.d.ts +1 -1
- package/dist/core/hooks/effects/index.js +3 -3
- package/dist/core/hooks/events/schema.d.ts +57 -1
- package/dist/core/hooks/events/schema.d.ts.map +1 -1
- package/dist/core/hooks/resolve/owner.d.ts +7 -1
- package/dist/core/hooks/resolve/owner.d.ts.map +1 -1
- package/dist/core/hooks/resolve/owner.js +15 -0
- package/dist/core/hooks/resolve/transcript.d.ts +44 -0
- package/dist/core/hooks/resolve/transcript.d.ts.map +1 -1
- package/dist/core/hooks/resolve/transcript.js +176 -1
- package/dist/core/hooks/session-name-presence.d.ts +30 -0
- package/dist/core/hooks/session-name-presence.d.ts.map +1 -0
- package/dist/core/hooks/session-name-presence.js +43 -0
- package/dist/core/hooks/unsafe-cross-shell.d.ts +13 -0
- package/dist/core/hooks/unsafe-cross-shell.d.ts.map +1 -0
- package/dist/core/hooks/unsafe-cross-shell.js +151 -0
- package/dist/core/presence/blob.d.ts +4 -0
- package/dist/core/presence/blob.d.ts.map +1 -1
- package/dist/core/presence/blob.js +12 -0
- package/dist/core/presence/index.js +15 -1
- package/dist/core/work/state.d.ts +4 -5
- package/dist/core/work/state.d.ts.map +1 -1
- package/dist/core/work/state.js +5 -8
- package/dist/core/workflow/index.d.ts +1 -1
- package/dist/core/workflow/index.d.ts.map +1 -1
- package/dist/core/workflow/proof.d.ts +2 -2
- package/dist/core/workflow/proof.d.ts.map +1 -1
- package/dist/core/workflow/proof.js +2 -2
- package/dist/core/workflow/run-state.d.ts +2 -2
- package/dist/core/workflow/run-state.d.ts.map +1 -1
- package/dist/core/workflow/run-state.js +2 -2
- package/dist/core/workflow/types.d.ts +3 -3
- package/dist/core/workflow/types.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/execution.d.ts +2 -2
- package/dist/core/workflow/workspaces/execution.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/execution.js +5 -0
- package/dist/core/workflow/workspaces/index.d.ts +1 -1
- package/dist/core/workflow/workspaces/index.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/local-git.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/local-git.js +1 -2
- package/dist/core/workflow/workspaces/paths.d.ts +2 -2
- package/dist/core/workflow/workspaces/types.d.ts +0 -6
- package/dist/core/workflow/workspaces/types.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/validate.d.ts +0 -2
- package/dist/core/workflow/workspaces/validate.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/validate.js +0 -2
- package/dist/lib/browser/client.d.ts +118 -1
- package/dist/lib/browser/client.d.ts.map +1 -1
- package/dist/lib/browser/client.js +435 -6
- package/dist/lib/browser/geometry.d.ts.map +1 -1
- package/dist/lib/browser/geometry.js +180 -37
- package/dist/lib/browser/index.d.ts +5 -1
- package/dist/lib/browser/index.d.ts.map +1 -1
- package/dist/lib/browser/index.js +5 -1
- package/dist/lib/browser/netscape-cookies.d.ts +6 -0
- package/dist/lib/browser/netscape-cookies.d.ts.map +1 -0
- package/dist/lib/browser/netscape-cookies.js +31 -0
- package/dist/lib/browser/proxy.d.ts +24 -0
- package/dist/lib/browser/proxy.d.ts.map +1 -0
- package/dist/lib/browser/proxy.js +84 -0
- package/dist/lib/browser/runts.d.ts +6 -0
- package/dist/lib/browser/runts.d.ts.map +1 -1
- package/dist/lib/browser/runts.js +21 -4
- package/dist/lib/browser/session-control.d.ts +112 -0
- package/dist/lib/browser/session-control.d.ts.map +1 -0
- package/dist/lib/browser/session-control.js +670 -0
- package/dist/lib/claude-desktop.d.ts +47 -0
- package/dist/lib/claude-desktop.d.ts.map +1 -1
- package/dist/lib/claude-desktop.js +169 -1
- package/dist/lib/docs-links.d.ts +108 -0
- package/dist/lib/docs-links.d.ts.map +1 -0
- package/dist/lib/docs-links.js +555 -0
- package/dist/lib/exec.d.ts +1 -1
- package/dist/lib/exec.js +1 -1
- package/dist/lib/identities/assume.d.ts +4 -2
- package/dist/lib/identities/assume.d.ts.map +1 -1
- package/dist/lib/identities/assume.js +15 -2
- package/dist/lib/instructions/bundle.d.ts +33 -0
- package/dist/lib/instructions/bundle.d.ts.map +1 -0
- package/dist/lib/instructions/bundle.js +149 -0
- package/dist/lib/instructions/git-hooks.d.ts +75 -0
- package/dist/lib/instructions/git-hooks.d.ts.map +1 -0
- package/dist/lib/instructions/git-hooks.js +238 -0
- package/dist/lib/instructions/splice.d.ts +10 -4
- package/dist/lib/instructions/splice.d.ts.map +1 -1
- package/dist/lib/instructions/splice.js +19 -11
- package/package.json +2 -2
- package/schemas/config.schema.json +32 -0
- package/src/commander.ts +5 -1
- package/src/commands/agents.ts +341 -113
- package/src/commands/browse-session.ts +245 -0
- package/src/commands/browse.ts +287 -44
- package/src/commands/checkpoint.ts +1 -1
- package/src/commands/claude-desktop.ts +106 -5
- package/src/commands/deinit.ts +7 -1
- package/src/commands/docs.ts +56 -0
- package/src/commands/doctor.ts +155 -21
- package/src/commands/init.ts +28 -9
- package/src/commands/instructions.ts +129 -0
- package/src/commands/presence.ts +7 -1
- package/src/commands/tunnel.ts +2 -5
- package/src/core/agents/canonical-emit.ts +7 -6
- package/src/core/agents/cli.ts +143 -89
- package/src/core/agents/coord-client.ts +21 -5
- package/src/core/agents/finalization.ts +595 -0
- package/src/core/agents/git-hook.ts +126 -0
- package/src/core/agents/index.ts +1 -0
- package/src/core/agents/render/prompt-context.ts +96 -16
- package/src/core/agents/render/session-context.ts +29 -4
- package/src/core/agents/rules/claim-conflict.ts +3 -3
- package/src/core/agents/rules/commit-conflict.ts +35 -8
- package/src/core/agents/rules/stop-hook.ts +71 -23
- package/src/core/agents/session-events.ts +14 -41
- package/src/core/agents/state/heartbeat-projector.ts +108 -1
- package/src/core/agents/state/heartbeat-writer.ts +129 -16
- package/src/core/agents/state/names.ts +54 -2
- package/src/core/agents/state/session-state.ts +131 -0
- package/src/core/config.ts +92 -12
- package/src/core/governor/planning.ts +17 -12
- package/src/core/hooks/adapter/detect.ts +4 -13
- package/src/core/hooks/adapter/events.ts +1 -0
- package/src/core/hooks/adapter/output.ts +9 -4
- package/src/core/hooks/adapter/parse.ts +3 -0
- package/src/core/hooks/adapter/wiring.ts +43 -0
- package/src/core/hooks/cli.ts +296 -27
- package/src/core/hooks/codex-authorization.ts +253 -0
- package/src/core/hooks/codex-wsl-bridge.ts +188 -0
- package/src/core/hooks/effects/index.ts +5 -5
- package/src/core/hooks/events/schema.ts +71 -0
- package/src/core/hooks/resolve/owner.ts +22 -1
- package/src/core/hooks/resolve/transcript.ts +164 -1
- package/src/core/hooks/session-name-presence.ts +52 -0
- package/src/core/hooks/unsafe-cross-shell.ts +160 -0
- package/src/core/presence/blob.ts +18 -0
- package/src/core/presence/index.ts +18 -1
- package/src/core/work/state.ts +8 -12
- package/src/core/workflow/engine.ts +2 -2
- package/src/core/workflow/index.ts +0 -1
- package/src/core/workflow/proof.ts +4 -4
- package/src/core/workflow/run-state.ts +5 -5
- package/src/core/workflow/types.ts +3 -3
- package/src/core/workflow/workspaces/execution.ts +11 -4
- package/src/core/workflow/workspaces/index.ts +0 -3
- package/src/core/workflow/workspaces/local-git.ts +1 -2
- package/src/core/workflow/workspaces/paths.ts +2 -2
- package/src/core/workflow/workspaces/types.ts +0 -9
- package/src/core/workflow/workspaces/validate.ts +1 -5
- package/src/lib/browser/client.ts +528 -6
- package/src/lib/browser/geometry.ts +197 -37
- package/src/lib/browser/index.ts +39 -0
- package/src/lib/browser/netscape-cookies.ts +39 -0
- package/src/lib/browser/proxy.ts +105 -0
- package/src/lib/browser/runts.ts +27 -3
- package/src/lib/browser/session-control.ts +892 -0
- package/src/lib/claude-desktop.ts +232 -1
- package/src/lib/docs-links.ts +674 -0
- package/src/lib/exec.ts +1 -1
- package/src/lib/identities/assume.ts +22 -1
- package/src/lib/instructions/bundle.ts +199 -0
- package/src/lib/instructions/git-hooks.ts +259 -0
- package/src/lib/instructions/splice.ts +41 -11
package/dist/core/agents/cli.js
CHANGED
|
@@ -91,24 +91,11 @@ async function handleVerdict(root) {
|
|
|
91
91
|
const { evaluateClaim } = await import("./rules/claim-conflict.js");
|
|
92
92
|
verdict = evaluateClaim(root, parsed);
|
|
93
93
|
}
|
|
94
|
-
else if (parsed.rule === "commit") {
|
|
95
|
-
const { evaluateCommit } = await import("./rules/commit-conflict.js");
|
|
96
|
-
const result = evaluateCommit(root, parsed);
|
|
97
|
-
// Map CommitVerdictResult → the standard verdict envelope, stash details
|
|
98
|
-
// on extra fields so the bash caller can pull conflicts + log_lines.
|
|
99
|
-
verdict = {
|
|
100
|
-
allow: result.allow,
|
|
101
|
-
exit_code: result.exit_code,
|
|
102
|
-
rule: result.rule,
|
|
103
|
-
reason: result.message,
|
|
104
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
105
|
-
};
|
|
106
|
-
verdict.conflicts = result.conflicts;
|
|
107
|
-
verdict.log_lines = result.log_lines;
|
|
108
|
-
verdict.suppressed_self_attribution =
|
|
109
|
-
result.suppressed_self_attribution ?? false;
|
|
110
|
-
}
|
|
111
94
|
else {
|
|
95
|
+
// NB: rule === "commit" was served here until 2026-08-09; the commit
|
|
96
|
+
// guard now enters through `git-hook pre-commit`, which runs the same
|
|
97
|
+
// evaluateCommit in-process. A straggler host lands in this fail-open
|
|
98
|
+
// branch, which is the pre-migration behavior for a malformed request.
|
|
112
99
|
verdict = {
|
|
113
100
|
allow: true,
|
|
114
101
|
exit_code: 0,
|
|
@@ -233,13 +220,6 @@ async function handleStateAction(root, action, rest) {
|
|
|
233
220
|
process.stdout.write(`${JSON.stringify({ instance_id: owner, task: hb.task ?? null, cleared: !task })}\n`);
|
|
234
221
|
return 0;
|
|
235
222
|
}
|
|
236
|
-
case "stamp-status-call": {
|
|
237
|
-
const hb = writer.stampStatusCheck(root, owner);
|
|
238
|
-
if (!hb)
|
|
239
|
-
return 1;
|
|
240
|
-
process.stdout.write(`${JSON.stringify({ instance_id: owner, last_status_at: hb.last_status_at })}\n`);
|
|
241
|
-
return 0;
|
|
242
|
-
}
|
|
243
223
|
case "set-turn-summary": {
|
|
244
224
|
const summary = args.join(" ");
|
|
245
225
|
const hb = writer.setTurnSummary(root, owner, summary);
|
|
@@ -313,10 +293,13 @@ async function handleStateAction(root, action, rest) {
|
|
|
313
293
|
// fragility. Positionals (sessionId, model) stay as-is once flags are
|
|
314
294
|
// filtered out.
|
|
315
295
|
const adapter = args.find((a) => a.startsWith("--adapter="))?.slice("--adapter=".length);
|
|
296
|
+
const forkedFrom = args
|
|
297
|
+
.find((a) => a.startsWith("--forked-from="))
|
|
298
|
+
?.slice("--forked-from=".length);
|
|
316
299
|
const positional = args.filter((a) => !a.startsWith("--"));
|
|
317
300
|
const sessionId = positional[0];
|
|
318
301
|
const model = positional[1];
|
|
319
|
-
const hb = writer.healHeartbeat(root, owner, sessionId, model, adapter);
|
|
302
|
+
const hb = writer.healHeartbeat(root, owner, sessionId, model, adapter, forkedFrom ? { forkedFrom } : undefined);
|
|
320
303
|
process.stdout.write(`${JSON.stringify({ instance_id: owner, recreated: !!hb })}\n`);
|
|
321
304
|
return hb ? 0 : 1;
|
|
322
305
|
}
|
|
@@ -450,70 +433,35 @@ async function handleCouncilAction(root, action, rest) {
|
|
|
450
433
|
}
|
|
451
434
|
async function handleAssignName(root, rest) {
|
|
452
435
|
const { assignName } = await import("./state/names.js");
|
|
453
|
-
|
|
436
|
+
// Optional recorded-fork-lineage flag: --forked-from <parent_instance_id>.
|
|
437
|
+
// Supplied by an adapter layer that knows (or detected) that this session
|
|
438
|
+
// was branched from another conversation. Inert on resume: assignName only
|
|
439
|
+
// stamps lineage on the row that first assigns the instance.
|
|
440
|
+
let forkedFrom;
|
|
441
|
+
const positional = [];
|
|
442
|
+
for (let i = 0; i < rest.length; i++) {
|
|
443
|
+
if (rest[i] === "--forked-from") {
|
|
444
|
+
forkedFrom = rest[++i];
|
|
445
|
+
continue;
|
|
446
|
+
}
|
|
447
|
+
positional.push(rest[i]);
|
|
448
|
+
}
|
|
449
|
+
const [owner, kindArg] = positional;
|
|
454
450
|
if (!owner || !kindArg) {
|
|
455
|
-
process.stderr.write("agent-coord assign-name <instance_id> <session|subagent|transient
|
|
451
|
+
process.stderr.write("agent-coord assign-name <instance_id> <session|subagent|transient> [--forked-from <instance_id>]\n");
|
|
456
452
|
return 2;
|
|
457
453
|
}
|
|
458
454
|
if (kindArg !== "session" && kindArg !== "subagent" && kindArg !== "transient") {
|
|
459
455
|
process.stderr.write(`agent-coord assign-name: invalid kind ${kindArg}\n`);
|
|
460
456
|
return 2;
|
|
461
457
|
}
|
|
462
|
-
const name = assignName(root, owner, kindArg);
|
|
463
|
-
process.stdout.write(`${JSON.stringify({
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
try {
|
|
470
|
-
req = JSON.parse(raw);
|
|
471
|
-
}
|
|
472
|
-
catch {
|
|
473
|
-
return 0;
|
|
474
|
-
}
|
|
475
|
-
const { groupUnclaim } = await import("./state/heartbeat-writer.js");
|
|
476
|
-
// Session-group-wide unclaim. `owner` is the parent's session_id which is
|
|
477
|
-
// also the group key (parent + subagents share session_id). Each actual
|
|
478
|
-
// removal also emits a durable claim.release event — the projector rebuilds
|
|
479
|
-
// files_touched from the permanent Edit/Write events, so a file-only prune
|
|
480
|
-
// would resurrect on the next replay.
|
|
481
|
-
if (req.owner && Array.isArray(req.prune)) {
|
|
482
|
-
for (const path of req.prune) {
|
|
483
|
-
try {
|
|
484
|
-
for (const hit of groupUnclaim(root, req.owner, path)) {
|
|
485
|
-
await emitClaimRelease(root, hit.instance_id, hit, path, "commit");
|
|
486
|
-
}
|
|
487
|
-
}
|
|
488
|
-
catch {
|
|
489
|
-
/* best-effort */
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
return 0;
|
|
494
|
-
}
|
|
495
|
-
async function handlePostCheckout(root, _rest) {
|
|
496
|
-
const raw = await readStdin();
|
|
497
|
-
let req = {};
|
|
498
|
-
try {
|
|
499
|
-
req = JSON.parse(raw);
|
|
500
|
-
}
|
|
501
|
-
catch {
|
|
502
|
-
return 0;
|
|
503
|
-
}
|
|
504
|
-
const { groupUnclaim } = await import("./state/heartbeat-writer.js");
|
|
505
|
-
if (req.owner && Array.isArray(req.removed)) {
|
|
506
|
-
for (const path of req.removed) {
|
|
507
|
-
try {
|
|
508
|
-
for (const hit of groupUnclaim(root, req.owner, path)) {
|
|
509
|
-
await emitClaimRelease(root, hit.instance_id, hit, path, "checkout");
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
catch {
|
|
513
|
-
/* best-effort */
|
|
514
|
-
}
|
|
515
|
-
}
|
|
516
|
-
}
|
|
458
|
+
const name = assignName(root, owner, kindArg, forkedFrom ? { forkedFrom } : undefined);
|
|
459
|
+
process.stdout.write(`${JSON.stringify({
|
|
460
|
+
instance_id: owner,
|
|
461
|
+
name,
|
|
462
|
+
kind: kindArg,
|
|
463
|
+
...(forkedFrom ? { forked_from: forkedFrom } : {}),
|
|
464
|
+
})}\n`);
|
|
517
465
|
return 0;
|
|
518
466
|
}
|
|
519
467
|
async function handleShellMutationPaths(root, rest) {
|
|
@@ -616,8 +564,11 @@ async function handlePromptContext(root, rest) {
|
|
|
616
564
|
const sessionNameNudge = args["session-name-nudge"] === "true";
|
|
617
565
|
const taskNudge = args["task-nudge"] === "true";
|
|
618
566
|
const statusFooterNudge = args["status-footer-nudge"] === "true";
|
|
567
|
+
// Value is the adapter id; a bare flag (parsed as "true") still enables the
|
|
568
|
+
// reminder with the adapter-neutral wording.
|
|
569
|
+
const turnRitualNudge = args["turn-ritual-nudge"] === "true" ? "generic" : args["turn-ritual-nudge"];
|
|
619
570
|
if (!instanceId) {
|
|
620
|
-
process.stderr.write("agent-coord prompt-context --instance <id> [--session <id>] [--name <agent-name>] [--session-name-nudge] [--task-nudge] [--status-footer-nudge]\n");
|
|
571
|
+
process.stderr.write("agent-coord prompt-context --instance <id> [--session <id>] [--name <agent-name>] [--session-name-nudge] [--task-nudge] [--status-footer-nudge] [--turn-ritual-nudge <adapter>]\n");
|
|
621
572
|
return 2;
|
|
622
573
|
}
|
|
623
574
|
const { renderPromptContext } = await import("./render/prompt-context.js");
|
|
@@ -629,6 +580,7 @@ async function handlePromptContext(root, rest) {
|
|
|
629
580
|
sessionNameNudge,
|
|
630
581
|
taskNudge,
|
|
631
582
|
statusFooterNudge,
|
|
583
|
+
turnRitualNudge,
|
|
632
584
|
});
|
|
633
585
|
process.stdout.write(text);
|
|
634
586
|
return 0;
|
|
@@ -776,6 +728,97 @@ async function handleEmitEvent(root, rest) {
|
|
|
776
728
|
process.stdout.write(`${JSON.stringify(result.envelope)}\n`);
|
|
777
729
|
return 0;
|
|
778
730
|
}
|
|
731
|
+
/**
|
|
732
|
+
* `agent-coord git-hook <event> [args]` — the single entry a host git hook
|
|
733
|
+
* invokes. Owns ALL of the coordination git plumbing that hosts used to carry
|
|
734
|
+
* as bash (staged/committed/checkout-removed collection, submodule
|
|
735
|
+
* canonicalization, gitlink probe, verdict, claim pruning), so a harnery
|
|
736
|
+
* upgrade upgrades hook behavior with no change to the host's hook file.
|
|
737
|
+
*
|
|
738
|
+
* Events: pre-commit (E-guard verdict; exit 1 blocks the commit),
|
|
739
|
+
* post-commit (prune committed paths' claims), post-checkout <old> <new>
|
|
740
|
+
* (release claims on paths the ref move rewrote).
|
|
741
|
+
*
|
|
742
|
+
* Fail-open by design: an internal error never blocks a commit (parity with
|
|
743
|
+
* the bash era, where a crashed verdict read as empty and the hook moved on).
|
|
744
|
+
* A clean conflict verdict still blocks.
|
|
745
|
+
*/
|
|
746
|
+
async function handleGitHook(fallbackRoot, rest) {
|
|
747
|
+
const event = rest[0];
|
|
748
|
+
if (process.env.HARNERY_AGENT_COORD_OFF === "1")
|
|
749
|
+
return 0;
|
|
750
|
+
const cwd = process.cwd();
|
|
751
|
+
try {
|
|
752
|
+
const gh = await import("./git-hook.js");
|
|
753
|
+
// Pin the coord root to the superproject: a submodule cwd may carry its
|
|
754
|
+
// own config-only .harnery that the generic root walk would land on.
|
|
755
|
+
const root = gh.discoverCoordRoot(cwd) ?? fallbackRoot;
|
|
756
|
+
if (event === "pre-commit") {
|
|
757
|
+
const { staged, gitlinks } = gh.collectStaged(cwd);
|
|
758
|
+
if (staged.length === 0)
|
|
759
|
+
return 0;
|
|
760
|
+
const { evaluateCommit } = await import("./rules/commit-conflict.js");
|
|
761
|
+
const result = evaluateCommit(root, {
|
|
762
|
+
staged_paths: staged,
|
|
763
|
+
staged_gitlinks: gitlinks,
|
|
764
|
+
bypass: process.env.HARNERY_AGENT_COORD_BYPASS === "1",
|
|
765
|
+
});
|
|
766
|
+
// Forensics channel shared with the stdin `verdict` path.
|
|
767
|
+
try {
|
|
768
|
+
const logPath = join(root, ".harnery", "debug", "agent-coord-verdict.ndjson");
|
|
769
|
+
await mkdir(dirname(logPath), { recursive: true });
|
|
770
|
+
await appendFile(logPath, `${JSON.stringify({ ts: new Date().toISOString(), via: "git-hook", staged, verdict: result })}\n`);
|
|
771
|
+
}
|
|
772
|
+
catch {
|
|
773
|
+
/* diagnostics never break a verdict */
|
|
774
|
+
}
|
|
775
|
+
if (result.rule !== "commit.pass") {
|
|
776
|
+
if (result.message)
|
|
777
|
+
process.stdout.write(`\n${result.message}\n\n`);
|
|
778
|
+
for (const c of result.conflicts) {
|
|
779
|
+
process.stdout.write(` ${c.staged_path} (held by ${c.short_name})\n`);
|
|
780
|
+
}
|
|
781
|
+
process.stdout.write("\n");
|
|
782
|
+
}
|
|
783
|
+
if (!result.allow) {
|
|
784
|
+
process.stdout.write(" Wait for them to finish, split the commit, or set\n" +
|
|
785
|
+
" HARNERY_AGENT_COORD_BYPASS=1 to force this commit through.\n\n");
|
|
786
|
+
return result.exit_code || 1;
|
|
787
|
+
}
|
|
788
|
+
return 0;
|
|
789
|
+
}
|
|
790
|
+
if (event === "post-commit" || event === "post-checkout") {
|
|
791
|
+
const paths = event === "post-commit"
|
|
792
|
+
? gh.collectCommitted(cwd)
|
|
793
|
+
: gh.collectCheckoutRemoved(cwd, rest[1] ?? "", rest[2] ?? "");
|
|
794
|
+
if (paths.length === 0)
|
|
795
|
+
return 0;
|
|
796
|
+
const { resolveOwner } = await import("../hooks/resolve/owner.js");
|
|
797
|
+
const owner = resolveOwner({ payload: null, coordRoot: root })?.instance_id;
|
|
798
|
+
if (!owner)
|
|
799
|
+
return 0;
|
|
800
|
+
const { groupUnclaim } = await import("./state/heartbeat-writer.js");
|
|
801
|
+
const reason = event === "post-commit" ? "commit" : "checkout";
|
|
802
|
+
for (const path of paths) {
|
|
803
|
+
try {
|
|
804
|
+
for (const hit of groupUnclaim(root, owner, path)) {
|
|
805
|
+
await emitClaimRelease(root, hit.instance_id, hit, path, reason);
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
catch {
|
|
809
|
+
/* best-effort */
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
return 0;
|
|
813
|
+
}
|
|
814
|
+
process.stderr.write(`agent-coord git-hook: unknown event ${event ?? "(none)"}\n`);
|
|
815
|
+
return 0;
|
|
816
|
+
}
|
|
817
|
+
catch {
|
|
818
|
+
// Fail open: coordination must never brick git.
|
|
819
|
+
return 0;
|
|
820
|
+
}
|
|
821
|
+
}
|
|
779
822
|
async function main() {
|
|
780
823
|
const [subcommand, ...rest] = process.argv.slice(2);
|
|
781
824
|
const root = findCoordRoot(process.cwd());
|
|
@@ -791,7 +834,6 @@ async function main() {
|
|
|
791
834
|
return handleEmitEvent(root, rest);
|
|
792
835
|
}
|
|
793
836
|
if (subcommand === "set-task" ||
|
|
794
|
-
subcommand === "stamp-status-call" ||
|
|
795
837
|
subcommand === "set-turn-summary" ||
|
|
796
838
|
subcommand === "release-claim" ||
|
|
797
839
|
subcommand === "kill-heartbeat" ||
|
|
@@ -835,11 +877,8 @@ async function main() {
|
|
|
835
877
|
if (subcommand === "shell-mutation-claim-log") {
|
|
836
878
|
return handleShellMutationClaimLog(root, rest);
|
|
837
879
|
}
|
|
838
|
-
if (subcommand === "
|
|
839
|
-
return
|
|
840
|
-
}
|
|
841
|
-
if (subcommand === "post-checkout") {
|
|
842
|
-
return handlePostCheckout(root, rest);
|
|
880
|
+
if (subcommand === "git-hook") {
|
|
881
|
+
return handleGitHook(root, rest);
|
|
843
882
|
}
|
|
844
883
|
await logNoop(root, subcommand ?? "(none)", rest);
|
|
845
884
|
// Phase 1/2: silent on stdout for unknown subcommands, exit 0. Existing
|
|
@@ -40,12 +40,27 @@ export interface Heartbeat {
|
|
|
40
40
|
task?: string;
|
|
41
41
|
/** UTC ISO-8601 timestamp when task was last set/cleared. Used by adapters without Stop enforcement to compute staleness. 2026-05-24. */
|
|
42
42
|
task_updated_at?: string | null;
|
|
43
|
+
/** Current evidence-derived activity axis. */
|
|
44
|
+
activity?: "unknown" | "working" | "needs_input" | "idle";
|
|
45
|
+
activity_updated_at?: string;
|
|
46
|
+
activity_source?: string;
|
|
47
|
+
/** Explicit task lifecycle axis. */
|
|
48
|
+
task_state?: "active" | "blocked" | "done";
|
|
49
|
+
task_state_updated_at?: string;
|
|
50
|
+
task_state_reason?: string;
|
|
51
|
+
/** Session name built on the first non-empty set-task; its presence means "this session has been named". 2026-08-09. */
|
|
52
|
+
suggested_session_name?: string;
|
|
53
|
+
/** Stamped by turn.stop once the suggested name is seen in assistant reply text. 2026-08-09. */
|
|
54
|
+
session_name_seen_at?: string;
|
|
55
|
+
/** Which suggested name the latest sighting covered. */
|
|
56
|
+
session_name_seen_for?: string;
|
|
43
57
|
/** Auto-generated per-turn summary written by the Stop hook via Haiku. 2026-05-23. */
|
|
44
58
|
turn_summary?: string | null;
|
|
45
59
|
/** UTC ISO-8601 timestamp when turn_summary was last refreshed. */
|
|
46
60
|
turn_summary_updated_at?: string | null;
|
|
47
|
-
/** Hook client: `
|
|
61
|
+
/** Hook client: `claude-code` (default) or `cursor`. Cursor Phase 1. */
|
|
48
62
|
platform?: string;
|
|
63
|
+
workflow_run_id?: string;
|
|
49
64
|
}
|
|
50
65
|
/**
|
|
51
66
|
* Resolve the monorepo root for coord-state purposes.
|
|
@@ -101,7 +116,7 @@ export declare function nearestCoordRoot(start: string): string | null;
|
|
|
101
116
|
export declare function rootKnowsSession(root: string): boolean;
|
|
102
117
|
/** Parse owner from a pid-map row (`owner` or `owner\tplatform`). */
|
|
103
118
|
export declare function parsePidmapRowOwner(row: string): string;
|
|
104
|
-
/** Parse platform from a pid-map row; legacy rows default to `
|
|
119
|
+
/** Parse platform from a pid-map row; legacy rows default to `claude-code`. */
|
|
105
120
|
export declare function parsePidmapRowPlatform(row: string): string;
|
|
106
121
|
/** Parse the start token from a pid-map row; rows written before it carry none. */
|
|
107
122
|
export declare function parsePidmapRowStartToken(row: string): string | undefined;
|
|
@@ -128,7 +143,7 @@ export declare function pidStartToken(pid: number): string | null;
|
|
|
128
143
|
*
|
|
129
144
|
* Pid-map files are `instance_id` or `instance_id\tplatform` (Cursor Phase 1).
|
|
130
145
|
* Prefer a row whose platform matches `HARNERY_AGENT_COORD_PLATFORM` (default
|
|
131
|
-
* `
|
|
146
|
+
* `claude-code`); otherwise return the first owner seen on the walk.
|
|
132
147
|
*
|
|
133
148
|
* Subagents intentionally do not write pid-map entries; a Bash-tool ppid-walk
|
|
134
149
|
* from inside a subagent therefore resolves to the *parent's* pid-map entry.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"coord-client.d.ts","sourceRoot":"","sources":["../../../src/core/agents/coord-client.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAWH;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAWhE;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,KAAK,IAAI,MAAM,CAI5E;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAOhF;AAED,MAAM,WAAW,SAAS;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,sEAAsE;IACtE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oGAAoG;IACpG,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,4EAA4E;IAC5E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yIAAyI;IACzI,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,sFAAsF;IACtF,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,mEAAmE;IACnE,uBAAuB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,wEAAwE;IACxE,QAAQ,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"coord-client.d.ts","sourceRoot":"","sources":["../../../src/core/agents/coord-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -224,10 +224,10 @@ export function parsePidmapRowOwner(row) {
|
|
|
224
224
|
const tab = trimmed.indexOf("\t");
|
|
225
225
|
return tab >= 0 ? trimmed.slice(0, tab) : trimmed;
|
|
226
226
|
}
|
|
227
|
-
/** Parse platform from a pid-map row; legacy rows default to `
|
|
227
|
+
/** Parse platform from a pid-map row; legacy rows default to `claude-code`. */
|
|
228
228
|
export function parsePidmapRowPlatform(row) {
|
|
229
229
|
const platform = row.trim().split("\t")[1]?.trim();
|
|
230
|
-
return platform || "
|
|
230
|
+
return platform || "claude-code";
|
|
231
231
|
}
|
|
232
232
|
/** Parse the start token from a pid-map row; rows written before it carry none. */
|
|
233
233
|
export function parsePidmapRowStartToken(row) {
|
|
@@ -336,7 +336,7 @@ function readPidmapRow(pidmapDir, pid) {
|
|
|
336
336
|
*
|
|
337
337
|
* Pid-map files are `instance_id` or `instance_id\tplatform` (Cursor Phase 1).
|
|
338
338
|
* Prefer a row whose platform matches `HARNERY_AGENT_COORD_PLATFORM` (default
|
|
339
|
-
* `
|
|
339
|
+
* `claude-code`); otherwise return the first owner seen on the walk.
|
|
340
340
|
*
|
|
341
341
|
* Subagents intentionally do not write pid-map entries; a Bash-tool ppid-walk
|
|
342
342
|
* from inside a subagent therefore resolves to the *parent's* pid-map entry.
|
|
@@ -400,7 +400,7 @@ export function resolveOwnerByPidmap(root) {
|
|
|
400
400
|
const pidmapDir = resolve(root, ".harnery", "pid-map");
|
|
401
401
|
if (!existsSync(pidmapDir))
|
|
402
402
|
return { owner: null, source: "none" };
|
|
403
|
-
const prefer = process.env.HARNERY_AGENT_COORD_PLATFORM?.trim() || "
|
|
403
|
+
const prefer = process.env.HARNERY_AGENT_COORD_PLATFORM?.trim() || "claude-code";
|
|
404
404
|
let fallbackOwner = null;
|
|
405
405
|
let pid = process.pid;
|
|
406
406
|
for (let hop = 0; hop < 20; hop++) {
|
|
@@ -439,6 +439,7 @@ const SESSION_ID_ENV_VARS = [
|
|
|
439
439
|
"CURSOR_SESSION_ID",
|
|
440
440
|
"CURSOR_CONVERSATION_ID",
|
|
441
441
|
"CODEX_SESSION_ID",
|
|
442
|
+
"CODEX_THREAD_ID",
|
|
442
443
|
];
|
|
443
444
|
/** Read normalized candidates from the first non-empty adapter session-id env var. */
|
|
444
445
|
function sessionIdsFromEnv() {
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ownership-aware Git completion checks for the end-of-turn status ritual.
|
|
3
|
+
*
|
|
4
|
+
* The heartbeat's durable `files_touched` ledger is the ownership boundary. We
|
|
5
|
+
* inspect only those paths, plus any enclosing submodule gitlinks, so a peer's
|
|
6
|
+
* active edits elsewhere in a shared checkout do not block this session.
|
|
7
|
+
*/
|
|
8
|
+
import { type AgentFinalizationDisposition } from "../config.js";
|
|
9
|
+
export interface GitFinalizationResult {
|
|
10
|
+
ok: boolean;
|
|
11
|
+
claim_history_complete: boolean;
|
|
12
|
+
dirty_paths: string[];
|
|
13
|
+
unpushed_repos: string[];
|
|
14
|
+
host_output_paths: string[];
|
|
15
|
+
unsupported_paths: UnsupportedFinalizationPath[];
|
|
16
|
+
unverifiable_paths: string[];
|
|
17
|
+
unverifiable_repos: string[];
|
|
18
|
+
repos_checked: string[];
|
|
19
|
+
}
|
|
20
|
+
export type UnsupportedFinalizationReason = "outside_finalization_roots" | "invalid_finalization_root" | "ambiguous_finalization_roots" | "path_escapes_finalization_root" | "git_repository_unavailable" | "output_path_is_git";
|
|
21
|
+
export interface UnsupportedFinalizationPath {
|
|
22
|
+
path: string;
|
|
23
|
+
reason: UnsupportedFinalizationReason;
|
|
24
|
+
}
|
|
25
|
+
export interface ClaimFinalizationDescriptor {
|
|
26
|
+
disposition: AgentFinalizationDisposition;
|
|
27
|
+
root: string;
|
|
28
|
+
}
|
|
29
|
+
export type ClaimFinalizationDecision = {
|
|
30
|
+
allow: true;
|
|
31
|
+
path: string;
|
|
32
|
+
descriptor: ClaimFinalizationDescriptor;
|
|
33
|
+
authorityRoot: string;
|
|
34
|
+
repo?: {
|
|
35
|
+
root: string;
|
|
36
|
+
path: string;
|
|
37
|
+
};
|
|
38
|
+
} | {
|
|
39
|
+
allow: false;
|
|
40
|
+
path: string;
|
|
41
|
+
reason: UnsupportedFinalizationReason;
|
|
42
|
+
};
|
|
43
|
+
export interface SessionWriteClaims {
|
|
44
|
+
paths: string[];
|
|
45
|
+
complete: boolean;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Read every write claim made by this session, including claims released after
|
|
49
|
+
* a commit. Current heartbeat claims describe dirty ownership; this history is
|
|
50
|
+
* what keeps the touched repository in scope until its commits are pushed.
|
|
51
|
+
*/
|
|
52
|
+
export declare function readSessionWriteClaims(coordRoot: string, instanceId: string, sessionId: string): SessionWriteClaims;
|
|
53
|
+
/**
|
|
54
|
+
* Resolve one guarded write to the host's single supported end-turn
|
|
55
|
+
* disposition. Claim event data never grants authority: every call starts from
|
|
56
|
+
* the project-owned finalization roots and only then inspects the selected
|
|
57
|
+
* repository or output tree.
|
|
58
|
+
*/
|
|
59
|
+
export declare function classifyWriteClaimFinalization(coordRoot: string, heldPath: string): ClaimFinalizationDecision;
|
|
60
|
+
/** Check that this session's held paths are committed and their repositories are pushed. */
|
|
61
|
+
export declare function checkGitFinalization(coordRoot: string, heldPaths: readonly string[], options?: {
|
|
62
|
+
claimHistoryComplete?: boolean;
|
|
63
|
+
}): GitFinalizationResult;
|
|
64
|
+
export declare function formatGitFinalizationFailure(result: GitFinalizationResult, bin: string): string;
|
|
65
|
+
export declare function formatWriteClaimFinalizationDenial(decision: Extract<ClaimFinalizationDecision, {
|
|
66
|
+
allow: false;
|
|
67
|
+
}>, bin: string): string;
|
|
68
|
+
//# sourceMappingURL=finalization.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"finalization.d.ts","sourceRoot":"","sources":["../../../src/core/agents/finalization.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,EAAE,KAAK,4BAA4B,EAA2B,MAAM,cAAc,CAAC;AA4B1F,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,OAAO,CAAC;IACZ,sBAAsB,EAAE,OAAO,CAAC;IAChC,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,iBAAiB,EAAE,2BAA2B,EAAE,CAAC;IACjD,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,MAAM,MAAM,6BAA6B,GACrC,4BAA4B,GAC5B,2BAA2B,GAC3B,8BAA8B,GAC9B,gCAAgC,GAChC,4BAA4B,GAC5B,oBAAoB,CAAC;AAEzB,MAAM,WAAW,2BAA2B;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,6BAA6B,CAAC;CACvC;AAED,MAAM,WAAW,2BAA2B;IAC1C,WAAW,EAAE,4BAA4B,CAAC;IAC1C,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,MAAM,yBAAyB,GACjC;IACE,KAAK,EAAE,IAAI,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,2BAA2B,CAAC;IACxC,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CACvC,GACD;IACE,KAAK,EAAE,KAAK,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,6BAA6B,CAAC;CACvC,CAAC;AAEN,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAChB,kBAAkB,CA+BpB;AA+JD;;;;;GAKG;AACH,wBAAgB,8BAA8B,CAC5C,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,yBAAyB,CA2D3B;AA2ED,4FAA4F;AAC5F,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,SAAS,MAAM,EAAE,EAC5B,OAAO,GAAE;IAAE,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAAO,GAC/C,qBAAqB,CA6EvB;AAED,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,qBAAqB,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAkD/F;AAmBD,wBAAgB,kCAAkC,CAChD,QAAQ,EAAE,OAAO,CAAC,yBAAyB,EAAE;IAAE,KAAK,EAAE,KAAK,CAAA;CAAE,CAAC,EAC9D,GAAG,EAAE,MAAM,GACV,MAAM,CAQR"}
|