pi-daddy 0.45.0 → 0.46.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 +4 -0
- package/README.md +355 -45
- package/dist/executors/captured-execution.d.ts +2 -2
- package/dist/executors/captured-execution.d.ts.map +1 -1
- package/dist/executors/captured-execution.js +2 -2
- package/dist/executors/captured-execution.js.map +1 -1
- package/dist/executors/executor.d.ts.map +1 -1
- package/dist/executors/executor.js +4 -2
- package/dist/executors/executor.js.map +1 -1
- package/dist/executors/herdr-cli.d.ts +2 -0
- package/dist/executors/herdr-cli.d.ts.map +1 -1
- package/dist/executors/herdr-cli.js +2 -2
- package/dist/executors/herdr-cli.js.map +1 -1
- package/dist/executors/herdr-launcher.d.ts +2 -0
- package/dist/executors/herdr-launcher.d.ts.map +1 -0
- package/dist/executors/herdr-launcher.js +123 -0
- package/dist/executors/herdr-launcher.js.map +1 -0
- package/dist/executors/herdr-owned.d.ts +13 -0
- package/dist/executors/herdr-owned.d.ts.map +1 -0
- package/dist/executors/herdr-owned.js +229 -0
- package/dist/executors/herdr-owned.js.map +1 -0
- package/dist/executors/herdr-qualification.d.ts +6 -0
- package/dist/executors/herdr-qualification.d.ts.map +1 -0
- package/dist/executors/herdr-qualification.js +33 -0
- package/dist/executors/herdr-qualification.js.map +1 -0
- package/dist/executors/herdr-wire.d.ts +5 -0
- package/dist/executors/herdr-wire.d.ts.map +1 -0
- package/dist/executors/herdr-wire.js +47 -0
- package/dist/executors/herdr-wire.js.map +1 -0
- package/dist/governance/runtime-settlement-lock.d.ts +5 -0
- package/dist/governance/runtime-settlement-lock.d.ts.map +1 -0
- package/dist/governance/runtime-settlement-lock.js +72 -0
- package/dist/governance/runtime-settlement-lock.js.map +1 -0
- package/dist/governance/runtime-settlement.d.ts +22 -0
- package/dist/governance/runtime-settlement.d.ts.map +1 -0
- package/dist/governance/runtime-settlement.js +236 -0
- package/dist/governance/runtime-settlement.js.map +1 -0
- package/extensions/execute-child.ts +98 -74
- package/extensions/executor-session.ts +2 -1
- package/extensions/grants.ts +3 -0
- package/extensions/reload-environment.ts +8 -0
- package/extensions/runtime-snapshot.ts +123 -0
- package/extensions/session.ts +1 -1
- package/package.json +1 -1
- package/src/executors/captured-execution.ts +2 -1
- package/src/executors/executor.ts +4 -2
- package/src/executors/herdr-cli.ts +19 -12
- package/src/executors/herdr-launcher.ts +124 -0
- package/src/executors/herdr-owned.ts +260 -0
- package/src/executors/herdr-qualification.ts +33 -0
- package/src/executors/herdr-wire.ts +43 -0
- package/src/governance/runtime-settlement-lock.ts +76 -0
- package/src/governance/runtime-settlement.ts +271 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/** Packaged pane entrypoint. Parent liveness is a private socket, native worker liveness is its control pipe. */
|
|
2
|
+
import { stat } from "node:fs/promises";
|
|
3
|
+
import { processTreeActivity } from "./process-activity.js";
|
|
4
|
+
import { createConnection } from "node:net";
|
|
5
|
+
import { runOwnedChild } from "./owned-worker.js";
|
|
6
|
+
import { wire } from "./herdr-wire.js";
|
|
7
|
+
export async function launchHerdrWorker(socketPath, token) {
|
|
8
|
+
const socket = createConnection(socketPath);
|
|
9
|
+
const abort = new AbortController();
|
|
10
|
+
let started = false, authenticated = false, acknowledge, rejectGate;
|
|
11
|
+
const lost = (error) => {
|
|
12
|
+
abort.abort();
|
|
13
|
+
rejectGate?.(error);
|
|
14
|
+
};
|
|
15
|
+
socket.on("close", () => lost(Error("Herdr coordinator connection closed")));
|
|
16
|
+
const send = wire(socket, (message) => {
|
|
17
|
+
if (message?.type === "cancel") {
|
|
18
|
+
abort.abort();
|
|
19
|
+
rejectGate?.(Error("Herdr coordinator cancelled startup"));
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
if (message?.type === "start" && authenticated) {
|
|
23
|
+
acknowledge?.();
|
|
24
|
+
acknowledge = undefined;
|
|
25
|
+
rejectGate = undefined;
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
if (message?.type === "display" && authenticated && typeof message.text === "string") {
|
|
29
|
+
process.stdout.write(message.text);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
if (message?.type !== "request" || started) {
|
|
33
|
+
lost(Error("invalid Herdr coordinator request"));
|
|
34
|
+
socket.destroy();
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
started = true;
|
|
38
|
+
authenticated = true;
|
|
39
|
+
const request = message.request;
|
|
40
|
+
let childPid;
|
|
41
|
+
void (async () => {
|
|
42
|
+
try {
|
|
43
|
+
const result = await runOwnedChild({
|
|
44
|
+
...request,
|
|
45
|
+
signal: abort.signal,
|
|
46
|
+
activityProbe: async () => {
|
|
47
|
+
const file = request.sessionPath
|
|
48
|
+
? await stat(request.sessionPath)
|
|
49
|
+
.then((s) => String(s.size) + ":" + s.mtimeMs)
|
|
50
|
+
.catch(() => undefined)
|
|
51
|
+
: undefined;
|
|
52
|
+
const tree = childPid === undefined ? undefined : await processTreeActivity(childPid);
|
|
53
|
+
return file === undefined && tree === undefined ? undefined : String(file) + "|" + tree;
|
|
54
|
+
},
|
|
55
|
+
onOwnership: (identity) => new Promise((resolve, reject) => {
|
|
56
|
+
acknowledge = resolve;
|
|
57
|
+
rejectGate = reject;
|
|
58
|
+
if (abort.signal.aborted) {
|
|
59
|
+
reject(Error("Herdr coordinator unavailable before ownership gate"));
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
send({ type: "ownership", identity });
|
|
63
|
+
}),
|
|
64
|
+
onObservation: (stream, bytes) => {
|
|
65
|
+
try {
|
|
66
|
+
const input = Buffer.from(bytes);
|
|
67
|
+
for (let offset = 0; offset < input.length; offset += 65536)
|
|
68
|
+
send({ type: "bytes", stream, data: input.subarray(offset, offset + 65536).toString("base64") });
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
lost(error instanceof Error ? error : Error(String(error)));
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
onStreamEnd: (stream) => {
|
|
75
|
+
try {
|
|
76
|
+
send({ type: "stream-end", stream });
|
|
77
|
+
}
|
|
78
|
+
catch { }
|
|
79
|
+
},
|
|
80
|
+
onSpawn: (pid) => {
|
|
81
|
+
childPid = pid;
|
|
82
|
+
send({ type: "spawned", pid });
|
|
83
|
+
process.stdout.write("pi-daddy: governed child running\n");
|
|
84
|
+
},
|
|
85
|
+
});
|
|
86
|
+
if (!socket.destroyed) {
|
|
87
|
+
send({ type: "result", result });
|
|
88
|
+
socket.end();
|
|
89
|
+
}
|
|
90
|
+
process.stdout.write("\npi-daddy: " + result.cleanup.state + "\n");
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
if (!socket.destroyed) {
|
|
94
|
+
try {
|
|
95
|
+
send({ type: "failure", reason: String(error) });
|
|
96
|
+
}
|
|
97
|
+
finally {
|
|
98
|
+
socket.end();
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
})();
|
|
103
|
+
}, lost);
|
|
104
|
+
await new Promise((resolve, reject) => {
|
|
105
|
+
socket.once("connect", () => {
|
|
106
|
+
try {
|
|
107
|
+
send({ type: "hello", token });
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
reject(error);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
socket.once("close", resolve);
|
|
114
|
+
socket.once("error", reject);
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
if (/herdr-launcher\.(?:js|ts)$/.test(process.argv[1] ?? "")) {
|
|
118
|
+
const [, , path, token] = process.argv;
|
|
119
|
+
if (!path || !token)
|
|
120
|
+
throw Error("Herdr launcher requires its private socket and nonce");
|
|
121
|
+
await launchHerdrWorker(path, token);
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=herdr-launcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"herdr-launcher.js","sourceRoot":"","sources":["../../src/executors/herdr-launcher.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { OwnedChildRunRequest, OwnedChildRunResult } from "./owned-worker.ts";
|
|
2
|
+
import { type HerdrExec } from "./herdr-cli.ts";
|
|
3
|
+
export interface HerdrOwnedOptions {
|
|
4
|
+
exec?: HerdrExec;
|
|
5
|
+
workspace?: string;
|
|
6
|
+
keepPane?: boolean;
|
|
7
|
+
onPane?: (paneId: string, tabId: string) => void;
|
|
8
|
+
onDisplay?: (display: (text: string) => void) => void;
|
|
9
|
+
/** Tests may select a freshly built launcher. Production always uses the packaged build. */
|
|
10
|
+
launcherPath?: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function runHerdrOwned(request: OwnedChildRunRequest, options?: HerdrOwnedOptions): Promise<OwnedChildRunResult>;
|
|
13
|
+
//# sourceMappingURL=herdr-owned.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"herdr-owned.d.ts","sourceRoot":"","sources":["../../src/executors/herdr-owned.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAOnF,OAAO,EAA2B,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAIzE,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,KAAK,IAAI,CAAC;IACtD,4FAA4F;IAC5F,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AACD,wBAAsB,aAAa,CACjC,OAAO,EAAE,oBAAoB,EAC7B,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,mBAAmB,CAAC,CAqO9B"}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
/** Governed work runs in its own Herdr pane, under the same independently settling native owner as captured work. */
|
|
2
|
+
import { createServer } from "node:net";
|
|
3
|
+
import { randomUUID } from "node:crypto";
|
|
4
|
+
import { chmod, mkdtemp, rm } from "node:fs/promises";
|
|
5
|
+
import { tmpdir } from "node:os";
|
|
6
|
+
import { join } from "node:path";
|
|
7
|
+
import { fileURLToPath } from "node:url";
|
|
8
|
+
import { isCapturedWorkerIdentity, readCapturedWorkerReceipt, validateLiveWorker, } from "../governance/captured-worker-record.js";
|
|
9
|
+
import { defaultExec, parseReply } from "./herdr-cli.js";
|
|
10
|
+
import { WORKER_SHA256 } from "./worker-artifact.js";
|
|
11
|
+
import { wire } from "./herdr-wire.js";
|
|
12
|
+
const quote = (value) => "'" + value.replaceAll("'", "'\\''") + "'";
|
|
13
|
+
export async function runHerdrOwned(request, options = {}) {
|
|
14
|
+
const exec = options.exec ?? defaultExec;
|
|
15
|
+
const directory = await mkdtemp(join(tmpdir(), "pd-herdr-"));
|
|
16
|
+
const path = join(directory, "owner.sock"), token = randomUUID();
|
|
17
|
+
const launcher = options.launcherPath ?? fileURLToPath(new URL("../../dist/executors/herdr-launcher.js", import.meta.url));
|
|
18
|
+
const helper = fileURLToPath(new URL("../../native/linux-x64/worker", import.meta.url));
|
|
19
|
+
let socket, send;
|
|
20
|
+
let identity, outcome, error;
|
|
21
|
+
let tabId, entered = false, done = false, authenticated = false;
|
|
22
|
+
let finish;
|
|
23
|
+
const startupTimer = setTimeout(() => {
|
|
24
|
+
fail("Herdr launcher did not connect before startup deadline");
|
|
25
|
+
socket?.destroy();
|
|
26
|
+
finish();
|
|
27
|
+
}, Math.min(request.timeoutMs ?? 10000, 10000));
|
|
28
|
+
const completed = new Promise((resolve) => {
|
|
29
|
+
finish = resolve;
|
|
30
|
+
});
|
|
31
|
+
const abort = () => {
|
|
32
|
+
try {
|
|
33
|
+
send?.({ type: "cancel" });
|
|
34
|
+
}
|
|
35
|
+
catch { }
|
|
36
|
+
};
|
|
37
|
+
const fail = (cause) => {
|
|
38
|
+
error ??= String(cause);
|
|
39
|
+
abort();
|
|
40
|
+
};
|
|
41
|
+
const server = createServer((candidate) => {
|
|
42
|
+
if (socket) {
|
|
43
|
+
candidate.destroy();
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
socket = candidate;
|
|
47
|
+
send = wire(candidate, (message) => {
|
|
48
|
+
if (!authenticated) {
|
|
49
|
+
if (message?.type !== "hello" || message.token !== token)
|
|
50
|
+
throw Error("Herdr launcher nonce mismatch");
|
|
51
|
+
authenticated = true;
|
|
52
|
+
clearTimeout(startupTimer);
|
|
53
|
+
const { signal: _signal, onOwnership: _owner, onSpawn: _spawn, onOutput: _out, onObservation: _observation, onStreamEnd: _end, activityProbe: _probe, ...serializable } = request;
|
|
54
|
+
send({ type: "request", request: serializable });
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (message?.type === "ownership") {
|
|
58
|
+
if (identity || !isCapturedWorkerIdentity(message.identity))
|
|
59
|
+
throw Error("ambiguous Herdr worker ownership");
|
|
60
|
+
const actual = message.identity;
|
|
61
|
+
if (actual.executionId !== request.executionId ||
|
|
62
|
+
actual.root !== request.cwd ||
|
|
63
|
+
actual.helperSha256 !== WORKER_SHA256 ||
|
|
64
|
+
actual.ownershipPath !== join(request.ownershipDir, "ownership.json"))
|
|
65
|
+
throw Error("Herdr worker identity differs from requested execution");
|
|
66
|
+
identity = actual;
|
|
67
|
+
void (async () => {
|
|
68
|
+
try {
|
|
69
|
+
await validateLiveWorker(actual, helper);
|
|
70
|
+
await request.onOwnership?.(actual);
|
|
71
|
+
if (!done && !request.signal?.aborted && !error) {
|
|
72
|
+
request.onSpawn?.(actual.workerPid);
|
|
73
|
+
send({ type: "start" });
|
|
74
|
+
}
|
|
75
|
+
else
|
|
76
|
+
abort();
|
|
77
|
+
}
|
|
78
|
+
catch (cause) {
|
|
79
|
+
fail(cause);
|
|
80
|
+
abort();
|
|
81
|
+
}
|
|
82
|
+
})();
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
if (message?.type === "bytes" &&
|
|
86
|
+
["stdout", "stderr"].includes(message.stream) &&
|
|
87
|
+
typeof message.data === "string") {
|
|
88
|
+
if (!identity ||
|
|
89
|
+
message.data.length > 90000 ||
|
|
90
|
+
!/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(message.data))
|
|
91
|
+
throw Error("invalid Herdr output frame");
|
|
92
|
+
try {
|
|
93
|
+
request.onObservation?.(message.stream, Buffer.from(message.data, "base64"));
|
|
94
|
+
}
|
|
95
|
+
catch { }
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
if (message?.type === "stream-end" && ["stdout", "stderr"].includes(message.stream)) {
|
|
99
|
+
try {
|
|
100
|
+
request.onStreamEnd?.(message.stream);
|
|
101
|
+
}
|
|
102
|
+
catch { }
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
if (message?.type === "spawned" && identity && message.pid === identity.workerPid) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
if (message?.type === "result" && !outcome) {
|
|
109
|
+
outcome = message.result;
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
if (message?.type === "failure") {
|
|
113
|
+
fail(message.reason);
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
throw Error("invalid Herdr worker transport message");
|
|
117
|
+
}, fail);
|
|
118
|
+
options.onDisplay?.((text) => {
|
|
119
|
+
if (authenticated && send) {
|
|
120
|
+
for (let at = 0; at < text.length; at += 16000)
|
|
121
|
+
send({ type: "display", text: text.slice(at, at + 16000) });
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
candidate.on("close", finish);
|
|
125
|
+
});
|
|
126
|
+
const timeout = setTimeout(() => {
|
|
127
|
+
fail("Herdr execution exceeded its transport deadline");
|
|
128
|
+
socket?.destroy();
|
|
129
|
+
finish();
|
|
130
|
+
}, (request.timeoutMs ?? 3600000) + Math.min(request.killGraceMs ?? 1500, 60000) + 7000);
|
|
131
|
+
request.signal?.addEventListener("abort", abort, { once: true });
|
|
132
|
+
try {
|
|
133
|
+
await new Promise((resolve, reject) => {
|
|
134
|
+
server.once("error", reject);
|
|
135
|
+
server.listen(path, resolve);
|
|
136
|
+
});
|
|
137
|
+
await chmod(path, 0o600);
|
|
138
|
+
if (request.signal?.aborted || (request.hardDeadlineAt !== undefined && request.hardDeadlineAt <= Date.now()))
|
|
139
|
+
return {
|
|
140
|
+
code: null,
|
|
141
|
+
text: "",
|
|
142
|
+
truncated: false,
|
|
143
|
+
timedOut: false,
|
|
144
|
+
aborted: true,
|
|
145
|
+
cleanup: { state: "not-started", reason: "cancelled before Herdr pane launch" },
|
|
146
|
+
};
|
|
147
|
+
const created = parseReply(await exec([
|
|
148
|
+
"tab",
|
|
149
|
+
"create",
|
|
150
|
+
"--cwd",
|
|
151
|
+
request.cwd,
|
|
152
|
+
"--label",
|
|
153
|
+
"pi-daddy governed child",
|
|
154
|
+
"--no-focus",
|
|
155
|
+
...(options.workspace ? ["--workspace", options.workspace] : []),
|
|
156
|
+
]));
|
|
157
|
+
if (created.error)
|
|
158
|
+
throw Error(created.error);
|
|
159
|
+
const pane = created.result?.root_pane;
|
|
160
|
+
tabId = pane?.tab_id;
|
|
161
|
+
if (!pane?.pane_id || !tabId)
|
|
162
|
+
throw Error("Herdr creation returned no exact pane/tab identity");
|
|
163
|
+
options.onPane?.(pane.pane_id, tabId);
|
|
164
|
+
if (error || request.signal?.aborted)
|
|
165
|
+
throw Error(error ?? "cancelled before Herdr command launch");
|
|
166
|
+
entered = true;
|
|
167
|
+
const launchReply = await exec([
|
|
168
|
+
"pane",
|
|
169
|
+
"run",
|
|
170
|
+
pane.pane_id,
|
|
171
|
+
(options.keepPane ? "" : "exec ") + [process.execPath, launcher, path, token].map(quote).join(" "),
|
|
172
|
+
]);
|
|
173
|
+
if (launchReply.code !== 0)
|
|
174
|
+
throw Error(parseReply(launchReply).error ?? "Herdr pane launch failed");
|
|
175
|
+
if (launchReply.stdout.trim()) {
|
|
176
|
+
const launched = parseReply(launchReply);
|
|
177
|
+
if (launched.error)
|
|
178
|
+
throw Error(launched.error);
|
|
179
|
+
}
|
|
180
|
+
await completed;
|
|
181
|
+
if (outcome?.cleanup?.state === "not-started" && !identity)
|
|
182
|
+
return outcome;
|
|
183
|
+
if (!outcome || !identity)
|
|
184
|
+
throw Error(error ?? "Herdr launcher closed without a complete result/ownership");
|
|
185
|
+
const receipt = await readCapturedWorkerReceipt(identity);
|
|
186
|
+
if (!receipt)
|
|
187
|
+
throw Error("Herdr worker supplied no independently verified cleanup receipt");
|
|
188
|
+
return { ...outcome, cleanup: { state: "settled", identity, receipt }, ...(error ? { spawnError: error } : {}) };
|
|
189
|
+
}
|
|
190
|
+
catch (cause) {
|
|
191
|
+
fail(cause);
|
|
192
|
+
socket?.destroy();
|
|
193
|
+
// Lost transport is never evidence of cleanup. Reconcile only the original bound receipt.
|
|
194
|
+
let receipt = identity ? await readCapturedWorkerReceipt(identity) : null;
|
|
195
|
+
const deadline = Date.now() + Math.min(request.killGraceMs ?? 1500, 60000) + 5500;
|
|
196
|
+
while (identity && !receipt && Date.now() < deadline) {
|
|
197
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
198
|
+
receipt = await readCapturedWorkerReceipt(identity);
|
|
199
|
+
}
|
|
200
|
+
return {
|
|
201
|
+
code: receipt?.workerCode ?? null,
|
|
202
|
+
text: "",
|
|
203
|
+
truncated: false,
|
|
204
|
+
timedOut: false,
|
|
205
|
+
aborted: Boolean(request.signal?.aborted),
|
|
206
|
+
spawnError: error ?? String(cause),
|
|
207
|
+
cleanup: identity && receipt
|
|
208
|
+
? { state: "settled", identity, receipt }
|
|
209
|
+
: entered
|
|
210
|
+
? { state: "unknown", ...(identity ? { identity } : {}), reason: error ?? String(cause) }
|
|
211
|
+
: { state: "not-started", reason: error ?? String(cause) },
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
finally {
|
|
215
|
+
done = true;
|
|
216
|
+
clearTimeout(timeout);
|
|
217
|
+
clearTimeout(startupTimer);
|
|
218
|
+
request.signal?.removeEventListener("abort", abort);
|
|
219
|
+
socket?.destroy();
|
|
220
|
+
await new Promise((resolve) => server.close(() => resolve()));
|
|
221
|
+
if (tabId && !options.keepPane) {
|
|
222
|
+
const closed = parseReply(await exec(["tab", "close", tabId]));
|
|
223
|
+
if (closed.error && !/tab .* not found|tab_not_found/.test(closed.error))
|
|
224
|
+
console.error("pi-daddy: settled worker pane could not close:", closed.error);
|
|
225
|
+
}
|
|
226
|
+
await rm(directory, { recursive: true, force: true });
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
//# sourceMappingURL=herdr-owned.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"herdr-owned.js","sourceRoot":"","sources":["../../src/executors/herdr-owned.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** Measured transport matrix. Reachability alone never qualifies a backend or changes execution location. */
|
|
2
|
+
import { type HerdrExec, type HerdrProbe } from "./herdr-cli.ts";
|
|
3
|
+
export declare const QUALIFIED_HERDR_VERSION = "0.8.2";
|
|
4
|
+
export declare const QUALIFIED_HERDR_PROTOCOL = 20;
|
|
5
|
+
export declare function qualifyHerdr(probe: HerdrProbe, exec?: HerdrExec): Promise<HerdrProbe>;
|
|
6
|
+
//# sourceMappingURL=herdr-qualification.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"herdr-qualification.d.ts","sourceRoot":"","sources":["../../src/executors/herdr-qualification.ts"],"names":[],"mappings":"AAAA,6GAA6G;AAC7G,OAAO,EAAe,KAAK,SAAS,EAAE,KAAK,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC9E,eAAO,MAAM,uBAAuB,UAAU,CAAC;AAC/C,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAC3C,wBAAsB,YAAY,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,GAAE,SAAuB,GAAG,OAAO,CAAC,UAAU,CAAC,CA4BxG"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/** Measured transport matrix. Reachability alone never qualifies a backend or changes execution location. */
|
|
2
|
+
import { defaultExec } from "./herdr-cli.js";
|
|
3
|
+
export const QUALIFIED_HERDR_VERSION = "0.8.2";
|
|
4
|
+
export const QUALIFIED_HERDR_PROTOCOL = 20;
|
|
5
|
+
export async function qualifyHerdr(probe, exec = defaultExec) {
|
|
6
|
+
if (!probe.ok)
|
|
7
|
+
return probe;
|
|
8
|
+
try {
|
|
9
|
+
if (process.platform !== "linux" || process.arch !== "x64")
|
|
10
|
+
throw Error("Herdr owned execution requires Linux x64");
|
|
11
|
+
const [client, server] = await Promise.all([exec(["--version"]), exec(["status", "server"])]);
|
|
12
|
+
if (client.code !== 0 || client.stdout.trim() !== "herdr " + QUALIFIED_HERDR_VERSION)
|
|
13
|
+
throw Error("Herdr client version is not qualified");
|
|
14
|
+
const fields = Object.fromEntries(server.stdout
|
|
15
|
+
.trim()
|
|
16
|
+
.split("\n")
|
|
17
|
+
.map((line) => {
|
|
18
|
+
const at = line.indexOf(":");
|
|
19
|
+
return [line.slice(0, at).trim(), line.slice(at + 1).trim()];
|
|
20
|
+
}));
|
|
21
|
+
if (server.code !== 0 ||
|
|
22
|
+
fields.status !== "running" ||
|
|
23
|
+
fields.version !== QUALIFIED_HERDR_VERSION ||
|
|
24
|
+
fields.protocol !== String(QUALIFIED_HERDR_PROTOCOL) ||
|
|
25
|
+
fields.compatible !== "yes")
|
|
26
|
+
throw Error("Herdr server version/protocol is not qualified");
|
|
27
|
+
return { ...probe, qualified: true };
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
return { ...probe, qualified: false, qualificationReason: String(error) };
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=herdr-qualification.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"herdr-qualification.js","sourceRoot":"","sources":["../../src/executors/herdr-qualification.ts"],"names":[],"mappings":"AAAA,6GAA6G;AAC7G,OAAO,EAAE,WAAW,EAAmC,MAAM,gBAAgB,CAAC;AAC9E,MAAM,CAAC,MAAM,uBAAuB,GAAG,OAAO,CAAC;AAC/C,MAAM,CAAC,MAAM,wBAAwB,GAAG,EAAE,CAAC;AAC3C,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,KAAiB,EAAE,OAAkB,WAAW;IACjF,IAAI,CAAC,KAAK,CAAC,EAAE;QAAE,OAAO,KAAK,CAAC;IAC5B,IAAI,CAAC;QACH,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,IAAI,OAAO,CAAC,IAAI,KAAK,KAAK;YAAE,MAAM,KAAK,CAAC,0CAA0C,CAAC,CAAC;QACpH,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9F,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,QAAQ,GAAG,uBAAuB;YAClF,MAAM,KAAK,CAAC,uCAAuC,CAAC,CAAC;QACvD,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAC/B,MAAM,CAAC,MAAM;aACV,IAAI,EAAE;aACN,KAAK,CAAC,IAAI,CAAC;aACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;YACZ,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YAC7B,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAC/D,CAAC,CAAC,CACL,CAAC;QACF,IACE,MAAM,CAAC,IAAI,KAAK,CAAC;YACjB,MAAM,CAAC,MAAM,KAAK,SAAS;YAC3B,MAAM,CAAC,OAAO,KAAK,uBAAuB;YAC1C,MAAM,CAAC,QAAQ,KAAK,MAAM,CAAC,wBAAwB,CAAC;YACpD,MAAM,CAAC,UAAU,KAAK,KAAK;YAE3B,MAAM,KAAK,CAAC,gDAAgD,CAAC,CAAC;QAChE,OAAO,EAAE,GAAG,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IACvC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,EAAE,GAAG,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,mBAAmB,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;IAC5E,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** Bounded local framing; this channel carries private execution input only between its two owners. */
|
|
2
|
+
import type { Socket } from "node:net";
|
|
3
|
+
export declare const HERDR_WIRE_LIMIT: number;
|
|
4
|
+
export declare function wire(socket: Socket, receive: (value: any) => void, failed: (error: Error) => void): (value: unknown) => void;
|
|
5
|
+
//# sourceMappingURL=herdr-wire.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"herdr-wire.d.ts","sourceRoot":"","sources":["../../src/executors/herdr-wire.ts"],"names":[],"mappings":"AAAA,uGAAuG;AACvG,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AACvC,eAAO,MAAM,gBAAgB,QAAkB,CAAC;AAChD,wBAAgB,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,EAAE,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,IAgCxF,OAAO,OAAO,UAOvB"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export const HERDR_WIRE_LIMIT = 8 * 1024 * 1024;
|
|
2
|
+
export function wire(socket, receive, failed) {
|
|
3
|
+
let pending = "";
|
|
4
|
+
const decoder = new TextDecoder("utf-8", { fatal: true });
|
|
5
|
+
const fail = (error) => {
|
|
6
|
+
failed(error instanceof Error ? error : new Error(String(error)));
|
|
7
|
+
socket.destroy();
|
|
8
|
+
};
|
|
9
|
+
socket.on("data", (bytes) => {
|
|
10
|
+
try {
|
|
11
|
+
pending += decoder.decode(bytes, { stream: true });
|
|
12
|
+
let end;
|
|
13
|
+
while ((end = pending.indexOf("\n")) >= 0) {
|
|
14
|
+
if (Buffer.byteLength(pending.slice(0, end)) > HERDR_WIRE_LIMIT)
|
|
15
|
+
throw Error("Herdr transport record exceeds bound");
|
|
16
|
+
const line = pending.slice(0, end);
|
|
17
|
+
pending = pending.slice(end + 1);
|
|
18
|
+
receive(JSON.parse(line));
|
|
19
|
+
}
|
|
20
|
+
if (Buffer.byteLength(pending) > HERDR_WIRE_LIMIT)
|
|
21
|
+
throw Error("Herdr transport record exceeds bound");
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
fail(error);
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
socket.on("end", () => {
|
|
28
|
+
try {
|
|
29
|
+
pending += decoder.decode();
|
|
30
|
+
if (pending)
|
|
31
|
+
throw Error("Herdr transport record is incomplete");
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
fail(error);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
socket.on("error", (error) => failed(error));
|
|
38
|
+
return (value) => {
|
|
39
|
+
const text = JSON.stringify(value) + "\n";
|
|
40
|
+
if (Buffer.byteLength(text) > HERDR_WIRE_LIMIT || socket.writableLength > HERDR_WIRE_LIMIT * 2)
|
|
41
|
+
throw Error("Herdr transport buffering exceeds bound");
|
|
42
|
+
if (socket.destroyed || !socket.writable)
|
|
43
|
+
throw Error("Herdr transport is closed");
|
|
44
|
+
socket.write(text);
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=herdr-wire.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"herdr-wire.js","sourceRoot":"","sources":["../../src/executors/herdr-wire.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;AAChD,MAAM,UAAU,IAAI,CAAC,MAAc,EAAE,OAA6B,EAAE,MAA8B;IAChG,IAAI,OAAO,GAAG,EAAE,CAAC;IACjB,MAAM,OAAO,GAAG,IAAI,WAAW,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1D,MAAM,IAAI,GAAG,CAAC,KAAc,EAAE,EAAE;QAC9B,MAAM,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAClE,MAAM,CAAC,OAAO,EAAE,CAAC;IACnB,CAAC,CAAC;IACF,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;QAC1B,IAAI,CAAC;YACH,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;YACnD,IAAI,GAAW,CAAC;YAChB,OAAO,CAAC,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC1C,IAAI,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,gBAAgB;oBAC7D,MAAM,KAAK,CAAC,sCAAsC,CAAC,CAAC;gBACtD,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;gBACnC,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;gBACjC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;YAC5B,CAAC;YACD,IAAI,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,gBAAgB;gBAAE,MAAM,KAAK,CAAC,sCAAsC,CAAC,CAAC;QACzG,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,KAAK,CAAC,CAAC;QACd,CAAC;IACH,CAAC,CAAC,CAAC;IACH,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;QACpB,IAAI,CAAC;YACH,OAAO,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YAC5B,IAAI,OAAO;gBAAE,MAAM,KAAK,CAAC,sCAAsC,CAAC,CAAC;QACnE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,KAAK,CAAC,CAAC;QACd,CAAC;IACH,CAAC,CAAC,CAAC;IACH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IAC7C,OAAO,CAAC,KAAc,EAAE,EAAE;QACxB,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;QAC1C,IAAI,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,gBAAgB,IAAI,MAAM,CAAC,cAAc,GAAG,gBAAgB,GAAG,CAAC;YAC5F,MAAM,KAAK,CAAC,yCAAyC,CAAC,CAAC;QACzD,IAAI,MAAM,CAAC,SAAS,IAAI,CAAC,MAAM,CAAC,QAAQ;YAAE,MAAM,KAAK,CAAC,2BAA2B,CAAC,CAAC;QACnF,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACrB,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-settlement-lock.d.ts","sourceRoot":"","sources":["../../src/governance/runtime-settlement-lock.ts"],"names":[],"mappings":"AAGA,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,OAAO,IAAI,OAAO,CAAC;IAAC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAAC,CAwEnH"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/** An OS-held single-writer lock; parent pipe loss releases it without stale-age guesses. */
|
|
2
|
+
import { spawn } from "node:child_process";
|
|
3
|
+
import { constants, openSync, closeSync, fstatSync } from "node:fs";
|
|
4
|
+
export async function lockRuntimeSettlement(path) {
|
|
5
|
+
const fd = openSync(path, constants.O_CREAT | constants.O_RDWR | constants.O_NOFOLLOW, 0o600);
|
|
6
|
+
const info = fstatSync(fd);
|
|
7
|
+
if (!info.isFile() || info.uid !== process.getuid() || info.mode & 0o077) {
|
|
8
|
+
closeSync(fd);
|
|
9
|
+
throw Error("runtime lock is not a private ordinary file");
|
|
10
|
+
}
|
|
11
|
+
const child = spawn("/usr/bin/flock", [
|
|
12
|
+
"--no-fork",
|
|
13
|
+
"--wait",
|
|
14
|
+
"1",
|
|
15
|
+
"/proc/self/fd/3",
|
|
16
|
+
process.execPath,
|
|
17
|
+
"-e",
|
|
18
|
+
'process.stdout.write("locked\\n");process.stdin.resume();process.stdin.on("end",()=>process.exit(0));',
|
|
19
|
+
], { stdio: ["pipe", "pipe", "ignore", fd] });
|
|
20
|
+
closeSync(fd);
|
|
21
|
+
let healthy = false, line = "";
|
|
22
|
+
await new Promise((resolve, reject) => {
|
|
23
|
+
const timer = setTimeout(() => {
|
|
24
|
+
child.stdin?.destroy();
|
|
25
|
+
child.kill();
|
|
26
|
+
reject(Error("runtime ownership lock timed out"));
|
|
27
|
+
}, 3000);
|
|
28
|
+
child.on("error", (error) => {
|
|
29
|
+
clearTimeout(timer);
|
|
30
|
+
reject(error);
|
|
31
|
+
});
|
|
32
|
+
child.on("exit", () => {
|
|
33
|
+
healthy = false;
|
|
34
|
+
clearTimeout(timer);
|
|
35
|
+
reject(Error("another live runtime owns this Pi session"));
|
|
36
|
+
});
|
|
37
|
+
child.stdout?.on("data", (bytes) => {
|
|
38
|
+
line += bytes.toString();
|
|
39
|
+
if (line === "locked\n") {
|
|
40
|
+
healthy = true;
|
|
41
|
+
clearTimeout(timer);
|
|
42
|
+
resolve();
|
|
43
|
+
}
|
|
44
|
+
else if (line.length > 16) {
|
|
45
|
+
clearTimeout(timer);
|
|
46
|
+
child.stdin?.destroy();
|
|
47
|
+
reject(Error("runtime lock returned malformed readiness"));
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
child.unref();
|
|
52
|
+
child.stdin.unref();
|
|
53
|
+
child.stdout.unref();
|
|
54
|
+
let releasing;
|
|
55
|
+
return {
|
|
56
|
+
healthy: () => healthy && child.exitCode === null && child.signalCode === null,
|
|
57
|
+
release: () => (releasing ??= new Promise((resolve) => {
|
|
58
|
+
healthy = false;
|
|
59
|
+
if (child.exitCode !== null || child.signalCode !== null) {
|
|
60
|
+
resolve();
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
const timer = setTimeout(() => child.kill("SIGKILL"), 1000);
|
|
64
|
+
child.once("close", () => {
|
|
65
|
+
clearTimeout(timer);
|
|
66
|
+
resolve();
|
|
67
|
+
});
|
|
68
|
+
child.stdin?.end();
|
|
69
|
+
})),
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=runtime-settlement-lock.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-settlement-lock.js","sourceRoot":"","sources":["../../src/governance/runtime-settlement-lock.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { CapturedWorkerCleanup, CapturedWorkerIdentity } from "../kernel/captured-worker-contract.ts";
|
|
2
|
+
export declare const settlementHash: (value: unknown) => string;
|
|
3
|
+
export interface RuntimeSettlement {
|
|
4
|
+
readonly ownerScope: string;
|
|
5
|
+
readonly ownerId: string;
|
|
6
|
+
readonly sessionId: string;
|
|
7
|
+
readonly cwd: string;
|
|
8
|
+
begin(id: string): void;
|
|
9
|
+
bind(identity: CapturedWorkerIdentity): void;
|
|
10
|
+
finish(id: string, cleanup: CapturedWorkerCleanup, problem?: string): Promise<void>;
|
|
11
|
+
snapshot(): Promise<{
|
|
12
|
+
ownerScope: string;
|
|
13
|
+
ownerId: string;
|
|
14
|
+
evidenceDigest: string;
|
|
15
|
+
state: "idle" | "busy" | "unknown";
|
|
16
|
+
settledExecutionIds: string[];
|
|
17
|
+
outstandingExecutionIds: string[];
|
|
18
|
+
reason?: string;
|
|
19
|
+
}>;
|
|
20
|
+
}
|
|
21
|
+
export declare function openRuntimeSettlement(directory: string, sessionId: string, cwd: string): Promise<RuntimeSettlement>;
|
|
22
|
+
//# sourceMappingURL=runtime-settlement.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-settlement.d.ts","sourceRoot":"","sources":["../../src/governance/runtime-settlement.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AAkB3G,eAAO,MAAM,cAAc,GAAI,OAAO,OAAO,KAAG,MACkB,CAAC;AAsDnE,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,IAAI,CAAC,QAAQ,EAAE,sBAAsB,GAAG,IAAI,CAAC;IAC7C,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,qBAAqB,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpF,QAAQ,IAAI,OAAO,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,OAAO,EAAE,MAAM,CAAC;QAChB,cAAc,EAAE,MAAM,CAAC;QACvB,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;QACnC,mBAAmB,EAAE,MAAM,EAAE,CAAC;QAC9B,uBAAuB,EAAE,MAAM,EAAE,CAAC;QAClC,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC,CAAC;CACJ;AACD,wBAAsB,qBAAqB,CACzC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,iBAAiB,CAAC,CA6J5B"}
|