@outerlayer/cli 0.34.0-next.20261025132734 → 0.34.0-next.20261025180645

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 (130) hide show
  1. package/README.md +6 -0
  2. package/dist/{agent-setup-HEJM3D3V.js → agent-setup-FNDKCPUP.js} +8 -9
  3. package/dist/{bridge-NBCXFTT4.js → bridge-YJBB4YA3.js} +2 -3
  4. package/dist/build-B4OKU4MV.js +16 -0
  5. package/dist/{build-disk-LEZ6LAM3.js → build-disk-ZL46AEN3.js} +7 -9
  6. package/dist/build-info.json +1 -1
  7. package/dist/{builder-I32JOQII.js → builder-XFPWE74N.js} +6 -8
  8. package/dist/{check-OOUGS65D.js → check-QULEN437.js} +45 -45
  9. package/dist/{chunk-65AKMFBH.js → chunk-25GRRBTH.js} +1 -1
  10. package/dist/{chunk-3CKMB2UK.js → chunk-2D6CKNR7.js} +8 -4
  11. package/dist/{chunk-5THSC6BD.js → chunk-2ILU7UAU.js} +1 -1
  12. package/dist/{chunk-5QBUX5YZ.js → chunk-3EJBI5JW.js} +3 -3
  13. package/dist/{chunk-6RKD7YZ6.js → chunk-3N77LUQI.js} +1 -1
  14. package/dist/{chunk-ES4ULBAL.js → chunk-4UPET3R7.js} +7 -3
  15. package/dist/{chunk-43I7PXDP.js → chunk-5AFPP3GZ.js} +239 -15
  16. package/dist/{chunk-HVRQQOMH.js → chunk-63IVRRIO.js} +3 -3
  17. package/dist/{chunk-FVKH3PMV.js → chunk-6OLVVAOK.js} +5 -5
  18. package/dist/{chunk-6ZFY2L2T.js → chunk-AJYZNISW.js} +416 -20
  19. package/dist/{chunk-6NUPXDAA.js → chunk-AVPLEFQR.js} +3 -3
  20. package/dist/{chunk-EN3YWO7Q.js → chunk-BHSSGVOY.js} +4 -4
  21. package/dist/{chunk-O6DYCIVW.js → chunk-CAQCDYKF.js} +2 -2
  22. package/dist/{chunk-7WM7K2DY.js → chunk-DNZYXEMY.js} +35 -21
  23. package/dist/{chunk-QMWUPRYQ.js → chunk-EGVHFHY4.js} +4 -4
  24. package/dist/{chunk-ACRRO3MB.js → chunk-FD5ASWTG.js} +22 -22
  25. package/dist/{chunk-57L2YAJA.js → chunk-FDJPDZSR.js} +1 -1
  26. package/dist/{chunk-EE2ZZGQV.js → chunk-FVCHHSHB.js} +3 -3
  27. package/dist/{chunk-BALIE3BA.js → chunk-G4W4B33M.js} +191 -8
  28. package/dist/{chunk-ZW6L275N.js → chunk-HHFZXOBC.js} +12 -14
  29. package/dist/{chunk-AMEM2ZLL.js → chunk-INOUUSYI.js} +29 -9
  30. package/dist/{chunk-XFFUXXI4.js → chunk-JBCOUY4M.js} +3 -3
  31. package/dist/{chunk-YEVPRO7L.js → chunk-JQSZTQSK.js} +81 -52
  32. package/dist/{chunk-TDAQHYM4.js → chunk-K2UAQWYO.js} +3 -3
  33. package/dist/{chunk-ZYKFYNES.js → chunk-KM2HLQE3.js} +2 -2
  34. package/dist/{chunk-DXJTBU7A.js → chunk-LUHIN4UZ.js} +3 -3
  35. package/dist/{chunk-SOI6K5DY.js → chunk-MOI2KDLH.js} +1 -1
  36. package/dist/{chunk-QDVGOMSC.js → chunk-NW26E4YU.js} +3 -3
  37. package/dist/{chunk-YIBFGAYI.js → chunk-O4Z2MNNL.js} +6 -6
  38. package/dist/{chunk-L26V6ILJ.js → chunk-OGPEHSNW.js} +1 -1
  39. package/dist/{chunk-2JB4GD34.js → chunk-OQLF3MQQ.js} +3 -4
  40. package/dist/{chunk-Z5IW4DHH.js → chunk-OS7DJOQJ.js} +1 -1
  41. package/dist/{chunk-DA3PLB5N.js → chunk-PAK5P2ND.js} +1 -1
  42. package/dist/{chunk-3IH6K7KG.js → chunk-PFHTT4PP.js} +5 -5
  43. package/dist/{chunk-PA6CK6WQ.js → chunk-PXGU3GKY.js} +1 -1
  44. package/dist/{chunk-YGSY2NWU.js → chunk-QANM5COC.js} +6 -6
  45. package/dist/{chunk-K5Q6T7SE.js → chunk-QQP3S5FU.js} +3 -3
  46. package/dist/{chunk-62LXQM7U.js → chunk-RFVIQLNB.js} +5 -5
  47. package/dist/{chunk-E4ASIOVL.js → chunk-RHV5SRI2.js} +3 -3
  48. package/dist/{chunk-6LBSAW6I.js → chunk-SI6WDF3U.js} +1 -1
  49. package/dist/chunk-SUOZYOWO.js +51 -0
  50. package/dist/{chunk-MZBQTVFG.js → chunk-SYVRBBLW.js} +1 -1
  51. package/dist/{chunk-5HZGLLNW.js → chunk-TBKV4L2W.js} +5 -5
  52. package/dist/{chunk-GH246BGV.js → chunk-TFPNPS4Q.js} +1 -1
  53. package/dist/{chunk-NBZ7XBT6.js → chunk-UMYYYF7B.js} +1 -1
  54. package/dist/{chunk-Z4KWHSO4.js → chunk-UN3SQTVL.js} +7 -7
  55. package/dist/{chunk-ZVLSYWDF.js → chunk-UO4FQAOX.js} +16 -12
  56. package/dist/{chunk-4Y54SQXH.js → chunk-VJ34F55N.js} +105 -44
  57. package/dist/{chunk-272AKVRP.js → chunk-YHKU2NOZ.js} +1 -1
  58. package/dist/{chunk-F5UL23I2.js → chunk-YNMVVQOQ.js} +1 -1
  59. package/dist/{claude-launcher-MORG66PJ.js → claude-launcher-OQZNW7XJ.js} +1 -1
  60. package/dist/{cli-XI7RUSC5.js → cli-G3P2B2XE.js} +124 -118
  61. package/dist/{command-BJSHY6OB.js → command-4XOXVWFW.js} +169 -48
  62. package/dist/config-QASNKYM6.js +16 -0
  63. package/dist/{connect-cmd-YAUOCX4X.js → connect-cmd-MEDWMW3L.js} +8 -9
  64. package/dist/{container-start-QADK3YGL.js → container-start-2DHCWV73.js} +34 -36
  65. package/dist/{context-show-cmd-VHY3OBIA.js → context-show-cmd-VSFCG663.js} +9 -10
  66. package/dist/{control-plane-launch-QSBWTA2V.js → control-plane-launch-XBGHM7DB.js} +5 -6
  67. package/dist/{dist-ZAHCXYSG.js → dist-QGN5R4Y2.js} +1 -1
  68. package/dist/{docker-DJ73SZRC.js → docker-TAC6G4VU.js} +6 -8
  69. package/dist/{doctor-UR76MCGI.js → doctor-LK6E3XOW.js} +68 -43
  70. package/dist/{emit-artifact-cmd-DP2EQ54N.js → emit-artifact-cmd-L4REOPWX.js} +13 -14
  71. package/dist/{emit-cmd-7NMNKDK7.js → emit-cmd-7TU3JBJ2.js} +2 -2
  72. package/dist/{emit-criteria-cmd-TTFBN6RK.js → emit-criteria-cmd-QVFOQARC.js} +10 -11
  73. package/dist/{emit-demo-cmd-Z7YGLEBJ.js → emit-demo-cmd-L4B6OOTV.js} +15 -16
  74. package/dist/{emit-finding-cmd-IQRD3J2X.js → emit-finding-cmd-YXFCIWMU.js} +10 -11
  75. package/dist/{emit-result-cmd-GIWB6UHH.js → emit-result-cmd-NI4LCTUM.js} +12 -13
  76. package/dist/{emit-step-cmd-PU5TTU6C.js → emit-step-cmd-HWAUCZZB.js} +10 -11
  77. package/dist/{exec-client-7PT4W7JR.js → exec-client-QB4OZRGM.js} +3 -4
  78. package/dist/find-unit-4UR647S4.js +18 -0
  79. package/dist/{findings-cmd-7J5SHCUO.js → findings-cmd-O2IBO25E.js} +10 -11
  80. package/dist/{fleet-readiness-G63D76EX.js → fleet-readiness-NJYTQYTA.js} +5 -6
  81. package/dist/{governing-source-DLESDP6T.js → governing-source-JCI7VDQ6.js} +12 -13
  82. package/dist/{guest-init-J3F3AEEY.js → guest-init-IF5LXGUL.js} +4 -5
  83. package/dist/{hook-fast-VQXRDS6E.js → hook-fast-GPUL7T77.js} +1 -1
  84. package/dist/host-key-5RU322O3.js +9 -0
  85. package/dist/{image-tag-ADSLWXBA.js → image-tag-SEMBVB5D.js} +3 -4
  86. package/dist/index.js +4 -4
  87. package/dist/{init-KSXU4PA7.js → init-2CEULE3F.js} +25 -27
  88. package/dist/{init-67R7LO4C.js → init-FAIF7KOK.js} +25 -27
  89. package/dist/{init-cmd-MNOVMADM.js → init-cmd-HZUUMO45.js} +13 -14
  90. package/dist/{init-update-6KEXRCJH.js → init-update-TTMFFNMB.js} +12 -13
  91. package/dist/{install-cmd-FV7IZ7XF.js → install-cmd-TWGRGEVL.js} +5 -6
  92. package/dist/{logs-HI46FO6Z.js → logs-6CMB3DO6.js} +2 -3
  93. package/dist/{loop-KUEOPBKX.js → loop-7U7MVICV.js} +41 -43
  94. package/dist/{machine-EQEAPT76.js → machine-S3JHOX4V.js} +25 -27
  95. package/dist/{mcp-serve-cmd-7ABBV2QE.js → mcp-serve-cmd-MWGIN6YL.js} +4 -5
  96. package/dist/{paths-7HVTDE6J.js → paths-T2DEBI62.js} +2 -3
  97. package/dist/pending-ERXWVLLG.js +9 -0
  98. package/dist/{pidfile-5UDLYPMC.js → pidfile-EAD2OEM7.js} +3 -4
  99. package/dist/{record-PPZEXAVA.js → record-IMXQNHPB.js} +3 -4
  100. package/dist/runner-env-BJPUHAKZ.js +18 -0
  101. package/dist/runner-identity-ZCPPC2BJ.js +13 -0
  102. package/dist/{runner-key-ML7R33HF.js → runner-key-CYSUYKSX.js} +25 -27
  103. package/dist/{session-sender-A43GZQ7T.js → session-sender-5T7BXPKC.js} +13 -14
  104. package/dist/{spec-cmd-VVUJZSG2.js → spec-cmd-4ABYAFNZ.js} +11 -12
  105. package/dist/{status-4G6K7I2C.js → status-2AP7J2L7.js} +32 -34
  106. package/dist/{sync-cmd-ZEC65ABJ.js → sync-cmd-34CGNA6T.js} +12 -13
  107. package/dist/{update-steps-XLO7734I.js → update-steps-JQOCCDWO.js} +33 -35
  108. package/dist/{watch-QB4AMWR3.js → watch-6HU7LCUY.js} +12 -13
  109. package/dist/{work-claim-cmd-6W3GBHRS.js → work-claim-cmd-5QKLHSCR.js} +17 -19
  110. package/dist/{work-cmd-LTZXOPPN.js → work-cmd-3MKUIE2C.js} +10 -11
  111. package/dist/{work-comment-cmd-LDZBUO6M.js → work-comment-cmd-ESC3DSHI.js} +11 -12
  112. package/dist/{work-demo-cmd-77LISWQ3.js → work-demo-cmd-7S23DGYO.js} +10 -11
  113. package/dist/{work-logs-cmd-FK7HE7PC.js → work-logs-cmd-46UPNN7Q.js} +10 -11
  114. package/dist/{work-open-pr-cmd-WVONEHZL.js → work-open-pr-cmd-JNGTGLIP.js} +11 -12
  115. package/dist/{work-pr-cmd-6IPXWJEH.js → work-pr-cmd-2J2LKETD.js} +10 -11
  116. package/dist/{work-proofs-cmd-TGIAP5IO.js → work-proofs-cmd-HRWTHYSS.js} +11 -12
  117. package/dist/{work-proofs-record-XPAU7N57.js → work-proofs-record-6OKAT3IC.js} +18 -19
  118. package/dist/{work-stop-cmd-UJ45EV3A.js → work-stop-cmd-Y22XIVQ6.js} +10 -11
  119. package/package.json +1 -1
  120. package/dist/build-LSU25G3M.js +0 -14
  121. package/dist/chunk-3Z3MPR55.js +0 -226
  122. package/dist/chunk-HACGUL52.js +0 -183
  123. package/dist/config-WRHQDGVI.js +0 -18
  124. package/dist/host-key-UERIQRE6.js +0 -10
  125. package/dist/inspect-DNLXTXLA.js +0 -6
  126. package/dist/install-OCBERTPQ.js +0 -19
  127. package/dist/pending-5HZACM2V.js +0 -10
  128. package/dist/runner-env-L7OPH3O3.js +0 -20
  129. package/dist/runner-identity-VASV2AEQ.js +0 -15
  130. package/dist/{chunk-2AIOOU3A.js → chunk-KPHRRCUY.js} +1 -1
@@ -1,15 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { RecipeError } from './chunk-3Z3MPR55.js';
4
- import { BUILDKIT_IMAGE } from './chunk-ES4ULBAL.js';
5
- import { compareVersions } from './chunk-6ZFY2L2T.js';
6
- import { ensureHostKey } from './chunk-SOI6K5DY.js';
7
- import { RUNNER_DIR_MODE, RUNNER_FILE_MODE, runnerDir, jobsDir } from './chunk-PA6CK6WQ.js';
8
- import { CLAUDE_PORT, JOB_MOUNT, GATEWAY_PORT, GATEWAY_SOCKET, CLAUDE_SOCKET, RELAY_PORT, DESTINATION_BASE_PORT } from './chunk-BALIE3BA.js';
3
+ import { BUILDKIT_IMAGE } from './chunk-4UPET3R7.js';
4
+ import { ensureHostKey } from './chunk-MOI2KDLH.js';
5
+ import { compareVersions } from './chunk-AJYZNISW.js';
6
+ import { RUNNER_DIR_MODE, RUNNER_FILE_MODE, runnerDir, jobsDir } from './chunk-PXGU3GKY.js';
7
+ import { CLAUDE_PORT, JOB_MOUNT, GATEWAY_PORT, GATEWAY_SOCKET, CLAUDE_SOCKET, RELAY_PORT, DESTINATION_BASE_PORT } from './chunk-G4W4B33M.js';
9
8
  import { JOIN_DIR, RELAY_ID, JOIN_SOCKET, TARGET_GATEWAY, TARGET_CLAUDE, destinationTarget, RELAY_USER } from './chunk-MESOOLF4.js';
10
9
  import { createHash } from 'crypto';
11
- import { existsSync, mkdirSync, createWriteStream, rmSync, readFileSync, chmodSync, writeFileSync, realpathSync, readdirSync, renameSync } from 'fs';
12
- import { join, dirname, resolve } from 'path';
10
+ import { existsSync, readdirSync, readFileSync, lstatSync, realpathSync, writeFileSync, mkdirSync, createWriteStream, rmSync, chmodSync, renameSync } from 'fs';
11
+ import { join, resolve, relative, dirname, sep, basename } from 'path';
13
12
  import { StringDecoder } from 'string_decoder';
14
13
  import { spawn } from 'child_process';
15
14
  import { createRequire as createRequire$1 } from 'module';
@@ -48,6 +47,228 @@ function cut(line) {
48
47
  const last = head.charCodeAt(head.length - 1);
49
48
  return last >= 55296 && last <= 56319 ? head.slice(0, -1) : head;
50
49
  }
50
+
51
+ // src/runner/image/properties.ts
52
+ var LIFECYCLE = ["onCreateCommand", "updateContentCommand", "postCreateCommand", "postStartCommand"];
53
+ var HONOURED = ["image", "build", "features", "containerEnv", "remoteUser", ...LIFECYCLE];
54
+ var IGNORED_BUILD_KEYS = ["options"];
55
+ var HOST_REFERENCE = /\$\{(?:localEnv|env)[:}]/;
56
+ var DROP = /* @__PURE__ */ Symbol("drop");
57
+ function isHonoured(property) {
58
+ return HONOURED.includes(property);
59
+ }
60
+ function isObject(value) {
61
+ return typeof value === "object" && value !== null && !Array.isArray(value);
62
+ }
63
+ function featureName(id) {
64
+ const slash = id.lastIndexOf("/");
65
+ const cut2 = id.slice(slash + 1).search(/[:@]/);
66
+ return cut2 === -1 ? id : id.slice(0, slash + 1 + cut2);
67
+ }
68
+ var DOCKER_FEATURE = "ghcr.io/devcontainers/features/docker-in-docker";
69
+ function asksForDocker(recipe, metadata) {
70
+ const isDocker = (id) => featureName(id) === DOCKER_FEATURE;
71
+ if (isObject(recipe.features) && Object.keys(recipe.features).some(isDocker)) return true;
72
+ return metadata.some((entry) => typeof entry.id === "string" && isDocker(entry.id));
73
+ }
74
+ function sameValue(a, b) {
75
+ return JSON.stringify(a) === JSON.stringify(b);
76
+ }
77
+ function isFilesOwnEntry(entry, recipe) {
78
+ if (typeof entry.id === "string") return false;
79
+ const keys = Object.keys(entry);
80
+ return keys.length > 0 && keys.every((key) => key in recipe && sameValue(entry[key], recipe[key]));
81
+ }
82
+ function withoutHostReferences(value, path, dropped) {
83
+ if (typeof value === "string") {
84
+ if (!HOST_REFERENCE.test(value)) return value;
85
+ dropped.push(path);
86
+ return DROP;
87
+ }
88
+ if (Array.isArray(value)) {
89
+ if (!HOST_REFERENCE.test(JSON.stringify(value))) return value;
90
+ dropped.push(path);
91
+ return DROP;
92
+ }
93
+ if (isObject(value)) {
94
+ const kept = {};
95
+ for (const [key, item] of Object.entries(value)) {
96
+ if (HOST_REFERENCE.test(key)) {
97
+ dropped.push(`${path}.${key}`);
98
+ continue;
99
+ }
100
+ const clean = withoutHostReferences(item, `${path}.${key}`, dropped);
101
+ if (clean !== DROP) kept[key] = clean;
102
+ }
103
+ return kept;
104
+ }
105
+ return value;
106
+ }
107
+ function honouredWithoutHostReferences(entry) {
108
+ const kept = {};
109
+ const dropped = [];
110
+ for (const property of HONOURED) {
111
+ if (!(property in entry)) continue;
112
+ const value = entry[property];
113
+ const clean = withoutHostReferences(
114
+ property === "build" && isObject(value) ? withoutIgnoredBuildKeys(value) : value,
115
+ property,
116
+ dropped
117
+ );
118
+ if (clean !== DROP) kept[property] = clean;
119
+ }
120
+ return { kept, dropped };
121
+ }
122
+ function withoutIgnoredBuildKeys(build) {
123
+ return Object.fromEntries(Object.entries(build).filter(([key]) => !IGNORED_BUILD_KEYS.includes(key)));
124
+ }
125
+ function ignoredIn(entry, source) {
126
+ const found = [];
127
+ for (const property of Object.keys(entry)) {
128
+ if (property === "id" || property.startsWith("$") || isHonoured(property)) continue;
129
+ found.push({ property, source });
130
+ }
131
+ if (isObject(entry.build)) {
132
+ for (const key of IGNORED_BUILD_KEYS) {
133
+ if (key in entry.build) found.push({ property: `build.${key}`, source });
134
+ }
135
+ }
136
+ for (const property of honouredWithoutHostReferences(entry).dropped) found.push({ property, source });
137
+ return found;
138
+ }
139
+ function emptyApply() {
140
+ return { containerEnv: {}, lifecycle: { onCreateCommand: [], updateContentCommand: [], postCreateCommand: [], postStartCommand: [] } };
141
+ }
142
+ function applyEntry(apply, raw, source) {
143
+ const entry = honouredWithoutHostReferences(raw).kept;
144
+ if (typeof entry.remoteUser === "string") apply.remoteUser = entry.remoteUser;
145
+ if (isObject(entry.containerEnv)) {
146
+ for (const [key, value] of Object.entries(entry.containerEnv)) {
147
+ if (typeof value === "string") apply.containerEnv[key] = value;
148
+ }
149
+ }
150
+ for (const name of LIFECYCLE) {
151
+ if (entry[name] !== void 0) apply.lifecycle[name].push({ source, command: entry[name] });
152
+ }
153
+ }
154
+ function classifyProperties(recipe, metadata) {
155
+ const ignored = ignoredIn(recipe, "file");
156
+ const apply = emptyApply();
157
+ let fileApplied = false;
158
+ const sanitized = sanitizeRecipe(recipe);
159
+ for (const entry of metadata) {
160
+ if (isFilesOwnEntry(entry, sanitized)) {
161
+ applyEntry(apply, entry, "file");
162
+ fileApplied = true;
163
+ continue;
164
+ }
165
+ const source = typeof entry.id === "string" ? `feature ${featureName(entry.id)}` : "image label";
166
+ ignored.push(...ignoredIn(entry, source));
167
+ applyEntry(apply, entry, source);
168
+ }
169
+ if (!fileApplied) applyEntry(apply, recipe, "file");
170
+ return { docker: asksForDocker(recipe, metadata), honoured: HONOURED.filter((property) => property in recipe), ignored, apply };
171
+ }
172
+ function sanitizeRecipe(recipe) {
173
+ return honouredWithoutHostReferences(recipe).kept;
174
+ }
175
+
176
+ // src/runner/image/recipe.ts
177
+ var RecipeError = class extends Error {
178
+ constructor(code, message, logPath) {
179
+ super(message);
180
+ this.code = code;
181
+ this.logPath = logPath;
182
+ }
183
+ };
184
+ var DIR_RECIPE = ".devcontainer/devcontainer.json";
185
+ var ROOT_RECIPE = ".devcontainer.json";
186
+ function locateRecipe(checkoutDir) {
187
+ if (existsSync(join(checkoutDir, DIR_RECIPE))) return { kind: "file", path: DIR_RECIPE };
188
+ if (existsSync(join(checkoutDir, ROOT_RECIPE))) return { kind: "file", path: ROOT_RECIPE };
189
+ const named = namedConfigurations(checkoutDir);
190
+ if (named.length > 0) {
191
+ throw new RecipeError(
192
+ "recipe_ambiguous",
193
+ `the repository has only named devcontainer configurations (${named.join(", ")}); add ${DIR_RECIPE} so the runner knows which to build`
194
+ );
195
+ }
196
+ return { kind: "default" };
197
+ }
198
+ function namedConfigurations(checkoutDir) {
199
+ const dir = join(checkoutDir, ".devcontainer");
200
+ if (!existsSync(dir)) return [];
201
+ return readdirSync(dir).sort().map((entry) => `.devcontainer/${entry}/devcontainer.json`).filter((path) => existsSync(join(checkoutDir, path)));
202
+ }
203
+ var COMMENTS = /("(?:[^"\\]|\\.)*")|\/\/[^\n]*|\/\*[\s\S]*?(?:\*\/|$)/g;
204
+ var TRAILING_COMMAS = /("(?:[^"\\]|\\.)*")|,(\s*[}\]])/g;
205
+ function parseJsonc(text) {
206
+ const withoutComments = text.replace(COMMENTS, (_match, str) => str ?? "");
207
+ return JSON.parse(withoutComments.replace(TRAILING_COMMAS, (_match, str, close) => str ?? close ?? ""));
208
+ }
209
+ function readRecipe(checkoutDir, location) {
210
+ if (location.kind === "default") return {};
211
+ const parsed = parseJsonc(readFileSync(join(checkoutDir, location.path), "utf8"));
212
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
213
+ throw new Error(`${location.path} is not a JSON object`);
214
+ }
215
+ return parsed;
216
+ }
217
+ function within(dir, path) {
218
+ const rel = relative(dir, path);
219
+ return rel !== ".." && !rel.startsWith(`..${sep}`);
220
+ }
221
+ function realish(path) {
222
+ let existing = path;
223
+ let rest = "";
224
+ while (!existsSync(existing)) {
225
+ rest = join(basename(existing), rest);
226
+ existing = dirname(existing);
227
+ }
228
+ return join(realpathSync(existing), rest);
229
+ }
230
+ function assertBuildable(checkoutDir, location, recipe) {
231
+ if (location.kind === "default") return;
232
+ const devcontainerDir = join(checkoutDir, ".devcontainer");
233
+ if (existsSync(devcontainerDir) && lstatSync(devcontainerDir).isSymbolicLink()) {
234
+ throw new RecipeError(
235
+ "recipe_context_outside",
236
+ ".devcontainer is a symbolic link, so the build could read files outside the repository; commit a real directory"
237
+ );
238
+ }
239
+ if (recipe.dockerComposeFile !== void 0) {
240
+ throw new RecipeError(
241
+ "recipe_needs_docker",
242
+ "the recipe uses dockerComposeFile; its services need Docker, which a container build does not have"
243
+ );
244
+ }
245
+ const build = recipe.build;
246
+ if (typeof build !== "object" || build === null) return;
247
+ const { dockerfile, context } = build;
248
+ const base = resolve(checkoutDir, location.path, "..");
249
+ const allowed = join(realpathSync(checkoutDir), ".devcontainer");
250
+ const contextPath = resolve(base, typeof context === "string" ? context : ".");
251
+ const paths = [contextPath];
252
+ if (typeof dockerfile === "string") paths.push(resolve(base, dockerfile));
253
+ for (const path of paths) {
254
+ if (!within(devcontainerDir, path) || !within(allowed, realish(path))) {
255
+ throw new RecipeError(
256
+ "recipe_context_outside",
257
+ `the recipe's build reads ${relative(checkoutDir, path) || "."}, outside .devcontainer/; move the build files into .devcontainer/`
258
+ );
259
+ }
260
+ }
261
+ }
262
+ function writeSanitizedRecipe(checkoutDir, location, recipe) {
263
+ if (location.kind === "default") throw new Error("the default image has no recipe to sanitize");
264
+ const path = location.path === ROOT_RECIPE ? join(checkoutDir, ".outerlayer-recipe.json") : join(checkoutDir, ".devcontainer", SANITIZED_NAME);
265
+ writeFileSync(path, `${JSON.stringify(sanitizeRecipe(recipe), null, 2)}
266
+ `);
267
+ return path;
268
+ }
269
+ var SANITIZED_NAME = "outerlayer-recipe.json";
270
+
271
+ // src/runner/image/devcontainer-cli.ts
51
272
  var PACKAGE = "@devcontainers/cli";
52
273
  function buildRootFromDist(moduleDir = dirname(fileURLToPath(import.meta.url))) {
53
274
  try {
@@ -58,9 +279,9 @@ function buildRootFromDist(moduleDir = dirname(fileURLToPath(import.meta.url)))
58
279
  }
59
280
  }
60
281
  function resolveDevcontainerCli(opts = {}) {
61
- const resolve2 = opts.resolve ?? createRequire$1(import.meta.url).resolve;
282
+ const resolve3 = opts.resolve ?? createRequire$1(import.meta.url).resolve;
62
283
  try {
63
- const bin = join(dirname(resolve2(`${PACKAGE}/package.json`)), "devcontainer.js");
284
+ const bin = join(dirname(resolve3(`${PACKAGE}/package.json`)), "devcontainer.js");
64
285
  if (existsSync(bin)) return { command: process.execPath, args: [bin] };
65
286
  } catch {
66
287
  }
@@ -133,7 +354,7 @@ function childEnvironment(base) {
133
354
  }
134
355
  return env;
135
356
  }
136
- var spawnRun = (command, args, opts = {}) => new Promise((resolve2) => {
357
+ var spawnRun = (command, args, opts = {}) => new Promise((resolve3) => {
137
358
  let log;
138
359
  if (opts.logPath !== void 0) {
139
360
  mkdirSync(dirname(opts.logPath), { recursive: true });
@@ -149,11 +370,11 @@ var spawnRun = (command, args, opts = {}) => new Promise((resolve2) => {
149
370
  settled = true;
150
371
  const result = { status, stdout: stdout + stdoutDecoder.end(), stderr: stderr + stderrDecoder.end() + extra };
151
372
  if (log === void 0) {
152
- resolve2(result);
373
+ resolve3(result);
153
374
  return;
154
375
  }
155
376
  if (extra) log.write(extra);
156
- log.end(() => resolve2(result));
377
+ log.end(() => resolve3(result));
157
378
  };
158
379
  let timer;
159
380
  const child = spawn(command, args, {
@@ -374,6 +595,9 @@ function readRunnerIdentity(configPath) {
374
595
  return void 0;
375
596
  }
376
597
  }
598
+ function identityDockerFor(runner) {
599
+ return runner.keepsHostBuilder ? void 0 : { holdsObjects: async () => false };
600
+ }
377
601
  function dockerIdentity(run = spawnRun) {
378
602
  return {
379
603
  async holdsObjects(label, builder) {
@@ -697,7 +921,7 @@ function ensureBuilder(rawRun, spec, options = {}) {
697
921
  const result = serialized(async () => {
698
922
  const state = await buildxState(run);
699
923
  if (state !== "usable") return { ok: false, problem: state.problem };
700
- const sleep = options.sleep ?? ((ms) => new Promise((resolve2) => setTimeout(resolve2, ms)));
924
+ const sleep = options.sleep ?? ((ms) => new Promise((resolve3) => setTimeout(resolve3, ms)));
701
925
  const inspected = await run("docker", ["buildx", "inspect", spec.name]);
702
926
  let create = inspected.status !== 0;
703
927
  if (!create) {
@@ -763,4 +987,4 @@ function ensureBuilder(rawRun, spec, options = {}) {
763
987
  );
764
988
  }
765
989
 
766
- export { BUILD_LABEL, COMMAND_DIR, HASH_ARGV, JUDGE_DIR, JUDGE_ITEMS, JUDGE_MAX_TURNS, JUDGE_PROGRAM, JUDGE_REPORT, MAX_ITEMS_BYTES, MAX_REPORT_BYTES, MIN_BUILDX_VERSION, RUNNER_LABEL, builderName, builderNameFor, builderSpec, buildxState, childEnvironment, containerExecArgs, containerRunArgs, createDockerHost, dockerIdentity, ensureBuilder, ensureFailureCount, ensureRunnerIdentity, exceedsDisk, isOutOfMemory, judgeCommand, parseProgramHash, parseSize, pathLabelValue, prepareRunArgs, proxyEnvironment, readDu, readJobFile, readJobFileChecked, readRunnerIdentity, resolveDevcontainerCli, runnerLabelValue, spawnRun, trackImageBuild, withAnswerProtocol, writeJobFile };
990
+ export { BUILD_LABEL, COMMAND_DIR, DOCKER_FEATURE, HASH_ARGV, JUDGE_DIR, JUDGE_ITEMS, JUDGE_MAX_TURNS, JUDGE_PROGRAM, JUDGE_REPORT, MAX_ITEMS_BYTES, MAX_REPORT_BYTES, MIN_BUILDX_VERSION, RUNNER_LABEL, RecipeError, SANITIZED_NAME, assertBuildable, builderName, builderNameFor, builderSpec, buildxState, childEnvironment, classifyProperties, containerExecArgs, containerRunArgs, createDockerHost, dockerIdentity, ensureBuilder, ensureFailureCount, ensureRunnerIdentity, exceedsDisk, identityDockerFor, isOutOfMemory, judgeCommand, locateRecipe, parseProgramHash, parseSize, pathLabelValue, prepareRunArgs, proxyEnvironment, readDu, readJobFile, readJobFileChecked, readRecipe, readRunnerIdentity, resolveDevcontainerCli, runnerLabelValue, spawnRun, trackImageBuild, withAnswerProtocol, writeJobFile, writeSanitizedRecipe };
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { TUNNEL_PORT, BRIDGE_ADDRESS, BRIDGE_CIDR } from './chunk-6LBSAW6I.js';
3
+ import { TUNNEL_PORT, BRIDGE_ADDRESS, BRIDGE_CIDR } from './chunk-SI6WDF3U.js';
4
+ import { EXEC_PORT } from './chunk-OGPEHSNW.js';
4
5
  import { startTimeOf } from './chunk-JBJTC3UU.js';
5
- import { EXEC_PORT } from './chunk-L26V6ILJ.js';
6
- import { RELAY_PORT } from './chunk-BALIE3BA.js';
6
+ import { RELAY_PORT } from './chunk-G4W4B33M.js';
7
7
  import { spawn, spawnSync } from 'child_process';
8
8
  import { symlinkSync, lstatSync, writeFileSync, chmodSync, mkdirSync, existsSync } from 'fs';
9
9
 
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { WorkCommandError, resolveCredentials, getJson } from './chunk-Z4KWHSO4.js';
4
- import { sanitizeTerminal } from './chunk-MECW77XP.js';
5
- import { resolveRepoIdentity } from './chunk-6ZFY2L2T.js';
3
+ import { WorkCommandError, resolveCredentials, getJson } from './chunk-UN3SQTVL.js';
6
4
  import { C } from './chunk-ANPNT6PM.js';
7
- import { defaultFetch } from './chunk-6RKD7YZ6.js';
5
+ import { sanitizeTerminal } from './chunk-MECW77XP.js';
6
+ import { defaultFetch } from './chunk-3N77LUQI.js';
7
+ import { resolveRepoIdentity } from './chunk-AJYZNISW.js';
8
8
  import { parseWorkItemEnv } from './chunk-T2Q7ISPE.js';
9
9
  import { parseTrackerNumber, trackerNumberError } from './chunk-WZBHBH3J.js';
10
10
  import { inferArtifactKind, mediaTypeForArtifactPath, WORK_ITEM_COMMENT_MAX_BODY_LENGTH } from './chunk-EOTMDIYC.js';
@@ -130,7 +130,7 @@ async function runWorkProofs(opts) {
130
130
  async function runWorkProofsCommand(opts) {
131
131
  try {
132
132
  if (opts.record) {
133
- const { runWorkProofsRecord } = await import('./work-proofs-record-XPAU7N57.js');
133
+ const { runWorkProofsRecord } = await import('./work-proofs-record-6OKAT3IC.js');
134
134
  const result2 = await runWorkProofsRecord(opts);
135
135
  process.exitCode = result2.exitCode;
136
136
  return;