@oxagen/cli 3.0.0 → 3.0.1-27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -7
- package/oxagen.mjs +933 -536
- package/package.json +2 -2
package/oxagen.mjs
CHANGED
|
@@ -4582,7 +4582,7 @@ function member(kind) {
|
|
|
4582
4582
|
function parseTachoEvent(value) {
|
|
4583
4583
|
return tachoEventSchema.parse(value);
|
|
4584
4584
|
}
|
|
4585
|
-
var TACHO_ENVELOPE_VERSION, digest, str, short, u8, u16, u32, u64, bool, ts, json, TACHO_RUNTIMES, TACHO_FIDELITIES, TACHO_SOURCES, ENFORCEMENT_TIERS, TOOL_STATUSES, POLICY_DECISIONS, POLICY_SOURCES, EFFECT_KINDS, GAP_CAUSES, INCIDENT_KINDS, TOKEN_SOURCE_BASES, SYSTEM_CONTEXT_PART_KINDS, SYSTEM_CONTEXT_PARTS_MAX, systemContextPartSchema, toolFacts, modelFacts, TOKEN_SOURCE_COUNTS, promptFacts, policyFacts, subagentFacts, SUBAGENT_CHAINLESS_ATTR, healthFacts, lifecycleFacts, integrityFacts, MAX_OBSERVED_CHANGES, observedChangeSchema, MAX_SESSION_COMMIT_ITEMS, MAX_COMMIT_FILES, MAX_COMMIT_PARENTS, MAX_COMMIT_SUBJECT, commitName, sessionCommitFileSchema, sessionCommitSchema, observationFacts, inventoryFacts, totalsFacts, allFacts, BODY_MEMBER_NAMES, BODY_FACTS_SHAPE, pick, toolKeys, modelKeys, promptKeys, policyKeys, subagentKeys, healthKeys, lifecycleKeys, integrityKeys, inventoryKeys, totalsKeys, observationKeys, KIND_BODIES, TACHO_KINDS, agentIdentitySchema, subagentIdentitySchema, turnRefSchema, contextSchema, hostSchema, anthropicSchema, ADDRESS_MEMBERS, spanSchema, MAX_CONTENT_REDACTIONS, contentSchema, envelopeBase, members, TOKEN_SOURCE_KINDS, tachoRecordedEventSchema, tachoEventSchema;
|
|
4585
|
+
var TACHO_ENVELOPE_VERSION, digest, str, short, u8, u16, u32, u64, i32, bool, ts, json, TACHO_RUNTIMES, TACHO_FIDELITIES, TACHO_SOURCES, ENFORCEMENT_TIERS, TOOL_STATUSES, POLICY_DECISIONS, POLICY_SOURCES, EFFECT_KINDS, GAP_CAUSES, INCIDENT_KINDS, TOKEN_SOURCE_BASES, SYSTEM_CONTEXT_PART_KINDS, SYSTEM_CONTEXT_PARTS_MAX, systemContextPartSchema, toolFacts, modelFacts, TOKEN_SOURCE_COUNTS, promptFacts, policyFacts, subagentFacts, SUBAGENT_CHAINLESS_ATTR, healthFacts, lifecycleFacts, integrityFacts, MAX_OBSERVED_CHANGES, observedChangeSchema, MAX_SESSION_COMMIT_ITEMS, MAX_COMMIT_FILES, MAX_COMMIT_PARENTS, MAX_COMMIT_SUBJECT, commitName, sessionCommitFileSchema, sessionCommitSchema, observationFacts, inventoryFacts, totalsFacts, allFacts, BODY_MEMBER_NAMES, BODY_FACTS_SHAPE, pick, toolKeys, modelKeys, promptKeys, policyKeys, subagentKeys, healthKeys, lifecycleKeys, integrityKeys, inventoryKeys, totalsKeys, observationKeys, KIND_BODIES, TACHO_KINDS, agentIdentitySchema, subagentIdentitySchema, turnRefSchema, contextSchema, hostSchema, anthropicSchema, ADDRESS_MEMBERS, spanSchema, MAX_CONTENT_REDACTIONS, contentSchema, envelopeBase, members, TOKEN_SOURCE_KINDS, tachoRecordedEventSchema, tachoEventSchema;
|
|
4586
4586
|
var init_envelope = __esm({
|
|
4587
4587
|
"../../packages/tacho/src/envelope.ts"() {
|
|
4588
4588
|
"use strict";
|
|
@@ -4597,6 +4597,7 @@ var init_envelope = __esm({
|
|
|
4597
4597
|
u16 = external_exports.number().int().min(0).max(65535);
|
|
4598
4598
|
u32 = external_exports.number().int().min(0).max(4294967295);
|
|
4599
4599
|
u64 = external_exports.number().int().min(0).max(Number.MAX_SAFE_INTEGER);
|
|
4600
|
+
i32 = external_exports.number().int().min(-2147483648).max(2147483647);
|
|
4600
4601
|
bool = external_exports.boolean();
|
|
4601
4602
|
ts = external_exports.string().refine(isProtocolTimestamp, "protocol timestamp");
|
|
4602
4603
|
json = external_exports.unknown();
|
|
@@ -4704,6 +4705,15 @@ var init_envelope = __esm({
|
|
|
4704
4705
|
tool_status: external_exports.enum(TOOL_STATUSES).optional(),
|
|
4705
4706
|
tool_error_class: short.optional(),
|
|
4706
4707
|
tool_error_message_digest: digest.optional(),
|
|
4708
|
+
/**
|
|
4709
|
+
* The exit code a shell command ended with, as the harness reported it
|
|
4710
|
+
* (#7158). Claude Code writes it at the start of a failed call's error
|
|
4711
|
+
* text ("Exit code 1"), Codex in its `exec_command_end` record, and Cursor
|
|
4712
|
+
* in `afterShellExecution`. Signed, because a process killed by a signal
|
|
4713
|
+
* can report a negative code. Absent when the harness did not say, which
|
|
4714
|
+
* is not the same as zero.
|
|
4715
|
+
*/
|
|
4716
|
+
tool_exit_code: i32.optional(),
|
|
4707
4717
|
tool_duration_ms: u32.optional(),
|
|
4708
4718
|
tool_blocked_on_user_ms: u32.optional(),
|
|
4709
4719
|
tool_is_mutating: bool.optional(),
|
|
@@ -8242,7 +8252,7 @@ function verifyBundle(bundle2, publicKeyPem, expectedHostEnrollmentId) {
|
|
|
8242
8252
|
createPublicKey(publicKeyPem),
|
|
8243
8253
|
Buffer.from(signature.sig, "base64")
|
|
8244
8254
|
);
|
|
8245
|
-
if (!ok) return { ok, reason: "
|
|
8255
|
+
if (!ok) return { ok, reason: "the lock does not verify" };
|
|
8246
8256
|
if (expectedHostEnrollmentId !== void 0 && bundle2.host_enrollment_id !== expectedHostEnrollmentId) {
|
|
8247
8257
|
return {
|
|
8248
8258
|
ok: false,
|
|
@@ -10398,6 +10408,7 @@ var init_paths = __esm({
|
|
|
10398
10408
|
backfillCursor: "backfill-cursor.json",
|
|
10399
10409
|
memoryCounts: "memory-counts.json",
|
|
10400
10410
|
stellaMemoryCursors: "stella-memory-cursors.json",
|
|
10411
|
+
memorySent: "memory-sent.json",
|
|
10401
10412
|
preSessionCopies: "pre-session",
|
|
10402
10413
|
stellaIdentity: "stella-identity",
|
|
10403
10414
|
workOrders: "work-orders"
|
|
@@ -10704,7 +10715,7 @@ function verifyBytes(pinned, bytes, signature) {
|
|
|
10704
10715
|
return ok ? { ok } : {
|
|
10705
10716
|
ok,
|
|
10706
10717
|
reason: "signature_invalid",
|
|
10707
|
-
detail: "
|
|
10718
|
+
detail: "the lock does not verify"
|
|
10708
10719
|
};
|
|
10709
10720
|
} catch (error) {
|
|
10710
10721
|
return {
|
|
@@ -10793,7 +10804,7 @@ function verifyKeySet(set, pinned) {
|
|
|
10793
10804
|
let last = {
|
|
10794
10805
|
ok: false,
|
|
10795
10806
|
reason: "unknown_kid",
|
|
10796
|
-
detail: "no
|
|
10807
|
+
detail: "no lock on the key set is by a pinned key"
|
|
10797
10808
|
};
|
|
10798
10809
|
for (const signature of signatures) {
|
|
10799
10810
|
if (!pinned.has(signature.kid)) continue;
|
|
@@ -14616,6 +14627,9 @@ var init_llm_call_dedupe = __esm({
|
|
|
14616
14627
|
});
|
|
14617
14628
|
|
|
14618
14629
|
// ../../packages/tacho/src/claude-code/backfill.ts
|
|
14630
|
+
function isMidTurnMessage(record) {
|
|
14631
|
+
return record["type"] === "attachment" && nonEmptyString(asRecord(record["attachment"])?.["type"]) === "queued_command";
|
|
14632
|
+
}
|
|
14619
14633
|
function emptyTally() {
|
|
14620
14634
|
return {
|
|
14621
14635
|
lines: 0,
|
|
@@ -14781,7 +14795,7 @@ var init_backfill = __esm({
|
|
|
14781
14795
|
init_record_basis();
|
|
14782
14796
|
init_context();
|
|
14783
14797
|
init_llm_call_dedupe();
|
|
14784
|
-
BACKFILL_NORMALIZER_VERSION = "
|
|
14798
|
+
BACKFILL_NORMALIZER_VERSION = "2";
|
|
14785
14799
|
TESTED_CLAUDE_CODE_VERSIONS = {
|
|
14786
14800
|
lowest: "2.1.263",
|
|
14787
14801
|
highest: "2.1.281"
|
|
@@ -15103,11 +15117,12 @@ var init_backfill = __esm({
|
|
|
15103
15117
|
count2(this.tally.drift.unknownTypes, "(none)");
|
|
15104
15118
|
return void 0;
|
|
15105
15119
|
}
|
|
15106
|
-
|
|
15120
|
+
const mapped = MAPPED_TYPES.has(type) || isMidTurnMessage(value);
|
|
15121
|
+
if (!mapped && (IGNORED_TYPES.has(type) || type.startsWith("artifact-"))) {
|
|
15107
15122
|
count2(this.tally.recordsIgnored, type);
|
|
15108
15123
|
return void 0;
|
|
15109
15124
|
}
|
|
15110
|
-
if (!
|
|
15125
|
+
if (!mapped) {
|
|
15111
15126
|
count2(this.tally.drift.unknownTypes, type);
|
|
15112
15127
|
return void 0;
|
|
15113
15128
|
}
|
|
@@ -17516,6 +17531,15 @@ var init_result = __esm({
|
|
|
17516
17531
|
});
|
|
17517
17532
|
|
|
17518
17533
|
// ../../packages/tacho/src/claude-code/transcript.ts
|
|
17534
|
+
function queuedText(value) {
|
|
17535
|
+
if (typeof value === "string") return value.length > 0 ? value : void 0;
|
|
17536
|
+
if (!Array.isArray(value)) return void 0;
|
|
17537
|
+
const text5 = value.map((block) => {
|
|
17538
|
+
const item = rec3(block);
|
|
17539
|
+
return s(item?.["type"]) === "text" ? s(item?.["text"]) : void 0;
|
|
17540
|
+
}).filter((t) => t !== void 0 && t.length > 0).join("\n");
|
|
17541
|
+
return text5.length > 0 ? text5 : void 0;
|
|
17542
|
+
}
|
|
17519
17543
|
function rec3(value) {
|
|
17520
17544
|
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
17521
17545
|
}
|
|
@@ -17830,6 +17854,34 @@ function normalizeTranscriptLine(line, fallbackTs) {
|
|
|
17830
17854
|
],
|
|
17831
17855
|
totals: {}
|
|
17832
17856
|
};
|
|
17857
|
+
case "attachment": {
|
|
17858
|
+
const attachment = rec3(record["attachment"]);
|
|
17859
|
+
if (s(attachment?.["type"]) !== QUEUED_COMMAND)
|
|
17860
|
+
return { drafts: [], totals: {} };
|
|
17861
|
+
const prompt = queuedText(attachment?.["prompt"]);
|
|
17862
|
+
if (prompt === void 0) return { drafts: [], totals: {} };
|
|
17863
|
+
const origin = promptOriginOf(attachment?.["origin"]);
|
|
17864
|
+
return {
|
|
17865
|
+
drafts: [
|
|
17866
|
+
{
|
|
17867
|
+
...draft(
|
|
17868
|
+
"oxagen:message",
|
|
17869
|
+
{
|
|
17870
|
+
prompt_digest: digestText(prompt),
|
|
17871
|
+
prompt_length: prompt.length,
|
|
17872
|
+
...defined({
|
|
17873
|
+
prompt_origin: origin,
|
|
17874
|
+
message_uuid: s(record["uuid"])
|
|
17875
|
+
})
|
|
17876
|
+
},
|
|
17877
|
+
{ [PROMPT_DELIVERY_ATTR]: MID_TURN_DELIVERY }
|
|
17878
|
+
),
|
|
17879
|
+
content: textContent(prompt)
|
|
17880
|
+
}
|
|
17881
|
+
],
|
|
17882
|
+
totals: {}
|
|
17883
|
+
};
|
|
17884
|
+
}
|
|
17833
17885
|
case "queue-operation": {
|
|
17834
17886
|
const queued = s(record["content"]);
|
|
17835
17887
|
return {
|
|
@@ -17898,7 +17950,7 @@ function normalizeTranscriptLine(line, fallbackTs) {
|
|
|
17898
17950
|
return { drafts: [], totals: {} };
|
|
17899
17951
|
}
|
|
17900
17952
|
}
|
|
17901
|
-
var SESSION_TITLE_MAX, INTERRUPT_MARKER2;
|
|
17953
|
+
var PROMPT_DELIVERY_ATTR, MID_TURN_DELIVERY, QUEUED_COMMAND, SESSION_TITLE_MAX, INTERRUPT_MARKER2;
|
|
17902
17954
|
var init_transcript = __esm({
|
|
17903
17955
|
"../../packages/tacho/src/claude-code/transcript.ts"() {
|
|
17904
17956
|
"use strict";
|
|
@@ -17908,6 +17960,9 @@ var init_transcript = __esm({
|
|
|
17908
17960
|
init_context();
|
|
17909
17961
|
init_payload_members();
|
|
17910
17962
|
init_tools();
|
|
17963
|
+
PROMPT_DELIVERY_ATTR = "oxagen.prompt_delivery";
|
|
17964
|
+
MID_TURN_DELIVERY = "mid_turn";
|
|
17965
|
+
QUEUED_COMMAND = "queued_command";
|
|
17911
17966
|
SESSION_TITLE_MAX = 512;
|
|
17912
17967
|
INTERRUPT_MARKER2 = "[Request interrupted by user";
|
|
17913
17968
|
}
|
|
@@ -22704,7 +22759,7 @@ function progressLine(report) {
|
|
|
22704
22759
|
function reportLines(report) {
|
|
22705
22760
|
const lines = [];
|
|
22706
22761
|
lines.push(
|
|
22707
|
-
report.dry_run ? `Dry run with normalizer ${report.normalizer_version}. Nothing was
|
|
22762
|
+
report.dry_run ? `Dry run with normalizer ${report.normalizer_version}. Nothing was locked or sent.` : `Backfill with normalizer ${report.normalizer_version}.`
|
|
22708
22763
|
);
|
|
22709
22764
|
lines.push("", "Projects");
|
|
22710
22765
|
for (const project2 of report.projects) {
|
|
@@ -22783,7 +22838,7 @@ function reportLines(report) {
|
|
|
22783
22838
|
}
|
|
22784
22839
|
lines.push(
|
|
22785
22840
|
"",
|
|
22786
|
-
`Bodies: the workspace keeps ${report.bodies.mode === "content_exact" ? "content" : "
|
|
22841
|
+
`Bodies: the workspace keeps ${report.bodies.mode === "content_exact" ? "content" : "hashes only"}, and ${number(report.bodies.shipped)} bodies ${report.dry_run ? "would be sent" : "were queued to send"}.`
|
|
22787
22842
|
);
|
|
22788
22843
|
return lines;
|
|
22789
22844
|
}
|
|
@@ -26331,7 +26386,7 @@ async function restoreCredentials(host, deps, mode = "unenroll", only) {
|
|
|
26331
26386
|
continue;
|
|
26332
26387
|
}
|
|
26333
26388
|
warnings.push(
|
|
26334
|
-
`the ${provider} credential in custody cannot be read (${unreadable}). ${label2}'s run token was taken out anyway, since the gateway it worked at is being removed; set the ${provider} key in ${label2} by hand. The
|
|
26389
|
+
`the ${provider} credential in custody cannot be read (${unreadable}). ${label2}'s run token was taken out anyway, since the gateway it worked at is being removed; set the ${provider} key in ${label2} by hand. The encrypted store is left at ${deps.paths.credentials} in case the key file can be repaired`
|
|
26335
26390
|
);
|
|
26336
26391
|
}
|
|
26337
26392
|
const state = await contract.restore(
|
|
@@ -26393,7 +26448,10 @@ async function acquireSubscriptionToken(options, deps) {
|
|
|
26393
26448
|
const run3 = await io.runSetupToken(
|
|
26394
26449
|
claude,
|
|
26395
26450
|
(chunk2) => process.stdout.write(
|
|
26396
|
-
chunk2.replace(
|
|
26451
|
+
chunk2.replace(
|
|
26452
|
+
/sk-ant-oat[A-Za-z0-9_-]*/g,
|
|
26453
|
+
"sk-ant-oat\u2026 (sent to Oxagen)"
|
|
26454
|
+
)
|
|
26397
26455
|
)
|
|
26398
26456
|
);
|
|
26399
26457
|
if (run3.token !== void 0)
|
|
@@ -26490,9 +26548,7 @@ async function ensureCodexLogin(deps) {
|
|
|
26490
26548
|
}
|
|
26491
26549
|
async function codexLogin(deps) {
|
|
26492
26550
|
const store = deps.credentialStore;
|
|
26493
|
-
const held = store?.status().some(
|
|
26494
|
-
(c) => c.provider === "openai" && c.kind === "chatgpt"
|
|
26495
|
-
);
|
|
26551
|
+
const held = store?.status().some((c) => c.provider === "openai" && c.kind === "chatgpt");
|
|
26496
26552
|
if (held !== true) {
|
|
26497
26553
|
const why = await ensureCodexLogin(deps);
|
|
26498
26554
|
if (why !== void 0)
|
|
@@ -26569,10 +26625,7 @@ var init_credential = __esm({
|
|
|
26569
26625
|
MODEL_CREDENTIAL_HARNESSES = [
|
|
26570
26626
|
...BROKERABLE_HARNESSES
|
|
26571
26627
|
];
|
|
26572
|
-
CREDENTIAL_MODES = [
|
|
26573
|
-
"brokered",
|
|
26574
|
-
"passthrough"
|
|
26575
|
-
];
|
|
26628
|
+
CREDENTIAL_MODES = ["brokered", "passthrough"];
|
|
26576
26629
|
STELLA_ANTHROPIC_KEY_ENV = "ANTHROPIC_API_KEY";
|
|
26577
26630
|
CLAUDE_OAUTH_TOKEN_ENV = "CLAUDE_CODE_OAUTH_TOKEN";
|
|
26578
26631
|
}
|
|
@@ -27344,7 +27397,7 @@ import { readFileSync as readFileSync10 } from "node:fs";
|
|
|
27344
27397
|
import { dirname as dirname9, resolve as resolve3 } from "node:path";
|
|
27345
27398
|
import { fileURLToPath } from "node:url";
|
|
27346
27399
|
function readVersion() {
|
|
27347
|
-
if (true) return "3.0.
|
|
27400
|
+
if (true) return "3.0.1-27";
|
|
27348
27401
|
try {
|
|
27349
27402
|
const here = dirname9(fileURLToPath(import.meta.url));
|
|
27350
27403
|
const pkg = JSON.parse(
|
|
@@ -32786,7 +32839,7 @@ function printStatus(report, deps) {
|
|
|
32786
32839
|
);
|
|
32787
32840
|
if (claudeDesktop.otherServers > 0)
|
|
32788
32841
|
deps.out(
|
|
32789
|
-
` ${claudeDesktop.otherServers} other MCP server(s): ${claudeDesktop.otherServerNames.join(", ")}
|
|
32842
|
+
` ${claudeDesktop.otherServers} other MCP server(s): ${claudeDesktop.otherServerNames.join(", ")}. Oxagen does not see what they serve`
|
|
32790
32843
|
);
|
|
32791
32844
|
}
|
|
32792
32845
|
if (codexHooks !== void 0) {
|
|
@@ -33423,6 +33476,7 @@ async function unenrollLocked(options, deps) {
|
|
|
33423
33476
|
deps.paths.backfillCursor,
|
|
33424
33477
|
deps.paths.memoryCounts,
|
|
33425
33478
|
deps.paths.stellaMemoryCursors,
|
|
33479
|
+
deps.paths.memorySent,
|
|
33426
33480
|
deps.paths.pid,
|
|
33427
33481
|
deps.paths.daemonLauncher
|
|
33428
33482
|
])
|
|
@@ -34444,7 +34498,7 @@ ${problems.map((problem) => ` ${problem}`).join("\n")}`
|
|
|
34444
34498
|
if (merged.changed) {
|
|
34445
34499
|
deps.writeStellaHooks(merged.file);
|
|
34446
34500
|
deps.out(
|
|
34447
|
-
` hooks written for ${stellaHookPresence(merged.file, host.host_enrollment_id).present.length} events (${file.format === "toml" ? "a managed block at the end of stella.toml; the rest of the file is untouched" : "command hooks in settings.json"}; Stella has no SessionEnd, so tachod
|
|
34501
|
+
` hooks written for ${stellaHookPresence(merged.file, host.host_enrollment_id).present.length} events (${file.format === "toml" ? "a managed block at the end of stella.toml; the rest of the file is untouched" : "command hooks in settings.json"}; Stella has no SessionEnd, so tachod locks a session's record when the stella process exits)`
|
|
34448
34502
|
);
|
|
34449
34503
|
} else {
|
|
34450
34504
|
deps.out(" already present; nothing to change");
|
|
@@ -34787,7 +34841,7 @@ ${problems.map((problem) => ` ${problem}`).join("\n")}`
|
|
|
34787
34841
|
}
|
|
34788
34842
|
if (!existsSync16(deps.paths.deviceKey))
|
|
34789
34843
|
warnings.push(
|
|
34790
|
-
`the device key is missing from ${deps.paths.deviceKey} after enrollment, so the daemon cannot
|
|
34844
|
+
`the device key is missing from ${deps.paths.deviceKey} after enrollment, so the daemon cannot lock what this machine sends; run \`oxagen agent enroll --force\` to enroll it again`
|
|
34791
34845
|
);
|
|
34792
34846
|
for (const warning of warnings) deps.err(`warning: ${warning}`);
|
|
34793
34847
|
const hooked = harnesses.filter((harness) => !unhooked.includes(harness));
|
|
@@ -35430,7 +35484,7 @@ async function exportCommand(options, deps) {
|
|
|
35430
35484
|
const events = wal.read(uuid);
|
|
35431
35485
|
const first = events[0];
|
|
35432
35486
|
const last = events[events.length - 1];
|
|
35433
|
-
return `${uuid} ${first?.session_id ?? "?"} ${events.length} events ${first?.ts ?? ""} .. ${last?.ts ?? ""}${last?.kind === "agent_stop" ? "
|
|
35487
|
+
return `${uuid} ${first?.session_id ?? "?"} ${events.length} events ${first?.ts ?? ""} .. ${last?.ts ?? ""}${last?.kind === "agent_stop" ? " locked" : ""}`;
|
|
35434
35488
|
})
|
|
35435
35489
|
);
|
|
35436
35490
|
deps.out(
|
|
@@ -36426,7 +36480,7 @@ async function verify4(options, rootDeps) {
|
|
|
36426
36480
|
};
|
|
36427
36481
|
}
|
|
36428
36482
|
deps.err(
|
|
36429
|
-
`Session ${found.session_id} chained as ${found.session_uuid}: ${found.seq} events,
|
|
36483
|
+
`Session ${found.session_id} chained as ${found.session_uuid}: ${found.seq} events, locked.`
|
|
36430
36484
|
);
|
|
36431
36485
|
return {
|
|
36432
36486
|
ok: true,
|
|
@@ -36454,12 +36508,12 @@ var init_verify = __esm({
|
|
|
36454
36508
|
stella: 45e3
|
|
36455
36509
|
};
|
|
36456
36510
|
ENDING_GRACE_MS = 3e4;
|
|
36457
|
-
ENDING_DETAIL = "SessionEnd arrived, but the Oxagen collector had not finished the session's final worktree read. The
|
|
36511
|
+
ENDING_DETAIL = "SessionEnd arrived, but the Oxagen collector had not finished the session's final worktree read. The collector locks the session's record once that read lands. Run `oxagen agent verify` again in a minute";
|
|
36458
36512
|
UNSEALED_DETAIL = {
|
|
36459
36513
|
"claude-code": "session started but SessionEnd never arrived within the timeout",
|
|
36460
|
-
codex: "session started but
|
|
36461
|
-
cursor: "session started but
|
|
36462
|
-
stella: "session started but was not
|
|
36514
|
+
codex: "session started but the final lock on its record never arrived; check Codex Stop and SessionEnd hook delivery with `oxagen agent status`",
|
|
36515
|
+
cursor: "session started but the final lock on its record never arrived; check Cursor stop and sessionEnd hook delivery with `oxagen agent status`",
|
|
36516
|
+
stella: "session started but its record was not locked within the timeout; Stella sends no SessionEnd, so the Oxagen collector locks the session's record once the stella process has exited and its sweep has run"
|
|
36463
36517
|
};
|
|
36464
36518
|
}
|
|
36465
36519
|
});
|
|
@@ -36709,7 +36763,7 @@ function sandboxMeasurement(placement, guest) {
|
|
|
36709
36763
|
];
|
|
36710
36764
|
if (!HOST_ID.test(placement.hostId) || !VM_ID.test(placement.vmId) || digests.some((digest6) => !DIGEST.test(digest6)))
|
|
36711
36765
|
throw new Error(
|
|
36712
|
-
"The sandbox placement or a measured
|
|
36766
|
+
"The sandbox placement or a measured hash is malformed; the agent was not started"
|
|
36713
36767
|
);
|
|
36714
36768
|
return {
|
|
36715
36769
|
profile: SANDBOX_PROFILE,
|
|
@@ -36731,7 +36785,7 @@ function modalSandboxMeasurement(placement, guest) {
|
|
|
36731
36785
|
];
|
|
36732
36786
|
if (placement.profile !== MODAL_SANDBOX_PROFILE || !MODAL_ENVIRONMENT.test(placement.modalEnvironment) || !MODAL_ID.test(placement.modalSandboxId) || !MODAL_ID.test(placement.imageId) || digests.some((digest6) => !DIGEST.test(digest6)))
|
|
36733
36787
|
throw new Error(
|
|
36734
|
-
"The Modal placement or a measured
|
|
36788
|
+
"The Modal placement or a measured hash is malformed; the agent was not started"
|
|
36735
36789
|
);
|
|
36736
36790
|
return {
|
|
36737
36791
|
profile: MODAL_SANDBOX_PROFILE,
|
|
@@ -38671,7 +38725,7 @@ function containerArguments(spec) {
|
|
|
38671
38725
|
if (!/^oxagen-contained-[a-f0-9]{32}$/.test(spec.name))
|
|
38672
38726
|
throw new Error("Invalid contained container name");
|
|
38673
38727
|
if (!/^sha256:[a-f0-9]{64}$/.test(spec.image))
|
|
38674
|
-
throw new Error("Contained execution requires a resolved image
|
|
38728
|
+
throw new Error("Contained execution requires a resolved image hash");
|
|
38675
38729
|
if (!Number.isSafeInteger(spec.uid) || spec.uid <= 0 || !Number.isSafeInteger(spec.gid) || spec.gid < 0)
|
|
38676
38730
|
throw new Error("Contained execution requires an unprivileged Linux user");
|
|
38677
38731
|
if (!CONTAINED_HARNESSES.includes(spec.harness))
|
|
@@ -39204,12 +39258,12 @@ function readBaseLayerDigest(system) {
|
|
|
39204
39258
|
const found = system.stat(BASE_LAYER_DIGEST_FILE);
|
|
39205
39259
|
if (found === void 0 || !found.isFile || found.uid !== 0 || (found.mode & 18) !== 0)
|
|
39206
39260
|
throw new Error(
|
|
39207
|
-
"The sandbox has no root-owned base layer
|
|
39261
|
+
"The sandbox has no root-owned base layer hash; the agent was not started"
|
|
39208
39262
|
);
|
|
39209
39263
|
const digest6 = system.readFile(BASE_LAYER_DIGEST_FILE).toString("utf8").trim();
|
|
39210
39264
|
if (!/^sha256:[a-f0-9]{64}$/.test(digest6))
|
|
39211
39265
|
throw new Error(
|
|
39212
|
-
"The sandbox's base layer
|
|
39266
|
+
"The sandbox's base layer hash is malformed; the agent was not started"
|
|
39213
39267
|
);
|
|
39214
39268
|
return digest6;
|
|
39215
39269
|
}
|
|
@@ -46448,7 +46502,7 @@ function createGithubProxy(deps) {
|
|
|
46448
46502
|
verdict = evaluate();
|
|
46449
46503
|
}
|
|
46450
46504
|
if (!deps.policy().verified) {
|
|
46451
|
-
reply(res, 403, "The
|
|
46505
|
+
reply(res, 403, "The mandate's lock did not verify");
|
|
46452
46506
|
return;
|
|
46453
46507
|
}
|
|
46454
46508
|
if (verdict.decision !== "allow" || !live(lease)) {
|
|
@@ -46813,6 +46867,163 @@ var init_hook_queues = __esm({
|
|
|
46813
46867
|
}
|
|
46814
46868
|
});
|
|
46815
46869
|
|
|
46870
|
+
// ../../packages/tacho/src/collector/memory-capture/memory-counts.ts
|
|
46871
|
+
function countsOf(state) {
|
|
46872
|
+
const counts2 = /* @__PURE__ */ new Map();
|
|
46873
|
+
if (typeof state !== "object" || state === null) return counts2;
|
|
46874
|
+
const record = state;
|
|
46875
|
+
if (record.schema !== MEMORY_COUNTS_STATE_SCHEMA) return counts2;
|
|
46876
|
+
if (typeof record.counts !== "object" || record.counts === null)
|
|
46877
|
+
return counts2;
|
|
46878
|
+
for (const [harness, paths] of Object.entries(
|
|
46879
|
+
record.counts
|
|
46880
|
+
)) {
|
|
46881
|
+
if (typeof paths !== "object" || paths === null) continue;
|
|
46882
|
+
for (const [path2, count12] of Object.entries(
|
|
46883
|
+
paths
|
|
46884
|
+
))
|
|
46885
|
+
if (Number.isSafeInteger(count12) && count12 > 0)
|
|
46886
|
+
counts2.set(keyOf(harness, path2), count12);
|
|
46887
|
+
}
|
|
46888
|
+
return counts2;
|
|
46889
|
+
}
|
|
46890
|
+
function stateOf2(counts2) {
|
|
46891
|
+
const byHarness = {};
|
|
46892
|
+
for (const [key, count12] of counts2) {
|
|
46893
|
+
const split = key.indexOf("\n");
|
|
46894
|
+
const harness = key.slice(0, split);
|
|
46895
|
+
const path2 = key.slice(split + 1);
|
|
46896
|
+
(byHarness[harness] ??= {})[path2] = count12;
|
|
46897
|
+
}
|
|
46898
|
+
return JSON.stringify({
|
|
46899
|
+
schema: MEMORY_COUNTS_STATE_SCHEMA,
|
|
46900
|
+
counts: byHarness
|
|
46901
|
+
});
|
|
46902
|
+
}
|
|
46903
|
+
function fileStateStorage(path2, unparsed) {
|
|
46904
|
+
return {
|
|
46905
|
+
load: () => readJsonStateFile(path2, unparsed),
|
|
46906
|
+
save: (json2) => writeSensitiveFileAtomic(path2, json2)
|
|
46907
|
+
};
|
|
46908
|
+
}
|
|
46909
|
+
function stateSaver(storage, failed3) {
|
|
46910
|
+
let lastFailure;
|
|
46911
|
+
return (json2) => {
|
|
46912
|
+
try {
|
|
46913
|
+
storage.save(json2);
|
|
46914
|
+
lastFailure = void 0;
|
|
46915
|
+
} catch (error) {
|
|
46916
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
46917
|
+
if (detail === lastFailure) return;
|
|
46918
|
+
lastFailure = detail;
|
|
46919
|
+
failed3(detail);
|
|
46920
|
+
}
|
|
46921
|
+
};
|
|
46922
|
+
}
|
|
46923
|
+
function fileUseCountStorage(path2, log) {
|
|
46924
|
+
return fileStateStorage(
|
|
46925
|
+
path2,
|
|
46926
|
+
(movedTo) => log(
|
|
46927
|
+
movedTo === void 0 ? "memory counts: the saved counts did not parse and could not be moved aside; every count is reported from zero" : `memory counts: the saved counts did not parse; moved them to ${movedTo}, and every count is reported from zero`
|
|
46928
|
+
)
|
|
46929
|
+
);
|
|
46930
|
+
}
|
|
46931
|
+
function createUseCountLedger(deps) {
|
|
46932
|
+
let counts2 = /* @__PURE__ */ new Map();
|
|
46933
|
+
let blind = false;
|
|
46934
|
+
try {
|
|
46935
|
+
counts2 = countsOf(deps.storage.load());
|
|
46936
|
+
} catch (error) {
|
|
46937
|
+
blind = true;
|
|
46938
|
+
deps.log(
|
|
46939
|
+
`memory counts: the saved counts could not be read (${error instanceof Error ? error.message : String(error)}); no harness count is reported until the daemon restarts`
|
|
46940
|
+
);
|
|
46941
|
+
}
|
|
46942
|
+
const saveState = stateSaver(
|
|
46943
|
+
deps.storage,
|
|
46944
|
+
(detail) => deps.log(
|
|
46945
|
+
`memory counts: the counts could not be saved (${detail}); a restart reports the rises since the last save again`
|
|
46946
|
+
)
|
|
46947
|
+
);
|
|
46948
|
+
const save = () => saveState(stateOf2(counts2));
|
|
46949
|
+
return {
|
|
46950
|
+
rises: (reads) => {
|
|
46951
|
+
if (blind) return [];
|
|
46952
|
+
const rises = [];
|
|
46953
|
+
let changed = false;
|
|
46954
|
+
for (const read2 of reads) {
|
|
46955
|
+
const present = /* @__PURE__ */ new Set();
|
|
46956
|
+
for (const { path: path2, count: count12, lastUsedAt } of read2.counts) {
|
|
46957
|
+
if (!Number.isSafeInteger(count12) || count12 < 0) continue;
|
|
46958
|
+
const key = keyOf(read2.harness, path2);
|
|
46959
|
+
present.add(key);
|
|
46960
|
+
const base2 = counts2.get(key) ?? 0;
|
|
46961
|
+
if (count12 < base2) {
|
|
46962
|
+
if (count12 === 0) counts2.delete(key);
|
|
46963
|
+
else counts2.set(key, count12);
|
|
46964
|
+
changed = true;
|
|
46965
|
+
continue;
|
|
46966
|
+
}
|
|
46967
|
+
if (count12 === base2) continue;
|
|
46968
|
+
const rise = Math.min(count12 - base2, RISE_MAX);
|
|
46969
|
+
rises.push({
|
|
46970
|
+
harness: read2.harness,
|
|
46971
|
+
path: path2,
|
|
46972
|
+
count: rise,
|
|
46973
|
+
usedAt: lastUsedAt ?? new Date(deps.now()).toISOString(),
|
|
46974
|
+
through: base2 + rise
|
|
46975
|
+
});
|
|
46976
|
+
}
|
|
46977
|
+
const prefix = keyOf(read2.harness, read2.root);
|
|
46978
|
+
for (const key of [...counts2.keys()])
|
|
46979
|
+
if (key.startsWith(prefix) && !present.has(key)) {
|
|
46980
|
+
counts2.delete(key);
|
|
46981
|
+
changed = true;
|
|
46982
|
+
}
|
|
46983
|
+
}
|
|
46984
|
+
if (changed) save();
|
|
46985
|
+
return rises;
|
|
46986
|
+
},
|
|
46987
|
+
settle: (rises) => {
|
|
46988
|
+
if (rises.length === 0) return;
|
|
46989
|
+
for (const rise of rises)
|
|
46990
|
+
counts2.set(keyOf(rise.harness, rise.path), rise.through);
|
|
46991
|
+
save();
|
|
46992
|
+
}
|
|
46993
|
+
};
|
|
46994
|
+
}
|
|
46995
|
+
var MEMORY_COUNTS_STATE_SCHEMA, RISE_MAX, keyOf;
|
|
46996
|
+
var init_memory_counts = __esm({
|
|
46997
|
+
"../../packages/tacho/src/collector/memory-capture/memory-counts.ts"() {
|
|
46998
|
+
"use strict";
|
|
46999
|
+
init_fs();
|
|
47000
|
+
MEMORY_COUNTS_STATE_SCHEMA = "tacho.memory-counts.v1";
|
|
47001
|
+
RISE_MAX = 1e4;
|
|
47002
|
+
keyOf = (harness, path2) => `${harness}
|
|
47003
|
+
${path2}`;
|
|
47004
|
+
}
|
|
47005
|
+
});
|
|
47006
|
+
|
|
47007
|
+
// ../../packages/tacho/src/collector/memory-capture/memory-send.ts
|
|
47008
|
+
function stillHeld(held, digest6, now) {
|
|
47009
|
+
return held !== void 0 && held.digest === digest6 && now - held.at < MEMORY_REFUSED_RETRY_MS;
|
|
47010
|
+
}
|
|
47011
|
+
var MemoryRateLimited, MEMORY_REFUSED_RETRY_MS;
|
|
47012
|
+
var init_memory_send = __esm({
|
|
47013
|
+
"../../packages/tacho/src/collector/memory-capture/memory-send.ts"() {
|
|
47014
|
+
"use strict";
|
|
47015
|
+
MemoryRateLimited = class extends Error {
|
|
47016
|
+
constructor(retryAfterMs2) {
|
|
47017
|
+
super("memory upload: the control plane answered 429");
|
|
47018
|
+
this.retryAfterMs = retryAfterMs2;
|
|
47019
|
+
this.name = "MemoryRateLimited";
|
|
47020
|
+
}
|
|
47021
|
+
retryAfterMs;
|
|
47022
|
+
};
|
|
47023
|
+
MEMORY_REFUSED_RETRY_MS = 60 * 6e4;
|
|
47024
|
+
}
|
|
47025
|
+
});
|
|
47026
|
+
|
|
46816
47027
|
// ../../packages/tacho/src/collector/memory-capture/memory-reader.ts
|
|
46817
47028
|
import { createRequire as createRequire2 } from "node:module";
|
|
46818
47029
|
import { isAbsolute as isAbsolute10, join as join40, sep as sep7 } from "node:path";
|
|
@@ -46932,9 +47143,9 @@ function memoryTextOf(text5) {
|
|
|
46932
47143
|
function sentDigest(entry2) {
|
|
46933
47144
|
return digestBytes(
|
|
46934
47145
|
JSON.stringify([
|
|
46935
|
-
entry2.statement,
|
|
46936
|
-
entry2.label
|
|
46937
|
-
entry2.summary
|
|
47146
|
+
redactText(entry2.statement),
|
|
47147
|
+
entry2.label === void 0 ? null : redactText(entry2.label),
|
|
47148
|
+
entry2.summary === void 0 ? null : redactText(entry2.summary),
|
|
46938
47149
|
entry2.memoryType ?? null,
|
|
46939
47150
|
entry2.personal ?? null,
|
|
46940
47151
|
entry2.repositoryDigests ?? null
|
|
@@ -46963,10 +47174,60 @@ function storedTextOf(memory) {
|
|
|
46963
47174
|
...memoryType !== void 0 ? { memoryType } : {}
|
|
46964
47175
|
};
|
|
46965
47176
|
}
|
|
47177
|
+
function timerWait(ms) {
|
|
47178
|
+
return new Promise((resolve28) => {
|
|
47179
|
+
setTimeout(() => resolve28(true), ms).unref?.();
|
|
47180
|
+
});
|
|
47181
|
+
}
|
|
47182
|
+
function sentMarksOf(saved) {
|
|
47183
|
+
const marks = /* @__PURE__ */ new Map();
|
|
47184
|
+
if (typeof saved !== "object" || saved === null) return marks;
|
|
47185
|
+
const state = saved;
|
|
47186
|
+
if (state.schema !== MEMORY_SENT_STATE_SCHEMA || !Array.isArray(state.sent))
|
|
47187
|
+
return marks;
|
|
47188
|
+
for (const pair2 of state.sent) {
|
|
47189
|
+
if (!Array.isArray(pair2) || pair2.length !== 2) continue;
|
|
47190
|
+
const [key, digest6] = pair2;
|
|
47191
|
+
if (typeof key !== "string" || typeof digest6 !== "string") continue;
|
|
47192
|
+
if (!digest6.startsWith("sha256:")) continue;
|
|
47193
|
+
marks.set(key, digest6);
|
|
47194
|
+
}
|
|
47195
|
+
return marks;
|
|
47196
|
+
}
|
|
46966
47197
|
function createMemoryReader(deps) {
|
|
46967
47198
|
const harnesses = deps.harnesses ?? HARNESS_MEMORY_LOCATIONS;
|
|
46968
47199
|
const stores = deps.stores ?? [];
|
|
46969
|
-
const
|
|
47200
|
+
const log = deps.log ?? (() => void 0);
|
|
47201
|
+
const now = deps.now ?? Date.now;
|
|
47202
|
+
const wait = deps.wait ?? timerWait;
|
|
47203
|
+
let sent = /* @__PURE__ */ new Map();
|
|
47204
|
+
if (deps.storage !== void 0) {
|
|
47205
|
+
try {
|
|
47206
|
+
sent = sentMarksOf(deps.storage.load());
|
|
47207
|
+
} catch (error) {
|
|
47208
|
+
log(
|
|
47209
|
+
`memory reader: the sent record could not be read (${error instanceof Error ? error.message : String(error)}); every memory is sent again`
|
|
47210
|
+
);
|
|
47211
|
+
}
|
|
47212
|
+
}
|
|
47213
|
+
let dirty = false;
|
|
47214
|
+
const saveState = deps.storage === void 0 ? void 0 : stateSaver(
|
|
47215
|
+
deps.storage,
|
|
47216
|
+
(detail) => log(
|
|
47217
|
+
`memory reader: the sent record could not be saved (${detail}); a restart sends the memories since the last save again`
|
|
47218
|
+
)
|
|
47219
|
+
);
|
|
47220
|
+
function persist() {
|
|
47221
|
+
if (!dirty || saveState === void 0) return;
|
|
47222
|
+
dirty = false;
|
|
47223
|
+
saveState(
|
|
47224
|
+
JSON.stringify({
|
|
47225
|
+
schema: MEMORY_SENT_STATE_SCHEMA,
|
|
47226
|
+
sent: [...sent].slice(0, MEMORY_SENT_SAVED_MAX)
|
|
47227
|
+
})
|
|
47228
|
+
);
|
|
47229
|
+
}
|
|
47230
|
+
const refused2 = /* @__PURE__ */ new Map();
|
|
46970
47231
|
const uploading = /* @__PURE__ */ new Set();
|
|
46971
47232
|
let running;
|
|
46972
47233
|
async function list2(dir) {
|
|
@@ -47014,16 +47275,39 @@ function createMemoryReader(deps) {
|
|
|
47014
47275
|
const whole = [];
|
|
47015
47276
|
const read2 = /* @__PURE__ */ new Set();
|
|
47016
47277
|
const seen = /* @__PURE__ */ new Set();
|
|
47278
|
+
let waited = 0;
|
|
47017
47279
|
async function offer(entry2) {
|
|
47018
|
-
const key =
|
|
47280
|
+
const key = keyOf2(entry2.harness, entry2.path);
|
|
47019
47281
|
const digest6 = sentDigest(entry2);
|
|
47020
47282
|
if (sent.get(key) === digest6) return true;
|
|
47021
|
-
|
|
47022
|
-
|
|
47023
|
-
|
|
47024
|
-
|
|
47283
|
+
if (stillHeld(refused2.get(key), digest6, now())) return true;
|
|
47284
|
+
for (; ; ) {
|
|
47285
|
+
let outcome;
|
|
47286
|
+
try {
|
|
47287
|
+
outcome = await deps.send(entry2);
|
|
47288
|
+
} catch (error) {
|
|
47289
|
+
if (!(error instanceof MemoryRateLimited)) return false;
|
|
47290
|
+
const ms = Math.max(
|
|
47291
|
+
MEMORY_RATE_WAIT_MIN_MS,
|
|
47292
|
+
Math.min(
|
|
47293
|
+
error.retryAfterMs ?? MEMORY_RATE_WAIT_MAX_MS,
|
|
47294
|
+
MEMORY_RATE_WAIT_MAX_MS
|
|
47295
|
+
)
|
|
47296
|
+
);
|
|
47297
|
+
if (waited + ms > MEMORY_SCAN_WAIT_MAX_MS) return false;
|
|
47298
|
+
waited += ms;
|
|
47299
|
+
if (!await wait(ms)) return false;
|
|
47300
|
+
continue;
|
|
47301
|
+
}
|
|
47302
|
+
if (outcome === "refused") {
|
|
47303
|
+
refused2.set(key, { digest: digest6, at: now() });
|
|
47304
|
+
return true;
|
|
47305
|
+
}
|
|
47306
|
+
break;
|
|
47025
47307
|
}
|
|
47308
|
+
refused2.delete(key);
|
|
47026
47309
|
sent.set(key, digest6);
|
|
47310
|
+
dirty = true;
|
|
47027
47311
|
count12 += 1;
|
|
47028
47312
|
return true;
|
|
47029
47313
|
}
|
|
@@ -47035,7 +47319,7 @@ function createMemoryReader(deps) {
|
|
|
47035
47319
|
const file = await readAt2(location.harness, path2);
|
|
47036
47320
|
if (file.kind === "absent" || file.kind === "empty") continue;
|
|
47037
47321
|
paths.push(path2);
|
|
47038
|
-
seen.add(
|
|
47322
|
+
seen.add(keyOf2(location.harness, path2));
|
|
47039
47323
|
if (file.kind !== "entry") continue;
|
|
47040
47324
|
if (!await offer({ ...file.entry, ...placedFields(where) }))
|
|
47041
47325
|
return false;
|
|
@@ -47052,7 +47336,7 @@ function createMemoryReader(deps) {
|
|
|
47052
47336
|
for (const location of locations) {
|
|
47053
47337
|
const top = location.projectsDir(deps.home);
|
|
47054
47338
|
const root = withSep(top);
|
|
47055
|
-
const prefix =
|
|
47339
|
+
const prefix = keyOf2(location.harness, root);
|
|
47056
47340
|
if (read2.has(prefix)) continue;
|
|
47057
47341
|
read2.add(prefix);
|
|
47058
47342
|
if (scoper === void 0) continue;
|
|
@@ -47069,7 +47353,7 @@ function createMemoryReader(deps) {
|
|
|
47069
47353
|
const paths2 = [];
|
|
47070
47354
|
if (!await readFolder(location, dir, files2.names, where2, paths2))
|
|
47071
47355
|
return { sent: count12 };
|
|
47072
|
-
whole.push(
|
|
47356
|
+
whole.push(keyOf2(location.harness, folder));
|
|
47073
47357
|
scans.push({
|
|
47074
47358
|
harness: location.harness,
|
|
47075
47359
|
root: folder,
|
|
@@ -47097,7 +47381,7 @@ function createMemoryReader(deps) {
|
|
|
47097
47381
|
scans.push({ harness: location.harness, root, paths: paths.sort() });
|
|
47098
47382
|
}
|
|
47099
47383
|
for (const store of typeof stores === "function" ? stores() : stores) {
|
|
47100
|
-
const prefix =
|
|
47384
|
+
const prefix = keyOf2(store.harness, store.root);
|
|
47101
47385
|
if (read2.has(prefix)) continue;
|
|
47102
47386
|
read2.add(prefix);
|
|
47103
47387
|
const found = await store.read();
|
|
@@ -47109,7 +47393,7 @@ function createMemoryReader(deps) {
|
|
|
47109
47393
|
for (const memory of found.memories) {
|
|
47110
47394
|
if (!memory.path.startsWith(store.root) || memory.path.length === store.root.length)
|
|
47111
47395
|
continue;
|
|
47112
|
-
const key =
|
|
47396
|
+
const key = keyOf2(store.harness, memory.path);
|
|
47113
47397
|
if (seen.has(key)) continue;
|
|
47114
47398
|
const text5 = storedTextOf(memory);
|
|
47115
47399
|
if (text5.statement.length === 0) continue;
|
|
@@ -47141,31 +47425,50 @@ function createMemoryReader(deps) {
|
|
|
47141
47425
|
counts: useCounts
|
|
47142
47426
|
});
|
|
47143
47427
|
}
|
|
47428
|
+
const gone = (key) => !seen.has(key) && whole.some((prefix) => key.startsWith(prefix));
|
|
47144
47429
|
for (const key of [...sent.keys()])
|
|
47145
|
-
if (
|
|
47430
|
+
if (gone(key)) {
|
|
47146
47431
|
sent.delete(key);
|
|
47432
|
+
dirty = true;
|
|
47433
|
+
}
|
|
47434
|
+
for (const key of [...refused2.keys()]) if (gone(key)) refused2.delete(key);
|
|
47147
47435
|
return { sent: count12, scans, counts: counts2 };
|
|
47148
47436
|
}
|
|
47149
47437
|
return {
|
|
47150
47438
|
// A scan that overlaps one still running joins it, so no entry is sent
|
|
47151
|
-
// twice at once.
|
|
47439
|
+
// twice at once. Every scan saves what it sent, whether it finished or
|
|
47440
|
+
// stopped on a failure.
|
|
47152
47441
|
scan: () => {
|
|
47153
47442
|
running ??= scanOnce().finally(() => {
|
|
47154
47443
|
running = void 0;
|
|
47444
|
+
persist();
|
|
47155
47445
|
});
|
|
47156
47446
|
return running;
|
|
47157
47447
|
},
|
|
47158
47448
|
uploads: (path2) => {
|
|
47159
47449
|
for (const root of uploading) if (path2.startsWith(root)) return true;
|
|
47160
47450
|
return false;
|
|
47451
|
+
},
|
|
47452
|
+
resend: (memories) => {
|
|
47453
|
+
for (const memory of memories)
|
|
47454
|
+
if (sent.delete(keyOf2(memory.harness, memory.path))) dirty = true;
|
|
47455
|
+
persist();
|
|
47161
47456
|
}
|
|
47162
47457
|
};
|
|
47163
47458
|
}
|
|
47164
|
-
var MEMORY_STATEMENT_MAX_CHARS, MEMORY_LABEL_MAX_CHARS, MEMORY_SUMMARY_MAX_CHARS, MEMORY_TYPE_PATTERN, MEMORY_PROJECT_DIRS_MAX, HARNESS_MEMORY_LOCATIONS, FRONTMATTER, sqliteModule, FRONTMATTER_LINE, sends,
|
|
47459
|
+
var MEMORY_SENT_STATE_SCHEMA, MEMORY_SENT_SAVED_MAX, MEMORY_RATE_WAIT_MAX_MS, MEMORY_RATE_WAIT_MIN_MS, MEMORY_SCAN_WAIT_MAX_MS, MEMORY_STATEMENT_MAX_CHARS, MEMORY_LABEL_MAX_CHARS, MEMORY_SUMMARY_MAX_CHARS, MEMORY_TYPE_PATTERN, MEMORY_PROJECT_DIRS_MAX, HARNESS_MEMORY_LOCATIONS, FRONTMATTER, sqliteModule, FRONTMATTER_LINE, sends, keyOf2, withSep;
|
|
47165
47460
|
var init_memory_reader = __esm({
|
|
47166
47461
|
"../../packages/tacho/src/collector/memory-capture/memory-reader.ts"() {
|
|
47167
47462
|
"use strict";
|
|
47168
47463
|
init_digest();
|
|
47464
|
+
init_redaction();
|
|
47465
|
+
init_memory_counts();
|
|
47466
|
+
init_memory_send();
|
|
47467
|
+
MEMORY_SENT_STATE_SCHEMA = "tacho.memory-sent.v1";
|
|
47468
|
+
MEMORY_SENT_SAVED_MAX = 5e4;
|
|
47469
|
+
MEMORY_RATE_WAIT_MAX_MS = 6e4;
|
|
47470
|
+
MEMORY_RATE_WAIT_MIN_MS = 1e3;
|
|
47471
|
+
MEMORY_SCAN_WAIT_MAX_MS = 30 * 6e4;
|
|
47169
47472
|
MEMORY_STATEMENT_MAX_CHARS = 2e3;
|
|
47170
47473
|
MEMORY_LABEL_MAX_CHARS = 200;
|
|
47171
47474
|
MEMORY_SUMMARY_MAX_CHARS = 1e3;
|
|
@@ -47182,7 +47485,7 @@ var init_memory_reader = __esm({
|
|
|
47182
47485
|
FRONTMATTER = /^---[ \t]*\r?\n(?:([\s\S]*?)\r?\n)?---[ \t]*(?:\r?\n|$)/;
|
|
47183
47486
|
FRONTMATTER_LINE = /^([ \t]*)([A-Za-z_][\w-]*)[ \t]*:[ \t]*(.*)$/;
|
|
47184
47487
|
sends = (where) => where.kind === "personal" || where.kind === "repository";
|
|
47185
|
-
|
|
47488
|
+
keyOf2 = (harness, path2) => `${harness}
|
|
47186
47489
|
${path2}`;
|
|
47187
47490
|
withSep = (dir) => dir.endsWith(sep7) ? dir : `${dir}${sep7}`;
|
|
47188
47491
|
}
|
|
@@ -47290,144 +47593,21 @@ var init_codex_store = __esm({
|
|
|
47290
47593
|
}
|
|
47291
47594
|
});
|
|
47292
47595
|
|
|
47293
|
-
// ../../packages/tacho/src/collector/memory-capture/memory-
|
|
47294
|
-
function
|
|
47295
|
-
|
|
47296
|
-
if (typeof state !== "object" || state === null) return counts2;
|
|
47297
|
-
const record = state;
|
|
47298
|
-
if (record.schema !== MEMORY_COUNTS_STATE_SCHEMA) return counts2;
|
|
47299
|
-
if (typeof record.counts !== "object" || record.counts === null)
|
|
47300
|
-
return counts2;
|
|
47301
|
-
for (const [harness, paths] of Object.entries(
|
|
47302
|
-
record.counts
|
|
47303
|
-
)) {
|
|
47304
|
-
if (typeof paths !== "object" || paths === null) continue;
|
|
47305
|
-
for (const [path2, count12] of Object.entries(
|
|
47306
|
-
paths
|
|
47307
|
-
))
|
|
47308
|
-
if (Number.isSafeInteger(count12) && count12 > 0)
|
|
47309
|
-
counts2.set(keyOf2(harness, path2), count12);
|
|
47310
|
-
}
|
|
47311
|
-
return counts2;
|
|
47312
|
-
}
|
|
47313
|
-
function stateOf2(counts2) {
|
|
47314
|
-
const byHarness = {};
|
|
47315
|
-
for (const [key, count12] of counts2) {
|
|
47316
|
-
const split = key.indexOf("\n");
|
|
47317
|
-
const harness = key.slice(0, split);
|
|
47318
|
-
const path2 = key.slice(split + 1);
|
|
47319
|
-
(byHarness[harness] ??= {})[path2] = count12;
|
|
47320
|
-
}
|
|
47321
|
-
return JSON.stringify({
|
|
47322
|
-
schema: MEMORY_COUNTS_STATE_SCHEMA,
|
|
47323
|
-
counts: byHarness
|
|
47324
|
-
});
|
|
47325
|
-
}
|
|
47326
|
-
function fileStateStorage(path2, unparsed) {
|
|
47327
|
-
return {
|
|
47328
|
-
load: () => readJsonStateFile(path2, unparsed),
|
|
47329
|
-
save: (json2) => writeSensitiveFileAtomic(path2, json2)
|
|
47330
|
-
};
|
|
47331
|
-
}
|
|
47332
|
-
function stateSaver(storage, failed3) {
|
|
47333
|
-
let lastFailure;
|
|
47334
|
-
return (json2) => {
|
|
47335
|
-
try {
|
|
47336
|
-
storage.save(json2);
|
|
47337
|
-
lastFailure = void 0;
|
|
47338
|
-
} catch (error) {
|
|
47339
|
-
const detail = error instanceof Error ? error.message : String(error);
|
|
47340
|
-
if (detail === lastFailure) return;
|
|
47341
|
-
lastFailure = detail;
|
|
47342
|
-
failed3(detail);
|
|
47343
|
-
}
|
|
47344
|
-
};
|
|
47345
|
-
}
|
|
47346
|
-
function fileUseCountStorage(path2, log) {
|
|
47347
|
-
return fileStateStorage(
|
|
47348
|
-
path2,
|
|
47349
|
-
(movedTo) => log(
|
|
47350
|
-
movedTo === void 0 ? "memory counts: the saved counts did not parse and could not be moved aside; every count is reported from zero" : `memory counts: the saved counts did not parse; moved them to ${movedTo}, and every count is reported from zero`
|
|
47351
|
-
)
|
|
47352
|
-
);
|
|
47353
|
-
}
|
|
47354
|
-
function createUseCountLedger(deps) {
|
|
47355
|
-
let counts2 = /* @__PURE__ */ new Map();
|
|
47356
|
-
let blind = false;
|
|
47596
|
+
// ../../packages/tacho/src/collector/memory-capture/memory-upload.ts
|
|
47597
|
+
function answerReason(text5) {
|
|
47598
|
+
let reason3 = text5;
|
|
47357
47599
|
try {
|
|
47358
|
-
|
|
47359
|
-
|
|
47360
|
-
|
|
47361
|
-
|
|
47362
|
-
|
|
47363
|
-
);
|
|
47364
|
-
}
|
|
47365
|
-
const saveState = stateSaver(
|
|
47366
|
-
deps.storage,
|
|
47367
|
-
(detail) => deps.log(
|
|
47368
|
-
`memory counts: the counts could not be saved (${detail}); a restart reports the rises since the last save again`
|
|
47369
|
-
)
|
|
47370
|
-
);
|
|
47371
|
-
const save = () => saveState(stateOf2(counts2));
|
|
47372
|
-
return {
|
|
47373
|
-
rises: (reads) => {
|
|
47374
|
-
if (blind) return [];
|
|
47375
|
-
const rises = [];
|
|
47376
|
-
let changed = false;
|
|
47377
|
-
for (const read2 of reads) {
|
|
47378
|
-
const present = /* @__PURE__ */ new Set();
|
|
47379
|
-
for (const { path: path2, count: count12, lastUsedAt } of read2.counts) {
|
|
47380
|
-
if (!Number.isSafeInteger(count12) || count12 < 0) continue;
|
|
47381
|
-
const key = keyOf2(read2.harness, path2);
|
|
47382
|
-
present.add(key);
|
|
47383
|
-
const base2 = counts2.get(key) ?? 0;
|
|
47384
|
-
if (count12 < base2) {
|
|
47385
|
-
if (count12 === 0) counts2.delete(key);
|
|
47386
|
-
else counts2.set(key, count12);
|
|
47387
|
-
changed = true;
|
|
47388
|
-
continue;
|
|
47389
|
-
}
|
|
47390
|
-
if (count12 === base2) continue;
|
|
47391
|
-
const rise = Math.min(count12 - base2, RISE_MAX);
|
|
47392
|
-
rises.push({
|
|
47393
|
-
harness: read2.harness,
|
|
47394
|
-
path: path2,
|
|
47395
|
-
count: rise,
|
|
47396
|
-
usedAt: lastUsedAt ?? new Date(deps.now()).toISOString(),
|
|
47397
|
-
through: base2 + rise
|
|
47398
|
-
});
|
|
47399
|
-
}
|
|
47400
|
-
const prefix = keyOf2(read2.harness, read2.root);
|
|
47401
|
-
for (const key of [...counts2.keys()])
|
|
47402
|
-
if (key.startsWith(prefix) && !present.has(key)) {
|
|
47403
|
-
counts2.delete(key);
|
|
47404
|
-
changed = true;
|
|
47405
|
-
}
|
|
47406
|
-
}
|
|
47407
|
-
if (changed) save();
|
|
47408
|
-
return rises;
|
|
47409
|
-
},
|
|
47410
|
-
settle: (rises) => {
|
|
47411
|
-
if (rises.length === 0) return;
|
|
47412
|
-
for (const rise of rises)
|
|
47413
|
-
counts2.set(keyOf2(rise.harness, rise.path), rise.through);
|
|
47414
|
-
save();
|
|
47600
|
+
const parsed2 = JSON.parse(text5);
|
|
47601
|
+
if (typeof parsed2 === "object" && parsed2 !== null) {
|
|
47602
|
+
const body2 = parsed2;
|
|
47603
|
+
const message = typeof body2.message === "string" ? body2.message : typeof body2.error === "object" && body2.error !== null && typeof body2.error.message === "string" ? body2.error.message : void 0;
|
|
47604
|
+
reason3 = message ?? "";
|
|
47415
47605
|
}
|
|
47416
|
-
}
|
|
47417
|
-
}
|
|
47418
|
-
var MEMORY_COUNTS_STATE_SCHEMA, RISE_MAX, keyOf2;
|
|
47419
|
-
var init_memory_counts = __esm({
|
|
47420
|
-
"../../packages/tacho/src/collector/memory-capture/memory-counts.ts"() {
|
|
47421
|
-
"use strict";
|
|
47422
|
-
init_fs();
|
|
47423
|
-
MEMORY_COUNTS_STATE_SCHEMA = "tacho.memory-counts.v1";
|
|
47424
|
-
RISE_MAX = 1e4;
|
|
47425
|
-
keyOf2 = (harness, path2) => `${harness}
|
|
47426
|
-
${path2}`;
|
|
47606
|
+
} catch {
|
|
47427
47607
|
}
|
|
47428
|
-
|
|
47429
|
-
|
|
47430
|
-
|
|
47608
|
+
const line = reason3.replace(/\s+/g, " ").trim();
|
|
47609
|
+
return line.length === 0 ? void 0 : clip2(line, REFUSAL_REASON_MAX_CHARS);
|
|
47610
|
+
}
|
|
47431
47611
|
async function postToControlPlane(fetch2, host, path2, body2, signal) {
|
|
47432
47612
|
const url = `${host.api_url.replace(/\/$/, "")}${path2}`;
|
|
47433
47613
|
const payload = JSON.stringify({
|
|
@@ -47444,10 +47624,15 @@ async function postToControlPlane(fetch2, host, path2, body2, signal) {
|
|
|
47444
47624
|
body: payload,
|
|
47445
47625
|
signal
|
|
47446
47626
|
});
|
|
47627
|
+
const retryAfterMs2 = parseRetryAfter(
|
|
47628
|
+
response.headers?.get("retry-after") ?? null,
|
|
47629
|
+
Date.now()
|
|
47630
|
+
);
|
|
47447
47631
|
return {
|
|
47448
47632
|
ok: response.ok,
|
|
47449
47633
|
status: response.status,
|
|
47450
|
-
text: await response.text()
|
|
47634
|
+
text: await response.text(),
|
|
47635
|
+
...retryAfterMs2 !== void 0 ? { retryAfterMs: retryAfterMs2 } : {}
|
|
47451
47636
|
};
|
|
47452
47637
|
}
|
|
47453
47638
|
function changedFailureLog(write) {
|
|
@@ -47503,7 +47688,7 @@ function createMemoryUpload(deps) {
|
|
|
47503
47688
|
const status2 = answer.status;
|
|
47504
47689
|
if (answer.ok) {
|
|
47505
47690
|
failures.clear();
|
|
47506
|
-
return;
|
|
47691
|
+
return "stored";
|
|
47507
47692
|
}
|
|
47508
47693
|
if (status2 === 404) {
|
|
47509
47694
|
if (!routeMissingLogged) {
|
|
@@ -47515,24 +47700,32 @@ function createMemoryUpload(deps) {
|
|
|
47515
47700
|
throw new Error("memory upload: the control plane answered 404");
|
|
47516
47701
|
}
|
|
47517
47702
|
if (ENTRY_REFUSED.has(status2)) {
|
|
47703
|
+
const reason3 = answerReason(answer.text);
|
|
47518
47704
|
deps.log(
|
|
47519
|
-
`memory upload: the control plane refused ${entry2.path} (${status2}); it is sent again
|
|
47705
|
+
`memory upload: the control plane refused ${entry2.path} (${status2}${reason3 === void 0 ? "" : `: ${reason3}`}); it is held and sent again later`
|
|
47520
47706
|
);
|
|
47521
|
-
return;
|
|
47707
|
+
return "refused";
|
|
47708
|
+
}
|
|
47709
|
+
if (status2 === 429) {
|
|
47710
|
+
failure4(`the control plane answered ${status2}`);
|
|
47711
|
+
throw new MemoryRateLimited(answer.retryAfterMs);
|
|
47522
47712
|
}
|
|
47523
47713
|
throw failure4(`the control plane answered ${status2}`);
|
|
47524
47714
|
};
|
|
47525
47715
|
}
|
|
47526
|
-
var MEMORY_UPLOAD_PATH, MEMORY_UPLOAD_TIMEOUT_MS, ENTRY_REFUSED;
|
|
47716
|
+
var MEMORY_UPLOAD_PATH, MEMORY_UPLOAD_TIMEOUT_MS, ENTRY_REFUSED, REFUSAL_REASON_MAX_CHARS;
|
|
47527
47717
|
var init_memory_upload = __esm({
|
|
47528
47718
|
"../../packages/tacho/src/collector/memory-capture/memory-upload.ts"() {
|
|
47529
47719
|
"use strict";
|
|
47530
47720
|
init_redaction();
|
|
47721
|
+
init_control_client();
|
|
47531
47722
|
init_request_signature();
|
|
47532
47723
|
init_memory_reader();
|
|
47724
|
+
init_memory_send();
|
|
47533
47725
|
MEMORY_UPLOAD_PATH = "/v1/tacho/memories";
|
|
47534
47726
|
MEMORY_UPLOAD_TIMEOUT_MS = 15e3;
|
|
47535
47727
|
ENTRY_REFUSED = /* @__PURE__ */ new Set([400, 413, 422]);
|
|
47728
|
+
REFUSAL_REASON_MAX_CHARS = 300;
|
|
47536
47729
|
}
|
|
47537
47730
|
});
|
|
47538
47731
|
|
|
@@ -47907,6 +48100,26 @@ function pendingOf(text5, sentCount) {
|
|
|
47907
48100
|
(index) => Number.isInteger(index) && index >= 0 && index < sentCount
|
|
47908
48101
|
);
|
|
47909
48102
|
}
|
|
48103
|
+
function missingOf(text5, listed) {
|
|
48104
|
+
let parsed2;
|
|
48105
|
+
try {
|
|
48106
|
+
parsed2 = JSON.parse(text5);
|
|
48107
|
+
} catch {
|
|
48108
|
+
return [];
|
|
48109
|
+
}
|
|
48110
|
+
const missing = typeof parsed2 === "object" && parsed2 !== null ? parsed2.missing : void 0;
|
|
48111
|
+
if (!Array.isArray(missing)) return [];
|
|
48112
|
+
const found = [];
|
|
48113
|
+
for (const item of missing) {
|
|
48114
|
+
if (typeof item !== "object" || item === null) continue;
|
|
48115
|
+
const { harness, path: path2 } = item;
|
|
48116
|
+
if (typeof harness !== "string" || typeof path2 !== "string") continue;
|
|
48117
|
+
if (!listed.has(`${harness}
|
|
48118
|
+
${path2}`)) continue;
|
|
48119
|
+
found.push({ harness, path: path2 });
|
|
48120
|
+
}
|
|
48121
|
+
return found;
|
|
48122
|
+
}
|
|
47910
48123
|
function createMemoryUses(deps) {
|
|
47911
48124
|
const queue = /* @__PURE__ */ new Map();
|
|
47912
48125
|
let indexQueued = 0;
|
|
@@ -47936,7 +48149,7 @@ function createMemoryUses(deps) {
|
|
|
47936
48149
|
}
|
|
47937
48150
|
enqueue(key, { ...use });
|
|
47938
48151
|
}
|
|
47939
|
-
async function call2(body2, uses) {
|
|
48152
|
+
async function call2(body2, uses, listed = /* @__PURE__ */ new Set()) {
|
|
47940
48153
|
let response;
|
|
47941
48154
|
try {
|
|
47942
48155
|
response = await postToControlPlane(
|
|
@@ -47954,7 +48167,11 @@ function createMemoryUses(deps) {
|
|
|
47954
48167
|
}
|
|
47955
48168
|
if (response.ok) {
|
|
47956
48169
|
failures.clear();
|
|
47957
|
-
return {
|
|
48170
|
+
return {
|
|
48171
|
+
kind: "taken",
|
|
48172
|
+
pending: pendingOf(response.text, uses),
|
|
48173
|
+
missing: missingOf(response.text, listed)
|
|
48174
|
+
};
|
|
47958
48175
|
}
|
|
47959
48176
|
if (response.status === 404) {
|
|
47960
48177
|
if (!routeMissingLogged) {
|
|
@@ -47971,6 +48188,7 @@ function createMemoryUses(deps) {
|
|
|
47971
48188
|
return { kind: "kept" };
|
|
47972
48189
|
}
|
|
47973
48190
|
async function reportOnce(scans, counts2) {
|
|
48191
|
+
const missing = [];
|
|
47974
48192
|
if (overflowed > 0) {
|
|
47975
48193
|
deps.log(
|
|
47976
48194
|
`memory uses: the queue was full, so ${overflowed} memory uses were not counted`
|
|
@@ -48009,7 +48227,7 @@ function createMemoryUses(deps) {
|
|
|
48009
48227
|
if (result2.kind === "kept") {
|
|
48010
48228
|
for (const rest of batches.slice(position))
|
|
48011
48229
|
for (const use of rest) requeue(use);
|
|
48012
|
-
return;
|
|
48230
|
+
return { missing };
|
|
48013
48231
|
}
|
|
48014
48232
|
if (result2.kind === "refused") {
|
|
48015
48233
|
deps.log(
|
|
@@ -48037,7 +48255,7 @@ function createMemoryUses(deps) {
|
|
|
48037
48255
|
},
|
|
48038
48256
|
0
|
|
48039
48257
|
);
|
|
48040
|
-
if (result2.kind === "kept") return;
|
|
48258
|
+
if (result2.kind === "kept") return { missing };
|
|
48041
48259
|
if (result2.kind === "refused")
|
|
48042
48260
|
deps.log(
|
|
48043
48261
|
`memory uses: the control plane refused ${batch.length} harness counts (${result2.status}); they are dropped`
|
|
@@ -48054,16 +48272,22 @@ function createMemoryUses(deps) {
|
|
|
48054
48272
|
);
|
|
48055
48273
|
}
|
|
48056
48274
|
for (let start = 0; start < lists.length; start += MEMORY_SCANS_PER_REPORT) {
|
|
48057
|
-
const
|
|
48058
|
-
|
|
48059
|
-
|
|
48275
|
+
const chunk2 = lists.slice(start, start + MEMORY_SCANS_PER_REPORT);
|
|
48276
|
+
const listed = new Set(
|
|
48277
|
+
chunk2.flatMap(
|
|
48278
|
+
(scan) => scan.paths.map((path2) => `${scan.harness}
|
|
48279
|
+
${path2}`)
|
|
48280
|
+
)
|
|
48060
48281
|
);
|
|
48061
|
-
|
|
48282
|
+
const result2 = await call2({ scans: chunk2 }, 0, listed);
|
|
48283
|
+
if (result2.kind === "kept") return { missing };
|
|
48062
48284
|
if (result2.kind === "refused")
|
|
48063
48285
|
deps.log(
|
|
48064
48286
|
`memory uses: the control plane refused a scan's file list (${result2.status})`
|
|
48065
48287
|
);
|
|
48288
|
+
else missing.push(...result2.missing);
|
|
48066
48289
|
}
|
|
48290
|
+
return { missing };
|
|
48067
48291
|
}
|
|
48068
48292
|
return {
|
|
48069
48293
|
note: (read2) => {
|
|
@@ -48094,6 +48318,7 @@ function createMemoryUses(deps) {
|
|
|
48094
48318
|
deps.log(
|
|
48095
48319
|
`memory uses: the report failed (${error instanceof Error ? error.message : String(error)})`
|
|
48096
48320
|
);
|
|
48321
|
+
return { missing: [] };
|
|
48097
48322
|
}).finally(() => {
|
|
48098
48323
|
running = void 0;
|
|
48099
48324
|
});
|
|
@@ -48344,6 +48569,7 @@ function createStellaMemories(deps) {
|
|
|
48344
48569
|
}
|
|
48345
48570
|
const gone = /* @__PURE__ */ new Set();
|
|
48346
48571
|
const sent = /* @__PURE__ */ new Map();
|
|
48572
|
+
const refused2 = /* @__PURE__ */ new Map();
|
|
48347
48573
|
const failures = /* @__PURE__ */ new Map();
|
|
48348
48574
|
const viewsMissingLogged = /* @__PURE__ */ new Set();
|
|
48349
48575
|
let running;
|
|
@@ -48443,12 +48669,19 @@ ${lineage}`;
|
|
|
48443
48669
|
const key = sentKey(store, memory.lineage);
|
|
48444
48670
|
const digest6 = sentDigest2(memory);
|
|
48445
48671
|
if (sent.get(key) === digest6) continue;
|
|
48672
|
+
if (stillHeld(refused2.get(key), digest6, deps.now())) continue;
|
|
48673
|
+
let outcome;
|
|
48446
48674
|
try {
|
|
48447
|
-
await deps.send(entryOf2(memory, store));
|
|
48675
|
+
outcome = await deps.send(entryOf2(memory, store));
|
|
48448
48676
|
} catch {
|
|
48449
48677
|
sending = false;
|
|
48450
48678
|
break;
|
|
48451
48679
|
}
|
|
48680
|
+
if (outcome === "refused") {
|
|
48681
|
+
refused2.set(key, { digest: digest6, at: deps.now() });
|
|
48682
|
+
continue;
|
|
48683
|
+
}
|
|
48684
|
+
refused2.delete(key);
|
|
48452
48685
|
sent.set(key, digest6);
|
|
48453
48686
|
result2.sent += 1;
|
|
48454
48687
|
}
|
|
@@ -48504,6 +48737,11 @@ ${lineage}`;
|
|
|
48504
48737
|
running = void 0;
|
|
48505
48738
|
});
|
|
48506
48739
|
return running;
|
|
48740
|
+
},
|
|
48741
|
+
resend: (lineages) => {
|
|
48742
|
+
const wanted = new Set(lineages);
|
|
48743
|
+
for (const key of [...sent.keys()])
|
|
48744
|
+
if (wanted.has(key.slice(key.indexOf("\n") + 1))) sent.delete(key);
|
|
48507
48745
|
}
|
|
48508
48746
|
};
|
|
48509
48747
|
}
|
|
@@ -48513,6 +48751,7 @@ var init_stella_memories = __esm({
|
|
|
48513
48751
|
"use strict";
|
|
48514
48752
|
init_digest();
|
|
48515
48753
|
init_memory_counts();
|
|
48754
|
+
init_memory_send();
|
|
48516
48755
|
init_memory_uses();
|
|
48517
48756
|
init_stella_store();
|
|
48518
48757
|
STELLA_CURSORS_STATE_SCHEMA = "tacho.stella-memory-cursors.v1";
|
|
@@ -48523,7 +48762,7 @@ var init_stella_memories = __esm({
|
|
|
48523
48762
|
function digestMismatch() {
|
|
48524
48763
|
return {
|
|
48525
48764
|
code: "digest_mismatch",
|
|
48526
|
-
message: "The package
|
|
48765
|
+
message: "The package hash does not match the lock.",
|
|
48527
48766
|
fix: "Reinstall the locked version, or run the sync if the package changed on purpose."
|
|
48528
48767
|
};
|
|
48529
48768
|
}
|
|
@@ -48566,7 +48805,7 @@ function envelopeInvalid(reason3, subject = "call") {
|
|
|
48566
48805
|
return {
|
|
48567
48806
|
code: "envelope_invalid",
|
|
48568
48807
|
message: `The ${subject}'s envelope does not verify: ${reason3}.`,
|
|
48569
|
-
fix: "Enroll this machine again if Oxagen
|
|
48808
|
+
fix: "Enroll this machine again if Oxagen changed the key it locks envelopes with, then retry."
|
|
48570
48809
|
};
|
|
48571
48810
|
}
|
|
48572
48811
|
function envelopeExpired(expiresAt, subject = "call") {
|
|
@@ -48580,7 +48819,7 @@ function envelopeReplayed(subject = "call") {
|
|
|
48580
48819
|
return {
|
|
48581
48820
|
code: "envelope_replayed",
|
|
48582
48821
|
message: `The local gateway already ran a ${subject} with this envelope's nonce.`,
|
|
48583
|
-
fix: `Retry the ${subject}. The cloud gateway
|
|
48822
|
+
fix: `Retry the ${subject}. The cloud gateway gives each ${subject} a new nonce.`
|
|
48584
48823
|
};
|
|
48585
48824
|
}
|
|
48586
48825
|
function wrongMachine(machine, subject = "call") {
|
|
@@ -48594,7 +48833,7 @@ function argumentsMismatch() {
|
|
|
48594
48833
|
return {
|
|
48595
48834
|
code: "arguments_mismatch",
|
|
48596
48835
|
message: "The call's arguments do not hash to the envelope's arguments_hash.",
|
|
48597
|
-
fix: "Retry the call. The local gateway runs only the arguments the cloud gateway
|
|
48836
|
+
fix: "Retry the call. The local gateway runs only the arguments the cloud gateway locked into the envelope."
|
|
48598
48837
|
};
|
|
48599
48838
|
}
|
|
48600
48839
|
function launchMismatch(reason3) {
|
|
@@ -48705,7 +48944,7 @@ var init_wire2 = __esm({
|
|
|
48705
48944
|
LOCAL_DISCOVERY_ENVELOPE_SCHEMA = "local-discovery-envelope/v1";
|
|
48706
48945
|
ENVELOPE_TTL_MAX_MS = 3e4;
|
|
48707
48946
|
DEFAULT_DEADLINE_MS = 3e4;
|
|
48708
|
-
sha256Schema = external_exports.string().regex(SHA256_DIGEST_PATTERN, "not a sha256:<hex>
|
|
48947
|
+
sha256Schema = external_exports.string().regex(SHA256_DIGEST_PATTERN, "not a sha256:<hex> hash");
|
|
48709
48948
|
machineIdSchema = external_exports.string().regex(/^[A-Za-z0-9_-]{1,64}$/, "not a machine id");
|
|
48710
48949
|
nonceSchema = external_exports.string().regex(/^[A-Za-z0-9_-]{22,64}$/, "a nonce is 22 to 64 base64url characters");
|
|
48711
48950
|
envVarNameSchema = external_exports.string().regex(/^[A-Za-z_][A-Za-z0-9_]{0,127}$/, "not an environment variable name");
|
|
@@ -48719,7 +48958,7 @@ var init_wire2 = __esm({
|
|
|
48719
48958
|
alg: external_exports.literal("ed25519"),
|
|
48720
48959
|
sig: external_exports.string().regex(
|
|
48721
48960
|
/^[A-Za-z0-9+/]{86}==$/,
|
|
48722
|
-
"an Ed25519
|
|
48961
|
+
"an Ed25519 lock is 64 bytes in padded base64"
|
|
48723
48962
|
)
|
|
48724
48963
|
}).strict();
|
|
48725
48964
|
localCallEnvelopeSchema = external_exports.object({
|
|
@@ -49085,7 +49324,7 @@ function createPackageDigester(deps) {
|
|
|
49085
49324
|
const pinned = args.find((arg) => arg.startsWith(prefix))?.slice(prefix.length);
|
|
49086
49325
|
if (pinned === void 0 || !SHA256_DIGEST_PATTERN.test(pinned)) {
|
|
49087
49326
|
throw new DigestProblem(
|
|
49088
|
-
`the launch does not pull ${pkg.name} by a sha256
|
|
49327
|
+
`the launch does not pull ${pkg.name} by a sha256 hash`
|
|
49089
49328
|
);
|
|
49090
49329
|
}
|
|
49091
49330
|
return pinned;
|
|
@@ -49220,7 +49459,7 @@ function checkSignedEnvelope(envelope2, launch, options, subject) {
|
|
|
49220
49459
|
if (signature.alg !== "ed25519") {
|
|
49221
49460
|
return refuse(
|
|
49222
49461
|
envelopeInvalid(
|
|
49223
|
-
`it is
|
|
49462
|
+
`it is locked with ${String(signature.alg)}, and this machine accepts only ed25519`,
|
|
49224
49463
|
subject
|
|
49225
49464
|
)
|
|
49226
49465
|
);
|
|
@@ -49229,14 +49468,14 @@ function checkSignedEnvelope(envelope2, launch, options, subject) {
|
|
|
49229
49468
|
if (signature.key_id !== trusted) {
|
|
49230
49469
|
return refuse(
|
|
49231
49470
|
envelopeInvalid(
|
|
49232
|
-
`it
|
|
49471
|
+
`it was locked with key ${signature.key_id}, and this machine trusts key ${trusted}`,
|
|
49233
49472
|
subject
|
|
49234
49473
|
)
|
|
49235
49474
|
);
|
|
49236
49475
|
}
|
|
49237
49476
|
if (!signatureVerifies(envelope2, options.publicKeyPem)) {
|
|
49238
49477
|
return refuse(
|
|
49239
|
-
envelopeInvalid("
|
|
49478
|
+
envelopeInvalid("its lock does not match its contents", subject)
|
|
49240
49479
|
);
|
|
49241
49480
|
}
|
|
49242
49481
|
if (envelope2.machine !== options.machine)
|
|
@@ -49266,7 +49505,7 @@ function checkSignedEnvelope(envelope2, launch, options, subject) {
|
|
|
49266
49505
|
if (launch.package.digest !== envelope2.package_digest) {
|
|
49267
49506
|
return refuse(
|
|
49268
49507
|
launchMismatch(
|
|
49269
|
-
`the launch pins package
|
|
49508
|
+
`the launch pins package hash ${launch.package.digest}, and the envelope locks ${envelope2.package_digest}`
|
|
49270
49509
|
)
|
|
49271
49510
|
);
|
|
49272
49511
|
}
|
|
@@ -49274,7 +49513,7 @@ function checkSignedEnvelope(envelope2, launch, options, subject) {
|
|
|
49274
49513
|
if (launchDigest !== envelope2.launch_digest) {
|
|
49275
49514
|
return refuse(
|
|
49276
49515
|
launchMismatch(
|
|
49277
|
-
`the launch's command, args, and env names hash to ${launchDigest}, and the envelope
|
|
49516
|
+
`the launch's command, args, and env names hash to ${launchDigest}, and the envelope locks ${envelope2.launch_digest}`
|
|
49278
49517
|
)
|
|
49279
49518
|
);
|
|
49280
49519
|
}
|
|
@@ -50441,7 +50680,7 @@ async function fetchOne(input, url) {
|
|
|
50441
50680
|
Buffer.from(await sum3.arrayBuffer()).toString("utf8")
|
|
50442
50681
|
);
|
|
50443
50682
|
if (want === void 0)
|
|
50444
|
-
return { ok: false, message: `${url}.sha256 names no SHA-256
|
|
50683
|
+
return { ok: false, message: `${url}.sha256 names no SHA-256 hash` };
|
|
50445
50684
|
const file = await input.fetch(url, {
|
|
50446
50685
|
signal: AbortSignal.timeout(timeoutMs)
|
|
50447
50686
|
});
|
|
@@ -53440,7 +53679,7 @@ function createModelProxy(deps) {
|
|
|
53440
53679
|
let session;
|
|
53441
53680
|
const lost = (error) => {
|
|
53442
53681
|
deps.log(
|
|
53443
|
-
`model proxy:
|
|
53682
|
+
`model proxy: locking the frame of a call it did not forward (${reason3}) failed: ${error instanceof Error ? error.message : String(error)} session=${session ?? "unattributed"}`
|
|
53444
53683
|
);
|
|
53445
53684
|
};
|
|
53446
53685
|
try {
|
|
@@ -53856,7 +54095,7 @@ function createModelProxy(deps) {
|
|
|
53856
54095
|
void onSessionQueue(deps.exclusive, record, land).catch(
|
|
53857
54096
|
(error) => {
|
|
53858
54097
|
deps.log(
|
|
53859
|
-
`model proxy:
|
|
54098
|
+
`model proxy: locking a cache keep-alive's frame failed: ${error instanceof Error ? error.message : String(error)} session=${sessionKey}`
|
|
53860
54099
|
);
|
|
53861
54100
|
}
|
|
53862
54101
|
);
|
|
@@ -54229,7 +54468,7 @@ function createModelProxy(deps) {
|
|
|
54229
54468
|
};
|
|
54230
54469
|
const logLostFrame = (error) => {
|
|
54231
54470
|
deps.log(
|
|
54232
|
-
`model proxy:
|
|
54471
|
+
`model proxy: locking the call's frame failed, the response the caller already has is unaffected: ${error instanceof Error ? error.message : String(error)} session=${sessionKey}`
|
|
54233
54472
|
);
|
|
54234
54473
|
};
|
|
54235
54474
|
const afterLanding = (landed, errorClass2) => {
|
|
@@ -56397,7 +56636,7 @@ function createSessionHeads(deps) {
|
|
|
56397
56636
|
text5 = await response.text();
|
|
56398
56637
|
} catch (error) {
|
|
56399
56638
|
deps.log(
|
|
56400
|
-
`backfill pre-flight: the control plane did not answer (${error instanceof Error ? error.message : String(error)}); the pass
|
|
56639
|
+
`backfill pre-flight: the control plane did not answer (${error instanceof Error ? error.message : String(error)}); the pass locks nothing it cannot check`
|
|
56401
56640
|
);
|
|
56402
56641
|
return void 0;
|
|
56403
56642
|
} finally {
|
|
@@ -56405,7 +56644,7 @@ function createSessionHeads(deps) {
|
|
|
56405
56644
|
}
|
|
56406
56645
|
if (status2 < 200 || status2 >= 300) {
|
|
56407
56646
|
deps.log(
|
|
56408
|
-
`backfill pre-flight: the control plane answered ${status2}; the pass
|
|
56647
|
+
`backfill pre-flight: the control plane answered ${status2}; the pass locks nothing it cannot check`
|
|
56409
56648
|
);
|
|
56410
56649
|
return void 0;
|
|
56411
56650
|
}
|
|
@@ -56414,7 +56653,7 @@ function createSessionHeads(deps) {
|
|
|
56414
56653
|
parsed2 = answerSchema.parse(JSON.parse(text5));
|
|
56415
56654
|
} catch {
|
|
56416
56655
|
deps.log(
|
|
56417
|
-
"backfill pre-flight: the control plane's answer did not parse; the pass
|
|
56656
|
+
"backfill pre-flight: the control plane's answer did not parse; the pass locks nothing it cannot check"
|
|
56418
56657
|
);
|
|
56419
56658
|
return void 0;
|
|
56420
56659
|
}
|
|
@@ -56871,7 +57110,7 @@ async function initializeDaemon(options, server, port, ready, clock2) {
|
|
|
56871
57110
|
const sealedState = parseSealedState(
|
|
56872
57111
|
readJsonStateFile(
|
|
56873
57112
|
paths.daemonSealedState,
|
|
56874
|
-
(movedTo) => logSetAside("daemon
|
|
57113
|
+
(movedTo) => logSetAside("daemon state of locked sessions", movedTo)
|
|
56875
57114
|
)
|
|
56876
57115
|
);
|
|
56877
57116
|
let reconcileMs = 0;
|
|
@@ -58087,7 +58326,7 @@ async function initializeDaemon(options, server, port, ready, clock2) {
|
|
|
58087
58326
|
}
|
|
58088
58327
|
} catch (error) {
|
|
58089
58328
|
log(
|
|
58090
|
-
`pending session ends unavailable: ${error instanceof Error ? error.message : String(error)}; those sessions are not
|
|
58329
|
+
`pending session ends unavailable: ${error instanceof Error ? error.message : String(error)}; those sessions are not locked at this start. Check ${pendingEndsPath}`
|
|
58091
58330
|
);
|
|
58092
58331
|
}
|
|
58093
58332
|
const persistPendingEnds = () => writeSensitiveFileAtomic(
|
|
@@ -58428,7 +58667,7 @@ async function initializeDaemon(options, server, port, ready, clock2) {
|
|
|
58428
58667
|
if (key !== void 0) forgetHookId(session, key);
|
|
58429
58668
|
}
|
|
58430
58669
|
log(
|
|
58431
|
-
`session end for ${uuid} conflicts with the WAL at ${conflict.sessionUuid}:${conflict.seq}; its
|
|
58670
|
+
`session end for ${uuid} conflicts with the WAL at ${conflict.sessionUuid}:${conflict.seq}; its locked end event is in quarantine/${name}, and the end is locked again on the chain the WAL holds`
|
|
58432
58671
|
);
|
|
58433
58672
|
}
|
|
58434
58673
|
async function warmTerminalIndexes(sessionUuid2) {
|
|
@@ -59157,7 +59396,9 @@ async function initializeDaemon(options, server, port, ready, clock2) {
|
|
|
59157
59396
|
return;
|
|
59158
59397
|
}
|
|
59159
59398
|
for (const refusal of session.recorder.takeOtelRefusals())
|
|
59160
|
-
log(
|
|
59399
|
+
log(
|
|
59400
|
+
`OTel record not locked into the chain for session ${sessionId}: ${refusal}`
|
|
59401
|
+
);
|
|
59161
59402
|
}
|
|
59162
59403
|
const api = {
|
|
59163
59404
|
runContained: contained.run,
|
|
@@ -59598,7 +59839,7 @@ async function initializeDaemon(options, server, port, ready, clock2) {
|
|
|
59598
59839
|
for (const session of registry2.list()) {
|
|
59599
59840
|
for (const repair of session.recorder.takeSealRepairs()) {
|
|
59600
59841
|
log(
|
|
59601
|
-
`recorder
|
|
59842
|
+
`recorder locked an event no path returned; written anyway: ${repair}`
|
|
59602
59843
|
);
|
|
59603
59844
|
}
|
|
59604
59845
|
}
|
|
@@ -59872,6 +60113,28 @@ async function initializeDaemon(options, server, port, ready, clock2) {
|
|
|
59872
60113
|
fetch: options.fetch ?? globalThis.fetch,
|
|
59873
60114
|
log
|
|
59874
60115
|
}),
|
|
60116
|
+
// What the API stored survives a restart, so a restart sends only new
|
|
60117
|
+
// and changed memories rather than every one on the machine (#7159).
|
|
60118
|
+
storage: fileStateStorage(
|
|
60119
|
+
paths.memorySent,
|
|
60120
|
+
(movedTo) => log(
|
|
60121
|
+
movedTo === void 0 ? "memory reader: the sent record did not parse and could not be moved aside; every memory is sent again" : `memory reader: the sent record did not parse; moved it to ${movedTo}, and every memory is sent again`
|
|
60122
|
+
)
|
|
60123
|
+
),
|
|
60124
|
+
log,
|
|
60125
|
+
// A 429 is waited out within the scan. A stop ends the wait at once.
|
|
60126
|
+
wait: (ms) => new Promise((resolve28) => {
|
|
60127
|
+
if (stopping.signal.aborted) return resolve28(false);
|
|
60128
|
+
const done = (passed) => {
|
|
60129
|
+
clearTimeout(timer2);
|
|
60130
|
+
stopping.signal.removeEventListener("abort", onAbort);
|
|
60131
|
+
resolve28(passed);
|
|
60132
|
+
};
|
|
60133
|
+
const onAbort = () => done(false);
|
|
60134
|
+
const timer2 = setTimeout(() => done(true), ms);
|
|
60135
|
+
timer2.unref();
|
|
60136
|
+
stopping.signal.addEventListener("abort", onAbort, { once: true });
|
|
60137
|
+
}),
|
|
59875
60138
|
harnesses: memoryLocations,
|
|
59876
60139
|
scope: () => memoryScope.forScan(),
|
|
59877
60140
|
// Codex's store follows `CODEX_HOME`. Only the agent that enrolls
|
|
@@ -59908,9 +60171,20 @@ async function initializeDaemon(options, server, port, ready, clock2) {
|
|
|
59908
60171
|
const stella = stopped2 ? void 0 : await stellaMemories?.scan();
|
|
59909
60172
|
const scans = [...result2.scans ?? [], ...stella?.scans ?? []];
|
|
59910
60173
|
return { scans, counts: result2.counts };
|
|
59911
|
-
}).then(
|
|
59912
|
-
(
|
|
59913
|
-
|
|
60174
|
+
}).then(async (result2) => {
|
|
60175
|
+
if (stopped2 || memoryUses === void 0) return;
|
|
60176
|
+
const report = await memoryUses.report(result2.scans, result2.counts);
|
|
60177
|
+
if (report.missing.length === 0) return;
|
|
60178
|
+
log(
|
|
60179
|
+
`memory scan: the control plane holds no memory for ${report.missing.length} scanned files; they are sent again at the next scan`
|
|
60180
|
+
);
|
|
60181
|
+
memoryReader.resend(
|
|
60182
|
+
report.missing.filter((memory) => memory.harness !== "stella")
|
|
60183
|
+
);
|
|
60184
|
+
stellaMemories?.resend(
|
|
60185
|
+
report.missing.filter((memory) => memory.harness === "stella").map((memory) => memory.path)
|
|
60186
|
+
);
|
|
60187
|
+
}).catch((error) => {
|
|
59914
60188
|
log(
|
|
59915
60189
|
`memory scan failed: ${error instanceof Error ? error.message : String(error)}`
|
|
59916
60190
|
);
|
|
@@ -59995,7 +60269,7 @@ async function initializeDaemon(options, server, port, ready, clock2) {
|
|
|
59995
60269
|
});
|
|
59996
60270
|
if (!await settleWithin(sealed, timers.stopQueueMs))
|
|
59997
60271
|
log(
|
|
59998
|
-
`stop: a task held the queue for ${timers.stopQueueMs} ms; the host chain
|
|
60272
|
+
`stop: a task held the queue for ${timers.stopQueueMs} ms; the host chain locks when it finishes`
|
|
59999
60273
|
);
|
|
60000
60274
|
if (!await settleWithin(shipper.drain(), timers.stopDrainMs))
|
|
60001
60275
|
log(
|
|
@@ -64384,7 +64658,8 @@ var init_esm = __esm({
|
|
|
64384
64658
|
});
|
|
64385
64659
|
|
|
64386
64660
|
// ../../packages/tacho/src/collector/run.ts
|
|
64387
|
-
import { readFileSync as readFileSync25, unlinkSync as unlinkSync15 } from "node:fs";
|
|
64661
|
+
import { readFileSync as readFileSync25, realpathSync as realpathSync7, statSync as statSync17, unlinkSync as unlinkSync15 } from "node:fs";
|
|
64662
|
+
import { dirname as dirname29, join as join53 } from "node:path";
|
|
64388
64663
|
function stopWithin(stop, graceMs, exit, log) {
|
|
64389
64664
|
const timer = setTimeout(() => {
|
|
64390
64665
|
log(`tachod: stop did not finish within ${graceMs} ms, exiting
|
|
@@ -64446,6 +64721,87 @@ function writeDaemonPid(path2, now = /* @__PURE__ */ new Date(), execPath = proc
|
|
|
64446
64721
|
420
|
|
64447
64722
|
);
|
|
64448
64723
|
}
|
|
64724
|
+
function installedCliVersion(entry2 = process.argv[1], read2 = (path2) => readFileSync25(path2, "utf8"), realpath3 = realpathSync7) {
|
|
64725
|
+
if (entry2 === void 0) return void 0;
|
|
64726
|
+
let dir;
|
|
64727
|
+
try {
|
|
64728
|
+
dir = dirname29(realpath3(entry2));
|
|
64729
|
+
} catch {
|
|
64730
|
+
return void 0;
|
|
64731
|
+
}
|
|
64732
|
+
for (let depth = 0; depth < CLI_PACKAGE_DEPTH_MAX; depth += 1) {
|
|
64733
|
+
try {
|
|
64734
|
+
const pkg = JSON.parse(read2(join53(dir, "package.json")));
|
|
64735
|
+
if (pkg.name === "@oxagen/cli")
|
|
64736
|
+
return typeof pkg.version === "string" ? pkg.version : void 0;
|
|
64737
|
+
} catch {
|
|
64738
|
+
}
|
|
64739
|
+
const parent = dirname29(dir);
|
|
64740
|
+
if (parent === dir) return void 0;
|
|
64741
|
+
dir = parent;
|
|
64742
|
+
}
|
|
64743
|
+
return void 0;
|
|
64744
|
+
}
|
|
64745
|
+
function processProbe() {
|
|
64746
|
+
return {
|
|
64747
|
+
entry: process.argv[1],
|
|
64748
|
+
native: isNativeBuild(),
|
|
64749
|
+
execPath: process.execPath,
|
|
64750
|
+
platform: process.platform,
|
|
64751
|
+
read: (path2) => readFileSync25(path2, "utf8"),
|
|
64752
|
+
realpath: realpathSync7,
|
|
64753
|
+
stat: statSync17,
|
|
64754
|
+
exists: (path2) => {
|
|
64755
|
+
try {
|
|
64756
|
+
statSync17(path2);
|
|
64757
|
+
return true;
|
|
64758
|
+
} catch {
|
|
64759
|
+
return false;
|
|
64760
|
+
}
|
|
64761
|
+
}
|
|
64762
|
+
};
|
|
64763
|
+
}
|
|
64764
|
+
function installedIdentity(probe = processProbe()) {
|
|
64765
|
+
if (!probe.native)
|
|
64766
|
+
return installedCliVersion(probe.entry, probe.read, probe.realpath);
|
|
64767
|
+
try {
|
|
64768
|
+
const real = probe.realpath(
|
|
64769
|
+
stableExecutablePath(probe.execPath, probe.platform, probe.exists)
|
|
64770
|
+
);
|
|
64771
|
+
const info = probe.stat(real);
|
|
64772
|
+
return `${real} (${info.size} bytes, changed ${new Date(info.mtimeMs).toISOString()})`;
|
|
64773
|
+
} catch {
|
|
64774
|
+
return void 0;
|
|
64775
|
+
}
|
|
64776
|
+
}
|
|
64777
|
+
function watchInstalledVersion(options) {
|
|
64778
|
+
const atStart = options.installed();
|
|
64779
|
+
let seen;
|
|
64780
|
+
let done = false;
|
|
64781
|
+
const set = options.setInterval ?? setInterval;
|
|
64782
|
+
const clear = options.clearInterval ?? ((handle2) => clearInterval(handle2));
|
|
64783
|
+
const handle = set(() => {
|
|
64784
|
+
if (done) return;
|
|
64785
|
+
const now = options.installed();
|
|
64786
|
+
const changed = now !== void 0 && now !== options.running && now !== atStart;
|
|
64787
|
+
if (!changed) {
|
|
64788
|
+
seen = void 0;
|
|
64789
|
+
return;
|
|
64790
|
+
}
|
|
64791
|
+
if (seen !== now) {
|
|
64792
|
+
seen = now;
|
|
64793
|
+
return;
|
|
64794
|
+
}
|
|
64795
|
+
done = true;
|
|
64796
|
+
clear(handle);
|
|
64797
|
+
options.restart(now);
|
|
64798
|
+
}, options.everyMs ?? VERSION_CHECK_MS);
|
|
64799
|
+
handle.unref?.();
|
|
64800
|
+
return () => {
|
|
64801
|
+
done = true;
|
|
64802
|
+
clear(handle);
|
|
64803
|
+
};
|
|
64804
|
+
}
|
|
64449
64805
|
function ownProcStart() {
|
|
64450
64806
|
if (process.platform !== "linux") return void 0;
|
|
64451
64807
|
return readProcessStarts([process.pid], void 0, "linux")?.get(process.pid);
|
|
@@ -64567,6 +64923,17 @@ async function runDaemonProcess(options = {}) {
|
|
|
64567
64923
|
releaseDaemonPid(paths.pid, previousPid);
|
|
64568
64924
|
throw error;
|
|
64569
64925
|
}
|
|
64926
|
+
watchInstalledVersion({
|
|
64927
|
+
running: TACHO_VERSION,
|
|
64928
|
+
installed: () => installedIdentity(),
|
|
64929
|
+
restart: (installed) => {
|
|
64930
|
+
log(
|
|
64931
|
+
`tachod: this daemon runs ${TACHO_VERSION} and the CLI installed under it is now ${installed}; restarting so the service manager starts the new one
|
|
64932
|
+
`
|
|
64933
|
+
);
|
|
64934
|
+
stop("CLI update");
|
|
64935
|
+
}
|
|
64936
|
+
});
|
|
64570
64937
|
if (options.started !== void 0) {
|
|
64571
64938
|
try {
|
|
64572
64939
|
await options.started(
|
|
@@ -64583,7 +64950,7 @@ async function runDaemonProcess(options = {}) {
|
|
|
64583
64950
|
}
|
|
64584
64951
|
await new Promise(() => void 0);
|
|
64585
64952
|
}
|
|
64586
|
-
var STOP_GRACE_MS2;
|
|
64953
|
+
var STOP_GRACE_MS2, VERSION_CHECK_MS, CLI_PACKAGE_DEPTH_MAX;
|
|
64587
64954
|
var init_run2 = __esm({
|
|
64588
64955
|
"../../packages/tacho/src/collector/run.ts"() {
|
|
64589
64956
|
"use strict";
|
|
@@ -64591,8 +64958,12 @@ var init_run2 = __esm({
|
|
|
64591
64958
|
init_fs();
|
|
64592
64959
|
init_paths();
|
|
64593
64960
|
init_process_scan();
|
|
64961
|
+
init_deps();
|
|
64962
|
+
init_version();
|
|
64594
64963
|
init_daemon();
|
|
64595
64964
|
STOP_GRACE_MS2 = 5e3;
|
|
64965
|
+
VERSION_CHECK_MS = 10 * 6e4;
|
|
64966
|
+
CLI_PACKAGE_DEPTH_MAX = 6;
|
|
64596
64967
|
}
|
|
64597
64968
|
});
|
|
64598
64969
|
|
|
@@ -64605,21 +64976,21 @@ import {
|
|
|
64605
64976
|
mkdirSync as mkdirSync9,
|
|
64606
64977
|
openSync as openSync9,
|
|
64607
64978
|
readSync as readSync5,
|
|
64608
|
-
realpathSync as
|
|
64979
|
+
realpathSync as realpathSync8,
|
|
64609
64980
|
writeFileSync as writeFileSync6
|
|
64610
64981
|
} from "node:fs";
|
|
64611
|
-
import { dirname as
|
|
64982
|
+
import { dirname as dirname30, join as join54, resolve as resolve20 } from "node:path";
|
|
64612
64983
|
function bundlePath(root, relative12, create2 = false) {
|
|
64613
64984
|
const absolute = resolve20(root);
|
|
64614
64985
|
if (create2) mkdirSync9(absolute, { recursive: true, mode: 448 });
|
|
64615
64986
|
if (lstatSync10(absolute).isSymbolicLink() || !lstatSync10(absolute).isDirectory()) {
|
|
64616
64987
|
arpFail(`The bundle root ${absolute} must be a directory, not a symlink.`);
|
|
64617
64988
|
}
|
|
64618
|
-
const base2 =
|
|
64989
|
+
const base2 = realpathSync8(absolute);
|
|
64619
64990
|
let current = base2;
|
|
64620
64991
|
const parts = relative12.split("/");
|
|
64621
64992
|
for (let i2 = 0; i2 < parts.length; i2++) {
|
|
64622
|
-
current =
|
|
64993
|
+
current = join54(current, parts[i2]);
|
|
64623
64994
|
try {
|
|
64624
64995
|
const stat7 = lstatSync10(current);
|
|
64625
64996
|
if (stat7.isSymbolicLink() || i2 < parts.length - 1 && !stat7.isDirectory()) {
|
|
@@ -64633,7 +65004,7 @@ function bundlePath(root, relative12, create2 = false) {
|
|
|
64633
65004
|
else if (i2 < parts.length - 1) throw error;
|
|
64634
65005
|
}
|
|
64635
65006
|
}
|
|
64636
|
-
if (
|
|
65007
|
+
if (realpathSync8(dirname30(current)) !== dirname30(current)) {
|
|
64637
65008
|
arpFail(`The bundle directory changed while ${relative12} was read.`);
|
|
64638
65009
|
}
|
|
64639
65010
|
return current;
|
|
@@ -64651,7 +65022,8 @@ function readBounded(root, relative12, limit = ARP_MAX_BLOB_BYTES) {
|
|
|
64651
65022
|
let offset = 0;
|
|
64652
65023
|
while (offset < bytes.length) {
|
|
64653
65024
|
const count12 = readSync5(fd2, bytes, offset, bytes.length - offset, offset);
|
|
64654
|
-
if (!count12)
|
|
65025
|
+
if (!count12)
|
|
65026
|
+
arpFail(`The bundle file ${relative12} changed while it was read.`);
|
|
64655
65027
|
offset += count12;
|
|
64656
65028
|
}
|
|
64657
65029
|
if (readSync5(fd2, Buffer.alloc(1), 0, 1, offset) !== 0)
|
|
@@ -64696,7 +65068,7 @@ function readBlob(root, ref) {
|
|
|
64696
65068
|
const bytes = readBounded(root, blobPath(ref), ref.bytes);
|
|
64697
65069
|
if (bytes.length !== ref.bytes || digestBytes(bytes) !== ref.digest) {
|
|
64698
65070
|
arpFail(
|
|
64699
|
-
`Blob ${ref.digest} failed its integrity check: its bytes do not match its
|
|
65071
|
+
`Blob ${ref.digest} failed its integrity check: its bytes do not match its hash and size (${ref.bytes} bytes).`
|
|
64700
65072
|
);
|
|
64701
65073
|
}
|
|
64702
65074
|
return bytes;
|
|
@@ -64704,12 +65076,14 @@ function readBlob(root, ref) {
|
|
|
64704
65076
|
function controlJson(bytes, name) {
|
|
64705
65077
|
const value = JSON.parse(bytes.toString("utf8"));
|
|
64706
65078
|
if (!Buffer.from(jcs(value)).equals(bytes))
|
|
64707
|
-
arpFail(`The ${name} must use
|
|
65079
|
+
arpFail(`The ${name} must use JSON in one standard form.`);
|
|
64708
65080
|
function check2(item, depth) {
|
|
64709
65081
|
if (depth > MAX_CONTROL_DEPTH)
|
|
64710
65082
|
arpFail(`The ${name} nests deeper than ${MAX_CONTROL_DEPTH} levels.`);
|
|
64711
65083
|
if (typeof item === "number" && !Number.isSafeInteger(item))
|
|
64712
|
-
arpFail(
|
|
65084
|
+
arpFail(
|
|
65085
|
+
`The ${name} holds ${item}, and its numbers must be safe integers.`
|
|
65086
|
+
);
|
|
64713
65087
|
if (typeof item === "string" && /[\ud800-\udfff]/u.test(item))
|
|
64714
65088
|
arpFail(`The ${name} contains an invalid Unicode string.`);
|
|
64715
65089
|
if (item && typeof item === "object") {
|
|
@@ -64732,7 +65106,7 @@ function parseControl(schema, bytes, name) {
|
|
|
64732
65106
|
function writeCheckpoint(root, checkpoint, key) {
|
|
64733
65107
|
const parsed2 = arpCheckpointSchema.parse(checkpoint);
|
|
64734
65108
|
const bytes = Buffer.from(jcs(parsed2));
|
|
64735
|
-
controlJson(bytes, "
|
|
65109
|
+
controlJson(bytes, "save point");
|
|
64736
65110
|
const subjectDigest = digestBytes(bytes);
|
|
64737
65111
|
const attestation = {
|
|
64738
65112
|
schema: "arp.attestation/0.1",
|
|
@@ -64858,16 +65232,16 @@ function verifyBundle2(root, trustedPublicKey) {
|
|
|
64858
65232
|
const checkpoint = parseControl(
|
|
64859
65233
|
arpCheckpointSchema,
|
|
64860
65234
|
checkpointBytes,
|
|
64861
|
-
"
|
|
65235
|
+
"save point"
|
|
64862
65236
|
);
|
|
64863
65237
|
if (checkpoint.gaps.some((gap) => gap.required) || checkpoint.effects.some((effect) => effect.status === "unknown")) {
|
|
64864
|
-
arpFail("The
|
|
65238
|
+
arpFail("The save point has required gaps or unresolved effects.");
|
|
64865
65239
|
}
|
|
64866
65240
|
const checkpointDigest = digestBytes(checkpointBytes);
|
|
64867
65241
|
const attestation = parseControl(
|
|
64868
65242
|
attestationSchema,
|
|
64869
65243
|
readBounded(root, "checkpoint.attestation.json", 4096),
|
|
64870
|
-
"
|
|
65244
|
+
"save point lock"
|
|
64871
65245
|
);
|
|
64872
65246
|
if (checkpoint.issuer !== deviceKeyFingerprint(trustedPublicKey) || attestation.subject_digest !== checkpointDigest || attestation.key_id !== deviceKeyFingerprint(trustedPublicKey) || !verifyDeviceSignature(
|
|
64873
65247
|
trustedPublicKey,
|
|
@@ -64875,7 +65249,7 @@ function verifyBundle2(root, trustedPublicKey) {
|
|
|
64875
65249
|
${checkpointDigest}`,
|
|
64876
65250
|
attestation.signature
|
|
64877
65251
|
)) {
|
|
64878
|
-
arpFail("The
|
|
65252
|
+
arpFail("The save point's lock does not match the trusted key.");
|
|
64879
65253
|
}
|
|
64880
65254
|
let total2 = 0;
|
|
64881
65255
|
const seen = /* @__PURE__ */ new Map();
|
|
@@ -64961,7 +65335,7 @@ ${checkpointDigest}`,
|
|
|
64961
65335
|
const evidence = JSON.parse(evidenceBytes.toString("utf8"));
|
|
64962
65336
|
if (!Buffer.from(jcs(evidence)).equals(evidenceBytes)) {
|
|
64963
65337
|
arpFail(
|
|
64964
|
-
"The evidence array must use
|
|
65338
|
+
"The evidence array must use JSON in one standard form without changing native events."
|
|
64965
65339
|
);
|
|
64966
65340
|
}
|
|
64967
65341
|
if (!Array.isArray(evidence) || evidence.length > MAX_EVIDENCE_EVENTS)
|
|
@@ -65056,7 +65430,7 @@ function readHandoffFrames(bytes) {
|
|
|
65056
65430
|
}
|
|
65057
65431
|
if (frame2.content_digest !== digestBytes(frame2.content) || frame2.token_cost !== budgetTokens(frame2.content)) {
|
|
65058
65432
|
arpFail(
|
|
65059
|
-
`Context frame ${frame2.id} has an invalid CGP content
|
|
65433
|
+
`Context frame ${frame2.id} has an invalid CGP content hash or token cost.`
|
|
65060
65434
|
);
|
|
65061
65435
|
}
|
|
65062
65436
|
}
|
|
@@ -65464,20 +65838,20 @@ function checkDeterministicComposition(journal) {
|
|
|
65464
65838
|
});
|
|
65465
65839
|
} else if (first.digest !== event.composition_digest) {
|
|
65466
65840
|
violations.push(
|
|
65467
|
-
`the frame set rendered at seq ${event.seq} is identical to seq ${first.seq} but composed to a different
|
|
65841
|
+
`the frame set rendered at seq ${event.seq} is identical to seq ${first.seq} but composed to a different hash: an unchanged set must render byte-identically (section 1)`
|
|
65468
65842
|
);
|
|
65469
65843
|
}
|
|
65470
65844
|
}
|
|
65471
65845
|
if (digested === 0) {
|
|
65472
65846
|
return skip(
|
|
65473
65847
|
CHECK_COMPOSITION,
|
|
65474
|
-
"no composition
|
|
65848
|
+
"no composition hashes recorded: prefix stability not exercised by this journal"
|
|
65475
65849
|
);
|
|
65476
65850
|
}
|
|
65477
65851
|
return fromViolations(
|
|
65478
65852
|
CHECK_COMPOSITION,
|
|
65479
65853
|
violations,
|
|
65480
|
-
`${digested}
|
|
65854
|
+
`${digested} hash-carrying prompt(s); identical frame sets composed identically`
|
|
65481
65855
|
);
|
|
65482
65856
|
}
|
|
65483
65857
|
function checkEffectExactlyOnce(journal) {
|
|
@@ -65576,11 +65950,11 @@ import {
|
|
|
65576
65950
|
mkdirSync as mkdirSync10,
|
|
65577
65951
|
openSync as openSync10,
|
|
65578
65952
|
readSync as readSync6,
|
|
65579
|
-
realpathSync as
|
|
65953
|
+
realpathSync as realpathSync9,
|
|
65580
65954
|
rmSync as rmSync12,
|
|
65581
65955
|
writeFileSync as writeFileSync7
|
|
65582
65956
|
} from "node:fs";
|
|
65583
|
-
import { dirname as
|
|
65957
|
+
import { dirname as dirname31, isAbsolute as isAbsolute15, join as join55, relative as relative6, resolve as resolve21, sep as sep8 } from "node:path";
|
|
65584
65958
|
function outsideProfile(path2) {
|
|
65585
65959
|
return HARNESS_CONFIG_PATH.test(path2) || CREDENTIAL_PATH.test(path2);
|
|
65586
65960
|
}
|
|
@@ -65595,9 +65969,7 @@ function readRegular(label2, path2, limit) {
|
|
|
65595
65969
|
try {
|
|
65596
65970
|
const before = fstatSync3(fd2);
|
|
65597
65971
|
if (!before.isFile() || before.size > limit)
|
|
65598
|
-
arpFail(
|
|
65599
|
-
`${label2} ${path2} is not a regular file of at most ${limit} bytes.`
|
|
65600
|
-
);
|
|
65972
|
+
arpFail(`${label2} ${path2} is not a regular file of at most ${limit} bytes.`);
|
|
65601
65973
|
const bytes = Buffer.alloc(before.size);
|
|
65602
65974
|
let offset = 0;
|
|
65603
65975
|
while (offset < bytes.length) {
|
|
@@ -65636,9 +66008,9 @@ function within2(root, path2) {
|
|
|
65636
66008
|
}
|
|
65637
66009
|
function newPath(path2) {
|
|
65638
66010
|
const full = resolve21(path2);
|
|
65639
|
-
return
|
|
65640
|
-
|
|
65641
|
-
full.slice(
|
|
66011
|
+
return join55(
|
|
66012
|
+
realpathSync9(dirname31(full)),
|
|
66013
|
+
full.slice(dirname31(full).length + 1)
|
|
65642
66014
|
);
|
|
65643
66015
|
}
|
|
65644
66016
|
function sourcePath(root, path2) {
|
|
@@ -65650,7 +66022,7 @@ function sourcePath(root, path2) {
|
|
|
65650
66022
|
}
|
|
65651
66023
|
let current = root;
|
|
65652
66024
|
for (const part2 of path2.split("/")) {
|
|
65653
|
-
current =
|
|
66025
|
+
current = join55(current, part2);
|
|
65654
66026
|
if (lstatSync11(current).isSymbolicLink())
|
|
65655
66027
|
arpFail(
|
|
65656
66028
|
`${path2} is a symlink or passes through one. Symlinks require a resource adapter.`
|
|
@@ -65701,15 +66073,15 @@ function readBrief(path2) {
|
|
|
65701
66073
|
function captureCheckpoint(options) {
|
|
65702
66074
|
if (!options.attestBoundary)
|
|
65703
66075
|
arpFail(
|
|
65704
|
-
"Pass --attest-boundary to
|
|
66076
|
+
"Pass --attest-boundary to confirm that the stopped workspace matches the brief's evidence boundary."
|
|
65705
66077
|
);
|
|
65706
|
-
const root =
|
|
66078
|
+
const root = realpathSync9(options.workspace);
|
|
65707
66079
|
if (!lstatSync11(root).isDirectory())
|
|
65708
66080
|
arpFail(`The workspace ${root} is not a directory.`);
|
|
65709
66081
|
const out = newPath(options.out);
|
|
65710
66082
|
if (within2(root, out))
|
|
65711
66083
|
arpFail(
|
|
65712
|
-
`Write the
|
|
66084
|
+
`Write the save point outside its source workspace; ${out} is inside ${root}.`
|
|
65713
66085
|
);
|
|
65714
66086
|
const brief = readBrief(options.briefFile);
|
|
65715
66087
|
const evidenceBytes = readRegular(
|
|
@@ -65865,7 +66237,7 @@ function captureCheckpoint(options) {
|
|
|
65865
66237
|
function prepareCheckpoint(options) {
|
|
65866
66238
|
const harness = external_exports.enum(["codex", "claude-code", "cursor", "stella"]).parse(options.harness);
|
|
65867
66239
|
const verified = verifyBundle2(options.bundle, options.publicKey);
|
|
65868
|
-
const bundle2 =
|
|
66240
|
+
const bundle2 = realpathSync9(options.bundle);
|
|
65869
66241
|
const { checkpoint, workspace, checkpointDigest, events } = verified;
|
|
65870
66242
|
const blob = (ref) => verified.blobs.get(ref.digest) ?? arpFail(`Blob ${ref.digest} was not read during verification.`);
|
|
65871
66243
|
const traceReport = runOracles(projectToTrace(events));
|
|
@@ -65878,15 +66250,15 @@ function prepareCheckpoint(options) {
|
|
|
65878
66250
|
);
|
|
65879
66251
|
const taskBytes = blob(checkpoint.task);
|
|
65880
66252
|
const contextBytes = blob(checkpoint.context);
|
|
65881
|
-
rejectSecrets("The
|
|
65882
|
-
rejectSecrets("The
|
|
66253
|
+
rejectSecrets("The save point's task", taskBytes);
|
|
66254
|
+
rejectSecrets("The save point's context", contextBytes);
|
|
65883
66255
|
const task = external_exports.object({ request: external_exports.string().min(1).max(64e3) }).strict().safeParse(JSON.parse(taskBytes.toString("utf8")));
|
|
65884
66256
|
if (!task.success)
|
|
65885
|
-
arpFail(`The
|
|
66257
|
+
arpFail(`The save point's task is not valid: ${zodIssues(task.error)}.`);
|
|
65886
66258
|
const frames = readHandoffFrames(contextBytes);
|
|
65887
66259
|
if (!sameJson(blob(checkpoint.environment), CAPTURED_ENVIRONMENT) || !sameJson(blob(checkpoint.authority), CAPTURED_AUTHORITY) || !sameJson(blob(checkpoint.tools), CAPTURED_TOOLS)) {
|
|
65888
66260
|
arpFail(
|
|
65889
|
-
"The
|
|
66261
|
+
"The save point needs an environment, tool, or authority adapter not supported here."
|
|
65890
66262
|
);
|
|
65891
66263
|
}
|
|
65892
66264
|
const unsupported = checkpoint.gaps.filter(
|
|
@@ -65894,7 +66266,7 @@ function prepareCheckpoint(options) {
|
|
|
65894
66266
|
);
|
|
65895
66267
|
if (workspace.repositories.length > 0 || unsupported.length > 0) {
|
|
65896
66268
|
arpFail(
|
|
65897
|
-
`The
|
|
66269
|
+
`The save point requires a repository or gap adapter not supported here${unsupported.length > 0 ? ` (gaps: ${unsupported.map((gap) => gap.code).join(", ")})` : ""}.`
|
|
65898
66270
|
);
|
|
65899
66271
|
}
|
|
65900
66272
|
const restore = workspace.entries.map((entry2) => {
|
|
@@ -65917,23 +66289,23 @@ function prepareCheckpoint(options) {
|
|
|
65917
66289
|
});
|
|
65918
66290
|
mkdirSync10(destination, { mode: 448 });
|
|
65919
66291
|
try {
|
|
65920
|
-
const restored =
|
|
66292
|
+
const restored = join55(destination, "workspace");
|
|
65921
66293
|
mkdirSync10(restored, { mode: 448 });
|
|
65922
66294
|
for (const item of restore) {
|
|
65923
|
-
const path2 =
|
|
66295
|
+
const path2 = join55(restored, item.path);
|
|
65924
66296
|
if (item.kind === "directory")
|
|
65925
66297
|
mkdirSync10(path2, { recursive: true, mode: 448 });
|
|
65926
66298
|
else {
|
|
65927
|
-
mkdirSync10(
|
|
66299
|
+
mkdirSync10(dirname31(path2), { recursive: true, mode: 448 });
|
|
65928
66300
|
writeFileSync7(path2, item.bytes, {
|
|
65929
66301
|
flag: "wx",
|
|
65930
66302
|
mode: item.executable ? 448 : 384
|
|
65931
66303
|
});
|
|
65932
66304
|
}
|
|
65933
66305
|
}
|
|
65934
|
-
const promptDir =
|
|
66306
|
+
const promptDir = join55(restored, ".arp");
|
|
65935
66307
|
mkdirSync10(promptDir, { mode: 448 });
|
|
65936
|
-
const promptFile =
|
|
66308
|
+
const promptFile = join55(promptDir, "handoff.json");
|
|
65937
66309
|
const prompt = {
|
|
65938
66310
|
checkpoint_digest: checkpointDigest,
|
|
65939
66311
|
task: task.data.request,
|
|
@@ -65950,7 +66322,7 @@ function prepareCheckpoint(options) {
|
|
|
65950
66322
|
flag: "wx",
|
|
65951
66323
|
mode: 384
|
|
65952
66324
|
});
|
|
65953
|
-
const reportPath =
|
|
66325
|
+
const reportPath = join55(destination, "report.json");
|
|
65954
66326
|
writeFileSync7(
|
|
65955
66327
|
reportPath,
|
|
65956
66328
|
jcs(
|
|
@@ -66065,7 +66437,7 @@ var init_transfer = __esm({
|
|
|
66065
66437
|
|
|
66066
66438
|
// ../../packages/tacho/src/cli/arp.ts
|
|
66067
66439
|
function addArpCommands(program2, deps = defaultCliDeps()) {
|
|
66068
|
-
const arp = program2.command("arp").description("Capture and prepare local Agent Run Protocol
|
|
66440
|
+
const arp = program2.command("arp").description("Capture and prepare local Agent Run Protocol save points");
|
|
66069
66441
|
async function report(operation, next) {
|
|
66070
66442
|
try {
|
|
66071
66443
|
deps.out(JSON.stringify(await operation()));
|
|
@@ -66075,12 +66447,12 @@ function addArpCommands(program2, deps = defaultCliDeps()) {
|
|
|
66075
66447
|
process.exitCode = 1;
|
|
66076
66448
|
}
|
|
66077
66449
|
}
|
|
66078
|
-
arp.command("capture").description("
|
|
66450
|
+
arp.command("capture").description("Lock selected files and a brief at a stopped turn boundary").requiredOption("--workspace <directory>", "Stopped source workspace").requiredOption("--evidence <file>", "Tacho export ending at turn_end").requiredOption(
|
|
66079
66451
|
"--brief <file>",
|
|
66080
66452
|
"Transfer brief and explicit file selection"
|
|
66081
|
-
).requiredOption("--out <directory>", "New
|
|
66453
|
+
).requiredOption("--out <directory>", "New save point directory").requiredOption("--key <file>", "Key file that locks the save point").requiredOption(
|
|
66082
66454
|
"--attest-boundary",
|
|
66083
|
-
"
|
|
66455
|
+
"Confirm that the stopped workspace matches the evidence boundary"
|
|
66084
66456
|
).action(
|
|
66085
66457
|
async (opts) => {
|
|
66086
66458
|
await report(
|
|
@@ -66096,22 +66468,27 @@ function addArpCommands(program2, deps = defaultCliDeps()) {
|
|
|
66096
66468
|
);
|
|
66097
66469
|
}
|
|
66098
66470
|
);
|
|
66099
|
-
arp.command("verify").description(
|
|
66100
|
-
|
|
66101
|
-
|
|
66102
|
-
|
|
66103
|
-
|
|
66104
|
-
|
|
66105
|
-
|
|
66106
|
-
|
|
66471
|
+
arp.command("verify").description(
|
|
66472
|
+
"Check that a save point is unchanged, using a pinned public key"
|
|
66473
|
+
).requiredOption("--bundle <directory>", "Save point directory").requiredOption(
|
|
66474
|
+
"--public-key <key>",
|
|
66475
|
+
"Trusted public key for the save point"
|
|
66476
|
+
).action(async (opts) => {
|
|
66477
|
+
await report(async () => {
|
|
66478
|
+
const verified = await verifyBundle2(opts.bundle, opts.publicKey);
|
|
66479
|
+
return { checkpointDigest: verified.checkpointDigest };
|
|
66480
|
+
}, "Check that --bundle names a save point directory and that --public-key matches the key that locked the save point. Run `oxagen arp verify --help` for each option.");
|
|
66107
66481
|
});
|
|
66108
|
-
arp.command("prepare").description("Restore selected files and write a prompt for a fresh run").requiredOption("--bundle <directory>", "
|
|
66482
|
+
arp.command("prepare").description("Restore selected files and write a prompt for a fresh run").requiredOption("--bundle <directory>", "Save point directory").requiredOption("--destination <directory>", "New preparation directory").requiredOption(
|
|
66483
|
+
"--public-key <key>",
|
|
66484
|
+
"Trusted public key for the save point"
|
|
66485
|
+
).addOption(
|
|
66109
66486
|
new Option("--harness <name>", "Destination harness").choices(["claude-code", "codex", "cursor", "stella"]).makeOptionMandatory()
|
|
66110
66487
|
).action(
|
|
66111
66488
|
async (opts) => {
|
|
66112
66489
|
await report(
|
|
66113
66490
|
() => prepareCheckpoint(opts),
|
|
66114
|
-
"Check that --bundle names a
|
|
66491
|
+
"Check that --bundle names a save point directory, that --public-key matches the key that locked the save point, and that --destination names a directory that does not exist yet. Run `oxagen arp prepare --help` for each option."
|
|
66115
66492
|
);
|
|
66116
66493
|
}
|
|
66117
66494
|
);
|
|
@@ -66642,8 +67019,8 @@ var init_package = __esm({
|
|
|
66642
67019
|
"package.json"() {
|
|
66643
67020
|
package_default = {
|
|
66644
67021
|
name: "@oxagen/cli",
|
|
66645
|
-
version: "3.0.
|
|
66646
|
-
description: "Oxagen governance CLI
|
|
67022
|
+
version: "3.0.1-27",
|
|
67023
|
+
description: "Oxagen governance CLI: spend, source tracking, grounding, credentials, and audit (agentic coding lives in the stella CLI)",
|
|
66647
67024
|
type: "module",
|
|
66648
67025
|
main: "./dist/index.js",
|
|
66649
67026
|
bin: {
|
|
@@ -66709,10 +67086,10 @@ var init_package = __esm({
|
|
|
66709
67086
|
|
|
66710
67087
|
// src/lib/atomic-write.ts
|
|
66711
67088
|
import { writeFileSync as writeFileSync8, renameSync as renameSync7, unlinkSync as unlinkSync16, existsSync as existsSync26 } from "node:fs";
|
|
66712
|
-
import { dirname as
|
|
67089
|
+
import { dirname as dirname32, join as join56 } from "node:path";
|
|
66713
67090
|
function atomicWriteFileSync(path2, data, mode) {
|
|
66714
|
-
const dir =
|
|
66715
|
-
const tmp =
|
|
67091
|
+
const dir = dirname32(path2);
|
|
67092
|
+
const tmp = join56(
|
|
66716
67093
|
dir,
|
|
66717
67094
|
`.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2)}.tmp`
|
|
66718
67095
|
);
|
|
@@ -66737,8 +67114,8 @@ var init_atomic_write = __esm({
|
|
|
66737
67114
|
|
|
66738
67115
|
// src/lib/config.ts
|
|
66739
67116
|
import { homedir as homedir9 } from "os";
|
|
66740
|
-
import { join as
|
|
66741
|
-
import { readFileSync as readFileSync27, mkdirSync as mkdirSync11, existsSync as existsSync27, statSync as
|
|
67117
|
+
import { join as join57 } from "path";
|
|
67118
|
+
import { readFileSync as readFileSync27, mkdirSync as mkdirSync11, existsSync as existsSync27, statSync as statSync18 } from "fs";
|
|
66742
67119
|
function getConfigDir() {
|
|
66743
67120
|
return CONFIG_DIR;
|
|
66744
67121
|
}
|
|
@@ -66768,7 +67145,7 @@ function parseConfig(raw) {
|
|
|
66768
67145
|
function readConfig() {
|
|
66769
67146
|
let identity;
|
|
66770
67147
|
try {
|
|
66771
|
-
const info =
|
|
67148
|
+
const info = statSync18(CONFIG_FILE);
|
|
66772
67149
|
identity = `${info.ino}:${info.size}:${info.mtimeMs}`;
|
|
66773
67150
|
} catch {
|
|
66774
67151
|
cached2 = void 0;
|
|
@@ -66824,8 +67201,8 @@ var CONFIG_DIR, CONFIG_FILE, STRING_FIELDS, TELEMETRY_FIELDS, cached2;
|
|
|
66824
67201
|
var init_config = __esm({
|
|
66825
67202
|
"src/lib/config.ts"() {
|
|
66826
67203
|
init_atomic_write();
|
|
66827
|
-
CONFIG_DIR =
|
|
66828
|
-
CONFIG_FILE =
|
|
67204
|
+
CONFIG_DIR = join57(homedir9(), ".config", "oxagen");
|
|
67205
|
+
CONFIG_FILE = join57(CONFIG_DIR, "config.json");
|
|
66829
67206
|
STRING_FIELDS = [
|
|
66830
67207
|
"token",
|
|
66831
67208
|
"orgSlug",
|
|
@@ -66870,16 +67247,16 @@ import {
|
|
|
66870
67247
|
writeFile as writeFile2
|
|
66871
67248
|
} from "node:fs/promises";
|
|
66872
67249
|
import { homedir as homedir10 } from "node:os";
|
|
66873
|
-
import { join as
|
|
67250
|
+
import { join as join58 } from "node:path";
|
|
66874
67251
|
function isDebugEnabled() {
|
|
66875
67252
|
const v = process.env[DEBUG_ENV];
|
|
66876
67253
|
return v === "1" || v === "true";
|
|
66877
67254
|
}
|
|
66878
67255
|
function logsDir() {
|
|
66879
|
-
return
|
|
67256
|
+
return join58(homedir10(), ".oxagen", "logs");
|
|
66880
67257
|
}
|
|
66881
67258
|
function debugLogFile() {
|
|
66882
|
-
return
|
|
67259
|
+
return join58(logsDir(), "cli.output");
|
|
66883
67260
|
}
|
|
66884
67261
|
function sanitize(value, depth = 0) {
|
|
66885
67262
|
if (value === null || value === void 0) return value;
|
|
@@ -67101,12 +67478,12 @@ function diagnosticHeaders(res) {
|
|
|
67101
67478
|
}
|
|
67102
67479
|
function httpErrorHint(status2, traceId) {
|
|
67103
67480
|
if (status2 >= 500) {
|
|
67104
|
-
return "Server-side error
|
|
67481
|
+
return "Server-side error. The stack lives in the API's runtime logs, not here. " + (traceId ? `Look up request id "${traceId}" (its region prefix names the deployment): \`vercel logs <deployment-url>\` or the Vercel dashboard \u2192 Logs.` : "Check the API deployment's runtime logs.");
|
|
67105
67482
|
}
|
|
67106
67483
|
if (status2 === 401 || status2 === 403) {
|
|
67107
67484
|
return "Auth/scope rejected. Re-check `oxagen login` or OXAGEN_API_TOKEN / OXAGEN_ORG_ID / OXAGEN_WORKSPACE_ID.";
|
|
67108
67485
|
}
|
|
67109
|
-
if (status2 === 429) return "Rate limited
|
|
67486
|
+
if (status2 === 429) return "Rate limited. Honor the retry-after header.";
|
|
67110
67487
|
return void 0;
|
|
67111
67488
|
}
|
|
67112
67489
|
async function buildHttpError(event, method, url, path2, res, startedAt, secret) {
|
|
@@ -68366,7 +68743,7 @@ function printProjection(opts, writer) {
|
|
|
68366
68743
|
const factor = cheap.totalUsd > 0 ? (dear.totalUsd / cheap.totalUsd).toFixed(1) : "\u221E";
|
|
68367
68744
|
out("");
|
|
68368
68745
|
out(
|
|
68369
|
-
` cheapest: ${cheap.label} (${formatUsd(cheap.totalUsd)})
|
|
68746
|
+
` cheapest: ${cheap.label} (${formatUsd(cheap.totalUsd)}), ${factor}\xD7 cheaper than ${dear.label}.`
|
|
68370
68747
|
);
|
|
68371
68748
|
}
|
|
68372
68749
|
if (rows.some((r) => r.fallback))
|
|
@@ -69586,8 +69963,8 @@ function checkLine(check2) {
|
|
|
69586
69963
|
async function contextRevert(proposalId, opts, writer = stdoutWriter) {
|
|
69587
69964
|
const out = createOutput({ json: opts.json }, writer);
|
|
69588
69965
|
if (!proposalId || !PROPOSAL_ID.test(proposalId)) {
|
|
69589
|
-
writer.writeErr("error: name the merged
|
|
69590
|
-
writer.writeErr("usage: oxagen context revert <
|
|
69966
|
+
writer.writeErr("error: name the merged suggestion, such as prp_01k5ru4a");
|
|
69967
|
+
writer.writeErr("usage: oxagen context revert <suggestionId> [--json]");
|
|
69591
69968
|
process.exitCode = 2;
|
|
69592
69969
|
return;
|
|
69593
69970
|
}
|
|
@@ -69723,7 +70100,7 @@ async function steeringFindings(opts = {}, writer = stdoutWriter) {
|
|
|
69723
70100
|
if (index > 0) writer.write("");
|
|
69724
70101
|
writer.write(`${repository.full_name} (${repository.provider})`);
|
|
69725
70102
|
printTable(
|
|
69726
|
-
["FINDING", "KIND", "FILE", "RECORD", "PULL REQUEST", "
|
|
70103
|
+
["FINDING", "KIND", "FILE", "RECORD", "PULL REQUEST", "SUGGESTION"],
|
|
69727
70104
|
repository.findings.map(findingRow),
|
|
69728
70105
|
writer
|
|
69729
70106
|
);
|
|
@@ -69738,7 +70115,7 @@ async function steeringFindings(opts = {}, writer = stdoutWriter) {
|
|
|
69738
70115
|
);
|
|
69739
70116
|
if (promotable) {
|
|
69740
70117
|
writer.write(
|
|
69741
|
-
"Promote a contradiction to a
|
|
70118
|
+
"Promote a contradiction to a suggestion with `oxagen steering promote <finding-id>`."
|
|
69742
70119
|
);
|
|
69743
70120
|
}
|
|
69744
70121
|
}
|
|
@@ -70556,9 +70933,9 @@ var init_git = __esm({
|
|
|
70556
70933
|
|
|
70557
70934
|
// ../../packages/steering-freshness/src/cache.ts
|
|
70558
70935
|
import { mkdir as mkdir4, readFile as readFile6, writeFile as writeFile4 } from "node:fs/promises";
|
|
70559
|
-
import { dirname as
|
|
70936
|
+
import { dirname as dirname33, join as join59 } from "node:path";
|
|
70560
70937
|
function stampPath(gitCommonDir) {
|
|
70561
|
-
return
|
|
70938
|
+
return join59(gitCommonDir, "oxagen", "steering-freshness.json");
|
|
70562
70939
|
}
|
|
70563
70940
|
async function readFetchStamp(gitCommonDir, io = defaultIo) {
|
|
70564
70941
|
try {
|
|
@@ -70579,7 +70956,7 @@ async function readFetchStamp(gitCommonDir, io = defaultIo) {
|
|
|
70579
70956
|
async function writeFetchStamp(gitCommonDir, stamp, io = defaultIo) {
|
|
70580
70957
|
const path2 = stampPath(gitCommonDir);
|
|
70581
70958
|
try {
|
|
70582
|
-
await io.mkdirp(
|
|
70959
|
+
await io.mkdirp(dirname33(path2));
|
|
70583
70960
|
await io.write(path2, `${JSON.stringify(stamp)}
|
|
70584
70961
|
`, "utf8");
|
|
70585
70962
|
} catch {
|
|
@@ -70610,24 +70987,24 @@ var init_cache = __esm({
|
|
|
70610
70987
|
// ../../packages/steering-freshness/src/hooks.ts
|
|
70611
70988
|
import { mkdir as mkdir5, readFile as readFile7, writeFile as writeFile5 } from "node:fs/promises";
|
|
70612
70989
|
import { homedir as homedir11 } from "node:os";
|
|
70613
|
-
import { dirname as
|
|
70990
|
+
import { dirname as dirname34, join as join60 } from "node:path";
|
|
70614
70991
|
function hookCommand(harness) {
|
|
70615
70992
|
return `oxagen steering gate --harness ${harness}`;
|
|
70616
70993
|
}
|
|
70617
70994
|
function hookConfigPath(projectRoot, harness, env = process.env, home = homedir11()) {
|
|
70618
70995
|
switch (harness) {
|
|
70619
70996
|
case "claude-code":
|
|
70620
|
-
return
|
|
70997
|
+
return join60(projectRoot, ".claude", "settings.json");
|
|
70621
70998
|
case "codex":
|
|
70622
|
-
return
|
|
70999
|
+
return join60(env["CODEX_HOME"] ?? join60(home, ".codex"), "hooks.json");
|
|
70623
71000
|
case "cursor":
|
|
70624
|
-
return
|
|
71001
|
+
return join60(home, ".cursor", "hooks.json");
|
|
70625
71002
|
case "stella":
|
|
70626
|
-
return
|
|
71003
|
+
return join60(env["STELLA_HOME"] ?? join60(home, ".stella"), "stella.toml");
|
|
70627
71004
|
}
|
|
70628
71005
|
}
|
|
70629
71006
|
function stellaJsonPath(env, home) {
|
|
70630
|
-
return
|
|
71007
|
+
return join60(env["STELLA_HOME"] ?? join60(home, ".stella"), "settings.json");
|
|
70631
71008
|
}
|
|
70632
71009
|
function isRecord8(v) {
|
|
70633
71010
|
return v !== null && typeof v === "object" && !Array.isArray(v);
|
|
@@ -70714,7 +71091,7 @@ async function installJsonGroupHook(path2, harness, entry2, io) {
|
|
|
70714
71091
|
};
|
|
70715
71092
|
}
|
|
70716
71093
|
const had = hasGroupHook(loaded.config);
|
|
70717
|
-
await io.mkdirp(
|
|
71094
|
+
await io.mkdirp(dirname34(path2));
|
|
70718
71095
|
await io.write(
|
|
70719
71096
|
path2,
|
|
70720
71097
|
`${JSON.stringify(withGroupHook(loaded.config, entry2), null, 2)}
|
|
@@ -70816,7 +71193,7 @@ async function installCursorHook(path2, io) {
|
|
|
70816
71193
|
];
|
|
70817
71194
|
const next = { ...config, hooks };
|
|
70818
71195
|
if (next.version === void 0) next.version = 1;
|
|
70819
|
-
await io.mkdirp(
|
|
71196
|
+
await io.mkdirp(dirname34(path2));
|
|
70820
71197
|
await io.write(path2, `${JSON.stringify(next, null, 2)}
|
|
70821
71198
|
`, "utf8");
|
|
70822
71199
|
return {
|
|
@@ -70999,7 +71376,7 @@ async function installStellaHook(projectRoot, io, env, home) {
|
|
|
70999
71376
|
}
|
|
71000
71377
|
const separator = base2.length === 0 ? "" : eol;
|
|
71001
71378
|
const next = `${base2}${separator}${renderStellaBlock(eol)}`;
|
|
71002
|
-
await io.mkdirp(
|
|
71379
|
+
await io.mkdirp(dirname34(path2));
|
|
71003
71380
|
await io.write(path2, next, "utf8");
|
|
71004
71381
|
return {
|
|
71005
71382
|
harness: "stella",
|
|
@@ -71287,7 +71664,7 @@ var init_policy = __esm({
|
|
|
71287
71664
|
// ../../packages/steering-freshness/src/settings.ts
|
|
71288
71665
|
import { readFile as readFile8 } from "node:fs/promises";
|
|
71289
71666
|
import { homedir as homedir12 } from "node:os";
|
|
71290
|
-
import { join as
|
|
71667
|
+
import { join as join61 } from "node:path";
|
|
71291
71668
|
async function readLayer(scope, path2, read2) {
|
|
71292
71669
|
let text5;
|
|
71293
71670
|
try {
|
|
@@ -71339,14 +71716,14 @@ function parseLayer(scope, path2, text5) {
|
|
|
71339
71716
|
}
|
|
71340
71717
|
async function loadSteeringSettings({
|
|
71341
71718
|
projectRoot,
|
|
71342
|
-
userSettingsPath =
|
|
71719
|
+
userSettingsPath = join61(homedir12(), USER_SETTINGS_RELATIVE),
|
|
71343
71720
|
read: read2 = readFile8,
|
|
71344
71721
|
workspacePolicy = null
|
|
71345
71722
|
}) {
|
|
71346
71723
|
const targets = [
|
|
71347
71724
|
["user", userSettingsPath],
|
|
71348
|
-
["project",
|
|
71349
|
-
["local",
|
|
71725
|
+
["project", join61(projectRoot, PROJECT_DIR_NAME, PROJECT_SETTINGS_FILE)],
|
|
71726
|
+
["local", join61(projectRoot, PROJECT_DIR_NAME, LOCAL_SETTINGS_FILE)]
|
|
71350
71727
|
];
|
|
71351
71728
|
const layers = [];
|
|
71352
71729
|
const warnings = [];
|
|
@@ -71409,7 +71786,7 @@ var init_settings = __esm({
|
|
|
71409
71786
|
"use strict";
|
|
71410
71787
|
init_git();
|
|
71411
71788
|
init_policy();
|
|
71412
|
-
USER_SETTINGS_RELATIVE =
|
|
71789
|
+
USER_SETTINGS_RELATIVE = join61(
|
|
71413
71790
|
".config",
|
|
71414
71791
|
"oxagen",
|
|
71415
71792
|
"settings.json"
|
|
@@ -71422,7 +71799,7 @@ var init_settings = __esm({
|
|
|
71422
71799
|
|
|
71423
71800
|
// ../../packages/steering-freshness/src/check.ts
|
|
71424
71801
|
import { lstat as lstat4 } from "node:fs/promises";
|
|
71425
|
-
import { isAbsolute as isAbsolute16, join as
|
|
71802
|
+
import { isAbsolute as isAbsolute16, join as join62, resolve as resolve22 } from "node:path";
|
|
71426
71803
|
function publishedCommits(platform) {
|
|
71427
71804
|
if (platform.headCommits && platform.headCommits.length > 0)
|
|
71428
71805
|
return platform.headCommits;
|
|
@@ -71759,7 +72136,7 @@ async function absentFromDisk(root, paths) {
|
|
|
71759
72136
|
const flags = await Promise.all(
|
|
71760
72137
|
paths.map(async (path2) => {
|
|
71761
72138
|
try {
|
|
71762
|
-
await lstat4(
|
|
72139
|
+
await lstat4(join62(root, path2));
|
|
71763
72140
|
return false;
|
|
71764
72141
|
} catch {
|
|
71765
72142
|
return true;
|
|
@@ -71818,7 +72195,7 @@ var init_check = __esm({
|
|
|
71818
72195
|
// ../../packages/steering-freshness/src/sync.ts
|
|
71819
72196
|
import { mkdtemp, rm as rm3, writeFile as writeFile6 } from "node:fs/promises";
|
|
71820
72197
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
71821
|
-
import { join as
|
|
72198
|
+
import { join as join63 } from "node:path";
|
|
71822
72199
|
function refuse3(refusal, message) {
|
|
71823
72200
|
return {
|
|
71824
72201
|
applied: false,
|
|
@@ -71999,9 +72376,9 @@ async function syncSteering(opts) {
|
|
|
71999
72376
|
};
|
|
72000
72377
|
}
|
|
72001
72378
|
async function commitPaths(ctx, message, paths) {
|
|
72002
|
-
const dir = await mkdtemp(
|
|
72379
|
+
const dir = await mkdtemp(join63(tmpdir2(), "oxagen-steering-sync-"));
|
|
72003
72380
|
try {
|
|
72004
|
-
const list2 =
|
|
72381
|
+
const list2 = join63(dir, "pathspec");
|
|
72005
72382
|
await writeFile6(list2, `${paths.join("\0")}\0`, "utf8");
|
|
72006
72383
|
await git3(
|
|
72007
72384
|
ctx,
|
|
@@ -72432,6 +72809,8 @@ function parseLedgerFileName(name) {
|
|
|
72432
72809
|
}
|
|
72433
72810
|
function classifySteering(parts) {
|
|
72434
72811
|
const name = parts[parts.length - 1];
|
|
72812
|
+
if (parts[1] === PEOPLE_DIR && PERSON_FOLDER.test(parts[2] ?? ""))
|
|
72813
|
+
return parts.length >= 5 && name.endsWith(".md") ? "person-record" : "unknown";
|
|
72435
72814
|
if (parts[1] === "promotions") {
|
|
72436
72815
|
return parts.length === 3 && parseLedgerFileName(name) ? "ledger" : "unknown";
|
|
72437
72816
|
}
|
|
@@ -72486,11 +72865,11 @@ function recordLineageFromPath(path2) {
|
|
|
72486
72865
|
const kind = classifySteeringRepoPath(path2);
|
|
72487
72866
|
const parts = path2.split("/");
|
|
72488
72867
|
if (kind === "skill-record") return parts[2];
|
|
72489
|
-
if (kind === "record")
|
|
72868
|
+
if (kind === "record" || kind === "person-record")
|
|
72490
72869
|
return parts[parts.length - 1].slice(0, -3);
|
|
72491
72870
|
return null;
|
|
72492
72871
|
}
|
|
72493
|
-
var AGENTS_MD_PATH, CLAUDE_MD_PATH, README_PATH, GITATTRIBUTES_PATH, WORKSPACE_TOML_PATH, AGENTS_DIR, STEERING_DIR, GOVERNANCE_TOML_PATH, SKILLS_DIR, TOOLS_DIR, TOOL_SERVERS_DIR, POLICY_DIR, CEDAR_SCHEMA_PATH, CODEGRAPH_SETTINGS_DIR, SANDBOX_TEMPLATE_DIR, SKILL_FILE_NAME, SERVER_TOML_NAME, TOOLS_TOML_NAME, TOOLS_LOCK_NAME, LEDGER_ROTATIONS, LEDGER_FILE, ROOT_FILES, SERVER_FILES, SANDBOX_SERVICE_NAME, WORKSPACE_LINK_PATH;
|
|
72872
|
+
var AGENTS_MD_PATH, CLAUDE_MD_PATH, README_PATH, GITATTRIBUTES_PATH, WORKSPACE_TOML_PATH, AGENTS_DIR, STEERING_DIR, PEOPLE_DIR, PERSON_FOLDER, GOVERNANCE_TOML_PATH, SKILLS_DIR, TOOLS_DIR, TOOL_SERVERS_DIR, POLICY_DIR, CEDAR_SCHEMA_PATH, CODEGRAPH_SETTINGS_DIR, SANDBOX_TEMPLATE_DIR, SKILL_FILE_NAME, SERVER_TOML_NAME, TOOLS_TOML_NAME, TOOLS_LOCK_NAME, LEDGER_ROTATIONS, LEDGER_FILE, ROOT_FILES, SERVER_FILES, SANDBOX_SERVICE_NAME, WORKSPACE_LINK_PATH;
|
|
72494
72873
|
var init_paths2 = __esm({
|
|
72495
72874
|
"../../packages/oxagen/src/steering-repo/paths.ts"() {
|
|
72496
72875
|
"use strict";
|
|
@@ -72501,6 +72880,8 @@ var init_paths2 = __esm({
|
|
|
72501
72880
|
WORKSPACE_TOML_PATH = "workspace.toml";
|
|
72502
72881
|
AGENTS_DIR = "agents";
|
|
72503
72882
|
STEERING_DIR = "steering";
|
|
72883
|
+
PEOPLE_DIR = "people";
|
|
72884
|
+
PERSON_FOLDER = /^usr_[0-9a-z]+$/i;
|
|
72504
72885
|
GOVERNANCE_TOML_PATH = "steering/governance.toml";
|
|
72505
72886
|
SKILLS_DIR = "steering/skills";
|
|
72506
72887
|
TOOLS_DIR = "tools";
|
|
@@ -72546,9 +72927,9 @@ var init_paths2 = __esm({
|
|
|
72546
72927
|
|
|
72547
72928
|
// src/commands/workspace-link.ts
|
|
72548
72929
|
import { existsSync as existsSync28, mkdirSync as mkdirSync12, readFileSync as readFileSync28 } from "node:fs";
|
|
72549
|
-
import { dirname as
|
|
72930
|
+
import { dirname as dirname35, join as join64 } from "node:path";
|
|
72550
72931
|
function workspaceLinkPath(cwd) {
|
|
72551
|
-
return
|
|
72932
|
+
return join64(cwd, WORKSPACE_LINK_PATH);
|
|
72552
72933
|
}
|
|
72553
72934
|
function isRecord9(value) {
|
|
72554
72935
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -72602,7 +72983,7 @@ function readWorkspaceLink(cwd) {
|
|
|
72602
72983
|
}
|
|
72603
72984
|
function writeWorkspaceLink(cwd, link) {
|
|
72604
72985
|
const filePath = workspaceLinkPath(cwd);
|
|
72605
|
-
mkdirSync12(
|
|
72986
|
+
mkdirSync12(dirname35(filePath), { recursive: true });
|
|
72606
72987
|
atomicWriteFileSync(filePath, JSON.stringify(link, null, 2));
|
|
72607
72988
|
}
|
|
72608
72989
|
var LINK_STRING_FIELDS;
|
|
@@ -72637,8 +73018,8 @@ __export(steering_exports, {
|
|
|
72637
73018
|
toSignal: () => toSignal
|
|
72638
73019
|
});
|
|
72639
73020
|
import { execFileSync } from "node:child_process";
|
|
72640
|
-
import { existsSync as existsSync29, realpathSync as
|
|
72641
|
-
import { dirname as
|
|
73021
|
+
import { existsSync as existsSync29, realpathSync as realpathSync10 } from "node:fs";
|
|
73022
|
+
import { dirname as dirname36, join as join65, normalize as normalize2, parse as parsePath } from "node:path";
|
|
72642
73023
|
function findProjectRoot(start) {
|
|
72643
73024
|
const { root } = parsePath(start);
|
|
72644
73025
|
const rawGitRoot = gitRootOr(start);
|
|
@@ -72647,16 +73028,16 @@ function findProjectRoot(start) {
|
|
|
72647
73028
|
if (gitRoot !== null) return gitRoot;
|
|
72648
73029
|
let dir = from;
|
|
72649
73030
|
for (; ; ) {
|
|
72650
|
-
if (existsSync29(
|
|
73031
|
+
if (existsSync29(join65(dir, PROJECT_DIR_NAME))) return dir;
|
|
72651
73032
|
if (dir === root) return from;
|
|
72652
|
-
const parent =
|
|
73033
|
+
const parent = dirname36(dir);
|
|
72653
73034
|
if (parent === dir) return from;
|
|
72654
73035
|
dir = parent;
|
|
72655
73036
|
}
|
|
72656
73037
|
}
|
|
72657
73038
|
function realpathOr(path2) {
|
|
72658
73039
|
try {
|
|
72659
|
-
return
|
|
73040
|
+
return realpathSync10(path2);
|
|
72660
73041
|
} catch {
|
|
72661
73042
|
return normalize2(path2);
|
|
72662
73043
|
}
|
|
@@ -72876,7 +73257,7 @@ async function resolveContext(cwd, {
|
|
|
72876
73257
|
if (boundRemote === null) {
|
|
72877
73258
|
belongsHere = false;
|
|
72878
73259
|
mismatch.push(
|
|
72879
|
-
budget.expired() ? `the check ran out of time before it could tell whether a remote of this checkout points at ${fromPlatform.repository}, so Oxagen's answer was ignored` : scope ? `Oxagen's answer is about ${fromPlatform.repository}, the linked workspace's steering repository. No remote of this checkout points at it, so the workspace's steering gates do not apply here` : `Oxagen's answer is about ${fromPlatform.repository}, which no remote of this checkout points at, so it was ignored
|
|
73260
|
+
budget.expired() ? `the check ran out of time before it could tell whether a remote of this checkout points at ${fromPlatform.repository}, so Oxagen's answer was ignored` : scope ? `Oxagen's answer is about ${fromPlatform.repository}, the linked workspace's steering repository. No remote of this checkout points at it, so the workspace's steering gates do not apply here` : `Oxagen's answer is about ${fromPlatform.repository}, which no remote of this checkout points at, so it was ignored. Run \`oxagen init\` in this repository to link it to its workspace`
|
|
72880
73261
|
);
|
|
72881
73262
|
}
|
|
72882
73263
|
}
|
|
@@ -73462,7 +73843,7 @@ var init_common = __esm({
|
|
|
73462
73843
|
init_names();
|
|
73463
73844
|
lineageSchema = external_exports.string().regex(
|
|
73464
73845
|
STEERING_RECORD_LINEAGE,
|
|
73465
|
-
"a
|
|
73846
|
+
"a record ID is lowercase letters, digits, dots, and hyphens, and starts and ends with a letter or digit"
|
|
73466
73847
|
);
|
|
73467
73848
|
repoRefSchema = external_exports.string().regex(
|
|
73468
73849
|
REPO_REF_PATTERN,
|
|
@@ -73486,7 +73867,7 @@ var init_common = __esm({
|
|
|
73486
73867
|
);
|
|
73487
73868
|
recordIdSchema = external_exports.string().regex(
|
|
73488
73869
|
/^rec_[a-z0-9_]+_[0-9a-f]{12}$/,
|
|
73489
|
-
"an id is rec_<
|
|
73870
|
+
"an id is rec_<record ID slug>_<12 hex characters>, which Oxagen writes on merge. Remove the line and let Oxagen write it."
|
|
73490
73871
|
);
|
|
73491
73872
|
sha256Schema2 = external_exports.string().regex(/^sha256:[0-9a-f]{64}$/);
|
|
73492
73873
|
gitObjectIdSchema = external_exports.string().regex(/^[0-9a-f]{40}(?:[0-9a-f]{24})?$/);
|
|
@@ -74044,15 +74425,15 @@ var init_context_steering_shared = __esm({
|
|
|
74044
74425
|
);
|
|
74045
74426
|
lineageIdSchema = external_exports.string().min(1).max(200).regex(
|
|
74046
74427
|
RECORD_LINEAGE_ID,
|
|
74047
|
-
`a
|
|
74428
|
+
`a record ID is lowercase letters, digits, dots and hyphens (e.g. ctx.release.notes-format). The id ${GOVERNANCE_LINEAGE} is reserved for governance changes`
|
|
74048
74429
|
);
|
|
74049
74430
|
proposedRecordSchema = external_exports.object({
|
|
74050
74431
|
lineageId: lineageIdSchema.describe(
|
|
74051
|
-
"The
|
|
74432
|
+
"The record ID this suggestion is about; the file stem under .oxagen/rules/"
|
|
74052
74433
|
),
|
|
74053
74434
|
title: external_exports.string().trim().min(1).max(200).optional(),
|
|
74054
74435
|
label: external_exports.string().trim().min(1).max(STEERING_RECORD_LABEL_MAX).optional().describe(
|
|
74055
|
-
"The record's name, at most 36 characters. Omit it to keep the current label. A rename never creates a version and never changes the
|
|
74436
|
+
"The record's name, at most 36 characters. Omit it to keep the current label. A rename never creates a version and never changes the record ID."
|
|
74056
74437
|
),
|
|
74057
74438
|
kind: recordKindSchema2,
|
|
74058
74439
|
force: recordForceSchema2,
|
|
@@ -74090,7 +74471,7 @@ var init_context_steering_shared = __esm({
|
|
|
74090
74471
|
}).strict();
|
|
74091
74472
|
proposalIdSchema = external_exports.string().regex(
|
|
74092
74473
|
/^prp_[0-9A-Za-z]+$/,
|
|
74093
|
-
"a
|
|
74474
|
+
"a suggestion id is prp_ followed by letters and digits"
|
|
74094
74475
|
);
|
|
74095
74476
|
proposalViewSchema = external_exports.object({
|
|
74096
74477
|
id: proposalIdSchema,
|
|
@@ -74304,7 +74685,7 @@ var init_steering_markdown_import_shared = __esm({
|
|
|
74304
74685
|
origin: markdownImportOriginSchema.describe(
|
|
74305
74686
|
"frontmatter for a file that is one steering record already, split for a statement the model split out"
|
|
74306
74687
|
),
|
|
74307
|
-
lineage: lineageSchema.max(200).describe("The record's
|
|
74688
|
+
lineage: lineageSchema.max(200).describe("The record's ID, and its file name in the steering repo"),
|
|
74308
74689
|
label: external_exports.string().trim().min(1).max(STEERING_RECORD_LABEL_MAX).describe("The record's name, at most 36 characters"),
|
|
74309
74690
|
statement: external_exports.string().trim().min(1).max(MARKDOWN_IMPORT_FILE_CHARS_MAX).describe("What the record tells an agent: the record's body"),
|
|
74310
74691
|
kind: recordKindSchema,
|
|
@@ -74409,7 +74790,7 @@ var init_steering_markdown_import_shared = __esm({
|
|
|
74409
74790
|
memory: external_exports.string().nullable().describe(
|
|
74410
74791
|
"The waiting memory's id (mem_...), or null for any other reason"
|
|
74411
74792
|
),
|
|
74412
|
-
lineage: external_exports.string().nullable().describe("The published record's
|
|
74793
|
+
lineage: external_exports.string().nullable().describe("The published record's ID, or null for any other reason"),
|
|
74413
74794
|
file: external_exports.string().nullable().describe("The file of the earlier row of this import, or null"),
|
|
74414
74795
|
line: external_exports.number().int().min(1).nullable().describe("The line of the earlier row of this import, or null")
|
|
74415
74796
|
}).strict();
|
|
@@ -83793,7 +84174,7 @@ var init_columns = __esm({
|
|
|
83793
84174
|
import { createHash as createHash18 } from "node:crypto";
|
|
83794
84175
|
function digestToBytes(digest6) {
|
|
83795
84176
|
if (!SHA256_DIGEST_PATTERN.test(digest6)) {
|
|
83796
|
-
throw new TypeError(`not a sha256
|
|
84177
|
+
throw new TypeError(`not a sha256 hash: ${digest6}`);
|
|
83797
84178
|
}
|
|
83798
84179
|
return Buffer.from(digest6.slice("sha256:".length), "hex");
|
|
83799
84180
|
}
|
|
@@ -84122,17 +84503,17 @@ function manifestProblem(manifest) {
|
|
|
84122
84503
|
return void 0;
|
|
84123
84504
|
}
|
|
84124
84505
|
function attestationFileProblem(file) {
|
|
84125
|
-
if (file === null) return "attestation is not a JSON object";
|
|
84506
|
+
if (file === null) return "attestation.json is not a JSON object";
|
|
84126
84507
|
const attestations = file["attestations"];
|
|
84127
84508
|
if (attestations === void 0) return void 0;
|
|
84128
84509
|
if (!Array.isArray(attestations))
|
|
84129
|
-
return "
|
|
84510
|
+
return "the `attestations` member of attestation.json is not a list";
|
|
84130
84511
|
const walkable = attestations.every((attestation) => {
|
|
84131
84512
|
const payload = asRecord2(asRecord2(attestation)?.["payload"]);
|
|
84132
84513
|
return payload !== null && isCount2(payload["frame_count"]);
|
|
84133
84514
|
});
|
|
84134
84515
|
if (!walkable)
|
|
84135
|
-
return "
|
|
84516
|
+
return "a lock in attestation.json lacks a payload with a whole frame_count";
|
|
84136
84517
|
return void 0;
|
|
84137
84518
|
}
|
|
84138
84519
|
function manifestOf(value, checks) {
|
|
@@ -84148,7 +84529,11 @@ function attestationFileOf(value, checks) {
|
|
|
84148
84529
|
const file = asRecord2(value);
|
|
84149
84530
|
const problem = attestationFileProblem(file);
|
|
84150
84531
|
if (problem !== void 0) {
|
|
84151
|
-
checks.push({
|
|
84532
|
+
checks.push({
|
|
84533
|
+
name: "attestation.json",
|
|
84534
|
+
status: "broken",
|
|
84535
|
+
detail: problem
|
|
84536
|
+
});
|
|
84152
84537
|
return null;
|
|
84153
84538
|
}
|
|
84154
84539
|
return file;
|
|
@@ -84166,7 +84551,7 @@ function verifyRunExport(files2) {
|
|
|
84166
84551
|
const manifestJson = parseJson2(files2["manifest.json"], "manifest", checks);
|
|
84167
84552
|
const attestationJson = parseJson2(
|
|
84168
84553
|
files2["attestation.json"],
|
|
84169
|
-
"attestation",
|
|
84554
|
+
"attestation.json",
|
|
84170
84555
|
checks
|
|
84171
84556
|
);
|
|
84172
84557
|
const manifest = manifestOf(manifestJson, checks);
|
|
@@ -84276,7 +84661,7 @@ function verifyRunExport(files2) {
|
|
|
84276
84661
|
}
|
|
84277
84662
|
if (digestOf3(frame2) === null) {
|
|
84278
84663
|
digest6 = "broken";
|
|
84279
|
-
reasons.push("frame carries no sha256
|
|
84664
|
+
reasons.push("frame carries no sha256 hash");
|
|
84280
84665
|
}
|
|
84281
84666
|
verdicts.push({
|
|
84282
84667
|
line,
|
|
@@ -84292,8 +84677,8 @@ function verifyRunExport(files2) {
|
|
|
84292
84677
|
hold(
|
|
84293
84678
|
`stream ${attempt.attempt_id}`,
|
|
84294
84679
|
stream === attempt.event_stream_digest,
|
|
84295
|
-
"the frames fold to the
|
|
84296
|
-
`the frames fold to ${stream}, the
|
|
84680
|
+
"the frames fold to the locked event_stream_digest",
|
|
84681
|
+
`the frames fold to ${stream}, the lock recorded ${attempt.event_stream_digest}`
|
|
84297
84682
|
);
|
|
84298
84683
|
}
|
|
84299
84684
|
offset += attempt.frame_count;
|
|
@@ -84307,7 +84692,7 @@ function verifyRunExport(files2) {
|
|
|
84307
84692
|
status: "broken",
|
|
84308
84693
|
digest: "broken",
|
|
84309
84694
|
link: "broken",
|
|
84310
|
-
reasons: ["frame lies outside every
|
|
84695
|
+
reasons: ["frame lies outside every locked attempt"]
|
|
84311
84696
|
});
|
|
84312
84697
|
}
|
|
84313
84698
|
verdicts.sort((a, b3) => a.line - b3.line);
|
|
@@ -84334,7 +84719,7 @@ function verifyRunExport(files2) {
|
|
|
84334
84719
|
keyId = null;
|
|
84335
84720
|
}
|
|
84336
84721
|
hold(
|
|
84337
|
-
"
|
|
84722
|
+
"lock key",
|
|
84338
84723
|
keyId !== null && keyId === attestationFile.key_id && keyId === manifest.attester_key_id,
|
|
84339
84724
|
`key ${String(keyId)}`,
|
|
84340
84725
|
"the bundled public key does not match the recorded key id"
|
|
@@ -84344,10 +84729,10 @@ function verifyRunExport(files2) {
|
|
|
84344
84729
|
attestations.forEach((a, i2) => {
|
|
84345
84730
|
const attemptId = a.payload?.attempt_id ?? `#${i2 + 1}`;
|
|
84346
84731
|
hold(
|
|
84347
|
-
`
|
|
84732
|
+
`lock ${attemptId}`,
|
|
84348
84733
|
keyId !== null && verifyAttestation(a, pem),
|
|
84349
|
-
"Ed25519
|
|
84350
|
-
"the
|
|
84734
|
+
"the Ed25519 lock verifies",
|
|
84735
|
+
"the lock does not verify"
|
|
84351
84736
|
);
|
|
84352
84737
|
const slice = digests.slice(
|
|
84353
84738
|
covered,
|
|
@@ -84360,30 +84745,30 @@ function verifyRunExport(files2) {
|
|
|
84360
84745
|
hold(
|
|
84361
84746
|
`exported content ${attemptId}`,
|
|
84362
84747
|
exportedDigest === a.payload?.archive_segment_digest,
|
|
84363
|
-
"the exported frame bytes match the
|
|
84364
|
-
"the exported frame bytes do not match the
|
|
84748
|
+
"the exported frame bytes match the locked segment hash",
|
|
84749
|
+
"the exported frame bytes do not match the locked segment hash"
|
|
84365
84750
|
);
|
|
84366
84751
|
}
|
|
84367
84752
|
hold(
|
|
84368
84753
|
`run identity ${attemptId}`,
|
|
84369
84754
|
a.payload?.run_id === manifest.run_id,
|
|
84370
|
-
"the
|
|
84371
|
-
"the manifest run differs from the
|
|
84755
|
+
"the lock names this run",
|
|
84756
|
+
"the manifest run differs from the locked run"
|
|
84372
84757
|
);
|
|
84373
84758
|
covered += a.payload?.frame_count ?? 0;
|
|
84374
84759
|
const attemptRoot = slice.every((d) => d !== null) ? merkleRoot(slice) : null;
|
|
84375
84760
|
hold(
|
|
84376
|
-
`
|
|
84761
|
+
`locked root ${attemptId}`,
|
|
84377
84762
|
attemptRoot === a.payload?.merkle_root,
|
|
84378
|
-
"the attempt's frames hash to the
|
|
84379
|
-
`the attempt's frames hash to ${attemptRoot ?? "nothing"}, the
|
|
84763
|
+
"the attempt's frames hash to the locked root",
|
|
84764
|
+
`the attempt's frames hash to ${attemptRoot ?? "nothing"}, the lock holds ${String(a.payload?.merkle_root)}`
|
|
84380
84765
|
);
|
|
84381
84766
|
});
|
|
84382
84767
|
hold(
|
|
84383
84768
|
"coverage",
|
|
84384
84769
|
covered === frames.length && attestations.length > 0,
|
|
84385
|
-
"the
|
|
84386
|
-
`the
|
|
84770
|
+
"the locks cover every frame",
|
|
84771
|
+
`the locks cover ${covered} of ${frames.length} frames`
|
|
84387
84772
|
);
|
|
84388
84773
|
let redactions = null;
|
|
84389
84774
|
const redactionsText = files2["redactions.json"];
|
|
@@ -84977,7 +85362,7 @@ var init_record = __esm({
|
|
|
84977
85362
|
"Tool names, or <server>__* prefixes. The record reaches a request only when the run's toolbelt holds a match."
|
|
84978
85363
|
),
|
|
84979
85364
|
skills: uniqueArray(lineageSchema, "skills", 1).optional().describe(
|
|
84980
|
-
"Skill
|
|
85365
|
+
"Skill record IDs. The record reaches a request only when the request's context.skill is on the list. A record cannot target a named agent."
|
|
84981
85366
|
),
|
|
84982
85367
|
toolbelt: external_exports.string().min(1).optional().describe(
|
|
84983
85368
|
"A named toolbelt in tools/toolbelts/. The steering repo spec defers what it does to a later version."
|
|
@@ -85345,7 +85730,7 @@ var init_codegraph_settings = __esm({
|
|
|
85345
85730
|
),
|
|
85346
85731
|
key_hint: external_exports.string().regex(/^.{4}$/u, "a key hint is the key's last 4 characters").optional().describe("The last 4 characters of the organization's key."),
|
|
85347
85732
|
linker_model: modelId().optional().describe(
|
|
85348
|
-
"The model that judges
|
|
85733
|
+
"The model that judges suggested links. Unset: GLM 5.3 Flash, or GLM 5.2 where 5.3 Flash has no batch option."
|
|
85349
85734
|
),
|
|
85350
85735
|
stronger_model: modelId().optional().describe(
|
|
85351
85736
|
"The model for cross-repo pairs the linker model could not settle. Unset: GLM 5.3."
|
|
@@ -85645,7 +86030,7 @@ var init_codegraph_settings = __esm({
|
|
|
85645
86030
|
7
|
|
85646
86031
|
),
|
|
85647
86032
|
stale_proposal_days: setting(
|
|
85648
|
-
external_exports.number().int().min(1).describe("A
|
|
86033
|
+
external_exports.number().int().min(1).describe("A suggestion untouched this many days is stale."),
|
|
85649
86034
|
30
|
|
85650
86035
|
),
|
|
85651
86036
|
package_categories: uniqueArray(
|
|
@@ -85834,7 +86219,7 @@ var init_codegraph_settings = __esm({
|
|
|
85834
86219
|
group: "decisions",
|
|
85835
86220
|
id: "codegraph-decisions/v1",
|
|
85836
86221
|
title: "Code graph decision records",
|
|
85837
|
-
description: "codegraph/decisions.toml: the importance threshold, grouping window, stale-
|
|
86222
|
+
description: "codegraph/decisions.toml: the importance threshold, grouping window, stale-suggestion age, and package categories.",
|
|
85838
86223
|
schema: codegraphDecisionsSchema,
|
|
85839
86224
|
defaults: CODEGRAPH_DECISIONS_DEFAULTS,
|
|
85840
86225
|
timing: "next_build"
|
|
@@ -86002,7 +86387,7 @@ var init_promotion = __esm({
|
|
|
86002
86387
|
"The hash of the line before, or null on the first line of the chain."
|
|
86003
86388
|
),
|
|
86004
86389
|
hash: sha256Schema2.describe(
|
|
86005
|
-
"sha256
|
|
86390
|
+
"sha256 of this line without hash, as JSON in one standard form (RFC 8785)."
|
|
86006
86391
|
)
|
|
86007
86392
|
}).strict();
|
|
86008
86393
|
}
|
|
@@ -86083,7 +86468,7 @@ var init_digest_shared = __esm({
|
|
|
86083
86468
|
"../../packages/oxagen/src/contracts/digest.shared.ts"() {
|
|
86084
86469
|
"use strict";
|
|
86085
86470
|
init_zod();
|
|
86086
|
-
sha256DigestSchema = external_exports.string().regex(/^sha256:[0-9a-f]{64}$/, "a sha256
|
|
86471
|
+
sha256DigestSchema = external_exports.string().regex(/^sha256:[0-9a-f]{64}$/, "a sha256 hash (sha256:<64 hex>)");
|
|
86087
86472
|
}
|
|
86088
86473
|
});
|
|
86089
86474
|
|
|
@@ -86978,7 +87363,7 @@ var init_workspace2 = __esm({
|
|
|
86978
87363
|
"Identical calls in a row that stop a run counting as progress. 2 or more."
|
|
86979
87364
|
),
|
|
86980
87365
|
mode: noProgressModeSchema.describe(
|
|
86981
|
-
"observe records each run that reaches the limit, and runs keep going. enforced also pauses the run
|
|
87366
|
+
"observe records each run that reaches the limit, and runs keep going. enforced also pauses the run before its next step."
|
|
86982
87367
|
)
|
|
86983
87368
|
}).strict();
|
|
86984
87369
|
workspaceSchema = external_exports.object({
|
|
@@ -87079,7 +87464,7 @@ var init_steering_tools = __esm({
|
|
|
87079
87464
|
STEERING_SEARCH_SNIPPET_MAX = 160;
|
|
87080
87465
|
steeringSearchInputSchema = external_exports.object({
|
|
87081
87466
|
query: external_exports.string().max(500).optional().describe(
|
|
87082
|
-
"Words to look for in each record's label, description,
|
|
87467
|
+
"Words to look for in each record's label, description, record ID, and body. A label match ranks above a description match, and a description match above a body match."
|
|
87083
87468
|
),
|
|
87084
87469
|
kind: recordKindSchema.optional().describe("Only records of this kind, such as skill."),
|
|
87085
87470
|
kinds: external_exports.array(recordKindSchema).min(1).max(20).optional().describe(
|
|
@@ -87261,9 +87646,12 @@ function isRecordKind(kind) {
|
|
|
87261
87646
|
function isRecordPath(path2) {
|
|
87262
87647
|
return isRecordKind(classifySteeringRepoPath(path2));
|
|
87263
87648
|
}
|
|
87649
|
+
function isReadRecordKind(kind) {
|
|
87650
|
+
return isRecordKind(kind) || kind === "person-record";
|
|
87651
|
+
}
|
|
87264
87652
|
function readRecordFile(path2, text5) {
|
|
87265
87653
|
const kind = classifySteeringRepoPath(path2);
|
|
87266
|
-
if (!
|
|
87654
|
+
if (!isReadRecordKind(kind)) return null;
|
|
87267
87655
|
const split = splitRecordFile(text5);
|
|
87268
87656
|
if (!split.ok) return null;
|
|
87269
87657
|
const parsed2 = parseFrontmatter(split.parts.frontmatter);
|
|
@@ -87650,6 +88038,9 @@ function sameBudget(a, b3) {
|
|
|
87650
88038
|
function entryText(entry2) {
|
|
87651
88039
|
return `${entry2.lineage} (${formatCount(entry2.tokens)} tokens)`;
|
|
87652
88040
|
}
|
|
88041
|
+
function workspaceRecords(env) {
|
|
88042
|
+
return env.records.filter((file) => file.kind !== "person-record");
|
|
88043
|
+
}
|
|
87653
88044
|
function changedRecordTokens(env) {
|
|
87654
88045
|
const lines = [];
|
|
87655
88046
|
for (const file of env.records) {
|
|
@@ -87685,7 +88076,10 @@ function alwaysOnPart(env) {
|
|
|
87685
88076
|
const budgetMoved = env.base !== null && !sameBudget(budget, alwaysOnBudget(env.base));
|
|
87686
88077
|
const before = /* @__PURE__ */ new Map();
|
|
87687
88078
|
if (env.base !== null && env.baseRecords !== null)
|
|
87688
|
-
for (const block of alwaysOnBlocks(
|
|
88079
|
+
for (const block of alwaysOnBlocks(
|
|
88080
|
+
env.base,
|
|
88081
|
+
env.baseRecords.filter((file) => file.kind !== "person-record")
|
|
88082
|
+
))
|
|
87689
88083
|
before.set(block.repository, block);
|
|
87690
88084
|
const governance = env.head.get(GOVERNANCE_TOML_PATH);
|
|
87691
88085
|
const line = governance === void 0 ? null : tomlLine(governance, "steering.always_on_tokens");
|
|
@@ -87693,7 +88087,7 @@ function alwaysOnPart(env) {
|
|
|
87693
88087
|
const notes = [];
|
|
87694
88088
|
const ceiling = budgetCeiling(budget, line);
|
|
87695
88089
|
if (ceiling !== null) findings.push(ceiling);
|
|
87696
|
-
for (const block of alwaysOnBlocks(env.head, env
|
|
88090
|
+
for (const block of alwaysOnBlocks(env.head, workspaceRecords(env))) {
|
|
87697
88091
|
const prior = before.get(block.repository);
|
|
87698
88092
|
if (!budgetMoved && prior?.text === block.text) continue;
|
|
87699
88093
|
const priorTokens = prior?.tokens ?? 0;
|
|
@@ -88085,7 +88479,7 @@ function flips(env) {
|
|
|
88085
88479
|
...place(file, "effect"),
|
|
88086
88480
|
message: `The published constraint ${record.lineage} is a ${before}, and this change makes it a ${record.effect}.`,
|
|
88087
88481
|
expected: `effect: ${before}, as published.`,
|
|
88088
|
-
fix: "Archive this record, and open a new record with its own
|
|
88482
|
+
fix: "Archive this record, and open a new record with its own record ID for the opposite effect."
|
|
88089
88483
|
})
|
|
88090
88484
|
);
|
|
88091
88485
|
}
|
|
@@ -88179,9 +88573,9 @@ var init_lineage = __esm({
|
|
|
88179
88573
|
path: file.path,
|
|
88180
88574
|
line: recordFieldLine(file, "lineage"),
|
|
88181
88575
|
field: "lineage",
|
|
88182
|
-
message: `The
|
|
88183
|
-
expected: "One file for each
|
|
88184
|
-
fix: "Give each record its own
|
|
88576
|
+
message: `The record ID ${lineage} is also declared in ${others.join(", ")}.`,
|
|
88577
|
+
expected: "One file for each record ID.",
|
|
88578
|
+
fix: "Give each record its own record ID, or delete the copy."
|
|
88185
88579
|
})
|
|
88186
88580
|
);
|
|
88187
88581
|
}
|
|
@@ -88440,12 +88834,12 @@ function recordFieldFindings(file, known) {
|
|
|
88440
88834
|
line: at2(`skills.${n2}`),
|
|
88441
88835
|
field: `skills.${n2}`,
|
|
88442
88836
|
...withHint(
|
|
88443
|
-
`The record names the skill ${skill}, and no active skill has that
|
|
88837
|
+
`The record names the skill ${skill}, and no active skill has that record ID.`,
|
|
88444
88838
|
skill,
|
|
88445
88839
|
skillList
|
|
88446
88840
|
),
|
|
88447
|
-
expected: "The
|
|
88448
|
-
fix: `Correct the
|
|
88841
|
+
expected: "The record ID of an active skill under steering/skills/.",
|
|
88842
|
+
fix: `Correct the record ID, or add the skill at steering/skills/${skill}/SKILL.md.`
|
|
88449
88843
|
})
|
|
88450
88844
|
);
|
|
88451
88845
|
});
|
|
@@ -88681,13 +89075,13 @@ var init_references = __esm({
|
|
|
88681
89075
|
init_repo2();
|
|
88682
89076
|
find8 = finder("references");
|
|
88683
89077
|
MENTION_TEXT = {
|
|
88684
|
-
record: "the
|
|
88685
|
-
skill: "the
|
|
89078
|
+
record: "the record ID of an active record",
|
|
89079
|
+
skill: "the record ID of an active skill",
|
|
88686
89080
|
tool: "a tool the workspace imports"
|
|
88687
89081
|
};
|
|
88688
89082
|
MENTION_MISS = {
|
|
88689
|
-
record: "no active record has that
|
|
88690
|
-
skill: "no active skill has that
|
|
89083
|
+
record: "no active record has that record ID",
|
|
89084
|
+
skill: "no active skill has that record ID",
|
|
88691
89085
|
tool: "no server in the workspace imports that tool"
|
|
88692
89086
|
};
|
|
88693
89087
|
FILE_MENTION = /(^|[\s(`'"])@([A-Za-z0-9_][A-Za-z0-9_./-]*\.[A-Za-z0-9]+)/g;
|
|
@@ -88909,16 +89303,16 @@ function recordShape2(file) {
|
|
|
88909
89303
|
const lineage = file.raw.lineage;
|
|
88910
89304
|
if (!isString(lineage)) return findings;
|
|
88911
89305
|
const parts = file.path.split("/");
|
|
88912
|
-
if (file.kind
|
|
89306
|
+
if (file.kind !== "skill-record" && fileStem(file.path) !== lineage) {
|
|
88913
89307
|
findings.push(
|
|
88914
89308
|
find9({
|
|
88915
89309
|
rule: "file-named-for-lineage",
|
|
88916
89310
|
path: file.path,
|
|
88917
89311
|
line: recordFieldLine(file, "lineage"),
|
|
88918
89312
|
field: "lineage",
|
|
88919
|
-
message: `The file is named ${fileStem(file.path)}.md, but its
|
|
88920
|
-
expected: "A record file named <
|
|
88921
|
-
fix: `Rename the file to ${lineage}.md, or correct the
|
|
89313
|
+
message: `The file is named ${fileStem(file.path)}.md, but its record ID is ${lineage}.`,
|
|
89314
|
+
expected: "A record file named <record ID>.md.",
|
|
89315
|
+
fix: `Rename the file to ${lineage}.md, or correct the record ID.`
|
|
88922
89316
|
})
|
|
88923
89317
|
);
|
|
88924
89318
|
}
|
|
@@ -88929,9 +89323,9 @@ function recordShape2(file) {
|
|
|
88929
89323
|
path: file.path,
|
|
88930
89324
|
line: recordFieldLine(file, "lineage"),
|
|
88931
89325
|
field: "lineage",
|
|
88932
|
-
message: `The skill's folder is named ${parts[2]}, but its
|
|
88933
|
-
expected: `A skill at ${SKILLS_DIR}/<
|
|
88934
|
-
fix: `Rename the folder to ${lineage}, or correct the
|
|
89326
|
+
message: `The skill's folder is named ${parts[2]}, but its record ID is ${lineage}.`,
|
|
89327
|
+
expected: `A skill at ${SKILLS_DIR}/<record ID>/${SKILL_FILE_NAME}.`,
|
|
89328
|
+
fix: `Rename the folder to ${lineage}, or correct the record ID.`
|
|
88935
89329
|
})
|
|
88936
89330
|
);
|
|
88937
89331
|
}
|
|
@@ -88944,7 +89338,7 @@ function recordShape2(file) {
|
|
|
88944
89338
|
line: recordFieldLine(file, "kind"),
|
|
88945
89339
|
field: "kind",
|
|
88946
89340
|
message: `A skill must live in its own folder under ${SKILLS_DIR}.`,
|
|
88947
|
-
expected: `A skill at ${SKILLS_DIR}/<
|
|
89341
|
+
expected: `A skill at ${SKILLS_DIR}/<record ID>/${SKILL_FILE_NAME}.`,
|
|
88948
89342
|
fix: `Move the file to ${SKILLS_DIR}/${lineage}/${SKILL_FILE_NAME}, or change the kind.`
|
|
88949
89343
|
})
|
|
88950
89344
|
);
|
|
@@ -89168,6 +89562,7 @@ var init_schema2 = __esm({
|
|
|
89168
89562
|
const kind = classifySteeringRepoPath(path2);
|
|
89169
89563
|
switch (kind) {
|
|
89170
89564
|
case "record":
|
|
89565
|
+
case "person-record":
|
|
89171
89566
|
case "skill-record":
|
|
89172
89567
|
findings.push(...readRecord(path2, text5, records.get(path2) ?? null));
|
|
89173
89568
|
findings.push(...scopeFitsRepo(records.get(path2) ?? null, env.repo));
|
|
@@ -89961,7 +90356,7 @@ var init_memory_client = __esm({
|
|
|
89961
90356
|
import { readFile as readFile9 } from "node:fs/promises";
|
|
89962
90357
|
import {
|
|
89963
90358
|
basename as basename7,
|
|
89964
|
-
dirname as
|
|
90359
|
+
dirname as dirname37,
|
|
89965
90360
|
isAbsolute as isAbsolute17,
|
|
89966
90361
|
relative as relative7,
|
|
89967
90362
|
resolve as resolve23,
|
|
@@ -89973,7 +90368,7 @@ function inside(rel) {
|
|
|
89973
90368
|
function importFilename(path2, folder) {
|
|
89974
90369
|
let rel = relative7(process.cwd(), path2);
|
|
89975
90370
|
if (!inside(rel) && folder !== void 0) {
|
|
89976
|
-
rel = relative7(
|
|
90371
|
+
rel = relative7(dirname37(resolve23(folder)), resolve23(path2));
|
|
89977
90372
|
}
|
|
89978
90373
|
const name = inside(rel) ? rel.split(sep9).join("/") : basename7(path2);
|
|
89979
90374
|
return name.length > 256 ? basename7(path2).slice(-256) : name;
|
|
@@ -90268,7 +90663,7 @@ __export(steering_import_exports, {
|
|
|
90268
90663
|
});
|
|
90269
90664
|
import { readdir as readdir4, realpath as realpath2, stat as stat4 } from "node:fs/promises";
|
|
90270
90665
|
import { homedir as homedir13 } from "node:os";
|
|
90271
|
-
import { basename as basename8, extname, join as
|
|
90666
|
+
import { basename as basename8, extname, join as join66, relative as relative8, sep as sep10 } from "node:path";
|
|
90272
90667
|
function envDir2(env, key) {
|
|
90273
90668
|
const value = env[key];
|
|
90274
90669
|
return value === void 0 || value.trim() === "" ? null : value;
|
|
@@ -90276,34 +90671,34 @@ function envDir2(env, key) {
|
|
|
90276
90671
|
function harnessHome(harness, env = process.env, home = homedir13()) {
|
|
90277
90672
|
switch (harness) {
|
|
90278
90673
|
case "claude-code": {
|
|
90279
|
-
const config = envDir2(env, "CLAUDE_CONFIG_DIR") ??
|
|
90674
|
+
const config = envDir2(env, "CLAUDE_CONFIG_DIR") ?? join66(home, ".claude");
|
|
90280
90675
|
return {
|
|
90281
90676
|
harness,
|
|
90282
90677
|
folders: [
|
|
90283
90678
|
{
|
|
90284
|
-
dir: skillsRoot("claude-code", env, home) ??
|
|
90679
|
+
dir: skillsRoot("claude-code", env, home) ?? join66(config, "skills"),
|
|
90285
90680
|
mount: ".claude/skills"
|
|
90286
90681
|
},
|
|
90287
|
-
{ dir:
|
|
90288
|
-
{ dir:
|
|
90682
|
+
{ dir: join66(config, "commands"), mount: ".claude/commands" },
|
|
90683
|
+
{ dir: join66(config, "agents"), mount: ".claude/agents" }
|
|
90289
90684
|
],
|
|
90290
90685
|
instructions: [
|
|
90291
|
-
{ file:
|
|
90686
|
+
{ file: join66(config, "CLAUDE.md"), filename: ".claude/CLAUDE.md" }
|
|
90292
90687
|
]
|
|
90293
90688
|
};
|
|
90294
90689
|
}
|
|
90295
90690
|
case "codex": {
|
|
90296
|
-
const codexHome = envDir2(env, "CODEX_HOME") ??
|
|
90691
|
+
const codexHome = envDir2(env, "CODEX_HOME") ?? join66(home, ".codex");
|
|
90297
90692
|
return {
|
|
90298
90693
|
harness,
|
|
90299
90694
|
folders: [
|
|
90300
90695
|
{
|
|
90301
|
-
dir: skillsRoot("codex", env, home) ??
|
|
90696
|
+
dir: skillsRoot("codex", env, home) ?? join66(home, ".agents", "skills"),
|
|
90302
90697
|
mount: ".agents/skills"
|
|
90303
90698
|
}
|
|
90304
90699
|
],
|
|
90305
90700
|
instructions: ["AGENTS.override.md", "AGENTS.md"].map((name) => ({
|
|
90306
|
-
file:
|
|
90701
|
+
file: join66(codexHome, name),
|
|
90307
90702
|
filename: `.codex/${name}`
|
|
90308
90703
|
}))
|
|
90309
90704
|
};
|
|
@@ -90312,8 +90707,8 @@ function harnessHome(harness, env = process.env, home = homedir13()) {
|
|
|
90312
90707
|
return {
|
|
90313
90708
|
harness,
|
|
90314
90709
|
folders: [
|
|
90315
|
-
{ dir:
|
|
90316
|
-
{ dir:
|
|
90710
|
+
{ dir: join66(home, ".cursor", "skills"), mount: ".cursor/skills" },
|
|
90711
|
+
{ dir: join66(home, ".cursor", "commands"), mount: ".cursor/commands" }
|
|
90317
90712
|
],
|
|
90318
90713
|
instructions: []
|
|
90319
90714
|
};
|
|
@@ -90359,7 +90754,7 @@ async function findMarkdownFiles(paths, harness) {
|
|
|
90359
90754
|
}
|
|
90360
90755
|
const found = [];
|
|
90361
90756
|
for (const entry2 of entries2.sort(byName)) {
|
|
90362
|
-
const path2 =
|
|
90757
|
+
const path2 = join66(dir, entry2.name);
|
|
90363
90758
|
if (entry2.isDirectory()) {
|
|
90364
90759
|
if (!entry2.name.startsWith(".") && entry2.name !== "node_modules")
|
|
90365
90760
|
found.push(...await filesUnder(path2, from));
|
|
@@ -90381,7 +90776,7 @@ async function findMarkdownFiles(paths, harness) {
|
|
|
90381
90776
|
const { folder } = frame2;
|
|
90382
90777
|
const named = (rel) => frame2.fixedNames ? { filename: rel } : {};
|
|
90383
90778
|
for (const entry2 of entries2) {
|
|
90384
|
-
const path2 =
|
|
90779
|
+
const path2 = join66(dir, entry2.name);
|
|
90385
90780
|
const rel = frame2.relOf(path2);
|
|
90386
90781
|
if (entry2.isDirectory()) {
|
|
90387
90782
|
if (entry2.name === "node_modules") continue;
|
|
@@ -90440,7 +90835,7 @@ async function findMarkdownFiles(paths, harness) {
|
|
|
90440
90835
|
}
|
|
90441
90836
|
if (folderGiven) {
|
|
90442
90837
|
const catalogue = CATALOGUE_FOLDERS.has(basename8(path2));
|
|
90443
|
-
const root = catalogue ?
|
|
90838
|
+
const root = catalogue ? join66(path2, "..") : path2;
|
|
90444
90839
|
await walk2(path2, {
|
|
90445
90840
|
relOf: (p) => under(root, p),
|
|
90446
90841
|
folder: path2,
|
|
@@ -90604,7 +90999,7 @@ async function steeringPromote(findingId, opts = {}, writer = stdoutWriter) {
|
|
|
90604
90999
|
return;
|
|
90605
91000
|
}
|
|
90606
91001
|
writer.write(
|
|
90607
|
-
`Opened
|
|
91002
|
+
`Opened suggestion ${result2.proposal_id} for record ${result2.lineage}.`
|
|
90608
91003
|
);
|
|
90609
91004
|
const pr = result2.pull_request;
|
|
90610
91005
|
writer.write(
|
|
@@ -90627,7 +91022,7 @@ var init_steering_promote = __esm({
|
|
|
90627
91022
|
USAGE2 = "oxagen steering promote <finding-id> [--json]";
|
|
90628
91023
|
NEXT_STEPS2 = {
|
|
90629
91024
|
finding_resolved: "Run `oxagen steering findings` to see the statements that still match a record.",
|
|
90630
|
-
already_proposed: "Run `oxagen steering findings` to see the open
|
|
91025
|
+
already_proposed: "Run `oxagen steering findings` to see the open suggestion and its steering PR.",
|
|
90631
91026
|
lineage_pr_open: "Merge or close the PR that is open on the record, then promote the finding again."
|
|
90632
91027
|
};
|
|
90633
91028
|
}
|
|
@@ -90650,7 +91045,7 @@ async function steeringRestoreBlock(proposalId, path2, opts = {}, writer = stdou
|
|
|
90650
91045
|
if (!PROPOSAL_ID2.test(id2)) {
|
|
90651
91046
|
usageError(
|
|
90652
91047
|
writer,
|
|
90653
|
-
`expected a
|
|
91048
|
+
`expected a suggestion id that starts with prp_, got ${JSON.stringify(proposalId)}`,
|
|
90654
91049
|
USAGE3
|
|
90655
91050
|
);
|
|
90656
91051
|
return;
|
|
@@ -90704,9 +91099,9 @@ var init_steering_restore_block = __esm({
|
|
|
90704
91099
|
NEXT_STEPS3 = {
|
|
90705
91100
|
no_managed_block: "Remove the marker lines and the text between them from the file on the PR's branch by hand.",
|
|
90706
91101
|
no_managed_blocks: "The repository keeps its steering under .oxagen/. Edit the file on the PR's branch directly.",
|
|
90707
|
-
pr_not_open: "Run `oxagen steering findings` to see the
|
|
91102
|
+
pr_not_open: "Run `oxagen steering findings` to see the suggestion's current steering PR."
|
|
90708
91103
|
};
|
|
90709
|
-
USAGE3 = "oxagen steering restore-block <
|
|
91104
|
+
USAGE3 = "oxagen steering restore-block <suggestion-id> <AGENTS.md|CLAUDE.md|README.md> [--json]";
|
|
90710
91105
|
}
|
|
90711
91106
|
});
|
|
90712
91107
|
|
|
@@ -90934,7 +91329,7 @@ async function terminalSession(relay, mode, runName, io, writer) {
|
|
|
90934
91329
|
if (detaching) {
|
|
90935
91330
|
writer.writeErr(
|
|
90936
91331
|
`
|
|
90937
|
-
|
|
91332
|
+
You left the terminal. The run keeps going. Open its terminal again with \`oxagen sandbox attach ${runName}\`.`
|
|
90938
91333
|
);
|
|
90939
91334
|
} else if (result2?.message) {
|
|
90940
91335
|
writer.writeErr(`
|
|
@@ -91269,7 +91664,7 @@ async function runExport(runId, opts = {}, writer = stdoutWriter) {
|
|
|
91269
91664
|
}
|
|
91270
91665
|
writer.write(`Export ${result2.exportId} queued for ${runId}.`);
|
|
91271
91666
|
writer.write(
|
|
91272
|
-
`The bundle holds the frames as NDJSON, the Merkle root,
|
|
91667
|
+
`The bundle holds the frames as NDJSON, the Merkle root, Oxagen's lock, the key that checks the lock, and a verifier script. Check on it with \`oxagen run export-status ${result2.exportId}\`.`
|
|
91273
91668
|
);
|
|
91274
91669
|
}
|
|
91275
91670
|
function resolveDownloadUrl(url, apiUrl) {
|
|
@@ -91312,7 +91707,7 @@ async function runExportStatus(exportId, opts = {}, writer = stdoutWriter) {
|
|
|
91312
91707
|
return;
|
|
91313
91708
|
}
|
|
91314
91709
|
writer.write(`Size: ${formatBytes2(result2.bundleBytes)}`);
|
|
91315
|
-
writer.write(`
|
|
91710
|
+
writer.write(`Hash: ${result2.bundleDigest ?? "not recorded"}`);
|
|
91316
91711
|
writer.write(`Frames: ${result2.frameCount ?? "not recorded"}`);
|
|
91317
91712
|
writer.write(`Merkle root: ${result2.merkleRoot ?? "not recorded"}`);
|
|
91318
91713
|
if (result2.download) {
|
|
@@ -91343,7 +91738,7 @@ async function runDownload(exportId, opts = {}, writer = stdoutWriter) {
|
|
|
91343
91738
|
}
|
|
91344
91739
|
if (!status2.download || !status2.bundleDigest) {
|
|
91345
91740
|
out.error(
|
|
91346
|
-
`Export ${exportId} is ready but the platform sent no download link or
|
|
91741
|
+
`Export ${exportId} is ready but the platform sent no download link or hash.`,
|
|
91347
91742
|
"not_ready"
|
|
91348
91743
|
);
|
|
91349
91744
|
return;
|
|
@@ -91426,7 +91821,7 @@ async function runDownload(exportId, opts = {}, writer = stdoutWriter) {
|
|
|
91426
91821
|
return;
|
|
91427
91822
|
}
|
|
91428
91823
|
writer.write(`Wrote ${path2} (${formatBytes2(size)}).`);
|
|
91429
|
-
writer.write(`
|
|
91824
|
+
writer.write(`Hash ${actual} matches the recorded bundle hash.`);
|
|
91430
91825
|
writer.write(`Check every frame offline with \`oxagen verify ${path2}\`.`);
|
|
91431
91826
|
}
|
|
91432
91827
|
function attestationLine(attestation) {
|
|
@@ -91453,7 +91848,7 @@ async function runChain(runId, opts = {}, writer = stdoutWriter) {
|
|
|
91453
91848
|
const many = result2.seals.length > 1;
|
|
91454
91849
|
result2.seals.forEach((seal2, i2) => {
|
|
91455
91850
|
writer.write(
|
|
91456
|
-
`${many ? `Attempt ${i2 + 1}
|
|
91851
|
+
`${many ? `Attempt ${i2 + 1} lock` : "Lock"}: ${attestationLine(seal2.attestation)}`
|
|
91457
91852
|
);
|
|
91458
91853
|
});
|
|
91459
91854
|
writer.write(
|
|
@@ -91477,7 +91872,9 @@ async function runChain(runId, opts = {}, writer = stdoutWriter) {
|
|
|
91477
91872
|
}
|
|
91478
91873
|
}
|
|
91479
91874
|
if (result2.checkpoints.length > 0) {
|
|
91480
|
-
writer.write(
|
|
91875
|
+
writer.write(
|
|
91876
|
+
`The agent's computer locked the record at ${result2.checkpoints.length} point(s) along the way.`
|
|
91877
|
+
);
|
|
91481
91878
|
}
|
|
91482
91879
|
const chains = result2.chains ?? [];
|
|
91483
91880
|
if (chains.length > 0) {
|
|
@@ -91486,7 +91883,7 @@ async function runChain(runId, opts = {}, writer = stdoutWriter) {
|
|
|
91486
91883
|
for (const chain of chains) {
|
|
91487
91884
|
const name = chain.subagentType ?? chain.subagentId ?? chain.sessionUuid;
|
|
91488
91885
|
writer.write(
|
|
91489
|
-
` ${name} (${chain.sessionUuid}): ${chain.frameCount} frames, ${chain.gaps.missingFrameCount} missing frames, ${chain.gaps.missingBodies} missing bodies${chain.sealedAt === null ? ",
|
|
91886
|
+
` ${name} (${chain.sessionUuid}): ${chain.frameCount} frames, ${chain.gaps.missingFrameCount} missing frames, ${chain.gaps.missingBodies} missing bodies${chain.sealedAt === null ? ", not locked" : ""}${chain.complete ? "" : ", cut short"}`
|
|
91490
91887
|
);
|
|
91491
91888
|
}
|
|
91492
91889
|
}
|
|
@@ -91774,7 +92171,7 @@ async function runShow(runId, opts = {}, writer = stdoutWriter) {
|
|
|
91774
92171
|
writer.write(`Steering: ${steeringOf(run3)}`);
|
|
91775
92172
|
writer.write(`Replay grade: ${run3.replayGrade ?? NOT_RECORDED}`);
|
|
91776
92173
|
writer.write(`Started: ${run3.startedAt}`);
|
|
91777
|
-
writer.write(`
|
|
92174
|
+
writer.write(`Locked: ${run3.sealedAt ?? "not locked"}`);
|
|
91778
92175
|
writer.write(`Turns: ${run3.turns ?? NOT_RECORDED}`);
|
|
91779
92176
|
writer.write(`Steps: ${run3.steps}`);
|
|
91780
92177
|
writer.write(`Frames: ${run3.frames}`);
|
|
@@ -92765,7 +93162,7 @@ function unzipSync(data, opts) {
|
|
|
92765
93162
|
}
|
|
92766
93163
|
return files2;
|
|
92767
93164
|
}
|
|
92768
|
-
var require2, _a, Worker, isMarkedAsUntransferable, u82, u162,
|
|
93165
|
+
var require2, _a, Worker, isMarkedAsUntransferable, u82, u162, i322, fleb, fdeb, clim, freb, _a, fl, revfl, _b, fd, revfd, rev, x, i, hMap, flt, i, i, i, i, fdt, i, flrm, fdrm, max, bits, bits16, shft, slc, ec, err, inflt, et, b2, b4, b8, td, tds, dutf8, slzh, zh, z64hs;
|
|
92769
93166
|
var init_esm2 = __esm({
|
|
92770
93167
|
"../../node_modules/.pnpm/fflate@0.8.3/node_modules/fflate/esm/index.mjs"() {
|
|
92771
93168
|
require2 = createRequire3("/");
|
|
@@ -92775,7 +93172,7 @@ var init_esm2 = __esm({
|
|
|
92775
93172
|
}
|
|
92776
93173
|
u82 = Uint8Array;
|
|
92777
93174
|
u162 = Uint16Array;
|
|
92778
|
-
|
|
93175
|
+
i322 = Int32Array;
|
|
92779
93176
|
fleb = new u82([
|
|
92780
93177
|
0,
|
|
92781
93178
|
0,
|
|
@@ -92853,7 +93250,7 @@ var init_esm2 = __esm({
|
|
|
92853
93250
|
for (var i2 = 0; i2 < 31; ++i2) {
|
|
92854
93251
|
b3[i2] = start += 1 << eb[i2 - 1];
|
|
92855
93252
|
}
|
|
92856
|
-
var r = new
|
|
93253
|
+
var r = new i322(b3[30]);
|
|
92857
93254
|
for (var i2 = 1; i2 < 30; ++i2) {
|
|
92858
93255
|
for (var j = b3[i2]; j < b3[i2 + 1]; ++j) {
|
|
92859
93256
|
r[j] = j - b3[i2] << 5 | i2;
|
|
@@ -93190,11 +93587,11 @@ __export(verify_exports, {
|
|
|
93190
93587
|
readBundle: () => readBundle,
|
|
93191
93588
|
verifyBundle: () => verifyBundle3
|
|
93192
93589
|
});
|
|
93193
|
-
import { existsSync as existsSync30, readFileSync as readFileSync30, statSync as
|
|
93194
|
-
import { join as
|
|
93590
|
+
import { existsSync as existsSync30, readFileSync as readFileSync30, statSync as statSync19 } from "node:fs";
|
|
93591
|
+
import { join as join67 } from "node:path";
|
|
93195
93592
|
function readDirectory(dir) {
|
|
93196
93593
|
const read2 = (name) => {
|
|
93197
|
-
const path2 =
|
|
93594
|
+
const path2 = join67(dir, name);
|
|
93198
93595
|
return existsSync30(path2) ? readFileSync30(path2, "utf8") : void 0;
|
|
93199
93596
|
};
|
|
93200
93597
|
return assemble(read2, dir);
|
|
@@ -93241,7 +93638,7 @@ function readBundle(path2) {
|
|
|
93241
93638
|
if (!existsSync30(path2)) {
|
|
93242
93639
|
throw new BundleReadError(`${path2} does not exist.`);
|
|
93243
93640
|
}
|
|
93244
|
-
return
|
|
93641
|
+
return statSync19(path2).isDirectory() ? readDirectory(path2) : readZip(path2);
|
|
93245
93642
|
}
|
|
93246
93643
|
function plural3(count12, one, many) {
|
|
93247
93644
|
return `${count12} ${count12 === 1 ? one : many}`;
|
|
@@ -93255,7 +93652,7 @@ function formatFrame(frame2) {
|
|
|
93255
93652
|
`frame ${frame2.line}`,
|
|
93256
93653
|
where,
|
|
93257
93654
|
frame2.status,
|
|
93258
|
-
`
|
|
93655
|
+
`hash ${digestLabel(frame2.digest)}`,
|
|
93259
93656
|
`link ${frame2.link}`
|
|
93260
93657
|
];
|
|
93261
93658
|
if (frame2.reasons.length > 0) parts.push(frame2.reasons.join("; "));
|
|
@@ -93277,7 +93674,7 @@ function formatVerification(result2) {
|
|
|
93277
93674
|
).length;
|
|
93278
93675
|
if (notCarried > 0) {
|
|
93279
93676
|
lines.push(
|
|
93280
|
-
`
|
|
93677
|
+
` Hash not carried on ${plural3(notCarried, "wrapped (tse_) frame", "wrapped (tse_) frames")}. A wrapped frame is hashed over its full event, and the bundle does not hold that event for these frames: an export before format 3 never did, and a format-3 export leaves it out when the stored row cannot be proven to rebuild it. For these frames, only the links and the Merkle root can be checked.`
|
|
93281
93678
|
);
|
|
93282
93679
|
}
|
|
93283
93680
|
lines.push("");
|
|
@@ -94439,7 +94836,7 @@ async function resolveOrg(opts) {
|
|
|
94439
94836
|
return promptChoice(
|
|
94440
94837
|
"Select an organization:",
|
|
94441
94838
|
organizations,
|
|
94442
|
-
(o) => `${o.name} (${o.slug})
|
|
94839
|
+
(o) => `${o.name} (${o.slug}), ${o.role}`,
|
|
94443
94840
|
opts.isTTY
|
|
94444
94841
|
);
|
|
94445
94842
|
}
|
|
@@ -94472,7 +94869,7 @@ async function resolveWorkspace(opts) {
|
|
|
94472
94869
|
const ws = await promptChoice(
|
|
94473
94870
|
`Select a workspace in ${opts.orgSlug}:`,
|
|
94474
94871
|
workspaces,
|
|
94475
|
-
(w) => `${w.name} (${w.slug})${w.role ?
|
|
94872
|
+
(w) => `${w.name} (${w.slug})${w.role ? `, ${w.role}` : ""}`,
|
|
94476
94873
|
opts.isTTY
|
|
94477
94874
|
);
|
|
94478
94875
|
return { org: organization, workspace: ws };
|
|
@@ -94510,11 +94907,11 @@ import {
|
|
|
94510
94907
|
mkdirSync as mkdirSync13,
|
|
94511
94908
|
readFileSync as readFileSync31,
|
|
94512
94909
|
readdirSync as readdirSync15,
|
|
94513
|
-
realpathSync as
|
|
94910
|
+
realpathSync as realpathSync11,
|
|
94514
94911
|
writeFileSync as writeFileSync9
|
|
94515
94912
|
} from "node:fs";
|
|
94516
94913
|
import { homedir as homedir14, hostname as osHostname3 } from "node:os";
|
|
94517
|
-
import { join as
|
|
94914
|
+
import { join as join68, relative as relative9, resolve as resolve25, sep as sep11 } from "node:path";
|
|
94518
94915
|
function git4(cwd, args) {
|
|
94519
94916
|
return new Promise((done) => {
|
|
94520
94917
|
try {
|
|
@@ -94561,7 +94958,7 @@ function parseRemoteRepository(url) {
|
|
|
94561
94958
|
}
|
|
94562
94959
|
function oxagenPresent(root) {
|
|
94563
94960
|
try {
|
|
94564
|
-
return readdirSync15(
|
|
94961
|
+
return readdirSync15(join68(root, ".oxagen")).some(
|
|
94565
94962
|
(name) => name !== "workspace.json"
|
|
94566
94963
|
);
|
|
94567
94964
|
} catch {
|
|
@@ -94570,21 +94967,21 @@ function oxagenPresent(root) {
|
|
|
94570
94967
|
}
|
|
94571
94968
|
function symlinkState(root) {
|
|
94572
94969
|
try {
|
|
94573
|
-
if (!lstatSync12(
|
|
94970
|
+
if (!lstatSync12(join68(root, ".stella")).isDirectory()) return "none";
|
|
94574
94971
|
} catch {
|
|
94575
94972
|
return "none";
|
|
94576
94973
|
}
|
|
94577
94974
|
let oxagenReal;
|
|
94578
94975
|
try {
|
|
94579
|
-
oxagenReal =
|
|
94976
|
+
oxagenReal = realpathSync11(join68(root, ".oxagen"));
|
|
94580
94977
|
} catch {
|
|
94581
94978
|
return "missing";
|
|
94582
94979
|
}
|
|
94583
94980
|
for (const link of STELLA_LINKS) {
|
|
94584
|
-
const at2 =
|
|
94981
|
+
const at2 = join68(root, link);
|
|
94585
94982
|
try {
|
|
94586
94983
|
if (!lstatSync12(at2).isSymbolicLink()) return "missing";
|
|
94587
|
-
const target2 =
|
|
94984
|
+
const target2 = realpathSync11(at2);
|
|
94588
94985
|
if (target2 !== oxagenReal && !target2.startsWith(oxagenReal + sep11)) {
|
|
94589
94986
|
return "missing";
|
|
94590
94987
|
}
|
|
@@ -94595,7 +94992,7 @@ function symlinkState(root) {
|
|
|
94595
94992
|
return "linked";
|
|
94596
94993
|
}
|
|
94597
94994
|
function machineId(configDir = getConfigDir()) {
|
|
94598
|
-
const file =
|
|
94995
|
+
const file = join68(configDir, MACHINE_ID_FILE);
|
|
94599
94996
|
let secret = null;
|
|
94600
94997
|
try {
|
|
94601
94998
|
if (existsSync31(file)) {
|
|
@@ -94666,7 +95063,7 @@ async function reportWorkingCopy(opts) {
|
|
|
94666
95063
|
}
|
|
94667
95064
|
function realpathOr2(path2) {
|
|
94668
95065
|
try {
|
|
94669
|
-
return
|
|
95066
|
+
return realpathSync11(path2);
|
|
94670
95067
|
} catch {
|
|
94671
95068
|
return resolve25(path2);
|
|
94672
95069
|
}
|
|
@@ -94677,12 +95074,12 @@ async function ensureWorkspaceLinkIgnored(root) {
|
|
|
94677
95074
|
const topDir = resolve25(top);
|
|
94678
95075
|
const entry2 = relative9(
|
|
94679
95076
|
topDir,
|
|
94680
|
-
|
|
95077
|
+
join68(realpathOr2(root), ".oxagen", "workspace.json")
|
|
94681
95078
|
).split(sep11).join("/");
|
|
94682
95079
|
if (entry2.startsWith("../")) return null;
|
|
94683
95080
|
const rule = await git4(topDir, ["check-ignore", "--no-index", "-v", entry2]);
|
|
94684
95081
|
if (rule !== null) return null;
|
|
94685
|
-
const gitignore =
|
|
95082
|
+
const gitignore = join68(resolve25(top), ".gitignore");
|
|
94686
95083
|
let existing = "";
|
|
94687
95084
|
try {
|
|
94688
95085
|
existing = readFileSync31(gitignore, "utf8");
|
|
@@ -94841,7 +95238,7 @@ Waiting for GitHub authorization (timeout: ${Math.round(poll.timeoutMs / 6e4)} m
|
|
|
94841
95238
|
return null;
|
|
94842
95239
|
}
|
|
94843
95240
|
process.stdout.write(`
|
|
94844
|
-
GitHub connected
|
|
95241
|
+
GitHub connected. Fetching repositories...
|
|
94845
95242
|
`);
|
|
94846
95243
|
let installations;
|
|
94847
95244
|
try {
|
|
@@ -95200,14 +95597,14 @@ import {
|
|
|
95200
95597
|
mkdirSync as mkdirSync14,
|
|
95201
95598
|
readFileSync as readFileSync32,
|
|
95202
95599
|
readdirSync as readdirSync16,
|
|
95203
|
-
realpathSync as
|
|
95600
|
+
realpathSync as realpathSync12,
|
|
95204
95601
|
rmSync as rmSync14,
|
|
95205
95602
|
rmdirSync as rmdirSync7
|
|
95206
95603
|
} from "node:fs";
|
|
95207
95604
|
import {
|
|
95208
|
-
dirname as
|
|
95605
|
+
dirname as dirname38,
|
|
95209
95606
|
isAbsolute as isAbsolute18,
|
|
95210
|
-
join as
|
|
95607
|
+
join as join69,
|
|
95211
95608
|
parse as parsePath2,
|
|
95212
95609
|
posix as posix5,
|
|
95213
95610
|
sep as sep12
|
|
@@ -95232,7 +95629,7 @@ function checkSteeringPath(path2) {
|
|
|
95232
95629
|
}
|
|
95233
95630
|
const normalized = posix5.normalize(path2);
|
|
95234
95631
|
if (normalized !== path2 || normalized.split("/").some((s2) => s2 === ".." || s2 === ".")) {
|
|
95235
|
-
return { ok: false, reason: "
|
|
95632
|
+
return { ok: false, reason: "has a . or .. part or a double slash" };
|
|
95236
95633
|
}
|
|
95237
95634
|
if (!normalized.startsWith(`${OXAGEN_DIR}/`)) {
|
|
95238
95635
|
return { ok: false, reason: "outside .oxagen/" };
|
|
@@ -95320,14 +95717,14 @@ function findLinkedRoot(start) {
|
|
|
95320
95717
|
} catch {
|
|
95321
95718
|
}
|
|
95322
95719
|
if (dir === root) return null;
|
|
95323
|
-
const parent =
|
|
95720
|
+
const parent = dirname38(dir);
|
|
95324
95721
|
if (parent === dir) return null;
|
|
95325
95722
|
dir = parent;
|
|
95326
95723
|
}
|
|
95327
95724
|
}
|
|
95328
95725
|
function fsReader(root) {
|
|
95329
95726
|
return (path2) => {
|
|
95330
|
-
const abs =
|
|
95727
|
+
const abs = join69(root, ...path2.split("/"));
|
|
95331
95728
|
try {
|
|
95332
95729
|
const st = lstatSync13(abs);
|
|
95333
95730
|
if (!st.isFile()) return Buffer.from(`\0not-a-file:${abs}`);
|
|
@@ -95338,14 +95735,14 @@ function fsReader(root) {
|
|
|
95338
95735
|
};
|
|
95339
95736
|
}
|
|
95340
95737
|
function assertInsideOxagen(root, path2) {
|
|
95341
|
-
const oxagenAbs =
|
|
95738
|
+
const oxagenAbs = join69(root, OXAGEN_DIR);
|
|
95342
95739
|
let oxagenReal;
|
|
95343
95740
|
try {
|
|
95344
|
-
oxagenReal =
|
|
95741
|
+
oxagenReal = realpathSync12(oxagenAbs);
|
|
95345
95742
|
} catch {
|
|
95346
95743
|
return;
|
|
95347
95744
|
}
|
|
95348
|
-
const abs =
|
|
95745
|
+
const abs = join69(root, ...path2.split("/"));
|
|
95349
95746
|
try {
|
|
95350
95747
|
if (lstatSync13(abs).isSymbolicLink()) {
|
|
95351
95748
|
throw new Error(
|
|
@@ -95355,11 +95752,11 @@ function assertInsideOxagen(root, path2) {
|
|
|
95355
95752
|
} catch (err2) {
|
|
95356
95753
|
if (err2.code !== "ENOENT") throw err2;
|
|
95357
95754
|
}
|
|
95358
|
-
let dir =
|
|
95755
|
+
let dir = dirname38(abs);
|
|
95359
95756
|
for (; ; ) {
|
|
95360
95757
|
let real = null;
|
|
95361
95758
|
try {
|
|
95362
|
-
real =
|
|
95759
|
+
real = realpathSync12(dir);
|
|
95363
95760
|
} catch {
|
|
95364
95761
|
real = null;
|
|
95365
95762
|
}
|
|
@@ -95369,14 +95766,14 @@ function assertInsideOxagen(root, path2) {
|
|
|
95369
95766
|
}
|
|
95370
95767
|
return;
|
|
95371
95768
|
}
|
|
95372
|
-
const parent =
|
|
95769
|
+
const parent = dirname38(dir);
|
|
95373
95770
|
if (parent === dir) return;
|
|
95374
95771
|
dir = parent;
|
|
95375
95772
|
}
|
|
95376
95773
|
}
|
|
95377
95774
|
function pruneEmptyDirs(root, path2) {
|
|
95378
|
-
const stop =
|
|
95379
|
-
let dir =
|
|
95775
|
+
const stop = join69(root, OXAGEN_DIR);
|
|
95776
|
+
let dir = dirname38(join69(root, ...path2.split("/")));
|
|
95380
95777
|
while (dir.startsWith(stop + sep12)) {
|
|
95381
95778
|
try {
|
|
95382
95779
|
if (readdirSync16(dir).length > 0) return;
|
|
@@ -95384,19 +95781,19 @@ function pruneEmptyDirs(root, path2) {
|
|
|
95384
95781
|
} catch {
|
|
95385
95782
|
return;
|
|
95386
95783
|
}
|
|
95387
|
-
dir =
|
|
95784
|
+
dir = dirname38(dir);
|
|
95388
95785
|
}
|
|
95389
95786
|
}
|
|
95390
95787
|
function applyPlan(root, plan) {
|
|
95391
95788
|
for (const w of plan.writes) assertInsideOxagen(root, w.path);
|
|
95392
95789
|
for (const d of plan.deletes) assertInsideOxagen(root, d);
|
|
95393
95790
|
for (const w of plan.writes) {
|
|
95394
|
-
const abs =
|
|
95395
|
-
mkdirSync14(
|
|
95791
|
+
const abs = join69(root, ...w.path.split("/"));
|
|
95792
|
+
mkdirSync14(dirname38(abs), { recursive: true });
|
|
95396
95793
|
atomicWriteFileSync(abs, w.content);
|
|
95397
95794
|
}
|
|
95398
95795
|
for (const d of plan.deletes) {
|
|
95399
|
-
rmSync14(
|
|
95796
|
+
rmSync14(join69(root, ...d.split("/")), { force: true });
|
|
95400
95797
|
pruneEmptyDirs(root, d);
|
|
95401
95798
|
}
|
|
95402
95799
|
}
|
|
@@ -97282,7 +97679,7 @@ var init_lock = __esm({
|
|
|
97282
97679
|
"source.registry_type: npm, pypi, oci, or nuget."
|
|
97283
97680
|
),
|
|
97284
97681
|
digest: sha256Schema2.describe(
|
|
97285
|
-
"For oci, the image's manifest
|
|
97682
|
+
"For oci, the SHA-256 of the image's manifest. For pypi, the SHA-256 of file. For the others, the SHA-256 of the package archive."
|
|
97286
97683
|
),
|
|
97287
97684
|
file: pypiLockFileSchema.optional().describe("For pypi: the one file of the release the launch installs.")
|
|
97288
97685
|
}),
|
|
@@ -97610,20 +98007,20 @@ var init_envelope3 = __esm({
|
|
|
97610
98007
|
);
|
|
97611
98008
|
envelopeSignatureSchema2 = external_exports.object({
|
|
97612
98009
|
key_id: external_exports.string().regex(/^[0-9a-f]{16}$/, "a key id is 16 lowercase hex characters").describe(
|
|
97613
|
-
"The first 8 bytes of the SHA-256 of the
|
|
98010
|
+
"The first 8 bytes of the SHA-256 of the public key that locks the envelope, in hex."
|
|
97614
98011
|
),
|
|
97615
98012
|
alg: external_exports.literal("ed25519"),
|
|
97616
98013
|
sig: external_exports.string().regex(
|
|
97617
98014
|
/^[A-Za-z0-9+/]{86}==$/,
|
|
97618
|
-
"an Ed25519
|
|
98015
|
+
"an Ed25519 lock is 64 bytes in padded base64"
|
|
97619
98016
|
).describe(
|
|
97620
|
-
"The
|
|
98017
|
+
"The lock over the envelope's RFC 8785 bytes without its `signature` field."
|
|
97621
98018
|
)
|
|
97622
|
-
}).strict().describe("The cloud gateway's
|
|
98019
|
+
}).strict().describe("The cloud gateway's lock on the envelope.");
|
|
97623
98020
|
envelopeDeadlineSchema = external_exports.number().int().min(1).max(3e5).optional();
|
|
97624
98021
|
machineIdSchema2 = external_exports.string().regex(/^[A-Za-z0-9_-]{1,64}$/, "not a machine id");
|
|
97625
98022
|
issuedAtSchema = instantSchema2.describe(
|
|
97626
|
-
"When the cloud gateway
|
|
98023
|
+
"When the cloud gateway locked the envelope."
|
|
97627
98024
|
);
|
|
97628
98025
|
expiresAtSchema = instantSchema2.describe(
|
|
97629
98026
|
`When the envelope stops being valid: after issued_at, and at most ${ENVELOPE_TTL_MAX_MS2 / 1e3} seconds after it.`
|
|
@@ -97770,7 +98167,7 @@ var init_relay_envelope = __esm({
|
|
|
97770
98167
|
),
|
|
97771
98168
|
credential: relayCredentialSchema.optional(),
|
|
97772
98169
|
signature: envelopeSignatureSchema2
|
|
97773
|
-
}).strict().describe("One request the cloud gateway decided and
|
|
98170
|
+
}).strict().describe("One request the cloud gateway decided and locked for a relay."),
|
|
97774
98171
|
[expiryCheck, mutualTlsCheck]
|
|
97775
98172
|
);
|
|
97776
98173
|
}
|
|
@@ -97801,7 +98198,7 @@ var init_local_call_envelope = __esm({
|
|
|
97801
98198
|
"The tool's definition hash in the lock."
|
|
97802
98199
|
),
|
|
97803
98200
|
package_digest: sha256Schema2.describe(
|
|
97804
|
-
"The lock's
|
|
98201
|
+
"The lock's hash of the package or binary. The local gateway refuses a command that does not match."
|
|
97805
98202
|
),
|
|
97806
98203
|
arguments_hash: sha256Schema2.describe(
|
|
97807
98204
|
"SHA-256 over the RFC 8785 form of the upstream arguments, after the input was shaped."
|
|
@@ -97820,7 +98217,7 @@ var init_local_call_envelope = __esm({
|
|
|
97820
98217
|
expires_at: expiresAtSchema,
|
|
97821
98218
|
signature: envelopeSignatureSchema2
|
|
97822
98219
|
}).strict().describe(
|
|
97823
|
-
"One call to a local server that the cloud gateway decided and
|
|
98220
|
+
"One call to a local server that the cloud gateway decided and locked."
|
|
97824
98221
|
),
|
|
97825
98222
|
[expiryCheck]
|
|
97826
98223
|
);
|
|
@@ -97840,7 +98237,7 @@ var init_local_discovery_envelope = __esm({
|
|
|
97840
98237
|
external_exports.object({
|
|
97841
98238
|
schema: external_exports.literal("local-discovery-envelope/v1"),
|
|
97842
98239
|
package_digest: sha256Schema2.describe(
|
|
97843
|
-
"The lock's
|
|
98240
|
+
"The lock's hash of the package or binary. The local gateway refuses a command that does not match."
|
|
97844
98241
|
),
|
|
97845
98242
|
launch_digest: sha256Schema2.describe(
|
|
97846
98243
|
"SHA-256 over the RFC 8785 form of the launch's command, args with each ${NAME} unfilled, and env names. The local gateway refuses a launch that does not match."
|
|
@@ -97856,7 +98253,7 @@ var init_local_discovery_envelope = __esm({
|
|
|
97856
98253
|
expires_at: expiresAtSchema,
|
|
97857
98254
|
signature: envelopeSignatureSchema2
|
|
97858
98255
|
}).strict().describe(
|
|
97859
|
-
"One discovery of a local server's tools that the cloud gateway decided and
|
|
98256
|
+
"One discovery of a local server's tools that the cloud gateway decided and locked."
|
|
97860
98257
|
),
|
|
97861
98258
|
[expiryCheck]
|
|
97862
98259
|
);
|
|
@@ -139514,9 +139911,9 @@ import {
|
|
|
139514
139911
|
mkdirSync as mkdirSync15,
|
|
139515
139912
|
readFileSync as readFileSync33,
|
|
139516
139913
|
readlinkSync as readlinkSync4,
|
|
139517
|
-
statSync as
|
|
139914
|
+
statSync as statSync20
|
|
139518
139915
|
} from "node:fs";
|
|
139519
|
-
import { dirname as
|
|
139916
|
+
import { dirname as dirname39, isAbsolute as isAbsolute19, join as join70, relative as relative10, resolve as resolve27, sep as sep13 } from "node:path";
|
|
139520
139917
|
function cloneRepoKind(root) {
|
|
139521
139918
|
const out = git5(root, ["remote", "get-url", "origin"]);
|
|
139522
139919
|
const url = out?.toString("utf8").trim() ?? "";
|
|
@@ -139556,7 +139953,7 @@ function commitOf2(root, ref) {
|
|
|
139556
139953
|
return sha2.length > 0 ? sha2 : null;
|
|
139557
139954
|
}
|
|
139558
139955
|
function readWorkingFile(root, path2) {
|
|
139559
|
-
const abs =
|
|
139956
|
+
const abs = join70(root, ...path2.split("/"));
|
|
139560
139957
|
try {
|
|
139561
139958
|
const stat7 = lstatSync14(abs);
|
|
139562
139959
|
if (stat7.isSymbolicLink()) return readlinkSync4(abs, "utf8");
|
|
@@ -139635,14 +140032,14 @@ function chooseBase(root, ref) {
|
|
|
139635
140032
|
}
|
|
139636
140033
|
function isFile(path2) {
|
|
139637
140034
|
try {
|
|
139638
|
-
return
|
|
140035
|
+
return statSync20(path2).isFile();
|
|
139639
140036
|
} catch {
|
|
139640
140037
|
return false;
|
|
139641
140038
|
}
|
|
139642
140039
|
}
|
|
139643
140040
|
function isDir(path2) {
|
|
139644
140041
|
try {
|
|
139645
|
-
return
|
|
140042
|
+
return statSync20(path2).isDirectory();
|
|
139646
140043
|
} catch {
|
|
139647
140044
|
return false;
|
|
139648
140045
|
}
|
|
@@ -139650,10 +140047,10 @@ function isDir(path2) {
|
|
|
139650
140047
|
function findSteeringRoot(start) {
|
|
139651
140048
|
let dir = resolve27(start);
|
|
139652
140049
|
for (; ; ) {
|
|
139653
|
-
if (isFile(
|
|
140050
|
+
if (isFile(join70(dir, WORKSPACE_TOML_PATH)) || isFile(join70(dir, AGENTS_MD_PATH)) && isDir(join70(dir, STEERING_DIR))) {
|
|
139654
140051
|
return dir;
|
|
139655
140052
|
}
|
|
139656
|
-
const parent =
|
|
140053
|
+
const parent = dirname39(dir);
|
|
139657
140054
|
if (parent === dir) return null;
|
|
139658
140055
|
dir = parent;
|
|
139659
140056
|
}
|
|
@@ -139730,7 +140127,7 @@ function cacheFile(cacheDir, root) {
|
|
|
139730
140127
|
key: token === void 0 ? null : createHash23("sha256").update(token).digest("hex").slice(0, 16)
|
|
139731
140128
|
};
|
|
139732
140129
|
const key = createHash23("sha256").update(JSON.stringify([root, identity])).digest("hex").slice(0, 32);
|
|
139733
|
-
return
|
|
140130
|
+
return join70(cacheDir, `${key}.json`);
|
|
139734
140131
|
}
|
|
139735
140132
|
function readCache(file, now) {
|
|
139736
140133
|
let entry2;
|
|
@@ -139758,7 +140155,7 @@ async function publishedInputs(root, deps, refresh, out) {
|
|
|
139758
140155
|
}
|
|
139759
140156
|
if (file !== null) {
|
|
139760
140157
|
try {
|
|
139761
|
-
mkdirSync15(
|
|
140158
|
+
mkdirSync15(dirname39(file), { recursive: true });
|
|
139762
140159
|
atomicWriteFileSync(
|
|
139763
140160
|
file,
|
|
139764
140161
|
JSON.stringify({
|
|
@@ -139844,7 +140241,7 @@ function defaultDeps2() {
|
|
|
139844
140241
|
return {
|
|
139845
140242
|
fetchPublished: fetchSteeringIndex,
|
|
139846
140243
|
cedar: cedarHooks,
|
|
139847
|
-
cacheDir:
|
|
140244
|
+
cacheDir: join70(getConfigDir(), "cache", "steering-check"),
|
|
139848
140245
|
now: () => Date.now()
|
|
139849
140246
|
};
|
|
139850
140247
|
}
|
|
@@ -144196,7 +144593,7 @@ var init_src9 = __esm({
|
|
|
144196
144593
|
|
|
144197
144594
|
// src/commands/codegraph-upload/files.ts
|
|
144198
144595
|
import { readdir as readdir5, stat as stat5 } from "node:fs/promises";
|
|
144199
|
-
import { join as
|
|
144596
|
+
import { join as join71, relative as relative11, sep as sep14 } from "node:path";
|
|
144200
144597
|
function hasGlobChars(pattern) {
|
|
144201
144598
|
return /[*?[\]{}]/.test(pattern);
|
|
144202
144599
|
}
|
|
@@ -144208,7 +144605,7 @@ async function walk(root, dir, out) {
|
|
|
144208
144605
|
const entries2 = await readdir5(dir, { withFileTypes: true });
|
|
144209
144606
|
for (const entry2 of entries2) {
|
|
144210
144607
|
if (entry2.isSymbolicLink()) continue;
|
|
144211
|
-
const full =
|
|
144608
|
+
const full = join71(dir, entry2.name);
|
|
144212
144609
|
if (entry2.isDirectory()) {
|
|
144213
144610
|
if (!SKIP_DIRS.has(entry2.name)) await walk(root, full, out);
|
|
144214
144611
|
} else if (entry2.isFile()) {
|
|
@@ -144220,7 +144617,7 @@ async function expandPattern(root, pattern) {
|
|
|
144220
144617
|
const wanted = normalize3(pattern.trim());
|
|
144221
144618
|
if (!hasGlobChars(wanted)) {
|
|
144222
144619
|
try {
|
|
144223
|
-
const info = await stat5(
|
|
144620
|
+
const info = await stat5(join71(root, wanted));
|
|
144224
144621
|
return info.isFile() ? [wanted] : [];
|
|
144225
144622
|
} catch {
|
|
144226
144623
|
return [];
|
|
@@ -144371,7 +144768,7 @@ var init_token = __esm({
|
|
|
144371
144768
|
});
|
|
144372
144769
|
|
|
144373
144770
|
// src/commands/codegraph-upload/run.ts
|
|
144374
|
-
import { join as
|
|
144771
|
+
import { join as join72 } from "node:path";
|
|
144375
144772
|
function addDropped(into, more) {
|
|
144376
144773
|
into.sensitiveValues += more.sensitiveValues;
|
|
144377
144774
|
into.secretData += more.secretData;
|
|
@@ -144389,7 +144786,7 @@ async function uploadOne(deps, config, token, group, path2, totals2) {
|
|
|
144389
144786
|
const label2 = `${group.kind}/${group.source} ${path2}`;
|
|
144390
144787
|
let bytes;
|
|
144391
144788
|
try {
|
|
144392
|
-
bytes = await deps.readFile(
|
|
144789
|
+
bytes = await deps.readFile(join72(deps.cwd, path2));
|
|
144393
144790
|
} catch (error) {
|
|
144394
144791
|
totals2.failed += 1;
|
|
144395
144792
|
deps.log(`error: ${label2}: cannot read the file: ${error.message}`);
|
|
@@ -144847,7 +145244,7 @@ var init_usage = __esm({
|
|
|
144847
145244
|
"Oxagen CLI collects anonymous usage telemetry (command names, durations,",
|
|
144848
145245
|
"coarse success/error categories, OS/arch) to improve the product. It never",
|
|
144849
145246
|
"collects code, prompts, file contents, file paths, model slugs, or",
|
|
144850
|
-
"personal data
|
|
145247
|
+
"personal data. See TELEMETRY.md for the exact field list.",
|
|
144851
145248
|
"",
|
|
144852
145249
|
"Opt out anytime: `oxagen telemetry off`, or set OXAGEN_TELEMETRY=0 /",
|
|
144853
145250
|
"DO_NOT_TRACK=1. This notice only prints once.",
|
|
@@ -144878,7 +145275,7 @@ function telemetryStatus(writer = stdoutWriter) {
|
|
|
144878
145275
|
status2,
|
|
144879
145276
|
() => [
|
|
144880
145277
|
`Telemetry: ${enabled ? "enabled" : "disabled"}`,
|
|
144881
|
-
`Install id: ${installId ?? "(not yet generated
|
|
145278
|
+
`Install id: ${installId ?? "(not yet generated; created on first command)"}`,
|
|
144882
145279
|
`Ingest endpoint: ${ingestEndpoint}`,
|
|
144883
145280
|
"See TELEMETRY.md for the full disclosure."
|
|
144884
145281
|
].join("\n")
|
|
@@ -144893,7 +145290,7 @@ function telemetryOff(writer = stdoutWriter) {
|
|
|
144893
145290
|
const config = readConfig();
|
|
144894
145291
|
writeConfig({ telemetry: { ...config.telemetry, enabled: false } });
|
|
144895
145292
|
createOutput({}, writer).info(
|
|
144896
|
-
"\u2713 Telemetry disabled
|
|
145293
|
+
"\u2713 Telemetry disabled. No usage data will be sent."
|
|
144897
145294
|
);
|
|
144898
145295
|
}
|
|
144899
145296
|
function isSubcommand(value) {
|
|
@@ -144983,7 +145380,7 @@ function makeErrorHtml(message) {
|
|
|
144983
145380
|
<html lang="en">
|
|
144984
145381
|
<head>
|
|
144985
145382
|
<meta charset="utf-8">
|
|
144986
|
-
<title>Oxagen
|
|
145383
|
+
<title>Oxagen: Login failed</title>
|
|
144987
145384
|
<style>
|
|
144988
145385
|
body { font-family: system-ui, sans-serif; display: flex; justify-content: center;
|
|
144989
145386
|
align-items: center; min-height: 100vh; margin: 0; background: #f4f4f5; }
|
|
@@ -145680,7 +146077,7 @@ async function agentStatus2(agent, opts = {}, writer = stdoutWriter) {
|
|
|
145680
146077
|
return;
|
|
145681
146078
|
}
|
|
145682
146079
|
const { identity } = result2;
|
|
145683
|
-
writer.write(`${identity.name} (${identity.slug})
|
|
146080
|
+
writer.write(`${identity.name} (${identity.slug}): ${identity.status}`);
|
|
145684
146081
|
writer.write(` id ${identity.id}`);
|
|
145685
146082
|
writer.write(` agent key ${identity.agentKey ?? "\u2014"}`);
|
|
145686
146083
|
writer.write(` harness ${identity.harness}`);
|
|
@@ -146126,7 +146523,7 @@ async function routerPreview(prompt, opts = {}, writer = stdoutWriter) {
|
|
|
146126
146523
|
writer.write("");
|
|
146127
146524
|
if (result2.candidates.length === 0) {
|
|
146128
146525
|
writer.write(
|
|
146129
|
-
"No observed
|
|
146526
|
+
"No observed models for this class. Deterministic fallback used."
|
|
146130
146527
|
);
|
|
146131
146528
|
return;
|
|
146132
146529
|
}
|
|
@@ -146383,7 +146780,7 @@ async function handleSecretImport(opts, writer = stdoutWriter) {
|
|
|
146383
146780
|
const { rows, committed } = await apiPostOrThrow("secret/import-env", { text: text5, environmentId, commit: !!opts.yes });
|
|
146384
146781
|
const newCount = rows.filter((r) => r.isNewKey).length;
|
|
146385
146782
|
writer.write(
|
|
146386
|
-
`${committed ? "imported" : "preview"}
|
|
146783
|
+
`${committed ? "imported" : "preview"}: ${rows.length} parsed (${newCount} new, ${rows.length - newCount} existing):`
|
|
146387
146784
|
);
|
|
146388
146785
|
printTable(
|
|
146389
146786
|
["", "KEY", "TARGET", "SENS", "STATE"],
|
|
@@ -146616,7 +147013,7 @@ function addHostWrapCommands(parent) {
|
|
|
146616
147013
|
function buildProgram() {
|
|
146617
147014
|
const program2 = new Command();
|
|
146618
147015
|
program2.name("oxagen").description(
|
|
146619
|
-
"Oxagen governance CLI
|
|
147016
|
+
"Oxagen governance CLI: spend, traces, grounding, credentials, and audit"
|
|
146620
147017
|
).version(version).option(
|
|
146621
147018
|
"-m, --model <slug>",
|
|
146622
147019
|
"Model slug for subcommands that price or filter by model (e.g. cost)"
|
|
@@ -146641,7 +147038,7 @@ function buildProgram() {
|
|
|
146641
147038
|
"github",
|
|
146642
147039
|
"Route repository Git requests through the host's credential custody"
|
|
146643
147040
|
],
|
|
146644
|
-
["arp", "Capture and prepare local Agent Run Protocol
|
|
147041
|
+
["arp", "Capture and prepare local Agent Run Protocol save points"]
|
|
146645
147042
|
];
|
|
146646
147043
|
for (const [name, description] of recorderCommands) {
|
|
146647
147044
|
program2.command(name, { hidden: true }).description(description).helpOption(false).allowUnknownOption().allowExcessArguments().action(async () => {
|
|
@@ -146657,17 +147054,17 @@ function buildProgram() {
|
|
|
146657
147054
|
handleCost2(merged);
|
|
146658
147055
|
});
|
|
146659
147056
|
const budgetCmd = program2.command("budget").description(
|
|
146660
|
-
"Hard period-to-date spend ceilings that gate agent runs
|
|
147057
|
+
"Hard period-to-date spend ceilings that gate agent runs (org + workspace)"
|
|
146661
147058
|
);
|
|
146662
147059
|
budgetCmd.command("show").description("Show configured spend ceilings with their live burn").option("--json", "Output JSON").action(async (opts) => {
|
|
146663
147060
|
const { budgetShow: budgetShow2 } = await Promise.resolve().then(() => (init_budget2(), budget_exports));
|
|
146664
147061
|
await budgetShow2(opts);
|
|
146665
147062
|
});
|
|
146666
147063
|
budgetCmd.command("set").description(
|
|
146667
|
-
"Set (create or replace) a spend ceiling
|
|
147064
|
+
"Set (create or replace) a spend ceiling (Owner/Admin/Billing only)"
|
|
146668
147065
|
).requiredOption("--scope <scope>", "org | workspace").requiredOption("--period <period>", "monthly | rolling").requiredOption("--limit <usd>", "Hard USD ceiling (> 0)").option(
|
|
146669
147066
|
"--window-days <n>",
|
|
146670
|
-
"Trailing window in days
|
|
147067
|
+
"Trailing window in days: required for --period rolling, omit for monthly"
|
|
146671
147068
|
).option(
|
|
146672
147069
|
"--enabled <bool>",
|
|
146673
147070
|
"Whether the ceiling is enforced (true/false)",
|
|
@@ -146699,7 +147096,7 @@ function buildProgram() {
|
|
|
146699
147096
|
}
|
|
146700
147097
|
);
|
|
146701
147098
|
const priceCmd = program2.command("price").description(
|
|
146702
|
-
"The organization's negotiated rates in the price book
|
|
147099
|
+
"The organization's negotiated rates in the price book: what runs are billed at"
|
|
146703
147100
|
);
|
|
146704
147101
|
priceCmd.command("list").description(
|
|
146705
147102
|
"Read current prices and optionally scheduled negotiated rates"
|
|
@@ -146713,7 +147110,7 @@ function buildProgram() {
|
|
|
146713
147110
|
}
|
|
146714
147111
|
);
|
|
146715
147112
|
priceCmd.command("set").description(
|
|
146716
|
-
"Set a negotiated rate for one model and token class
|
|
147113
|
+
"Set a negotiated rate for one model and token class (Owner/Admin/Billing only)"
|
|
146717
147114
|
).requiredOption("--provider <provider>", "Provider, e.g. anthropic").requiredOption("--model <model>", "Model id, e.g. claude-sonnet-5").requiredOption(
|
|
146718
147115
|
"--token-class <class>",
|
|
146719
147116
|
"input_uncached | cache_read | cache_write_5m | cache_write_1h | output | reasoning | server_tool_request | embedding_input | rerank | image | video_second"
|
|
@@ -146737,7 +147134,7 @@ function buildProgram() {
|
|
|
146737
147134
|
await priceSet2(opts);
|
|
146738
147135
|
});
|
|
146739
147136
|
priceCmd.command("remove").description(
|
|
146740
|
-
"End a negotiated rate so the model returns to the list price
|
|
147137
|
+
"End a negotiated rate so the model returns to the list price (Owner/Admin/Billing only)"
|
|
146741
147138
|
).requiredOption("--provider <provider>", "Provider, e.g. anthropic").requiredOption("--model <model>", "Model id, e.g. claude-sonnet-5").requiredOption("--token-class <class>", "The token class to end").option("--region <region>", "Region the rate applies to; omit for any").option(
|
|
146742
147139
|
"--at <instant>",
|
|
146743
147140
|
"RFC 3339 instant the rate stops applying; omit for now"
|
|
@@ -146820,23 +147217,23 @@ function buildProgram() {
|
|
|
146820
147217
|
}
|
|
146821
147218
|
);
|
|
146822
147219
|
const contextCmd = program2.command("context").description(
|
|
146823
|
-
"Steering: record a
|
|
147220
|
+
"Steering: record a suggestion for a steering record, or revert a merged one"
|
|
146824
147221
|
);
|
|
146825
147222
|
contextCmd.command("propose").description(
|
|
146826
|
-
"Record a
|
|
147223
|
+
"Record a suggestion (the record it should become, why); its steering PR is opened and merged in Oxagen"
|
|
146827
147224
|
).requiredOption(
|
|
146828
147225
|
"--lineage <id>",
|
|
146829
|
-
"The
|
|
147226
|
+
"The record ID (the file stem under .oxagen/rules/)"
|
|
146830
147227
|
).requiredOption(
|
|
146831
147228
|
"--kind <kind>",
|
|
146832
147229
|
"rule | constraint | procedure | fact | memory | preference"
|
|
146833
|
-
).requiredOption("--force <force>", "must | should | may | info").requiredOption("--scope <scope>", "workspace | repository").requiredOption("--statement <text>", "The single-sentence claim").requiredOption("--rationale <text>", "Why the record should be published").option("--effect <effect>", "require | forbid
|
|
147230
|
+
).requiredOption("--force <force>", "must | should | may | info").requiredOption("--scope <scope>", "workspace | repository").requiredOption("--statement <text>", "The single-sentence claim").requiredOption("--rationale <text>", "Why the record should be published").option("--effect <effect>", "require | forbid (a constraint only)").option("--json", "Output JSON").action(
|
|
146834
147231
|
async (opts) => {
|
|
146835
147232
|
const { contextPropose: contextPropose2 } = await Promise.resolve().then(() => (init_context4(), context_exports));
|
|
146836
147233
|
await contextPropose2(opts);
|
|
146837
147234
|
}
|
|
146838
147235
|
);
|
|
146839
|
-
contextCmd.command("revert <
|
|
147236
|
+
contextCmd.command("revert <suggestionId>").description(
|
|
146840
147237
|
"Open a steering PR that undoes a merged one (revert_steering_pr); it merges after its own review"
|
|
146841
147238
|
).option("--json", "Output JSON").action(async (proposalId, opts) => {
|
|
146842
147239
|
const { contextRevert: contextRevert2 } = await Promise.resolve().then(() => (init_context4(), context_exports));
|
|
@@ -146984,8 +147381,8 @@ function buildProgram() {
|
|
|
146984
147381
|
await steeringPromote2(findingId, opts);
|
|
146985
147382
|
});
|
|
146986
147383
|
steeringCmd.command("restore-block").argument(
|
|
146987
|
-
"<
|
|
146988
|
-
"The prp_\u2026
|
|
147384
|
+
"<suggestion-id>",
|
|
147385
|
+
"The prp_\u2026 suggestion whose steering PR holds the file"
|
|
146989
147386
|
).argument("<path>", "AGENTS.md, CLAUDE.md, or README.md").description(
|
|
146990
147387
|
"Restore Oxagen's managed block in one file of an open steering PR, as one commit from the production branch"
|
|
146991
147388
|
).option("--json", "Output JSON").action(
|
|
@@ -147002,7 +147399,7 @@ function buildProgram() {
|
|
|
147002
147399
|
await toolsMigrate2(opts);
|
|
147003
147400
|
});
|
|
147004
147401
|
const runCmd = program2.command("run").description(
|
|
147005
|
-
"Start an agent under the contained launcher (`oxagen run -- claude -p <task>`), start a run in its own sandbox (`oxagen run --harness claude --workspace-slug <slug> --repo <owner/name>`), or read a recorded run: its chain
|
|
147402
|
+
"Start an agent under the contained launcher (`oxagen run -- claude -p <task>`), start a run in its own sandbox (`oxagen run --harness claude --workspace-slug <slug> --repo <owner/name>`), or read a recorded run: its chain, Oxagen's lock on it, and its locked evidence bundle"
|
|
147006
147403
|
).option("--image <ref>", "The contained image (or OXAGEN_CONTAINED_IMAGE)").option(
|
|
147007
147404
|
"--workspace <dir>",
|
|
147008
147405
|
"The repository root to mount at /workspace (default: the current directory). A sandbox run names its workspace with --workspace-slug"
|
|
@@ -147072,7 +147469,7 @@ function buildProgram() {
|
|
|
147072
147469
|
}
|
|
147073
147470
|
);
|
|
147074
147471
|
runCmd.command("chain").description(
|
|
147075
|
-
"Show what makes a run's record tamper-evident: the hash rule, the root, the
|
|
147472
|
+
"Show what makes a run's record tamper-evident: the hash rule, the root, the locks taken along the way, the gaps, and the replay ladder"
|
|
147076
147473
|
).argument("<run-id>", "The run's public id (arun_\u2026 or tse_\u2026)").option("--json", "Output JSON").action(async (runId, opts) => {
|
|
147077
147474
|
const { runChain: runChain2 } = await Promise.resolve().then(() => (init_run4(), run_exports));
|
|
147078
147475
|
await runChain2(runId, opts);
|
|
@@ -147087,7 +147484,7 @@ function buildProgram() {
|
|
|
147087
147484
|
"Read one page of a run's transcript: its entries, the count per chip over the whole run, and a search of the kept bodies"
|
|
147088
147485
|
).argument("<run-id>", "The run's public id (arun_\u2026 or tse_\u2026)").option("--zoom <zoom>", "turns, steps, or everything", "steps").option(
|
|
147089
147486
|
"--kinds <kinds>",
|
|
147090
|
-
"The chips to keep, comma-separated (thinking,
|
|
147487
|
+
"The chips to keep, comma-separated (thinking,tools)"
|
|
147091
147488
|
).option("--query <words>", "Words to search the entries for, ignoring case").option("--after <cursor>", "The cursor the previous page printed").option("--limit <n>", "Page size, 1 to 500", wholeNumber2(1, 500)).option("--text <text>", "How much of each body to carry: excerpt or full").option("--json", "Output the raw contract payload as JSON").action(
|
|
147092
147489
|
async (runId, opts) => {
|
|
147093
147490
|
const { runTranscript: runTranscript2 } = await Promise.resolve().then(() => (init_run4(), run_exports));
|
|
@@ -147101,7 +147498,7 @@ function buildProgram() {
|
|
|
147101
147498
|
await runContext2(runId, opts);
|
|
147102
147499
|
});
|
|
147103
147500
|
runCmd.command("export").description(
|
|
147104
|
-
"Queue the
|
|
147501
|
+
"Queue the evidence bundle for a locked run. Oxagen locks the bundle so anyone can check it offline (Owner/Admin only)"
|
|
147105
147502
|
).argument("<run-id>", "The run's public id (arun_\u2026 or tse_\u2026)").option("--json", "Output JSON").action(async (runId, opts) => {
|
|
147106
147503
|
const { runExport: runExport2 } = await Promise.resolve().then(() => (init_run4(), run_exports));
|
|
147107
147504
|
await runExport2(runId, opts);
|
|
@@ -147116,7 +147513,7 @@ function buildProgram() {
|
|
|
147116
147513
|
await runExportStatus2(exportId, opts);
|
|
147117
147514
|
});
|
|
147118
147515
|
runCmd.command("download").description(
|
|
147119
|
-
"Download a ready run export and check its sha256 against the recorded
|
|
147516
|
+
"Download a ready run export and check its sha256 against the recorded hash"
|
|
147120
147517
|
).argument(
|
|
147121
147518
|
"<export-id>",
|
|
147122
147519
|
"The export id `oxagen run export` printed (rexp_\u2026)"
|
|
@@ -147281,13 +147678,13 @@ function buildProgram() {
|
|
|
147281
147678
|
)
|
|
147282
147679
|
);
|
|
147283
147680
|
program2.command("verify").description(
|
|
147284
|
-
"Check a run export bundle offline: each frame's
|
|
147681
|
+
"Check a run export bundle offline: each frame's hash and link, the Merkle root, and each lock"
|
|
147285
147682
|
).argument("<bundle>", "The bundle's .zip file or its extracted directory").option("--json", "Output the verification as JSON").action(async (bundle2, opts) => {
|
|
147286
147683
|
const { verifyBundle: verifyBundle4 } = await Promise.resolve().then(() => (init_verify2(), verify_exports));
|
|
147287
147684
|
await verifyBundle4(bundle2, opts);
|
|
147288
147685
|
});
|
|
147289
147686
|
program2.command("attention").description(
|
|
147290
|
-
"List what waits on you in this workspace: approvals and questions on your runs, work orders in review, ready work items assigned to you, and steering
|
|
147687
|
+
"List what waits on you in this workspace: approvals and questions on your runs, work orders in review, ready work items assigned to you, and steering suggestions"
|
|
147291
147688
|
).option(
|
|
147292
147689
|
"--state <state>",
|
|
147293
147690
|
"open lists what waits; resolved lists what was answered",
|
|
@@ -147373,7 +147770,7 @@ function buildProgram() {
|
|
|
147373
147770
|
).option(
|
|
147374
147771
|
"--harness <harness>",
|
|
147375
147772
|
"Only memories this harness keeps: claude-code, codex, cursor, stella, or claude-desktop"
|
|
147376
|
-
).option("--agent <
|
|
147773
|
+
).option("--agent <record-id>", "Only memories this agent wrote").option(
|
|
147377
147774
|
"--repository <repo>",
|
|
147378
147775
|
"Only memories scoped to this repository, such as github.com/acme/api"
|
|
147379
147776
|
).option(
|
|
@@ -147598,16 +147995,16 @@ function buildProgram() {
|
|
|
147598
147995
|
}
|
|
147599
147996
|
);
|
|
147600
147997
|
program2.command("telemetry").description(
|
|
147601
|
-
"Inspect or control anonymous CLI usage telemetry (on by default
|
|
147998
|
+
"Inspect or control anonymous CLI usage telemetry (on by default; see TELEMETRY.md)"
|
|
147602
147999
|
).argument("[subcommand]", "on | off | status (default: status)").action(async (subcommand) => {
|
|
147603
148000
|
const { handleTelemetry: handleTelemetry2 } = await Promise.resolve().then(() => (init_telemetry(), telemetry_exports));
|
|
147604
148001
|
handleTelemetry2(subcommand);
|
|
147605
148002
|
});
|
|
147606
148003
|
program2.command("login").description(
|
|
147607
|
-
"Authenticate the CLI
|
|
148004
|
+
"Authenticate the CLI. Opens a browser by default (interactive). Use --token for CI/headless."
|
|
147608
148005
|
).option(
|
|
147609
148006
|
"--token <token>",
|
|
147610
|
-
"Platform API token
|
|
148007
|
+
"Platform API token: skips browser login (CI/headless)"
|
|
147611
148008
|
).option(
|
|
147612
148009
|
"--org <slug>",
|
|
147613
148010
|
"Organization slug; with a saved session and no --token, rescopes the default without a browser"
|
|
@@ -147670,7 +148067,7 @@ function buildProgram() {
|
|
|
147670
148067
|
"[agent]",
|
|
147671
148068
|
"An agent id or slug. Omit it to unenroll this machine instead"
|
|
147672
148069
|
).description(
|
|
147673
|
-
"With an agent: revoke its live host enrollments, or one host with --host
|
|
148070
|
+
"With an agent: revoke its live host enrollments, or one host with --host (Owner/Admin only). Without one: remove this machine's hooks and service, revoke its enrollment, delete its host key"
|
|
147674
148071
|
).option("--host <tch_id>", "With an agent: only this host").option("--reason <text>", "Recorded on the host and in the revoke command").option("--json", "With an agent: output JSON").option(
|
|
147675
148072
|
"--yes",
|
|
147676
148073
|
"With an agent and no --host: revoke every live host without asking"
|
|
@@ -147893,7 +148290,7 @@ function buildProgram() {
|
|
|
147893
148290
|
await handleEnvSetDefault2(idOrSlug);
|
|
147894
148291
|
});
|
|
147895
148292
|
const routerCmd = program2.command("router").description(
|
|
147896
|
-
"Verified-Outcome Market Router
|
|
148293
|
+
"Verified-Outcome Market Router: learned, economic model routing"
|
|
147897
148294
|
);
|
|
147898
148295
|
routerCmd.command("preview <prompt>").description("Dry-run the routing decision for a prompt (changes nothing)").option("--files <n>", "Expected number of files touched", wholeNumber2(0)).option("--cross-package", "The task crosses package boundaries").option("--task-class <class>", "Override the derived task class").option("--json", "Output JSON").action(
|
|
147899
148296
|
async (prompt, opts) => {
|
|
@@ -147906,7 +148303,7 @@ function buildProgram() {
|
|
|
147906
148303
|
const { routerPolicyGet: routerPolicyGet2 } = await Promise.resolve().then(() => (init_router(), router_exports));
|
|
147907
148304
|
await routerPolicyGet2(opts);
|
|
147908
148305
|
});
|
|
147909
|
-
routerPolicyCmd.command("set").description("Update the policy
|
|
148306
|
+
routerPolicyCmd.command("set").description("Update the policy, which changes spend behavior (org Owner)").option(
|
|
147910
148307
|
"--scope <scope>",
|
|
147911
148308
|
"org | workspace (default workspace)",
|
|
147912
148309
|
oneOf2(["org", "workspace"])
|