@outerlayer/cli 0.4.0 → 0.4.1

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.
Files changed (45) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/README.md +4 -2
  3. package/dist/build-info.json +1 -1
  4. package/dist/{check-WQP2CZDW.js → check-7MFH6HNC.js} +11 -11
  5. package/dist/{chunk-L2DBRKRA.js → chunk-3TFPDVTI.js} +1 -1
  6. package/dist/{chunk-G7FSV7JX.js → chunk-4C4THABW.js} +2116 -5
  7. package/dist/{chunk-DVYHCMB2.js → chunk-7WERLFVR.js} +1 -1
  8. package/dist/{chunk-FAJSS2WN.js → chunk-DM3VFDS3.js} +138 -34
  9. package/dist/{chunk-7A6RVXPZ.js → chunk-HZRNMGLF.js} +1 -1
  10. package/dist/{chunk-3YPKXE5L.js → chunk-LT5TZHYH.js} +8 -5
  11. package/dist/{chunk-HE2D4EY5.js → chunk-LYCDNMOH.js} +1 -1
  12. package/dist/{chunk-FV2CCGXK.js → chunk-QDQEUVUF.js} +1 -1
  13. package/dist/{chunk-FS2VYGZT.js → chunk-QY22NZUW.js} +6 -6
  14. package/dist/{chunk-7YIOOFVJ.js → chunk-RFUPN6KX.js} +4 -4
  15. package/dist/{chunk-3TT7RQYB.js → chunk-SY4GK4SP.js} +1 -1
  16. package/dist/{chunk-NYC54VBD.js → chunk-TWNWNS2Q.js} +5 -5
  17. package/dist/{chunk-5DLBAXY5.js → chunk-W5FVUZXV.js} +2 -2
  18. package/dist/{chunk-6Y63SXFO.js → chunk-WFJ65NUD.js} +1 -1
  19. package/dist/{chunk-2E54Z3P5.js → chunk-Y7KJLXYN.js} +3 -3
  20. package/dist/{chunk-CBZB6XY6.js → chunk-YFHIIH4B.js} +2 -2
  21. package/dist/{cli-NHUXABYH.js → cli-W62AFRSW.js} +71 -47
  22. package/dist/{connect-cmd-OOG4TPU7.js → connect-cmd-ZTJONP37.js} +4 -4
  23. package/dist/{dist-RW4UPPC2.js → dist-44CQVWGT.js} +1 -1
  24. package/dist/{doctor-UFVL4PZY.js → doctor-ZLGZYMDK.js} +7 -7
  25. package/dist/{emit-artifact-cmd-KTYW2TN2.js → emit-artifact-cmd-AKZP7TMF.js} +67 -7
  26. package/dist/{emit-criteria-cmd-VAUUSAYD.js → emit-criteria-cmd-7MXQVCKD.js} +1 -1
  27. package/dist/{emit-finding-cmd-UR4ID45Z.js → emit-finding-cmd-N2FTGCVC.js} +1 -1
  28. package/dist/{emit-result-cmd-FDTUKGKE.js → emit-result-cmd-4CPDBMN2.js} +4 -4
  29. package/dist/index.js +1 -1
  30. package/dist/{init-DXBCOAJK.js → init-55Y4LHWF.js} +6 -6
  31. package/dist/{init-YEXK35CF.js → init-XXEKWZQP.js} +6 -6
  32. package/dist/{init-cmd-NHR7PRSQ.js → init-cmd-WLST2F7G.js} +6 -6
  33. package/dist/{loop-VZOLL4WQ.js → loop-JFIBP4B7.js} +8 -8
  34. package/dist/{machine-WSG52J75.js → machine-ZBPT2J3R.js} +5 -5
  35. package/dist/{mcp-serve-cmd-JPTP5FMS.js → mcp-serve-cmd-N6UD2KBX.js} +1 -1
  36. package/dist/{status-2UZKKNB7.js → status-UJXWZRN5.js} +6 -6
  37. package/dist/{sync-cmd-VPPYCNNM.js → sync-cmd-4G4A7EVN.js} +4 -4
  38. package/dist/{watch-5C4ZBBGO.js → watch-7SKJKGAA.js} +4 -4
  39. package/dist/{work-claim-cmd-LSO2B2EX.js → work-claim-cmd-5F7VZ42N.js} +6 -6
  40. package/dist/{work-cmd-UOQO2AD4.js → work-cmd-QAUZ7MTD.js} +3 -3
  41. package/dist/{work-comment-cmd-WF3EOLAE.js → work-comment-cmd-BNCSBTLH.js} +3 -3
  42. package/dist/{work-open-pr-cmd-4SSQZMYG.js → work-open-pr-cmd-VFYZHIIW.js} +4 -4
  43. package/dist/{work-pr-cmd-6AN6RRQJ.js → work-pr-cmd-PV32ZLSI.js} +2 -2
  44. package/package.json +1 -1
  45. package/skill-pack/maintained/emitting-evidence/SKILL.md +10 -1
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
3
  import { detectActiveSession } from './chunk-BFESLKPP.js';
4
- import { resolveRepoIdentity } from './chunk-G7FSV7JX.js';
4
+ import { resolveRepoIdentity } from './chunk-4C4THABW.js';
5
5
  import { parseTrackerNumber, trackerNumberError } from './chunk-WZBHBH3J.js';
6
6
  import { defaultFetch } from './chunk-BCLJSQCV.js';
7
7
  import { unauthorizedMessage, resolveGatewayCredentials } from './chunk-BOLTI6LR.js';
@@ -1,16 +1,16 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
3
  import { DOCKERD_LOG } from './chunk-CBPPJSAR.js';
4
- import { installScrubContext } from './chunk-HE2D4EY5.js';
5
- import { AssetError, describeCallFailure, obtainImage, ensureRootfs, gitRemoteFor, startServicesFor, createBuildDisk, machineConfig, refusalCode, resolveAgentUser, AgentUserError, runBuildSteps, removeStagedContext, stageGovernedContext, shellQuote, ADDED_USER, createRunnerLog, createContainerRuntime, stopContainer, syncInContainer, formatDuration, cleanupContainer, retrySend, formatClock, GH_CONFIG_YML, ghHostsYml, isLiteralAddress, deleteBuildDisk } from './chunk-7A6RVXPZ.js';
4
+ import { installScrubContext } from './chunk-LYCDNMOH.js';
5
+ import { AssetError, describeCallFailure, obtainImage, ensureRootfs, gitRemoteFor, startServicesFor, createBuildDisk, machineConfig, refusalCode, resolveAgentUser, AgentUserError, runBuildSteps, removeStagedContext, stageGovernedContext, shellQuote, ADDED_USER, createRunnerLog, createContainerRuntime, stopContainer, syncInContainer, formatDuration, cleanupContainer, retrySend, formatClock, GH_CONFIG_YML, ghHostsYml, isLiteralAddress, deleteBuildDisk } from './chunk-HZRNMGLF.js';
6
6
  import { CLAUDE_CODE_VERSION } from './chunk-ZNA27WEV.js';
7
7
  import { isSameProcess, startTimeOf } from './chunk-N5FOE5PS.js';
8
8
  import { childEnvironment } from './chunk-774HEQL6.js';
9
9
  import { waitForAgent, vmExecArgs } from './chunk-W4SQCOZU.js';
10
10
  import { socketPathProblem, vsockLinks, linkVsockSockets } from './chunk-B2G7JHHB.js';
11
- import { WorkCommandError, postJson, isSignatureRefusal } from './chunk-5DLBAXY5.js';
12
- import { planArtifactUpload } from './chunk-6Y63SXFO.js';
13
- import { scrubText } from './chunk-G7FSV7JX.js';
11
+ import { WorkCommandError, postJson, isSignatureRefusal, getJson } from './chunk-W5FVUZXV.js';
12
+ import { planArtifactUpload } from './chunk-WFJ65NUD.js';
13
+ import { scrubText } from './chunk-4C4THABW.js';
14
14
  import { isBuiltinContainer, isBuiltinProcess, isBuiltinVm } from './chunk-5Y3QQRUH.js';
15
15
  import { parseSize } from './chunk-F6GFZXZ3.js';
16
16
  import { claudeCredential, buildEnvironment, JOB_MOUNT, CHECKOUT_DIR, parseIsolation, proxyEnvironment, containerLocalAddress, destinationEnvironment, CLAUDE_CREDENTIAL_VARIABLES, builtInEnvironment, withHooksPath, startBuildServices, BUILT_IN_NAMES, AGENT_CREDENTIAL_MISSING, sharedUserEnvironment, headerVariables, authorEnvironment, withTunnelRecord, commitIdentityRecord, RELAY_PORT } from './chunk-AUFG23AA.js';
@@ -38,8 +38,8 @@ var DOCKER_LOG_LINES = 20;
38
38
  var GUEST_GH_DIR = `${JOB_MOUNT}/gh`;
39
39
  var GUEST_HOOKS_DIR = `${JOB_MOUNT}/git-hooks`;
40
40
  var GUEST_CONTEXT_DIR = `${JOB_MOUNT}/context`;
41
- function firstLine(text) {
42
- return text.trim().split("\n")[0] ?? "";
41
+ function firstLine(text2) {
42
+ return text2.trim().split("\n")[0] ?? "";
43
43
  }
44
44
  function execEnvironment(image, env) {
45
45
  const merged = { ...image, ...env.literals };
@@ -435,25 +435,25 @@ function unspecified(address) {
435
435
  const normal = new URL(`http://[${address}]/`).hostname;
436
436
  return normal === "[::]" || normal === "[::ffff:0:0]";
437
437
  }
438
- function parseBroker(text) {
439
- const match = /^(?:\[([0-9a-fA-F:.]+)\]|([0-9.]+)):(\d{1,5})$/.exec(text);
438
+ function parseBroker(text2) {
439
+ const match = /^(?:\[([0-9a-fA-F:.]+)\]|([0-9.]+)):(\d{1,5})$/.exec(text2);
440
440
  if (match === null) return void 0;
441
441
  const host = match[1] ?? match[2];
442
442
  const port = Number(match[3]);
443
443
  if (!isLiteralAddress(host) || unspecified(host) || port < 1 || port > 65535) return void 0;
444
- return { host, port, text };
444
+ return { host, port, text: text2 };
445
445
  }
446
446
  function readReport(path) {
447
447
  const named = `provision.out names recipe ${path}`;
448
448
  if (!isAbsolute(path)) return { problem: `${named}, which is not an absolute path` };
449
- let text;
449
+ let text2;
450
450
  try {
451
- text = readFileSync(path, "utf8");
451
+ text2 = readFileSync(path, "utf8");
452
452
  } catch {
453
453
  return { problem: `${named}, which does not exist` };
454
454
  }
455
455
  try {
456
- const parsed = JSON.parse(text);
456
+ const parsed = JSON.parse(text2);
457
457
  const lifecycle = parsed.apply?.lifecycle;
458
458
  if (typeof parsed.sourceCommit === "string" && typeof parsed.recipeKey === "string" && typeof parsed.imageId === "string" && typeof lifecycle === "object" && lifecycle !== null && Object.values(lifecycle).every((entries) => Array.isArray(entries) && entries.every((entry) => typeof entry === "object" && entry !== null))) {
459
459
  return { report: { ...parsed, ignored: Array.isArray(parsed.ignored) ? parsed.ignored : [] } };
@@ -635,6 +635,81 @@ async function provisionProcess(input) {
635
635
  function cleanupProcess(runtime, state) {
636
636
  return closeHostBuild(runtime, state);
637
637
  }
638
+
639
+ // src/runner/verdict.ts
640
+ var VERDICT_SETTLE_MS = 5 * 6e4;
641
+ var VERDICT_READ_EVERY_MS = 3e4;
642
+ var REASON_MAX = 200;
643
+ function text(value) {
644
+ return typeof value === "string" ? value : "";
645
+ }
646
+ function fields(value) {
647
+ return Object(value);
648
+ }
649
+ function parseEvaluation(value) {
650
+ if (value === void 0) return void 0;
651
+ const raw = fields(value);
652
+ const verdict = raw.verdict;
653
+ if (verdict !== "pass" && verdict !== "flag" && verdict !== "unverifiable" && verdict !== "waiting") return null;
654
+ const open = [];
655
+ for (const row of Array.isArray(raw.open) ? raw.open : []) {
656
+ const r = fields(row);
657
+ if (r.status !== "flag" && r.status !== "pending") continue;
658
+ open.push({ label: text(r.label), status: r.status, sentence: text(r.sentence) });
659
+ }
660
+ return { verdict, sentence: text(raw.sentence), waitingOn: raw.waitingOn, open };
661
+ }
662
+ async function readItemEvaluation(config, item, fetchImpl) {
663
+ try {
664
+ const { data } = await getJson(config.url, `/v1/work-items/${item}`, config.apiKey, config.appId, fetchImpl, await signerFor(config.configPath));
665
+ return { ok: true, evaluation: parseEvaluation(fields(data).evaluation) };
666
+ } catch (err) {
667
+ return { ok: false, reason: describeCallFailure(err) };
668
+ }
669
+ }
670
+ function rowText(row) {
671
+ const name = row.label !== "" && row.sentence !== "" && row.label !== row.sentence ? `${row.label}: ${row.sentence}` : row.sentence || row.label;
672
+ return row.status === "pending" ? `${name} (no result)` : name;
673
+ }
674
+ function fit(prefix, parts) {
675
+ let text2 = prefix + parts.join("; ");
676
+ for (let kept = parts.length - 1; text2.length > REASON_MAX && kept > 0; kept--) {
677
+ text2 = `${prefix}${parts.slice(0, kept).join("; ")}; and ${parts.length - kept} more`;
678
+ }
679
+ return text2.length > REASON_MAX ? `${text2.slice(0, REASON_MAX - 1)}\u2026` : text2;
680
+ }
681
+ function decideFromEvaluation(read) {
682
+ if (!read.ok) return { outcome: "incomplete", reason: fit("the item's status could not be read: ", [read.reason]) };
683
+ const evaluation = read.evaluation;
684
+ if (evaluation === void 0) return { outcome: "ok" };
685
+ if (evaluation === null) return { outcome: "incomplete", reason: "the item has no evidence evaluation yet" };
686
+ if (evaluation.open.length > 0) return { outcome: "incomplete", reason: fit("checks not passing: ", evaluation.open.map(rowText)) };
687
+ if (evaluation.verdict === "pass") return { outcome: "ok" };
688
+ if (evaluation.verdict === "waiting" && evaluation.waitingOn === "review") return { outcome: "ok" };
689
+ if (evaluation.verdict === "waiting" && evaluation.waitingOn === "links") {
690
+ return { outcome: "incomplete", reason: "the item's evidence was still waiting on session links to be confirmed" };
691
+ }
692
+ if (evaluation.verdict === "waiting" && evaluation.waitingOn === "claim") {
693
+ return { outcome: "incomplete", reason: "the item's required checks had no result when the build ended" };
694
+ }
695
+ return { outcome: "incomplete", reason: fit("the item's verdict is not passing: ", [evaluation.sentence || evaluation.verdict]) };
696
+ }
697
+ function waitMs(ms) {
698
+ return new Promise((resolve) => setTimeout(resolve, ms));
699
+ }
700
+ async function settleVerdict(deps) {
701
+ const settleMs = deps.settleMs ?? VERDICT_SETTLE_MS;
702
+ const everyMs = deps.everyMs ?? VERDICT_READ_EVERY_MS;
703
+ const startedMs = deps.now().getTime();
704
+ for (; ; ) {
705
+ const decision = decideFromEvaluation(await deps.read());
706
+ if (decision.outcome === "ok") return decision;
707
+ if (deps.now().getTime() - startedMs + everyMs > settleMs) return decision;
708
+ await deps.sleep(everyMs);
709
+ }
710
+ }
711
+
712
+ // src/runner/job.ts
638
713
  var LEASE_SECONDS = 900;
639
714
  var RENEW_INTERVAL_SECONDS = 300;
640
715
  var IDLE_CPU_USEC_PER_MINUTE_FLOOR = 2e6;
@@ -753,14 +828,14 @@ function workdirProblem(workdir) {
753
828
  function readProvisionOut(jobDirPath) {
754
829
  const path = join(jobDirPath, "provision.out");
755
830
  if (!existsSync(path)) return { ok: false };
756
- let text;
831
+ let text2;
757
832
  try {
758
- text = readFileSync(path, "utf8");
833
+ text2 = readFileSync(path, "utf8");
759
834
  } catch {
760
835
  return { ok: false };
761
836
  }
762
837
  const kv = {};
763
- for (const line of text.split("\n")) {
838
+ for (const line of text2.split("\n")) {
764
839
  const eq = line.indexOf("=");
765
840
  if (eq === -1) continue;
766
841
  kv[line.slice(0, eq).trim()] = line.slice(eq + 1).trim();
@@ -792,13 +867,13 @@ function commandWithExitCodeTrailer(cmdline) {
792
867
  ].join("\n");
793
868
  }
794
869
  function readExitCode(jobDirPath) {
795
- let text;
870
+ let text2;
796
871
  try {
797
- text = readFileSync(join(jobDirPath, EXIT_CODE_FILE), "utf8");
872
+ text2 = readFileSync(join(jobDirPath, EXIT_CODE_FILE), "utf8");
798
873
  } catch {
799
874
  return void 0;
800
875
  }
801
- const trimmed = text.trim();
876
+ const trimmed = text2.trim();
802
877
  return /^\d+$/.test(trimmed) ? Number(trimmed) : void 0;
803
878
  }
804
879
  function outcomeFromExitCode(jobDirPath) {
@@ -807,8 +882,8 @@ function outcomeFromExitCode(jobDirPath) {
807
882
  return { outcome: code === 0 ? "ok" : "failed", code };
808
883
  }
809
884
  var REASON_FILE = "reason";
810
- var REASON_MAX = 200;
811
- function cutReasonLine(line, max = REASON_MAX) {
885
+ var REASON_MAX2 = 200;
886
+ function cutReasonLine(line, max = REASON_MAX2) {
812
887
  const cut = line.slice(0, max);
813
888
  const last = cut.charCodeAt(cut.length - 1);
814
889
  return last >= 55296 && last <= 56319 ? cut.slice(0, -1) : cut;
@@ -828,8 +903,8 @@ function releaseScrub(config, home) {
828
903
  const secrets = [...headerVariables(config.build?.destinations), ...CLAUDE_CREDENTIAL_VARIABLES].map((name) => process.env[name] ?? "");
829
904
  return { literals: [...scrubList(merged?.literals), ...secrets], patterns: scrubList(merged?.patterns) };
830
905
  }
831
- function stripUnsendableReasonChars(text) {
832
- return text.replace(/\u0000/g, "").replace(/\p{Cs}/gu, "");
906
+ function stripUnsendableReasonChars(text2) {
907
+ return text2.replace(/\u0000/g, "").replace(/\p{Cs}/gu, "");
833
908
  }
834
909
  function readReasonLine(jobDirPath, config, home = homeFromEnv()) {
835
910
  let raw;
@@ -937,8 +1012,8 @@ function isIdle(logMtimeMs, nowMs, idleLimitMinutes, cpuUsecPerMinuteOverWindow)
937
1012
  }
938
1013
  function readCpuUsec(cgroupPath) {
939
1014
  try {
940
- const text = readFileSync(join(cgroupPath, "cpu.stat"), "utf8");
941
- const match = /^usage_usec (\d+)$/m.exec(text);
1015
+ const text2 = readFileSync(join(cgroupPath, "cpu.stat"), "utf8");
1016
+ const match = /^usage_usec (\d+)$/m.exec(text2);
942
1017
  return match ? Number(match[1]) : null;
943
1018
  } catch {
944
1019
  return null;
@@ -965,23 +1040,37 @@ async function renewLease(config, item, fetchImpl) {
965
1040
  }
966
1041
  var ALREADY_RELEASED = "already released";
967
1042
  async function releaseLease(config, item, outcome, detail, fetchImpl) {
968
- const send = async (environment) => postJson(
1043
+ const send = async (environment2, sent2) => postJson(
969
1044
  config.url,
970
1045
  `/v1/work-items/${item}/claim/release`,
971
1046
  config.apiKey,
972
1047
  config.appId,
973
- { host: config.host, outcome, stage: detail.stage, exitCode: detail.exitCode, reason: detail.reason, environment },
1048
+ { host: config.host, outcome: sent2, stage: detail.stage, exitCode: detail.exitCode, reason: detail.reason, environment: environment2 },
974
1049
  fetchImpl,
975
1050
  void 0,
976
1051
  await signerFor(config.configPath)
977
1052
  );
1053
+ let environment = detail.environment;
1054
+ let sent = outcome;
978
1055
  let data;
979
- try {
980
- ({ data } = await send(detail.environment));
981
- } catch (err) {
982
- if (detail.environment?.commitIdentity === void 0 || !(err instanceof WorkCommandError) || err.status !== 400 || err.code !== "invalid_request_body") throw err;
983
- const { commitIdentity: _omitted, ...withoutIdentity } = detail.environment;
984
- ({ data } = await send(withoutIdentity));
1056
+ for (; ; ) {
1057
+ try {
1058
+ ({ data } = await send(environment, sent));
1059
+ break;
1060
+ } catch (err) {
1061
+ if (!(err instanceof WorkCommandError) || err.status !== 400 || err.code !== "invalid_request_body") throw err;
1062
+ const namesOutcome = /\boutcome\b/.test(err.message);
1063
+ if (sent === "incomplete" && namesOutcome) {
1064
+ sent = "ok";
1065
+ } else if (environment?.commitIdentity !== void 0) {
1066
+ const { commitIdentity: _omitted, ...withoutIdentity } = environment;
1067
+ environment = withoutIdentity;
1068
+ } else if (sent === "incomplete") {
1069
+ sent = "ok";
1070
+ } else {
1071
+ throw err;
1072
+ }
1073
+ }
985
1074
  }
986
1075
  return {
987
1076
  releasedAt: typeof data.releasedAt === "string" ? data.releasedAt : void 0,
@@ -1198,6 +1287,19 @@ async function finishJob(job, jobDirPath, outcome, config, deps, ending) {
1198
1287
  job.cleanupRan = true;
1199
1288
  writeJobFile(jobFilePath, job);
1200
1289
  }
1290
+ let verdictReason;
1291
+ if (outcome === "ok") {
1292
+ const decision = await settleVerdict({
1293
+ read: () => readItemEvaluation(config, job.item, deps.fetchImpl),
1294
+ now,
1295
+ sleep: deps.sleep ?? waitMs
1296
+ });
1297
+ if (decision.outcome === "incomplete") {
1298
+ outcome = "incomplete";
1299
+ verdictReason = scrubReason(decision.reason, config);
1300
+ log.error(`${tag} the command exited 0 but the item is not done: ${verdictReason}`);
1301
+ }
1302
+ }
1201
1303
  if (config.hooks.report) {
1202
1304
  setStage(job, jobDirPath, "report");
1203
1305
  log.line(`${tag} report started \xB7 phase end`);
@@ -1236,7 +1338,9 @@ async function finishJob(job, jobDirPath, outcome, config, deps, ending) {
1236
1338
  }
1237
1339
  if (outcome !== void 0) {
1238
1340
  const fromHook = readReasonLine(jobDirPath, config);
1239
- if (ending?.reason === void 0) {
1341
+ if (verdictReason !== void 0) {
1342
+ job.reason = verdictReason;
1343
+ } else if (ending?.reason === void 0) {
1240
1344
  job.reason = (outcome === "ok" ? void 0 : held?.reason) ?? (isolated ? fromHook ?? job.reason : fromHook);
1241
1345
  }
1242
1346
  const cliVersion = deps.cliVersion ?? resolveVersion();
@@ -7,7 +7,7 @@ import { createDockerHost, childEnvironment, spawnRun } from './chunk-774HEQL6.j
7
7
  import { RecipeError } from './chunk-QOZKPLVJ.js';
8
8
  import { execCapture } from './chunk-W4SQCOZU.js';
9
9
  import { GUEST_CID } from './chunk-B2G7JHHB.js';
10
- import { WorkCommandError, postJson } from './chunk-5DLBAXY5.js';
10
+ import { WorkCommandError, postJson } from './chunk-W5FVUZXV.js';
11
11
  import { parseDuKilobytes, hostAllowed } from './chunk-F6GFZXZ3.js';
12
12
  import { RELAY_PORT, CHECKOUT_DIR, JOB_MOUNT, claudeCredential, buildEnvironment, startBuildServices, AGENT_CREDENTIAL_MISSING, GATEWAY_PORT, GATEWAY_SOCKET, CLAUDE_PORT, CLAUDE_SOCKET, DESTINATION_BASE_PORT } from './chunk-AUFG23AA.js';
13
13
  import { defaultGitRunner, materializeContext } from './chunk-XDDW4FRS.js';
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { applyContextProvenance, installScrubContext, prepareSessionForUpload, wholeSessionCounts, sliceTurnIo } from './chunk-HE2D4EY5.js';
3
+ import { applyContextProvenance, installScrubContext, prepareSessionForUpload, wholeSessionCounts, sliceTurnIo } from './chunk-LYCDNMOH.js';
4
4
  import { LaunchFilter } from './chunk-BCJNHMZT.js';
5
5
  import { RepoFilter } from './chunk-TBT347UY.js';
6
6
  import { hookExecSpoolPath } from './chunk-F7CU5ABH.js';
7
7
  import { applyReportedCost } from './chunk-BKO6JEZI.js';
8
- import { migrateLegacyArtifactSidecars, planArtifactUpload, artifactsStatePath, sanitizeTerminal, artifactBlobsDir, resolveArtifactTurnIndex, isArtifactTombstoned, ARTIFACT_RETRY_MAX_AGE_MS, writeArtifactSpoolState, reclaimUnneededArtifactBlobs, neededArtifactShas } from './chunk-6Y63SXFO.js';
9
- import { tailTranscript, enrichSessionRepo, CAPTURE_TIERS, scanAll, setRepoRoot, resolveRepoIdentity, inferArtifactKind, bannedPathsForTier, sessionIdFromPath, SOURCE_ADAPTERS, EVENT_TYPES } from './chunk-G7FSV7JX.js';
8
+ import { migrateLegacyArtifactSidecars, planArtifactUpload, artifactsStatePath, sanitizeTerminal, artifactBlobsDir, resolveArtifactTurnIndex, isArtifactTombstoned, ARTIFACT_RETRY_MAX_AGE_MS, writeArtifactSpoolState, reclaimUnneededArtifactBlobs, neededArtifactShas } from './chunk-WFJ65NUD.js';
9
+ import { tailTranscript, enrichSessionRepo, CAPTURE_TIERS, scanAll, setRepoRoot, resolveRepoIdentity, inferArtifactKind, bannedPathsForTier, sessionIdFromPath, SOURCE_ADAPTERS, EVENT_TYPES } from './chunk-4C4THABW.js';
10
10
  import { C } from './chunk-YRYMNBGQ.js';
11
11
  import { readLaunchSpoolState, launchStatusIsDecisive, launchedItemsBySession, launchesPath } from './chunk-DVDEBNQJ.js';
12
12
  import { readLatestProvenanceForSession, readContextProvenance } from './chunk-ZJSNLVCE.js';
@@ -786,14 +786,16 @@ var KNOWN_PERMANENT_ARTIFACT_ERROR_CODES = /* @__PURE__ */ new Set([
786
786
  "unknown_replaces_target",
787
787
  "nothing_to_attach",
788
788
  "artifact_content_conflict",
789
- "payload_too_large"
789
+ "payload_too_large",
790
+ "unreadable_test_results"
790
791
  ]);
791
792
  var NEVER_REACHED_SERVER_ERROR_CODES = /* @__PURE__ */ new Set([
792
793
  "invalid_request_body",
793
794
  "invalid_field_value",
794
795
  "session_not_found",
795
796
  "nothing_to_attach",
796
- "payload_too_large"
797
+ "payload_too_large",
798
+ "unreadable_test_results"
797
799
  ]);
798
800
  function splitPayload(payload) {
799
801
  const mid = Math.ceil(payload.sessions.length / 2);
@@ -1493,6 +1495,7 @@ ${C.yellow}!${C.reset} batch ${shippedBatches + 1}/${batches.length} accounting
1493
1495
  ...record.commitSha !== void 0 ? { commitSha: record.commitSha } : {},
1494
1496
  ...replaces !== void 0 ? { replaces } : {},
1495
1497
  ...record.replacesTargets !== void 0 ? { replacesTargets: record.replacesTargets } : {},
1498
+ ...record.tests !== void 0 ? { tests: record.tests } : {},
1496
1499
  session: { sessionId: record.sessionId, ...turnIndex !== void 0 ? { turnIndex } : {} }
1497
1500
  },
1498
1501
  blob: { data: blobData.toString("base64") }
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { setCustomScrubbers, setLocalIdentity, setRepoRoot, resolveRepoIdentity, scrubDeep, downconvertSession, isHumanUserTurn, turnCountBound } from './chunk-G7FSV7JX.js';
3
+ import { setCustomScrubbers, setLocalIdentity, setRepoRoot, resolveRepoIdentity, scrubDeep, downconvertSession, isHumanUserTurn, turnCountBound } from './chunk-4C4THABW.js';
4
4
  import { execFileSync } from 'child_process';
5
5
  import { hostname, userInfo } from 'os';
6
6
 
@@ -4,6 +4,6 @@ import { createRequire } from 'node:module';
4
4
  createRequire(import.meta.url);
5
5
 
6
6
  // src/runner/protocol.ts
7
- var RUNNER_PROTOCOL = 11;
7
+ var RUNNER_PROTOCOL = 12;
8
8
 
9
9
  export { RUNNER_PROTOCOL };
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { LEASE_SECONDS, releaseLease, isUnfinished, writeJobFile, setStage, jobEnv, runHook, describeHookEnd, provisionMicroVm, deliverCommitHooks, provisionProcess, provisionEnvironment, readProvisionOut, resolveHostBuild, workdirProblem, listenOnBroker, hostEnvironment, hostCommandEnvironment, execArgv, microVmCommandLine, runCommand, execCommandLine, startHostServices, finishJob, isGroupAlive, outcomeFromExitCode, needsRenew, renewLease, RENEW_INTERVAL_SECONDS, isTimedOut, readCpuUsec, isIdle, stopOrphanedMicroVms, unfinishedJobs, listAdoptableJobs, retryFailedReleases, recoverLostJobs, readJobFile, hookLimitsFor } from './chunk-FAJSS2WN.js';
4
- import { RUNNER_PROTOCOL } from './chunk-FV2CCGXK.js';
3
+ import { LEASE_SECONDS, releaseLease, isUnfinished, writeJobFile, setStage, jobEnv, runHook, describeHookEnd, provisionMicroVm, deliverCommitHooks, provisionProcess, provisionEnvironment, readProvisionOut, resolveHostBuild, workdirProblem, listenOnBroker, hostEnvironment, hostCommandEnvironment, execArgv, microVmCommandLine, runCommand, execCommandLine, startHostServices, finishJob, isGroupAlive, outcomeFromExitCode, needsRenew, renewLease, RENEW_INTERVAL_SECONDS, isTimedOut, readCpuUsec, isIdle, stopOrphanedMicroVms, unfinishedJobs, listAdoptableJobs, retryFailedReleases, recoverLostJobs, readJobFile, hookLimitsFor } from './chunk-DM3VFDS3.js';
4
+ import { RUNNER_PROTOCOL } from './chunk-QDQEUVUF.js';
5
5
  import { fetchVersionMeta, npmVersion, npmSupportsProvenance, fetchTarballDigest, fetchProvenance, installVersion, auditSignatures } from './chunk-ABIWDUMS.js';
6
6
  import { readMarker, currentVersion, removeMarker, writeMarker, entryIn, versionDir, switchCurrent, cleanVersions, isInLayout, startedThroughCurrent, stagingDir } from './chunk-YYYXRJUW.js';
7
7
  import { RepoFilter } from './chunk-TBT347UY.js';
8
- import { describeCallFailure, retrySend, shortClaim, relativeToRunner, formatDuration, provisionContainer, lifecycleSteps, lifecycleFailureReason, prepareBranch, containerCommandLine, BuildTokens, classifyRefusal, refusalCode, formatClock, measureDisk, createRunnerLog, ensureTunnel, keepGhConfigCurrent, createContainerRuntime } from './chunk-7A6RVXPZ.js';
8
+ import { describeCallFailure, retrySend, shortClaim, relativeToRunner, formatDuration, provisionContainer, lifecycleSteps, lifecycleFailureReason, prepareBranch, containerCommandLine, BuildTokens, classifyRefusal, refusalCode, formatClock, measureDisk, createRunnerLog, ensureTunnel, keepGhConfigCurrent, createContainerRuntime } from './chunk-HZRNMGLF.js';
9
9
  import { startTimeOf, claimPidFile, readPidFile, isSameProcess, releasePidFile } from './chunk-N5FOE5PS.js';
10
- import { isSignatureRefusal, WorkCommandError, getJson, postJson } from './chunk-5DLBAXY5.js';
10
+ import { isSignatureRefusal, WorkCommandError, getJson, postJson } from './chunk-W5FVUZXV.js';
11
11
  import { isBuiltinContainer, isBuiltinVm, isBuiltinProcess, loadRunnerConfig, checkHooks } from './chunk-5Y3QQRUH.js';
12
12
  import { exceedsDisk } from './chunk-F6GFZXZ3.js';
13
13
  import { parseClaimIdentity, sharedUserEnvironment, JOB_MOUNT } from './chunk-AUFG23AA.js';
@@ -825,7 +825,7 @@ var CLAIM_REFUSAL_CODES = new Set(
825
825
  "pull_request_from_fork pull_request_on_default_branch pull_request_ambiguous branch_claimed_elsewhere".split(" ")
826
826
  );
827
827
  async function tryClaimAndStart(state, item, queue) {
828
- const { postJson: postJson2 } = await import('./work-cmd-UOQO2AD4.js');
828
+ const { postJson: postJson2 } = await import('./work-cmd-QAUZ7MTD.js');
829
829
  const log = logOf(state);
830
830
  const hostKey = await loadHostKey(state.config.configPath);
831
831
  const claim = await retrySend(
@@ -1525,7 +1525,7 @@ async function start(configPath, deps = { fetchImpl: fetch }) {
1525
1525
  const outcome = await onStartUnderMarker({
1526
1526
  configPath,
1527
1527
  own: ownVersionOf(deps),
1528
- check: update.check ? () => update.check(configPath) : async () => (await import('./check-WQP2CZDW.js')).runRunnerCheck(configPath, { fetchImpl: deps.fetchImpl }),
1528
+ check: update.check ? () => update.check(configPath) : async () => (await import('./check-7MFH6HNC.js')).runRunnerCheck(configPath, { fetchImpl: deps.fetchImpl }),
1529
1529
  now: () => (deps.now ?? (() => /* @__PURE__ */ new Date()))().getTime(),
1530
1530
  log
1531
1531
  });
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { isPlaceholderCommand } from './chunk-CBZB6XY6.js';
4
- import { describeCallFailure } from './chunk-7A6RVXPZ.js';
5
- import { WorkCommandError, getJson } from './chunk-5DLBAXY5.js';
6
- import { sanitizeTerminal } from './chunk-6Y63SXFO.js';
3
+ import { isPlaceholderCommand } from './chunk-YFHIIH4B.js';
4
+ import { describeCallFailure } from './chunk-HZRNMGLF.js';
5
+ import { WorkCommandError, getJson } from './chunk-W5FVUZXV.js';
6
+ import { sanitizeTerminal } from './chunk-WFJ65NUD.js';
7
7
  import { builtinKind } from './chunk-5Y3QQRUH.js';
8
8
  import { claudeCredential, CLAUDE_CREDENTIAL_VARIABLES } from './chunk-AUFG23AA.js';
9
9
  import { signerFor } from './chunk-M5POMKKW.js';
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { sanitizeTerminal } from './chunk-6Y63SXFO.js';
3
+ import { sanitizeTerminal } from './chunk-WFJ65NUD.js';
4
4
  import { DEFAULT_DASHBOARD } from './chunk-USO2DKBD.js';
5
5
  import { readCloudConfig } from './chunk-EABW6AJQ.js';
6
6
 
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { isLinkedRepository } from './chunk-3TT7RQYB.js';
3
+ import { isLinkedRepository } from './chunk-SY4GK4SP.js';
4
4
  import { readStatuslineState, STATE_FRESH_MS } from './chunk-F47JBIAW.js';
5
- import { resolveCredentials, getJson, WorkCommandError } from './chunk-5DLBAXY5.js';
6
- import { sanitizeTerminal } from './chunk-6Y63SXFO.js';
7
- import { resolveRepoIdentity, compareVersions, SUPPORTED_VERSIONS } from './chunk-G7FSV7JX.js';
5
+ import { resolveCredentials, getJson, WorkCommandError } from './chunk-W5FVUZXV.js';
6
+ import { sanitizeTerminal } from './chunk-WFJ65NUD.js';
7
+ import { resolveRepoIdentity, compareVersions, SUPPORTED_VERSIONS } from './chunk-4C4THABW.js';
8
8
  import { C } from './chunk-YRYMNBGQ.js';
9
9
  import { readSettings, settingsPath, isOurStatuslineSlot, statuslineWrappedOriginal, REGISTERED_EVENTS, isOurHookCommand, ourCommandBins, cliBinResolvable, ourDirectScriptBins, wrappedOriginalCommand } from './chunk-5QRP3MVS.js';
10
10
  import { readPin, readContextManifest, readDegraded, readSourceCache } from './chunk-WIOZAJ2W.js';
@@ -1016,7 +1016,7 @@ async function gatherDoctorChecks() {
1016
1016
  const { runnerVmCheck } = await import('./doctor-53F2PYY7.js');
1017
1017
  checks.push(runnerVmCheck(configPath, { lima: realLima(), home: homeFromEnv(), instance: runnerVm.instance }));
1018
1018
  } else if (hasRunnerBlock(configPath)) {
1019
- const { runnerHostChecks } = await import('./doctor-UFVL4PZY.js');
1019
+ const { runnerHostChecks } = await import('./doctor-ZLGZYMDK.js');
1020
1020
  const hooks = (() => {
1021
1021
  try {
1022
1022
  return loadRunnerConfig(configPath).hooks;
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
3
  import { detectActiveSession } from './chunk-BFESLKPP.js';
4
- import { sanitizeTerminal } from './chunk-6Y63SXFO.js';
5
- import { resolveRepoIdentity } from './chunk-G7FSV7JX.js';
4
+ import { sanitizeTerminal } from './chunk-WFJ65NUD.js';
5
+ import { resolveRepoIdentity } from './chunk-4C4THABW.js';
6
6
  import { parseTrackerNumber, trackerNumberError } from './chunk-WZBHBH3J.js';
7
7
  import { defaultFetch } from './chunk-BCLJSQCV.js';
8
8
  import { resolveGatewayCredentials, unauthorizedMessage } from './chunk-BOLTI6LR.js';
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { ArtifactTombstoneRecordSchema, ArtifactSpoolRecordSchema } from './chunk-G7FSV7JX.js';
3
+ import { ArtifactTombstoneRecordSchema, ArtifactSpoolRecordSchema } from './chunk-4C4THABW.js';
4
4
  import { homeFromEnv } from './chunk-VNVZDWO3.js';
5
5
  import { mkdirSync, appendFileSync, writeFileSync, renameSync, existsSync, unlinkSync, readdirSync, readFileSync } from 'fs';
6
6
  import { join, dirname } from 'path';
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { dashboardBase, isRepositoryLinked, workPageUrl, notLinkedText } from './chunk-3TT7RQYB.js';
4
- import { sanitizeTerminal } from './chunk-6Y63SXFO.js';
5
- import { remoteLookupFailed } from './chunk-G7FSV7JX.js';
3
+ import { dashboardBase, isRepositoryLinked, workPageUrl, notLinkedText } from './chunk-SY4GK4SP.js';
4
+ import { sanitizeTerminal } from './chunk-WFJ65NUD.js';
5
+ import { remoteLookupFailed } from './chunk-4C4THABW.js';
6
6
  import { resolveGatewayCredentials } from './chunk-BOLTI6LR.js';
7
7
  import { findGitDirs, readRepoConnection, writeRepoConnection } from './chunk-BJ3KTMDH.js';
8
8
  import { createInterface } from 'readline/promises';
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { detectMachine, supportsContainerBuilds, reachDockerStep, describeMachineDocker, supportsMicroVmBuilds } from './chunk-L2DBRKRA.js';
4
- import { MIN_ENGINE_MAJOR } from './chunk-7A6RVXPZ.js';
3
+ import { detectMachine, supportsContainerBuilds, reachDockerStep, describeMachineDocker, supportsMicroVmBuilds } from './chunk-3TFPDVTI.js';
4
+ import { MIN_ENGINE_MAJOR } from './chunk-HZRNMGLF.js';
5
5
  import { RUNNER_DIR_MODE, runnerDir, RUNNER_FILE_MODE } from './chunk-ZM2IMMYN.js';
6
6
  import { existsSync, readFileSync, mkdirSync, writeFileSync } from 'fs';
7
7
  import { dirname } from 'path';