pi-daddy 0.15.0 → 0.17.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/CHANGELOG.md +119 -0
- package/README.md +46 -12
- package/dist/chain.d.ts +94 -0
- package/dist/chain.d.ts.map +1 -0
- package/dist/chain.js +161 -0
- package/dist/chain.js.map +1 -0
- package/dist/cli.js +0 -0
- package/dist/delegate.d.ts.map +1 -1
- package/dist/delegate.js +6 -2
- package/dist/delegate.js.map +1 -1
- package/dist/executor.d.ts +38 -0
- package/dist/executor.d.ts.map +1 -0
- package/dist/executor.js +93 -0
- package/dist/executor.js.map +1 -0
- package/dist/fanout.d.ts +9 -0
- package/dist/fanout.d.ts.map +1 -1
- package/dist/fanout.js +9 -0
- package/dist/fanout.js.map +1 -1
- package/dist/herdr-cli.d.ts +78 -0
- package/dist/herdr-cli.d.ts.map +1 -0
- package/dist/herdr-cli.js +113 -0
- package/dist/herdr-cli.js.map +1 -0
- package/dist/herdr-name.d.ts +37 -0
- package/dist/herdr-name.d.ts.map +1 -0
- package/dist/herdr-name.js +59 -0
- package/dist/herdr-name.js.map +1 -0
- package/dist/herdr-poll.d.ts +104 -0
- package/dist/herdr-poll.d.ts.map +1 -0
- package/dist/herdr-poll.js +150 -0
- package/dist/herdr-poll.js.map +1 -0
- package/dist/herdr-stage.d.ts +40 -0
- package/dist/herdr-stage.d.ts.map +1 -0
- package/dist/herdr-stage.js +54 -0
- package/dist/herdr-stage.js.map +1 -0
- package/dist/ledger-report.d.ts +18 -0
- package/dist/ledger-report.d.ts.map +1 -1
- package/dist/ledger-report.js +10 -0
- package/dist/ledger-report.js.map +1 -1
- package/dist/ledger.d.ts +31 -0
- package/dist/ledger.d.ts.map +1 -1
- package/dist/ledger.js +2 -0
- package/dist/ledger.js.map +1 -1
- package/dist/pane-reaper.d.ts +66 -4
- package/dist/pane-reaper.d.ts.map +1 -1
- package/dist/pane-reaper.js +131 -9
- package/dist/pane-reaper.js.map +1 -1
- package/dist/progress.d.ts +96 -0
- package/dist/progress.d.ts.map +1 -0
- package/dist/progress.js +167 -0
- package/dist/progress.js.map +1 -0
- package/dist/run-child.d.ts +27 -0
- package/dist/run-child.d.ts.map +1 -1
- package/dist/run-child.js +84 -7
- package/dist/run-child.js.map +1 -1
- package/dist/run-herdr.d.ts +41 -28
- package/dist/run-herdr.d.ts.map +1 -1
- package/dist/run-herdr.js +150 -167
- package/dist/run-herdr.js.map +1 -1
- package/extensions/delegate-chain.ts +357 -0
- package/extensions/delegation.ts +100 -2
- package/extensions/grants-command.ts +26 -1
- package/extensions/grants.ts +85 -163
- package/extensions/run-delegation.ts +130 -13
- package/extensions/session-report.ts +231 -0
- package/extensions/session.ts +63 -11
- package/extensions/tripwire.ts +44 -0
- package/package.json +21 -1
- package/src/chain.ts +174 -0
- package/src/delegate.ts +6 -2
- package/src/executor.ts +122 -0
- package/src/fanout.ts +10 -0
- package/src/herdr-cli.ts +125 -0
- package/src/herdr-name.ts +61 -0
- package/src/herdr-poll.ts +185 -0
- package/src/herdr-stage.ts +55 -0
- package/src/ledger-report.ts +21 -0
- package/src/ledger.ts +33 -0
- package/src/pane-reaper.ts +147 -9
- package/src/progress.ts +206 -0
- package/src/run-child.ts +96 -7
- package/src/run-herdr.ts +170 -174
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Waiting for a herdr agent to settle, and reading what it printed on the way.
|
|
3
|
+
*
|
|
4
|
+
* Split out of `src/run-herdr.ts` when that file hit **404 of the 400-line ceiling** adding ADR-0032's output
|
|
5
|
+
* polling. The seam was named in the plan before it was needed, and it is a real one: this module is about
|
|
6
|
+
* *observing* an agent, `run-herdr.ts` is about *starting and cleaning up after* one. Nothing here creates or
|
|
7
|
+
* destroys anything.
|
|
8
|
+
*
|
|
9
|
+
* The two facts it is built on were measured against real herdr 0.7.5 (`docs/probes/g16-herdr`) and both are
|
|
10
|
+
* counter-intuitive enough to be worth the module comment: `agent wait --until idle` matches the state the
|
|
11
|
+
* agent was **already** in, and `agent read` is the one command that does **not** return a JSON envelope.
|
|
12
|
+
*/
|
|
13
|
+
import { parseReply } from "./herdr-cli.js";
|
|
14
|
+
/** Statuses herdr reports for a settled agent. `blocked` counts: it is waiting for a human, not working. */
|
|
15
|
+
const TERMINAL = new Set(["idle", "done", "blocked"]);
|
|
16
|
+
/** How often to poll `agent get` while waiting for the child to settle. */
|
|
17
|
+
export const POLL_INTERVAL_MS = 750;
|
|
18
|
+
/** Lines of pane tail reported per poll. Matches the status block's own tail, so nothing is fetched unused. */
|
|
19
|
+
export const DEFAULT_SNAPSHOT_LINES = 3;
|
|
20
|
+
/**
|
|
21
|
+
* Wait for the child to settle, without accepting the state it was already in.
|
|
22
|
+
*
|
|
23
|
+
* **R-33, measured.** `herdr agent wait --until idle` called right after `agent prompt` returned
|
|
24
|
+
* *immediately*, matching the agent's **pre-existing** idle state with `state_change_seq` unchanged — a
|
|
25
|
+
* reply indistinguishable from a completed run. For fan-out that is not an inconvenience but a
|
|
26
|
+
* correctness bug: an orchestrator would "collect" N children that never ran and merge N empty results
|
|
27
|
+
* into a confident summary (R-03 with a new cause).
|
|
28
|
+
*
|
|
29
|
+
* So this polls `agent get` and requires **both** that the status is terminal **and** that
|
|
30
|
+
* `state_change_seq` has advanced past the value observed before prompting. `agent wait` is deliberately
|
|
31
|
+
* not used at all: its contract cannot express "settled *after* this point".
|
|
32
|
+
*/
|
|
33
|
+
export async function waitForSettled(exec, request, before, deadline, maxOutputBytes) {
|
|
34
|
+
const interval = request.pollIntervalMs ?? POLL_INTERVAL_MS;
|
|
35
|
+
// ADR-0032. The pane is read on every poll so the parent can show what the child is doing, rather than the
|
|
36
|
+
// one word `delegate` for up to ten minutes.
|
|
37
|
+
//
|
|
38
|
+
// No cross-poll state is kept, deliberately: the previous design remembered what it had reported so it could
|
|
39
|
+
// send a diff, and that is what broke — see `tailLines`. A snapshot needs no memory.
|
|
40
|
+
const keep = request.snapshotLines ?? DEFAULT_SNAPSHOT_LINES;
|
|
41
|
+
for (;;) {
|
|
42
|
+
if (request.signal?.aborted)
|
|
43
|
+
return { aborted: true };
|
|
44
|
+
if (Date.now() >= deadline)
|
|
45
|
+
return { timedOut: true };
|
|
46
|
+
const reply = parseReply(await exec(["agent", "get", request.name]));
|
|
47
|
+
if (reply.error)
|
|
48
|
+
return { spawnError: `herdr agent get failed: ${reply.error}` };
|
|
49
|
+
const agent = (reply.result?.agent ?? reply.result ?? {});
|
|
50
|
+
const status = agent.agent_status;
|
|
51
|
+
const seq = typeof agent.state_change_seq === "number" ? agent.state_change_seq : -1;
|
|
52
|
+
if (request.onSnapshot) {
|
|
53
|
+
// Read BEFORE the terminal check returns, so a child that settles on this iteration still has its last
|
|
54
|
+
// output shown. `readFailed` is passed so a failed read renders as such instead of silently freezing the
|
|
55
|
+
// block on the previous frame — and, crucially, is never mistaken for the child's output.
|
|
56
|
+
const read = await readPane(exec, request.name, maxOutputBytes);
|
|
57
|
+
try {
|
|
58
|
+
request.onSnapshot(read.readFailed ? ["[pane could not be read]"] : tailLines(read.text, keep));
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
/* display only — a renderer must not break a governed run */
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
if (status && TERMINAL.has(status) && seq > before)
|
|
65
|
+
return { status };
|
|
66
|
+
await new Promise((r) => setTimeout(r, Math.min(interval, Math.max(0, deadline - Date.now()))));
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* The last `keep` non-blank lines of a pane snapshot — what the display actually needs.
|
|
71
|
+
*
|
|
72
|
+
* **This replaces a `newSuffix` diff, and the replacement is a correction rather than a tune-up.** The old
|
|
73
|
+
* design treated `agent read` as a *stream* and tried to report only what was new, by testing whether the new
|
|
74
|
+
* text extended the old. That is wrong about the substrate: `agent read` returns a **snapshot of a bounded
|
|
75
|
+
* terminal**, and a snapshot is not an append-only log. Two ordinary things break the prefix test forever —
|
|
76
|
+
* the pane **scrolling** (its top lines are gone, so the new text is not an extension of the old) and
|
|
77
|
+
* `readPane` **truncating to the tail** past `maxOutputBytes` (each read is a different window of a growing
|
|
78
|
+
* buffer). Once either happens, every poll reported the whole buffer.
|
|
79
|
+
*
|
|
80
|
+
* Measured before the fix: **51 MiB streamed for ~600 bytes of real output — 89,000× amplification** in 37
|
|
81
|
+
* seconds, per child, with a scrolling pane also delivering the same real lines three times each. The old
|
|
82
|
+
* docstring named that exact failure as the thing it prevented.
|
|
83
|
+
*
|
|
84
|
+
* So the herdr path now reports a **bounded snapshot** and the consumer *replaces* rather than appends. There
|
|
85
|
+
* is no diff to get wrong, the per-poll cost is `keep` lines regardless of buffer size, and a scrolling pane
|
|
86
|
+
* simply shows its current tail — which is what a human looking at that pane would see.
|
|
87
|
+
*/
|
|
88
|
+
export function tailLines(snapshot, keep) {
|
|
89
|
+
if (keep <= 0)
|
|
90
|
+
return [];
|
|
91
|
+
const lines = [];
|
|
92
|
+
// Walked from the END, so a 1 MiB buffer costs the last few lines rather than a full split.
|
|
93
|
+
let end = snapshot.length;
|
|
94
|
+
while (end > 0 && lines.length < keep) {
|
|
95
|
+
const start = snapshot.lastIndexOf("\n", end - 1);
|
|
96
|
+
const line = snapshot.slice(start + 1, end).replace(/\r/g, "").trimEnd();
|
|
97
|
+
if (line.length > 0)
|
|
98
|
+
lines.unshift(line);
|
|
99
|
+
if (start === -1)
|
|
100
|
+
break;
|
|
101
|
+
end = start;
|
|
102
|
+
}
|
|
103
|
+
return lines;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Read the pane's contents.
|
|
107
|
+
*
|
|
108
|
+
* `agent read` is the ONE command that does not return herdr's JSON envelope — it writes the terminal's
|
|
109
|
+
* text straight to stdout. Running it through `parseReply` turned every successful read into
|
|
110
|
+
* "unparseable herdr reply", i.e. reported the child's actual answer as a failure to read it. Found by the
|
|
111
|
+
* end-to-end run; the unit fake had been written to the envelope shape and so agreed with the bug.
|
|
112
|
+
*
|
|
113
|
+
* A JSON envelope is still accepted first, because an `error` reply here IS JSON and must not be mistaken
|
|
114
|
+
* for terminal output.
|
|
115
|
+
*
|
|
116
|
+
* **`readFailed` is separate from `text`, and that separation is the fix for an R-03 defect.** A failed read
|
|
117
|
+
* used to return its own diagnostic *as* `text` — so `runHerdrPane` returned
|
|
118
|
+
* `[grants] could not read the agent pane: pane is gone` **as the child's answer, with `code: 0`**, and the
|
|
119
|
+
* orchestrator read a failure message as a completed sub-agent's report. Measured. It mattered little when this
|
|
120
|
+
* ran once per child; ADR-0032 made it run on every poll, up to 800 times for a ten-minute child, so a
|
|
121
|
+
* transient failure went from unlikely to expected. The caller must now decide, and it cannot do so by
|
|
122
|
+
* inspecting a string.
|
|
123
|
+
*/
|
|
124
|
+
export async function readPane(exec, name, maxOutputBytes) {
|
|
125
|
+
const reply = await exec(["agent", "read", name]);
|
|
126
|
+
let text;
|
|
127
|
+
try {
|
|
128
|
+
const parsed = JSON.parse(reply.stdout);
|
|
129
|
+
if (parsed.error) {
|
|
130
|
+
return { text: "", truncated: false, readFailed: parsed.error.message ?? "unknown error" };
|
|
131
|
+
}
|
|
132
|
+
const raw = parsed.result?.output ?? parsed.result?.text ?? parsed.result?.content ?? "";
|
|
133
|
+
text = typeof raw === "string" ? raw : JSON.stringify(raw);
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
text = reply.stdout;
|
|
137
|
+
}
|
|
138
|
+
if (Buffer.byteLength(text) <= maxOutputBytes)
|
|
139
|
+
return { text, truncated: false };
|
|
140
|
+
// Keep the TAIL, not the head: a terminal's useful content is its most recent output, and the head is
|
|
141
|
+
// the startup banner. `runChild` keeps the head because it streams and must stop a runaway producer;
|
|
142
|
+
// here the output is already complete, so the choice is free and the tail is the answer.
|
|
143
|
+
//
|
|
144
|
+
// Sliced by BYTES via a Buffer round trip rather than by code units, for `takeBytes`'s reason in
|
|
145
|
+
// `run-child.ts`: `slice(-maxOutputBytes)` on a CJK pane overran the cap by three times. `toString` repairs
|
|
146
|
+
// a character split at the cut by replacing it, which is the right trade for a tail — one replacement
|
|
147
|
+
// character at the boundary, versus a cap that does not hold.
|
|
148
|
+
return { text: Buffer.from(text, "utf8").subarray(-maxOutputBytes).toString("utf8"), truncated: true };
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=herdr-poll.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"herdr-poll.js","sourceRoot":"","sources":["../src/herdr-poll.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Staging a definition's instructions to a file, because herdr cannot carry them in argv.
|
|
3
|
+
*
|
|
4
|
+
* Split out of `src/run-herdr.ts` at the 400-line ceiling. A real seam rather than an arbitrary cut: this is
|
|
5
|
+
* the one place that works around a **herdr encoding limit**, and it is the only part of the herdr path that
|
|
6
|
+
* touches the filesystem. `run-herdr.ts` starts and reaps agents; this prepares one argument.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Move a multi-line `--append-system-prompt` out of argv, because herdr cannot encode it.
|
|
10
|
+
*
|
|
11
|
+
* **Measured.** `herdr agent start` types the argv into the pane's shell, so a value containing newlines
|
|
12
|
+
* is rejected outright: `invalid_agent_argument — agent arguments cannot be encoded safely for the target
|
|
13
|
+
* shell`. A definition's `SKILL.md` body is always multi-line, so every `delegate({agent})` spawn would
|
|
14
|
+
* fail on this path.
|
|
15
|
+
*
|
|
16
|
+
* pi accepts a **file path** there as readily as literal text (`resolvePromptInput` + `existsSync` in
|
|
17
|
+
* `dist/core/resource-loader.js`), so the fix is to write the body to a temp file and pass its path — one
|
|
18
|
+
* short, shell-safe argument.
|
|
19
|
+
*
|
|
20
|
+
* The split lives here rather than in `planSpawn` because the constraint is **herdr's**, not pi's: the
|
|
21
|
+
* direct executor passes the same text inline with no trouble, and a plan builder that pre-emptively wrote
|
|
22
|
+
* temp files for everybody would be paying one executor's tax on both paths.
|
|
23
|
+
*/
|
|
24
|
+
export declare function splitSystemPrompt(args: string[]): {
|
|
25
|
+
args: string[];
|
|
26
|
+
systemPrompt?: string;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Move a multi-line system prompt into a temp file and return argv pointing at it.
|
|
30
|
+
*
|
|
31
|
+
* Returns the directory so the caller can remove it — and **every** early return on the herdr path must, because
|
|
32
|
+
* nothing else can: a reviewer measured a permanent `/tmp/grants-herdr-*` per failed `tab create`, unreachable by
|
|
33
|
+
* either pane sweep because the pane it belonged to never existed.
|
|
34
|
+
*/
|
|
35
|
+
export declare function stageSystemPrompt(args: string[]): Promise<{
|
|
36
|
+
args: string[];
|
|
37
|
+
promptDir?: string;
|
|
38
|
+
error?: string;
|
|
39
|
+
}>;
|
|
40
|
+
//# sourceMappingURL=herdr-stage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"herdr-stage.d.ts","sourceRoot":"","sources":["../src/herdr-stage.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG;IAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,CAI3F;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,MAAM,EAAE,GACb,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAWjE"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Staging a definition's instructions to a file, because herdr cannot carry them in argv.
|
|
3
|
+
*
|
|
4
|
+
* Split out of `src/run-herdr.ts` at the 400-line ceiling. A real seam rather than an arbitrary cut: this is
|
|
5
|
+
* the one place that works around a **herdr encoding limit**, and it is the only part of the herdr path that
|
|
6
|
+
* touches the filesystem. `run-herdr.ts` starts and reaps agents; this prepares one argument.
|
|
7
|
+
*/
|
|
8
|
+
import { mkdtemp, writeFile } from "node:fs/promises";
|
|
9
|
+
import { tmpdir } from "node:os";
|
|
10
|
+
import { join } from "node:path";
|
|
11
|
+
/**
|
|
12
|
+
* Move a multi-line `--append-system-prompt` out of argv, because herdr cannot encode it.
|
|
13
|
+
*
|
|
14
|
+
* **Measured.** `herdr agent start` types the argv into the pane's shell, so a value containing newlines
|
|
15
|
+
* is rejected outright: `invalid_agent_argument — agent arguments cannot be encoded safely for the target
|
|
16
|
+
* shell`. A definition's `SKILL.md` body is always multi-line, so every `delegate({agent})` spawn would
|
|
17
|
+
* fail on this path.
|
|
18
|
+
*
|
|
19
|
+
* pi accepts a **file path** there as readily as literal text (`resolvePromptInput` + `existsSync` in
|
|
20
|
+
* `dist/core/resource-loader.js`), so the fix is to write the body to a temp file and pass its path — one
|
|
21
|
+
* short, shell-safe argument.
|
|
22
|
+
*
|
|
23
|
+
* The split lives here rather than in `planSpawn` because the constraint is **herdr's**, not pi's: the
|
|
24
|
+
* direct executor passes the same text inline with no trouble, and a plan builder that pre-emptively wrote
|
|
25
|
+
* temp files for everybody would be paying one executor's tax on both paths.
|
|
26
|
+
*/
|
|
27
|
+
export function splitSystemPrompt(args) {
|
|
28
|
+
const at = args.indexOf("--append-system-prompt");
|
|
29
|
+
if (at === -1 || at + 1 >= args.length)
|
|
30
|
+
return { args };
|
|
31
|
+
return { args: [...args.slice(0, at), ...args.slice(at + 2)], systemPrompt: args[at + 1] };
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Move a multi-line system prompt into a temp file and return argv pointing at it.
|
|
35
|
+
*
|
|
36
|
+
* Returns the directory so the caller can remove it — and **every** early return on the herdr path must, because
|
|
37
|
+
* nothing else can: a reviewer measured a permanent `/tmp/grants-herdr-*` per failed `tab create`, unreachable by
|
|
38
|
+
* either pane sweep because the pane it belonged to never existed.
|
|
39
|
+
*/
|
|
40
|
+
export async function stageSystemPrompt(args) {
|
|
41
|
+
const split = splitSystemPrompt(args);
|
|
42
|
+
if (split.systemPrompt === undefined)
|
|
43
|
+
return { args: split.args };
|
|
44
|
+
try {
|
|
45
|
+
const promptDir = await mkdtemp(join(tmpdir(), "grants-herdr-"));
|
|
46
|
+
const file = join(promptDir, "system-prompt.md");
|
|
47
|
+
await writeFile(file, split.systemPrompt, "utf8");
|
|
48
|
+
return { args: [...split.args, "--append-system-prompt", file], promptDir };
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
return { args: split.args, error: `could not stage the system prompt for herdr: ${String(error)}` };
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=herdr-stage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"herdr-stage.js","sourceRoot":"","sources":["../src/herdr-stage.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAc;IAC9C,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,wBAAwB,CAAC,CAAC;IAClD,IAAI,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IACxD,OAAO,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC;AAC7F,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,IAAc;IAEd,MAAM,KAAK,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IACtC,IAAI,KAAK,CAAC,YAAY,KAAK,SAAS;QAAE,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;IAClE,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,eAAe,CAAC,CAAC,CAAC;QACjE,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,EAAE,kBAAkB,CAAC,CAAC;QACjD,MAAM,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;QAClD,OAAO,EAAE,IAAI,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,wBAAwB,EAAE,IAAI,CAAC,EAAE,SAAS,EAAE,CAAC;IAC9E,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,gDAAgD,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;IACtG,CAAC;AACH,CAAC"}
|
package/dist/ledger-report.d.ts
CHANGED
|
@@ -23,6 +23,24 @@ export interface LedgerReport {
|
|
|
23
23
|
}>;
|
|
24
24
|
/** Records where an agent asked for more than it held — ADR-0008's designated signal. */
|
|
25
25
|
escalationAttempts: number;
|
|
26
|
+
/**
|
|
27
|
+
* How many records ran under each executor, plus how many name none — ADR-0031.
|
|
28
|
+
*
|
|
29
|
+
* **Added because the field was written and never read, which is R-51's shape exactly.** R-51 was
|
|
30
|
+
* `definitionDigest`: recorded from the start, absent from every report, so the questions ADR-0018 advertised
|
|
31
|
+
* needed hand-written `jq`. `executor` arrived the same way — `src/ledger.ts` justifies making it *required*
|
|
32
|
+
* with "reading it back is the only reason it exists", and nothing read it back. `docs/SPEC.md` claims the
|
|
33
|
+
* executor is "announced three times… per child in the ledger"; without this the third announcement was to
|
|
34
|
+
* `jq` only.
|
|
35
|
+
*
|
|
36
|
+
* `unknown` counts pre-0.16 lines, which have no such field. Reported rather than folded into `process`,
|
|
37
|
+
* because "written before the executor was recorded" and "ran as a subprocess" are different facts.
|
|
38
|
+
*/
|
|
39
|
+
executors: {
|
|
40
|
+
herdr: number;
|
|
41
|
+
process: number;
|
|
42
|
+
unknown: number;
|
|
43
|
+
};
|
|
26
44
|
/**
|
|
27
45
|
* Every distinct set of instructions this ledger saw run, with how many spawns used it (R-51).
|
|
28
46
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ledger-report.d.ts","sourceRoot":"","sources":["../src/ledger-report.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAIpD,MAAM,WAAW,YAAY;IAC3B,yEAAyE;IACzE,MAAM,EAAE,OAAO,CAAC;IAChB,oCAAoC;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,iFAAiF;IACjF,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,yFAAyF;IACzF,kBAAkB,EAAE,MAAM,CAAC;IAC3B;;;;;;;;;;;;OAYG;IACH,WAAW,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACrF;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACH,SAAS,EAAE;QACT,2FAA2F;QAC3F,QAAQ,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;QACzC,2EAA2E;QAC3E,gBAAgB,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;QACjD,0GAA0G;QAC1G,YAAY,EAAE,MAAM,CAAC;QACrB,uFAAuF;QACvF,WAAW,EAAE,MAAM,CAAC;QACpB;;;;;;;;WAQG;QACH,gBAAgB,EAAE,MAAM,CAAC;KAC1B,CAAC;IACF,EAAE,EAAE,OAAO,CAAC;CACb;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,
|
|
1
|
+
{"version":3,"file":"ledger-report.d.ts","sourceRoot":"","sources":["../src/ledger-report.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAIpD,MAAM,WAAW,YAAY;IAC3B,yEAAyE;IACzE,MAAM,EAAE,OAAO,CAAC;IAChB,oCAAoC;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,iFAAiF;IACjF,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,yFAAyF;IACzF,kBAAkB,EAAE,MAAM,CAAC;IAC3B;;;;;;;;;;;;OAYG;IACH,SAAS,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/D;;;;;;;;;;;;OAYG;IACH,WAAW,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACrF;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACH,SAAS,EAAE;QACT,2FAA2F;QAC3F,QAAQ,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;QACzC,2EAA2E;QAC3E,gBAAgB,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;QACjD,0GAA0G;QAC1G,YAAY,EAAE,MAAM,CAAC;QACrB,uFAAuF;QACvF,WAAW,EAAE,MAAM,CAAC;QACpB;;;;;;;;WAQG;QACH,gBAAgB,EAAE,MAAM,CAAC;KAC1B,CAAC;IACF,EAAE,EAAE,OAAO,CAAC;CACb;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAiItE"}
|
package/dist/ledger-report.js
CHANGED
|
@@ -36,6 +36,7 @@ export async function verifyLedger(path) {
|
|
|
36
36
|
records: 0,
|
|
37
37
|
corrupt: [],
|
|
38
38
|
escalationAttempts: 0,
|
|
39
|
+
executors: { herdr: 0, process: 0, unknown: 0 },
|
|
39
40
|
definitions: [],
|
|
40
41
|
approvals: {
|
|
41
42
|
bySource: { prompt: 0, session: 0, persisted: 0, inherited: 0 },
|
|
@@ -54,6 +55,7 @@ export async function verifyLedger(path) {
|
|
|
54
55
|
const digests = new Map();
|
|
55
56
|
let records = 0;
|
|
56
57
|
let escalationAttempts = 0;
|
|
58
|
+
const executors = { herdr: 0, process: 0, unknown: 0 };
|
|
57
59
|
const bySource = { prompt: 0, session: 0, persisted: 0, inherited: 0 };
|
|
58
60
|
// `capability@subject` seen per source, so the report can state a bound as well as a raw count.
|
|
59
61
|
const distinct = {
|
|
@@ -77,6 +79,13 @@ export async function verifyLedger(path) {
|
|
|
77
79
|
records += 1;
|
|
78
80
|
if (isEscalationAttempt(parsed))
|
|
79
81
|
escalationAttempts += 1;
|
|
82
|
+
const executor = parsed.executor;
|
|
83
|
+
if (executor === "herdr")
|
|
84
|
+
executors.herdr += 1;
|
|
85
|
+
else if (executor === "process")
|
|
86
|
+
executors.process += 1;
|
|
87
|
+
else
|
|
88
|
+
executors.unknown += 1;
|
|
80
89
|
if (parsed.humanDenied) {
|
|
81
90
|
humanDenied += 1;
|
|
82
91
|
const subject = parsed.agentType === undefined || parsed.agentType === "delegate" ? DELEGATE_SUBJECT : parsed.agentType;
|
|
@@ -138,6 +147,7 @@ export async function verifyLedger(path) {
|
|
|
138
147
|
records,
|
|
139
148
|
corrupt,
|
|
140
149
|
escalationAttempts,
|
|
150
|
+
executors,
|
|
141
151
|
definitions: [...digests.values()].sort((a, b) => a.name.localeCompare(b.name) || a.sha256.localeCompare(b.sha256)),
|
|
142
152
|
approvals: {
|
|
143
153
|
bySource,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ledger-report.js","sourceRoot":"","sources":["../src/ledger-report.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAGjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"ledger-report.js","sourceRoot":"","sources":["../src/ledger-report.ts"],"names":[],"mappings":"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"}
|
package/dist/ledger.d.ts
CHANGED
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
* "what was this child told to do?" is out of the ledger by decision, not by omission.
|
|
20
20
|
*/
|
|
21
21
|
import type { Capability, ResolveResult } from "./resolve.ts";
|
|
22
|
+
import type { ExecutorKind } from "./executor.ts";
|
|
22
23
|
import type { DefinitionDigest } from "./definitions.ts";
|
|
23
24
|
import type { ApprovalScope, ApprovalSource } from "./approval.ts";
|
|
24
25
|
import type { PromptOutcomeKind } from "./approval-prompt.ts";
|
|
@@ -101,6 +102,32 @@ export interface GrantRecord {
|
|
|
101
102
|
* it. Absent for a `tools:`-style delegation, which has no definition.
|
|
102
103
|
*/
|
|
103
104
|
definitionDigest?: DefinitionDigest;
|
|
105
|
+
/**
|
|
106
|
+
* WHERE this child ran — ADR-0031.
|
|
107
|
+
*
|
|
108
|
+
* **Required rather than optional**, which is unusual in this record and deliberate. Before ADR-0031 the
|
|
109
|
+
* executor was a variable an operator set, so "which one ran?" was answerable from configuration after the
|
|
110
|
+
* fact. It is now decided by a **runtime probe** at session start, so nothing outside the record preserves
|
|
111
|
+
* the answer — and the two paths do not produce the same argv, because the herdr plan withholds `--print`
|
|
112
|
+
* (`delegationContext.interactive`). A trail that cannot say where a child ran cannot be read back
|
|
113
|
+
* reliably, and reading it back is the only reason it exists.
|
|
114
|
+
*
|
|
115
|
+
* Written on refusals too, including the tripwire's: the honest value there is the executor the session
|
|
116
|
+
* *would* have used, because a refused spawn has no executor of its own.
|
|
117
|
+
*/
|
|
118
|
+
executor: ExecutorKind;
|
|
119
|
+
/**
|
|
120
|
+
* The child whose OUTPUT composed this child's task — ADR-0033.
|
|
121
|
+
*
|
|
122
|
+
* **Optional, unlike `executor`, and the asymmetry is deliberate.** A non-chained spawn has no prior author, and
|
|
123
|
+
* an empty string would assert one. Present only on chain steps after the first.
|
|
124
|
+
*
|
|
125
|
+
* Why it is recorded at all: a chain makes step N's task the output of a governed child, and ADR-0033's chosen
|
|
126
|
+
* handoff is *framing* rather than enforcement. So "who wrote this instruction?" is exactly the question that
|
|
127
|
+
* decision makes worth asking, and it is unanswerable from any other field — `agentType` names the definition,
|
|
128
|
+
* `definitionDigest` names its instructions, and neither says where the TASK came from.
|
|
129
|
+
*/
|
|
130
|
+
taskFrom?: string;
|
|
104
131
|
}
|
|
105
132
|
export interface LedgerOptions {
|
|
106
133
|
/** Path to the JSONL file. Parent directories are created on demand. */
|
|
@@ -129,6 +156,10 @@ export declare function buildRecord(args: {
|
|
|
129
156
|
humanDenied?: boolean;
|
|
130
157
|
gateOutcome?: PromptOutcomeKind;
|
|
131
158
|
definitionDigest?: DefinitionDigest;
|
|
159
|
+
/** Where the child ran (ADR-0031). Required: the probe's answer survives nowhere else. */
|
|
160
|
+
executor: ExecutorKind;
|
|
161
|
+
/** The child whose output composed this task (ADR-0033). Absent for anything but a chain step. */
|
|
162
|
+
taskFrom?: string;
|
|
132
163
|
now: Date;
|
|
133
164
|
}): GrantRecord;
|
|
134
165
|
export { LOCK_TIMEOUT_MS, STALE_LOCK_MS } from "./file-lock.ts";
|
package/dist/ledger.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ledger.d.ts","sourceRoot":"","sources":["../src/ledger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAKH,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC9D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEzD,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACnE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAE9D,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,UAAU,EAAE,CAAC;IACxB,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,SAAS,EAAE,UAAU,EAAE,CAAC;IACxB,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,YAAY,EAAE,UAAU,EAAE,CAAC;IAC3B,qEAAqE;IACrE,OAAO,EAAE,OAAO,CAAC;IACjB,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;;;OAQG;IACH,QAAQ,CAAC,EAAE,UAAU,EAAE,CAAC;IACxB,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC;;;;;;;;;;;;OAYG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;IACrD;;;;;OAKG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;IACnD,oGAAoG;IACpG,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,8FAA8F;IAC9F,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;;;;;;;;;;;;;OAgBG;IACH,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC;;;;;;;OAOG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"ledger.d.ts","sourceRoot":"","sources":["../src/ledger.ts"],"names":[],"mappings":"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"}
|
package/dist/ledger.js
CHANGED
|
@@ -35,6 +35,8 @@ export function buildRecord(args) {
|
|
|
35
35
|
childId: args.childId,
|
|
36
36
|
depth: args.depth,
|
|
37
37
|
agentType: args.agentType,
|
|
38
|
+
executor: args.executor,
|
|
39
|
+
...(args.taskFrom ? { taskFrom: args.taskFrom } : {}),
|
|
38
40
|
requested: args.requested,
|
|
39
41
|
parentGrant: args.parentGrant,
|
|
40
42
|
effective: args.result.effective,
|
package/dist/ledger.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ledger.js","sourceRoot":"","sources":["../src/ledger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"ledger.js","sourceRoot":"","sources":["../src/ledger.ts"],"names":[],"mappings":"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"}
|
package/dist/pane-reaper.d.ts
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Close herdr panes this process opened but never got to close.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* **As of ADR-0032 a pane belongs to the AGENT RUN, not to the tool call.** `runHerdrPane` closes a tab only for
|
|
5
|
+
* a child that did *not* settle — closing the tab is the only kill herdr offers, so a child still working must
|
|
6
|
+
* lose its pane. A child that answered keeps its pane so a human can read it, and this module reaps those: at
|
|
7
|
+
* `agent_settled` (async) and at process `exit` (sync backstop).
|
|
8
|
+
*
|
|
9
|
+
* The gap that remains is the one this module was created for. A pi session **killed outright** runs no `exit`
|
|
10
|
+
* handler, so it leaves one pane per tracked child, and `docs/probes/g16-herdr` records that an orphaned pane is
|
|
11
|
+
* not trivially closable afterwards. R-62 was re-rated L×L → M×L when ADR-0031 made panes the default path.
|
|
7
12
|
*
|
|
8
13
|
* **Registered on `exit` only, deliberately — not on SIGINT or SIGTERM.** That is the part worth reading,
|
|
9
14
|
* because the obvious fix is the dangerous one. Adding a signal listener *suppresses Node's default
|
|
@@ -21,14 +26,45 @@
|
|
|
21
26
|
*
|
|
22
27
|
* Everything here is **synchronous**, because an `exit` handler is: a promise scheduled there never runs.
|
|
23
28
|
*/
|
|
29
|
+
import { type HerdrExec } from "./herdr-cli.ts";
|
|
30
|
+
/**
|
|
31
|
+
* How many panes may be open at once — ADR-0032.
|
|
32
|
+
*
|
|
33
|
+
* **Derived from `MAX_CHILDREN_PER_CALL` rather than declared, so the two cannot drift.** The bound is not
|
|
34
|
+
* decoration: `delegate_all` is capped per call and the fan-out budget bounds a subtree, but a plain blocking
|
|
35
|
+
* `delegate` spends **nothing** from that budget by design — so thirty sequential `delegate` calls in one agent
|
|
36
|
+
* run would otherwise hold thirty panes open until it settled.
|
|
37
|
+
*/
|
|
38
|
+
export declare const MAX_OPEN_PANES = 8;
|
|
24
39
|
export interface OpenPane {
|
|
25
40
|
/** herdr tab id — what `tab close` takes. */
|
|
26
41
|
tab: string;
|
|
27
|
-
/**
|
|
42
|
+
/** herdr agent name, for diagnostics. There is no `agent stop`, so nothing acts on it — see `closePane`. */
|
|
28
43
|
name: string;
|
|
29
44
|
/** Staged system-prompt directory, removed with the pane it belonged to. */
|
|
30
45
|
promptDir?: string;
|
|
46
|
+
/**
|
|
47
|
+
* True once the child has answered and stopped working.
|
|
48
|
+
*
|
|
49
|
+
* **The trim may only close a pane with this set**, and that is a correctness rule rather than politeness. pi
|
|
50
|
+
* executes tool calls in **parallel** by default, and a plain `delegate` spends nothing from the fan-out
|
|
51
|
+
* budget — so one assistant message can hold `delegate_all(8)` *and* a `delegate`, and the ninth pane's trim
|
|
52
|
+
* used to close the oldest **live sibling**. Measured: two `delegate_all(8)` in one message killed **8 of 16
|
|
53
|
+
* children mid-work**, each reported as "could not be started" with its partial output discarded, while the
|
|
54
|
+
* ledger recorded all sixteen as provisioned. ADR-0032 argued the cap from *sequential* delegates only.
|
|
55
|
+
*/
|
|
56
|
+
settled?: boolean;
|
|
57
|
+
/**
|
|
58
|
+
* The operator asked to keep this tab (`PI_GRANTS_HERDR_KEEP_PANE=1`), so no sweep may close it.
|
|
59
|
+
*
|
|
60
|
+
* It is registered anyway, and only for its `promptDir`: that temp dir was otherwise unreachable by either
|
|
61
|
+
* sweep and leaked one directory per kept pane, forever. So `exit` removes the staged prompt and leaves the
|
|
62
|
+
* tab, which is exactly what the flag promises.
|
|
63
|
+
*/
|
|
64
|
+
keepTab?: boolean;
|
|
31
65
|
}
|
|
66
|
+
/** A run has finished with its pane: the trim may now reclaim it. */
|
|
67
|
+
export declare function markPaneSettled(tab: string): void;
|
|
32
68
|
/** A run has opened a pane. Idempotent per tab, and installs the exit hook on first use only. */
|
|
33
69
|
export declare function trackPane(pane: OpenPane): void;
|
|
34
70
|
/** A run closed its own pane the normal way. */
|
|
@@ -46,4 +82,30 @@ export declare function openPaneCount(): number;
|
|
|
46
82
|
* other seven, and nothing at exit has anywhere to report to anyway.
|
|
47
83
|
*/
|
|
48
84
|
export declare function reapOpenPanes(syncExec?: (args: string[]) => void, now?: () => number): string[];
|
|
85
|
+
/**
|
|
86
|
+
* Close every outstanding pane — the `agent_settled` path (ADR-0032).
|
|
87
|
+
*
|
|
88
|
+
* **A separate function from `reapOpenPanes` rather than a shared implementation**, and the reason is not
|
|
89
|
+
* style. The sync one is `execFileSync` with a six-second total budget *by necessity*: an `exit` handler cannot
|
|
90
|
+
* await. Running that at `agent_settled` would freeze pi for up to six seconds **every time the operator gets
|
|
91
|
+
* their prompt back** — turning a feature that exists to make work visible into a stall.
|
|
92
|
+
*
|
|
93
|
+
* Both drain the same `Map`, keyed by tab id, so a double close is impossible and a pane herdr refused stays
|
|
94
|
+
* registered for whichever sweep runs next.
|
|
95
|
+
*
|
|
96
|
+
* Sequential rather than concurrent: a fan-out's panes are at most `MAX_OPEN_PANES`, and eight `tab close`
|
|
97
|
+
* calls in parallel against one herdr server buys nothing worth the burst.
|
|
98
|
+
*/
|
|
99
|
+
export declare function reapOpenPanesAsync(exec?: HerdrExec): Promise<string[]>;
|
|
100
|
+
/**
|
|
101
|
+
* Keep at most `MAX_OPEN_PANES` open, closing the oldest first.
|
|
102
|
+
*
|
|
103
|
+
* The `Map`'s insertion order **is** the age order, so no timestamp is needed — and that is why `trackPane`
|
|
104
|
+
* must never re-`set` an existing tab, which would move it to the back of the queue and make an old pane look
|
|
105
|
+
* new.
|
|
106
|
+
*
|
|
107
|
+
* Whatever it closes is returned so the caller can **say so** rather than silently dropping a pane the operator
|
|
108
|
+
* was reading (R-48's rule, applied to a display).
|
|
109
|
+
*/
|
|
110
|
+
export declare function trimOpenPanes(exec?: HerdrExec): Promise<string[]>;
|
|
49
111
|
//# sourceMappingURL=pane-reaper.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pane-reaper.d.ts","sourceRoot":"","sources":["../src/pane-reaper.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"pane-reaper.d.ts","sourceRoot":"","sources":["../src/pane-reaper.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAMH,OAAO,EAA2B,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEzE;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,IAAwB,CAAC;AAEpD,MAAM,WAAW,QAAQ;IACvB,6CAA6C;IAC7C,GAAG,EAAE,MAAM,CAAC;IACZ,4GAA4G;IAC5G,IAAI,EAAE,MAAM,CAAC;IACb,4EAA4E;IAC5E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;;;;OASG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,qEAAqE;AACrE,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAGjD;AAeD,iGAAiG;AACjG,wBAAgB,SAAS,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,CAO9C;AAED,gDAAgD;AAChD,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAE7C;AAED,8EAA8E;AAC9E,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAyBD;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,QAAQ,GAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,IAAsB,EAAE,GAAG,eAAW,GAAG,MAAM,EAAE,CAgD5G;AAsBD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,GAAE,SAAuB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CASzF;AAED;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CAAC,IAAI,GAAE,SAAuB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAmBpF"}
|