@outerlayer/cli 0.27.1 → 0.28.2

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 (129) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/README.md +6 -0
  3. package/dist/{agent-setup-UW36TAQM.js → agent-setup-YVR5RO56.js} +17 -14
  4. package/dist/{bridge-B5VJVECY.js → bridge-WW2V7DTB.js} +3 -2
  5. package/dist/build-5FRC3RKM.js +13 -0
  6. package/dist/build-info.json +1 -1
  7. package/dist/{builder-6Y6ZWGNH.js → builder-4F2XNSFC.js} +7 -6
  8. package/dist/{check-YTXFVWK7.js → check-YEI6TCUH.js} +70 -61
  9. package/dist/{chunk-LPFOWUHG.js → chunk-25X2PJDI.js} +20 -13
  10. package/dist/{chunk-BPKO76QR.js → chunk-4XN5FRRJ.js} +4 -4
  11. package/dist/{chunk-EPPIISRD.js → chunk-55XLX5PA.js} +1 -1
  12. package/dist/{chunk-LOKSLO25.js → chunk-5B7BEQPR.js} +1 -1
  13. package/dist/chunk-5BHIBJDA.js +93 -0
  14. package/dist/{chunk-RHAGBUL5.js → chunk-5K3KB4YR.js} +1 -1
  15. package/dist/{chunk-ABXQBEYK.js → chunk-66T6XJAB.js} +1 -1
  16. package/dist/{chunk-ZFBJUOYT.js → chunk-6S4V4UIC.js} +10 -10
  17. package/dist/{chunk-BWH36FOC.js → chunk-7CK2TJFB.js} +20 -4
  18. package/dist/{chunk-QKIQ2R7F.js → chunk-ATJOFXTE.js} +3 -3
  19. package/dist/chunk-CDDED64E.js +13 -0
  20. package/dist/{chunk-QHH4OSD4.js → chunk-CTYSTE5C.js} +1 -1
  21. package/dist/{chunk-DJHNEGNM.js → chunk-DKWQMPSL.js} +18 -2
  22. package/dist/{chunk-IMOB4IOI.js → chunk-DQYMQ47E.js} +3 -2
  23. package/dist/{chunk-YETTWTAY.js → chunk-E7R2GIAW.js} +4 -4
  24. package/dist/{chunk-GFUE5TKO.js → chunk-F4FA3ZUT.js} +24 -14
  25. package/dist/{chunk-6TRNCUM4.js → chunk-FGF52V4V.js} +1 -1
  26. package/dist/{chunk-R7SGBXUD.js → chunk-GLL4TN2M.js} +226 -72
  27. package/dist/{chunk-MATUHHN4.js → chunk-GUXWQIEY.js} +1 -1
  28. package/dist/{chunk-B7DJVG25.js → chunk-HOB7Z4JQ.js} +3 -3
  29. package/dist/{chunk-2I3LIRZP.js → chunk-HXAEQPZR.js} +101 -10
  30. package/dist/{chunk-P33PZIWS.js → chunk-ITAIEJ2T.js} +7 -142
  31. package/dist/{chunk-RHGF73IU.js → chunk-IVX3U7KV.js} +1 -1
  32. package/dist/{chunk-7OUOLGUV.js → chunk-JGML2VUN.js} +3 -7
  33. package/dist/{chunk-6VFH52MP.js → chunk-KU7QL4XW.js} +24 -22
  34. package/dist/{chunk-2F762IXY.js → chunk-LNIFYSNK.js} +3 -3
  35. package/dist/{chunk-XBPUTQ7E.js → chunk-MHAR6S7B.js} +1 -1
  36. package/dist/{chunk-VS27BP3E.js → chunk-MKIC65SD.js} +52 -9
  37. package/dist/{chunk-64GMBWAK.js → chunk-MNHMUZGC.js} +6 -6
  38. package/dist/{chunk-7AQ5AM7U.js → chunk-MQHTM4YJ.js} +177 -21
  39. package/dist/{chunk-6KKM7VGZ.js → chunk-N7WAEEIU.js} +3 -3
  40. package/dist/{chunk-D7ECMB7B.js → chunk-NUHZV3A4.js} +1 -1
  41. package/dist/{chunk-5VMDGJGH.js → chunk-O65LES4V.js} +39 -25
  42. package/dist/{chunk-MHX7YX7Y.js → chunk-P2RWZCV7.js} +1 -1
  43. package/dist/chunk-QBQHQEUG.js +300 -0
  44. package/dist/{chunk-FP23SVDD.js → chunk-QJFDAKRF.js} +5 -5
  45. package/dist/{chunk-WUL2OP5A.js → chunk-QKXF7CLR.js} +3 -3
  46. package/dist/{chunk-XZ6Q6ZNR.js → chunk-SATUCMAJ.js} +3 -2
  47. package/dist/{chunk-Y7ZCHBYB.js → chunk-SFJXGISY.js} +3 -3
  48. package/dist/{chunk-2BTFKNTR.js → chunk-SJZL5F3F.js} +2 -2
  49. package/dist/{chunk-HWDYLXHH.js → chunk-T2QSWFSU.js} +4 -4
  50. package/dist/{chunk-E5IJ5533.js → chunk-TF7G2PR6.js} +3 -3
  51. package/dist/{chunk-O2IJTY7L.js → chunk-TVZAC2NP.js} +3 -3
  52. package/dist/{chunk-QE3UQAHK.js → chunk-UHU7H57K.js} +26 -7
  53. package/dist/{chunk-WSYXLLA5.js → chunk-USJZ2LDK.js} +6 -6
  54. package/dist/{chunk-EX5MQYEF.js → chunk-VC5J7QPV.js} +5 -5
  55. package/dist/{chunk-N4D5TMVU.js → chunk-VU7ZJPIR.js} +5 -5
  56. package/dist/{chunk-GLUKDQS4.js → chunk-WWQVKFN6.js} +1 -1
  57. package/dist/{chunk-55GNQPO6.js → chunk-X52PMPOM.js} +7 -7
  58. package/dist/{chunk-YB3CSYXX.js → chunk-XD4ZCMA4.js} +81 -2
  59. package/dist/{chunk-Y4OKEFAX.js → chunk-YL2VDSNF.js} +1 -1
  60. package/dist/{chunk-M3MHHIUW.js → chunk-Z3ASAXVU.js} +1 -1
  61. package/dist/{chunk-XS3FDWSZ.js → chunk-ZTY7HHYB.js} +1 -1
  62. package/dist/{claude-launcher-NQSZBTQ5.js → claude-launcher-7RGVOYCD.js} +6 -5
  63. package/dist/{cli-GHEOBXC7.js → cli-SCTKM2Y5.js} +151 -130
  64. package/dist/cli-update-notice-4DLZ3655.js +9 -0
  65. package/dist/{command-V7B7GTPZ.js → command-PY3C2E4B.js} +53 -37
  66. package/dist/{config-TWS5VZEN.js → config-5QYIKYUP.js} +3 -2
  67. package/dist/{connect-cmd-HGS7YPA2.js → connect-cmd-5TYAOK5M.js} +14 -11
  68. package/dist/{container-start-FHB2VDC4.js → container-start-7WLZMPEI.js} +37 -36
  69. package/dist/{control-plane-launch-DBQA3KLJ.js → control-plane-launch-FZMD4MXX.js} +13 -10
  70. package/dist/{dist-QPHZE47F.js → dist-JFVKLUHL.js} +1 -1
  71. package/dist/{docker-YT6Z3LXI.js → docker-ZTC4EIU4.js} +7 -6
  72. package/dist/{doctor-Y4NCNSJM.js → doctor-DQWRUAEB.js} +159 -41
  73. package/dist/{emit-artifact-cmd-ALDK55Y2.js → emit-artifact-cmd-SOXLBPQB.js} +19 -16
  74. package/dist/{emit-cmd-VAQHRWJR.js → emit-cmd-QUABLVO6.js} +6 -5
  75. package/dist/{emit-criteria-cmd-Q7SM6VP2.js → emit-criteria-cmd-JDO2VUG5.js} +15 -12
  76. package/dist/{emit-finding-cmd-2NBAPDSV.js → emit-finding-cmd-VCQPCLI2.js} +16 -13
  77. package/dist/{emit-result-cmd-KUSL56RI.js → emit-result-cmd-TKA3GAN7.js} +19 -16
  78. package/dist/{emit-step-cmd-KD4AKEAT.js → emit-step-cmd-XN44BXYU.js} +16 -13
  79. package/dist/{exec-client-6WVS7DRZ.js → exec-client-VKT2XNB3.js} +4 -3
  80. package/dist/fleet-readiness-G5X3MKP2.js +29 -0
  81. package/dist/{governing-source-VVUA5TKB.js → governing-source-B3M2U4BC.js} +21 -18
  82. package/dist/{guest-init-H5K2RW3P.js → guest-init-QW2DPX7H.js} +5 -4
  83. package/dist/{hook-fast-3SUJM765.js → hook-fast-EFC44SXV.js} +4 -1
  84. package/dist/{host-key-XNKZCWTS.js → host-key-AC6LTZDS.js} +4 -3
  85. package/dist/{image-tag-R34J4O3F.js → image-tag-SS7YKJHN.js} +4 -3
  86. package/dist/index.js +4 -4
  87. package/dist/init-5LHTF72R.js +56 -0
  88. package/dist/{init-3DAGX7UY.js → init-BTH5YPBC.js} +38 -37
  89. package/dist/{init-cmd-RIDBVSE4.js → init-cmd-L4VW3ZCT.js} +25 -21
  90. package/dist/{init-update-ECWNG47R.js → init-update-RWTQSTPE.js} +51 -35
  91. package/dist/{inspect-IPFA7AAT.js → inspect-L7JIBK3Y.js} +1 -1
  92. package/dist/{install-6OIY3KHZ.js → install-35SAMY75.js} +5 -5
  93. package/dist/{install-cmd-JMT67P35.js → install-cmd-GFY4QF72.js} +6 -5
  94. package/dist/{layout-XNFDTOET.js → layout-BBTQPS6V.js} +4 -3
  95. package/dist/{login-browser-EWXSGHM7.js → login-browser-WSOSQH2T.js} +2 -2
  96. package/dist/{logs-XHAS6LMZ.js → logs-X2IRDP5T.js} +3 -2
  97. package/dist/loop-QDV7T65M.js +80 -0
  98. package/dist/{machine-OOQ2NXC3.js → machine-PLNSGKNF.js} +32 -30
  99. package/dist/{machine-skills-FLIRJYP7.js → machine-skills-O7W6NMWB.js} +4 -3
  100. package/dist/{mcp-serve-cmd-LY5A3CE7.js → mcp-serve-cmd-IITCPAAR.js} +9 -6
  101. package/dist/{paths-LHSPNORF.js → paths-32DWGK35.js} +3 -2
  102. package/dist/pending-CSIY4Y2I.js +10 -0
  103. package/dist/{pidfile-DKMYYXLH.js → pidfile-CYCTH6NQ.js} +4 -3
  104. package/dist/{real-deps-KNNBQC75.js → real-deps-QX5YH7FG.js} +1 -1
  105. package/dist/{record-3LPTY3G5.js → record-N4WPZCGK.js} +4 -3
  106. package/dist/{relay-GFPPD6GF.js → relay-FJ5K37Z5.js} +8 -4
  107. package/dist/{runner-env-YRRNRKF4.js → runner-env-EIB6WFPG.js} +6 -7
  108. package/dist/{runner-identity-YS2BZXZV.js → runner-identity-S3V6I4I3.js} +7 -6
  109. package/dist/{runner-key-EFNTZWNX.js → runner-key-M4N2BY5A.js} +36 -35
  110. package/dist/{session-sender-SC5PSU2G.js → session-sender-UQ3VF732.js} +20 -17
  111. package/dist/{spec-cmd-JGYHHJ4P.js → spec-cmd-Z6MGATWC.js} +16 -13
  112. package/dist/{starter-pack-GPU4X6B7.js → starter-pack-5SOT5V4I.js} +4 -3
  113. package/dist/{status-7WM7S7JX.js → status-PWMPP4ES.js} +39 -37
  114. package/dist/{sync-cmd-ATXJVS7S.js → sync-cmd-N4R7ST6X.js} +19 -16
  115. package/dist/{watch-M7NR3DOW.js → watch-L5MSAWEO.js} +19 -16
  116. package/dist/{work-claim-cmd-DNUDZKJA.js → work-claim-cmd-CXALMILD.js} +21 -18
  117. package/dist/{work-cmd-VECTYST6.js → work-cmd-COESFSHE.js} +16 -13
  118. package/dist/{work-comment-cmd-F3NRWKPZ.js → work-comment-cmd-A4ZUVCSA.js} +16 -13
  119. package/dist/{work-logs-cmd-QF6P32FE.js → work-logs-cmd-CTF43MBE.js} +16 -13
  120. package/dist/{work-open-pr-cmd-XE23JA3R.js → work-open-pr-cmd-EMGYJXVD.js} +17 -14
  121. package/dist/{work-pr-cmd-BH56GUKN.js → work-pr-cmd-FEXMS6RH.js} +16 -13
  122. package/dist/{work-stop-cmd-C3F5HNUO.js → work-stop-cmd-NIHAN45R.js} +16 -13
  123. package/package.json +1 -1
  124. package/dist/build-HRLACBOZ.js +0 -12
  125. package/dist/chunk-STSLH5EJ.js +0 -71
  126. package/dist/init-SWKYV6CL.js +0 -55
  127. package/dist/loop-AIJZVUNA.js +0 -79
  128. package/dist/pending-3YZCSKON.js +0 -9
  129. package/dist/{chunk-6BLXUD56.js → chunk-HOU33DW5.js} +1 -1
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { MIN_ENGINE_MAJOR } from './chunk-R7SGBXUD.js';
4
- import { runnerImageVersion } from './chunk-M3MHHIUW.js';
5
- import { firecrackerArch, MICROVM_ARCHES, guestAssetsPinned } from './chunk-2BTFKNTR.js';
3
+ import { MIN_ENGINE_MAJOR } from './chunk-GLL4TN2M.js';
4
+ import { runnerImageVersion } from './chunk-Z3ASAXVU.js';
5
+ import { firecrackerArch, MICROVM_ARCHES, guestAssetsPinned } from './chunk-SJZL5F3F.js';
6
6
  import { spawnSync } from 'child_process';
7
7
  import { existsSync, accessSync, constants, statSync, readFileSync } from 'fs';
8
8
 
@@ -1,13 +1,93 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
+ import { parseRunnerEnv } from './chunk-XD4ZCMA4.js';
3
4
  import { TARGET_TUNNEL, TARGET_LEASE, destinationTarget } from './chunk-JGD5TWQ2.js';
4
- import { existsSync, unlinkSync, chmodSync } from 'fs';
5
+ import { readFileSync, existsSync, unlinkSync, chmodSync } from 'fs';
6
+ import { join, dirname } from 'path';
5
7
  import { request as request$1, createServer } from 'http';
6
8
  import { request } from 'https';
7
9
  import { createServer as createServer$1 } from 'net';
8
- import { join } from 'path';
9
10
 
10
11
  createRequire(import.meta.url);
12
+ var CLAUDE_CREDENTIAL_ID = "claude";
13
+ var CLAUDE_ENV_FILE = "claude.env";
14
+ function claudeEnvPath(configPath) {
15
+ return join(dirname(configPath), CLAUDE_ENV_FILE);
16
+ }
17
+ var CLAUDE_CREDENTIAL_VARIABLES = ["CLAUDE_CODE_OAUTH_TOKEN", "ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN"];
18
+ var FORWARDED = ["CLAUDE_CODE_OAUTH_TOKEN", "ANTHROPIC_API_KEY"];
19
+ function firstOf(values, source) {
20
+ for (const variable of FORWARDED) {
21
+ const value = values[variable];
22
+ if (value !== void 0 && value !== "") return { variable, value, source };
23
+ }
24
+ return void 0;
25
+ }
26
+ function readClaudeCredential(env) {
27
+ const fromEnvironment = firstOf(env, "environment");
28
+ if (fromEnvironment !== void 0) return fromEnvironment;
29
+ const directory = env.CREDENTIALS_DIRECTORY;
30
+ if (directory === void 0 || directory === "") return void 0;
31
+ const path = join(directory, CLAUDE_CREDENTIAL_ID);
32
+ try {
33
+ const text = readFileSync(path, "utf8");
34
+ const found = firstOf(parseRunnerEnv(text), "credentials-directory");
35
+ if (found === void 0 && text.trim() !== "") complain(path, "it sets neither CLAUDE_CODE_OAUTH_TOKEN nor ANTHROPIC_API_KEY, each as NAME=value");
36
+ return found;
37
+ } catch (err) {
38
+ if (err.code !== "ENOENT") complain(path, `it could not be read (${err instanceof Error ? err.message : String(err)})`);
39
+ return void 0;
40
+ }
41
+ }
42
+ var complained = /* @__PURE__ */ new Set();
43
+ function complain(path, reason) {
44
+ if (complained.has(path)) return;
45
+ complained.add(path);
46
+ process.stderr.write(`the Claude credential file ${path} holds no usable credential: ${reason}
47
+ `);
48
+ }
49
+ var held;
50
+ var removedValues = /* @__PURE__ */ new Set();
51
+ function holdClaudeCredential(env = process.env) {
52
+ held ??= readClaudeCredential(env);
53
+ for (const name of CLAUDE_CREDENTIAL_VARIABLES) {
54
+ const value = env[name];
55
+ if (value !== void 0 && value !== "") removedValues.add(value);
56
+ delete env[name];
57
+ }
58
+ return held;
59
+ }
60
+ function takeClaudeCredential(env, hooks) {
61
+ return /^builtin:(container|process|vm)$/.test(hooks.provision) ? holdClaudeCredential(env) : void 0;
62
+ }
63
+ function removedClaudeCredentialValues() {
64
+ return [...removedValues];
65
+ }
66
+ function heldClaudeCredential() {
67
+ return held;
68
+ }
69
+ function currentClaudeCredential(env) {
70
+ return held ?? readClaudeCredential(env);
71
+ }
72
+ var SETS = /^\s*(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)=/;
73
+ function credentialLineIn(text) {
74
+ const set = parseRunnerEnv(text);
75
+ const lines = text.split("\n");
76
+ for (const variable of FORWARDED) {
77
+ if ((set[variable] ?? "") === "") continue;
78
+ const line = lines.find((candidate) => (parseRunnerEnv(candidate)[variable] ?? "") !== "");
79
+ return line.replace(/^\s*(?:export\s+)?/, "").trimEnd();
80
+ }
81
+ return void 0;
82
+ }
83
+ function withoutCredentialLines(text) {
84
+ const lines = text.split("\n");
85
+ const kept = lines.filter((line) => !CLAUDE_CREDENTIAL_VARIABLES.includes(SETS.exec(line)?.[1] ?? ""));
86
+ if (kept.length === lines.length) return void 0;
87
+ while (kept[kept.length - 1] === "") kept.pop();
88
+ return kept.length === 0 ? "" : `${kept.join("\n")}
89
+ `;
90
+ }
11
91
 
12
92
  // src/runner/builtin-destinations.ts
13
93
  var GATEWAY_DESTINATION = "gateway";
@@ -23,16 +103,27 @@ var OAUTH_PLACEHOLDER = "sk-ant-oat01-placeholder-not-a-real-token";
23
103
  var API_KEY_PLACEHOLDER = "sk-ant-api03-placeholder-not-a-real-key";
24
104
  var ITEM_KEY_PLACEHOLDER = "olitem_placeholder-not-a-real-key";
25
105
  var ITEM_KEY_VARIABLE = "OUTERLAYER_ITEM_KEY";
26
- var CLAUDE_CREDENTIAL_VARIABLES = ["CLAUDE_CODE_OAUTH_TOKEN", "ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN"];
27
- function claudeCredential(hostEnv) {
28
- const held = (name) => hostEnv[name] !== void 0 && hostEnv[name] !== "";
29
- if (held("CLAUDE_CODE_OAUTH_TOKEN")) return { variable: "CLAUDE_CODE_OAUTH_TOKEN", placeholder: OAUTH_PLACEHOLDER };
30
- if (held("ANTHROPIC_API_KEY")) return { variable: "ANTHROPIC_API_KEY", placeholder: API_KEY_PLACEHOLDER };
31
- return void 0;
106
+ function claudeCredential(hostEnv, options = {}) {
107
+ const credential = options.ignoreHeld === true ? readClaudeCredential(hostEnv) : currentClaudeCredential(hostEnv);
108
+ if (credential === void 0) return void 0;
109
+ return { variable: credential.variable, placeholder: credential.variable === "CLAUDE_CODE_OAUTH_TOKEN" ? OAUTH_PLACEHOLDER : API_KEY_PLACEHOLDER };
32
110
  }
33
111
  function gatewayUpstream(gatewayUrl) {
34
112
  return `${new URL(gatewayUrl).origin}/`;
35
113
  }
114
+ function forwardedEnvironment(hostEnv) {
115
+ const env = {};
116
+ for (const name of ["CLAUDE_CODE_OAUTH_TOKEN", "ANTHROPIC_API_KEY"]) {
117
+ Object.defineProperty(env, name, {
118
+ enumerable: true,
119
+ get: () => {
120
+ const current = currentClaudeCredential(hostEnv);
121
+ return current !== void 0 && current.variable === name ? current.value : hostEnv[name];
122
+ }
123
+ });
124
+ }
125
+ return env;
126
+ }
36
127
  function builtInDestinations(input) {
37
128
  const credential = claudeCredential(input.hostEnv);
38
129
  const apiKeyMode = credential?.variable === "ANTHROPIC_API_KEY";
@@ -55,7 +146,7 @@ function builtInDestinations(input) {
55
146
  header: apiKeyMode ? { name: "x-api-key", value: "${ANTHROPIC_API_KEY}", variables: ["ANTHROPIC_API_KEY"] } : { name: "Authorization", value: "Bearer ${CLAUDE_CODE_OAUTH_TOKEN}", variables: ["CLAUDE_CODE_OAUTH_TOKEN"] },
56
147
  env: {}
57
148
  },
58
- hostEnv: input.hostEnv,
149
+ hostEnv: forwardedEnvironment(input.hostEnv),
59
150
  // A build's own key in either header would sit beside the runner's, and the upstream takes one of them.
60
151
  drop: ["x-api-key", "authorization"],
61
152
  socket: CLAUDE_SOCKET
@@ -661,4 +752,4 @@ function withTunnelRecord(environment, record, onlyWhenUsed = false) {
661
752
  };
662
753
  }
663
754
 
664
- export { AGENT_CREDENTIAL_MISSING, BUILD_HOME, BUILT_IN_NAMES, CHECKOUT_DIR, CLAUDE_CREDENTIAL_VARIABLES, CLAUDE_PORT, CLAUDE_SOCKET, DESTINATION_BASE_PORT, EVAL_INPUT_DIR, GATEWAY_PORT, GATEWAY_SOCKET, JOB_MOUNT, PROXY_WARNING_FLAG, RELAY_PORT, authorEnvironment, buildEnvironment, builtInEnvironment, checkEnvironment, checkoutPath, claudeCredential, commitIdentityRecord, containerLocalAddress, destinationEnvironment, headerVariables, isRefusedInConfig, isReservedVariable, lifecycleWorkdir, parseClaimIdentity, parseClaimedRepositories, parseIsolation, parseUnreachable, primaryOf, proxyEnvironment, repositoriesOf, repositoryPath, resolveDestinations, sharedUserEnvironment, startBuildServices, tokenHeader, withGitConfig, withHooksPath, withProxyWarningHidden, withTokenHeader, withTunnelRecord };
755
+ export { AGENT_CREDENTIAL_MISSING, BUILD_HOME, BUILT_IN_NAMES, CHECKOUT_DIR, CLAUDE_CREDENTIAL_ID, CLAUDE_CREDENTIAL_VARIABLES, CLAUDE_ENV_FILE, CLAUDE_PORT, CLAUDE_SOCKET, DESTINATION_BASE_PORT, EVAL_INPUT_DIR, GATEWAY_PORT, GATEWAY_SOCKET, JOB_MOUNT, PROXY_WARNING_FLAG, RELAY_PORT, authorEnvironment, buildEnvironment, builtInEnvironment, checkEnvironment, checkoutPath, claudeCredential, claudeEnvPath, commitIdentityRecord, containerLocalAddress, credentialLineIn, currentClaudeCredential, destinationEnvironment, headerVariables, heldClaudeCredential, isRefusedInConfig, isReservedVariable, lifecycleWorkdir, parseClaimIdentity, parseClaimedRepositories, parseIsolation, parseUnreachable, primaryOf, proxyEnvironment, readClaudeCredential, removedClaudeCredentialValues, repositoriesOf, repositoryPath, resolveDestinations, sharedUserEnvironment, startBuildServices, takeClaudeCredential, tokenHeader, withGitConfig, withHooksPath, withProxyWarningHidden, withTokenHeader, withTunnelRecord, withoutCredentialLines };
@@ -1,18 +1,16 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { POLICY_CONTENT, VALIDATOR_FILES, VALIDATORS_DIR, POLICY_PATH } from './chunk-XZ6Q6ZNR.js';
4
- import { skillsBaseFor, isAgentsMdLayout } from './chunk-LOKSLO25.js';
5
- import { findGitDirs } from './chunk-BJ3KTMDH.js';
6
- import { machineSkillsState, staleClaudeSkills } from './chunk-IMOB4IOI.js';
7
- import { resolvePackRoot, OUTERLAYER_SKILLS_BASE, skillDir, namesCore, MACHINE_SKILL_PATH, AGENTS_SKILLS_BASE, MAINTAINED_SKILLS, isMaintainedCopy, loadTemplateFiles, rewriteSkillPaths, restoreSkillPaths, TEMPLATE_SKILLS } from './chunk-7OUOLGUV.js';
8
3
  import { mcpTargetPath, INIT_STDIO_ENTRY, INIT_DOCS_ENTRY, DOCS_MCP_SERVER_NAME } from './chunk-KT4CN6OU.js';
4
+ import { POLICY_CONTENT, VALIDATOR_FILES, VALIDATORS_DIR, POLICY_PATH } from './chunk-SATUCMAJ.js';
5
+ import { skillsBaseFor } from './chunk-5B7BEQPR.js';
6
+ import { findGitDirs } from './chunk-BJ3KTMDH.js';
7
+ import { resolvePackRoot, OUTERLAYER_SKILLS_BASE, skillDir, loadTemplateFiles, rewriteSkillPaths, restoreSkillPaths, TEMPLATE_SKILLS } from './chunk-JGML2VUN.js';
9
8
  import { cliInvocation } from './chunk-CRB3POP4.js';
10
9
  import { hasSymlinkComponent } from './chunk-VWFOKRYS.js';
11
10
  import { cloneIsGoverned } from './chunk-YQR6E6OV.js';
12
- import { emitTree, ALL_TARGET_IDS, classifyTree, splitRawFile } from './chunk-RKOTJQVG.js';
13
11
  import { createHash } from 'crypto';
14
- import { existsSync, readFileSync, realpathSync } from 'fs';
15
- import { join, dirname } from 'path';
12
+ import { existsSync, readFileSync } from 'fs';
13
+ import { join } from 'path';
16
14
 
17
15
  createRequire(import.meta.url);
18
16
  var SHIPPED_MANIFEST = "shipped.json";
@@ -190,138 +188,5 @@ function checkStarterFiles(cwd, opts = {}) {
190
188
  const fix = actionable ? `Run \`${UPDATE}\` to update the outdated files and write the missing ones. It never changes a file you edited.${compare}` : "Reinstall the CLI: `npm install -g @outerlayer/cli`, or run it with `npx -y @outerlayer/cli`.";
191
189
  return { checks: [{ name: NAME, status: "warn", detail: parts.join("; "), fix }], mcpOutdated };
192
190
  }
193
- var BUILD_PHASES = ["Intake", "Criteria", "Implement", "Review", "Pull request", "Evidence"];
194
- var MACHINE_CORE = `${MACHINE_SKILL_PATH}/outerlayer-build/SKILL.md`;
195
- var CHANGES_HEADING = "## Changes for this repository";
196
- var NAME2 = "Build skill";
197
- function changeHeadings(text) {
198
- const lines = text.split(/\r?\n/);
199
- const start = lines.findIndex((line) => line.trim() === CHANGES_HEADING);
200
- if (start === -1) return [];
201
- const headings = [];
202
- for (const line of lines.slice(start + 1)) {
203
- if (/^## /.test(line)) break;
204
- const match = /^### (.+?)\s*$/.exec(line);
205
- if (match) headings.push(match[1]);
206
- }
207
- return headings;
208
- }
209
- function skillsFolders() {
210
- const probe = `${skillDir("probe")}/SKILL.md`;
211
- const compiled = emitTree({
212
- entries: classifyTree([probe]).entries,
213
- contents: /* @__PURE__ */ new Map([[probe, "---\nname: probe\ndescription: probe\n---\n"]]),
214
- assetPaths: [],
215
- targets: [...ALL_TARGET_IDS]
216
- });
217
- return [...new Set(compiled.files.map((file) => dirname(dirname(file.path))))].sort();
218
- }
219
- function shortBuild() {
220
- const file = loadTemplateFiles().find((f) => f.path === `${skillDir("build")}/SKILL.md`);
221
- if (file === void 0) return "";
222
- return splitRawFile(file.content).body.split("\n").filter((line) => !line.startsWith("<!--")).join("\n").trim();
223
- }
224
- var read = (abs) => {
225
- try {
226
- return readFileSync(abs, "utf8");
227
- } catch {
228
- return void 0;
229
- }
230
- };
231
- function buildsOf(repoRoot, folders) {
232
- const source = `${folders[0]}/build/SKILL.md`;
233
- return (existsSync(join(repoRoot, source)) ? [source] : folders.slice(1).map((f) => `${f}/build/SKILL.md`)).map((path) => ({ path, text: read(join(repoRoot, path)) })).filter((b) => b.text !== void 0);
234
- }
235
- function checkBuildSkill(repoRoot) {
236
- const folders = [".outerlayer/skills", ...skillsFolders()];
237
- const builds = buildsOf(repoRoot, folders);
238
- const checks = [];
239
- const detached = builds.filter((b) => !namesCore(b.text));
240
- if (detached.length > 0) {
241
- checks.push({
242
- name: NAME2,
243
- status: "warn",
244
- detail: `${detached.map((b) => b.path).join(", ")} does not name outerlayer-build, so it gets no updates from the core`,
245
- fix: `Move to the short build, and put your own changes under the name of the phase each applies to:
246
-
247
- ${shortBuild()}`
248
- });
249
- }
250
- for (const build of builds.filter((b) => namesCore(b.text))) {
251
- const unknown = changeHeadings(build.text).filter((heading) => !BUILD_PHASES.includes(heading));
252
- if (unknown.length === 0) continue;
253
- checks.push({
254
- name: NAME2,
255
- status: "warn",
256
- detail: `${build.path} has ${unknown.map((h) => `"${h}"`).join(", ")} under "Changes for this repository", which matches no phase`,
257
- fix: `Rename each heading to a phase: ${BUILD_PHASES.join(", ")}.`
258
- });
259
- }
260
- const agentsMd = isAgentsMdLayout(repoRoot);
261
- const seen = /* @__PURE__ */ new Set();
262
- const lacking = folders.filter((folder) => {
263
- const text = read(join(repoRoot, folder, "build", "SKILL.md")) ?? "";
264
- if (!namesCore(text) || text.includes(MACHINE_CORE) || existsSync(join(repoRoot, folder, "outerlayer-build", "SKILL.md"))) return false;
265
- let key = folder;
266
- try {
267
- key = realpathSync(join(repoRoot, folder));
268
- } catch {
269
- }
270
- if (seen.has(key)) return false;
271
- seen.add(key);
272
- return true;
273
- });
274
- if (lacking.length > 0) {
275
- checks.push({
276
- name: NAME2,
277
- status: "warn",
278
- detail: `${lacking.join(", ")} holds build with no outerlayer-build beside it`,
279
- fix: `Run \`${cliInvocation()} ${agentsMd ? "init --update" : "context emit"}\` to write outerlayer-build, then commit.`
280
- });
281
- }
282
- return checks;
283
- }
284
- function committedMaintainedFolders(repoRoot) {
285
- const found = [];
286
- for (const base of [AGENTS_SKILLS_BASE, ".claude/skills"]) {
287
- for (const name of MAINTAINED_SKILLS) {
288
- const folder = skillDir(name, base);
289
- if (!hasSymlinkComponent(repoRoot, folder) && isMaintainedCopy(repoRoot, name, base)) found.push(folder);
290
- }
291
- }
292
- return found;
293
- }
294
- function checkCommittedMaintainedSkills(repoRoot) {
295
- if (!isAgentsMdLayout(repoRoot)) return [];
296
- const folders = committedMaintainedFolders(repoRoot);
297
- if (folders.length === 0) return [];
298
- return [
299
- {
300
- name: "Committed maintained skills",
301
- status: "warn",
302
- detail: `${folders.join(", ")} ${folders.length === 1 ? "is a maintained skill" : "are maintained skills"} that every machine keeps in ${MACHINE_SKILL_PATH}/ now`,
303
- fix: `Run \`${cliInvocation()} init --update\` to remove ${folders.length === 1 ? "it" : "them"}, then commit. Before you commit, every machine and runner host must run this CLI version or later, and each machine a person works on must run \`${cliInvocation()} init --local\`.`
304
- }
305
- ];
306
- }
307
- function checkMachineSkills(opts) {
308
- const build = buildsOf(opts.repoRoot, [".outerlayer/skills", ...skillsFolders()]).find((b) => b.text.includes(MACHINE_CORE));
309
- if (build === void 0) return [];
310
- const problems = machineSkillsState(opts.home, opts.version).filter((s) => s.state !== "current");
311
- const claudeStale = staleClaudeSkills(opts.home, opts.version);
312
- if (problems.length === 0 && claudeStale.length === 0) return [];
313
- const parts = [
314
- ...problems.map((s) => `${MACHINE_SKILL_PATH}/${s.name} ${s.state === "missing" ? "is missing" : "is from another CLI version"}`),
315
- ...claudeStale.map((name) => `~/.claude/skills/${name} is not this CLI version's copy`)
316
- ];
317
- return [
318
- {
319
- name: "Maintained skills on this machine",
320
- status: "warn",
321
- detail: `${build.path} reads ${MACHINE_CORE}, but ${parts.join(", ")}`,
322
- fix: `Run \`${cliInvocation()} init --local\` on this machine. If it reports a failed write, fix the permissions on the folder it names first.`
323
- }
324
- ];
325
- }
326
191
 
327
- export { canonical, checkBuildSkill, checkCommittedMaintainedSkills, checkMachineSkills, checkStarterFiles, committedMaintainedFolders, contentHash, contextIsGoverned, inspectStarterFiles, readShippedManifest, skillsFolders };
192
+ export { canonical, checkStarterFiles, contentHash, contextIsGoverned, inspectStarterFiles, readShippedManifest };
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { RUNNER_DIR_MODE, RUNNER_FILE_MODE } from './chunk-RHAGBUL5.js';
3
+ import { RUNNER_DIR_MODE, RUNNER_FILE_MODE } from './chunk-5K3KB4YR.js';
4
4
  import { readFileSync, existsSync, rmSync, mkdirSync, writeFileSync, renameSync } from 'fs';
5
5
  import { join } from 'path';
6
6
 
@@ -1,14 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { splitRawFile } from './chunk-RKOTJQVG.js';
3
+ import { MAINTAINED_SKILLS } from './chunk-CDDED64E.js';
4
4
  import { resolvePackageVersion } from './chunk-RA3O54FC.js';
5
+ import { splitRawFile } from './chunk-RKOTJQVG.js';
5
6
  import { existsSync, readFileSync, mkdirSync, writeFileSync, readdirSync } from 'fs';
6
7
  import { join, dirname } from 'path';
7
8
  import { fileURLToPath } from 'url';
8
9
 
9
10
  createRequire(import.meta.url);
10
11
  var TEMPLATE_SKILLS = ["spec", "writing-specs", "writing-tests", "build"];
11
- var MAINTAINED_SKILLS = ["outerlayer-evidence", "outerlayer-amend", "outerlayer-findings", "outerlayer-cli", "outerlayer-build"];
12
12
  function templateClassLine(version) {
13
13
  return `<!-- yours to edit. Copied once from the default template by outerlayer init ${version}; never overwritten. -->`;
14
14
  }
@@ -130,10 +130,6 @@ var FORMER_MAINTAINED_NAMES = {
130
130
  outerlayer: "outerlayer-cli"
131
131
  };
132
132
  var MAINTAINED_LINE = /^<!-- maintained by OuterLayer \S+?\. /m;
133
- var MAINTAINED_LINE_VERSION = /^<!-- maintained by OuterLayer (\S+?)\. /m;
134
- function maintainedLineVersion(text) {
135
- return MAINTAINED_LINE_VERSION.exec(text)?.[1];
136
- }
137
133
  function isMaintainedCopy(repoRoot, skill, base = OUTERLAYER_SKILLS_BASE) {
138
134
  try {
139
135
  return MAINTAINED_LINE.test(readFileSync(join(repoRoot, skillDir(skill, base), "SKILL.md"), "utf8"));
@@ -145,4 +141,4 @@ function formerNameExists(repoRoot, skill, base) {
145
141
  return Object.entries(FORMER_MAINTAINED_NAMES).some(([former, current]) => current === skill && isMaintainedCopy(repoRoot, former, base));
146
142
  }
147
143
 
148
- export { AGENTS_SKILLS_BASE, FORMER_MAINTAINED_NAMES, MACHINE_SKILL_PATH, MAINTAINED_SKILLS, OUTERLAYER_SKILLS_BASE, TEMPLATE_SKILLS, isMaintainedCopy, loadMachineSkillFiles, loadMaintainedFiles, loadTemplateFiles, maintainedFilesForExistingSkills, maintainedLineVersion, namesCore, resolvePackRoot, restoreSkillPaths, rewriteSkillPaths, skillDir, writeMaintainedFiles };
144
+ export { AGENTS_SKILLS_BASE, FORMER_MAINTAINED_NAMES, MACHINE_SKILL_PATH, OUTERLAYER_SKILLS_BASE, TEMPLATE_SKILLS, isMaintainedCopy, loadMachineSkillFiles, loadMaintainedFiles, loadTemplateFiles, maintainedFilesForExistingSkills, namesCore, resolvePackRoot, restoreSkillPaths, rewriteSkillPaths, skillDir, writeMaintainedFiles };
@@ -1,32 +1,33 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
3
  import { readsJobState, READ_JOB_STATE_FORMATS, jobStateFormatOf } from './chunk-ZVB57WI6.js';
4
- import { senderPidfile } from './chunk-Y7ZCHBYB.js';
5
- import { DOCKERD_LOG, HELPER_PATH, HELPER_RECORD } from './chunk-6KKM7VGZ.js';
6
- import { writeDockerClientConfig } from './chunk-XS3FDWSZ.js';
7
- import { installScrubContext } from './chunk-VS27BP3E.js';
8
- import { ADDED_USER, shellQuote, GH_CONFIG_YML, ghHostsYml, AssetError, obtainImage, ensureRootfs, gitRemoteFor, startServicesFor, createLeaseChannel, createBuildDisk, machineConfig, resolveAgentUser, AgentUserError, runBuildSteps, LEASE_SECONDS, createContainerRuntime, stopContainer, cleanupContainer, outOfMemoryReason, containerSenderCommand, signalInContainer, syncInContainer, copyTranscriptsFromContainer, senderAliveScript, helperFirecrackerNote, HelperRefusal, isLiteralAddress, deleteBuildDisk, startCheckContainer, lifecycleSteps, lifecycleFailureReason, writeEvalInput, DeliveryFailure, EVAL_INPUT_NAME, copyTranscripts, senderSignalScript, containerJudgeEnvironment, copyJudgeTree } from './chunk-R7SGBXUD.js';
9
- import { describeCallFailure, resolveGoverningSource, refusalCode, removeStagedContext, stageGovernedContext, pinnedSourceOf, commandWithShim, logStamp, createRunnerLog, removeKeptContext, formatDuration, retrySend, formatClock, keptContextTree } from './chunk-WSYXLLA5.js';
10
- import { fdName } from './chunk-YB3CSYXX.js';
11
- import { readBranchHead, fetchCommit, diffBetween } from './chunk-HWDYLXHH.js';
4
+ import { DOCKERD_LOG, HELPER_PATH, HELPER_RECORD } from './chunk-N7WAEEIU.js';
5
+ import { senderPidfile } from './chunk-SFJXGISY.js';
6
+ import { installScrubContext } from './chunk-MKIC65SD.js';
7
+ import { writeDockerClientConfig } from './chunk-ZTY7HHYB.js';
8
+ import { ADDED_USER, shellQuote, GH_CONFIG_YML, ghHostsYml, AssetError, obtainImage, ensureRootfs, gitRemoteFor, startServicesFor, createLeaseChannel, createBuildDisk, machineConfig, resolveAgentUser, AgentUserError, runBuildSteps, LEASE_SECONDS, createContainerRuntime, stopContainer, cleanupContainer, outOfMemoryReason, containerSenderCommand, signalInContainer, syncInContainer, copyTranscriptsFromContainer, senderAliveScript, helperFirecrackerNote, HelperRefusal, isLiteralAddress, deleteBuildDisk, startCheckContainer, lifecycleSteps, lifecycleFailureReason, writeEvalInput, DeliveryFailure, EVAL_INPUT_NAME, copyTranscripts, senderSignalScript, containerJudgeEnvironment, copyJudgeTree } from './chunk-GLL4TN2M.js';
9
+ import { waitForAgent, vmExecArgs } from './chunk-MHAR6S7B.js';
10
+ import { socketPathProblem, vsockLinks, LEASE_LINK, linkVsockSockets } from './chunk-WWQVKFN6.js';
11
+ import { describeCallFailure, resolveGoverningSource, refusalCode, removeStagedContext, stageGovernedContext, pinnedSourceOf, commandWithShim, logStamp, createRunnerLog, removeKeptContext, formatDuration, retrySend, formatClock, keptContextTree } from './chunk-USJZ2LDK.js';
12
+ import { isBuiltinContainer, isBuiltinProcess, isBuiltinVm, DEFAULT_CHECK_TIME_LIMIT_MINUTES } from './chunk-55XLX5PA.js';
13
+ import { readBranchHead, fetchCommit, diffBetween } from './chunk-T2QSWFSU.js';
12
14
  import { isSameProcess, startTimeOf } from './chunk-JBJTC3UU.js';
13
- import { HASH_ARGV, parseProgramHash, JUDGE_PROGRAM, writeJobFile, readJobFile, childEnvironment, judgeCommand, JUDGE_MAX_TURNS, MAX_REPORT_BYTES, JUDGE_DIR, COMMAND_DIR } from './chunk-EX5MQYEF.js';
14
- import { CLAUDE_CODE_VERSION, FIRECRACKER_VERSION } from './chunk-2BTFKNTR.js';
15
- import { waitForAgent, vmExecArgs } from './chunk-XBPUTQ7E.js';
16
- import { socketPathProblem, vsockLinks, LEASE_LINK, linkVsockSockets } from './chunk-GLUKDQS4.js';
17
- import { WorkCommandError, postJson, isSignatureRefusal, getJson } from './chunk-55GNQPO6.js';
18
- import { planArtifactUpload } from './chunk-BUP5N3X6.js';
19
- import { isBuiltinContainer, isBuiltinProcess, isBuiltinVm, DEFAULT_CHECK_TIME_LIMIT_MINUTES } from './chunk-EPPIISRD.js';
15
+ import { HASH_ARGV, parseProgramHash, JUDGE_PROGRAM, writeJobFile, readJobFile, childEnvironment, judgeCommand, JUDGE_MAX_TURNS, MAX_REPORT_BYTES, JUDGE_DIR, COMMAND_DIR } from './chunk-VC5J7QPV.js';
20
16
  import { parseSize } from './chunk-YJLHUKYS.js';
21
- import { resolvePackRoot, MAINTAINED_SKILLS } from './chunk-7OUOLGUV.js';
22
- import { scrubText } from './chunk-QE3UQAHK.js';
17
+ import { CLAUDE_CODE_VERSION, FIRECRACKER_VERSION } from './chunk-SJZL5F3F.js';
18
+ import { WorkCommandError, postJson, isSignatureRefusal, getJson } from './chunk-X52PMPOM.js';
19
+ import { planArtifactUpload } from './chunk-BUP5N3X6.js';
20
+ import { scrubText } from './chunk-UHU7H57K.js';
23
21
  import { readCloudConfig } from './chunk-PJDQPF5N.js';
22
+ import { signerFor } from './chunk-YL2VDSNF.js';
23
+ import { RUNNER_FILE_MODE, runnerDir, buildDir, vsockPath } from './chunk-5K3KB4YR.js';
24
+ import { JOB_MOUNT, claudeCredential, repositoriesOf, primaryOf, buildEnvironment, CHECKOUT_DIR, parseIsolation, proxyEnvironment, withProxyWarningHidden, containerLocalAddress, destinationEnvironment, CLAUDE_CREDENTIAL_VARIABLES, builtInEnvironment, withHooksPath, startBuildServices, BUILT_IN_NAMES, AGENT_CREDENTIAL_MISSING, sharedUserEnvironment, headerVariables, authorEnvironment, withTunnelRecord, commitIdentityRecord, RELAY_PORT, repositoryPath, lifecycleWorkdir, currentClaudeCredential, removedClaudeCredentialValues, checkEnvironment, EVAL_INPUT_DIR } from './chunk-HXAEQPZR.js';
25
+ import { resolvePackRoot } from './chunk-JGML2VUN.js';
26
+ import { MAINTAINED_SKILLS } from './chunk-CDDED64E.js';
27
+ import { resolveVersion } from './chunk-RA3O54FC.js';
24
28
  import { parsePolicy } from './chunk-RKOTJQVG.js';
25
29
  import { homeFromEnv } from './chunk-VNVZDWO3.js';
26
- import { resolveVersion } from './chunk-RA3O54FC.js';
27
- import { signerFor } from './chunk-Y4OKEFAX.js';
28
- import { RUNNER_FILE_MODE, runnerDir, buildDir, vsockPath } from './chunk-RHAGBUL5.js';
29
- import { JOB_MOUNT, claudeCredential, repositoriesOf, primaryOf, buildEnvironment, CHECKOUT_DIR, parseIsolation, proxyEnvironment, withProxyWarningHidden, containerLocalAddress, destinationEnvironment, CLAUDE_CREDENTIAL_VARIABLES, builtInEnvironment, withHooksPath, startBuildServices, BUILT_IN_NAMES, AGENT_CREDENTIAL_MISSING, sharedUserEnvironment, headerVariables, authorEnvironment, withTunnelRecord, commitIdentityRecord, RELAY_PORT, repositoryPath, lifecycleWorkdir, checkEnvironment, EVAL_INPUT_DIR } from './chunk-2I3LIRZP.js';
30
+ import { fdName } from './chunk-XD4ZCMA4.js';
30
31
  import { RUNNER_WORDED_REASONS, UNKNOWN_TRACKING_REASON } from './chunk-JGD5TWQ2.js';
31
32
  import { existsSync, statSync, appendFileSync, rmSync, mkdirSync, chmodSync, writeFileSync, accessSync, constants, openSync, readFileSync, closeSync, readdirSync, linkSync, lstatSync, fstatSync, readSync, realpathSync } from 'fs';
32
33
  import { join, isAbsolute, dirname, delimiter, sep } from 'path';
@@ -2420,7 +2421,8 @@ function mergeScrubConfig(a, b) {
2420
2421
  function releaseScrub(config, home) {
2421
2422
  const merged = mergeScrubConfig(config.scrub, readCloudConfig(home).scrub);
2422
2423
  const secrets = [...headerVariables(config.build?.destinations), ...CLAUDE_CREDENTIAL_VARIABLES].map((name) => process.env[name] ?? "");
2423
- return { literals: [...scrubList(merged?.literals), ...secrets], patterns: scrubList(merged?.patterns) };
2424
+ const held = [currentClaudeCredential(process.env)?.value, ...removedClaudeCredentialValues()].filter((value) => value !== void 0);
2425
+ return { literals: [...scrubList(merged?.literals), ...secrets, ...held], patterns: scrubList(merged?.patterns) };
2424
2426
  }
2425
2427
  function transcriptScrub(config, secrets) {
2426
2428
  const base = releaseScrub(config, homeFromEnv());
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { fetchFactories, selectFactory, saveFactoryConnection, autoConnectedLine } from './chunk-N4D5TMVU.js';
4
- import { resolveGatewayCredentials } from './chunk-BWH36FOC.js';
3
+ import { fetchFactories, selectFactory, saveFactoryConnection, autoConnectedLine } from './chunk-VU7ZJPIR.js';
4
+ import { resolveRepoIdentity } from './chunk-UHU7H57K.js';
5
+ import { resolveGatewayCredentials } from './chunk-7CK2TJFB.js';
5
6
  import { findGitDirs, readRepoConnection } from './chunk-BJ3KTMDH.js';
6
- import { resolveRepoIdentity } from './chunk-QE3UQAHK.js';
7
7
  import { cliInvocation } from './chunk-CRB3POP4.js';
8
8
  import { homeFromEnv } from './chunk-VNVZDWO3.js';
9
9
  import { openSync, fstatSync, readSync, closeSync } from 'fs';
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { EXEC_PORT } from './chunk-GLUKDQS4.js';
3
+ import { EXEC_PORT } from './chunk-WWQVKFN6.js';
4
4
  import { createConnection } from 'net';
5
5
 
6
6
  createRequire(import.meta.url);
@@ -1,25 +1,25 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { uploadSpooledSteps } from './chunk-O2IJTY7L.js';
3
+ import { uploadSpooledSteps } from './chunk-TVZAC2NP.js';
4
4
  import { LaunchFilter } from './chunk-ESVW4MJY.js';
5
5
  import { RepoFilter } from './chunk-TBT347UY.js';
6
6
  import { migrateLegacyArtifactSidecars, planArtifactUpload, artifactsStatePath, sanitizeTerminal, acquireArtifactSpoolLock, artifactBlobsDir, resolveArtifactTurnIndex, isArtifactTombstoned, ARTIFACT_RETRY_MAX_AGE_MS, writeArtifactSpoolState, reclaimUnneededArtifactBlobs, neededArtifactShas } from './chunk-BUP5N3X6.js';
7
- import { cliFetch, resolveGatewayCredentials, defaultFetch, unauthorizedMessage } from './chunk-BWH36FOC.js';
8
- import { writeSyncStatus, spoolDir } from './chunk-DJHNEGNM.js';
7
+ import { setCustomScrubbers, setLocalIdentity, tailTranscript, enrichSessionRepo, scanAll, setRepoRoot, resolveRepoIdentity, sessionIdFromPath, scrubDeep, SOURCE_ADAPTERS } from './chunk-UHU7H57K.js';
8
+ import { C } from './chunk-ANPNT6PM.js';
9
+ import { cliFetch, resolveGatewayCredentials, defaultFetch, unauthorizedMessage } from './chunk-7CK2TJFB.js';
10
+ import { readCloudConfig, cloudConfigPath, writeCloudConfig } from './chunk-PJDQPF5N.js';
11
+ import { signerFor, signRunnerRequest } from './chunk-YL2VDSNF.js';
12
+ import { writeSyncStatus, spoolDir } from './chunk-DKWQMPSL.js';
9
13
  import { readLatestProvenanceForSession, readContextProvenance } from './chunk-ZJSNLVCE.js';
10
14
  import { hookExecSpoolPath } from './chunk-2O5KA67H.js';
11
15
  import { applyReportedCost } from './chunk-BKO6JEZI.js';
12
16
  import { readRepoConnection, findGitDirs } from './chunk-BJ3KTMDH.js';
13
- import { setCustomScrubbers, setLocalIdentity, tailTranscript, enrichSessionRepo, scanAll, setRepoRoot, resolveRepoIdentity, sessionIdFromPath, scrubDeep, SOURCE_ADAPTERS } from './chunk-QE3UQAHK.js';
14
- import { C } from './chunk-ANPNT6PM.js';
15
- import { readCloudConfig, cloudConfigPath, writeCloudConfig } from './chunk-PJDQPF5N.js';
16
17
  import { readLaunchSpoolState, launchStatusIsDecisive, launchedItemsBySession, launchesPath } from './chunk-T2Q7ISPE.js';
17
18
  import { cliInvocation } from './chunk-CRB3POP4.js';
18
19
  import { removeJournalHooks } from './chunk-TUSYOL2O.js';
19
20
  import { CAPTURE_TIERS, inferArtifactKind, bannedPathsForTier, downconvertSession, isHumanUserTurn, turnCountBound, EVENT_TYPES } from './chunk-QZBXLLTV.js';
20
21
  import { homeFromEnv } from './chunk-VNVZDWO3.js';
21
- import { signerFor, signRunnerRequest } from './chunk-Y4OKEFAX.js';
22
- import { dirname, basename, join } from 'path';
22
+ import { dirname, basename, join, sep } from 'path';
23
23
  import { statSync, readFileSync, readdirSync, mkdirSync, writeFileSync, renameSync, existsSync, rmSync } from 'fs';
24
24
  import { execFileSync } from 'child_process';
25
25
  import { hostname, userInfo } from 'os';
@@ -834,6 +834,49 @@ var LiveUploader = class {
834
834
  }
835
835
  }
836
836
  };
837
+ var NOTICE = /<task-id>(?:\s|\\n)*([\w-]+)(?:\s|\\n)*<\/task-id>(?:(?!<task-notification>)[\s\S])*?<status>(?:\s|\\n)*(completed|failed|killed|stopped|cancelled|canceled|error)(?:\s|\\n)*<\/status>/gi;
838
+ var cache = /* @__PURE__ */ new Map();
839
+ function parentTranscriptOf(subagentFile) {
840
+ const segments = subagentFile.split(sep);
841
+ const at = segments.lastIndexOf("subagents");
842
+ if (at < 2) return void 0;
843
+ return join(segments.slice(0, at - 1).join(sep), `${segments[at - 1]}.jsonl`);
844
+ }
845
+ function endNotices(text) {
846
+ const endedAt = /* @__PURE__ */ new Map();
847
+ for (const raw of text.split("\n")) {
848
+ if (!raw.includes("<task-notification>")) continue;
849
+ let line;
850
+ try {
851
+ line = JSON.parse(raw);
852
+ } catch {
853
+ continue;
854
+ }
855
+ if (line.type !== "user" || typeof line.timestamp !== "string") continue;
856
+ for (const [, id] of raw.matchAll(NOTICE)) endedAt.set(id, [...endedAt.get(id) ?? [], line.timestamp]);
857
+ }
858
+ return endedAt;
859
+ }
860
+ function noticesIn(parentFile) {
861
+ try {
862
+ const { size, mtimeMs } = statSync(parentFile);
863
+ const key = `${parentFile}\0${size}\0${mtimeMs}`;
864
+ const known = cache.get(key) ?? endNotices(readFileSync(parentFile, "utf8"));
865
+ cache.set(key, known);
866
+ return known;
867
+ } catch {
868
+ return /* @__PURE__ */ new Map();
869
+ }
870
+ }
871
+ function subagentEndedInParent(subagentFile, lastActivityAt) {
872
+ const parent = parentTranscriptOf(subagentFile);
873
+ if (parent === void 0) return false;
874
+ const notices = noticesIn(parent).get(basename(subagentFile, ".jsonl").replace(/^agent-/, "")) ?? [];
875
+ return notices.some((at) => lastActivityAt === void 0 || Date.parse(at) >= Date.parse(lastActivityAt));
876
+ }
877
+ function runningForParent(entry, lastActivityAt) {
878
+ return !entry.isSubagent || !subagentEndedInParent(entry.file, lastActivityAt);
879
+ }
837
880
 
838
881
  // src/skip-verdict.ts
839
882
  var RESUME_WINDOW_MS = 14 * 24 * 60 * 60 * 1e3;
@@ -1206,7 +1249,7 @@ async function runSyncInner(opts, stats) {
1206
1249
  applyContextProvenance(session, contextSourceBySessionId.get(session.id));
1207
1250
  applyReportedCost(session, home);
1208
1251
  const gated = prepareSessionForUpload(session, tier, envVars);
1209
- const liveEntry = liveUploads[gated.id];
1252
+ const liveEntry = runningForParent(entry, gated.endedAt) ? liveUploads[gated.id] : void 0;
1210
1253
  const daemonIsStreaming = liveEntry !== void 0 && !liveEntry.ended && !liveEntry.failed;
1211
1254
  if (daemonIsStreaming && !sessionHasEnded(home, gated.subagent?.parentSessionId ?? gated.id)) {
1212
1255
  const gatedTurns = gated.turns ?? [];
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { detectMachine, supportsContainerBuilds, reachDockerStep, describeMachineDocker, supportsMicroVmBuilds } from './chunk-B7DJVG25.js';
4
- import { MIN_ENGINE_MAJOR } from './chunk-R7SGBXUD.js';
5
- import { hasStoredCredential, AGENT_COMMANDS, storeClaudeCredential, credentialFromStdin, isAgentName } from './chunk-GFUE5TKO.js';
6
- import { runnerCredentialProblem } from './chunk-EPPIISRD.js';
7
- import { runnerDir, RUNNER_DIR_MODE, RUNNER_FILE_MODE } from './chunk-RHAGBUL5.js';
3
+ import { detectMachine, supportsContainerBuilds, reachDockerStep, describeMachineDocker, supportsMicroVmBuilds } from './chunk-HOB7Z4JQ.js';
4
+ import { MIN_ENGINE_MAJOR } from './chunk-GLL4TN2M.js';
5
+ import { hasStoredCredential, AGENT_COMMANDS, storeClaudeCredential, credentialFromStdin, isAgentName } from './chunk-F4FA3ZUT.js';
6
+ import { runnerCredentialProblem } from './chunk-55XLX5PA.js';
7
+ import { runnerDir, RUNNER_DIR_MODE, RUNNER_FILE_MODE } from './chunk-5K3KB4YR.js';
8
8
  import { existsSync, readFileSync, mkdirSync, writeFileSync } from 'fs';
9
9
  import { dirname } from 'path';
10
10
 
@@ -104,7 +104,7 @@ function prepareRunnerInit(configPath, opts = {}) {
104
104
  if (hooks === "builtin:process" && opts.allowProcess !== true) throw new RunnerInitError(processRefusal(machine));
105
105
  if (agent === "claude" && credential === void 0 && opts.credentialInEnvironment !== true && !hasStoredCredential(configPath)) {
106
106
  throw new RunnerInitError(
107
- "--agent claude needs Claude's credential, and none was piped on stdin or is in the runner.env beside the config. Pipe a token from `claude setup-token`, or an Anthropic API key: printf '%s' \"$CLAUDE_CODE_OAUTH_TOKEN\" | outerlayer runner init --agent claude"
107
+ "--agent claude needs Claude's credential, and none was piped on stdin or is in the claude.env beside the config. Pipe a token from `claude setup-token`, or an Anthropic API key: printf '%s' \"$CLAUDE_CODE_OAUTH_TOKEN\" | outerlayer runner init --agent claude"
108
108
  );
109
109
  }
110
110
  return { configPath, config, carried, credential, agent, machine, hooks, needsKey, host: opts.host };