harnery 0.34.1 → 0.35.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/dist/commander.d.ts.map +1 -1
- package/dist/commander.js +2 -0
- package/dist/commands/agents.d.ts +15 -4
- package/dist/commands/agents.d.ts.map +1 -1
- package/dist/commands/agents.js +89 -175
- package/dist/commands/browse.d.ts.map +1 -1
- package/dist/commands/browse.js +26 -2
- package/dist/commands/decision.d.ts.map +1 -1
- package/dist/commands/decision.js +2 -2
- package/dist/commands/events.d.ts.map +1 -1
- package/dist/commands/events.js +18 -1
- package/dist/commands/presence.d.ts.map +1 -1
- package/dist/commands/presence.js +2 -2
- package/dist/commands/semantic.d.ts +4 -0
- package/dist/commands/semantic.d.ts.map +1 -0
- package/dist/commands/semantic.js +147 -0
- package/dist/commands/web.d.ts.map +1 -1
- package/dist/commands/web.js +17 -0
- package/dist/core/agents/canonical-emit.d.ts +3 -0
- package/dist/core/agents/canonical-emit.d.ts.map +1 -1
- package/dist/core/agents/canonical-emit.js +12 -0
- package/dist/core/agents/claim-path.d.ts +11 -0
- package/dist/core/agents/claim-path.d.ts.map +1 -0
- package/dist/core/agents/claim-path.js +22 -0
- package/dist/core/agents/coord-client.d.ts +29 -3
- package/dist/core/agents/coord-client.d.ts.map +1 -1
- package/dist/core/agents/coord-client.js +88 -9
- package/dist/core/agents/live-authority-v3.d.ts.map +1 -1
- package/dist/core/agents/live-authority-v3.js +1 -3
- package/dist/core/agents/live-lifecycle-v3.js +3 -3
- package/dist/core/agents/live-observation-v3.d.ts.map +1 -1
- package/dist/core/agents/live-observation-v3.js +2 -2
- package/dist/core/agents/render/prompt-context.js +12 -10
- package/dist/core/agents/rules/stop-hook.d.ts.map +1 -1
- package/dist/core/agents/rules/stop-hook.js +23 -11
- package/dist/core/agents/session-name-display.d.ts +1 -0
- package/dist/core/agents/session-name-display.d.ts.map +1 -1
- package/dist/core/agents/session-name-display.js +8 -1
- package/dist/core/agents/state/heartbeat-reader.d.ts +46 -0
- package/dist/core/agents/state/heartbeat-reader.d.ts.map +1 -0
- package/dist/core/agents/state/heartbeat-reader.js +25 -0
- package/dist/core/agents/state/heartbeat-writer.d.ts +3 -48
- package/dist/core/agents/state/heartbeat-writer.d.ts.map +1 -1
- package/dist/core/agents/state/heartbeat-writer.js +16 -34
- package/dist/core/agents/state/live-coordination-view.d.ts +1 -1
- package/dist/core/agents/state/live-coordination-view.d.ts.map +1 -1
- package/dist/core/agents/state/live-coordination-view.js +25 -1
- package/dist/core/agents/state/names.d.ts +9 -1
- package/dist/core/agents/state/names.d.ts.map +1 -1
- package/dist/core/agents/state/names.js +190 -182
- package/dist/core/agents/state/stale-sweep.d.ts.map +1 -1
- package/dist/core/agents/state/stale-sweep.js +23 -5
- package/dist/core/artifacts/constants.d.ts +5 -0
- package/dist/core/artifacts/constants.d.ts.map +1 -0
- package/dist/core/artifacts/constants.js +4 -0
- package/dist/core/artifacts/index.d.ts +3 -3
- package/dist/core/artifacts/index.d.ts.map +1 -1
- package/dist/core/artifacts/index.js +50 -7
- package/dist/core/events/v3/base-contract.d.ts +795 -0
- package/dist/core/events/v3/base-contract.d.ts.map +1 -1
- package/dist/core/events/v3/base-contract.js +33 -0
- package/dist/core/events/v3/capabilities.d.ts +11 -0
- package/dist/core/events/v3/capabilities.d.ts.map +1 -1
- package/dist/core/events/v3/capabilities.js +23 -0
- package/dist/core/events/v3/generated.d.ts +1 -1
- package/dist/core/events/v3/generated.js +1 -1
- package/dist/core/events/v3/index.d.ts +4 -3
- package/dist/core/events/v3/index.d.ts.map +1 -1
- package/dist/core/events/v3/index.js +4 -3
- package/dist/core/events/v3/latency.d.ts +31 -1
- package/dist/core/events/v3/latency.d.ts.map +1 -1
- package/dist/core/events/v3/latency.js +127 -3
- package/dist/core/events/v3/live-routing.d.ts +30 -0
- package/dist/core/events/v3/live-routing.d.ts.map +1 -1
- package/dist/core/events/v3/live-routing.js +109 -1
- package/dist/core/events/v3/producers/command-recorder.d.ts.map +1 -1
- package/dist/core/events/v3/producers/command-recorder.js +10 -1
- package/dist/core/events/v3/producers/coordination-recorder.d.ts.map +1 -1
- package/dist/core/events/v3/producers/coordination-recorder.js +14 -3
- package/dist/core/events/v3/producers/hook-base.d.ts +17 -1
- package/dist/core/events/v3/producers/hook-base.d.ts.map +1 -1
- package/dist/core/events/v3/producers/hook-base.js +82 -1
- package/dist/core/events/v3/producers/intake.d.ts +6 -0
- package/dist/core/events/v3/producers/intake.d.ts.map +1 -1
- package/dist/core/events/v3/producers/intake.js +11 -0
- package/dist/core/events/v3/producers/recorder.d.ts +62 -0
- package/dist/core/events/v3/producers/recorder.d.ts.map +1 -1
- package/dist/core/events/v3/producers/recorder.js +654 -18
- package/dist/core/events/v3/runtime-telemetry-capabilities.d.ts +51 -0
- package/dist/core/events/v3/runtime-telemetry-capabilities.d.ts.map +1 -0
- package/dist/core/events/v3/runtime-telemetry-capabilities.js +54 -0
- package/dist/core/events/v3/turn-telemetry.d.ts +9 -0
- package/dist/core/events/v3/turn-telemetry.d.ts.map +1 -1
- package/dist/core/hooks/adapter/parse.d.ts +3 -0
- package/dist/core/hooks/adapter/parse.d.ts.map +1 -1
- package/dist/core/hooks/adapter/parse.js +14 -0
- package/dist/core/hooks/adapter/runtime-telemetry.d.ts +119 -0
- package/dist/core/hooks/adapter/runtime-telemetry.d.ts.map +1 -0
- package/dist/core/hooks/adapter/runtime-telemetry.js +568 -0
- package/dist/core/hooks/cli.js +111 -36
- package/dist/core/hooks/remediation-cap.d.ts +34 -0
- package/dist/core/hooks/remediation-cap.d.ts.map +1 -0
- package/dist/core/hooks/remediation-cap.js +71 -0
- package/dist/core/hooks/resolve/transcript.d.ts +25 -9
- package/dist/core/hooks/resolve/transcript.d.ts.map +1 -1
- package/dist/core/hooks/resolve/transcript.js +22 -10
- package/dist/core/semantic/adapters.d.ts +34 -0
- package/dist/core/semantic/adapters.d.ts.map +1 -0
- package/dist/core/semantic/adapters.js +222 -0
- package/dist/core/semantic/contract.d.ts +588 -0
- package/dist/core/semantic/contract.d.ts.map +1 -0
- package/dist/core/semantic/contract.js +230 -0
- package/dist/core/semantic/evidence.d.ts +11 -0
- package/dist/core/semantic/evidence.d.ts.map +1 -0
- package/dist/core/semantic/evidence.js +262 -0
- package/dist/core/semantic/index.d.ts +10 -0
- package/dist/core/semantic/index.d.ts.map +1 -0
- package/dist/core/semantic/index.js +9 -0
- package/dist/core/semantic/once.d.ts +33 -0
- package/dist/core/semantic/once.d.ts.map +1 -0
- package/dist/core/semantic/once.js +293 -0
- package/dist/core/semantic/prompt.d.ts +12 -0
- package/dist/core/semantic/prompt.d.ts.map +1 -0
- package/dist/core/semantic/prompt.js +70 -0
- package/dist/core/semantic/scheduler.d.ts +16 -0
- package/dist/core/semantic/scheduler.d.ts.map +1 -0
- package/dist/core/semantic/scheduler.js +67 -0
- package/dist/core/semantic/service-status.d.ts +31 -0
- package/dist/core/semantic/service-status.d.ts.map +1 -0
- package/dist/core/semantic/service-status.js +84 -0
- package/dist/core/semantic/service.d.ts +51 -0
- package/dist/core/semantic/service.d.ts.map +1 -0
- package/dist/core/semantic/service.js +470 -0
- package/dist/core/semantic/storage.d.ts +71 -0
- package/dist/core/semantic/storage.d.ts.map +1 -0
- package/dist/core/semantic/storage.js +179 -0
- package/dist/core/semantic/validate.d.ts +16 -0
- package/dist/core/semantic/validate.d.ts.map +1 -0
- package/dist/core/semantic/validate.js +174 -0
- package/dist/lib/browser/client.d.ts +11 -0
- package/dist/lib/browser/client.d.ts.map +1 -1
- package/dist/lib/browser/client.js +13 -0
- package/dist/lib/browser/index.d.ts +1 -0
- package/dist/lib/browser/index.d.ts.map +1 -1
- package/dist/lib/browser/standalone-html.d.ts +25 -0
- package/dist/lib/browser/standalone-html.d.ts.map +1 -0
- package/dist/lib/browser/standalone-html.js +284 -0
- package/dist/lib/instructions/apply.d.ts.map +1 -1
- package/dist/lib/instructions/apply.js +1 -0
- package/dist/lib/instructions/templates.d.ts +2 -0
- package/dist/lib/instructions/templates.d.ts.map +1 -1
- package/dist/lib/instructions/templates.js +144 -4
- package/package.json +6 -1
- package/schemas/event-v3.schema.json +2758 -478
- package/src/commander.ts +2 -0
- package/src/commands/agents.ts +102 -167
- package/src/commands/browse.ts +25 -2
- package/src/commands/decision.ts +8 -2
- package/src/commands/events.ts +21 -1
- package/src/commands/presence.ts +7 -2
- package/src/commands/semantic.ts +179 -0
- package/src/commands/web.ts +15 -0
- package/src/core/agents/canonical-emit.ts +15 -0
- package/src/core/agents/claim-path.ts +23 -0
- package/src/core/agents/coord-client.ts +92 -8
- package/src/core/agents/live-authority-v3.ts +1 -4
- package/src/core/agents/live-lifecycle-v3.ts +8 -3
- package/src/core/agents/live-observation-v3.ts +7 -2
- package/src/core/agents/render/prompt-context.ts +13 -10
- package/src/core/agents/rules/stop-hook.ts +24 -11
- package/src/core/agents/session-name-display.ts +9 -1
- package/src/core/agents/state/heartbeat-reader.ts +69 -0
- package/src/core/agents/state/heartbeat-writer.ts +20 -84
- package/src/core/agents/state/live-coordination-view.ts +26 -1
- package/src/core/agents/state/names.ts +190 -182
- package/src/core/agents/state/stale-sweep.ts +25 -5
- package/src/core/artifacts/constants.ts +4 -0
- package/src/core/artifacts/index.ts +49 -7
- package/src/core/events/v3/base-contract.ts +39 -0
- package/src/core/events/v3/capabilities.ts +34 -0
- package/src/core/events/v3/generated.ts +1 -1
- package/src/core/events/v3/index.ts +21 -0
- package/src/core/events/v3/latency.ts +213 -2
- package/src/core/events/v3/live-routing.ts +120 -1
- package/src/core/events/v3/producers/command-recorder.ts +10 -1
- package/src/core/events/v3/producers/coordination-recorder.ts +17 -5
- package/src/core/events/v3/producers/hook-base.ts +115 -1
- package/src/core/events/v3/producers/intake.ts +18 -0
- package/src/core/events/v3/producers/recorder.ts +856 -21
- package/src/core/events/v3/runtime-telemetry-capabilities.ts +137 -0
- package/src/core/events/v3/turn-telemetry.ts +10 -0
- package/src/core/hooks/adapter/parse.ts +16 -0
- package/src/core/hooks/adapter/runtime-telemetry.ts +805 -0
- package/src/core/hooks/cli.ts +123 -39
- package/src/core/hooks/remediation-cap.ts +77 -0
- package/src/core/hooks/resolve/transcript.ts +37 -11
- package/src/core/semantic/adapters.ts +293 -0
- package/src/core/semantic/contract.ts +298 -0
- package/src/core/semantic/evidence.ts +336 -0
- package/src/core/semantic/index.ts +127 -0
- package/src/core/semantic/once.ts +410 -0
- package/src/core/semantic/prompt.ts +84 -0
- package/src/core/semantic/scheduler.ts +107 -0
- package/src/core/semantic/service-status.ts +118 -0
- package/src/core/semantic/service.ts +580 -0
- package/src/core/semantic/storage.ts +286 -0
- package/src/core/semantic/validate.ts +212 -0
- package/src/lib/browser/client.ts +21 -0
- package/src/lib/browser/index.ts +4 -0
- package/src/lib/browser/standalone-html.ts +312 -0
- package/src/lib/instructions/apply.ts +1 -0
- package/src/lib/instructions/templates.ts +149 -4
|
@@ -78,12 +78,14 @@ export function evaluateStopHookV3Events(coordRoot, req, events) {
|
|
|
78
78
|
const taskSet = inTurn.some((event) => event.event_type === "coord.task_changed" && event.payload.subject_instance_id === owner);
|
|
79
79
|
const turnTerminals = inTurn.filter((event) => event.event_type === "turn.completed");
|
|
80
80
|
const latestTerminal = turnTerminals.at(-1);
|
|
81
|
-
const latestBox = observedBoolean(latestTerminal?.payload.ritual?.
|
|
81
|
+
const latestBox = observedBoolean(latestTerminal?.payload.ritual?.status_box_present_strict);
|
|
82
82
|
if (req.adapter !== "cursor" && latestBox === undefined) {
|
|
83
|
-
return evidenceUnavailable("turn.completed has no observed V3 status-box result; Stop remains fail-open");
|
|
83
|
+
return evidenceUnavailable("turn.completed has no observed V3 assistant-text status-box result; Stop remains fail-open");
|
|
84
84
|
}
|
|
85
85
|
const ackPresent = req.adapter === "cursor" ? requiredStatusChecked : latestBox === true;
|
|
86
|
-
const ackBlock = req.adapter === "cursor"
|
|
86
|
+
const ackBlock = req.adapter === "cursor"
|
|
87
|
+
? () => rule13Block(coordRoot, req.session_id)
|
|
88
|
+
: () => rule23Block(coordRoot, req.session_id);
|
|
87
89
|
// Pure prose turns keep the human-visible acknowledgement but do not require
|
|
88
90
|
// task or final-status mutations. This preserves the pre-V3 policy exactly.
|
|
89
91
|
if (!usedTool) {
|
|
@@ -97,11 +99,11 @@ export function evaluateStopHookV3Events(coordRoot, req, events) {
|
|
|
97
99
|
};
|
|
98
100
|
}
|
|
99
101
|
if (!requiredStatusChecked)
|
|
100
|
-
return rule13Block(coordRoot);
|
|
102
|
+
return rule13Block(coordRoot, req.session_id);
|
|
101
103
|
if (!ackPresent)
|
|
102
104
|
return ackBlock();
|
|
103
105
|
if (!taskSet)
|
|
104
|
-
return rule33Block(coordRoot);
|
|
106
|
+
return rule33Block(coordRoot, req.session_id);
|
|
105
107
|
// Claude Code can prove session-name presentation from assistant-only text.
|
|
106
108
|
// Cursor cannot expose that text and Codex returned observe-only above.
|
|
107
109
|
if (req.adapter !== "cursor") {
|
|
@@ -192,7 +194,17 @@ function evidenceUnavailable(reason) {
|
|
|
192
194
|
reason,
|
|
193
195
|
};
|
|
194
196
|
}
|
|
195
|
-
|
|
197
|
+
/**
|
|
198
|
+
* Remediation commands carry `--session-id` when the session id is known: the
|
|
199
|
+
* remediating tool call may not descend from a pid-map-registered anchor
|
|
200
|
+
* (headless children, Cursor shells), and a ppid-walk that resolves to a
|
|
201
|
+
* DIFFERENT owner records evidence this verdict will never see — the block
|
|
202
|
+
* then repeats forever while the agent complies every time.
|
|
203
|
+
*/
|
|
204
|
+
function sessionIdSuffix(sessionId) {
|
|
205
|
+
return sessionId ? ` --session-id ${sessionId}` : "";
|
|
206
|
+
}
|
|
207
|
+
function rule13Block(coordRoot, sessionId) {
|
|
196
208
|
const missingEvidence = agentsRequireGitFinalization(coordRoot)
|
|
197
209
|
? "no end_turn_checked coord.status_observed event found in this turn"
|
|
198
210
|
: "no coord.status_observed event found in this turn";
|
|
@@ -200,15 +212,15 @@ function rule13Block(coordRoot) {
|
|
|
200
212
|
allow: false,
|
|
201
213
|
exit_code: 2,
|
|
202
214
|
rule: "stop-hook.rule_1_3",
|
|
203
|
-
reason: `End-of-turn rule (1/3): ${missingEvidence}; run \`${endOfTurnStatusCommand(coordRoot)}\` as your last tool call.`,
|
|
215
|
+
reason: `End-of-turn rule (1/3): ${missingEvidence}; run \`${endOfTurnStatusCommand(coordRoot)}${sessionIdSuffix(sessionId)}\` as your last tool call.`,
|
|
204
216
|
};
|
|
205
217
|
}
|
|
206
|
-
function rule23Block(coordRoot) {
|
|
218
|
+
function rule23Block(coordRoot, sessionId) {
|
|
207
219
|
return {
|
|
208
220
|
allow: false,
|
|
209
221
|
exit_code: 2,
|
|
210
222
|
rule: "stop-hook.rule_2_3",
|
|
211
|
-
reason: `End-of-turn rule (2/3): turn.completed did not observe the agent-status box in your reply text. Paste the \`${endOfTurnStatusCommand(coordRoot)}\` output verbatim as a fenced code block (the \`┌─ agent-\` prefix is the detection signal).`,
|
|
223
|
+
reason: `End-of-turn rule (2/3): turn.completed did not observe the agent-status box in your reply text. Paste the \`${endOfTurnStatusCommand(coordRoot)}${sessionIdSuffix(sessionId)}\` output verbatim as a fenced code block (the \`┌─ agent-\` prefix is the detection signal).`,
|
|
212
224
|
};
|
|
213
225
|
}
|
|
214
226
|
/**
|
|
@@ -252,11 +264,11 @@ function sessionNameBlock(coordRoot, instanceId) {
|
|
|
252
264
|
reason: `Session-naming rule: V3 observed that the current session name was required but absent. ${instruction}`,
|
|
253
265
|
};
|
|
254
266
|
}
|
|
255
|
-
function rule33Block(coordRoot) {
|
|
267
|
+
function rule33Block(coordRoot, sessionId) {
|
|
256
268
|
return {
|
|
257
269
|
allow: false,
|
|
258
270
|
exit_code: 2,
|
|
259
271
|
rule: "stop-hook.rule_3_3",
|
|
260
|
-
reason: `End-of-turn rule (3/3): no coord.task_changed event found in this turn; run \`${resolveBinName(coordRoot)} agents set-task "<short focus>"\` to declare what you're working on. Pass an empty string if the turn was purely conversational.`,
|
|
272
|
+
reason: `End-of-turn rule (3/3): no coord.task_changed event found in this turn; run \`${resolveBinName(coordRoot)} agents set-task${sessionIdSuffix(sessionId)} "<short focus>"\` to declare what you're working on. Pass an empty string if the turn was purely conversational.`,
|
|
261
273
|
};
|
|
262
274
|
}
|
|
@@ -12,6 +12,7 @@ export declare const SESSION_NAME_DISPLAY_NOTE = "Next, before any prose or anot
|
|
|
12
12
|
export declare function sessionNameDisplayPending(row: SessionNameDisplayState | null | undefined): string | null;
|
|
13
13
|
export declare function sessionNameDisplayBlock(name: string): string;
|
|
14
14
|
export declare function sessionNameDisplayInstruction(name: string): string;
|
|
15
|
+
export declare function sessionNameDisplayRecoveryInstruction(name: string, binName: string): string;
|
|
15
16
|
/**
|
|
16
17
|
* A PostToolUse result should announce the display protocol only when that
|
|
17
18
|
* exact tool call minted or retried the current suggestion. The coordination row keeps
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-name-display.d.ts","sourceRoot":"","sources":["../../../src/core/agents/session-name-display.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,uBAAuB;IACtC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,eAAO,MAAM,yBAAyB,wHACiF,CAAC;AAExH,wBAAgB,yBAAyB,CACvC,GAAG,EAAE,uBAAuB,GAAG,IAAI,GAAG,SAAS,GAC9C,MAAM,GAAG,IAAI,CAIf;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CASlE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,6BAA6B,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAGtF;AAgDD;;;;GAIG;AACH,wBAAgB,uCAAuC,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAK3F;AAUD;;;;GAIG;AACH,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,OAAO,EAAE,MAAM,GACd,OAAO,CAmBT"}
|
|
1
|
+
{"version":3,"file":"session-name-display.d.ts","sourceRoot":"","sources":["../../../src/core/agents/session-name-display.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,uBAAuB;IACtC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,eAAO,MAAM,yBAAyB,wHACiF,CAAC;AAExH,wBAAgB,yBAAyB,CACvC,GAAG,EAAE,uBAAuB,GAAG,IAAI,GAAG,SAAS,GAC9C,MAAM,GAAG,IAAI,CAIf;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CASlE;AAED,wBAAgB,qCAAqC,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAM3F;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,6BAA6B,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAGtF;AAgDD;;;;GAIG;AACH,wBAAgB,uCAAuC,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAK3F;AAUD;;;;GAIG;AACH,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,OAAO,EAAE,MAAM,GACd,OAAO,CAmBT"}
|
|
@@ -24,6 +24,13 @@ export function sessionNameDisplayInstruction(name) {
|
|
|
24
24
|
"Do not put commentary before the block. Harnery will reject tool calls until it is shown.",
|
|
25
25
|
].join("\n");
|
|
26
26
|
}
|
|
27
|
+
export function sessionNameDisplayRecoveryInstruction(name, binName) {
|
|
28
|
+
return [
|
|
29
|
+
sessionNameDisplayInstruction(name),
|
|
30
|
+
"",
|
|
31
|
+
`If that exact block was already shown but the gate still rejects tools, run \`${binName} agents suggest-name --json\` as the only tool call. That read-only command is exempt and creates a fresh verification boundary.`,
|
|
32
|
+
].join("\n");
|
|
33
|
+
}
|
|
27
34
|
/**
|
|
28
35
|
* A PostToolUse result should announce the display protocol only when that
|
|
29
36
|
* exact tool call minted or retried the current suggestion. The coordination row keeps
|
|
@@ -114,6 +121,6 @@ export function isSessionNameRemediationCommand(command, binName) {
|
|
|
114
121
|
if (!body || /[\n;&|<>`$]/.test(body))
|
|
115
122
|
return false;
|
|
116
123
|
const escapedBin = binName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
117
|
-
const pattern = new RegExp(`^(?:codex-wsl\\s+--\\s+)?${escapedBin}\\s+agents\\s+(?:set-task|status)(?:\\s+.*)?$`);
|
|
124
|
+
const pattern = new RegExp(`^(?:codex-wsl\\s+--\\s+)?${escapedBin}\\s+agents\\s+(?:set-task|status|suggest-name)(?:\\s+.*)?$`);
|
|
118
125
|
return pattern.test(body);
|
|
119
126
|
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/** Read-only access to the generation-bound heartbeat cache. */
|
|
2
|
+
import type { AgentActivity, TaskState } from "./session-state.js";
|
|
3
|
+
export interface Heartbeat {
|
|
4
|
+
schema_version?: number;
|
|
5
|
+
instance_id: string;
|
|
6
|
+
name?: string;
|
|
7
|
+
kind?: string;
|
|
8
|
+
agent_id?: string;
|
|
9
|
+
session_id: string;
|
|
10
|
+
/** Native adapter session ID retained only in a generation-bound local projection. */
|
|
11
|
+
native_session_id?: string;
|
|
12
|
+
subagent_call_id?: string;
|
|
13
|
+
model?: string;
|
|
14
|
+
platform?: string;
|
|
15
|
+
started_at?: string;
|
|
16
|
+
last_heartbeat: string;
|
|
17
|
+
files_touched: string[];
|
|
18
|
+
task?: string;
|
|
19
|
+
task_updated_at?: string | null;
|
|
20
|
+
activity?: AgentActivity;
|
|
21
|
+
activity_updated_at?: string;
|
|
22
|
+
activity_source?: string;
|
|
23
|
+
task_state?: TaskState;
|
|
24
|
+
task_state_updated_at?: string;
|
|
25
|
+
task_state_reason?: string;
|
|
26
|
+
/** Session name built on the first non-empty set-task (never rebuilt). */
|
|
27
|
+
suggested_session_name?: string;
|
|
28
|
+
/** Stamped once the suggested name is seen in assistant reply text. */
|
|
29
|
+
session_name_seen_at?: string;
|
|
30
|
+
/** The specific suggested name proven present by the sighting stamp. */
|
|
31
|
+
session_name_seen_for?: string;
|
|
32
|
+
last_status_at?: string;
|
|
33
|
+
current_turn_id?: string;
|
|
34
|
+
parent_instance_id?: string;
|
|
35
|
+
workflow_run_id?: string;
|
|
36
|
+
workflow_agent_id?: string;
|
|
37
|
+
/** Disposable-cache bindings that prove a row belongs to the current V3 generation. */
|
|
38
|
+
v3_instance_id?: `inst_${string}`;
|
|
39
|
+
v3_generation_id?: `gen_${string}`;
|
|
40
|
+
v3_projection_event_id?: string;
|
|
41
|
+
v3_task_state?: "set" | "cleared";
|
|
42
|
+
[extra: string]: unknown;
|
|
43
|
+
}
|
|
44
|
+
export declare function heartbeatPath(coordRoot: string, instanceId: string): string;
|
|
45
|
+
export declare function readHeartbeat(coordRoot: string, instanceId: string): Heartbeat | null;
|
|
46
|
+
//# sourceMappingURL=heartbeat-reader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heartbeat-reader.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/state/heartbeat-reader.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAIhE,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAEnE,MAAM,WAAW,SAAS;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,sFAAsF;IACtF,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,0EAA0E;IAC1E,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,uEAAuE;IACvE,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,wEAAwE;IACxE,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,uFAAuF;IACvF,cAAc,CAAC,EAAE,QAAQ,MAAM,EAAE,CAAC;IAClC,gBAAgB,CAAC,EAAE,OAAO,MAAM,EAAE,CAAC;IACnC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,aAAa,CAAC,EAAE,KAAK,GAAG,SAAS,CAAC;IAClC,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAED,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAU3E;AAED,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAQrF"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/** Read-only access to the generation-bound heartbeat cache. */
|
|
2
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
3
|
+
import { dirname, resolve, sep } from "node:path";
|
|
4
|
+
export function heartbeatPath(coordRoot, instanceId) {
|
|
5
|
+
if (!/^[A-Za-z0-9_-]{1,128}$/.test(instanceId)) {
|
|
6
|
+
throw new Error("instance_id must be 1-128 ASCII letters, digits, hyphens, or underscores");
|
|
7
|
+
}
|
|
8
|
+
const root = resolve(coordRoot, ".harnery", "active");
|
|
9
|
+
const candidate = resolve(root, `${instanceId}.json`);
|
|
10
|
+
if (!candidate.startsWith(`${root}${sep}`) || dirname(candidate) !== root) {
|
|
11
|
+
throw new Error("coordination filename must resolve directly beneath its root");
|
|
12
|
+
}
|
|
13
|
+
return candidate;
|
|
14
|
+
}
|
|
15
|
+
export function readHeartbeat(coordRoot, instanceId) {
|
|
16
|
+
const path = heartbeatPath(coordRoot, instanceId);
|
|
17
|
+
if (!existsSync(path))
|
|
18
|
+
return null;
|
|
19
|
+
try {
|
|
20
|
+
return JSON.parse(readFileSync(path, "utf8"));
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -13,54 +13,9 @@
|
|
|
13
13
|
* `.harnery/active/<instance_id>.json`; the canonical V3 ledger remains authoritative.
|
|
14
14
|
* (the file IS the heartbeat). No mutations happen elsewhere.
|
|
15
15
|
*/
|
|
16
|
-
import
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
instance_id: string;
|
|
20
|
-
name?: string;
|
|
21
|
-
kind?: string;
|
|
22
|
-
agent_id?: string;
|
|
23
|
-
session_id: string;
|
|
24
|
-
/** Native adapter session ID retained only in a generation-bound local projection. */
|
|
25
|
-
native_session_id?: string;
|
|
26
|
-
subagent_call_id?: string;
|
|
27
|
-
model?: string;
|
|
28
|
-
platform?: string;
|
|
29
|
-
started_at?: string;
|
|
30
|
-
last_heartbeat: string;
|
|
31
|
-
files_touched: string[];
|
|
32
|
-
task?: string;
|
|
33
|
-
task_updated_at?: string | null;
|
|
34
|
-
activity?: AgentActivity;
|
|
35
|
-
activity_updated_at?: string;
|
|
36
|
-
activity_source?: string;
|
|
37
|
-
task_state?: TaskState;
|
|
38
|
-
task_state_updated_at?: string;
|
|
39
|
-
task_state_reason?: string;
|
|
40
|
-
/** Session name built on the first non-empty set-task (never rebuilt). Its
|
|
41
|
-
* presence is the "this session has been named" signal the prompt-context
|
|
42
|
-
* nudge and the Stop-hook naming rule key on. */
|
|
43
|
-
suggested_session_name?: string;
|
|
44
|
-
/** Stamped by turn.completed once the suggested name is seen in assistant reply
|
|
45
|
-
* text, ending the per-turn transcript scan. */
|
|
46
|
-
session_name_seen_at?: string;
|
|
47
|
-
/** WHICH name that sighting was for. The scan is skipped only while this
|
|
48
|
-
* matches the current suggested name, so a re-minted name is detectable
|
|
49
|
-
* again rather than being suppressed by the earlier sighting. */
|
|
50
|
-
session_name_seen_for?: string;
|
|
51
|
-
last_status_at?: string;
|
|
52
|
-
current_turn_id?: string;
|
|
53
|
-
parent_instance_id?: string;
|
|
54
|
-
workflow_run_id?: string;
|
|
55
|
-
workflow_agent_id?: string;
|
|
56
|
-
/** Disposable-cache bindings that prove a row belongs to the current V3 generation. */
|
|
57
|
-
v3_instance_id?: `inst_${string}`;
|
|
58
|
-
v3_generation_id?: `gen_${string}`;
|
|
59
|
-
v3_projection_event_id?: string;
|
|
60
|
-
v3_task_state?: "set" | "cleared";
|
|
61
|
-
[extra: string]: unknown;
|
|
62
|
-
}
|
|
63
|
-
export declare function readHeartbeat(coordRoot: string, instanceId: string): Heartbeat | null;
|
|
16
|
+
import { type Heartbeat } from "./heartbeat-reader.js";
|
|
17
|
+
import type { TaskState } from "./session-state.js";
|
|
18
|
+
export { type Heartbeat, readHeartbeat } from "./heartbeat-reader.js";
|
|
64
19
|
/** Persist operator-facing lifecycle prose in the generation-bound cache only. */
|
|
65
20
|
export declare function setLifecycleCache(coordRoot: string, instanceId: string, state: TaskState, reason?: string, suggestedSessionName?: string): Heartbeat | null;
|
|
66
21
|
export declare function setTask(coordRoot: string, instanceId: string, task: string): Heartbeat | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"heartbeat-writer.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/state/heartbeat-writer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAaH,OAAO,
|
|
1
|
+
{"version":3,"file":"heartbeat-writer.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/state/heartbeat-writer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAaH,OAAO,EAAE,KAAK,SAAS,EAAgC,MAAM,uBAAuB,CAAC;AACrF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAEpD,OAAO,EAAE,KAAK,SAAS,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAatE,kFAAkF;AAClF,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,SAAS,EAChB,MAAM,CAAC,EAAE,MAAM,EACf,oBAAoB,CAAC,EAAE,MAAM,GAC5B,SAAS,GAAG,IAAI,CAQlB;AAeD,wBAAgB,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAoB7F;AAED,6EAA6E;AAC7E,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,GACd,SAAS,GAAG,IAAI,CAOlB;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,MAAM,EAAE,GACzB;IAAE,aAAa,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAKvD;AAED,2EAA2E;AAC3E,wBAAgB,2BAA2B,CACzC,kBAAkB,EAAE,MAAM,GAAG,SAAS,EACtC,KAAK,EAAE,SAAS,GACf,MAAM,GAAG,IAAI,CAOf;AAED;;;;4EAI4E;AAC5E,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,IAAI,CAAC,EAAE,MAAM,GACZ,SAAS,GAAG,IAAI,CAMlB;AAED,wBAAgB,YAAY,CAC1B,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,GACX,SAAS,GAAG,IAAI,CAQlB;AAED,oFAAoF;AACpF,wBAAgB,YAAY,CAC1B,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,GACX,SAAS,GAAG,IAAI,CAWlB;AAED,uEAAuE;AACvE,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,eAAe,CAC7B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,GACX,eAAe,EAAE,CA6BnB;AAED,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CASrF;AAED,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAiBnF"}
|
|
@@ -14,16 +14,10 @@
|
|
|
14
14
|
* (the file IS the heartbeat). No mutations happen elsewhere.
|
|
15
15
|
*/
|
|
16
16
|
import { existsSync, mkdirSync, readdirSync, readFileSync, renameSync, unlinkSync, writeFileSync, } from "node:fs";
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
const safeInstanceId = basename(instanceId);
|
|
22
|
-
if (safeInstanceId !== instanceId) {
|
|
23
|
-
throw new Error("instance_id must be a direct-child coordination basename");
|
|
24
|
-
}
|
|
25
|
-
return resolveContainedFile(join(coordRoot, ".harnery", "active"), `${safeInstanceId}.json`);
|
|
26
|
-
}
|
|
17
|
+
import { dirname, join } from "node:path";
|
|
18
|
+
import { canonicalClaimPath } from "../claim-path.js";
|
|
19
|
+
import { heartbeatPath, readHeartbeat } from "./heartbeat-reader.js";
|
|
20
|
+
export { readHeartbeat } from "./heartbeat-reader.js";
|
|
27
21
|
function nowIsoSeconds() {
|
|
28
22
|
return new Date().toISOString().replace(/\.\d{3}Z$/, "Z");
|
|
29
23
|
}
|
|
@@ -33,17 +27,6 @@ function atomicWrite(path, content) {
|
|
|
33
27
|
writeFileSync(tmp, content, "utf8");
|
|
34
28
|
renameSync(tmp, path);
|
|
35
29
|
}
|
|
36
|
-
export function readHeartbeat(coordRoot, instanceId) {
|
|
37
|
-
const path = heartbeatPath(coordRoot, instanceId);
|
|
38
|
-
if (!existsSync(path))
|
|
39
|
-
return null;
|
|
40
|
-
try {
|
|
41
|
-
return JSON.parse(readFileSync(path, "utf8"));
|
|
42
|
-
}
|
|
43
|
-
catch {
|
|
44
|
-
return null;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
30
|
/** Persist operator-facing lifecycle prose in the generation-bound cache only. */
|
|
48
31
|
export function setLifecycleCache(coordRoot, instanceId, state, reason, suggestedSessionName) {
|
|
49
32
|
return mutate(coordRoot, instanceId, (heartbeat) => ({
|
|
@@ -128,24 +111,23 @@ export function stampSessionNameSeen(coordRoot, instanceId, name) {
|
|
|
128
111
|
}));
|
|
129
112
|
}
|
|
130
113
|
export function releaseClaim(coordRoot, instanceId, path) {
|
|
131
|
-
|
|
132
|
-
// monorepo-relative entries; normalize both sides so release matches
|
|
133
|
-
// regardless of the form the caller passes (the old exact-string filter
|
|
134
|
-
// silently no-op'd on a form mismatch).
|
|
135
|
-
const norm = (p) => p.startsWith(`${coordRoot}/`) ? p.slice(coordRoot.length + 1) : p;
|
|
136
|
-
const target = norm(path);
|
|
114
|
+
const target = canonicalClaimPath(coordRoot, path);
|
|
137
115
|
return mutate(coordRoot, instanceId, (hb) => ({
|
|
138
116
|
...hb,
|
|
139
|
-
files_touched: (hb.files_touched ?? []).filter((
|
|
117
|
+
files_touched: (hb.files_touched ?? []).filter((candidate) => canonicalClaimPath(coordRoot, candidate) !== target),
|
|
140
118
|
}));
|
|
141
119
|
}
|
|
142
120
|
/** Materialize one V3 write-claim authority transition into the heartbeat cache. */
|
|
143
121
|
export function acquireClaim(coordRoot, instanceId, path) {
|
|
144
|
-
const
|
|
145
|
-
const target = norm(path);
|
|
122
|
+
const target = canonicalClaimPath(coordRoot, path);
|
|
146
123
|
return mutate(coordRoot, instanceId, (hb) => ({
|
|
147
124
|
...hb,
|
|
148
|
-
files_touched: [
|
|
125
|
+
files_touched: [
|
|
126
|
+
...new Set([
|
|
127
|
+
...(hb.files_touched ?? []).map((candidate) => canonicalClaimPath(coordRoot, candidate)),
|
|
128
|
+
target,
|
|
129
|
+
]),
|
|
130
|
+
].sort(),
|
|
149
131
|
}));
|
|
150
132
|
}
|
|
151
133
|
/**
|
|
@@ -172,8 +154,7 @@ export function findGroupClaims(coordRoot, groupId, path) {
|
|
|
172
154
|
const activeDir = join(coordRoot, ".harnery", "active");
|
|
173
155
|
if (!existsSync(activeDir))
|
|
174
156
|
return hits;
|
|
175
|
-
const
|
|
176
|
-
const target = norm(path);
|
|
157
|
+
const target = canonicalClaimPath(coordRoot, path);
|
|
177
158
|
for (const f of readdirSync(activeDir)) {
|
|
178
159
|
if (!f.endsWith(".json"))
|
|
179
160
|
continue;
|
|
@@ -189,8 +170,9 @@ export function findGroupClaims(coordRoot, groupId, path) {
|
|
|
189
170
|
if (peerSession !== groupId)
|
|
190
171
|
continue;
|
|
191
172
|
const files = body.files_touched ?? [];
|
|
192
|
-
if (!files.some((candidate) =>
|
|
173
|
+
if (!files.some((candidate) => canonicalClaimPath(coordRoot, candidate) === target)) {
|
|
193
174
|
continue;
|
|
175
|
+
}
|
|
194
176
|
hits.push({
|
|
195
177
|
instance_id: body.instance_id ?? f.replace(/\.json$/, ""),
|
|
196
178
|
session_id: body.session_id,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Adapter } from "../../adapter.js";
|
|
2
|
-
import { type Heartbeat } from "./heartbeat-
|
|
2
|
+
import { type Heartbeat } from "./heartbeat-reader.js";
|
|
3
3
|
/**
|
|
4
4
|
* Heartbeat files are disposable V3 caches. These bindings prevent a stale
|
|
5
5
|
* row from a prior generation from being mistaken for current authority.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"live-coordination-view.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/state/live-coordination-view.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAYhD,OAAO,EAAE,KAAK,SAAS,EAAiB,MAAM,uBAAuB,CAAC;AAGtE;;;GAGG;AACH,MAAM,WAAW,0BAA2B,SAAQ,SAAS;IAC3D,cAAc,EAAE,CAAC,CAAC;IAClB,cAAc,EAAE,QAAQ,MAAM,EAAE,CAAC;IACjC,gBAAgB,EAAE,OAAO,MAAM,EAAE,CAAC;IAClC,sBAAsB,EAAE,MAAM,CAAC;IAC/B,aAAa,EAAE,KAAK,GAAG,SAAS,CAAC;CAClC;AAED,yEAAyE;AACzE,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,0BAA0B,EAAE,CA2BxF;AAED,kEAAkE;AAClE,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,MAAM,GACvB,0BAA0B,GAAG,IAAI,CAuBnC;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,MAAM,GACvB,OAAO,GAAG,IAAI,CAWhB;AAED;;;;;GAKG;AACH,wBAAgB,+BAA+B,CAC7C,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,MAAM,EACxB,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,OAAO,EACjB,KAAK,CAAC,EAAE,MAAM,GACb,SAAS,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"live-coordination-view.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/state/live-coordination-view.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAYhD,OAAO,EAAE,KAAK,SAAS,EAAiB,MAAM,uBAAuB,CAAC;AAGtE;;;GAGG;AACH,MAAM,WAAW,0BAA2B,SAAQ,SAAS;IAC3D,cAAc,EAAE,CAAC,CAAC;IAClB,cAAc,EAAE,QAAQ,MAAM,EAAE,CAAC;IACjC,gBAAgB,EAAE,OAAO,MAAM,EAAE,CAAC;IAClC,sBAAsB,EAAE,MAAM,CAAC;IAC/B,aAAa,EAAE,KAAK,GAAG,SAAS,CAAC;CAClC;AAED,yEAAyE;AACzE,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,0BAA0B,EAAE,CA2BxF;AAED,kEAAkE;AAClE,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,MAAM,GACvB,0BAA0B,GAAG,IAAI,CAuBnC;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,MAAM,GACvB,OAAO,GAAG,IAAI,CAWhB;AAED;;;;;GAKG;AACH,wBAAgB,+BAA+B,CAC7C,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,MAAM,EACxB,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,OAAO,EACjB,KAAK,CAAC,EAAE,MAAM,GACb,SAAS,GAAG,IAAI,CAyDlB"}
|
|
@@ -2,7 +2,7 @@ import { existsSync, mkdirSync, readdirSync, readFileSync, renameSync, writeFile
|
|
|
2
2
|
import { dirname, join } from "node:path";
|
|
3
3
|
import { readCoordinationViewV3, requireAuthoritySafeCoordinationViewV3, } from "../../events/v3/coordination-view.js";
|
|
4
4
|
import { liveInstanceIdV3, nativeInstanceIdV3, resolveLiveEventLedgerRouteV3, } from "../../events/v3/live-routing.js";
|
|
5
|
-
import { readHeartbeat } from "./heartbeat-
|
|
5
|
+
import { readHeartbeat } from "./heartbeat-reader.js";
|
|
6
6
|
import { resolveName } from "./names.js";
|
|
7
7
|
/** Read the live coordination rows through the hard-cut ledger route. */
|
|
8
8
|
export function readLiveCoordinationRows(coordRoot) {
|
|
@@ -89,8 +89,32 @@ export function ensureLiveCoordinationHeartbeat(coordRoot, nativeInstanceId, nat
|
|
|
89
89
|
return current;
|
|
90
90
|
const resolved = resolveName(coordRoot, nativeInstanceId, nativeSessionId);
|
|
91
91
|
const projected = projectHeartbeatV3(coordRoot, generation, undefined, nativeInstanceId);
|
|
92
|
+
// A generation reopen (resume, mid-flight onboarding) discards the stale
|
|
93
|
+
// cache, but the adapter tab it names is unchanged: same native session,
|
|
94
|
+
// same agent identity. Rebuilding without the naming evidence re-mints a
|
|
95
|
+
// fresh suggested name on the next set-task, so a multi-day session
|
|
96
|
+
// accumulates titles it is asked to display over and over. Carry the
|
|
97
|
+
// naming evidence across generations; everything else re-projects from V3.
|
|
98
|
+
// Same native session id means the same adapter tab; drop the carry only
|
|
99
|
+
// when the durable identity observably changed (a reassumed name would make
|
|
100
|
+
// the old "Agent <name> - …" block wrong for the new owner).
|
|
101
|
+
const identityUnchanged = !resolved?.name || !current?.name || resolved.name === current.name;
|
|
102
|
+
const carriedNaming = current && current.session_id === nativeSessionId && identityUnchanged
|
|
103
|
+
? {
|
|
104
|
+
...(current.suggested_session_name
|
|
105
|
+
? { suggested_session_name: current.suggested_session_name }
|
|
106
|
+
: {}),
|
|
107
|
+
...(current.session_name_seen_for
|
|
108
|
+
? { session_name_seen_for: current.session_name_seen_for }
|
|
109
|
+
: {}),
|
|
110
|
+
...(current.session_name_seen_at
|
|
111
|
+
? { session_name_seen_at: current.session_name_seen_at }
|
|
112
|
+
: {}),
|
|
113
|
+
}
|
|
114
|
+
: {};
|
|
92
115
|
const materialized = {
|
|
93
116
|
...projected,
|
|
117
|
+
...carriedNaming,
|
|
94
118
|
schema_version: 2,
|
|
95
119
|
instance_id: nativeInstanceId,
|
|
96
120
|
session_id: nativeSessionId,
|
|
@@ -5,6 +5,14 @@
|
|
|
5
5
|
* Layout invariant: 260 entries (10 per starting letter A..Z). Counter N
|
|
6
6
|
* picks COORD_NAMES[N % 260]; wraps to A at N=260.
|
|
7
7
|
*
|
|
8
|
+
* Gender invariant: within each 26-name pass the names alternate female/male
|
|
9
|
+
* letter by letter, so every pass is 13 female and 13 male. Five passes start
|
|
10
|
+
* female at A (1, 3, 5, 7, 9) and five start male (2, 4, 6, 8, 10), which gives
|
|
11
|
+
* each letter exactly five names of each gender and the pool 130/130 overall.
|
|
12
|
+
* This exists so a fixed set of 13 female and 13 male portraits can dress one
|
|
13
|
+
* whole pass. Adding or reordering a name must preserve it; the expected
|
|
14
|
+
* pattern is pinned in tests/unit/names-pool.test.ts.
|
|
15
|
+
*
|
|
8
16
|
* Durable persistence: `.harnery/.name-history` (JSONL, one row per assignment)
|
|
9
17
|
* + `.harnery/.name-counter` (current counter, atomic temp+rename).
|
|
10
18
|
*
|
|
@@ -19,7 +27,7 @@
|
|
|
19
27
|
* 3. Else: new assignment, consume a counter slot.
|
|
20
28
|
*/
|
|
21
29
|
/** All 260 names. */
|
|
22
|
-
export declare const COORD_NAMES: readonly ["Anna", "Bob", "
|
|
30
|
+
export declare const COORD_NAMES: readonly ["Anna", "Bob", "Carmen", "Dorian", "Erika", "Fred", "Gemma", "Hank", "Imelda", "Jerry", "Karen", "Lorenzo", "Mindy", "Nate", "Odette", "Peter", "Quinn", "Rafael", "Sara", "Tony", "Ursula", "Vinson", "Whitney", "Xander", "Yara", "Zane", "Alex", "Bertha", "Carlos", "Dalia", "Ernesto", "Francine", "Gordon", "Helene", "Isaias", "Joyce", "Kirk", "Lucia", "Milton", "Nadine", "Oscar", "Patty", "Quentin", "Rebekah", "Sean", "Tammy", "Ulrik", "Valerie", "Wallace", "Xanthe", "Yusuf", "Zara", "Adelaide", "Bruno", "Cora", "Damon", "Edna", "Felix", "Greta", "Hugo", "Ines", "Jasper", "Kaia", "Larry", "Maxine", "Nicholas", "Olive", "Paxton", "Querida", "Roman", "Stella", "Tobias", "Una", "Virgil", "Willow", "Xavier", "Yolanda", "Zephyr", "Aaron", "Beatrice", "Cyrus", "Delia", "Elias", "Florence", "Galileo", "Hester", "Ian", "Jenna", "Klaus", "Linda", "Marco", "Nora", "Otto", "Paulette", "Quill", "Renee", "Sebastian", "Theresa", "Umberto", "Vera", "Walter", "Xena", "Yves", "Zoe", "Anita", "Beau", "Celeste", "Dexter", "Edith", "Fitz", "Gloria", "Hadley", "Iris", "Jude", "Kira", "Leo", "Maya", "Nash", "Olga", "Phillip", "Quetzal", "Royce", "Sage", "Trent", "Uma", "Vincent", "Wynne", "Xerxes", "Yvette", "Zoltan", "Andre", "Bonnie", "Caleb", "Daphne", "Ezra", "Fiona", "Gibson", "Holly", "Ivan", "Juno", "Knox", "Lila", "Mason", "Nila", "Owen", "Petra", "Quincy", "Rosa", "Sterling", "Talia", "Uri", "Violet", "Wesley", "Ximena", "Yuri", "Zelda", "Astrid", "Boris", "Cassidy", "Davis", "Esme", "Forrest", "Genevieve", "Henry", "Imogen", "Joaquin", "Kestrel", "Luther", "Margot", "Nigel", "Ophelia", "Percy", "Quenby", "Reagan", "Sienna", "Truman", "Undine", "Voss", "Wren", "Xan", "Yael", "Zia", "Arthur", "Bianca", "Cody", "Dahlia", "Evander", "Fern", "Gustavo", "Harriet", "Ira", "Josephine", "Kendrick", "Lainey", "Miles", "Naomi", "Orion", "Pearl", "Quark", "Rylie", "Saul", "Tessa", "Ulysses", "Vesper", "Wyatt", "Xiomara", "Yancy", "Zinnia", "Amelia", "Barnaby", "Calliope", "Drake", "Estelle", "Foster", "Greer", "Hollis", "Irene", "Jericho", "Klara", "Logan", "Mavis", "Nico", "Oakley", "Pascal", "Quito", "Rhett", "Scout", "Theron", "Unity", "Vance", "Winifred", "Xola", "Yvonne", "Zev", "Atticus", "Brenda", "Crispin", "Dolores", "Eustace", "Felicity", "Granger", "Hazel", "Idris", "Jovi", "Kasper", "Lyric", "Magnus", "Noor", "Otis", "Phoebe", "Querubin", "Rosalind", "Silas", "Tatum", "Upton", "Vivian", "Wendell", "Xuxa", "Yann", "Zora"];
|
|
23
31
|
export type NameKind = "session" | "subagent" | "transient";
|
|
24
32
|
export interface NameHistoryRow {
|
|
25
33
|
instance_id: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"names.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/state/names.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"names.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/state/names.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAKH,qBAAqB;AACrB,eAAO,MAAM,WAAW,85EA+Qd,CAAC;AAMX,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,UAAU,GAAG,WAAW,CAAC;AAE5D,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,QAAQ,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,oEAAoE;IACpE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kFAAkF;IAClF,MAAM,CAAC,EAAE,MAAM,GAAG,iBAAiB,CAAC;IACpC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;2DAEuD;IACvD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAsCD;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,SAAS,CAAC,EAAE,MAAM,GACjB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CA4B5D;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,QAAQ,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACrE,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,QAAQ,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;CAC7D;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,QAAoB,GACzB,oBAAoB,CAoBtB;AAED;;;GAGG;AACH,wBAAgB,UAAU,CACxB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,QAAQ,EACd,IAAI,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GAC7B,MAAM,CA0BR;AAED;oEACoE;AACpE,wBAAgB,cAAc,CAC5B,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAAG,IAAI,CAUrD;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,KAAK,CAAC;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,CAYrD"}
|