@boxes-dev/dvb 0.2.28 → 0.2.29

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 (39) hide show
  1. package/dist/bin/dvb.cjs +878 -688
  2. package/dist/bin/dvb.js +2 -1
  3. package/dist/bin/dvb.js.map +1 -1
  4. package/dist/bin/dvbd.cjs +47 -16
  5. package/dist/devbox/commands/destroy.d.ts.map +1 -1
  6. package/dist/devbox/commands/destroy.js +62 -2
  7. package/dist/devbox/commands/destroy.js.map +1 -1
  8. package/dist/devbox/commands/init/codex/local.d.ts +8 -4
  9. package/dist/devbox/commands/init/codex/local.d.ts.map +1 -1
  10. package/dist/devbox/commands/init/codex/local.js +36 -12
  11. package/dist/devbox/commands/init/codex/local.js.map +1 -1
  12. package/dist/devbox/commands/init/index.d.ts.map +1 -1
  13. package/dist/devbox/commands/init/index.js +169 -173
  14. package/dist/devbox/commands/init/index.js.map +1 -1
  15. package/dist/devbox/commands/init/registry.d.ts +3 -4
  16. package/dist/devbox/commands/init/registry.d.ts.map +1 -1
  17. package/dist/devbox/commands/init/registry.js +22 -25
  18. package/dist/devbox/commands/init/registry.js.map +1 -1
  19. package/dist/devbox/commands/init/repo.d.ts +4 -1
  20. package/dist/devbox/commands/init/repo.d.ts.map +1 -1
  21. package/dist/devbox/commands/init/repo.js +57 -1
  22. package/dist/devbox/commands/init/repo.js.map +1 -1
  23. package/dist/devbox/commands/init/state.d.ts +2 -2
  24. package/dist/devbox/commands/init/state.d.ts.map +1 -1
  25. package/dist/devbox/commands/init/state.js +22 -7
  26. package/dist/devbox/commands/init/state.js.map +1 -1
  27. package/dist/devbox/commands/wezterm.d.ts.map +1 -1
  28. package/dist/devbox/commands/wezterm.js +29 -5
  29. package/dist/devbox/commands/wezterm.js.map +1 -1
  30. package/dist/devbox/completions/index.d.ts.map +1 -1
  31. package/dist/devbox/completions/index.js +42 -22
  32. package/dist/devbox/completions/index.js.map +1 -1
  33. package/dist/devbox/daemonClient.js +2 -2
  34. package/dist/devbox/daemonClient.js.map +1 -1
  35. package/dist/prompts/local-scan-env-secrets.md +1 -1
  36. package/dist/prompts/local-scan-external.md +1 -1
  37. package/dist/prompts/local-scan-extra-artifacts.md +1 -1
  38. package/dist/prompts/local-services-scan.md +1 -1
  39. package/package.json +1 -1
package/dist/bin/dvb.cjs CHANGED
@@ -33,14 +33,39 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
33
33
  mod
34
34
  ));
35
35
 
36
+ // ../core/src/profile.ts
37
+ var DEVBOX_PROFILE_ENV, RESERVED_PROFILES, sanitizeProfile, normalizeDevboxProfile, resolveDevboxProfile;
38
+ var init_profile = __esm({
39
+ "../core/src/profile.ts"() {
40
+ "use strict";
41
+ DEVBOX_PROFILE_ENV = "DEVBOX_PROFILE";
42
+ RESERVED_PROFILES = /* @__PURE__ */ new Set(["default", "prod", "production"]);
43
+ sanitizeProfile = (value) => {
44
+ const lower = value.toLowerCase();
45
+ const replaced = lower.replace(/[^a-z0-9_-]+/g, "-");
46
+ return replaced.replace(/^-+/, "").replace(/-+$/, "");
47
+ };
48
+ normalizeDevboxProfile = (value) => {
49
+ const trimmed = value?.trim() ?? "";
50
+ if (!trimmed) return null;
51
+ const normalized = sanitizeProfile(trimmed);
52
+ if (!normalized) return null;
53
+ if (RESERVED_PROFILES.has(normalized)) return null;
54
+ return normalized;
55
+ };
56
+ resolveDevboxProfile = (env2 = process.env) => normalizeDevboxProfile(env2[DEVBOX_PROFILE_ENV]);
57
+ }
58
+ });
59
+
36
60
  // ../core/src/config.ts
37
- var import_promises, import_node_os, import_node_path, DEFAULT_SPRITES_API_URL, resolveEmbeddedSpritesApiUrl, resolveSpritesApiUrl, resolveDevboxDir, resolveConfigPath, ensureDevboxDir, writeJsonAtomic, loadConfig, saveConfig;
61
+ var import_promises, import_node_os, import_node_path, DEFAULT_SPRITES_API_URL, resolveEmbeddedSpritesApiUrl, resolveSpritesApiUrl, resolveDevboxDir, resolveDevboxProjectsDir, resolveDevboxProjectDir, resolveConfigPath, ensureDevboxDir, writeJsonAtomic, loadConfig, saveConfig;
38
62
  var init_config = __esm({
39
63
  "../core/src/config.ts"() {
40
64
  "use strict";
41
65
  import_promises = __toESM(require("node:fs/promises"), 1);
42
66
  import_node_os = __toESM(require("node:os"), 1);
43
67
  import_node_path = __toESM(require("node:path"), 1);
68
+ init_profile();
44
69
  DEFAULT_SPRITES_API_URL = "https://api.sprites.dev";
45
70
  resolveEmbeddedSpritesApiUrl = () => {
46
71
  if (true) {
@@ -50,7 +75,13 @@ var init_config = __esm({
50
75
  return trimmed.length > 0 ? trimmed : null;
51
76
  };
52
77
  resolveSpritesApiUrl = (config) => config?.spritesApiUrl ?? resolveEmbeddedSpritesApiUrl() ?? DEFAULT_SPRITES_API_URL;
53
- resolveDevboxDir = (homeDir = import_node_os.default.homedir()) => import_node_path.default.join(homeDir, ".devbox");
78
+ resolveDevboxDir = (homeDir = import_node_os.default.homedir()) => (() => {
79
+ const profile = resolveDevboxProfile();
80
+ const base = import_node_path.default.join(homeDir, ".devbox");
81
+ return profile ? import_node_path.default.join(homeDir, `.devbox-${profile}`) : base;
82
+ })();
83
+ resolveDevboxProjectsDir = (homeDir = import_node_os.default.homedir()) => import_node_path.default.join(resolveDevboxDir(homeDir), "projects");
84
+ resolveDevboxProjectDir = (projectId, homeDir = import_node_os.default.homedir()) => import_node_path.default.join(resolveDevboxProjectsDir(homeDir), projectId);
54
85
  resolveConfigPath = (homeDir) => import_node_path.default.join(resolveDevboxDir(homeDir), "config.json");
55
86
  ensureDevboxDir = async (homeDir) => {
56
87
  const dir = resolveDevboxDir(homeDir);
@@ -150,6 +181,7 @@ var init_paths = __esm({
150
181
  "../core/src/paths.ts"() {
151
182
  "use strict";
152
183
  import_node_path2 = __toESM(require("node:path"), 1);
184
+ init_profile();
153
185
  DEVBOX_SOCKET_ENV = "DEVBOX_SOCKET_PATH";
154
186
  getUid = () => {
155
187
  if (typeof process.getuid === "function") return process.getuid();
@@ -164,15 +196,17 @@ var init_paths = __esm({
164
196
  source: "env"
165
197
  };
166
198
  }
199
+ const profile = resolveDevboxProfile(env2);
167
200
  if (platform === "linux" && env2.XDG_RUNTIME_DIR) {
201
+ const runtimeDir2 = profile ? import_node_path2.default.join(env2.XDG_RUNTIME_DIR, `devbox-${profile}`) : env2.XDG_RUNTIME_DIR;
168
202
  return {
169
- socketPath: import_node_path2.default.join(env2.XDG_RUNTIME_DIR, "devboxd.sock"),
170
- runtimeDir: env2.XDG_RUNTIME_DIR,
203
+ socketPath: import_node_path2.default.join(runtimeDir2, "devboxd.sock"),
204
+ runtimeDir: runtimeDir2,
171
205
  source: "xdg"
172
206
  };
173
207
  }
174
208
  const uid = getUid();
175
- const runtimeDir = `/tmp/devbox-${uid}`;
209
+ const runtimeDir = profile ? `/tmp/devbox-${uid}-${profile}` : `/tmp/devbox-${uid}`;
176
210
  return {
177
211
  socketPath: import_node_path2.default.join(runtimeDir, "devboxd.sock"),
178
212
  runtimeDir,
@@ -183,17 +217,16 @@ var init_paths = __esm({
183
217
  });
184
218
 
185
219
  // ../core/src/secrets.ts
186
- var import_promises2, import_node_os2, import_node_path3, resolveDevboxDir2, resolveSecretsPath, ensureDevboxDir2, readFileSecrets, writeFileSecrets, FileSecretStore, createSecretStore;
220
+ var import_promises2, import_node_path3, resolveSecretsPath, ensureDevboxDir2, readFileSecrets, writeFileSecrets, FileSecretStore, createSecretStore;
187
221
  var init_secrets = __esm({
188
222
  "../core/src/secrets.ts"() {
189
223
  "use strict";
190
224
  import_promises2 = __toESM(require("node:fs/promises"), 1);
191
- import_node_os2 = __toESM(require("node:os"), 1);
192
225
  import_node_path3 = __toESM(require("node:path"), 1);
193
- resolveDevboxDir2 = (homeDir = import_node_os2.default.homedir()) => import_node_path3.default.join(homeDir, ".devbox");
194
- resolveSecretsPath = (homeDir) => import_node_path3.default.join(resolveDevboxDir2(homeDir), "secrets.json");
226
+ init_config();
227
+ resolveSecretsPath = (homeDir) => import_node_path3.default.join(resolveDevboxDir(homeDir), "secrets.json");
195
228
  ensureDevboxDir2 = async (homeDir) => {
196
- const dir = resolveDevboxDir2(homeDir);
229
+ const dir = resolveDevboxDir(homeDir);
197
230
  await import_promises2.default.mkdir(dir, { recursive: true, mode: 448 });
198
231
  try {
199
232
  await import_promises2.default.chmod(dir, 448);
@@ -313,15 +346,14 @@ var init_secrets = __esm({
313
346
  });
314
347
 
315
348
  // ../core/src/registry.ts
316
- var import_promises3, import_node_os3, import_node_path4, resolveDevboxDir3, resolveRegistryPath, createEmptyRegistry, loadRegistry, resolveAlias;
349
+ var import_promises3, import_node_path4, resolveRegistryPath, createEmptyRegistry, loadRegistry, resolveAlias;
317
350
  var init_registry = __esm({
318
351
  "../core/src/registry.ts"() {
319
352
  "use strict";
320
353
  import_promises3 = __toESM(require("node:fs/promises"), 1);
321
- import_node_os3 = __toESM(require("node:os"), 1);
322
354
  import_node_path4 = __toESM(require("node:path"), 1);
323
- resolveDevboxDir3 = (homeDir = import_node_os3.default.homedir()) => import_node_path4.default.join(homeDir, ".devbox");
324
- resolveRegistryPath = (homeDir) => import_node_path4.default.join(resolveDevboxDir3(homeDir), "registry.json");
355
+ init_config();
356
+ resolveRegistryPath = (homeDir) => import_node_path4.default.join(resolveDevboxDir(homeDir), "registry.json");
325
357
  createEmptyRegistry = () => ({
326
358
  version: 1,
327
359
  aliases: {},
@@ -345,11 +377,10 @@ var init_registry = __esm({
345
377
  });
346
378
 
347
379
  // ../core/src/repo.ts
348
- var import_node_crypto, stripGitSuffix, normalizeGitRemoteUrl, hashString, fingerprintFromOrigin, fingerprintFromRootCommit;
380
+ var stripGitSuffix, normalizeGitRemoteUrl;
349
381
  var init_repo = __esm({
350
382
  "../core/src/repo.ts"() {
351
383
  "use strict";
352
- import_node_crypto = require("node:crypto");
353
384
  stripGitSuffix = (value) => {
354
385
  let trimmed = value.trim();
355
386
  if (trimmed.endsWith(".git")) {
@@ -373,11 +404,11 @@ var init_repo = __esm({
373
404
  try {
374
405
  const url = new URL(trimmed);
375
406
  const host = url.hostname.toLowerCase();
376
- const path24 = stripGitSuffix(url.pathname);
377
- if (!host || !path24) {
407
+ const path25 = stripGitSuffix(url.pathname);
408
+ if (!host || !path25) {
378
409
  throw new Error(`Unrecognized git URL: ${input}`);
379
410
  }
380
- return `${host}/${path24}`;
411
+ return `${host}/${path25}`;
381
412
  } catch {
382
413
  }
383
414
  if (trimmed.includes(":")) {
@@ -388,18 +419,15 @@ var init_repo = __esm({
388
419
  }
389
420
  return stripGitSuffix(trimmed);
390
421
  };
391
- hashString = (value) => (0, import_node_crypto.createHash)("sha256").update(value).digest("hex");
392
- fingerprintFromOrigin = (originUrl) => hashString(normalizeGitRemoteUrl(originUrl));
393
- fingerprintFromRootCommit = (rootCommit, salt) => hashString(`${rootCommit}:${salt}`);
394
422
  }
395
423
  });
396
424
 
397
425
  // ../core/src/sprites.ts
398
- var import_node_crypto2, import_node_util, import_ws, SpritesApiError, logger, USE_INTERNAL_SERVICE_API, INTERNAL_SERVICE_SIGNAL_TIMEOUT_SECONDS, toWebSocketErrorInfo, toWsUrl, shellQuote, requestJson, listSprites, requestNdjson, writeFile, normalizeServiceRecord, readFile, openExecSocket, attachExecSocket, openProxySocket, listExecSessions, listServices, internalServicesRequest, createCheckpointInternal, listServicesInternal, getServiceInternal, createServiceInternal, startServiceInternal, stopServiceInternal, execCommand, createSpritesClient;
426
+ var import_node_crypto, import_node_util, import_ws, SpritesApiError, logger, USE_INTERNAL_SERVICE_API, INTERNAL_SERVICE_SIGNAL_TIMEOUT_SECONDS, toWebSocketErrorInfo, toWsUrl, shellQuote, requestJson, listSprites, requestNdjson, writeFile, normalizeServiceRecord, readFile, openExecSocket, attachExecSocket, openProxySocket, listExecSessions, listServices, internalServicesRequest, createCheckpointInternal, listServicesInternal, getServiceInternal, createServiceInternal, startServiceInternal, stopServiceInternal, execCommand, createSpritesClient;
399
427
  var init_sprites = __esm({
400
428
  "../core/src/sprites.ts"() {
401
429
  "use strict";
402
- import_node_crypto2 = require("node:crypto");
430
+ import_node_crypto = require("node:crypto");
403
431
  import_node_util = require("node:util");
404
432
  import_ws = __toESM(require("ws"), 1);
405
433
  init_logger();
@@ -408,11 +436,11 @@ var init_sprites = __esm({
408
436
  method;
409
437
  path;
410
438
  body;
411
- constructor(status, method, path24, body) {
412
- super(`Sprites API error ${status} ${method} ${path24}: ${body}`);
439
+ constructor(status, method, path25, body) {
440
+ super(`Sprites API error ${status} ${method} ${path25}: ${body}`);
413
441
  this.status = status;
414
442
  this.method = method;
415
- this.path = path24;
443
+ this.path = path25;
416
444
  this.body = body;
417
445
  }
418
446
  };
@@ -457,15 +485,15 @@ var init_sprites = __esm({
457
485
  }
458
486
  return { message: String(event) };
459
487
  };
460
- toWsUrl = (apiBaseUrl, path24) => {
488
+ toWsUrl = (apiBaseUrl, path25) => {
461
489
  const base = new URL(apiBaseUrl);
462
490
  const protocol = base.protocol === "https:" ? "wss:" : "ws:";
463
- return new URL(path24, `${protocol}//${base.host}`);
491
+ return new URL(path25, `${protocol}//${base.host}`);
464
492
  };
465
493
  shellQuote = (value) => `'${value.replace(/'/g, `'\\''`)}'`;
466
- requestJson = async (apiBaseUrl, token, method, path24, body) => {
467
- const requestId = (0, import_node_crypto2.randomUUID)();
468
- const url = new URL(path24, apiBaseUrl);
494
+ requestJson = async (apiBaseUrl, token, method, path25, body) => {
495
+ const requestId = (0, import_node_crypto.randomUUID)();
496
+ const url = new URL(path25, apiBaseUrl);
469
497
  const headers = {
470
498
  authorization: `Bearer ${token}`,
471
499
  "x-request-id": requestId
@@ -477,18 +505,18 @@ var init_sprites = __esm({
477
505
  if (body) {
478
506
  init.body = JSON.stringify(body);
479
507
  }
480
- logger.info("sprites_request", { requestId, method, path: path24 });
508
+ logger.info("sprites_request", { requestId, method, path: path25 });
481
509
  const response = await fetch(url, init);
482
510
  const text = await response.text();
483
511
  logger.info("sprites_response", {
484
512
  requestId,
485
513
  method,
486
- path: path24,
514
+ path: path25,
487
515
  status: response.status
488
516
  });
489
517
  if (!response.ok) {
490
518
  const snippet = text.trim().slice(0, 200);
491
- throw new SpritesApiError(response.status, method, path24, snippet);
519
+ throw new SpritesApiError(response.status, method, path25, snippet);
492
520
  }
493
521
  if (!text) return null;
494
522
  try {
@@ -508,8 +536,8 @@ var init_sprites = __esm({
508
536
  if (options?.prefix) {
509
537
  params.set("prefix", options.prefix);
510
538
  }
511
- const path24 = `/v1/sprites${params.size ? `?${params.toString()}` : ""}`;
512
- const payload = await requestJson(apiBaseUrl, token, "GET", path24);
539
+ const path25 = `/v1/sprites${params.size ? `?${params.toString()}` : ""}`;
540
+ const payload = await requestJson(apiBaseUrl, token, "GET", path25);
513
541
  const record = payload && typeof payload === "object" ? payload : null;
514
542
  const rawSprites = Array.isArray(record?.sprites) ? record?.sprites : Array.isArray(payload) ? payload : [];
515
543
  const sprites = rawSprites.filter(
@@ -535,9 +563,9 @@ var init_sprites = __esm({
535
563
  }
536
564
  return response;
537
565
  };
538
- requestNdjson = async (apiBaseUrl, token, method, path24, body) => {
539
- const requestId = (0, import_node_crypto2.randomUUID)();
540
- const url = new URL(path24, apiBaseUrl);
566
+ requestNdjson = async (apiBaseUrl, token, method, path25, body) => {
567
+ const requestId = (0, import_node_crypto.randomUUID)();
568
+ const url = new URL(path25, apiBaseUrl);
541
569
  const headers = {
542
570
  authorization: `Bearer ${token}`,
543
571
  "x-request-id": requestId
@@ -549,18 +577,18 @@ var init_sprites = __esm({
549
577
  if (body) {
550
578
  init.body = JSON.stringify(body);
551
579
  }
552
- logger.info("sprites_request", { requestId, method, path: path24 });
580
+ logger.info("sprites_request", { requestId, method, path: path25 });
553
581
  const response = await fetch(url, init);
554
582
  logger.info("sprites_response", {
555
583
  requestId,
556
584
  method,
557
- path: path24,
585
+ path: path25,
558
586
  status: response.status
559
587
  });
560
588
  const text = await response.text();
561
589
  if (!response.ok) {
562
590
  const snippet = text.trim().slice(0, 200);
563
- throw new SpritesApiError(response.status, method, path24, snippet);
591
+ throw new SpritesApiError(response.status, method, path25, snippet);
564
592
  }
565
593
  const lines = text.split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0);
566
594
  const events = [];
@@ -589,14 +617,14 @@ var init_sprites = __esm({
589
617
  return events;
590
618
  };
591
619
  writeFile = async (apiBaseUrl, token, name, remotePath, data) => {
592
- const requestId = (0, import_node_crypto2.randomUUID)();
593
- const path24 = `/v1/sprites/${name}/fs/write`;
594
- const url = new URL(path24, apiBaseUrl);
620
+ const requestId = (0, import_node_crypto.randomUUID)();
621
+ const path25 = `/v1/sprites/${name}/fs/write`;
622
+ const url = new URL(path25, apiBaseUrl);
595
623
  url.searchParams.set("path", remotePath);
596
624
  url.searchParams.set("mkdir", "true");
597
625
  logger.info("sprites_fs_write", {
598
626
  requestId,
599
- path: path24,
627
+ path: path25,
600
628
  name,
601
629
  remotePath,
602
630
  size: data.length
@@ -612,7 +640,7 @@ var init_sprites = __esm({
612
640
  });
613
641
  logger.info("sprites_fs_write_response", {
614
642
  requestId,
615
- path: path24,
643
+ path: path25,
616
644
  status: response.status
617
645
  });
618
646
  if (!response.ok) {
@@ -648,16 +676,16 @@ var init_sprites = __esm({
648
676
  return service;
649
677
  };
650
678
  readFile = async (apiBaseUrl, token, name, options) => {
651
- const requestId = (0, import_node_crypto2.randomUUID)();
652
- const path24 = `/v1/sprites/${name}/fs/read`;
653
- const url = new URL(path24, apiBaseUrl);
679
+ const requestId = (0, import_node_crypto.randomUUID)();
680
+ const path25 = `/v1/sprites/${name}/fs/read`;
681
+ const url = new URL(path25, apiBaseUrl);
654
682
  url.searchParams.set("path", options.path);
655
683
  if (options.workingDir) {
656
684
  url.searchParams.set("workingDir", options.workingDir);
657
685
  }
658
686
  logger.info("sprites_fs_read", {
659
687
  requestId,
660
- path: path24,
688
+ path: path25,
661
689
  name,
662
690
  remotePath: options.path,
663
691
  workingDir: options.workingDir
@@ -671,12 +699,12 @@ var init_sprites = __esm({
671
699
  });
672
700
  logger.info("sprites_fs_read_response", {
673
701
  requestId,
674
- path: path24,
702
+ path: path25,
675
703
  status: response.status
676
704
  });
677
705
  if (!response.ok) {
678
706
  const snippet = (await response.text()).trim().slice(0, 200);
679
- throw new SpritesApiError(response.status, "GET", path24, snippet);
707
+ throw new SpritesApiError(response.status, "GET", path25, snippet);
680
708
  }
681
709
  const buffer = await response.arrayBuffer();
682
710
  return new Uint8Array(buffer);
@@ -759,7 +787,7 @@ var init_sprites = __esm({
759
787
  return services;
760
788
  };
761
789
  internalServicesRequest = async (apiBaseUrl, token, name, command) => {
762
- const requestId = (0, import_node_crypto2.randomUUID)();
790
+ const requestId = (0, import_node_crypto.randomUUID)();
763
791
  const result = await execCommand(
764
792
  apiBaseUrl,
765
793
  token,
@@ -904,8 +932,8 @@ var init_sprites = __esm({
904
932
  return [];
905
933
  };
906
934
  execCommand = async (apiBaseUrl, token, name, cmd, requestId) => {
907
- const path24 = `/v1/sprites/${name}/exec`;
908
- const url = toWsUrl(apiBaseUrl, path24);
935
+ const path25 = `/v1/sprites/${name}/exec`;
936
+ const url = toWsUrl(apiBaseUrl, path25);
909
937
  cmd.forEach((part) => url.searchParams.append("cmd", part));
910
938
  url.searchParams.set("tty", "false");
911
939
  url.searchParams.set("stdin", "false");
@@ -938,7 +966,7 @@ var init_sprites = __esm({
938
966
  const status = response.statusCode ?? 0;
939
967
  logger.warn("sprites_exec_unexpected_response", {
940
968
  requestId,
941
- path: path24,
969
+ path: path25,
942
970
  status,
943
971
  headers: response.headers,
944
972
  bodySnippet: snippet ? snippet.slice(0, 800) : void 0
@@ -952,7 +980,7 @@ var init_sprites = __esm({
952
980
  const finish = (code2) => {
953
981
  if (resolved) return;
954
982
  resolved = true;
955
- logger.info("sprites_exec_response", { requestId, path: path24, status: code2 });
983
+ logger.info("sprites_exec_response", { requestId, path: path25, status: code2 });
956
984
  resolve({
957
985
  exitCode: code2,
958
986
  stdout: Buffer.concat(stdout).toString("utf8"),
@@ -1002,7 +1030,7 @@ var init_sprites = __esm({
1002
1030
  const errorMessage = errorInfo.details && errorInfo.details !== errorInfo.message ? `${errorInfo.message} (${errorInfo.details})` : errorInfo.message;
1003
1031
  logger.warn("sprites_exec_error", {
1004
1032
  requestId,
1005
- path: path24,
1033
+ path: path25,
1006
1034
  errorMessage,
1007
1035
  errorName: errorInfo.name,
1008
1036
  errorCode: errorInfo.code,
@@ -1064,7 +1092,7 @@ var init_sprites = __esm({
1064
1092
  },
1065
1093
  readFile: async (name, options) => readFile(apiBaseUrl, token, name, options),
1066
1094
  exec: async (name, cmd) => {
1067
- const requestId = (0, import_node_crypto2.randomUUID)();
1095
+ const requestId = (0, import_node_crypto.randomUUID)();
1068
1096
  logger.info("sprites_exec", {
1069
1097
  requestId,
1070
1098
  name,
@@ -1457,6 +1485,7 @@ var init_strings = __esm({
1457
1485
  // ../core/src/index.ts
1458
1486
  var init_src = __esm({
1459
1487
  "../core/src/index.ts"() {
1488
+ init_profile();
1460
1489
  init_config();
1461
1490
  init_logger();
1462
1491
  init_paths();
@@ -1633,12 +1662,12 @@ function validateDeploymentUrl(deploymentUrl) {
1633
1662
  }
1634
1663
  }
1635
1664
  function isSimpleObject(value) {
1636
- const isObject3 = typeof value === "object";
1665
+ const isObject5 = typeof value === "object";
1637
1666
  const prototype = Object.getPrototypeOf(value);
1638
1667
  const isSimple = prototype === null || prototype === Object.prototype || // Objects generated from other contexts (e.g. across Node.js `vm` modules) will not satisfy the previous
1639
1668
  // conditions but are still simple objects.
1640
1669
  prototype?.constructor?.name === "Object";
1641
- return isObject3 && isSimple;
1670
+ return isObject5 && isSimple;
1642
1671
  }
1643
1672
  var init_common = __esm({
1644
1673
  "../../node_modules/convex/dist/esm/common/index.js"() {
@@ -3306,12 +3335,12 @@ function createApi(pathParts = []) {
3306
3335
  `API path is expected to be of the form \`api.moduleName.functionName\`. Found: \`${found}\``
3307
3336
  );
3308
3337
  }
3309
- const path24 = pathParts.slice(0, -1).join("/");
3338
+ const path25 = pathParts.slice(0, -1).join("/");
3310
3339
  const exportName = pathParts[pathParts.length - 1];
3311
3340
  if (exportName === "default") {
3312
- return path24;
3341
+ return path25;
3313
3342
  } else {
3314
- return path24 + ":" + exportName;
3343
+ return path25 + ":" + exportName;
3315
3344
  }
3316
3345
  } else if (prop === Symbol.toStringTag) {
3317
3346
  return "FunctionReference";
@@ -6520,16 +6549,16 @@ var init_simple_client_node = __esm({
6520
6549
  });
6521
6550
  require_node_gyp_build = __commonJS2({
6522
6551
  "../common/temp/node_modules/.pnpm/node-gyp-build@4.8.4/node_modules/node-gyp-build/node-gyp-build.js"(exports2, module2) {
6523
- var fs23 = __require("fs");
6524
- var path24 = __require("path");
6525
- var os12 = __require("os");
6552
+ var fs25 = __require("fs");
6553
+ var path25 = __require("path");
6554
+ var os11 = __require("os");
6526
6555
  var runtimeRequire = typeof __webpack_require__ === "function" ? __non_webpack_require__ : __require;
6527
6556
  var vars = process.config && process.config.variables || {};
6528
6557
  var prebuildsOnly = !!process.env.PREBUILDS_ONLY;
6529
6558
  var abi = process.versions.modules;
6530
6559
  var runtime = isElectron() ? "electron" : isNwjs() ? "node-webkit" : "node";
6531
- var arch = process.env.npm_config_arch || os12.arch();
6532
- var platform = process.env.npm_config_platform || os12.platform();
6560
+ var arch = process.env.npm_config_arch || os11.arch();
6561
+ var platform = process.env.npm_config_platform || os11.platform();
6533
6562
  var libc = process.env.LIBC || (isAlpine(platform) ? "musl" : "glibc");
6534
6563
  var armv = process.env.ARM_VERSION || (arch === "arm64" ? "8" : vars.arm_version) || "";
6535
6564
  var uv = (process.versions.uv || "").split(".")[0];
@@ -6538,21 +6567,21 @@ var init_simple_client_node = __esm({
6538
6567
  return runtimeRequire(load2.resolve(dir));
6539
6568
  }
6540
6569
  load2.resolve = load2.path = function(dir) {
6541
- dir = path24.resolve(dir || ".");
6570
+ dir = path25.resolve(dir || ".");
6542
6571
  try {
6543
- var name = runtimeRequire(path24.join(dir, "package.json")).name.toUpperCase().replace(/-/g, "_");
6572
+ var name = runtimeRequire(path25.join(dir, "package.json")).name.toUpperCase().replace(/-/g, "_");
6544
6573
  if (process.env[name + "_PREBUILD"]) dir = process.env[name + "_PREBUILD"];
6545
6574
  } catch (err) {
6546
6575
  }
6547
6576
  if (!prebuildsOnly) {
6548
- var release = getFirst(path24.join(dir, "build/Release"), matchBuild);
6577
+ var release = getFirst(path25.join(dir, "build/Release"), matchBuild);
6549
6578
  if (release) return release;
6550
- var debug = getFirst(path24.join(dir, "build/Debug"), matchBuild);
6579
+ var debug = getFirst(path25.join(dir, "build/Debug"), matchBuild);
6551
6580
  if (debug) return debug;
6552
6581
  }
6553
6582
  var prebuild = resolve(dir);
6554
6583
  if (prebuild) return prebuild;
6555
- var nearby = resolve(path24.dirname(process.execPath));
6584
+ var nearby = resolve(path25.dirname(process.execPath));
6556
6585
  if (nearby) return nearby;
6557
6586
  var target = [
6558
6587
  "platform=" + platform,
@@ -6569,26 +6598,26 @@ var init_simple_client_node = __esm({
6569
6598
  ].filter(Boolean).join(" ");
6570
6599
  throw new Error("No native build was found for " + target + "\n loaded from: " + dir + "\n");
6571
6600
  function resolve(dir2) {
6572
- var tuples = readdirSync(path24.join(dir2, "prebuilds")).map(parseTuple);
6601
+ var tuples = readdirSync(path25.join(dir2, "prebuilds")).map(parseTuple);
6573
6602
  var tuple = tuples.filter(matchTuple(platform, arch)).sort(compareTuples)[0];
6574
6603
  if (!tuple) return;
6575
- var prebuilds = path24.join(dir2, "prebuilds", tuple.name);
6604
+ var prebuilds = path25.join(dir2, "prebuilds", tuple.name);
6576
6605
  var parsed = readdirSync(prebuilds).map(parseTags);
6577
6606
  var candidates = parsed.filter(matchTags(runtime, abi));
6578
6607
  var winner = candidates.sort(compareTags(runtime))[0];
6579
- if (winner) return path24.join(prebuilds, winner.file);
6608
+ if (winner) return path25.join(prebuilds, winner.file);
6580
6609
  }
6581
6610
  };
6582
6611
  function readdirSync(dir) {
6583
6612
  try {
6584
- return fs23.readdirSync(dir);
6613
+ return fs25.readdirSync(dir);
6585
6614
  } catch (err) {
6586
6615
  return [];
6587
6616
  }
6588
6617
  }
6589
6618
  function getFirst(dir, filter) {
6590
6619
  var files = readdirSync(dir).filter(filter);
6591
- return files[0] && path24.join(dir, files[0]);
6620
+ return files[0] && path25.join(dir, files[0]);
6592
6621
  }
6593
6622
  function matchBuild(name) {
6594
6623
  return /\.node$/.test(name);
@@ -6675,7 +6704,7 @@ var init_simple_client_node = __esm({
6675
6704
  return typeof window !== "undefined" && window.process && window.process.type === "renderer";
6676
6705
  }
6677
6706
  function isAlpine(platform2) {
6678
- return platform2 === "linux" && fs23.existsSync("/etc/alpine-release");
6707
+ return platform2 === "linux" && fs25.existsSync("/etc/alpine-release");
6679
6708
  }
6680
6709
  load2.parseTags = parseTags;
6681
6710
  load2.matchTags = matchTags;
@@ -8881,7 +8910,7 @@ var init_simple_client_node = __esm({
8881
8910
  var http3 = __require("http");
8882
8911
  var net3 = __require("net");
8883
8912
  var tls = __require("tls");
8884
- var { randomBytes, createHash: createHash3 } = __require("crypto");
8913
+ var { randomBytes, createHash: createHash2 } = __require("crypto");
8885
8914
  var { Duplex, Readable } = __require("stream");
8886
8915
  var { URL: URL2 } = __require("url");
8887
8916
  var PerMessageDeflate = require_permessage_deflate();
@@ -9538,7 +9567,7 @@ var init_simple_client_node = __esm({
9538
9567
  abortHandshake(websocket, socket, "Invalid Upgrade header");
9539
9568
  return;
9540
9569
  }
9541
- const digest = createHash3("sha1").update(key + GUID).digest("base64");
9570
+ const digest = createHash2("sha1").update(key + GUID).digest("base64");
9542
9571
  if (res.headers["sec-websocket-accept"] !== digest) {
9543
9572
  abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
9544
9573
  return;
@@ -9803,7 +9832,7 @@ var init_simple_client_node = __esm({
9803
9832
  var EventEmitter = __require("events");
9804
9833
  var http3 = __require("http");
9805
9834
  var { Duplex } = __require("stream");
9806
- var { createHash: createHash3 } = __require("crypto");
9835
+ var { createHash: createHash2 } = __require("crypto");
9807
9836
  var extension = require_extension();
9808
9837
  var PerMessageDeflate = require_permessage_deflate();
9809
9838
  var subprotocol = require_subprotocol();
@@ -10098,7 +10127,7 @@ var init_simple_client_node = __esm({
10098
10127
  );
10099
10128
  }
10100
10129
  if (this._state > RUNNING) return abortHandshake(socket, 503);
10101
- const digest = createHash3("sha1").update(key + GUID).digest("base64");
10130
+ const digest = createHash2("sha1").update(key + GUID).digest("base64");
10102
10131
  const headers = [
10103
10132
  "HTTP/1.1 101 Switching Protocols",
10104
10133
  "Upgrade: websocket",
@@ -10657,11 +10686,11 @@ var init_server = __esm({
10657
10686
  });
10658
10687
 
10659
10688
  // ../daemon/src/spritesRegistry.ts
10660
- var import_node_crypto3, import_node_fs, import_promises4, registryGet, registryReplace, registryUpsert, registryUsage, registryRemove, logger4, TOKEN_REFRESH_BUFFER_MS, clientCache, migrationPromise, migrationCompleted, trimEnv, resolveConvexUrl, resolveControlPlaneUrl, requireConvexConfig, decodeJwtPayload, parseTokenExpiresAt, shouldRefreshToken, isUnauthorizedError, clearControlPlaneSession, handleUnauthorized, refreshSession, loadControlPlaneToken, getClient, spritePortsList, logRequest, logResponse, parseTimestamp, pickEarlier, pickLater, mergeBoxes, mergeProjects, mergeRegistry, getRegistryFromConvex, replaceRegistry, migrateLocalRegistry, backfillInitStatus, fetchRegistry, upsertRegistry, recordRegistryUsage, removeRegistryEntry, subscribeSpritePorts;
10689
+ var import_node_crypto2, import_node_fs, import_promises4, registryGet, registryReplace, registryUpsert, registryUsage, registryRemove, logger4, TOKEN_REFRESH_BUFFER_MS, clientCache, migrationPromise, migrationCompleted, trimEnv, resolveConvexUrl, resolveControlPlaneUrl, requireConvexConfig, decodeJwtPayload, parseTokenExpiresAt, shouldRefreshToken, isUnauthorizedError, clearControlPlaneSession, handleUnauthorized, refreshSession, loadControlPlaneToken, getClient, spritePortsList, logRequest, logResponse, parseTimestamp, pickEarlier, pickLater, mergeBoxes, mergeProjects, mergeRegistry, getRegistryFromConvex, replaceRegistry, migrateLocalRegistry, backfillInitStatus, fetchRegistry, upsertRegistry, recordRegistryUsage, removeRegistryEntry, subscribeSpritePorts;
10661
10690
  var init_spritesRegistry = __esm({
10662
10691
  "../daemon/src/spritesRegistry.ts"() {
10663
10692
  "use strict";
10664
- import_node_crypto3 = require("node:crypto");
10693
+ import_node_crypto2 = require("node:crypto");
10665
10694
  import_node_fs = require("node:fs");
10666
10695
  import_promises4 = __toESM(require("node:fs/promises"), 1);
10667
10696
  init_index_node();
@@ -10760,7 +10789,7 @@ var init_spritesRegistry = __esm({
10760
10789
  "Control plane URL is required. Rebuild with CONVEX_SITE_URL/CONVEX_DEPLOYMENT/VITE_CONVEX_URL set."
10761
10790
  );
10762
10791
  }
10763
- const requestId = (0, import_node_crypto3.randomUUID)();
10792
+ const requestId = (0, import_node_crypto2.randomUUID)();
10764
10793
  const url = new URL("/auth/refresh", baseUrl);
10765
10794
  logger4.info("control_plane_request", {
10766
10795
  requestId,
@@ -10855,7 +10884,7 @@ var init_spritesRegistry = __esm({
10855
10884
  };
10856
10885
  spritePortsList = makeFunctionReference("spriteDaemonPorts:listForSprite");
10857
10886
  logRequest = (method, fn) => {
10858
- const requestId = (0, import_node_crypto3.randomUUID)();
10887
+ const requestId = (0, import_node_crypto2.randomUUID)();
10859
10888
  logger4.info("convex_request", { requestId, method, path: fn });
10860
10889
  return requestId;
10861
10890
  };
@@ -11090,11 +11119,11 @@ var init_spritesRegistry = __esm({
11090
11119
  });
11091
11120
 
11092
11121
  // ../daemon/src/ports.ts
11093
- var import_node_crypto4, import_node_net, logger5, MAX_PORT2, MAX_PORT_SHIFT, MIN_UNPRIVILEGED_PORT, AUTO_FORWARD_BLOCKED_PORTS, nextCandidatePort, isRetryableListenError, isIpv6LoopbackAvailable, listenOnPort, PortManager;
11122
+ var import_node_crypto3, import_node_net, logger5, MAX_PORT2, MAX_PORT_SHIFT, MIN_UNPRIVILEGED_PORT, AUTO_FORWARD_BLOCKED_PORTS, nextCandidatePort, isRetryableListenError, isIpv6LoopbackAvailable, listenOnPort, PortManager;
11094
11123
  var init_ports2 = __esm({
11095
11124
  "../daemon/src/ports.ts"() {
11096
11125
  "use strict";
11097
- import_node_crypto4 = require("node:crypto");
11126
+ import_node_crypto3 = require("node:crypto");
11098
11127
  import_node_net = __toESM(require("node:net"), 1);
11099
11128
  init_src();
11100
11129
  init_spritesRegistry();
@@ -11507,7 +11536,7 @@ var init_ports2 = __esm({
11507
11536
  }
11508
11537
  }
11509
11538
  async handleProxyConnection(box, remotePort, socket, forward) {
11510
- const connectionId = (0, import_node_crypto4.randomUUID)();
11539
+ const connectionId = (0, import_node_crypto3.randomUUID)();
11511
11540
  const client = await this.getSpritesClient();
11512
11541
  if (!client) {
11513
11542
  socket.destroy();
@@ -11648,13 +11677,13 @@ __export(src_exports, {
11648
11677
  runDaemon: () => runDaemon,
11649
11678
  startDaemon: () => startDaemon
11650
11679
  });
11651
- var import_node_http, import_promises5, import_node_fs2, import_node_crypto5, import_node_net2, import_node_path5, logger6, startedAt, DAEMON_API_VERSION, DAEMON_FEATURES, allowShutdown, buildBoxSummaries, readBody, readRequestPath, writeJson, handleRequestError, isSocketAlive, ensureRuntimeDir, startDaemon, runDaemon;
11680
+ var import_node_http, import_promises5, import_node_fs2, import_node_crypto4, import_node_net2, import_node_path5, logger6, startedAt, DAEMON_API_VERSION, DAEMON_FEATURES, allowShutdown, buildBoxSummaries, readBody, readRequestPath, writeJson, handleRequestError, isSocketAlive, ensureRuntimeDir, startDaemon, runDaemon;
11652
11681
  var init_src2 = __esm({
11653
11682
  "../daemon/src/index.ts"() {
11654
11683
  import_node_http = require("node:http");
11655
11684
  import_promises5 = __toESM(require("node:fs/promises"));
11656
11685
  import_node_fs2 = require("node:fs");
11657
- import_node_crypto5 = require("node:crypto");
11686
+ import_node_crypto4 = require("node:crypto");
11658
11687
  import_node_net2 = __toESM(require("node:net"));
11659
11688
  import_node_path5 = __toESM(require("node:path"));
11660
11689
  init_src();
@@ -11798,17 +11827,17 @@ var init_src2 = __esm({
11798
11827
  logger6.warn("ports_registry_load_failed", { error: String(error) });
11799
11828
  });
11800
11829
  const server = (0, import_node_http.createServer)((req, res) => {
11801
- const requestId = req.headers["x-request-id"] ?? (0, import_node_crypto5.randomUUID)();
11802
- const path24 = readRequestPath(req);
11830
+ const requestId = req.headers["x-request-id"] ?? (0, import_node_crypto4.randomUUID)();
11831
+ const path25 = readRequestPath(req);
11803
11832
  res.on("finish", () => {
11804
11833
  logger6.info("daemon_request", {
11805
11834
  requestId,
11806
11835
  method: req.method,
11807
- path: path24,
11836
+ path: path25,
11808
11837
  status: res.statusCode
11809
11838
  });
11810
11839
  });
11811
- if (path24 === "/health") {
11840
+ if (path25 === "/health") {
11812
11841
  writeJson(res, 200, {
11813
11842
  ok: true,
11814
11843
  pid: process.pid,
@@ -11817,7 +11846,7 @@ var init_src2 = __esm({
11817
11846
  });
11818
11847
  return;
11819
11848
  }
11820
- if (path24 === "/version") {
11849
+ if (path25 === "/version") {
11821
11850
  writeJson(res, 200, {
11822
11851
  name: "dvbd",
11823
11852
  version: "0.0.0",
@@ -11826,7 +11855,7 @@ var init_src2 = __esm({
11826
11855
  });
11827
11856
  return;
11828
11857
  }
11829
- if (path24 === "/boxes") {
11858
+ if (path25 === "/boxes") {
11830
11859
  void buildBoxSummaries().then((boxes) => {
11831
11860
  writeJson(res, 200, { boxes });
11832
11861
  }).catch((error) => {
@@ -11834,7 +11863,7 @@ var init_src2 = __esm({
11834
11863
  });
11835
11864
  return;
11836
11865
  }
11837
- if (path24 === "/registry/project" && req.method === "GET") {
11866
+ if (path25 === "/registry/project" && req.method === "GET") {
11838
11867
  const url = new URL(req.url ?? "", "http://localhost");
11839
11868
  const fingerprint = url.searchParams.get("fingerprint") ?? "";
11840
11869
  void fetchRegistry().then((registry) => {
@@ -11845,7 +11874,7 @@ var init_src2 = __esm({
11845
11874
  });
11846
11875
  return;
11847
11876
  }
11848
- if (path24 === "/registry/alias" && req.method === "GET") {
11877
+ if (path25 === "/registry/alias" && req.method === "GET") {
11849
11878
  const url = new URL(req.url ?? "", "http://localhost");
11850
11879
  const alias = url.searchParams.get("alias") ?? "";
11851
11880
  void fetchRegistry().then((registry) => {
@@ -11856,7 +11885,7 @@ var init_src2 = __esm({
11856
11885
  });
11857
11886
  return;
11858
11887
  }
11859
- if (path24 === "/registry/upsert" && req.method === "POST") {
11888
+ if (path25 === "/registry/upsert" && req.method === "POST") {
11860
11889
  void readBody(req).then(async (payload) => {
11861
11890
  const project = payload?.project;
11862
11891
  const box = payload?.box;
@@ -11881,7 +11910,7 @@ var init_src2 = __esm({
11881
11910
  });
11882
11911
  return;
11883
11912
  }
11884
- if (path24 === "/registry/usage" && req.method === "POST") {
11913
+ if (path25 === "/registry/usage" && req.method === "POST") {
11885
11914
  void readBody(req).then(async (payload) => {
11886
11915
  const canonical = typeof payload?.canonical === "string" ? payload.canonical : "";
11887
11916
  if (!canonical) {
@@ -11896,7 +11925,7 @@ var init_src2 = __esm({
11896
11925
  });
11897
11926
  return;
11898
11927
  }
11899
- if (path24 === "/registry/remove" && req.method === "POST") {
11928
+ if (path25 === "/registry/remove" && req.method === "POST") {
11900
11929
  void readBody(req).then(async (payload) => {
11901
11930
  const canonical = typeof payload?.canonical === "string" ? payload.canonical : "";
11902
11931
  if (!canonical) {
@@ -11911,12 +11940,12 @@ var init_src2 = __esm({
11911
11940
  });
11912
11941
  return;
11913
11942
  }
11914
- if (path24 === "/ports" && req.method === "GET") {
11943
+ if (path25 === "/ports" && req.method === "GET") {
11915
11944
  const snapshot = portManager.listPorts();
11916
11945
  writeJson(res, 200, snapshot);
11917
11946
  return;
11918
11947
  }
11919
- if (path24 === "/ports/clear" && req.method === "POST") {
11948
+ if (path25 === "/ports/clear" && req.method === "POST") {
11920
11949
  void readBody(req).then((payload) => {
11921
11950
  const box = typeof payload?.box === "string" ? payload.box : void 0;
11922
11951
  if (!box) {
@@ -11930,7 +11959,7 @@ var init_src2 = __esm({
11930
11959
  });
11931
11960
  return;
11932
11961
  }
11933
- if (path24 === "/ports/reload" && req.method === "POST") {
11962
+ if (path25 === "/ports/reload" && req.method === "POST") {
11934
11963
  void readBody(req).then(async (payload) => {
11935
11964
  const box = typeof payload?.box === "string" ? payload.box : void 0;
11936
11965
  if (!box) {
@@ -11944,7 +11973,7 @@ var init_src2 = __esm({
11944
11973
  });
11945
11974
  return;
11946
11975
  }
11947
- if (path24 === "/ports/policy" && req.method === "POST") {
11976
+ if (path25 === "/ports/policy" && req.method === "POST") {
11948
11977
  void readBody(req).then((payload) => {
11949
11978
  const box = typeof payload?.box === "string" ? payload.box : void 0;
11950
11979
  const policy = payload?.policy === "auto" || payload?.policy === "disabled" ? payload.policy : null;
@@ -11961,7 +11990,7 @@ var init_src2 = __esm({
11961
11990
  });
11962
11991
  return;
11963
11992
  }
11964
- if (path24 === "/ports/forward" && req.method === "POST") {
11993
+ if (path25 === "/ports/forward" && req.method === "POST") {
11965
11994
  void readBody(req).then(async (payload) => {
11966
11995
  const box = typeof payload?.box === "string" ? payload.box : void 0;
11967
11996
  const port = typeof payload?.port === "number" ? payload.port : void 0;
@@ -11981,7 +12010,7 @@ var init_src2 = __esm({
11981
12010
  });
11982
12011
  return;
11983
12012
  }
11984
- if (path24 === "/ports/stop" && req.method === "POST") {
12013
+ if (path25 === "/ports/stop" && req.method === "POST") {
11985
12014
  void readBody(req).then((payload) => {
11986
12015
  const box = typeof payload?.box === "string" ? payload.box : void 0;
11987
12016
  const port = typeof payload?.port === "number" ? payload.port : void 0;
@@ -11996,7 +12025,7 @@ var init_src2 = __esm({
11996
12025
  });
11997
12026
  return;
11998
12027
  }
11999
- if (path24 === "/shutdown" && req.method === "POST" && allowShutdown()) {
12028
+ if (path25 === "/shutdown" && req.method === "POST" && allowShutdown()) {
12000
12029
  writeJson(res, 202, { ok: true });
12001
12030
  void close();
12002
12031
  return;
@@ -12069,12 +12098,12 @@ var init_logger2 = __esm({
12069
12098
  });
12070
12099
 
12071
12100
  // src/devbox/controlPlane.ts
12072
- var import_node_http2, import_node_crypto6, import_node_child_process, resolveControlPlaneUrl2, resolveConvexUrl2, openBrowser, requestJson2, startCallbackServer, getControlPlaneUrl, getConvexUrl, signInWithBrowser, spriteTokenGet, spriteTokenSet, spriteDaemonReleaseGet, spriteDaemonTokenIssue, spriteDaemonSessionSummariesList, spriteDaemonSessionsList, withConvexClient, fetchSpriteToken, storeSpriteToken, fetchSpriteDaemonRelease, issueSpriteDaemonToken, listSpriteDaemonSessionSummaries, listSpriteDaemonSessions, signOutControlPlane, refreshControlPlaneSession;
12101
+ var import_node_http2, import_node_crypto5, import_node_child_process, resolveControlPlaneUrl2, resolveConvexUrl2, openBrowser, requestJson2, startCallbackServer, getControlPlaneUrl, getConvexUrl, signInWithBrowser, spriteTokenGet, spriteTokenSet, spriteDaemonReleaseGet, spriteDaemonTokenIssue, spriteDaemonSessionSummariesList, spriteDaemonSessionsList, withConvexClient, fetchSpriteToken, storeSpriteToken, fetchSpriteDaemonRelease, issueSpriteDaemonToken, listSpriteDaemonSessionSummaries, listSpriteDaemonSessions, signOutControlPlane, refreshControlPlaneSession;
12073
12102
  var init_controlPlane = __esm({
12074
12103
  "src/devbox/controlPlane.ts"() {
12075
12104
  "use strict";
12076
12105
  import_node_http2 = __toESM(require("node:http"), 1);
12077
- import_node_crypto6 = require("node:crypto");
12106
+ import_node_crypto5 = require("node:crypto");
12078
12107
  import_node_child_process = require("node:child_process");
12079
12108
  init_index_node();
12080
12109
  init_server();
@@ -12122,9 +12151,9 @@ var init_controlPlane = __esm({
12122
12151
  console.log(url);
12123
12152
  }
12124
12153
  };
12125
- requestJson2 = async (baseUrl, method, path24, body, token) => {
12126
- const requestId = (0, import_node_crypto6.randomUUID)();
12127
- const url = new URL(path24, baseUrl);
12154
+ requestJson2 = async (baseUrl, method, path25, body, token) => {
12155
+ const requestId = (0, import_node_crypto5.randomUUID)();
12156
+ const url = new URL(path25, baseUrl);
12128
12157
  const headers = {
12129
12158
  "x-request-id": requestId
12130
12159
  };
@@ -12311,7 +12340,7 @@ var init_controlPlane = __esm({
12311
12340
  });
12312
12341
  };
12313
12342
  listSpriteDaemonSessionSummaries = async (token, spriteName) => {
12314
- const requestId = (0, import_node_crypto6.randomUUID)();
12343
+ const requestId = (0, import_node_crypto5.randomUUID)();
12315
12344
  logger7.info("control_plane_query", {
12316
12345
  requestId,
12317
12346
  action: "spriteDaemonSessionSummaries:listForSprite",
@@ -12339,7 +12368,7 @@ var init_controlPlane = __esm({
12339
12368
  }
12340
12369
  };
12341
12370
  listSpriteDaemonSessions = async (token, spriteName) => {
12342
- const requestId = (0, import_node_crypto6.randomUUID)();
12371
+ const requestId = (0, import_node_crypto5.randomUUID)();
12343
12372
  logger7.info("control_plane_query", {
12344
12373
  requestId,
12345
12374
  action: "spriteDaemonSessions:listForSprite",
@@ -12397,14 +12426,14 @@ var init_controlPlane = __esm({
12397
12426
  });
12398
12427
 
12399
12428
  // src/devbox/daemonClient.ts
12400
- var import_node_http3, import_node_path6, import_node_child_process2, import_node_crypto7, import_promises6, DAEMON_TIMEOUT_MS, DaemonConnectionError, isConnectionError, requestJson3, requireDaemonFeatures, resolveDaemonCommand, spawnDaemon, waitForHealth, listAlternateSocketPaths, pruneDuplicateDaemons, ensureDaemonRunning, waitForSocketGone, stopDaemon;
12429
+ var import_node_http3, import_node_path6, import_node_child_process2, import_node_crypto6, import_promises6, DAEMON_TIMEOUT_MS, DaemonConnectionError, isConnectionError, requestJson3, requireDaemonFeatures, resolveDaemonCommand, spawnDaemon, waitForHealth, listAlternateSocketPaths, pruneDuplicateDaemons, ensureDaemonRunning, waitForSocketGone, stopDaemon;
12401
12430
  var init_daemonClient = __esm({
12402
12431
  "src/devbox/daemonClient.ts"() {
12403
12432
  "use strict";
12404
12433
  import_node_http3 = __toESM(require("node:http"), 1);
12405
12434
  import_node_path6 = __toESM(require("node:path"), 1);
12406
12435
  import_node_child_process2 = require("node:child_process");
12407
- import_node_crypto7 = require("node:crypto");
12436
+ import_node_crypto6 = require("node:crypto");
12408
12437
  import_promises6 = require("node:fs/promises");
12409
12438
  init_src();
12410
12439
  init_controlPlane();
@@ -12431,7 +12460,7 @@ var init_daemonClient = __esm({
12431
12460
  return code2 === "ENOENT" || code2 === "ECONNREFUSED" || code2 === "EPIPE" || code2 === "ENOTFOUND";
12432
12461
  };
12433
12462
  requestJson3 = async (socketPath, method, requestPath, timeoutMs, body) => {
12434
- const requestId = (0, import_node_crypto7.randomUUID)();
12463
+ const requestId = (0, import_node_crypto6.randomUUID)();
12435
12464
  logger7.info("daemon_request", {
12436
12465
  requestId,
12437
12466
  method,
@@ -12598,7 +12627,7 @@ var init_daemonClient = __esm({
12598
12627
  candidates.add(fallback2);
12599
12628
  const homeDir = process.env.HOME?.trim();
12600
12629
  if (homeDir) {
12601
- candidates.add(import_node_path6.default.join(homeDir, ".devbox", "run", "devboxd.sock"));
12630
+ candidates.add(import_node_path6.default.join(resolveDevboxDir(homeDir), "run", "devboxd.sock"));
12602
12631
  }
12603
12632
  candidates.delete(primary);
12604
12633
  return [...candidates];
@@ -12689,11 +12718,11 @@ var init_daemonClient = __esm({
12689
12718
  });
12690
12719
 
12691
12720
  // src/devbox/auth.ts
12692
- var import_node_crypto8, import_promises7, promptForValue, computeSyncHash, TOKEN_REFRESH_BUFFER_MS2, decodeJwtPayload2, parseTokenExpiresAt2, shouldRefreshToken2, isUnauthorizedError2, clearControlPlaneSession2, updateControlPlaneSession, refreshControlPlaneToken, tokenInstructions, promptForSpritesToken, ensureControlPlaneToken, ensureSpritesToken;
12721
+ var import_node_crypto7, import_promises7, promptForValue, computeSyncHash, TOKEN_REFRESH_BUFFER_MS2, decodeJwtPayload2, parseTokenExpiresAt2, shouldRefreshToken2, isUnauthorizedError2, clearControlPlaneSession2, updateControlPlaneSession, refreshControlPlaneToken, tokenInstructions, promptForSpritesToken, ensureControlPlaneToken, ensureSpritesToken;
12693
12722
  var init_auth = __esm({
12694
12723
  "src/devbox/auth.ts"() {
12695
12724
  "use strict";
12696
- import_node_crypto8 = require("node:crypto");
12725
+ import_node_crypto7 = require("node:crypto");
12697
12726
  import_promises7 = __toESM(require("node:readline/promises"), 1);
12698
12727
  init_logger2();
12699
12728
  init_controlPlane();
@@ -12711,7 +12740,7 @@ var init_auth = __esm({
12711
12740
  };
12712
12741
  computeSyncHash = (token, controlPlaneToken) => {
12713
12742
  if (!controlPlaneToken) return null;
12714
- return (0, import_node_crypto8.createHash)("sha256").update(`${controlPlaneToken}:${token}`).digest("hex");
12743
+ return (0, import_node_crypto7.createHash)("sha256").update(`${controlPlaneToken}:${token}`).digest("hex");
12715
12744
  };
12716
12745
  TOKEN_REFRESH_BUFFER_MS2 = 5 * 60 * 1e3;
12717
12746
  decodeJwtPayload2 = (token) => {
@@ -13497,7 +13526,7 @@ function _supportsColor(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
13497
13526
  return min;
13498
13527
  }
13499
13528
  if (import_node_process.default.platform === "win32") {
13500
- const osRelease = import_node_os4.default.release().split(".");
13529
+ const osRelease = import_node_os2.default.release().split(".");
13501
13530
  if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
13502
13531
  return Number(osRelease[2]) >= 14931 ? 3 : 2;
13503
13532
  }
@@ -13556,11 +13585,11 @@ function createSupportsColor(stream, options = {}) {
13556
13585
  });
13557
13586
  return translateLevel(level);
13558
13587
  }
13559
- var import_node_process, import_node_os4, import_node_tty, env, flagForceColor, supportsColor, supports_color_default;
13588
+ var import_node_process, import_node_os2, import_node_tty, env, flagForceColor, supportsColor, supports_color_default;
13560
13589
  var init_supports_color = __esm({
13561
13590
  "../../node_modules/chalk/source/vendor/supports-color/index.js"() {
13562
13591
  import_node_process = __toESM(require("node:process"), 1);
13563
- import_node_os4 = __toESM(require("node:os"), 1);
13592
+ import_node_os2 = __toESM(require("node:os"), 1);
13564
13593
  import_node_tty = __toESM(require("node:tty"), 1);
13565
13594
  ({ env } = import_node_process.default);
13566
13595
  if (hasFlag("no-color") || hasFlag("no-colors") || hasFlag("color=false") || hasFlag("color=never")) {
@@ -17542,17 +17571,17 @@ var init_t = __esm({
17542
17571
  });
17543
17572
 
17544
17573
  // src/devbox/completions/cache.ts
17545
- var import_promises8, import_node_os5, import_node_path7, resolveCacheDir, resolveCompletionsDir, resolveCompletionCachePath, ensureDir, writeJsonAtomic2, createEmptyCache, loadCompletionCache, saveCompletionCache, dedupeSessionEntries, mergeSessionEntries, updateCompletionCacheSessions, updateCompletionCacheSessionsFromMap, updateCompletionCacheSessionsFromViews, updateCompletionCacheAlias;
17574
+ var import_promises8, import_node_os3, import_node_path7, resolveCacheDir, resolveCompletionsDir, resolveCompletionCachePath, ensureDir, writeJsonAtomic2, createEmptyCache, loadCompletionCache, saveCompletionCache, dedupeSessionEntries, mergeSessionEntries, updateCompletionCacheSessions, updateCompletionCacheSessionsFromMap, updateCompletionCacheSessionsFromViews, updateCompletionCacheAlias;
17546
17575
  var init_cache = __esm({
17547
17576
  "src/devbox/completions/cache.ts"() {
17548
17577
  "use strict";
17549
17578
  import_promises8 = __toESM(require("node:fs/promises"), 1);
17550
- import_node_os5 = __toESM(require("node:os"), 1);
17579
+ import_node_os3 = __toESM(require("node:os"), 1);
17551
17580
  import_node_path7 = __toESM(require("node:path"), 1);
17552
17581
  init_src();
17553
- resolveCacheDir = (homeDir = import_node_os5.default.homedir()) => import_node_path7.default.join(resolveDevboxDir(homeDir), "cache");
17554
- resolveCompletionsDir = (homeDir = import_node_os5.default.homedir()) => import_node_path7.default.join(resolveDevboxDir(homeDir), "completions");
17555
- resolveCompletionCachePath = (homeDir = import_node_os5.default.homedir()) => import_node_path7.default.join(resolveCacheDir(homeDir), "completions.json");
17582
+ resolveCacheDir = (homeDir = import_node_os3.default.homedir()) => import_node_path7.default.join(resolveDevboxDir(homeDir), "cache");
17583
+ resolveCompletionsDir = (homeDir = import_node_os3.default.homedir()) => import_node_path7.default.join(resolveDevboxDir(homeDir), "completions");
17584
+ resolveCompletionCachePath = (homeDir = import_node_os3.default.homedir()) => import_node_path7.default.join(resolveCacheDir(homeDir), "completions.json");
17556
17585
  ensureDir = async (dir) => {
17557
17586
  await import_promises8.default.mkdir(dir, { recursive: true, mode: 448 });
17558
17587
  try {
@@ -17656,12 +17685,12 @@ var init_cache = __esm({
17656
17685
  });
17657
17686
 
17658
17687
  // src/devbox/completions/index.ts
17659
- var import_promises9, import_node_os6, import_node_path8, import_promises10, SESSION_TTL_MS, REMOTE_ATTEMPT_INTERVAL_MS, REMOTE_TIMEOUT_MS, PRIME_SESSION_LIMIT, ALIAS_TTL_MS, ALIAS_ATTEMPT_INTERVAL_MS, RC_BEGIN, RC_END, SUPPORTED_SHELLS, normalizeShell, resolveShellFromEnv, nowIso, isStale, readTextFile, writeTextFile, captureConsole, createCompletionRoot, parseCompletionContext, createSpriteAuth, fetchWithTimeout, fetchRemoteSessionMap, shouldAttemptRemote, mergeAliasMaps, refreshAliasesFromDaemonIfNeeded, refreshRemoteSessionsIfNeeded, primeCompletionCache, loadCompletionData, resolveShellPaths, buildRcBlock, updateRcFile, removeRcBlock, generateCompletionScript, installCompletions, uninstallCompletions, detectStatusForShell, resolveCompletionStatus, maybeAutoUpdateCompletions, promptYesNo, maybeOfferCompletionsInstall, usage, parseCompletionsArgs, runCompletions, runComplete, recordCompletionAliases, recordCompletionSessionsFromMap, recordCompletionSessionsFromViews;
17688
+ var import_promises9, import_node_os4, import_node_path8, import_promises10, SESSION_TTL_MS, REMOTE_ATTEMPT_INTERVAL_MS, REMOTE_TIMEOUT_MS, PRIME_SESSION_LIMIT, ALIAS_TTL_MS, ALIAS_ATTEMPT_INTERVAL_MS, resolveCliName, rcMarkers, SUPPORTED_SHELLS, normalizeShell, resolveShellFromEnv, nowIso, isStale, readTextFile, writeTextFile, captureConsole, createCompletionRoot, parseCompletionContext, createSpriteAuth, fetchWithTimeout, fetchRemoteSessionMap, shouldAttemptRemote, mergeAliasMaps, refreshAliasesFromDaemonIfNeeded, refreshRemoteSessionsIfNeeded, primeCompletionCache, loadCompletionData, resolveShellPaths, buildRcBlock, updateRcFile, removeRcBlock, generateCompletionScript, installCompletions, uninstallCompletions, detectStatusForShell, resolveCompletionStatus, maybeAutoUpdateCompletions, promptYesNo, maybeOfferCompletionsInstall, usage, parseCompletionsArgs, runCompletions, runComplete, recordCompletionAliases, recordCompletionSessionsFromMap, recordCompletionSessionsFromViews;
17660
17689
  var init_completions = __esm({
17661
17690
  "src/devbox/completions/index.ts"() {
17662
17691
  "use strict";
17663
17692
  import_promises9 = __toESM(require("node:fs/promises"), 1);
17664
- import_node_os6 = __toESM(require("node:os"), 1);
17693
+ import_node_os4 = __toESM(require("node:os"), 1);
17665
17694
  import_node_path8 = __toESM(require("node:path"), 1);
17666
17695
  import_promises10 = __toESM(require("node:readline/promises"), 1);
17667
17696
  init_t();
@@ -17674,8 +17703,16 @@ var init_completions = __esm({
17674
17703
  PRIME_SESSION_LIMIT = 5;
17675
17704
  ALIAS_TTL_MS = 6e4;
17676
17705
  ALIAS_ATTEMPT_INTERVAL_MS = 3e4;
17677
- RC_BEGIN = "# >>> dvb completions >>>";
17678
- RC_END = "# <<< dvb completions <<<";
17706
+ resolveCliName = () => {
17707
+ const raw = process.env.DEVBOX_CLI_NAME?.trim();
17708
+ if (!raw) return "dvb";
17709
+ const normalized = raw.replace(/[^A-Za-z0-9_-]+/g, "").slice(0, 32);
17710
+ return normalized.length > 0 ? normalized : "dvb";
17711
+ };
17712
+ rcMarkers = (cliName) => ({
17713
+ begin: `# >>> ${cliName} completions >>>`,
17714
+ end: `# <<< ${cliName} completions <<<`
17715
+ });
17679
17716
  SUPPORTED_SHELLS = ["bash", "zsh", "fish"];
17680
17717
  normalizeShell = (value) => {
17681
17718
  if (!value) return null;
@@ -18117,31 +18154,37 @@ var init_completions = __esm({
18117
18154
  };
18118
18155
  };
18119
18156
  resolveShellPaths = (shell) => {
18120
- const home = import_node_os6.default.homedir();
18157
+ const cliName = resolveCliName();
18158
+ const home = import_node_os4.default.homedir();
18121
18159
  if (shell === "fish") {
18122
18160
  const configHome = process.env.XDG_CONFIG_HOME ?? import_node_path8.default.join(home, ".config");
18123
18161
  return {
18124
- scriptPath: import_node_path8.default.join(configHome, "fish", "completions", "dvb.fish"),
18162
+ scriptPath: import_node_path8.default.join(
18163
+ configHome,
18164
+ "fish",
18165
+ "completions",
18166
+ `${cliName}.fish`
18167
+ ),
18125
18168
  rcPath: void 0
18126
18169
  };
18127
18170
  }
18128
18171
  const completionsDir = resolveCompletionsDir(home);
18129
- const scriptPath = shell === "zsh" ? import_node_path8.default.join(completionsDir, "dvb.zsh") : import_node_path8.default.join(completionsDir, "dvb.bash");
18172
+ const scriptPath = shell === "zsh" ? import_node_path8.default.join(completionsDir, `${cliName}.zsh`) : import_node_path8.default.join(completionsDir, `${cliName}.bash`);
18130
18173
  const rcPath = shell === "zsh" ? import_node_path8.default.join(process.env.ZDOTDIR ?? home, ".zshrc") : import_node_path8.default.join(home, ".bashrc");
18131
18174
  return { scriptPath, rcPath };
18132
18175
  };
18133
- buildRcBlock = (scriptPath) => [
18134
- RC_BEGIN,
18176
+ buildRcBlock = (scriptPath, markers) => [
18177
+ markers.begin,
18135
18178
  `if [ -f "${scriptPath}" ]; then`,
18136
18179
  ` source "${scriptPath}"`,
18137
18180
  "fi",
18138
- RC_END
18181
+ markers.end
18139
18182
  ].join("\n");
18140
- updateRcFile = async (rcPath, block) => {
18183
+ updateRcFile = async (rcPath, block, markers) => {
18141
18184
  const existing = await readTextFile(rcPath) ?? "";
18142
- if (existing.includes(RC_BEGIN) && existing.includes(RC_END)) {
18185
+ if (existing.includes(markers.begin) && existing.includes(markers.end)) {
18143
18186
  const updated = existing.replace(
18144
- new RegExp(`${RC_BEGIN}[\\s\\S]*?${RC_END}`, "m"),
18187
+ new RegExp(`${markers.begin}[\\s\\S]*?${markers.end}`, "m"),
18145
18188
  block
18146
18189
  );
18147
18190
  await writeTextFile(rcPath, updated);
@@ -18151,17 +18194,20 @@ var init_completions = __esm({
18151
18194
  await writeTextFile(rcPath, `${existing}${suffix}${block}
18152
18195
  `);
18153
18196
  };
18154
- removeRcBlock = async (rcPath) => {
18197
+ removeRcBlock = async (rcPath, markers) => {
18155
18198
  const existing = await readTextFile(rcPath);
18156
18199
  if (!existing) return;
18157
- if (!existing.includes(RC_BEGIN) || !existing.includes(RC_END)) return;
18200
+ if (!existing.includes(markers.begin) || !existing.includes(markers.end)) {
18201
+ return;
18202
+ }
18158
18203
  const updated = existing.replace(
18159
- new RegExp(`\\n?${RC_BEGIN}[\\s\\S]*?${RC_END}\\n?`, "m"),
18204
+ new RegExp(`\\n?${markers.begin}[\\s\\S]*?${markers.end}\\n?`, "m"),
18160
18205
  "\n"
18161
18206
  );
18162
18207
  await writeTextFile(rcPath, updated.trimEnd() + "\n");
18163
18208
  };
18164
18209
  generateCompletionScript = (shell) => {
18210
+ const cliName = resolveCliName();
18165
18211
  const root = createCompletionRoot({
18166
18212
  boxes: [],
18167
18213
  boxSessionNames: [],
@@ -18169,15 +18215,17 @@ var init_completions = __esm({
18169
18215
  sessionRefs: []
18170
18216
  });
18171
18217
  return captureConsole(() => {
18172
- root.setup("dvb", "dvb", shell);
18218
+ root.setup(cliName, cliName, shell);
18173
18219
  });
18174
18220
  };
18175
18221
  installCompletions = async (shell) => {
18222
+ const cliName = resolveCliName();
18223
+ const markers = rcMarkers(cliName);
18176
18224
  const { scriptPath, rcPath } = resolveShellPaths(shell);
18177
18225
  const script = generateCompletionScript(shell);
18178
18226
  await writeTextFile(scriptPath, script);
18179
18227
  if (rcPath) {
18180
- await updateRcFile(rcPath, buildRcBlock(scriptPath));
18228
+ await updateRcFile(rcPath, buildRcBlock(scriptPath, markers), markers);
18181
18229
  }
18182
18230
  try {
18183
18231
  await primeCompletionCache();
@@ -18195,13 +18243,15 @@ var init_completions = __esm({
18195
18243
  return { scriptPath, rcPath };
18196
18244
  };
18197
18245
  uninstallCompletions = async (shell) => {
18246
+ const cliName = resolveCliName();
18247
+ const markers = rcMarkers(cliName);
18198
18248
  const { scriptPath, rcPath } = resolveShellPaths(shell);
18199
18249
  try {
18200
18250
  await import_promises9.default.unlink(scriptPath);
18201
18251
  } catch {
18202
18252
  }
18203
18253
  if (rcPath) {
18204
- await removeRcBlock(rcPath);
18254
+ await removeRcBlock(rcPath, markers);
18205
18255
  }
18206
18256
  const cache = await loadCompletionCache();
18207
18257
  if (cache.install?.shell === shell) {
@@ -18211,13 +18261,15 @@ var init_completions = __esm({
18211
18261
  return { scriptPath, rcPath };
18212
18262
  };
18213
18263
  detectStatusForShell = async (shell) => {
18264
+ const cliName = resolveCliName();
18265
+ const markers = rcMarkers(cliName);
18214
18266
  const { scriptPath, rcPath } = resolveShellPaths(shell);
18215
18267
  const scriptExists = Boolean(await readTextFile(scriptPath));
18216
18268
  let rcConfigured = scriptExists;
18217
18269
  if (rcPath) {
18218
18270
  const rcContents = await readTextFile(rcPath);
18219
18271
  rcConfigured = Boolean(
18220
- rcContents?.includes(RC_BEGIN) && rcContents?.includes(RC_END)
18272
+ rcContents?.includes(markers.begin) && rcContents?.includes(markers.end)
18221
18273
  );
18222
18274
  }
18223
18275
  const status = { shell, scriptPath, scriptExists, rcConfigured };
@@ -18282,11 +18334,12 @@ var init_completions = __esm({
18282
18334
  }
18283
18335
  };
18284
18336
  usage = () => {
18337
+ const cliName = resolveCliName();
18285
18338
  console.log("Usage:");
18286
- console.log(" dvb completions status");
18287
- console.log(" dvb completions install [--shell <bash|zsh|fish>]");
18288
- console.log(" dvb completions uninstall [--shell <bash|zsh|fish>]");
18289
- console.log(" dvb completions generate <bash|zsh|fish>");
18339
+ console.log(` ${cliName} completions status`);
18340
+ console.log(` ${cliName} completions install [--shell <bash|zsh|fish>]`);
18341
+ console.log(` ${cliName} completions uninstall [--shell <bash|zsh|fish>]`);
18342
+ console.log(` ${cliName} completions generate <bash|zsh|fish>`);
18290
18343
  };
18291
18344
  parseCompletionsArgs = (args) => {
18292
18345
  const parsed = {
@@ -18730,12 +18783,12 @@ var init_sessionUtils = __esm({
18730
18783
  });
18731
18784
 
18732
18785
  // src/devbox/commands/connect.ts
18733
- var import_node_child_process3, import_node_crypto9, import_node_path9, import_node_readline, import_promises12, DEFAULT_TTY_COLS, DEFAULT_TTY_ROWS, openBrowser2, warnSetupStatus, resolveTtyEnv, formatEnvExports, parseEnvSize, readStreamSize, resolveTtySize, resolveSessionEnv, parseReachabilityState, runCommand, checkReachability, watchReachabilityWithScutil, watchReachabilityWithNotifyutil, waitForNetworkOnline, parseConnectArgs, parseConnectTarget, buildLoggingCommand, CONNECT_SHELL, confirmNewSession, promptRenameSession, HEARTBEAT_INTERVAL_MS, HEARTBEAT_TIMEOUT_MS, INPUT_PROBE_TIMEOUT_MS, WS_OPEN_STATE, streamExecSession, runConnect;
18786
+ var import_node_child_process3, import_node_crypto8, import_node_path9, import_node_readline, import_promises12, DEFAULT_TTY_COLS, DEFAULT_TTY_ROWS, openBrowser2, warnSetupStatus, resolveTtyEnv, formatEnvExports, parseEnvSize, readStreamSize, resolveTtySize, resolveSessionEnv, parseReachabilityState, runCommand, checkReachability, watchReachabilityWithScutil, watchReachabilityWithNotifyutil, waitForNetworkOnline, parseConnectArgs, parseConnectTarget, buildLoggingCommand, CONNECT_SHELL, confirmNewSession, promptRenameSession, HEARTBEAT_INTERVAL_MS, HEARTBEAT_TIMEOUT_MS, INPUT_PROBE_TIMEOUT_MS, WS_OPEN_STATE, streamExecSession, runConnect;
18734
18787
  var init_connect = __esm({
18735
18788
  "src/devbox/commands/connect.ts"() {
18736
18789
  "use strict";
18737
18790
  import_node_child_process3 = require("node:child_process");
18738
- import_node_crypto9 = require("node:crypto");
18791
+ import_node_crypto8 = require("node:crypto");
18739
18792
  import_node_path9 = require("node:path");
18740
18793
  import_node_readline = require("node:readline");
18741
18794
  import_promises12 = __toESM(require("node:readline/promises"), 1);
@@ -19760,7 +19813,7 @@ var init_connect = __esm({
19760
19813
  const weztermPane = process.env.WEZTERM_PANE?.trim() || "";
19761
19814
  const weztermSocket = process.env.WEZTERM_UNIX_SOCKET?.trim() || "";
19762
19815
  const weztermSessionId = weztermPane ? `wezterm:${weztermPane}${weztermSocket ? `:${(0, import_node_path9.basename)(weztermSocket)}` : ""}` : "";
19763
- const terminalSessionId = process.env.DEVBOX_TERM_SESSION_ID?.trim() || weztermSessionId || process.env.TERM_SESSION_ID?.trim() || process.env.ITERM_SESSION_ID?.trim() || `dvb-${(0, import_node_crypto9.randomUUID)()}`;
19816
+ const terminalSessionId = process.env.DEVBOX_TERM_SESSION_ID?.trim() || weztermSessionId || process.env.TERM_SESSION_ID?.trim() || process.env.ITERM_SESSION_ID?.trim() || `dvb-${(0, import_node_crypto8.randomUUID)()}`;
19764
19817
  const execCommand2 = (() => {
19765
19818
  const sessionEnv = resolveSessionEnv(terminalSessionId);
19766
19819
  const ttyEnv = isTty ? resolveTtyEnv(terminalSessionId) : null;
@@ -20092,17 +20145,65 @@ var init_daemon = __esm({
20092
20145
  });
20093
20146
 
20094
20147
  // src/devbox/commands/destroy.ts
20095
- var import_promises13, parseDestroyArgs, confirmDestroy, runDestroy;
20148
+ var import_promises13, import_promises14, import_node_os5, import_node_path10, isObject, readCanonicalFromJson, cleanupLocalProjectDirsForBox, parseDestroyArgs, confirmDestroy, runDestroy;
20096
20149
  var init_destroy = __esm({
20097
20150
  "src/devbox/commands/destroy.ts"() {
20098
20151
  "use strict";
20099
20152
  import_promises13 = __toESM(require("node:readline/promises"), 1);
20100
- init_src();
20153
+ import_promises14 = __toESM(require("node:fs/promises"), 1);
20154
+ import_node_os5 = __toESM(require("node:os"), 1);
20155
+ import_node_path10 = __toESM(require("node:path"), 1);
20101
20156
  init_src();
20102
20157
  init_daemonClient();
20103
20158
  init_auth();
20104
20159
  init_statusLine();
20105
20160
  init_boxSelect();
20161
+ isObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
20162
+ readCanonicalFromJson = async (filePath) => {
20163
+ try {
20164
+ const raw = await import_promises14.default.readFile(filePath, "utf8");
20165
+ const parsed = JSON.parse(raw);
20166
+ if (!isObject(parsed)) return null;
20167
+ const canonical = parsed.canonical;
20168
+ if (typeof canonical !== "string") return null;
20169
+ const trimmed = canonical.trim();
20170
+ return trimmed.length > 0 ? trimmed : null;
20171
+ } catch {
20172
+ return null;
20173
+ }
20174
+ };
20175
+ cleanupLocalProjectDirsForBox = async ({
20176
+ canonical,
20177
+ homeDir
20178
+ }) => {
20179
+ const projectsDir = resolveDevboxProjectsDir(homeDir);
20180
+ let entries = [];
20181
+ try {
20182
+ const dirents = await import_promises14.default.readdir(projectsDir, { withFileTypes: true });
20183
+ entries = dirents.map((entry) => ({
20184
+ name: entry.name,
20185
+ isDir: entry.isDirectory()
20186
+ }));
20187
+ } catch {
20188
+ return { removed: 0 };
20189
+ }
20190
+ let removed = 0;
20191
+ for (const entry of entries) {
20192
+ if (!entry.isDir) continue;
20193
+ const projectDir = import_node_path10.default.join(projectsDir, entry.name);
20194
+ const markerCanonical = await readCanonicalFromJson(
20195
+ import_node_path10.default.join(projectDir, "box.json")
20196
+ );
20197
+ const stateCanonical = markerCanonical ?? await readCanonicalFromJson(import_node_path10.default.join(projectDir, "init-state.json"));
20198
+ if (stateCanonical !== canonical) continue;
20199
+ try {
20200
+ await import_promises14.default.rm(projectDir, { recursive: true, force: true });
20201
+ removed += 1;
20202
+ } catch {
20203
+ }
20204
+ }
20205
+ return { removed };
20206
+ };
20106
20207
  parseDestroyArgs = (args) => {
20107
20208
  const parsed = { force: false, json: false };
20108
20209
  for (let i2 = 0; i2 < args.length; i2 += 1) {
@@ -20232,6 +20333,12 @@ var init_destroy = __esm({
20232
20333
  "dvbd failed to clear local state. Restart dvbd and retry."
20233
20334
  );
20234
20335
  }
20336
+ status.stage("Cleaning local project state");
20337
+ try {
20338
+ const homeDir = process.env.HOME ?? import_node_os5.default.homedir();
20339
+ await cleanupLocalProjectDirsForBox({ canonical, homeDir });
20340
+ } catch {
20341
+ }
20235
20342
  status.stop();
20236
20343
  if (parsed.json) {
20237
20344
  console.log(JSON.stringify({ ok: true, canonical }, null, 2));
@@ -20252,11 +20359,11 @@ var init_destroy = __esm({
20252
20359
  });
20253
20360
 
20254
20361
  // src/devbox/commands/agent.ts
20255
- var import_promises14, resolveSummaryLabel, agentLabel, usageForAgent, parseAgentArgs, parseClaudeTerminalSessionId, decideResumeSelection, resolveCanonical, loadResumeSessions, promptForSession, buildResumeCommand, buildStartCommand, runAgent, runCodex, runClaude;
20362
+ var import_promises15, resolveSummaryLabel, agentLabel, usageForAgent, parseAgentArgs, parseClaudeTerminalSessionId, decideResumeSelection, resolveCanonical, loadResumeSessions, promptForSession, buildResumeCommand, buildStartCommand, runAgent, runCodex, runClaude;
20256
20363
  var init_agent = __esm({
20257
20364
  "src/devbox/commands/agent.ts"() {
20258
20365
  "use strict";
20259
- import_promises14 = __toESM(require("node:readline/promises"), 1);
20366
+ import_promises15 = __toESM(require("node:readline/promises"), 1);
20260
20367
  init_src();
20261
20368
  init_auth();
20262
20369
  init_controlPlane();
@@ -20429,7 +20536,7 @@ var init_agent = __esm({
20429
20536
  console.log(` ${line}`);
20430
20537
  }
20431
20538
  console.log("");
20432
- const rl = import_promises14.default.createInterface({
20539
+ const rl = import_promises15.default.createInterface({
20433
20540
  input: process.stdin,
20434
20541
  output: process.stdout
20435
20542
  });
@@ -21702,12 +21809,14 @@ var init_args = __esm({
21702
21809
  });
21703
21810
 
21704
21811
  // src/devbox/commands/init/repo.ts
21705
- var import_node_child_process4, import_node_path10, buildSpawnEnv, runCommand2, runCommandRaw, findRepoRoot, readRepoOrigin, readRootCommit, resolveGitCommonDir, readHeadState, readNullSeparatedPaths, readWorktreeState, confirmCopyWorktree, readGlobalGitConfigFiles, mapGlobalGitConfigDestinations;
21812
+ var import_node_crypto9, import_node_child_process4, import_node_path11, import_promises16, buildSpawnEnv, runCommand2, runCommandRaw, findRepoRoot, readRepoOrigin, isObject2, readLegacyRepoFingerprint, readLocalGitConfigValue, writeLocalGitConfigValue, ensureRepoProjectId, resolveGitCommonDir, readHeadState, readNullSeparatedPaths, readWorktreeState, confirmCopyWorktree, readGlobalGitConfigFiles, mapGlobalGitConfigDestinations;
21706
21813
  var init_repo2 = __esm({
21707
21814
  "src/devbox/commands/init/repo.ts"() {
21708
21815
  "use strict";
21816
+ import_node_crypto9 = require("node:crypto");
21709
21817
  import_node_child_process4 = require("node:child_process");
21710
- import_node_path10 = __toESM(require("node:path"), 1);
21818
+ import_node_path11 = __toESM(require("node:path"), 1);
21819
+ import_promises16 = __toESM(require("node:fs/promises"), 1);
21711
21820
  init_dist2();
21712
21821
  buildSpawnEnv = (options) => {
21713
21822
  if (!options?.env) return process.env;
@@ -21767,15 +21876,62 @@ var init_repo2 = __esm({
21767
21876
  return null;
21768
21877
  }
21769
21878
  };
21770
- readRootCommit = async (cwd) => runCommand2(cwd, "git", ["rev-list", "--max-parents=0", "HEAD"]);
21879
+ isObject2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
21880
+ readLegacyRepoFingerprint = async (repoRoot) => {
21881
+ const legacyDir = import_node_path11.default.join(repoRoot, ".devbox");
21882
+ const candidates = [
21883
+ import_node_path11.default.join(legacyDir, "box.json"),
21884
+ import_node_path11.default.join(legacyDir, "init-state.json")
21885
+ ];
21886
+ for (const filePath of candidates) {
21887
+ try {
21888
+ const raw = await import_promises16.default.readFile(filePath, "utf8");
21889
+ const parsed = JSON.parse(raw);
21890
+ if (!isObject2(parsed)) continue;
21891
+ const fingerprint = parsed.fingerprint;
21892
+ if (typeof fingerprint !== "string") continue;
21893
+ const trimmed = fingerprint.trim();
21894
+ if (trimmed.length === 0) continue;
21895
+ return trimmed;
21896
+ } catch {
21897
+ }
21898
+ }
21899
+ return null;
21900
+ };
21901
+ readLocalGitConfigValue = async (repoRoot, key) => {
21902
+ try {
21903
+ const value = await runCommand2(repoRoot, "git", [
21904
+ "config",
21905
+ "--local",
21906
+ "--get",
21907
+ key
21908
+ ]);
21909
+ const trimmed = value.trim();
21910
+ return trimmed.length > 0 ? trimmed : null;
21911
+ } catch {
21912
+ return null;
21913
+ }
21914
+ };
21915
+ writeLocalGitConfigValue = async (repoRoot, key, value) => {
21916
+ await runCommand2(repoRoot, "git", ["config", "--local", key, value]);
21917
+ };
21918
+ ensureRepoProjectId = async (repoRoot) => {
21919
+ const key = "devbox.projectId";
21920
+ const existing = await readLocalGitConfigValue(repoRoot, key);
21921
+ if (existing) return existing;
21922
+ const legacyFingerprint = await readLegacyRepoFingerprint(repoRoot);
21923
+ const created = legacyFingerprint ?? (0, import_node_crypto9.randomUUID)();
21924
+ await writeLocalGitConfigValue(repoRoot, key, created);
21925
+ return created;
21926
+ };
21771
21927
  resolveGitCommonDir = async (repoRoot) => {
21772
21928
  const gitDir = await runCommand2(repoRoot, "git", ["rev-parse", "--git-dir"]);
21773
21929
  const commonDir = await runCommand2(repoRoot, "git", [
21774
21930
  "rev-parse",
21775
21931
  "--git-common-dir"
21776
21932
  ]);
21777
- const resolvedGitDir = import_node_path10.default.isAbsolute(gitDir) ? gitDir : import_node_path10.default.resolve(repoRoot, gitDir);
21778
- const resolvedCommonDir = import_node_path10.default.isAbsolute(commonDir) ? commonDir : import_node_path10.default.resolve(repoRoot, commonDir);
21933
+ const resolvedGitDir = import_node_path11.default.isAbsolute(gitDir) ? gitDir : import_node_path11.default.resolve(repoRoot, gitDir);
21934
+ const resolvedCommonDir = import_node_path11.default.isAbsolute(commonDir) ? commonDir : import_node_path11.default.resolve(repoRoot, commonDir);
21779
21935
  return { gitDir: resolvedGitDir, commonDir: resolvedCommonDir };
21780
21936
  };
21781
21937
  readHeadState = async (repoRoot) => {
@@ -21859,10 +22015,10 @@ var init_repo2 = __esm({
21859
22015
  mapGlobalGitConfigDestinations = (sources, homeDir) => {
21860
22016
  const mapped = [];
21861
22017
  for (const source of sources) {
21862
- if (!import_node_path10.default.isAbsolute(source)) continue;
21863
- if (source === homeDir || source.startsWith(`${homeDir}${import_node_path10.default.sep}`)) {
21864
- const relative = import_node_path10.default.relative(homeDir, source);
21865
- const dest = import_node_path10.default.posix.join("/home/sprite", ...relative.split(import_node_path10.default.sep));
22018
+ if (!import_node_path11.default.isAbsolute(source)) continue;
22019
+ if (source === homeDir || source.startsWith(`${homeDir}${import_node_path11.default.sep}`)) {
22020
+ const relative = import_node_path11.default.relative(homeDir, source);
22021
+ const dest = import_node_path11.default.posix.join("/home/sprite", ...relative.split(import_node_path11.default.sep));
21866
22022
  mapped.push({ source, dest });
21867
22023
  }
21868
22024
  }
@@ -21872,12 +22028,12 @@ var init_repo2 = __esm({
21872
22028
  });
21873
22029
 
21874
22030
  // src/devbox/commands/init/packaging.ts
21875
- var import_node_path11, import_promises15, macCopyfileDisabledEnv, runTar, createGitMetaArchive, writePatch, createFileListArchive;
22031
+ var import_node_path12, import_promises17, macCopyfileDisabledEnv, runTar, createGitMetaArchive, writePatch, createFileListArchive;
21876
22032
  var init_packaging = __esm({
21877
22033
  "src/devbox/commands/init/packaging.ts"() {
21878
22034
  "use strict";
21879
- import_node_path11 = __toESM(require("node:path"), 1);
21880
- import_promises15 = __toESM(require("node:fs/promises"), 1);
22035
+ import_node_path12 = __toESM(require("node:path"), 1);
22036
+ import_promises17 = __toESM(require("node:fs/promises"), 1);
21881
22037
  init_repo2();
21882
22038
  macCopyfileDisabledEnv = process.platform === "darwin" ? { COPYFILE_DISABLE: "1" } : void 0;
21883
22039
  runTar = async (cwd, args) => runCommand2(
@@ -21890,7 +22046,7 @@ var init_packaging = __esm({
21890
22046
  const entries = [];
21891
22047
  const pushIfExists = async (entry) => {
21892
22048
  try {
21893
- await import_promises15.default.stat(import_node_path11.default.join(gitCommonDir, entry));
22049
+ await import_promises17.default.stat(import_node_path12.default.join(gitCommonDir, entry));
21894
22050
  entries.push(entry);
21895
22051
  } catch {
21896
22052
  }
@@ -21899,25 +22055,25 @@ var init_packaging = __esm({
21899
22055
  await pushIfExists("packed-refs");
21900
22056
  await pushIfExists("logs");
21901
22057
  await pushIfExists("config");
21902
- await pushIfExists(import_node_path11.default.join("info", "exclude"));
21903
- await pushIfExists(import_node_path11.default.join("info", "attributes"));
21904
- await pushIfExists(import_node_path11.default.join("info", "sparse-checkout"));
22058
+ await pushIfExists(import_node_path12.default.join("info", "exclude"));
22059
+ await pushIfExists(import_node_path12.default.join("info", "attributes"));
22060
+ await pushIfExists(import_node_path12.default.join("info", "sparse-checkout"));
21905
22061
  await pushIfExists("modules");
21906
22062
  try {
21907
- const hooksDir = import_node_path11.default.join(gitCommonDir, "hooks");
21908
- const hookEntries = await import_promises15.default.readdir(hooksDir);
22063
+ const hooksDir = import_node_path12.default.join(gitCommonDir, "hooks");
22064
+ const hookEntries = await import_promises17.default.readdir(hooksDir);
21909
22065
  for (const entry of hookEntries) {
21910
22066
  if (entry.endsWith(".sample")) continue;
21911
- const fullPath = import_node_path11.default.join(hooksDir, entry);
21912
- const stat = await import_promises15.default.stat(fullPath);
22067
+ const fullPath = import_node_path12.default.join(hooksDir, entry);
22068
+ const stat = await import_promises17.default.stat(fullPath);
21913
22069
  if (stat.isFile()) {
21914
- entries.push(import_node_path11.default.join("hooks", entry));
22070
+ entries.push(import_node_path12.default.join("hooks", entry));
21915
22071
  }
21916
22072
  }
21917
22073
  } catch {
21918
22074
  }
21919
22075
  if (entries.length === 0) return false;
21920
- await import_promises15.default.writeFile(listPath, `${entries.join("\n")}
22076
+ await import_promises17.default.writeFile(listPath, `${entries.join("\n")}
21921
22077
  `, "utf8");
21922
22078
  await runTar(gitCommonDir, [
21923
22079
  "-czf",
@@ -21932,7 +22088,7 @@ var init_packaging = __esm({
21932
22088
  writePatch = async (repoRoot, args, destPath) => {
21933
22089
  const output = await runCommandRaw(repoRoot, "git", args);
21934
22090
  if (!output.trim()) return false;
21935
- await import_promises15.default.writeFile(destPath, output, "utf8");
22091
+ await import_promises17.default.writeFile(destPath, output, "utf8");
21936
22092
  return true;
21937
22093
  };
21938
22094
  createFileListArchive = async (repoRoot, files, archivePath, listPath) => {
@@ -21940,13 +22096,13 @@ var init_packaging = __esm({
21940
22096
  const existing = [];
21941
22097
  for (const file of files) {
21942
22098
  try {
21943
- await import_promises15.default.lstat(import_node_path11.default.join(repoRoot, file));
22099
+ await import_promises17.default.lstat(import_node_path12.default.join(repoRoot, file));
21944
22100
  existing.push(file);
21945
22101
  } catch {
21946
22102
  }
21947
22103
  }
21948
22104
  if (existing.length === 0) return false;
21949
- await import_promises15.default.writeFile(listPath, `${existing.join("\n")}
22105
+ await import_promises17.default.writeFile(listPath, `${existing.join("\n")}
21950
22106
  `, "utf8");
21951
22107
  await runTar(repoRoot, ["-czf", archivePath, "-C", repoRoot, "-T", listPath]);
21952
22108
  return true;
@@ -21955,29 +22111,39 @@ var init_packaging = __esm({
21955
22111
  });
21956
22112
 
21957
22113
  // src/devbox/commands/init/registry.ts
21958
- var import_node_path12, import_promises16, readRepoMarker, writeRepoMarker, buildCodexConfig, ensureDevboxToml;
22114
+ var import_node_path13, import_promises18, readRepoMarker, writeRepoMarker, buildCodexConfig;
21959
22115
  var init_registry2 = __esm({
21960
22116
  "src/devbox/commands/init/registry.ts"() {
21961
22117
  "use strict";
21962
- import_node_path12 = __toESM(require("node:path"), 1);
21963
- import_promises16 = __toESM(require("node:fs/promises"), 1);
21964
- readRepoMarker = async (repoRoot) => {
21965
- const markerPath = import_node_path12.default.join(repoRoot, ".devbox", "box.json");
22118
+ import_node_path13 = __toESM(require("node:path"), 1);
22119
+ import_promises18 = __toESM(require("node:fs/promises"), 1);
22120
+ readRepoMarker = async (projectDir) => {
22121
+ const markerPath = import_node_path13.default.join(projectDir, "box.json");
21966
22122
  try {
21967
- const raw = await import_promises16.default.readFile(markerPath, "utf8");
22123
+ const raw = await import_promises18.default.readFile(markerPath, "utf8");
21968
22124
  return JSON.parse(raw);
21969
22125
  } catch {
21970
22126
  return null;
21971
22127
  }
21972
22128
  };
21973
- writeRepoMarker = async (repoRoot, data) => {
21974
- const dir = import_node_path12.default.join(repoRoot, ".devbox");
21975
- await import_promises16.default.mkdir(dir, { recursive: true });
21976
- const markerPath = import_node_path12.default.join(dir, "box.json");
21977
- await import_promises16.default.writeFile(markerPath, JSON.stringify(data, null, 2), "utf8");
22129
+ writeRepoMarker = async (projectDir, data) => {
22130
+ await import_promises18.default.mkdir(projectDir, { recursive: true, mode: 448 });
22131
+ try {
22132
+ await import_promises18.default.chmod(projectDir, 448);
22133
+ } catch {
22134
+ }
22135
+ const markerPath = import_node_path13.default.join(projectDir, "box.json");
22136
+ await import_promises18.default.writeFile(markerPath, JSON.stringify(data, null, 2), {
22137
+ encoding: "utf8",
22138
+ mode: 384
22139
+ });
22140
+ try {
22141
+ await import_promises18.default.chmod(markerPath, 384);
22142
+ } catch {
22143
+ }
21978
22144
  };
21979
22145
  buildCodexConfig = (repoName) => {
21980
- const repoPath = import_node_path12.default.posix.join("/home/sprite", repoName);
22146
+ const repoPath = import_node_path13.default.posix.join("/home/sprite", repoName);
21981
22147
  const lines = [
21982
22148
  'approval_policy = "never"',
21983
22149
  "",
@@ -21994,41 +22160,26 @@ var init_registry2 = __esm({
21994
22160
  ];
21995
22161
  return lines.join("\n");
21996
22162
  };
21997
- ensureDevboxToml = async (repoRoot, projectName, slug) => {
21998
- const filePath = import_node_path12.default.join(repoRoot, "devbox.toml");
21999
- try {
22000
- await import_promises16.default.access(filePath);
22001
- return;
22002
- } catch {
22003
- }
22004
- const content = [
22005
- "[project]",
22006
- `name = ${JSON.stringify(projectName)}`,
22007
- `slug = ${JSON.stringify(slug)}`,
22008
- ""
22009
- ].join("\n");
22010
- await import_promises16.default.writeFile(filePath, content, { encoding: "utf8", flag: "wx" });
22011
- };
22012
22163
  }
22013
22164
  });
22014
22165
 
22015
22166
  // src/devbox/commands/init/scripts.ts
22016
- var import_promises17, import_node_path13, resolveScriptsDir, loadInitScript;
22167
+ var import_promises19, import_node_path14, resolveScriptsDir, loadInitScript;
22017
22168
  var init_scripts = __esm({
22018
22169
  "src/devbox/commands/init/scripts.ts"() {
22019
22170
  "use strict";
22020
- import_promises17 = __toESM(require("node:fs/promises"), 1);
22021
- import_node_path13 = __toESM(require("node:path"), 1);
22171
+ import_promises19 = __toESM(require("node:fs/promises"), 1);
22172
+ import_node_path14 = __toESM(require("node:path"), 1);
22022
22173
  resolveScriptsDir = () => {
22023
22174
  const binPath = process.argv[1];
22024
22175
  if (binPath) {
22025
- return import_node_path13.default.resolve(import_node_path13.default.dirname(binPath), "..", "scripts");
22176
+ return import_node_path14.default.resolve(import_node_path14.default.dirname(binPath), "..", "scripts");
22026
22177
  }
22027
- return import_node_path13.default.resolve(process.cwd(), "scripts");
22178
+ return import_node_path14.default.resolve(process.cwd(), "scripts");
22028
22179
  };
22029
22180
  loadInitScript = async (name) => {
22030
- const scriptPath = import_node_path13.default.join(resolveScriptsDir(), name);
22031
- return await import_promises17.default.readFile(scriptPath, "utf8");
22181
+ const scriptPath = import_node_path14.default.join(resolveScriptsDir(), name);
22182
+ return await import_promises19.default.readFile(scriptPath, "utf8");
22032
22183
  };
22033
22184
  }
22034
22185
  });
@@ -22112,21 +22263,21 @@ var init_remote = __esm({
22112
22263
  });
22113
22264
  return result;
22114
22265
  };
22115
- writeRemoteFile = async (client, canonical, path24, content, stage) => {
22266
+ writeRemoteFile = async (client, canonical, path25, content, stage) => {
22116
22267
  const requestId = (0, import_node_crypto10.randomUUID)();
22117
22268
  logger8.info("sprites_request", {
22118
22269
  requestId,
22119
22270
  method: "writeFile",
22120
- path: path24,
22271
+ path: path25,
22121
22272
  box: canonical,
22122
22273
  stage
22123
22274
  });
22124
22275
  const buffer = typeof content === "string" ? Buffer.from(content, "utf8") : content;
22125
- await client.writeFile(canonical, path24, buffer);
22276
+ await client.writeFile(canonical, path25, buffer);
22126
22277
  logger8.info("sprites_response", {
22127
22278
  requestId,
22128
22279
  method: "writeFile",
22129
- path: path24,
22280
+ path: path25,
22130
22281
  status: "ok",
22131
22282
  box: canonical,
22132
22283
  stage
@@ -22846,12 +22997,12 @@ chmod 755 ${WEZTERM_MUX_RUNNER_PATH}`,
22846
22997
  });
22847
22998
 
22848
22999
  // src/wezterm/installOptions.ts
22849
- var import_node_child_process5, import_promises18, WEZTERM_DARWIN_BIN_PATH, WEZTERM_GITHUB_TIMEOUT_MS, runCommand3, parseWeztermVersion, resolveLocalWeztermVersion, resolveWeztermAssetUrl, resolveWeztermInstallOptions;
23000
+ var import_node_child_process5, import_promises20, WEZTERM_DARWIN_BIN_PATH, WEZTERM_GITHUB_TIMEOUT_MS, runCommand3, parseWeztermVersion, resolveLocalWeztermVersion, resolveWeztermAssetUrl, resolveWeztermInstallOptions;
22850
23001
  var init_installOptions = __esm({
22851
23002
  "src/wezterm/installOptions.ts"() {
22852
23003
  "use strict";
22853
23004
  import_node_child_process5 = require("node:child_process");
22854
- import_promises18 = __toESM(require("node:fs/promises"), 1);
23005
+ import_promises20 = __toESM(require("node:fs/promises"), 1);
22855
23006
  WEZTERM_DARWIN_BIN_PATH = "/Applications/WezTerm.app/Contents/MacOS/wezterm";
22856
23007
  WEZTERM_GITHUB_TIMEOUT_MS = 5e3;
22857
23008
  runCommand3 = async (cmd, args) => new Promise((resolve) => {
@@ -22899,7 +23050,7 @@ var init_installOptions = __esm({
22899
23050
  if (!command) continue;
22900
23051
  if (command.includes("/")) {
22901
23052
  try {
22902
- await import_promises18.default.access(command);
23053
+ await import_promises20.default.access(command);
22903
23054
  } catch {
22904
23055
  continue;
22905
23056
  }
@@ -23060,12 +23211,12 @@ var init_ensureMux = __esm({
23060
23211
  });
23061
23212
 
23062
23213
  // src/devbox/commands/init/state.ts
23063
- var import_node_path14, import_promises19, INIT_STEP_KEYS, initStatePath, isObject, readInitState, writeInitState;
23214
+ var import_node_path15, import_promises21, INIT_STEP_KEYS, initStatePath, isObject3, readInitState, writeInitState;
23064
23215
  var init_state = __esm({
23065
23216
  "src/devbox/commands/init/state.ts"() {
23066
23217
  "use strict";
23067
- import_node_path14 = __toESM(require("node:path"), 1);
23068
- import_promises19 = __toESM(require("node:fs/promises"), 1);
23218
+ import_node_path15 = __toESM(require("node:path"), 1);
23219
+ import_promises21 = __toESM(require("node:fs/promises"), 1);
23069
23220
  INIT_STEP_KEYS = [
23070
23221
  "spritesCreated",
23071
23222
  "registrySynced",
@@ -23090,27 +23241,34 @@ var init_state = __esm({
23090
23241
  "weztermMuxServiceEnsured",
23091
23242
  "codexApplied"
23092
23243
  ];
23093
- initStatePath = (repoRoot) => import_node_path14.default.join(repoRoot, ".devbox", "init-state.json");
23094
- isObject = (value) => typeof value === "object" && value !== null;
23095
- readInitState = async (repoRoot) => {
23244
+ initStatePath = (projectDir) => import_node_path15.default.join(projectDir, "init-state.json");
23245
+ isObject3 = (value) => typeof value === "object" && value !== null;
23246
+ readInitState = async (projectDir) => {
23096
23247
  try {
23097
- const raw = await import_promises19.default.readFile(initStatePath(repoRoot), "utf8");
23248
+ const raw = await import_promises21.default.readFile(initStatePath(projectDir), "utf8");
23098
23249
  const parsed = JSON.parse(raw);
23099
- if (!isObject(parsed)) return null;
23250
+ if (!isObject3(parsed)) return null;
23100
23251
  if (parsed.version !== 1) return null;
23101
23252
  return parsed;
23102
23253
  } catch {
23103
23254
  return null;
23104
23255
  }
23105
23256
  };
23106
- writeInitState = async (repoRoot, state) => {
23107
- const dir = import_node_path14.default.join(repoRoot, ".devbox");
23108
- await import_promises19.default.mkdir(dir, { recursive: true });
23109
- await import_promises19.default.writeFile(
23110
- initStatePath(repoRoot),
23111
- JSON.stringify(state, null, 2),
23112
- "utf8"
23113
- );
23257
+ writeInitState = async (projectDir, state) => {
23258
+ await import_promises21.default.mkdir(projectDir, { recursive: true, mode: 448 });
23259
+ try {
23260
+ await import_promises21.default.chmod(projectDir, 448);
23261
+ } catch {
23262
+ }
23263
+ const statePath = initStatePath(projectDir);
23264
+ await import_promises21.default.writeFile(statePath, JSON.stringify(state, null, 2), {
23265
+ encoding: "utf8",
23266
+ mode: 384
23267
+ });
23268
+ try {
23269
+ await import_promises21.default.chmod(statePath, 384);
23270
+ } catch {
23271
+ }
23114
23272
  };
23115
23273
  }
23116
23274
  });
@@ -23136,7 +23294,7 @@ var init_ssh = __esm({
23136
23294
  }
23137
23295
  return trimmed.replace(/^\/+/, "");
23138
23296
  };
23139
- buildSshUrl = (host, path24) => `git@${host}:${stripGitSuffix2(path24)}.git`;
23297
+ buildSshUrl = (host, path25) => `git@${host}:${stripGitSuffix2(path25)}.git`;
23140
23298
  buildSettingsUrl = (host) => {
23141
23299
  const lower = host.toLowerCase();
23142
23300
  if (lower.includes("gitlab")) {
@@ -23149,12 +23307,12 @@ var init_ssh = __esm({
23149
23307
  const withoutUser = trimmed.startsWith("git@") ? trimmed.slice("git@".length) : trimmed;
23150
23308
  const [host, pathPart] = withoutUser.split(":");
23151
23309
  if (!host || !pathPart) return null;
23152
- const path24 = stripGitSuffix2(pathPart);
23310
+ const path25 = stripGitSuffix2(pathPart);
23153
23311
  return {
23154
23312
  host: host.toLowerCase(),
23155
- path: path24,
23313
+ path: path25,
23156
23314
  protocol: "ssh",
23157
- sshUrl: buildSshUrl(host, path24),
23315
+ sshUrl: buildSshUrl(host, path25),
23158
23316
  settingsUrl: buildSettingsUrl(host)
23159
23317
  };
23160
23318
  };
@@ -23171,13 +23329,13 @@ var init_ssh = __esm({
23171
23329
  try {
23172
23330
  const url = new URL(trimmed);
23173
23331
  const host = url.hostname;
23174
- const path24 = stripGitSuffix2(url.pathname);
23175
- if (!host || !path24) return null;
23332
+ const path25 = stripGitSuffix2(url.pathname);
23333
+ if (!host || !path25) return null;
23176
23334
  return {
23177
23335
  host: host.toLowerCase(),
23178
- path: path24,
23336
+ path: path25,
23179
23337
  protocol: "ssh",
23180
- sshUrl: buildSshUrl(host, path24),
23338
+ sshUrl: buildSshUrl(host, path25),
23181
23339
  settingsUrl: buildSettingsUrl(host)
23182
23340
  };
23183
23341
  } catch {
@@ -23188,13 +23346,13 @@ var init_ssh = __esm({
23188
23346
  try {
23189
23347
  const url = new URL(trimmed);
23190
23348
  const host = url.hostname;
23191
- const path24 = stripGitSuffix2(url.pathname);
23192
- if (!host || !path24) return null;
23349
+ const path25 = stripGitSuffix2(url.pathname);
23350
+ if (!host || !path25) return null;
23193
23351
  return {
23194
23352
  host: host.toLowerCase(),
23195
- path: path24,
23353
+ path: path25,
23196
23354
  protocol: "https",
23197
- sshUrl: buildSshUrl(host, path24),
23355
+ sshUrl: buildSshUrl(host, path25),
23198
23356
  settingsUrl: buildSettingsUrl(host)
23199
23357
  };
23200
23358
  } catch {
@@ -23416,19 +23574,19 @@ ${sshResult.stderr}`.trim();
23416
23574
  });
23417
23575
 
23418
23576
  // src/devbox/commands/mountSsh.ts
23419
- var import_node_child_process7, import_promises20, import_node_os7, import_node_path15, DEVBOX_SSH_DIR, MOUNT_KEY_PATH, MOUNT_PUBLIC_KEY_PATH, KNOWN_HOSTS_PATH, REMOTE_SSH_DIR, REMOTE_AUTH_KEYS, REMOTE_SSHD_CONFIG, SSHD_SERVICE_NAME, runCommand4, ensureDevboxSshDir, ensureKnownHostsFile, ensureLocalMountKey, readLocalMountPublicKey, buildSshdConfig, ensureRemoteMountAccess, ensureSshdService;
23577
+ var import_node_child_process7, import_promises22, import_node_os6, import_node_path16, DEVBOX_SSH_DIR, MOUNT_KEY_PATH, MOUNT_PUBLIC_KEY_PATH, KNOWN_HOSTS_PATH, REMOTE_SSH_DIR, REMOTE_AUTH_KEYS, REMOTE_SSHD_CONFIG, SSHD_SERVICE_NAME, runCommand4, ensureDevboxSshDir, ensureKnownHostsFile, ensureLocalMountKey, readLocalMountPublicKey, buildSshdConfig, ensureRemoteMountAccess, ensureSshdService;
23420
23578
  var init_mountSsh = __esm({
23421
23579
  "src/devbox/commands/mountSsh.ts"() {
23422
23580
  "use strict";
23423
23581
  import_node_child_process7 = require("node:child_process");
23424
- import_promises20 = __toESM(require("node:fs/promises"), 1);
23425
- import_node_os7 = __toESM(require("node:os"), 1);
23426
- import_node_path15 = __toESM(require("node:path"), 1);
23582
+ import_promises22 = __toESM(require("node:fs/promises"), 1);
23583
+ import_node_os6 = __toESM(require("node:os"), 1);
23584
+ import_node_path16 = __toESM(require("node:path"), 1);
23427
23585
  init_src();
23428
- DEVBOX_SSH_DIR = import_node_path15.default.join(resolveDevboxDir(), "ssh");
23429
- MOUNT_KEY_PATH = import_node_path15.default.join(DEVBOX_SSH_DIR, "mount_ed25519");
23586
+ DEVBOX_SSH_DIR = import_node_path16.default.join(resolveDevboxDir(), "ssh");
23587
+ MOUNT_KEY_PATH = import_node_path16.default.join(DEVBOX_SSH_DIR, "mount_ed25519");
23430
23588
  MOUNT_PUBLIC_KEY_PATH = `${MOUNT_KEY_PATH}.pub`;
23431
- KNOWN_HOSTS_PATH = import_node_path15.default.join(DEVBOX_SSH_DIR, "known_hosts");
23589
+ KNOWN_HOSTS_PATH = import_node_path16.default.join(DEVBOX_SSH_DIR, "known_hosts");
23432
23590
  REMOTE_SSH_DIR = "/home/sprite/.devbox/ssh";
23433
23591
  REMOTE_AUTH_KEYS = `${REMOTE_SSH_DIR}/authorized_keys`;
23434
23592
  REMOTE_SSHD_CONFIG = `${REMOTE_SSH_DIR}/sshd_config`;
@@ -23442,24 +23600,24 @@ var init_mountSsh = __esm({
23442
23600
  child.on("exit", (code2) => resolve(code2 ?? 0));
23443
23601
  });
23444
23602
  ensureDevboxSshDir = async () => {
23445
- await import_promises20.default.mkdir(DEVBOX_SSH_DIR, { recursive: true, mode: 448 });
23603
+ await import_promises22.default.mkdir(DEVBOX_SSH_DIR, { recursive: true, mode: 448 });
23446
23604
  };
23447
23605
  ensureKnownHostsFile = async () => {
23448
23606
  await ensureDevboxSshDir();
23449
- await import_promises20.default.writeFile(KNOWN_HOSTS_PATH, "", { flag: "a" });
23607
+ await import_promises22.default.writeFile(KNOWN_HOSTS_PATH, "", { flag: "a" });
23450
23608
  return KNOWN_HOSTS_PATH;
23451
23609
  };
23452
23610
  ensureLocalMountKey = async () => {
23453
23611
  await ensureDevboxSshDir();
23454
23612
  try {
23455
- await import_promises20.default.access(MOUNT_KEY_PATH);
23456
- await import_promises20.default.access(MOUNT_PUBLIC_KEY_PATH);
23613
+ await import_promises22.default.access(MOUNT_KEY_PATH);
23614
+ await import_promises22.default.access(MOUNT_PUBLIC_KEY_PATH);
23457
23615
  return {
23458
23616
  privateKeyPath: MOUNT_KEY_PATH,
23459
23617
  publicKeyPath: MOUNT_PUBLIC_KEY_PATH
23460
23618
  };
23461
23619
  } catch {
23462
- const comment = `devbox-mount@${import_node_os7.default.hostname()}`;
23620
+ const comment = `devbox-mount@${import_node_os6.default.hostname()}`;
23463
23621
  const exitCode = await runCommand4("ssh-keygen", [
23464
23622
  "-t",
23465
23623
  "ed25519",
@@ -23480,7 +23638,7 @@ var init_mountSsh = __esm({
23480
23638
  };
23481
23639
  };
23482
23640
  readLocalMountPublicKey = async () => {
23483
- const raw = await import_promises20.default.readFile(MOUNT_PUBLIC_KEY_PATH, "utf8");
23641
+ const raw = await import_promises22.default.readFile(MOUNT_PUBLIC_KEY_PATH, "utf8");
23484
23642
  const trimmed = raw.trim();
23485
23643
  if (!trimmed) {
23486
23644
  throw new Error("Mount public key is empty.");
@@ -23620,23 +23778,23 @@ var init_template = __esm({
23620
23778
  });
23621
23779
 
23622
23780
  // src/devbox/commands/init/codex/prompts.ts
23623
- var import_promises21, import_node_path16, resolvePromptsDir, readPromptTemplate, loadPrompt, loadLocalEnvSecretsScanPrompt, loadLocalExternalScanPrompt, loadLocalExtraArtifactsScanPrompt, loadLocalServicesScanPrompt;
23781
+ var import_promises23, import_node_path17, resolvePromptsDir, readPromptTemplate, loadPrompt, loadLocalEnvSecretsScanPrompt, loadLocalExternalScanPrompt, loadLocalExtraArtifactsScanPrompt, loadLocalServicesScanPrompt;
23624
23782
  var init_prompts = __esm({
23625
23783
  "src/devbox/commands/init/codex/prompts.ts"() {
23626
23784
  "use strict";
23627
- import_promises21 = __toESM(require("node:fs/promises"), 1);
23628
- import_node_path16 = __toESM(require("node:path"), 1);
23785
+ import_promises23 = __toESM(require("node:fs/promises"), 1);
23786
+ import_node_path17 = __toESM(require("node:path"), 1);
23629
23787
  init_template();
23630
23788
  resolvePromptsDir = () => {
23631
23789
  const binPath = process.argv[1];
23632
23790
  if (binPath) {
23633
- return import_node_path16.default.resolve(import_node_path16.default.dirname(binPath), "..", "prompts");
23791
+ return import_node_path17.default.resolve(import_node_path17.default.dirname(binPath), "..", "prompts");
23634
23792
  }
23635
- return import_node_path16.default.resolve(process.cwd(), "prompts");
23793
+ return import_node_path17.default.resolve(process.cwd(), "prompts");
23636
23794
  };
23637
23795
  readPromptTemplate = async (name) => {
23638
- const promptPath = import_node_path16.default.join(resolvePromptsDir(), name);
23639
- const raw = await import_promises21.default.readFile(promptPath, "utf8");
23796
+ const promptPath = import_node_path17.default.join(resolvePromptsDir(), name);
23797
+ const raw = await import_promises23.default.readFile(promptPath, "utf8");
23640
23798
  return raw;
23641
23799
  };
23642
23800
  loadPrompt = async (name, vars = {}) => renderTemplate(await readPromptTemplate(name), vars).trim();
@@ -24152,75 +24310,75 @@ fi`
24152
24310
  });
24153
24311
 
24154
24312
  // src/devbox/commands/init/codex/plan.ts
24155
- var import_node_path17, import_promises22, resolveSchemaPath, writeSetupEnvSecretsSchema, writeSetupExternalSchema, writeSetupExtraArtifactsSchema, writeServicesSchema, isObject2, isSetupPlan, isSetupEnvSecretsPlan, isSetupExternalPlan, isSetupExtraArtifactsPlan, isServicesPlan, readSetupPlan, readSetupEnvSecretsPlan, readSetupExternalPlan, readSetupExtraArtifactsPlan, readServicesPlan, writeSetupPlan, mergeSetupScans, writeServicesPlan;
24313
+ var import_node_path18, import_promises24, resolveSchemaPath, writeSetupEnvSecretsSchema, writeSetupExternalSchema, writeSetupExtraArtifactsSchema, writeServicesSchema, isObject4, isSetupPlan, isSetupEnvSecretsPlan, isSetupExternalPlan, isSetupExtraArtifactsPlan, isServicesPlan, readSetupPlan, readSetupEnvSecretsPlan, readSetupExternalPlan, readSetupExtraArtifactsPlan, readServicesPlan, writeSetupPlan, mergeSetupScans, writeServicesPlan;
24156
24314
  var init_plan = __esm({
24157
24315
  "src/devbox/commands/init/codex/plan.ts"() {
24158
24316
  "use strict";
24159
- import_node_path17 = __toESM(require("node:path"), 1);
24160
- import_promises22 = __toESM(require("node:fs/promises"), 1);
24317
+ import_node_path18 = __toESM(require("node:path"), 1);
24318
+ import_promises24 = __toESM(require("node:fs/promises"), 1);
24161
24319
  resolveSchemaPath = (fileName) => {
24162
24320
  const binPath = process.argv[1];
24163
24321
  if (binPath) {
24164
- return import_node_path17.default.resolve(
24165
- import_node_path17.default.dirname(binPath),
24322
+ return import_node_path18.default.resolve(
24323
+ import_node_path18.default.dirname(binPath),
24166
24324
  "..",
24167
24325
  "codex",
24168
24326
  fileName
24169
24327
  );
24170
24328
  }
24171
- return import_node_path17.default.resolve(process.cwd(), "codex", fileName);
24329
+ return import_node_path18.default.resolve(process.cwd(), "codex", fileName);
24172
24330
  };
24173
24331
  writeSetupEnvSecretsSchema = async (dir) => {
24174
24332
  const sourceSchemaPath = resolveSchemaPath("setup-env-secrets-schema.json");
24175
- const schemaContents = await import_promises22.default.readFile(sourceSchemaPath, "utf8");
24176
- const schemaPath = import_node_path17.default.join(dir, "setup-env-secrets-schema.json");
24177
- await import_promises22.default.writeFile(schemaPath, schemaContents, "utf8");
24333
+ const schemaContents = await import_promises24.default.readFile(sourceSchemaPath, "utf8");
24334
+ const schemaPath = import_node_path18.default.join(dir, "setup-env-secrets-schema.json");
24335
+ await import_promises24.default.writeFile(schemaPath, schemaContents, "utf8");
24178
24336
  return schemaPath;
24179
24337
  };
24180
24338
  writeSetupExternalSchema = async (dir) => {
24181
24339
  const sourceSchemaPath = resolveSchemaPath("setup-external-schema.json");
24182
- const schemaContents = await import_promises22.default.readFile(sourceSchemaPath, "utf8");
24183
- const schemaPath = import_node_path17.default.join(dir, "setup-external-schema.json");
24184
- await import_promises22.default.writeFile(schemaPath, schemaContents, "utf8");
24340
+ const schemaContents = await import_promises24.default.readFile(sourceSchemaPath, "utf8");
24341
+ const schemaPath = import_node_path18.default.join(dir, "setup-external-schema.json");
24342
+ await import_promises24.default.writeFile(schemaPath, schemaContents, "utf8");
24185
24343
  return schemaPath;
24186
24344
  };
24187
24345
  writeSetupExtraArtifactsSchema = async (dir) => {
24188
24346
  const sourceSchemaPath = resolveSchemaPath("setup-extra-artifacts-schema.json");
24189
- const schemaContents = await import_promises22.default.readFile(sourceSchemaPath, "utf8");
24190
- const schemaPath = import_node_path17.default.join(dir, "setup-extra-artifacts-schema.json");
24191
- await import_promises22.default.writeFile(schemaPath, schemaContents, "utf8");
24347
+ const schemaContents = await import_promises24.default.readFile(sourceSchemaPath, "utf8");
24348
+ const schemaPath = import_node_path18.default.join(dir, "setup-extra-artifacts-schema.json");
24349
+ await import_promises24.default.writeFile(schemaPath, schemaContents, "utf8");
24192
24350
  return schemaPath;
24193
24351
  };
24194
24352
  writeServicesSchema = async (dir) => {
24195
24353
  const sourceSchemaPath = resolveSchemaPath("services-schema.json");
24196
- const schemaContents = await import_promises22.default.readFile(sourceSchemaPath, "utf8");
24197
- const schemaPath = import_node_path17.default.join(dir, "services-schema.json");
24198
- await import_promises22.default.writeFile(schemaPath, schemaContents, "utf8");
24354
+ const schemaContents = await import_promises24.default.readFile(sourceSchemaPath, "utf8");
24355
+ const schemaPath = import_node_path18.default.join(dir, "services-schema.json");
24356
+ await import_promises24.default.writeFile(schemaPath, schemaContents, "utf8");
24199
24357
  return schemaPath;
24200
24358
  };
24201
- isObject2 = (value) => typeof value === "object" && value !== null;
24359
+ isObject4 = (value) => typeof value === "object" && value !== null;
24202
24360
  isSetupPlan = (value) => {
24203
- if (!isObject2(value)) return false;
24361
+ if (!isObject4(value)) return false;
24204
24362
  return typeof value.schemaVersion === "number" && Array.isArray(value.envFiles) && Array.isArray(value.secretFiles) && Array.isArray(value.extraArtifacts) && Array.isArray(value.externalDependencies) && Array.isArray(value.externalConfigs);
24205
24363
  };
24206
24364
  isSetupEnvSecretsPlan = (value) => {
24207
- if (!isObject2(value)) return false;
24365
+ if (!isObject4(value)) return false;
24208
24366
  return typeof value.schemaVersion === "number" && typeof value.scanFullyCompleted === "boolean" && Array.isArray(value.envFiles) && Array.isArray(value.secretFiles);
24209
24367
  };
24210
24368
  isSetupExternalPlan = (value) => {
24211
- if (!isObject2(value)) return false;
24369
+ if (!isObject4(value)) return false;
24212
24370
  return typeof value.schemaVersion === "number" && typeof value.scanFullyCompleted === "boolean" && Array.isArray(value.externalDependencies) && Array.isArray(value.externalConfigs);
24213
24371
  };
24214
24372
  isSetupExtraArtifactsPlan = (value) => {
24215
- if (!isObject2(value)) return false;
24373
+ if (!isObject4(value)) return false;
24216
24374
  return typeof value.schemaVersion === "number" && typeof value.scanFullyCompleted === "boolean" && Array.isArray(value.extraArtifacts);
24217
24375
  };
24218
24376
  isServicesPlan = (value) => {
24219
- if (!isObject2(value)) return false;
24377
+ if (!isObject4(value)) return false;
24220
24378
  return typeof value.schemaVersion === "number" && typeof value.scanFullyCompleted === "boolean" && Array.isArray(value.appEntrypoints) && Array.isArray(value.backgroundServices);
24221
24379
  };
24222
24380
  readSetupPlan = async (setupPath) => {
24223
- const raw = await import_promises22.default.readFile(setupPath, "utf8");
24381
+ const raw = await import_promises24.default.readFile(setupPath, "utf8");
24224
24382
  const parsed = JSON.parse(raw);
24225
24383
  if (!isSetupPlan(parsed)) {
24226
24384
  throw new Error(`Invalid setup plan: ${setupPath}`);
@@ -24228,7 +24386,7 @@ var init_plan = __esm({
24228
24386
  return parsed;
24229
24387
  };
24230
24388
  readSetupEnvSecretsPlan = async (scanPath) => {
24231
- const raw = await import_promises22.default.readFile(scanPath, "utf8");
24389
+ const raw = await import_promises24.default.readFile(scanPath, "utf8");
24232
24390
  const parsed = JSON.parse(raw);
24233
24391
  if (!isSetupEnvSecretsPlan(parsed)) {
24234
24392
  throw new Error(`Invalid env/secrets scan: ${scanPath}`);
@@ -24236,7 +24394,7 @@ var init_plan = __esm({
24236
24394
  return parsed;
24237
24395
  };
24238
24396
  readSetupExternalPlan = async (scanPath) => {
24239
- const raw = await import_promises22.default.readFile(scanPath, "utf8");
24397
+ const raw = await import_promises24.default.readFile(scanPath, "utf8");
24240
24398
  const parsed = JSON.parse(raw);
24241
24399
  if (!isSetupExternalPlan(parsed)) {
24242
24400
  throw new Error(`Invalid external scan: ${scanPath}`);
@@ -24244,7 +24402,7 @@ var init_plan = __esm({
24244
24402
  return parsed;
24245
24403
  };
24246
24404
  readSetupExtraArtifactsPlan = async (scanPath) => {
24247
- const raw = await import_promises22.default.readFile(scanPath, "utf8");
24405
+ const raw = await import_promises24.default.readFile(scanPath, "utf8");
24248
24406
  const parsed = JSON.parse(raw);
24249
24407
  if (!isSetupExtraArtifactsPlan(parsed)) {
24250
24408
  throw new Error(`Invalid extra artifacts scan: ${scanPath}`);
@@ -24252,7 +24410,7 @@ var init_plan = __esm({
24252
24410
  return parsed;
24253
24411
  };
24254
24412
  readServicesPlan = async (servicesPath) => {
24255
- const raw = await import_promises22.default.readFile(servicesPath, "utf8");
24413
+ const raw = await import_promises24.default.readFile(servicesPath, "utf8");
24256
24414
  const parsed = JSON.parse(raw);
24257
24415
  if (!isServicesPlan(parsed)) {
24258
24416
  throw new Error(`Invalid services plan: ${servicesPath}`);
@@ -24260,7 +24418,7 @@ var init_plan = __esm({
24260
24418
  return parsed;
24261
24419
  };
24262
24420
  writeSetupPlan = async (setupPath, plan) => {
24263
- await import_promises22.default.writeFile(setupPath, JSON.stringify(plan, null, 2), "utf8");
24421
+ await import_promises24.default.writeFile(setupPath, JSON.stringify(plan, null, 2), "utf8");
24264
24422
  };
24265
24423
  mergeSetupScans = ({
24266
24424
  envSecrets,
@@ -24308,7 +24466,7 @@ var init_plan = __esm({
24308
24466
  };
24309
24467
  };
24310
24468
  writeServicesPlan = async (servicesPath, plan) => {
24311
- await import_promises22.default.writeFile(servicesPath, JSON.stringify(plan, null, 2), "utf8");
24469
+ await import_promises24.default.writeFile(servicesPath, JSON.stringify(plan, null, 2), "utf8");
24312
24470
  };
24313
24471
  }
24314
24472
  });
@@ -24453,14 +24611,14 @@ ${bottom}
24453
24611
  });
24454
24612
 
24455
24613
  // src/devbox/commands/init/codex/local.ts
24456
- var import_node_child_process9, import_node_fs3, import_promises23, import_node_path18, stripAnsi3, extractBoldText2, runCodexExec, runLocalSetupEnvSecretsScan, runLocalSetupExternalScan, runLocalSetupExtraArtifactsScan, runLocalServicesScan, toPosixPath, toRepoRelativePath, countSecretVars, buildEnvFileHint, buildExternalDependencyLabel, promptForPlanApproval, promptForServicesApproval;
24614
+ var import_node_child_process9, import_node_fs3, import_promises25, import_node_path19, stripAnsi3, extractBoldText2, runCodexExec, runLocalSetupEnvSecretsScan, runLocalSetupExternalScan, runLocalSetupExtraArtifactsScan, runLocalServicesScan, toPosixPath, toRepoRelativePath, countSecretVars, buildEnvFileHint, buildExternalDependencyLabel, promptForPlanApproval, promptForServicesApproval;
24457
24615
  var init_local = __esm({
24458
24616
  "src/devbox/commands/init/codex/local.ts"() {
24459
24617
  "use strict";
24460
24618
  import_node_child_process9 = require("node:child_process");
24461
24619
  import_node_fs3 = require("node:fs");
24462
- import_promises23 = __toESM(require("node:fs/promises"), 1);
24463
- import_node_path18 = __toESM(require("node:path"), 1);
24620
+ import_promises25 = __toESM(require("node:fs/promises"), 1);
24621
+ import_node_path19 = __toESM(require("node:path"), 1);
24464
24622
  init_dist2();
24465
24623
  init_prompts();
24466
24624
  init_clack();
@@ -24476,11 +24634,11 @@ var init_local = __esm({
24476
24634
  let stderrStream = null;
24477
24635
  try {
24478
24636
  if (stdoutLogPath) {
24479
- await import_promises23.default.mkdir(import_node_path18.default.dirname(stdoutLogPath), { recursive: true });
24637
+ await import_promises25.default.mkdir(import_node_path19.default.dirname(stdoutLogPath), { recursive: true });
24480
24638
  stdoutStream = (0, import_node_fs3.createWriteStream)(stdoutLogPath, { flags: "a" });
24481
24639
  }
24482
24640
  if (stderrLogPath) {
24483
- await import_promises23.default.mkdir(import_node_path18.default.dirname(stderrLogPath), { recursive: true });
24641
+ await import_promises25.default.mkdir(import_node_path19.default.dirname(stderrLogPath), { recursive: true });
24484
24642
  stderrStream = (0, import_node_fs3.createWriteStream)(stderrLogPath, { flags: "a" });
24485
24643
  }
24486
24644
  } catch {
@@ -24556,34 +24714,39 @@ var init_local = __esm({
24556
24714
  };
24557
24715
  runLocalSetupEnvSecretsScan = async ({
24558
24716
  cwd,
24717
+ logDir,
24559
24718
  schemaPath,
24560
24719
  outputPath,
24561
24720
  onProgress
24562
24721
  }) => {
24563
24722
  const localScanPrompt = await loadLocalEnvSecretsScanPrompt();
24564
24723
  const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
24565
- const logDir = import_node_path18.default.join(cwd, ".devbox", "logs");
24566
- const stdoutLogPath = import_node_path18.default.join(
24724
+ const stdoutLogPath = import_node_path19.default.join(
24567
24725
  logDir,
24568
24726
  `codex-local-setup-env-secrets-scan-${stamp}.jsonl`
24569
24727
  );
24570
- const stderrLogPath = import_node_path18.default.join(
24728
+ const stderrLogPath = import_node_path19.default.join(
24571
24729
  logDir,
24572
24730
  `codex-local-setup-env-secrets-scan-${stamp}.stderr.log`
24573
24731
  );
24574
- const metaLogPath = import_node_path18.default.join(
24732
+ const metaLogPath = import_node_path19.default.join(
24575
24733
  logDir,
24576
24734
  `codex-local-setup-env-secrets-scan-${stamp}.meta.json`
24577
24735
  );
24578
- await import_promises23.default.mkdir(logDir, { recursive: true });
24579
- await import_promises23.default.mkdir(import_node_path18.default.dirname(outputPath), { recursive: true });
24580
- await import_promises23.default.writeFile(
24736
+ await import_promises25.default.mkdir(logDir, { recursive: true, mode: 448 });
24737
+ try {
24738
+ await import_promises25.default.chmod(logDir, 448);
24739
+ } catch {
24740
+ }
24741
+ await import_promises25.default.mkdir(import_node_path19.default.dirname(outputPath), { recursive: true });
24742
+ await import_promises25.default.writeFile(
24581
24743
  metaLogPath,
24582
24744
  JSON.stringify(
24583
24745
  {
24584
24746
  kind: "local-setup-env-secrets-scan",
24585
24747
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
24586
24748
  cwd,
24749
+ logDir,
24587
24750
  schemaPath,
24588
24751
  outputPath,
24589
24752
  prompt: localScanPrompt
@@ -24607,6 +24770,7 @@ var init_local = __esm({
24607
24770
  };
24608
24771
  runLocalSetupExternalScan = async ({
24609
24772
  cwd,
24773
+ logDir,
24610
24774
  schemaPath,
24611
24775
  outputPath,
24612
24776
  homeDir,
@@ -24614,28 +24778,32 @@ var init_local = __esm({
24614
24778
  }) => {
24615
24779
  const localScanPrompt = await loadLocalExternalScanPrompt();
24616
24780
  const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
24617
- const logDir = import_node_path18.default.join(cwd, ".devbox", "logs");
24618
- const stdoutLogPath = import_node_path18.default.join(
24781
+ const stdoutLogPath = import_node_path19.default.join(
24619
24782
  logDir,
24620
24783
  `codex-local-setup-external-scan-${stamp}.jsonl`
24621
24784
  );
24622
- const stderrLogPath = import_node_path18.default.join(
24785
+ const stderrLogPath = import_node_path19.default.join(
24623
24786
  logDir,
24624
24787
  `codex-local-setup-external-scan-${stamp}.stderr.log`
24625
24788
  );
24626
- const metaLogPath = import_node_path18.default.join(
24789
+ const metaLogPath = import_node_path19.default.join(
24627
24790
  logDir,
24628
24791
  `codex-local-setup-external-scan-${stamp}.meta.json`
24629
24792
  );
24630
- await import_promises23.default.mkdir(logDir, { recursive: true });
24631
- await import_promises23.default.mkdir(import_node_path18.default.dirname(outputPath), { recursive: true });
24632
- await import_promises23.default.writeFile(
24793
+ await import_promises25.default.mkdir(logDir, { recursive: true, mode: 448 });
24794
+ try {
24795
+ await import_promises25.default.chmod(logDir, 448);
24796
+ } catch {
24797
+ }
24798
+ await import_promises25.default.mkdir(import_node_path19.default.dirname(outputPath), { recursive: true });
24799
+ await import_promises25.default.writeFile(
24633
24800
  metaLogPath,
24634
24801
  JSON.stringify(
24635
24802
  {
24636
24803
  kind: "local-setup-external-scan",
24637
24804
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
24638
24805
  cwd,
24806
+ logDir,
24639
24807
  schemaPath,
24640
24808
  outputPath,
24641
24809
  prompt: localScanPrompt
@@ -24660,34 +24828,39 @@ var init_local = __esm({
24660
24828
  };
24661
24829
  runLocalSetupExtraArtifactsScan = async ({
24662
24830
  cwd,
24831
+ logDir,
24663
24832
  schemaPath,
24664
24833
  outputPath,
24665
24834
  onProgress
24666
24835
  }) => {
24667
24836
  const localScanPrompt = await loadLocalExtraArtifactsScanPrompt();
24668
24837
  const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
24669
- const logDir = import_node_path18.default.join(cwd, ".devbox", "logs");
24670
- const stdoutLogPath = import_node_path18.default.join(
24838
+ const stdoutLogPath = import_node_path19.default.join(
24671
24839
  logDir,
24672
24840
  `codex-local-setup-extra-artifacts-scan-${stamp}.jsonl`
24673
24841
  );
24674
- const stderrLogPath = import_node_path18.default.join(
24842
+ const stderrLogPath = import_node_path19.default.join(
24675
24843
  logDir,
24676
24844
  `codex-local-setup-extra-artifacts-scan-${stamp}.stderr.log`
24677
24845
  );
24678
- const metaLogPath = import_node_path18.default.join(
24846
+ const metaLogPath = import_node_path19.default.join(
24679
24847
  logDir,
24680
24848
  `codex-local-setup-extra-artifacts-scan-${stamp}.meta.json`
24681
24849
  );
24682
- await import_promises23.default.mkdir(logDir, { recursive: true });
24683
- await import_promises23.default.mkdir(import_node_path18.default.dirname(outputPath), { recursive: true });
24684
- await import_promises23.default.writeFile(
24850
+ await import_promises25.default.mkdir(logDir, { recursive: true, mode: 448 });
24851
+ try {
24852
+ await import_promises25.default.chmod(logDir, 448);
24853
+ } catch {
24854
+ }
24855
+ await import_promises25.default.mkdir(import_node_path19.default.dirname(outputPath), { recursive: true });
24856
+ await import_promises25.default.writeFile(
24685
24857
  metaLogPath,
24686
24858
  JSON.stringify(
24687
24859
  {
24688
24860
  kind: "local-setup-extra-artifacts-scan",
24689
24861
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
24690
24862
  cwd,
24863
+ logDir,
24691
24864
  schemaPath,
24692
24865
  outputPath,
24693
24866
  prompt: localScanPrompt
@@ -24711,6 +24884,7 @@ var init_local = __esm({
24711
24884
  };
24712
24885
  runLocalServicesScan = async ({
24713
24886
  cwd,
24887
+ logDir,
24714
24888
  schemaPath,
24715
24889
  outputPath,
24716
24890
  homeDir,
@@ -24718,27 +24892,31 @@ var init_local = __esm({
24718
24892
  }) => {
24719
24893
  const servicesScanPrompt = await loadLocalServicesScanPrompt();
24720
24894
  const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
24721
- const logDir = import_node_path18.default.join(cwd, ".devbox", "logs");
24722
- const stdoutLogPath = import_node_path18.default.join(
24895
+ const stdoutLogPath = import_node_path19.default.join(
24723
24896
  logDir,
24724
24897
  `codex-local-services-scan-${stamp}.jsonl`
24725
24898
  );
24726
- const stderrLogPath = import_node_path18.default.join(
24899
+ const stderrLogPath = import_node_path19.default.join(
24727
24900
  logDir,
24728
24901
  `codex-local-services-scan-${stamp}.stderr.log`
24729
24902
  );
24730
- const metaLogPath = import_node_path18.default.join(
24903
+ const metaLogPath = import_node_path19.default.join(
24731
24904
  logDir,
24732
24905
  `codex-local-services-scan-${stamp}.meta.json`
24733
24906
  );
24734
- await import_promises23.default.mkdir(logDir, { recursive: true });
24735
- await import_promises23.default.writeFile(
24907
+ await import_promises25.default.mkdir(logDir, { recursive: true, mode: 448 });
24908
+ try {
24909
+ await import_promises25.default.chmod(logDir, 448);
24910
+ } catch {
24911
+ }
24912
+ await import_promises25.default.writeFile(
24736
24913
  metaLogPath,
24737
24914
  JSON.stringify(
24738
24915
  {
24739
24916
  kind: "local-services-scan",
24740
24917
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
24741
24918
  cwd,
24919
+ logDir,
24742
24920
  schemaPath,
24743
24921
  outputPath,
24744
24922
  prompt: servicesScanPrompt
@@ -24761,10 +24939,10 @@ var init_local = __esm({
24761
24939
  ];
24762
24940
  await runCodexExec(cwd, args, onProgress, { stdoutLogPath, stderrLogPath });
24763
24941
  };
24764
- toPosixPath = (value) => value.split(import_node_path18.default.sep).join(import_node_path18.default.posix.sep);
24942
+ toPosixPath = (value) => value.split(import_node_path19.default.sep).join(import_node_path19.default.posix.sep);
24765
24943
  toRepoRelativePath = (repoRoot, filePath) => {
24766
- const resolved = import_node_path18.default.isAbsolute(filePath) ? filePath : import_node_path18.default.resolve(repoRoot, filePath);
24767
- const relative = import_node_path18.default.relative(repoRoot, resolved) || filePath;
24944
+ const resolved = import_node_path19.default.isAbsolute(filePath) ? filePath : import_node_path19.default.resolve(repoRoot, filePath);
24945
+ const relative = import_node_path19.default.relative(repoRoot, resolved) || filePath;
24768
24946
  return toPosixPath(relative);
24769
24947
  };
24770
24948
  countSecretVars = (vars) => vars.reduce((count, entry) => count + (entry.isSecret ? 1 : 0), 0);
@@ -24927,38 +25105,38 @@ ${usageText}`;
24927
25105
  });
24928
25106
 
24929
25107
  // src/devbox/commands/init/codex/artifacts.ts
24930
- var import_promises24, import_node_path19, import_node_os8, macCopyfileDisabledEnv2, isWithinRepo, normalizeExternalPath, expandHomePath, buildArtifactEntry, buildEntries, copyArtifact, createSetupArtifacts;
25108
+ var import_promises26, import_node_path20, import_node_os7, macCopyfileDisabledEnv2, isWithinRepo, normalizeExternalPath, expandHomePath, buildArtifactEntry, buildEntries, copyArtifact, createSetupArtifacts;
24931
25109
  var init_artifacts = __esm({
24932
25110
  "src/devbox/commands/init/codex/artifacts.ts"() {
24933
25111
  "use strict";
24934
- import_promises24 = __toESM(require("node:fs/promises"), 1);
24935
- import_node_path19 = __toESM(require("node:path"), 1);
24936
- import_node_os8 = __toESM(require("node:os"), 1);
25112
+ import_promises26 = __toESM(require("node:fs/promises"), 1);
25113
+ import_node_path20 = __toESM(require("node:path"), 1);
25114
+ import_node_os7 = __toESM(require("node:os"), 1);
24937
25115
  init_repo2();
24938
25116
  macCopyfileDisabledEnv2 = process.platform === "darwin" ? { COPYFILE_DISABLE: "1" } : void 0;
24939
25117
  isWithinRepo = (repoRoot, candidate) => {
24940
- const relative = import_node_path19.default.relative(repoRoot, candidate);
24941
- return relative && !relative.startsWith("..") && !import_node_path19.default.isAbsolute(relative);
25118
+ const relative = import_node_path20.default.relative(repoRoot, candidate);
25119
+ return relative && !relative.startsWith("..") && !import_node_path20.default.isAbsolute(relative);
24942
25120
  };
24943
25121
  normalizeExternalPath = (value) => value.replace(/^([A-Za-z]:)?[\\/]+/, "");
24944
25122
  expandHomePath = (value, homeDir) => {
24945
25123
  if (!value.startsWith("~")) return value;
24946
- const home = homeDir ?? import_node_os8.default.homedir();
25124
+ const home = homeDir ?? import_node_os7.default.homedir();
24947
25125
  if (!home) return value;
24948
25126
  if (value === "~") return home;
24949
25127
  if (value.startsWith("~/") || value.startsWith("~\\")) {
24950
- return import_node_path19.default.join(home, value.slice(2));
25128
+ return import_node_path20.default.join(home, value.slice(2));
24951
25129
  }
24952
25130
  return value;
24953
25131
  };
24954
25132
  buildArtifactEntry = (repoRoot, kind, name, artifactPath, homeDir, description, vars, usage2) => {
24955
25133
  const expanded = expandHomePath(artifactPath, homeDir);
24956
- const resolved = import_node_path19.default.isAbsolute(expanded) ? expanded : import_node_path19.default.resolve(repoRoot, expanded);
25134
+ const resolved = import_node_path20.default.isAbsolute(expanded) ? expanded : import_node_path20.default.resolve(repoRoot, expanded);
24957
25135
  const base = {
24958
25136
  kind,
24959
25137
  name,
24960
25138
  sourcePath: resolved,
24961
- bundlePath: isWithinRepo(repoRoot, resolved) ? import_node_path19.default.join("repo", import_node_path19.default.relative(repoRoot, resolved)) : import_node_path19.default.join("external", normalizeExternalPath(import_node_path19.default.resolve(resolved)))
25139
+ bundlePath: isWithinRepo(repoRoot, resolved) ? import_node_path20.default.join("repo", import_node_path20.default.relative(repoRoot, resolved)) : import_node_path20.default.join("external", normalizeExternalPath(import_node_path20.default.resolve(resolved)))
24962
25140
  };
24963
25141
  if (description !== void 0) {
24964
25142
  base.description = description;
@@ -25026,14 +25204,14 @@ var init_artifacts = __esm({
25026
25204
  return entries;
25027
25205
  };
25028
25206
  copyArtifact = async (entry, bundleRoot) => {
25029
- const destPath = import_node_path19.default.join(bundleRoot, entry.bundlePath);
25030
- const stat = await import_promises24.default.lstat(entry.sourcePath);
25031
- await import_promises24.default.mkdir(import_node_path19.default.dirname(destPath), { recursive: true });
25207
+ const destPath = import_node_path20.default.join(bundleRoot, entry.bundlePath);
25208
+ const stat = await import_promises26.default.lstat(entry.sourcePath);
25209
+ await import_promises26.default.mkdir(import_node_path20.default.dirname(destPath), { recursive: true });
25032
25210
  if (stat.isDirectory()) {
25033
- await import_promises24.default.cp(entry.sourcePath, destPath, { recursive: true });
25211
+ await import_promises26.default.cp(entry.sourcePath, destPath, { recursive: true });
25034
25212
  return;
25035
25213
  }
25036
- await import_promises24.default.cp(entry.sourcePath, destPath, { recursive: false });
25214
+ await import_promises26.default.cp(entry.sourcePath, destPath, { recursive: false });
25037
25215
  };
25038
25216
  createSetupArtifacts = async ({
25039
25217
  repoRoot,
@@ -25044,8 +25222,8 @@ var init_artifacts = __esm({
25044
25222
  }) => {
25045
25223
  const entries = buildEntries(repoRoot, plan, homeDir);
25046
25224
  if (entries.length === 0) return null;
25047
- const bundleRoot = import_node_path19.default.join(tempDir, "setup-artifacts");
25048
- await import_promises24.default.mkdir(bundleRoot, { recursive: true });
25225
+ const bundleRoot = import_node_path20.default.join(tempDir, "setup-artifacts");
25226
+ await import_promises26.default.mkdir(bundleRoot, { recursive: true });
25049
25227
  for (const entry of entries) {
25050
25228
  await copyArtifact(entry, bundleRoot);
25051
25229
  }
@@ -25060,19 +25238,19 @@ var init_artifacts = __esm({
25060
25238
  usage: entry.usage ?? null
25061
25239
  }))
25062
25240
  };
25063
- const manifestPath = import_node_path19.default.join(tempDir, "setup-artifacts.json");
25064
- await import_promises24.default.writeFile(manifestPath, JSON.stringify(manifest, null, 2), "utf8");
25065
- const bundlePath = import_node_path19.default.join(tempDir, "setup-artifacts.tgz");
25241
+ const manifestPath = import_node_path20.default.join(tempDir, "setup-artifacts.json");
25242
+ await import_promises26.default.writeFile(manifestPath, JSON.stringify(manifest, null, 2), "utf8");
25243
+ const bundlePath = import_node_path20.default.join(tempDir, "setup-artifacts.tgz");
25066
25244
  await runCommand2(
25067
25245
  bundleRoot,
25068
25246
  "tar",
25069
25247
  ["-czf", bundlePath, "-C", bundleRoot, "."],
25070
25248
  macCopyfileDisabledEnv2 ? { env: macCopyfileDisabledEnv2 } : void 0
25071
25249
  );
25072
- const finalBundle = import_node_path19.default.join(outputDir, "setup-artifacts.tgz");
25073
- const finalManifest = import_node_path19.default.join(outputDir, "setup-artifacts.json");
25074
- await import_promises24.default.copyFile(bundlePath, finalBundle);
25075
- await import_promises24.default.copyFile(manifestPath, finalManifest);
25250
+ const finalBundle = import_node_path20.default.join(outputDir, "setup-artifacts.tgz");
25251
+ const finalManifest = import_node_path20.default.join(outputDir, "setup-artifacts.json");
25252
+ await import_promises26.default.copyFile(bundlePath, finalBundle);
25253
+ await import_promises26.default.copyFile(manifestPath, finalManifest);
25076
25254
  return {
25077
25255
  bundlePath: finalBundle,
25078
25256
  manifestPath: finalManifest,
@@ -25083,13 +25261,13 @@ var init_artifacts = __esm({
25083
25261
  });
25084
25262
 
25085
25263
  // src/devbox/commands/init/codex/index.ts
25086
- var import_node_path20, import_promises25, import_node_os9, resolveLocalCodexRoot, readLocalCodexAuthCache, syncLocalCodexAuthCacheToSprite, uploadSetupPlan, runRemoteCodexSetup;
25264
+ var import_node_path21, import_promises27, import_node_os8, resolveLocalCodexRoot, readLocalCodexAuthCache, syncLocalCodexAuthCacheToSprite, uploadSetupPlan, runRemoteCodexSetup;
25087
25265
  var init_codex = __esm({
25088
25266
  "src/devbox/commands/init/codex/index.ts"() {
25089
25267
  "use strict";
25090
- import_node_path20 = __toESM(require("node:path"), 1);
25091
- import_promises25 = __toESM(require("node:fs/promises"), 1);
25092
- import_node_os9 = require("node:os");
25268
+ import_node_path21 = __toESM(require("node:path"), 1);
25269
+ import_promises27 = __toESM(require("node:fs/promises"), 1);
25270
+ import_node_os8 = require("node:os");
25093
25271
  init_dist2();
25094
25272
  init_src();
25095
25273
  init_daemonClient();
@@ -25100,12 +25278,12 @@ var init_codex = __esm({
25100
25278
  init_artifacts();
25101
25279
  resolveLocalCodexRoot = () => {
25102
25280
  const configured = (process.env.CODEX_HOME ?? "").trim();
25103
- return configured || import_node_path20.default.join((0, import_node_os9.homedir)(), ".codex");
25281
+ return configured || import_node_path21.default.join((0, import_node_os8.homedir)(), ".codex");
25104
25282
  };
25105
25283
  readLocalCodexAuthCache = async () => {
25106
- const authPath = import_node_path20.default.join(resolveLocalCodexRoot(), "auth.json");
25284
+ const authPath = import_node_path21.default.join(resolveLocalCodexRoot(), "auth.json");
25107
25285
  try {
25108
- return await import_promises25.default.readFile(authPath);
25286
+ return await import_promises27.default.readFile(authPath);
25109
25287
  } catch {
25110
25288
  return null;
25111
25289
  }
@@ -25178,7 +25356,7 @@ var init_codex = __esm({
25178
25356
  "-o",
25179
25357
  "pipefail",
25180
25358
  "-c",
25181
- `mkdir -p ${shellQuote3(import_node_path20.default.posix.dirname(remoteSetupPath))}`
25359
+ `mkdir -p ${shellQuote3(import_node_path21.default.posix.dirname(remoteSetupPath))}`
25182
25360
  ]);
25183
25361
  if (setupDirResult.exitCode !== 0) {
25184
25362
  throw new Error(
@@ -25188,19 +25366,19 @@ var init_codex = __esm({
25188
25366
  await client.writeFile(
25189
25367
  canonical,
25190
25368
  remoteSetupPath,
25191
- await import_promises25.default.readFile(localSetupPath)
25369
+ await import_promises27.default.readFile(localSetupPath)
25192
25370
  );
25193
25371
  if (localArtifactsBundlePath && localArtifactsManifestPath && remoteArtifactsBundlePath && remoteArtifactsManifestPath) {
25194
25372
  status.stage("Uploading setup artifacts");
25195
25373
  await client.writeFile(
25196
25374
  canonical,
25197
25375
  remoteArtifactsBundlePath,
25198
- await import_promises25.default.readFile(localArtifactsBundlePath)
25376
+ await import_promises27.default.readFile(localArtifactsBundlePath)
25199
25377
  );
25200
25378
  await client.writeFile(
25201
25379
  canonical,
25202
25380
  remoteArtifactsManifestPath,
25203
- await import_promises25.default.readFile(localArtifactsManifestPath)
25381
+ await import_promises27.default.readFile(localArtifactsManifestPath)
25204
25382
  );
25205
25383
  }
25206
25384
  };
@@ -26396,14 +26574,13 @@ var init_progress = __esm({
26396
26574
  });
26397
26575
 
26398
26576
  // src/devbox/commands/init/index.ts
26399
- var import_node_crypto12, import_node_path21, import_promises26, import_node_os10, resolveInitStatus, mergeLocalPaths, buildServicesTomlUpdates, extractCheckpointId, writeRemoteServicesToml, enableRemoteServices, throwInitCanceled, promptBeforeOpenBrowser, toPosixPath2, toRepoRelativePath2, isOutsideRepoPath, ensureWorkdirOwnership, ensureGitSafeDirectory, runInit;
26577
+ var import_node_path22, import_promises28, import_node_os9, resolveInitStatus, mergeLocalPaths, ensurePrivateDir, migrateLegacyRepoDevboxDir, buildServicesTomlUpdates, extractCheckpointId, writeRemoteServicesToml, enableRemoteServices, throwInitCanceled, promptBeforeOpenBrowser, toPosixPath2, toRepoRelativePath2, isOutsideRepoPath, ensureWorkdirOwnership, ensureGitSafeDirectory, runInit;
26400
26578
  var init_init = __esm({
26401
26579
  "src/devbox/commands/init/index.ts"() {
26402
26580
  "use strict";
26403
- import_node_crypto12 = require("node:crypto");
26404
- import_node_path21 = __toESM(require("node:path"), 1);
26405
- import_promises26 = __toESM(require("node:fs/promises"), 1);
26406
- import_node_os10 = __toESM(require("node:os"), 1);
26581
+ import_node_path22 = __toESM(require("node:path"), 1);
26582
+ import_promises28 = __toESM(require("node:fs/promises"), 1);
26583
+ import_node_os9 = __toESM(require("node:os"), 1);
26407
26584
  init_dist2();
26408
26585
  init_src();
26409
26586
  init_src();
@@ -26435,6 +26612,49 @@ var init_init = __esm({
26435
26612
  merged.add(repoRoot);
26436
26613
  return [...merged];
26437
26614
  };
26615
+ ensurePrivateDir = async (dir) => {
26616
+ await import_promises28.default.mkdir(dir, { recursive: true, mode: 448 });
26617
+ try {
26618
+ await import_promises28.default.chmod(dir, 448);
26619
+ } catch {
26620
+ }
26621
+ };
26622
+ migrateLegacyRepoDevboxDir = async ({
26623
+ repoRoot,
26624
+ projectDir
26625
+ }) => {
26626
+ const legacyDir = import_node_path22.default.join(repoRoot, ".devbox");
26627
+ try {
26628
+ const stat = await import_promises28.default.stat(legacyDir);
26629
+ if (!stat.isDirectory()) return;
26630
+ } catch {
26631
+ return;
26632
+ }
26633
+ await ensurePrivateDir(projectDir);
26634
+ const entries = [
26635
+ "box.json",
26636
+ "init-state.json",
26637
+ "setup.json",
26638
+ "services.json",
26639
+ "setup-artifacts.tgz",
26640
+ "setup-artifacts.json",
26641
+ "scans",
26642
+ "logs"
26643
+ ];
26644
+ for (const entry of entries) {
26645
+ const src = import_node_path22.default.join(legacyDir, entry);
26646
+ const dest = import_node_path22.default.join(projectDir, entry);
26647
+ try {
26648
+ await import_promises28.default.access(dest);
26649
+ continue;
26650
+ } catch {
26651
+ }
26652
+ try {
26653
+ await import_promises28.default.cp(src, dest, { recursive: true });
26654
+ } catch {
26655
+ }
26656
+ }
26657
+ };
26438
26658
  buildServicesTomlUpdates = (services) => {
26439
26659
  const updates = {};
26440
26660
  for (const service of services) {
@@ -26500,7 +26720,7 @@ var init_init = __esm({
26500
26720
  const merged = mergeServicesToml(baseContent, updates);
26501
26721
  await client.writeFile(
26502
26722
  canonical,
26503
- import_node_path21.default.posix.join(workdir.replace(/\/$/, ""), "devbox.toml"),
26723
+ import_node_path22.default.posix.join(workdir.replace(/\/$/, ""), "devbox.toml"),
26504
26724
  Buffer.from(merged)
26505
26725
  );
26506
26726
  };
@@ -26563,13 +26783,13 @@ var init_init = __esm({
26563
26783
  }
26564
26784
  return true;
26565
26785
  };
26566
- toPosixPath2 = (value) => value.split(import_node_path21.default.sep).join(import_node_path21.default.posix.sep);
26786
+ toPosixPath2 = (value) => value.split(import_node_path22.default.sep).join(import_node_path22.default.posix.sep);
26567
26787
  toRepoRelativePath2 = (repoRoot, filePath) => {
26568
- const resolved = import_node_path21.default.isAbsolute(filePath) ? filePath : import_node_path21.default.resolve(repoRoot, filePath);
26569
- const relative = import_node_path21.default.relative(repoRoot, resolved) || filePath;
26788
+ const resolved = import_node_path22.default.isAbsolute(filePath) ? filePath : import_node_path22.default.resolve(repoRoot, filePath);
26789
+ const relative = import_node_path22.default.relative(repoRoot, resolved) || filePath;
26570
26790
  return toPosixPath2(relative);
26571
26791
  };
26572
- isOutsideRepoPath = (relativePath) => relativePath === ".." || relativePath.startsWith(`..${import_node_path21.default.posix.sep}`);
26792
+ isOutsideRepoPath = (relativePath) => relativePath === ".." || relativePath.startsWith(`..${import_node_path22.default.posix.sep}`);
26573
26793
  ensureWorkdirOwnership = async ({
26574
26794
  client,
26575
26795
  canonical,
@@ -26690,27 +26910,29 @@ var init_init = __esm({
26690
26910
  fn: async () => {
26691
26911
  const cwd = process.cwd();
26692
26912
  const repoRoot2 = await findRepoRoot(cwd);
26693
- const repoName2 = import_node_path21.default.basename(repoRoot2);
26913
+ const repoName2 = import_node_path22.default.basename(repoRoot2);
26694
26914
  const slug2 = slugify(repoName2);
26695
- const localHomeDir2 = process.env.HOME ?? import_node_os10.default.homedir();
26696
- const repoMarker2 = await readRepoMarker(repoRoot2);
26915
+ const localHomeDir2 = process.env.HOME ?? import_node_os9.default.homedir();
26916
+ const projectId2 = await ensureRepoProjectId(repoRoot2);
26917
+ const projectDir2 = resolveDevboxProjectDir(projectId2, localHomeDir2);
26918
+ await migrateLegacyRepoDevboxDir({ repoRoot: repoRoot2, projectDir: projectDir2 });
26919
+ const repoMarker2 = await readRepoMarker(projectDir2);
26697
26920
  const origin2 = await readRepoOrigin(repoRoot2);
26698
26921
  const normalizedOrigin2 = origin2 ? normalizeGitRemoteUrl(origin2) : null;
26699
- const fingerprint2 = origin2 ? fingerprintFromOrigin(origin2) : repoMarker2?.fingerprint ?? fingerprintFromRootCommit(
26700
- await readRootCommit(repoRoot2),
26701
- (0, import_node_crypto12.randomUUID)()
26702
- );
26703
- let initState2 = await readInitState(repoRoot2);
26922
+ const fingerprint2 = projectId2;
26923
+ let initState2 = await readInitState(projectDir2);
26704
26924
  const initFingerprintMismatch2 = Boolean(initState2?.fingerprint) && initState2?.fingerprint !== fingerprint2;
26705
26925
  if (!initFingerprintMismatch2 && initState2?.complete && !initState2.steps.codexApplied) {
26706
26926
  initState2 = { ...initState2, complete: false };
26707
- await writeInitState(repoRoot2, initState2);
26927
+ await writeInitState(projectDir2, initState2);
26708
26928
  }
26709
26929
  return {
26710
26930
  repoRoot: repoRoot2,
26711
26931
  repoName: repoName2,
26712
26932
  slug: slug2,
26713
26933
  localHomeDir: localHomeDir2,
26934
+ projectId: projectId2,
26935
+ projectDir: projectDir2,
26714
26936
  repoMarker: repoMarker2,
26715
26937
  origin: origin2,
26716
26938
  normalizedOrigin: normalizedOrigin2,
@@ -26725,6 +26947,8 @@ var init_init = __esm({
26725
26947
  repoName,
26726
26948
  slug,
26727
26949
  localHomeDir,
26950
+ projectId,
26951
+ projectDir,
26728
26952
  repoMarker,
26729
26953
  origin,
26730
26954
  normalizedOrigin,
@@ -26761,6 +26985,8 @@ var init_init = __esm({
26761
26985
  const recommendsInit = !registryProject && (!initState || initFingerprintMismatch);
26762
26986
  const recommendsForce = !recommendsResume && (!initState || initFingerprintMismatch) && Boolean(registryProject?.initStatus && registryProject.initStatus !== "complete");
26763
26987
  const lines = [];
26988
+ const markerPath = import_node_path22.default.join(projectDir, "box.json");
26989
+ const checkpointPath = import_node_path22.default.join(projectDir, "init-state.json");
26764
26990
  lines.push("INIT STATUS");
26765
26991
  lines.push("");
26766
26992
  lines.push("Repo");
@@ -26768,20 +26994,21 @@ var init_init = __esm({
26768
26994
  lines.push(
26769
26995
  ` origin: ${normalizedOrigin ?? origin ?? "(none)"}`
26770
26996
  );
26771
- lines.push(` fingerprint: ${fingerprint}`);
26997
+ lines.push(` projectId (git config devbox.projectId): ${projectId}`);
26998
+ lines.push(` local state dir: ${projectDir}`);
26772
26999
  lines.push("");
26773
27000
  lines.push("Local state");
26774
27001
  if (repoMarker?.canonical) {
26775
27002
  lines.push(
26776
- ` box marker (.devbox/box.json): present (alias: ${repoMarker.alias ?? "(none)"}, box: ${repoMarker.canonical})`
27003
+ ` box marker (${markerPath}): present (alias: ${repoMarker.alias ?? "(none)"}, box: ${repoMarker.canonical})`
26777
27004
  );
26778
27005
  } else {
26779
- lines.push(" box marker (.devbox/box.json): missing");
27006
+ lines.push(` box marker (${markerPath}): missing`);
26780
27007
  }
26781
27008
  if (initState) {
26782
- const completeText = initFingerprintMismatch ? `${String(Boolean(initState.complete))} (fingerprint mismatch)` : String(Boolean(initState.complete));
27009
+ const completeText = initFingerprintMismatch ? `${String(Boolean(initState.complete))} (projectId mismatch)` : String(Boolean(initState.complete));
26783
27010
  lines.push(
26784
- ` init checkpoint (.devbox/init-state.json): present (updated: ${initState.updatedAt}, complete: ${completeText})`
27011
+ ` init checkpoint (${checkpointPath}): present (updated: ${initState.updatedAt}, complete: ${completeText})`
26785
27012
  );
26786
27013
  if (initState.canonical || initState.alias || initState.workdir) {
26787
27014
  lines.push(
@@ -26809,7 +27036,7 @@ var init_init = __esm({
26809
27036
  lines.push(` ${key}: ${steps[key] ? "yes" : "no"}`);
26810
27037
  }
26811
27038
  } else {
26812
- lines.push(" init checkpoint (.devbox/init-state.json): missing");
27039
+ lines.push(` init checkpoint (${checkpointPath}): missing`);
26813
27040
  }
26814
27041
  lines.push("");
26815
27042
  lines.push("Registry");
@@ -26887,7 +27114,10 @@ var init_init = __esm({
26887
27114
  if (parsed.resume) {
26888
27115
  if (initFingerprintMismatch) {
26889
27116
  throw new Error(
26890
- "Init state does not match this repo. Remove .devbox/init-state.json and run `dvb init` again."
27117
+ `Init state does not match this repo. Remove ${import_node_path22.default.join(
27118
+ projectDir,
27119
+ "init-state.json"
27120
+ )} and run \`dvb init\` again.`
26891
27121
  );
26892
27122
  }
26893
27123
  if (!initState) {
@@ -26938,7 +27168,7 @@ var init_init = __esm({
26938
27168
  },
26939
27169
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
26940
27170
  };
26941
- await writeInitState(repoRoot, initState);
27171
+ await writeInitState(projectDir, initState);
26942
27172
  };
26943
27173
  const recordCodexCheckpoint = async ({
26944
27174
  client: client2,
@@ -27005,27 +27235,29 @@ var init_init = __esm({
27005
27235
  if (!repoMarker?.canonical) {
27006
27236
  throw new Error("Repo is not initialized. Run `dvb init` first.");
27007
27237
  }
27008
- const setupDir2 = import_node_path21.default.join(repoRoot, ".devbox");
27009
- const setupPath2 = import_node_path21.default.join(setupDir2, "setup.json");
27010
- const servicesPath2 = import_node_path21.default.join(setupDir2, "services.json");
27238
+ const setupDir2 = projectDir;
27239
+ const setupPath2 = import_node_path22.default.join(setupDir2, "setup.json");
27240
+ const servicesPath2 = import_node_path22.default.join(setupDir2, "services.json");
27011
27241
  try {
27012
- await import_promises26.default.access(setupPath2);
27242
+ await import_promises28.default.access(setupPath2);
27013
27243
  } catch {
27014
- throw new Error("Missing .devbox/setup.json. Run `dvb init` first.");
27244
+ throw new Error(
27245
+ `Missing setup plan (${setupPath2}). Run \`dvb init\` first.`
27246
+ );
27015
27247
  }
27016
- const localArtifactsBundlePath = import_node_path21.default.join(
27248
+ const localArtifactsBundlePath = import_node_path22.default.join(
27017
27249
  setupDir2,
27018
27250
  "setup-artifacts.tgz"
27019
27251
  );
27020
- const localArtifactsManifestPath = import_node_path21.default.join(
27252
+ const localArtifactsManifestPath = import_node_path22.default.join(
27021
27253
  setupDir2,
27022
27254
  "setup-artifacts.json"
27023
27255
  );
27024
27256
  let artifactsBundlePath = null;
27025
27257
  let artifactsManifestPath = null;
27026
27258
  try {
27027
- await import_promises26.default.access(localArtifactsBundlePath);
27028
- await import_promises26.default.access(localArtifactsManifestPath);
27259
+ await import_promises28.default.access(localArtifactsBundlePath);
27260
+ await import_promises28.default.access(localArtifactsManifestPath);
27029
27261
  artifactsBundlePath = localArtifactsBundlePath;
27030
27262
  artifactsManifestPath = localArtifactsManifestPath;
27031
27263
  } catch {
@@ -27074,17 +27306,17 @@ var init_init = __esm({
27074
27306
  }
27075
27307
  } catch {
27076
27308
  }
27077
- const remoteSetupPath2 = import_node_path21.default.posix.join(
27309
+ const remoteSetupPath2 = import_node_path22.default.posix.join(
27078
27310
  expandedWorkdir2,
27079
27311
  ".devbox",
27080
27312
  "setup.json"
27081
27313
  );
27082
- const remoteArtifactsBundlePath2 = import_node_path21.default.posix.join(
27314
+ const remoteArtifactsBundlePath2 = import_node_path22.default.posix.join(
27083
27315
  expandedWorkdir2,
27084
27316
  ".devbox",
27085
27317
  "setup-artifacts.tgz"
27086
27318
  );
27087
- const remoteArtifactsManifestPath2 = import_node_path21.default.posix.join(
27319
+ const remoteArtifactsManifestPath2 = import_node_path22.default.posix.join(
27088
27320
  expandedWorkdir2,
27089
27321
  ".devbox",
27090
27322
  "setup-artifacts.json"
@@ -27278,17 +27510,17 @@ var init_init = __esm({
27278
27510
  const canonicalHint = parsed.name ?? initState?.canonical ?? existingEntry?.canonical;
27279
27511
  const workdir = `~/${slug}`;
27280
27512
  const expandedWorkdir = expandHome2(workdir);
27281
- const remoteSetupPath = import_node_path21.default.posix.join(
27513
+ const remoteSetupPath = import_node_path22.default.posix.join(
27282
27514
  expandedWorkdir,
27283
27515
  ".devbox",
27284
27516
  "setup.json"
27285
27517
  );
27286
- const remoteArtifactsBundlePath = import_node_path21.default.posix.join(
27518
+ const remoteArtifactsBundlePath = import_node_path22.default.posix.join(
27287
27519
  expandedWorkdir,
27288
27520
  ".devbox",
27289
27521
  "setup-artifacts.tgz"
27290
27522
  );
27291
- const remoteArtifactsManifestPath = import_node_path21.default.posix.join(
27523
+ const remoteArtifactsManifestPath = import_node_path22.default.posix.join(
27292
27524
  expandedWorkdir,
27293
27525
  ".devbox",
27294
27526
  "setup-artifacts.json"
@@ -27317,7 +27549,7 @@ var init_init = __esm({
27317
27549
  return { config: config2, client: client2, controlPlaneToken: controlPlaneToken2 };
27318
27550
  }
27319
27551
  });
27320
- const username = import_node_os10.default.userInfo().username;
27552
+ const username = import_node_os9.default.userInfo().username;
27321
27553
  let canonical = (shouldResume && initState?.canonical ? initState.canonical : null) ?? canonicalHint ?? `${username}-${slug}`;
27322
27554
  const createSprite = async (name) => {
27323
27555
  try {
@@ -27531,13 +27763,14 @@ var init_init = __esm({
27531
27763
  }
27532
27764
  }
27533
27765
  });
27534
- const setupDir = import_node_path21.default.join(repoRoot, ".devbox");
27535
- const setupPath = import_node_path21.default.join(setupDir, "setup.json");
27536
- const servicesPath = import_node_path21.default.join(setupDir, "services.json");
27537
- const scansDir = import_node_path21.default.join(setupDir, "scans");
27538
- const setupEnvSecretsScanPath = import_node_path21.default.join(scansDir, "setup-env-secrets.json");
27539
- const setupExternalScanPath = import_node_path21.default.join(scansDir, "setup-external.json");
27540
- const setupExtraArtifactsScanPath = import_node_path21.default.join(
27766
+ const setupDir = projectDir;
27767
+ const setupPath = import_node_path22.default.join(setupDir, "setup.json");
27768
+ const servicesPath = import_node_path22.default.join(setupDir, "services.json");
27769
+ const scansDir = import_node_path22.default.join(setupDir, "scans");
27770
+ const logDir = import_node_path22.default.join(setupDir, "logs");
27771
+ const setupEnvSecretsScanPath = import_node_path22.default.join(scansDir, "setup-env-secrets.json");
27772
+ const setupExternalScanPath = import_node_path22.default.join(scansDir, "setup-external.json");
27773
+ const setupExtraArtifactsScanPath = import_node_path22.default.join(
27541
27774
  scansDir,
27542
27775
  "setup-extra-artifacts.json"
27543
27776
  );
@@ -27551,11 +27784,15 @@ var init_init = __esm({
27551
27784
  const skipCodexApply = nonInteractive || shouldResume && initState?.steps.codexApplied;
27552
27785
  let approvedPlan = null;
27553
27786
  let approvedServices = null;
27554
- const setupTempDir = await import_promises26.default.mkdtemp(
27555
- import_node_path21.default.join(import_node_os10.default.tmpdir(), "devbox-setup-")
27787
+ const setupTempDir = await import_promises28.default.mkdtemp(
27788
+ import_node_path22.default.join(import_node_os9.default.tmpdir(), "devbox-setup-")
27556
27789
  );
27557
27790
  try {
27558
- await import_promises26.default.mkdir(setupDir, { recursive: true });
27791
+ await import_promises28.default.mkdir(setupDir, { recursive: true, mode: 448 });
27792
+ try {
27793
+ await import_promises28.default.chmod(setupDir, 448);
27794
+ } catch {
27795
+ }
27559
27796
  const tryReadSetupPlan = async () => {
27560
27797
  try {
27561
27798
  return await readSetupPlan(setupPath);
@@ -27665,7 +27902,7 @@ var init_init = __esm({
27665
27902
  throw new Error("Services schema path missing.");
27666
27903
  }
27667
27904
  if (needsSetupScan) {
27668
- await import_promises26.default.mkdir(scansDir, { recursive: true });
27905
+ await import_promises28.default.mkdir(scansDir, { recursive: true });
27669
27906
  }
27670
27907
  const runCodexScanWithImmediateRetry = async ({
27671
27908
  run: run3,
@@ -27679,7 +27916,7 @@ var init_init = __esm({
27679
27916
  let out = await read();
27680
27917
  if (shouldRetry(out)) {
27681
27918
  update("retrying");
27682
- await import_promises26.default.rm(outputPath, { force: true });
27919
+ await import_promises28.default.rm(outputPath, { force: true });
27683
27920
  await run3();
27684
27921
  out = await read();
27685
27922
  }
@@ -27693,6 +27930,7 @@ var init_init = __esm({
27693
27930
  const envSecretsPromise = !needsSetupScan ? Promise.resolve(null) : !needsEnvSecretsScan ? Promise.resolve(envSecretsScan) : runCodexScanWithImmediateRetry({
27694
27931
  run: async () => await runLocalSetupEnvSecretsScan({
27695
27932
  cwd: repoRoot,
27933
+ logDir,
27696
27934
  schemaPath: envSecretsSchemaPath,
27697
27935
  outputPath: setupEnvSecretsScanPath,
27698
27936
  onProgress: updateEnvSecrets
@@ -27709,6 +27947,7 @@ var init_init = __esm({
27709
27947
  const externalPromise = !needsSetupScan ? Promise.resolve(null) : !needsExternalScan ? Promise.resolve(externalScan) : runCodexScanWithImmediateRetry({
27710
27948
  run: async () => await runLocalSetupExternalScan({
27711
27949
  cwd: repoRoot,
27950
+ logDir,
27712
27951
  schemaPath: externalSchemaPath,
27713
27952
  outputPath: setupExternalScanPath,
27714
27953
  homeDir: localHomeDir,
@@ -27726,6 +27965,7 @@ var init_init = __esm({
27726
27965
  const extraArtifactsPromise = !needsSetupScan ? Promise.resolve(null) : !needsExtraArtifactsScan ? Promise.resolve(extraArtifactsScan) : runCodexScanWithImmediateRetry({
27727
27966
  run: async () => await runLocalSetupExtraArtifactsScan({
27728
27967
  cwd: repoRoot,
27968
+ logDir,
27729
27969
  schemaPath: extraArtifactsSchemaPath,
27730
27970
  outputPath: setupExtraArtifactsScanPath,
27731
27971
  onProgress: updateExtraArtifacts
@@ -27741,6 +27981,7 @@ var init_init = __esm({
27741
27981
  const servicesPromise = !needsServicesScan ? Promise.resolve(servicesPlan) : runCodexScanWithImmediateRetry({
27742
27982
  run: async () => await runLocalServicesScan({
27743
27983
  cwd: repoRoot,
27984
+ logDir,
27744
27985
  schemaPath: servicesSchemaPath,
27745
27986
  outputPath: servicesPath,
27746
27987
  homeDir: localHomeDir,
@@ -27934,12 +28175,12 @@ var init_init = __esm({
27934
28175
  const readPathInfo = async (candidatePath) => {
27935
28176
  const cached = statCache.get(candidatePath);
27936
28177
  if (cached) return cached;
27937
- const resolved = import_node_path21.default.isAbsolute(candidatePath) ? candidatePath : import_node_path21.default.resolve(repoRoot, candidatePath);
28178
+ const resolved = import_node_path22.default.isAbsolute(candidatePath) ? candidatePath : import_node_path22.default.resolve(repoRoot, candidatePath);
27938
28179
  const relative = toRepoRelativePath2(repoRoot, candidatePath);
27939
28180
  const outsideRepo = isOutsideRepoPath(relative);
27940
28181
  let isDirectory = false;
27941
28182
  try {
27942
- const stat = await import_promises26.default.stat(resolved);
28183
+ const stat = await import_promises28.default.stat(resolved);
27943
28184
  isDirectory = stat.isDirectory();
27944
28185
  } catch {
27945
28186
  isDirectory = false;
@@ -28122,7 +28363,7 @@ var init_init = __esm({
28122
28363
  });
28123
28364
  }
28124
28365
  } finally {
28125
- await import_promises26.default.rm(setupTempDir, { recursive: true, force: true });
28366
+ await import_promises28.default.rm(setupTempDir, { recursive: true, force: true });
28126
28367
  }
28127
28368
  const skipProvision = shouldResume && initState?.steps.workdirProvisioned;
28128
28369
  if (skipProvision && !skipSetupUpload) {
@@ -28137,8 +28378,8 @@ var init_init = __esm({
28137
28378
  remoteSetupPath,
28138
28379
  localArtifactsBundlePath: setupArtifacts?.bundlePath ?? null,
28139
28380
  localArtifactsManifestPath: setupArtifacts?.manifestPath ?? null,
28140
- remoteArtifactsBundlePath: setupArtifacts ? import_node_path21.default.posix.join(expandedWorkdir, ".devbox", "setup-artifacts.tgz") : null,
28141
- remoteArtifactsManifestPath: setupArtifacts ? import_node_path21.default.posix.join(
28381
+ remoteArtifactsBundlePath: setupArtifacts ? import_node_path22.default.posix.join(expandedWorkdir, ".devbox", "setup-artifacts.tgz") : null,
28382
+ remoteArtifactsManifestPath: setupArtifacts ? import_node_path22.default.posix.join(
28142
28383
  expandedWorkdir,
28143
28384
  ".devbox",
28144
28385
  "setup-artifacts.json"
@@ -28152,15 +28393,14 @@ var init_init = __esm({
28152
28393
  resolveInitStatus(initState?.steps, initState?.complete)
28153
28394
  );
28154
28395
  } else if (!skipProvision || !skipSetupUpload) {
28155
- const tempDir = await import_promises26.default.mkdtemp(import_node_path21.default.join(import_node_os10.default.tmpdir(), "devbox-init-"));
28156
- const bundlePath = import_node_path21.default.join(tempDir, "repo.bundle");
28157
- const archivePath = import_node_path21.default.join(tempDir, "repo.tgz");
28158
- const gitMetaPath = import_node_path21.default.join(tempDir, "git-meta.tgz");
28159
- const gitMetaListPath = import_node_path21.default.join(tempDir, "git-meta.list");
28160
- const stagedPatchPath = import_node_path21.default.join(tempDir, "staged.patch");
28161
- const unstagedPatchPath = import_node_path21.default.join(tempDir, "unstaged.patch");
28162
- const untrackedPath = import_node_path21.default.join(tempDir, "untracked.tgz");
28163
- const untrackedListPath = import_node_path21.default.join(tempDir, "untracked.list");
28396
+ const tempDir = await import_promises28.default.mkdtemp(import_node_path22.default.join(import_node_os9.default.tmpdir(), "devbox-init-"));
28397
+ const bundlePath = import_node_path22.default.join(tempDir, "repo.bundle");
28398
+ const gitMetaPath = import_node_path22.default.join(tempDir, "git-meta.tgz");
28399
+ const gitMetaListPath = import_node_path22.default.join(tempDir, "git-meta.list");
28400
+ const stagedPatchPath = import_node_path22.default.join(tempDir, "staged.patch");
28401
+ const unstagedPatchPath = import_node_path22.default.join(tempDir, "unstaged.patch");
28402
+ const untrackedPath = import_node_path22.default.join(tempDir, "untracked.tgz");
28403
+ const untrackedListPath = import_node_path22.default.join(tempDir, "untracked.list");
28164
28404
  const globalGitConfigSources = await readGlobalGitConfigFiles(repoRoot);
28165
28405
  const globalGitConfigMappings = mapGlobalGitConfigDestinations(
28166
28406
  globalGitConfigSources,
@@ -28168,12 +28408,11 @@ var init_init = __esm({
28168
28408
  );
28169
28409
  try {
28170
28410
  const remoteBundlePath = "/home/sprite/.devbox/upload.bundle";
28171
- const remoteArchivePath = "/home/sprite/.devbox/upload.tgz";
28172
28411
  const remoteGitMetaPath = "/home/sprite/.devbox/git-meta.tgz";
28173
28412
  const remoteStagedPatchPath = "/home/sprite/.devbox/staged.patch";
28174
28413
  const remoteUnstagedPatchPath = "/home/sprite/.devbox/unstaged.patch";
28175
28414
  const remoteUntrackedPath = "/home/sprite/.devbox/untracked.tgz";
28176
- const remoteHasGit = await runInitStep({
28415
+ await runInitStep({
28177
28416
  enabled: progressEnabled,
28178
28417
  title: "Preparing remote directories",
28179
28418
  fn: async ({ status }) => {
@@ -28183,16 +28422,20 @@ var init_init = __esm({
28183
28422
  "-lc",
28184
28423
  "git --version"
28185
28424
  ]);
28186
- const remoteHasGit2 = gitCheck.exitCode === 0;
28425
+ if (gitCheck.exitCode !== 0) {
28426
+ const details = gitCheck.stderr || gitCheck.stdout || "";
28427
+ throw new Error(
28428
+ details ? `Remote git unavailable: ${details.trim()}` : "Remote git unavailable"
28429
+ );
28430
+ }
28187
28431
  const remoteDirs = /* @__PURE__ */ new Set();
28188
- remoteDirs.add(import_node_path21.default.posix.dirname(remoteBundlePath));
28189
- remoteDirs.add(import_node_path21.default.posix.dirname(remoteArchivePath));
28190
- remoteDirs.add(import_node_path21.default.posix.dirname(remoteGitMetaPath));
28191
- remoteDirs.add(import_node_path21.default.posix.dirname(remoteStagedPatchPath));
28192
- remoteDirs.add(import_node_path21.default.posix.dirname(remoteUnstagedPatchPath));
28193
- remoteDirs.add(import_node_path21.default.posix.dirname(remoteUntrackedPath));
28432
+ remoteDirs.add(import_node_path22.default.posix.dirname(remoteBundlePath));
28433
+ remoteDirs.add(import_node_path22.default.posix.dirname(remoteGitMetaPath));
28434
+ remoteDirs.add(import_node_path22.default.posix.dirname(remoteStagedPatchPath));
28435
+ remoteDirs.add(import_node_path22.default.posix.dirname(remoteUnstagedPatchPath));
28436
+ remoteDirs.add(import_node_path22.default.posix.dirname(remoteUntrackedPath));
28194
28437
  for (const mapping of globalGitConfigMappings) {
28195
- remoteDirs.add(import_node_path21.default.posix.dirname(mapping.dest));
28438
+ remoteDirs.add(import_node_path22.default.posix.dirname(mapping.dest));
28196
28439
  }
28197
28440
  if (remoteDirs.size > 0) {
28198
28441
  status.stage("Preparing remote directories");
@@ -28207,7 +28450,6 @@ var init_init = __esm({
28207
28450
  );
28208
28451
  }
28209
28452
  }
28210
- return remoteHasGit2;
28211
28453
  }
28212
28454
  });
28213
28455
  const { headState, gitCommonDir, worktreeState, copyWorktree } = await runInitStep({
@@ -28242,63 +28484,37 @@ var init_init = __esm({
28242
28484
  let stagedPatchCreated = false;
28243
28485
  let unstagedPatchCreated = false;
28244
28486
  let untrackedCreated = false;
28245
- if (remoteHasGit) {
28246
- status.stage("Packaging repo bundle");
28247
- await runCommand2(repoRoot, "git", [
28248
- "bundle",
28249
- "create",
28250
- bundlePath,
28251
- "--all"
28252
- ]);
28253
- status.stage("Packaging git metadata");
28254
- gitMetaCreated = await createGitMetaArchive(
28255
- gitCommonDir,
28256
- gitMetaPath,
28257
- gitMetaListPath
28487
+ status.stage("Packaging repo bundle");
28488
+ await runCommand2(repoRoot, "git", [
28489
+ "bundle",
28490
+ "create",
28491
+ bundlePath,
28492
+ "--all"
28493
+ ]);
28494
+ status.stage("Packaging git metadata");
28495
+ gitMetaCreated = await createGitMetaArchive(
28496
+ gitCommonDir,
28497
+ gitMetaPath,
28498
+ gitMetaListPath
28499
+ );
28500
+ if (copyWorktree) {
28501
+ status.stage("Packaging repo changes");
28502
+ stagedPatchCreated = await writePatch(
28503
+ repoRoot,
28504
+ ["diff", "--binary", "--cached"],
28505
+ stagedPatchPath
28506
+ );
28507
+ unstagedPatchCreated = await writePatch(
28508
+ repoRoot,
28509
+ ["diff", "--binary"],
28510
+ unstagedPatchPath
28511
+ );
28512
+ untrackedCreated = await createFileListArchive(
28513
+ repoRoot,
28514
+ worktreeState.untracked,
28515
+ untrackedPath,
28516
+ untrackedListPath
28258
28517
  );
28259
- if (copyWorktree) {
28260
- status.stage("Packaging repo changes");
28261
- stagedPatchCreated = await writePatch(
28262
- repoRoot,
28263
- ["diff", "--binary", "--cached"],
28264
- stagedPatchPath
28265
- );
28266
- unstagedPatchCreated = await writePatch(
28267
- repoRoot,
28268
- ["diff", "--binary"],
28269
- unstagedPatchPath
28270
- );
28271
- untrackedCreated = await createFileListArchive(
28272
- repoRoot,
28273
- worktreeState.untracked,
28274
- untrackedPath,
28275
- untrackedListPath
28276
- );
28277
- }
28278
- } else {
28279
- status.stage("Packaging repo archive");
28280
- if (copyWorktree) {
28281
- const workingFiles = await readNullSeparatedPaths(repoRoot, [
28282
- "ls-files",
28283
- "--cached",
28284
- "--others",
28285
- "--exclude-standard"
28286
- ]);
28287
- await createFileListArchive(
28288
- repoRoot,
28289
- workingFiles,
28290
- archivePath,
28291
- untrackedListPath
28292
- );
28293
- } else {
28294
- await runCommand2(repoRoot, "git", [
28295
- "archive",
28296
- "--format=tar.gz",
28297
- "-o",
28298
- archivePath,
28299
- "HEAD"
28300
- ]);
28301
- }
28302
28518
  }
28303
28519
  return {
28304
28520
  gitMetaCreated,
@@ -28312,51 +28528,42 @@ var init_init = __esm({
28312
28528
  enabled: progressEnabled,
28313
28529
  title: "Uploading repo",
28314
28530
  fn: async ({ status }) => {
28315
- if (remoteHasGit) {
28316
- status.stage("Uploading repo bundle");
28317
- const bundleData = await import_promises26.default.readFile(bundlePath);
28318
- await client.writeFile(canonical, remoteBundlePath, bundleData);
28319
- if (packaged.gitMetaCreated) {
28320
- status.stage("Uploading git metadata");
28321
- const gitMetaData = await import_promises26.default.readFile(gitMetaPath);
28322
- await client.writeFile(canonical, remoteGitMetaPath, gitMetaData);
28323
- }
28324
- if (packaged.stagedPatchCreated) {
28325
- status.stage("Uploading staged changes");
28326
- await client.writeFile(
28327
- canonical,
28328
- remoteStagedPatchPath,
28329
- await import_promises26.default.readFile(stagedPatchPath)
28330
- );
28331
- }
28332
- if (packaged.unstagedPatchCreated) {
28333
- status.stage("Uploading unstaged changes");
28334
- await client.writeFile(
28335
- canonical,
28336
- remoteUnstagedPatchPath,
28337
- await import_promises26.default.readFile(unstagedPatchPath)
28338
- );
28339
- }
28340
- if (packaged.untrackedCreated) {
28341
- status.stage("Uploading untracked files");
28342
- await client.writeFile(
28343
- canonical,
28344
- remoteUntrackedPath,
28345
- await import_promises26.default.readFile(untrackedPath)
28346
- );
28347
- }
28348
- } else {
28349
- status.stage("Uploading repo archive");
28531
+ status.stage("Uploading repo bundle");
28532
+ const bundleData = await import_promises28.default.readFile(bundlePath);
28533
+ await client.writeFile(canonical, remoteBundlePath, bundleData);
28534
+ if (packaged.gitMetaCreated) {
28535
+ status.stage("Uploading git metadata");
28536
+ const gitMetaData = await import_promises28.default.readFile(gitMetaPath);
28537
+ await client.writeFile(canonical, remoteGitMetaPath, gitMetaData);
28538
+ }
28539
+ if (packaged.stagedPatchCreated) {
28540
+ status.stage("Uploading staged changes");
28350
28541
  await client.writeFile(
28351
28542
  canonical,
28352
- remoteArchivePath,
28353
- await import_promises26.default.readFile(archivePath)
28543
+ remoteStagedPatchPath,
28544
+ await import_promises28.default.readFile(stagedPatchPath)
28545
+ );
28546
+ }
28547
+ if (packaged.unstagedPatchCreated) {
28548
+ status.stage("Uploading unstaged changes");
28549
+ await client.writeFile(
28550
+ canonical,
28551
+ remoteUnstagedPatchPath,
28552
+ await import_promises28.default.readFile(unstagedPatchPath)
28553
+ );
28554
+ }
28555
+ if (packaged.untrackedCreated) {
28556
+ status.stage("Uploading untracked files");
28557
+ await client.writeFile(
28558
+ canonical,
28559
+ remoteUntrackedPath,
28560
+ await import_promises28.default.readFile(untrackedPath)
28354
28561
  );
28355
28562
  }
28356
28563
  if (globalGitConfigMappings.length > 0) {
28357
28564
  status.stage("Uploading git config");
28358
28565
  for (const mapping of globalGitConfigMappings) {
28359
- const data = await import_promises26.default.readFile(mapping.source);
28566
+ const data = await import_promises28.default.readFile(mapping.source);
28360
28567
  await client.writeFile(canonical, mapping.dest, data);
28361
28568
  }
28362
28569
  }
@@ -28367,70 +28574,44 @@ var init_init = __esm({
28367
28574
  title: "Provisioning workdir",
28368
28575
  fn: async () => {
28369
28576
  const backup = `${expandedWorkdir}.bak-${Date.now()}`;
28370
- if (remoteHasGit) {
28371
- const checkoutCommand = headState.branch ? `git checkout -B ${shellQuote3(headState.branch)} ${shellQuote3(headState.commit)}` : `git checkout --detach ${shellQuote3(headState.commit)}`;
28372
- const remoteCommand = [
28373
- "set -euo pipefail",
28374
- "unset GIT_DIR GIT_WORK_TREE GIT_INDEX_FILE",
28375
- `if [ -d ${shellQuote3(expandedWorkdir)} ]; then`,
28376
- parsed.force ? ` mv ${shellQuote3(expandedWorkdir)} ${shellQuote3(backup)}` : ` echo "Target exists: ${expandedWorkdir}" >&2; exit 1`,
28377
- "fi",
28378
- `mkdir -p ${shellQuote3(import_node_path21.default.dirname(expandedWorkdir))}`,
28379
- `git init -b devbox-init ${shellQuote3(expandedWorkdir)}`,
28380
- `cd ${shellQuote3(expandedWorkdir)}`,
28381
- `git fetch ${shellQuote3(remoteBundlePath)} 'refs/*:refs/*'`,
28382
- `if [ -f ${shellQuote3(remoteGitMetaPath)} ]; then`,
28383
- ` tar -xzf ${shellQuote3(remoteGitMetaPath)} -C .git`,
28384
- "fi",
28385
- checkoutCommand,
28386
- `if [ -f ${shellQuote3(remoteStagedPatchPath)} ]; then`,
28387
- ` git apply --index ${shellQuote3(remoteStagedPatchPath)}`,
28388
- "fi",
28389
- `if [ -f ${shellQuote3(remoteUnstagedPatchPath)} ]; then`,
28390
- ` git apply ${shellQuote3(remoteUnstagedPatchPath)}`,
28391
- "fi",
28392
- `if [ -f ${shellQuote3(remoteUntrackedPath)} ]; then`,
28393
- ` tar -xzf ${shellQuote3(remoteUntrackedPath)} -C .`,
28394
- "fi"
28395
- ].join("\n");
28396
- const execResult = await client.exec(canonical, [
28397
- "/bin/bash",
28398
- "--noprofile",
28399
- "--norc",
28400
- "-e",
28401
- "-u",
28402
- "-o",
28403
- "pipefail",
28404
- "-c",
28405
- remoteCommand
28406
- ]);
28407
- if (execResult.exitCode !== 0) {
28408
- throw new Error(execResult.stderr || "Remote init failed");
28409
- }
28410
- } else {
28411
- const remoteCommand = [
28412
- "set -euo pipefail",
28413
- "unset GIT_DIR GIT_WORK_TREE GIT_INDEX_FILE",
28414
- `if [ -d ${shellQuote3(expandedWorkdir)} ]; then`,
28415
- parsed.force ? ` mv ${shellQuote3(expandedWorkdir)} ${shellQuote3(backup)}` : ` echo "Target exists: ${expandedWorkdir}" >&2; exit 1`,
28416
- "fi",
28417
- `mkdir -p ${shellQuote3(expandedWorkdir)}`,
28418
- `tar -xzf ${shellQuote3(remoteArchivePath)} -C ${shellQuote3(expandedWorkdir)}`
28419
- ].join("\n");
28420
- const execResult = await client.exec(canonical, [
28421
- "/bin/bash",
28422
- "--noprofile",
28423
- "--norc",
28424
- "-e",
28425
- "-u",
28426
- "-o",
28427
- "pipefail",
28428
- "-c",
28429
- remoteCommand
28430
- ]);
28431
- if (execResult.exitCode !== 0) {
28432
- throw new Error(execResult.stderr || "Remote init failed");
28433
- }
28577
+ const checkoutCommand = headState.branch ? `git checkout -B ${shellQuote3(headState.branch)} ${shellQuote3(headState.commit)}` : `git checkout --detach ${shellQuote3(headState.commit)}`;
28578
+ const remoteCommand = [
28579
+ "set -euo pipefail",
28580
+ "unset GIT_DIR GIT_WORK_TREE GIT_INDEX_FILE",
28581
+ `if [ -d ${shellQuote3(expandedWorkdir)} ]; then`,
28582
+ parsed.force ? ` mv ${shellQuote3(expandedWorkdir)} ${shellQuote3(backup)}` : ` echo "Target exists: ${expandedWorkdir}" >&2; exit 1`,
28583
+ "fi",
28584
+ `mkdir -p ${shellQuote3(import_node_path22.default.dirname(expandedWorkdir))}`,
28585
+ `git init -b devbox-init ${shellQuote3(expandedWorkdir)}`,
28586
+ `cd ${shellQuote3(expandedWorkdir)}`,
28587
+ `git fetch ${shellQuote3(remoteBundlePath)} 'refs/*:refs/*'`,
28588
+ `if [ -f ${shellQuote3(remoteGitMetaPath)} ]; then`,
28589
+ ` tar -xzf ${shellQuote3(remoteGitMetaPath)} -C .git`,
28590
+ "fi",
28591
+ checkoutCommand,
28592
+ `if [ -f ${shellQuote3(remoteStagedPatchPath)} ]; then`,
28593
+ ` git apply --index ${shellQuote3(remoteStagedPatchPath)}`,
28594
+ "fi",
28595
+ `if [ -f ${shellQuote3(remoteUnstagedPatchPath)} ]; then`,
28596
+ ` git apply ${shellQuote3(remoteUnstagedPatchPath)}`,
28597
+ "fi",
28598
+ `if [ -f ${shellQuote3(remoteUntrackedPath)} ]; then`,
28599
+ ` tar -xzf ${shellQuote3(remoteUntrackedPath)} -C .`,
28600
+ "fi"
28601
+ ].join("\n");
28602
+ const execResult = await client.exec(canonical, [
28603
+ "/bin/bash",
28604
+ "--noprofile",
28605
+ "--norc",
28606
+ "-e",
28607
+ "-u",
28608
+ "-o",
28609
+ "pipefail",
28610
+ "-c",
28611
+ remoteCommand
28612
+ ]);
28613
+ if (execResult.exitCode !== 0) {
28614
+ throw new Error(execResult.stderr || "Remote init failed");
28434
28615
  }
28435
28616
  await updateInitState({ steps: { workdirProvisioned: true } });
28436
28617
  }
@@ -28447,12 +28628,12 @@ var init_init = __esm({
28447
28628
  remoteSetupPath,
28448
28629
  localArtifactsBundlePath: setupArtifacts?.bundlePath ?? null,
28449
28630
  localArtifactsManifestPath: setupArtifacts?.manifestPath ?? null,
28450
- remoteArtifactsBundlePath: setupArtifacts ? import_node_path21.default.posix.join(
28631
+ remoteArtifactsBundlePath: setupArtifacts ? import_node_path22.default.posix.join(
28451
28632
  expandedWorkdir,
28452
28633
  ".devbox",
28453
28634
  "setup-artifacts.tgz"
28454
28635
  ) : null,
28455
- remoteArtifactsManifestPath: setupArtifacts ? import_node_path21.default.posix.join(
28636
+ remoteArtifactsManifestPath: setupArtifacts ? import_node_path22.default.posix.join(
28456
28637
  expandedWorkdir,
28457
28638
  ".devbox",
28458
28639
  "setup-artifacts.json"
@@ -28467,7 +28648,7 @@ var init_init = __esm({
28467
28648
  );
28468
28649
  }
28469
28650
  } finally {
28470
- await import_promises26.default.rm(tempDir, { recursive: true, force: true });
28651
+ await import_promises28.default.rm(tempDir, { recursive: true, force: true });
28471
28652
  }
28472
28653
  }
28473
28654
  await runInitStep({
@@ -28801,8 +28982,7 @@ Tip: re-run with DEVBOX_LOG_LEVEL=info to see Sprite exec logs on stderr.`
28801
28982
  enabled: progressEnabled,
28802
28983
  title: "Writing local metadata",
28803
28984
  fn: async () => {
28804
- await ensureDevboxToml(repoRoot, repoName, slug);
28805
- await writeRepoMarker(repoRoot, { fingerprint, canonical, alias });
28985
+ await writeRepoMarker(projectDir, { fingerprint, canonical, alias });
28806
28986
  }
28807
28987
  });
28808
28988
  await runInitStep({
@@ -28824,18 +29004,6 @@ Tip: re-run with DEVBOX_LOG_LEVEL=info to see Sprite exec logs on stderr.`
28824
29004
  }
28825
29005
  }
28826
29006
  });
28827
- try {
28828
- const gitignore = await import_promises26.default.readFile(
28829
- import_node_path21.default.join(repoRoot, ".gitignore"),
28830
- "utf8"
28831
- );
28832
- if (!gitignore.includes(".devbox")) {
28833
- console.log(
28834
- "Note: add .devbox/ to .gitignore to keep local marker private."
28835
- );
28836
- }
28837
- } catch {
28838
- }
28839
29007
  const skipSetupArtifactsStage = skipCodexApply || shouldResume && initState?.steps.setupArtifactsStaged;
28840
29008
  if (!skipSetupArtifactsStage) {
28841
29009
  await runInitStep({
@@ -29264,13 +29432,13 @@ var init_logout = __esm({
29264
29432
  });
29265
29433
 
29266
29434
  // src/devbox/commands/mount.ts
29267
- var import_node_child_process10, import_promises27, import_node_path22, parseMountArgs, resolveMountDir, commandExists, ensureLocalDependencies, resolveCanonicalBox, runCommand5, forwardSshPort, stopSshPort, unmount, runMount, runUnmount;
29435
+ var import_node_child_process10, import_promises29, import_node_path23, parseMountArgs, resolveMountDir, commandExists, ensureLocalDependencies, resolveCanonicalBox, runCommand5, forwardSshPort, stopSshPort, unmount, runMount, runUnmount;
29268
29436
  var init_mount = __esm({
29269
29437
  "src/devbox/commands/mount.ts"() {
29270
29438
  "use strict";
29271
29439
  import_node_child_process10 = require("node:child_process");
29272
- import_promises27 = __toESM(require("node:fs/promises"), 1);
29273
- import_node_path22 = __toESM(require("node:path"), 1);
29440
+ import_promises29 = __toESM(require("node:fs/promises"), 1);
29441
+ import_node_path23 = __toESM(require("node:path"), 1);
29274
29442
  init_src();
29275
29443
  init_daemonClient();
29276
29444
  init_auth();
@@ -29291,7 +29459,7 @@ var init_mount = __esm({
29291
29459
  }
29292
29460
  return parsed;
29293
29461
  };
29294
- resolveMountDir = (canonical) => import_node_path22.default.join(resolveDevboxDir(), "mounts", canonical);
29462
+ resolveMountDir = (canonical) => import_node_path23.default.join(resolveDevboxDir(), "mounts", canonical);
29295
29463
  commandExists = (command) => {
29296
29464
  const checker = process.platform === "win32" ? "where" : "which";
29297
29465
  const result = (0, import_node_child_process10.spawnSync)(checker, [command], { stdio: "ignore" });
@@ -29394,7 +29562,7 @@ var init_mount = __esm({
29394
29562
  await ensureRemoteMountAccess(client, canonical, publicKey);
29395
29563
  await ensureSshdService(client, canonical);
29396
29564
  const mountDir = resolveMountDir(canonical);
29397
- await import_promises27.default.mkdir(mountDir, { recursive: true });
29565
+ await import_promises29.default.mkdir(mountDir, { recursive: true });
29398
29566
  const localPort = await forwardSshPort(socketInfo.socketPath, canonical);
29399
29567
  const sshfsArgs = [
29400
29568
  "-o",
@@ -30353,11 +30521,11 @@ var init_services = __esm({
30353
30521
  };
30354
30522
  loadConfigFromSprite = async (client, canonical) => {
30355
30523
  const workdir = await resolveProjectWorkdir(client, canonical);
30356
- const path24 = workdir ? `${workdir.replace(/\/$/, "")}/devbox.toml` : null;
30524
+ const path25 = workdir ? `${workdir.replace(/\/$/, "")}/devbox.toml` : null;
30357
30525
  if (!workdir) {
30358
30526
  return {
30359
30527
  workdir: null,
30360
- path: path24,
30528
+ path: path25,
30361
30529
  content: null,
30362
30530
  services: {},
30363
30531
  missing: true,
@@ -30372,7 +30540,7 @@ var init_services = __esm({
30372
30540
  const content = Buffer.from(bytes).toString("utf8");
30373
30541
  return {
30374
30542
  workdir,
30375
- path: path24,
30543
+ path: path25,
30376
30544
  content,
30377
30545
  services: parseServicesToml(content),
30378
30546
  missing: false
@@ -30381,7 +30549,7 @@ var init_services = __esm({
30381
30549
  if (error instanceof SpritesApiError && error.status === 404) {
30382
30550
  return {
30383
30551
  workdir,
30384
- path: path24,
30552
+ path: path25,
30385
30553
  content: null,
30386
30554
  services: {},
30387
30555
  missing: true
@@ -30389,7 +30557,7 @@ var init_services = __esm({
30389
30557
  }
30390
30558
  return {
30391
30559
  workdir,
30392
- path: path24,
30560
+ path: path25,
30393
30561
  content: null,
30394
30562
  services: {},
30395
30563
  missing: false,
@@ -30682,12 +30850,12 @@ var init_services = __esm({
30682
30850
  });
30683
30851
 
30684
30852
  // src/devbox/commands/setup.ts
30685
- var import_node_crypto13, import_promises28, parseSetupArgs, promptForValue2, listSprites2, runSetup;
30853
+ var import_node_crypto12, import_promises30, parseSetupArgs, promptForValue2, listSprites2, runSetup;
30686
30854
  var init_setup = __esm({
30687
30855
  "src/devbox/commands/setup.ts"() {
30688
30856
  "use strict";
30689
- import_node_crypto13 = require("node:crypto");
30690
- import_promises28 = __toESM(require("node:readline/promises"), 1);
30857
+ import_node_crypto12 = require("node:crypto");
30858
+ import_promises30 = __toESM(require("node:readline/promises"), 1);
30691
30859
  init_src();
30692
30860
  init_src();
30693
30861
  init_auth();
@@ -30736,7 +30904,7 @@ var init_setup = __esm({
30736
30904
  if (!process.stdin.isTTY) {
30737
30905
  throw new Error(`Missing ${label} (non-interactive)`);
30738
30906
  }
30739
- const rl = import_promises28.default.createInterface({
30907
+ const rl = import_promises30.default.createInterface({
30740
30908
  input: process.stdin,
30741
30909
  output: process.stdout
30742
30910
  });
@@ -30745,7 +30913,7 @@ var init_setup = __esm({
30745
30913
  return answer.trim();
30746
30914
  };
30747
30915
  listSprites2 = async (apiBaseUrl, token) => {
30748
- const requestId = (0, import_node_crypto13.randomUUID)();
30916
+ const requestId = (0, import_node_crypto12.randomUUID)();
30749
30917
  const url = new URL("/v1/sprites", apiBaseUrl);
30750
30918
  url.searchParams.set("max_results", "1");
30751
30919
  logger7.info("sprites_request", {
@@ -30862,16 +31030,16 @@ var init_setup = __esm({
30862
31030
  });
30863
31031
 
30864
31032
  // src/devbox/commands/wezterm.ts
30865
- var import_node_crypto14, import_node_child_process11, import_promises29, import_node_os11, import_node_path23, import_promises30, logger10, WEZTERM_APP_PATH, WEZTERM_BIN_PATH, WEZTERM_BIN_DIR, WEZTERM_INSTALL_URL, WEZTERM_PATH_EXPORT, WEZTERM_HEALTH_POLL_INTERVAL_MS, WEZTERM_HEALTH_POLL_TIMEOUT_MS, WEZTERM_PROXY_ENV, WEZTERM_PROXY_LOG_NAME, WEZTERM_USAGE, parseWeztermArgs, resolveCanonical3, initWeztermClient, waitForWeztermMuxHealthy, ensureWeztermMuxReady, runWeztermProxy, runCommand6, promptYesNo2, fileExists, hasWeztermOnPath, resolveShellProfilePath, ensureWeztermOnPath, ensureWeztermInstalled, expandPath, resolveDefaultConfigPath, escapeRegExp, resolveDvbCommand, formatLuaArgs, buildProxyCommand, buildDomainBlock, canAppendToConfig, countReturns, applyReturnTableTransform, insertBlock, runWeztermSetup, startWeztermDomain, runWezterm;
31033
+ var import_node_crypto13, import_node_child_process11, import_promises31, import_node_os10, import_node_path24, import_promises32, logger10, WEZTERM_APP_PATH, WEZTERM_BIN_PATH, WEZTERM_BIN_DIR, WEZTERM_INSTALL_URL, WEZTERM_PATH_EXPORT, WEZTERM_HEALTH_POLL_INTERVAL_MS, WEZTERM_HEALTH_POLL_TIMEOUT_MS, WEZTERM_PROXY_BASE_ENV, WEZTERM_PROXY_LOG_NAME, WEZTERM_USAGE, parseWeztermArgs, resolveCanonical3, initWeztermClient, waitForWeztermMuxHealthy, ensureWeztermMuxReady, runWeztermProxy, runCommand6, promptYesNo2, fileExists, hasWeztermOnPath, resolveShellProfilePath, ensureWeztermOnPath, ensureWeztermInstalled, expandPath, resolveDefaultConfigPath, escapeRegExp, resolveCliName2, resolveDvbCommand, formatLuaArgs, resolveWeztermProxyEnv, buildProxyCommand, buildDomainBlock, canAppendToConfig, countReturns, applyReturnTableTransform, insertBlock, runWeztermSetup, startWeztermDomain, runWezterm;
30866
31034
  var init_wezterm = __esm({
30867
31035
  "src/devbox/commands/wezterm.ts"() {
30868
31036
  "use strict";
30869
- import_node_crypto14 = require("node:crypto");
31037
+ import_node_crypto13 = require("node:crypto");
30870
31038
  import_node_child_process11 = require("node:child_process");
30871
- import_promises29 = __toESM(require("node:fs/promises"), 1);
30872
- import_node_os11 = __toESM(require("node:os"), 1);
30873
- import_node_path23 = __toESM(require("node:path"), 1);
30874
- import_promises30 = __toESM(require("node:readline/promises"), 1);
31039
+ import_promises31 = __toESM(require("node:fs/promises"), 1);
31040
+ import_node_os10 = __toESM(require("node:os"), 1);
31041
+ import_node_path24 = __toESM(require("node:path"), 1);
31042
+ import_promises32 = __toESM(require("node:readline/promises"), 1);
30875
31043
  init_src();
30876
31044
  init_daemonClient();
30877
31045
  init_auth();
@@ -30887,7 +31055,7 @@ var init_wezterm = __esm({
30887
31055
  WEZTERM_PATH_EXPORT = 'export PATH="$PATH:/Applications/WezTerm.app/Contents/MacOS"';
30888
31056
  WEZTERM_HEALTH_POLL_INTERVAL_MS = 200;
30889
31057
  WEZTERM_HEALTH_POLL_TIMEOUT_MS = 6e3;
30890
- WEZTERM_PROXY_ENV = [
31058
+ WEZTERM_PROXY_BASE_ENV = [
30891
31059
  "DEVBOX_LOG_LEVEL=silent",
30892
31060
  "DEVBOX_WEZTERM_PROXY=1",
30893
31061
  "NODE_NO_WARNINGS=1"
@@ -31059,14 +31227,14 @@ var init_wezterm = __esm({
31059
31227
  runWeztermProxy = async (box, port, options) => {
31060
31228
  const writeProxyLog = async (message) => {
31061
31229
  if (process.env.DEVBOX_WEZTERM_PROXY !== "1") return;
31062
- const homeDir = import_node_os11.default.homedir();
31230
+ const homeDir = import_node_os10.default.homedir();
31063
31231
  if (!homeDir) return;
31064
31232
  try {
31065
- const logDir = import_node_path23.default.join(homeDir, ".devbox", "wezterm");
31066
- await import_promises29.default.mkdir(logDir, { recursive: true });
31233
+ const logDir = import_node_path24.default.join(resolveDevboxDir(homeDir), "wezterm");
31234
+ await import_promises31.default.mkdir(logDir, { recursive: true });
31067
31235
  const line = `${(/* @__PURE__ */ new Date()).toISOString()} ${message}
31068
31236
  `;
31069
- await import_promises29.default.appendFile(import_node_path23.default.join(logDir, WEZTERM_PROXY_LOG_NAME), line, "utf8");
31237
+ await import_promises31.default.appendFile(import_node_path24.default.join(logDir, WEZTERM_PROXY_LOG_NAME), line, "utf8");
31070
31238
  } catch {
31071
31239
  }
31072
31240
  };
@@ -31076,7 +31244,7 @@ var init_wezterm = __esm({
31076
31244
  await writeProxyLog(
31077
31245
  `proxy_ready box=${canonical} setup=${skipSetup ? "skip" : "full"}`
31078
31246
  );
31079
- const requestId = (0, import_node_crypto14.randomUUID)();
31247
+ const requestId = (0, import_node_crypto13.randomUUID)();
31080
31248
  const proxyPath = `/v1/sprites/${canonical}/proxy`;
31081
31249
  logger10.info("sprites_request", {
31082
31250
  requestId,
@@ -31280,7 +31448,7 @@ var init_wezterm = __esm({
31280
31448
  if (!process.stdin.isTTY || !process.stdout.isTTY) {
31281
31449
  throw new Error("This command requires a TTY to confirm changes.");
31282
31450
  }
31283
- const rl = import_promises30.default.createInterface({
31451
+ const rl = import_promises32.default.createInterface({
31284
31452
  input: process.stdin,
31285
31453
  output: process.stdout
31286
31454
  });
@@ -31292,7 +31460,7 @@ var init_wezterm = __esm({
31292
31460
  };
31293
31461
  fileExists = async (value) => {
31294
31462
  try {
31295
- await import_promises29.default.access(value);
31463
+ await import_promises31.default.access(value);
31296
31464
  return true;
31297
31465
  } catch {
31298
31466
  return false;
@@ -31309,16 +31477,16 @@ var init_wezterm = __esm({
31309
31477
  }
31310
31478
  const shell = process.env.SHELL ?? "";
31311
31479
  if (shell.includes("zsh")) {
31312
- return import_node_path23.default.join(homeDir, ".zshrc");
31480
+ return import_node_path24.default.join(homeDir, ".zshrc");
31313
31481
  }
31314
31482
  if (shell.includes("bash")) {
31315
- const profile = import_node_path23.default.join(homeDir, ".bash_profile");
31483
+ const profile = import_node_path24.default.join(homeDir, ".bash_profile");
31316
31484
  if (await fileExists(profile)) {
31317
31485
  return profile;
31318
31486
  }
31319
- return import_node_path23.default.join(homeDir, ".bashrc");
31487
+ return import_node_path24.default.join(homeDir, ".bashrc");
31320
31488
  }
31321
- return import_node_path23.default.join(homeDir, ".profile");
31489
+ return import_node_path24.default.join(homeDir, ".profile");
31322
31490
  };
31323
31491
  ensureWeztermOnPath = async () => {
31324
31492
  if (await hasWeztermOnPath()) {
@@ -31338,7 +31506,7 @@ var init_wezterm = __esm({
31338
31506
  if (shouldUpdate) {
31339
31507
  let content = "";
31340
31508
  try {
31341
- content = await import_promises29.default.readFile(profilePath, "utf8");
31509
+ content = await import_promises31.default.readFile(profilePath, "utf8");
31342
31510
  } catch {
31343
31511
  content = "";
31344
31512
  }
@@ -31346,7 +31514,7 @@ var init_wezterm = __esm({
31346
31514
  const next = `${content.trimEnd()}
31347
31515
  ${content ? "\n" : ""}${WEZTERM_PATH_EXPORT}
31348
31516
  `;
31349
- await import_promises29.default.writeFile(profilePath, next, "utf8");
31517
+ await import_promises31.default.writeFile(profilePath, next, "utf8");
31350
31518
  updatedProfile = true;
31351
31519
  }
31352
31520
  const currentPath = process.env.PATH ?? "";
@@ -31375,7 +31543,7 @@ ${content ? "\n" : ""}${WEZTERM_PATH_EXPORT}
31375
31543
  expandPath = (value) => {
31376
31544
  if (value.startsWith("~/")) {
31377
31545
  const homeDir = process.env.HOME ?? "";
31378
- return homeDir ? import_node_path23.default.join(homeDir, value.slice(2)) : value;
31546
+ return homeDir ? import_node_path24.default.join(homeDir, value.slice(2)) : value;
31379
31547
  }
31380
31548
  return value;
31381
31549
  };
@@ -31385,12 +31553,12 @@ ${content ? "\n" : ""}${WEZTERM_PATH_EXPORT}
31385
31553
  throw new Error("HOME is not set; pass --path to wezterm setup.");
31386
31554
  }
31387
31555
  const candidates = [
31388
- import_node_path23.default.join(homeDir, ".wezterm.lua"),
31389
- import_node_path23.default.join(homeDir, ".config", "wezterm", "wezterm.lua")
31556
+ import_node_path24.default.join(homeDir, ".wezterm.lua"),
31557
+ import_node_path24.default.join(homeDir, ".config", "wezterm", "wezterm.lua")
31390
31558
  ];
31391
31559
  for (const candidate of candidates) {
31392
31560
  try {
31393
- await import_promises29.default.access(candidate);
31561
+ await import_promises31.default.access(candidate);
31394
31562
  return candidate;
31395
31563
  } catch {
31396
31564
  }
@@ -31398,22 +31566,43 @@ ${content ? "\n" : ""}${WEZTERM_PATH_EXPORT}
31398
31566
  return candidates[0];
31399
31567
  };
31400
31568
  escapeRegExp = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
31569
+ resolveCliName2 = () => {
31570
+ const raw = process.env.DEVBOX_CLI_NAME?.trim();
31571
+ if (!raw) return "dvb";
31572
+ const normalized = raw.replace(/[^A-Za-z0-9_-]+/g, "").slice(0, 32);
31573
+ return normalized.length > 0 ? normalized : "dvb";
31574
+ };
31401
31575
  resolveDvbCommand = async () => {
31402
31576
  const scriptPath = process.argv[1];
31403
31577
  if (scriptPath) {
31404
- const candidate = import_node_path23.default.isAbsolute(scriptPath) ? scriptPath : import_node_path23.default.resolve(process.cwd(), scriptPath);
31578
+ const candidate = import_node_path24.default.isAbsolute(scriptPath) ? scriptPath : import_node_path24.default.resolve(process.cwd(), scriptPath);
31405
31579
  try {
31406
- await import_promises29.default.access(candidate);
31580
+ await import_promises31.default.access(candidate);
31407
31581
  return [process.execPath, candidate];
31408
31582
  } catch {
31409
31583
  }
31410
31584
  }
31411
- return ["dvb"];
31585
+ return [resolveCliName2()];
31412
31586
  };
31413
31587
  formatLuaArgs = (args) => `{ ${args.map((arg) => JSON.stringify(arg)).join(", ")} }`;
31588
+ resolveWeztermProxyEnv = () => {
31589
+ const env2 = [...WEZTERM_PROXY_BASE_ENV];
31590
+ const profile = process.env.DEVBOX_PROFILE?.trim();
31591
+ if (profile) env2.push(`DEVBOX_PROFILE=${profile}`);
31592
+ const cliName = resolveCliName2();
31593
+ if (cliName !== "dvb") env2.push(`DEVBOX_CLI_NAME=${cliName}`);
31594
+ return env2;
31595
+ };
31414
31596
  buildProxyCommand = async (box, port) => {
31415
31597
  const command = await resolveDvbCommand();
31416
- const args = ["env", ...WEZTERM_PROXY_ENV, ...command, "wezterm", "proxy", box];
31598
+ const args = [
31599
+ "env",
31600
+ ...resolveWeztermProxyEnv(),
31601
+ ...command,
31602
+ "wezterm",
31603
+ "proxy",
31604
+ box
31605
+ ];
31417
31606
  if (port) {
31418
31607
  args.push("--port", String(port));
31419
31608
  }
@@ -31487,7 +31676,7 @@ ${block}`;
31487
31676
  let existing = "";
31488
31677
  let hasExisting = false;
31489
31678
  try {
31490
- existing = await import_promises29.default.readFile(configPath, "utf8");
31679
+ existing = await import_promises31.default.readFile(configPath, "utf8");
31491
31680
  hasExisting = true;
31492
31681
  } catch {
31493
31682
  hasExisting = false;
@@ -31526,8 +31715,8 @@ ${block}`;
31526
31715
  }
31527
31716
  }
31528
31717
  if (updated) {
31529
- await import_promises29.default.mkdir(import_node_path23.default.dirname(configPath), { recursive: true });
31530
- await import_promises29.default.writeFile(configPath, nextContent, "utf8");
31718
+ await import_promises31.default.mkdir(import_node_path24.default.dirname(configPath), { recursive: true });
31719
+ await import_promises31.default.writeFile(configPath, nextContent, "utf8");
31531
31720
  console.log(`Updated WezTerm config: ${configPath}`);
31532
31721
  } else {
31533
31722
  console.log(`WezTerm config already up to date: ${configPath}`);
@@ -31777,8 +31966,9 @@ var init_cli = __esm({
31777
31966
 
31778
31967
  // src/bin/dvb.ts
31779
31968
  var import_node_fs4 = __toESM(require("node:fs"), 1);
31780
- var import_node_os12 = __toESM(require("node:os"), 1);
31781
- var import_node_path24 = __toESM(require("node:path"), 1);
31969
+ var import_node_os11 = __toESM(require("node:os"), 1);
31970
+ var import_node_path25 = __toESM(require("node:path"), 1);
31971
+ init_src();
31782
31972
  var MIN_NODE_MAJOR = 24;
31783
31973
  var assertNodeVersion = () => {
31784
31974
  const version2 = process.versions.node;
@@ -31829,13 +32019,13 @@ var formatErrorMessage = (error) => {
31829
32019
  run().catch((error) => {
31830
32020
  const message = formatErrorMessage(error);
31831
32021
  if (process.env.DEVBOX_WEZTERM_PROXY === "1") {
31832
- const homeDir = import_node_os12.default.homedir();
32022
+ const homeDir = import_node_os11.default.homedir();
31833
32023
  if (homeDir) {
31834
32024
  try {
31835
- const logDir = import_node_path24.default.join(homeDir, ".devbox", "wezterm");
32025
+ const logDir = import_node_path25.default.join(resolveDevboxDir(homeDir), "wezterm");
31836
32026
  import_node_fs4.default.mkdirSync(logDir, { recursive: true });
31837
32027
  import_node_fs4.default.appendFileSync(
31838
- import_node_path24.default.join(logDir, "proxy.log"),
32028
+ import_node_path25.default.join(logDir, "proxy.log"),
31839
32029
  `${(/* @__PURE__ */ new Date()).toISOString()} ${message}
31840
32030
  `
31841
32031
  );