@boxes-dev/dvb 0.2.44 → 0.2.46

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin/dvbd.cjs CHANGED
@@ -351,7 +351,7 @@ var init_repo = __esm({
351
351
  });
352
352
 
353
353
  // ../core/src/sprites.ts
354
- 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;
354
+ var import_node_crypto, import_node_util, import_ws, SpritesApiError, logger, USE_INTERNAL_SERVICE_API, INTERNAL_SERVICE_SIGNAL_TIMEOUT_SECONDS, toWebSocketErrorInfo, toWsUrl, shellQuote, DEFAULT_SPRITES_HTTP_TIMEOUT_MS_IDEMPOTENT, DEFAULT_SPRITES_HTTP_TIMEOUT_MS_NON_IDEMPOTENT, DEFAULT_SPRITES_HTTP_MAX_ATTEMPTS, SPRITES_HTTP_RETRYABLE_STATUSES, delay, isIdempotentMethod, computeRetryDelayMs, isAbortError, getErrorCode, isRetryableFetchError, shouldRetrySpritesRequest, withSpritesRetry, requestJson, listSprites, requestNdjson, writeFile, normalizeServiceRecord, readFile, openExecSocket, attachExecSocket, openProxySocket, listExecSessions, listServices, internalServicesRequest, createCheckpointInternal, listServicesInternal, getServiceInternal, createServiceInternal, startServiceInternal, stopServiceInternal, execCommand, createSpritesClient;
355
355
  var init_sprites = __esm({
356
356
  "../core/src/sprites.ts"() {
357
357
  "use strict";
@@ -419,39 +419,126 @@ var init_sprites = __esm({
419
419
  return new URL(path6, `${protocol}//${base.host}`);
420
420
  };
421
421
  shellQuote = (value) => `'${value.replace(/'/g, `'\\''`)}'`;
422
- requestJson = async (apiBaseUrl, token, method, path6, body) => {
423
- const requestId = (0, import_node_crypto.randomUUID)();
424
- const url = new URL(path6, apiBaseUrl);
425
- const headers = {
426
- authorization: `Bearer ${token}`,
427
- "x-request-id": requestId
428
- };
429
- if (body) {
430
- headers["content-type"] = "application/json";
422
+ DEFAULT_SPRITES_HTTP_TIMEOUT_MS_IDEMPOTENT = 5e3;
423
+ DEFAULT_SPRITES_HTTP_TIMEOUT_MS_NON_IDEMPOTENT = 2e4;
424
+ DEFAULT_SPRITES_HTTP_MAX_ATTEMPTS = 5;
425
+ SPRITES_HTTP_RETRYABLE_STATUSES = /* @__PURE__ */ new Set([408, 409, 425, 429, 500, 502, 503, 504]);
426
+ delay = async (ms) => new Promise((resolve) => setTimeout(resolve, ms));
427
+ isIdempotentMethod = (method) => {
428
+ const normalized = method.toUpperCase();
429
+ return normalized === "GET" || normalized === "HEAD" || normalized === "PUT" || normalized === "DELETE" || normalized === "OPTIONS";
430
+ };
431
+ computeRetryDelayMs = (attempt) => {
432
+ const base = 250;
433
+ const cap = 2500;
434
+ const exp = Math.min(cap, base * 2 ** Math.max(0, attempt - 1));
435
+ const jitter = Math.floor(Math.random() * 120);
436
+ return exp + jitter;
437
+ };
438
+ isAbortError = (error) => error instanceof Error && (error.name === "AbortError" || error.message.includes("aborted"));
439
+ getErrorCode = (error) => {
440
+ if (!error || typeof error !== "object") return void 0;
441
+ const record = error;
442
+ const code2 = record.code;
443
+ return typeof code2 === "string" || typeof code2 === "number" ? String(code2) : void 0;
444
+ };
445
+ isRetryableFetchError = (error) => {
446
+ if (isAbortError(error)) return true;
447
+ if (error instanceof TypeError) return true;
448
+ const code2 = getErrorCode(error);
449
+ return code2 === "ECONNRESET" || code2 === "ETIMEDOUT" || code2 === "EAI_AGAIN" || code2 === "ENOTFOUND" || code2 === "ECONNREFUSED";
450
+ };
451
+ shouldRetrySpritesRequest = (method, error) => {
452
+ if (!isIdempotentMethod(method)) return false;
453
+ if (error instanceof SpritesApiError) {
454
+ return SPRITES_HTTP_RETRYABLE_STATUSES.has(error.status);
431
455
  }
432
- const init = { method, headers };
433
- if (body) {
434
- init.body = JSON.stringify(body);
456
+ return isRetryableFetchError(error);
457
+ };
458
+ withSpritesRetry = async (options) => {
459
+ const opId = (0, import_node_crypto.randomUUID)();
460
+ const timeoutMs = options.timeoutMs ?? (isIdempotentMethod(options.method) ? DEFAULT_SPRITES_HTTP_TIMEOUT_MS_IDEMPOTENT : DEFAULT_SPRITES_HTTP_TIMEOUT_MS_NON_IDEMPOTENT);
461
+ const maxAttemptsRaw = options.maxAttempts ?? DEFAULT_SPRITES_HTTP_MAX_ATTEMPTS;
462
+ const maxAttempts = isIdempotentMethod(options.method) ? Math.max(1, maxAttemptsRaw) : 1;
463
+ for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
464
+ const requestId = (0, import_node_crypto.randomUUID)();
465
+ const controller = new AbortController();
466
+ const timeoutHandle = typeof timeoutMs === "number" && timeoutMs > 0 ? setTimeout(() => controller.abort(), timeoutMs) : null;
467
+ try {
468
+ logger.info("sprites_request", {
469
+ opId,
470
+ attempt,
471
+ requestId,
472
+ method: options.method,
473
+ path: options.path,
474
+ timeoutMs
475
+ });
476
+ return await options.run(controller.signal, requestId);
477
+ } catch (error) {
478
+ const retryable = shouldRetrySpritesRequest(options.method, error);
479
+ const remaining = maxAttempts - attempt;
480
+ if (!retryable || remaining <= 0) {
481
+ throw error;
482
+ }
483
+ const delayMs = computeRetryDelayMs(attempt);
484
+ logger.warn("sprites_http_retry", {
485
+ opId,
486
+ attempt,
487
+ requestId,
488
+ method: options.method,
489
+ path: options.path,
490
+ timeoutMs,
491
+ delayMs,
492
+ remainingAttempts: remaining,
493
+ errorName: error instanceof Error ? error.name : void 0,
494
+ errorMessage: error instanceof Error ? error.message : String(error),
495
+ errorCode: getErrorCode(error),
496
+ ...error instanceof SpritesApiError ? { status: error.status } : {}
497
+ });
498
+ await delay(delayMs);
499
+ } finally {
500
+ if (timeoutHandle) clearTimeout(timeoutHandle);
501
+ }
435
502
  }
436
- logger.info("sprites_request", { requestId, method, path: path6 });
437
- const response = await fetch(url, init);
438
- const text = await response.text();
439
- logger.info("sprites_response", {
440
- requestId,
503
+ throw new Error(`Sprites request failed: ${options.method} ${options.path}`);
504
+ };
505
+ requestJson = async (apiBaseUrl, token, method, path6, body) => {
506
+ return await withSpritesRetry({
441
507
  method,
442
508
  path: path6,
443
- status: response.status
509
+ run: async (signal, requestId) => {
510
+ const url = new URL(path6, apiBaseUrl);
511
+ const headers = {
512
+ authorization: `Bearer ${token}`,
513
+ "x-request-id": requestId
514
+ };
515
+ if (body) {
516
+ headers["content-type"] = "application/json";
517
+ }
518
+ const init = { method, headers, signal };
519
+ if (body) {
520
+ init.body = JSON.stringify(body);
521
+ }
522
+ const response = await fetch(url, init);
523
+ const text = await response.text();
524
+ logger.info("sprites_response", {
525
+ requestId,
526
+ method,
527
+ path: path6,
528
+ status: response.status
529
+ });
530
+ if (!response.ok) {
531
+ const snippet = text.trim().slice(0, 200);
532
+ throw new SpritesApiError(response.status, method, path6, snippet);
533
+ }
534
+ if (!text) return null;
535
+ try {
536
+ return JSON.parse(text);
537
+ } catch {
538
+ return text;
539
+ }
540
+ }
444
541
  });
445
- if (!response.ok) {
446
- const snippet = text.trim().slice(0, 200);
447
- throw new SpritesApiError(response.status, method, path6, snippet);
448
- }
449
- if (!text) return null;
450
- try {
451
- return JSON.parse(text);
452
- } catch {
453
- return text;
454
- }
455
542
  };
456
543
  listSprites = async (apiBaseUrl, token, options) => {
457
544
  const params = new URLSearchParams();
@@ -492,88 +579,99 @@ var init_sprites = __esm({
492
579
  return response;
493
580
  };
494
581
  requestNdjson = async (apiBaseUrl, token, method, path6, body) => {
495
- const requestId = (0, import_node_crypto.randomUUID)();
496
- const url = new URL(path6, apiBaseUrl);
497
- const headers = {
498
- authorization: `Bearer ${token}`,
499
- "x-request-id": requestId
500
- };
501
- if (body) {
502
- headers["content-type"] = "application/json";
503
- }
504
- const init = { method, headers };
505
- if (body) {
506
- init.body = JSON.stringify(body);
507
- }
508
- logger.info("sprites_request", { requestId, method, path: path6 });
509
- const response = await fetch(url, init);
510
- logger.info("sprites_response", {
511
- requestId,
582
+ return await withSpritesRetry({
512
583
  method,
513
584
  path: path6,
514
- status: response.status
515
- });
516
- const text = await response.text();
517
- if (!response.ok) {
518
- const snippet = text.trim().slice(0, 200);
519
- throw new SpritesApiError(response.status, method, path6, snippet);
520
- }
521
- const lines = text.split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0);
522
- const events = [];
523
- for (const line of lines) {
524
- try {
525
- const parsed = JSON.parse(line);
526
- if (Array.isArray(parsed)) {
527
- for (const entry of parsed) {
528
- if (entry && typeof entry === "object") {
529
- events.push(entry);
530
- } else {
531
- events.push({ value: entry });
585
+ run: async (signal, requestId) => {
586
+ const url = new URL(path6, apiBaseUrl);
587
+ const headers = {
588
+ authorization: `Bearer ${token}`,
589
+ "x-request-id": requestId
590
+ };
591
+ if (body) {
592
+ headers["content-type"] = "application/json";
593
+ }
594
+ const init = { method, headers, signal };
595
+ if (body) {
596
+ init.body = JSON.stringify(body);
597
+ }
598
+ const response = await fetch(url, init);
599
+ logger.info("sprites_response", {
600
+ requestId,
601
+ method,
602
+ path: path6,
603
+ status: response.status
604
+ });
605
+ const text = await response.text();
606
+ if (!response.ok) {
607
+ const snippet = text.trim().slice(0, 200);
608
+ throw new SpritesApiError(response.status, method, path6, snippet);
609
+ }
610
+ const lines = text.split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0);
611
+ const events = [];
612
+ for (const line of lines) {
613
+ try {
614
+ const parsed = JSON.parse(line);
615
+ if (Array.isArray(parsed)) {
616
+ for (const entry of parsed) {
617
+ if (entry && typeof entry === "object") {
618
+ events.push(entry);
619
+ } else {
620
+ events.push({ value: entry });
621
+ }
622
+ }
623
+ continue;
624
+ }
625
+ if (parsed && typeof parsed === "object") {
626
+ events.push(parsed);
627
+ continue;
532
628
  }
629
+ events.push({ value: parsed });
630
+ } catch {
631
+ events.push({ raw: line });
533
632
  }
534
- continue;
535
- }
536
- if (parsed && typeof parsed === "object") {
537
- events.push(parsed);
538
- continue;
539
633
  }
540
- events.push({ value: parsed });
541
- } catch {
542
- events.push({ raw: line });
634
+ return events;
543
635
  }
544
- }
545
- return events;
636
+ });
546
637
  };
547
638
  writeFile = async (apiBaseUrl, token, name, remotePath, data) => {
548
- const requestId = (0, import_node_crypto.randomUUID)();
549
639
  const path6 = `/v1/sprites/${name}/fs/write`;
550
640
  const url = new URL(path6, apiBaseUrl);
551
641
  url.searchParams.set("path", remotePath);
552
642
  url.searchParams.set("mkdir", "true");
553
- logger.info("sprites_fs_write", {
554
- requestId,
555
- path: path6,
556
- name,
557
- remotePath,
558
- size: data.length
559
- });
560
- const response = await fetch(url, {
643
+ await withSpritesRetry({
561
644
  method: "PUT",
562
- headers: {
563
- authorization: `Bearer ${token}`,
564
- "content-type": "application/octet-stream",
565
- "x-request-id": requestId
566
- },
567
- body: data
568
- });
569
- logger.info("sprites_fs_write_response", {
570
- requestId,
571
645
  path: path6,
572
- status: response.status
646
+ run: async (signal, requestId) => {
647
+ logger.info("sprites_fs_write", {
648
+ requestId,
649
+ path: path6,
650
+ name,
651
+ remotePath,
652
+ size: data.length
653
+ });
654
+ const response = await fetch(url, {
655
+ method: "PUT",
656
+ headers: {
657
+ authorization: `Bearer ${token}`,
658
+ "content-type": "application/octet-stream",
659
+ "x-request-id": requestId
660
+ },
661
+ body: data,
662
+ signal
663
+ });
664
+ logger.info("sprites_fs_write_response", {
665
+ requestId,
666
+ path: path6,
667
+ status: response.status
668
+ });
669
+ if (!response.ok) {
670
+ const snippet = (await response.text()).trim().slice(0, 200);
671
+ throw new SpritesApiError(response.status, "PUT", path6, snippet);
672
+ }
673
+ }
573
674
  });
574
- if (!response.ok) {
575
- throw new Error(`Sprites FS write failed: ${response.status}`);
576
- }
577
675
  };
578
676
  normalizeServiceRecord = (entry) => {
579
677
  const rawName = entry.name;
@@ -604,38 +702,44 @@ var init_sprites = __esm({
604
702
  return service;
605
703
  };
606
704
  readFile = async (apiBaseUrl, token, name, options) => {
607
- const requestId = (0, import_node_crypto.randomUUID)();
608
705
  const path6 = `/v1/sprites/${name}/fs/read`;
609
706
  const url = new URL(path6, apiBaseUrl);
610
707
  url.searchParams.set("path", options.path);
611
708
  if (options.workingDir) {
612
709
  url.searchParams.set("workingDir", options.workingDir);
613
710
  }
614
- logger.info("sprites_fs_read", {
615
- requestId,
616
- path: path6,
617
- name,
618
- remotePath: options.path,
619
- workingDir: options.workingDir
620
- });
621
- const response = await fetch(url, {
711
+ return await withSpritesRetry({
622
712
  method: "GET",
623
- headers: {
624
- authorization: `Bearer ${token}`,
625
- "x-request-id": requestId
626
- }
627
- });
628
- logger.info("sprites_fs_read_response", {
629
- requestId,
630
713
  path: path6,
631
- status: response.status
714
+ run: async (signal, requestId) => {
715
+ logger.info("sprites_fs_read", {
716
+ requestId,
717
+ path: path6,
718
+ name,
719
+ remotePath: options.path,
720
+ workingDir: options.workingDir
721
+ });
722
+ const response = await fetch(url, {
723
+ method: "GET",
724
+ headers: {
725
+ authorization: `Bearer ${token}`,
726
+ "x-request-id": requestId
727
+ },
728
+ signal
729
+ });
730
+ logger.info("sprites_fs_read_response", {
731
+ requestId,
732
+ path: path6,
733
+ status: response.status
734
+ });
735
+ if (!response.ok) {
736
+ const snippet = (await response.text()).trim().slice(0, 200);
737
+ throw new SpritesApiError(response.status, "GET", path6, snippet);
738
+ }
739
+ const buffer = await response.arrayBuffer();
740
+ return new Uint8Array(buffer);
741
+ }
632
742
  });
633
- if (!response.ok) {
634
- const snippet = (await response.text()).trim().slice(0, 200);
635
- throw new SpritesApiError(response.status, "GET", path6, snippet);
636
- }
637
- const buffer = await response.arrayBuffer();
638
- return new Uint8Array(buffer);
639
743
  };
640
744
  openExecSocket = (apiBaseUrl, token, name, options) => {
641
745
  const url = toWsUrl(apiBaseUrl, `/v1/sprites/${name}/exec`);
@@ -859,7 +963,7 @@ var init_sprites = __esm({
859
963
  await internalServicesRequest(apiBaseUrl, token, name, command);
860
964
  return [];
861
965
  };
862
- execCommand = async (apiBaseUrl, token, name, cmd, requestId) => {
966
+ execCommand = async (apiBaseUrl, token, name, cmd, requestId, options) => {
863
967
  const path6 = `/v1/sprites/${name}/exec`;
864
968
  const url = toWsUrl(apiBaseUrl, path6);
865
969
  cmd.forEach((part) => url.searchParams.append("cmd", part));
@@ -870,11 +974,28 @@ var init_sprites = __esm({
870
974
  const stderr = [];
871
975
  let exitCode = null;
872
976
  let resolved = false;
977
+ const timeoutMs = options?.timeoutMs;
978
+ const handshakeTimeoutMs = options?.handshakeTimeoutMs ?? (typeof timeoutMs === "number" ? Math.min(timeoutMs, 6e4) : void 0);
979
+ const timeoutHandle = typeof timeoutMs === "number" && timeoutMs > 0 ? setTimeout(() => {
980
+ if (resolved) return;
981
+ resolved = true;
982
+ logger.warn("sprites_exec_timeout", {
983
+ requestId,
984
+ path: path6,
985
+ timeoutMs
986
+ });
987
+ try {
988
+ ws.terminate();
989
+ } catch {
990
+ }
991
+ reject(new Error(`Exec websocket timed out after ${timeoutMs}ms`));
992
+ }, timeoutMs) : null;
873
993
  const ws = new import_ws.default(url.toString(), {
874
994
  headers: {
875
995
  Authorization: `Bearer ${token}`,
876
996
  "x-request-id": requestId
877
- }
997
+ },
998
+ ...typeof handshakeTimeoutMs === "number" && handshakeTimeoutMs > 0 ? { handshakeTimeout: handshakeTimeoutMs } : {}
878
999
  });
879
1000
  const readResponseSnippet = async (response, limit = 800) => new Promise((resolveBody) => {
880
1001
  let body = "";
@@ -900,6 +1021,8 @@ var init_sprites = __esm({
900
1021
  bodySnippet: snippet ? snippet.slice(0, 800) : void 0
901
1022
  });
902
1023
  if (!resolved) {
1024
+ if (timeoutHandle) clearTimeout(timeoutHandle);
1025
+ resolved = true;
903
1026
  const suffix = snippet ? ` (${snippet.slice(0, 800)})` : "";
904
1027
  reject(new Error(`Exec websocket error: Unexpected server response: ${status}${suffix}`));
905
1028
  }
@@ -908,6 +1031,7 @@ var init_sprites = __esm({
908
1031
  const finish = (code2) => {
909
1032
  if (resolved) return;
910
1033
  resolved = true;
1034
+ if (timeoutHandle) clearTimeout(timeoutHandle);
911
1035
  logger.info("sprites_exec_response", { requestId, path: path6, status: code2 });
912
1036
  resolve({
913
1037
  exitCode: code2,
@@ -965,6 +1089,8 @@ var init_sprites = __esm({
965
1089
  errorStack: errorInfo.stack
966
1090
  });
967
1091
  if (!resolved) {
1092
+ if (timeoutHandle) clearTimeout(timeoutHandle);
1093
+ resolved = true;
968
1094
  reject(new Error(`Exec websocket error: ${errorMessage}`));
969
1095
  }
970
1096
  };
@@ -1019,7 +1145,7 @@ var init_sprites = __esm({
1019
1145
  await writeFile(apiBaseUrl, token, name, remotePath, data);
1020
1146
  },
1021
1147
  readFile: async (name, options) => readFile(apiBaseUrl, token, name, options),
1022
- exec: async (name, cmd) => {
1148
+ exec: async (name, cmd, options) => {
1023
1149
  const requestId = (0, import_node_crypto.randomUUID)();
1024
1150
  logger.info("sprites_exec", {
1025
1151
  requestId,
@@ -1027,7 +1153,7 @@ var init_sprites = __esm({
1027
1153
  cmd,
1028
1154
  path: `/v1/sprites/${name}/exec`
1029
1155
  });
1030
- return execCommand(apiBaseUrl, token, name, cmd, requestId);
1156
+ return execCommand(apiBaseUrl, token, name, cmd, requestId, options);
1031
1157
  },
1032
1158
  listExecSessions: async (name) => listExecSessions(apiBaseUrl, token, name),
1033
1159
  listServices: async (name) => USE_INTERNAL_SERVICE_API ? listServicesInternal(apiBaseUrl, token, name) : listServices(apiBaseUrl, token, name),
@@ -4534,27 +4660,27 @@ var init_authentication_manager = __esm({
4534
4660
  );
4535
4661
  return;
4536
4662
  }
4537
- let delay = Math.min(
4663
+ let delay2 = Math.min(
4538
4664
  MAXIMUM_REFRESH_DELAY,
4539
4665
  (tokenValiditySeconds - this.refreshTokenLeewaySeconds) * 1e3
4540
4666
  );
4541
- if (delay <= 0) {
4667
+ if (delay2 <= 0) {
4542
4668
  this.logger.warn(
4543
4669
  `Refetching auth token immediately, configured leeway ${this.refreshTokenLeewaySeconds}s is larger than the token's lifetime ${tokenValiditySeconds}s`
4544
4670
  );
4545
- delay = 0;
4671
+ delay2 = 0;
4546
4672
  }
4547
4673
  const refetchTokenTimeoutId = setTimeout(() => {
4548
4674
  this._logVerbose("running scheduled token refetch");
4549
4675
  void this.refetchToken();
4550
- }, delay);
4676
+ }, delay2);
4551
4677
  this.setAuthState({
4552
4678
  state: "waitingForScheduledRefetch",
4553
4679
  refetchTokenTimeoutId,
4554
4680
  config: this.authState.config
4555
4681
  });
4556
4682
  this._logVerbose(
4557
- `scheduled preemptive auth token refetching in ${delay}ms`
4683
+ `scheduled preemptive auth token refetching in ${delay2}ms`
4558
4684
  );
4559
4685
  }
4560
4686
  // Protects against simultaneous calls to `setConfig`
@@ -1 +1 @@
1
- {"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../../../../src/devbox/commands/init/codex/plan.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../../../../src/devbox/commands/init/codex/plan.ts"],"names":[],"mappings":"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"}
@@ -1,38 +1,53 @@
1
1
  import path from "node:path";
2
- import fs from "node:fs/promises";
2
+ import fs from "node:fs";
3
+ import fsPromises from "node:fs/promises";
3
4
  const resolveSchemaPath = (fileName) => {
4
- const binPath = process.argv[1];
5
- if (binPath) {
6
- return path.resolve(path.dirname(binPath), "..", "codex", fileName);
5
+ // Prefer resolving relative to the real dvb entrypoint, since `process.argv[1]`
6
+ // may be a bin shim (e.g. ~/.nvm/.../bin/dvb) rather than `.../dist/bin/dvb.cjs`.
7
+ const argv1 = typeof process.argv[1] === "string" ? process.argv[1] : "";
8
+ if (argv1) {
9
+ try {
10
+ const real = fs.realpathSync(argv1);
11
+ return path.resolve(path.dirname(real), "..", "codex", fileName);
12
+ }
13
+ catch {
14
+ // ignore and fall back
15
+ }
16
+ try {
17
+ return path.resolve(path.dirname(argv1), "..", "codex", fileName);
18
+ }
19
+ catch {
20
+ // ignore and fall back
21
+ }
7
22
  }
8
23
  return path.resolve(process.cwd(), "codex", fileName);
9
24
  };
10
25
  const writeSetupEnvSecretsSchema = async (dir) => {
11
26
  const sourceSchemaPath = resolveSchemaPath("setup-env-secrets-schema.json");
12
- const schemaContents = await fs.readFile(sourceSchemaPath, "utf8");
27
+ const schemaContents = await fsPromises.readFile(sourceSchemaPath, "utf8");
13
28
  const schemaPath = path.join(dir, "setup-env-secrets-schema.json");
14
- await fs.writeFile(schemaPath, schemaContents, "utf8");
29
+ await fsPromises.writeFile(schemaPath, schemaContents, "utf8");
15
30
  return schemaPath;
16
31
  };
17
32
  const writeSetupExternalSchema = async (dir) => {
18
33
  const sourceSchemaPath = resolveSchemaPath("setup-external-schema.json");
19
- const schemaContents = await fs.readFile(sourceSchemaPath, "utf8");
34
+ const schemaContents = await fsPromises.readFile(sourceSchemaPath, "utf8");
20
35
  const schemaPath = path.join(dir, "setup-external-schema.json");
21
- await fs.writeFile(schemaPath, schemaContents, "utf8");
36
+ await fsPromises.writeFile(schemaPath, schemaContents, "utf8");
22
37
  return schemaPath;
23
38
  };
24
39
  const writeSetupExtraArtifactsSchema = async (dir) => {
25
40
  const sourceSchemaPath = resolveSchemaPath("setup-extra-artifacts-schema.json");
26
- const schemaContents = await fs.readFile(sourceSchemaPath, "utf8");
41
+ const schemaContents = await fsPromises.readFile(sourceSchemaPath, "utf8");
27
42
  const schemaPath = path.join(dir, "setup-extra-artifacts-schema.json");
28
- await fs.writeFile(schemaPath, schemaContents, "utf8");
43
+ await fsPromises.writeFile(schemaPath, schemaContents, "utf8");
29
44
  return schemaPath;
30
45
  };
31
46
  const writeServicesSchema = async (dir) => {
32
47
  const sourceSchemaPath = resolveSchemaPath("services-schema.json");
33
- const schemaContents = await fs.readFile(sourceSchemaPath, "utf8");
48
+ const schemaContents = await fsPromises.readFile(sourceSchemaPath, "utf8");
34
49
  const schemaPath = path.join(dir, "services-schema.json");
35
- await fs.writeFile(schemaPath, schemaContents, "utf8");
50
+ await fsPromises.writeFile(schemaPath, schemaContents, "utf8");
36
51
  return schemaPath;
37
52
  };
38
53
  const isObject = (value) => typeof value === "object" && value !== null;
@@ -85,7 +100,7 @@ const isServicesPlan = (value) => {
85
100
  Array.isArray(value.backgroundServices));
86
101
  };
87
102
  const readSetupPlan = async (setupPath) => {
88
- const raw = await fs.readFile(setupPath, "utf8");
103
+ const raw = await fsPromises.readFile(setupPath, "utf8");
89
104
  const parsed = JSON.parse(raw);
90
105
  if (!isSetupPlan(parsed)) {
91
106
  throw new Error(`Invalid setup plan: ${setupPath}`);
@@ -93,7 +108,7 @@ const readSetupPlan = async (setupPath) => {
93
108
  return parsed;
94
109
  };
95
110
  const readSetupEnvSecretsPlan = async (scanPath) => {
96
- const raw = await fs.readFile(scanPath, "utf8");
111
+ const raw = await fsPromises.readFile(scanPath, "utf8");
97
112
  const parsed = JSON.parse(raw);
98
113
  if (!isSetupEnvSecretsPlan(parsed)) {
99
114
  throw new Error(`Invalid env/secrets scan: ${scanPath}`);
@@ -101,7 +116,7 @@ const readSetupEnvSecretsPlan = async (scanPath) => {
101
116
  return parsed;
102
117
  };
103
118
  const readSetupExternalPlan = async (scanPath) => {
104
- const raw = await fs.readFile(scanPath, "utf8");
119
+ const raw = await fsPromises.readFile(scanPath, "utf8");
105
120
  const parsed = JSON.parse(raw);
106
121
  if (!isSetupExternalPlan(parsed)) {
107
122
  throw new Error(`Invalid external scan: ${scanPath}`);
@@ -109,7 +124,7 @@ const readSetupExternalPlan = async (scanPath) => {
109
124
  return parsed;
110
125
  };
111
126
  const readSetupExtraArtifactsPlan = async (scanPath) => {
112
- const raw = await fs.readFile(scanPath, "utf8");
127
+ const raw = await fsPromises.readFile(scanPath, "utf8");
113
128
  const parsed = JSON.parse(raw);
114
129
  if (!isSetupExtraArtifactsPlan(parsed)) {
115
130
  throw new Error(`Invalid extra artifacts scan: ${scanPath}`);
@@ -117,7 +132,7 @@ const readSetupExtraArtifactsPlan = async (scanPath) => {
117
132
  return parsed;
118
133
  };
119
134
  const readServicesPlan = async (servicesPath) => {
120
- const raw = await fs.readFile(servicesPath, "utf8");
135
+ const raw = await fsPromises.readFile(servicesPath, "utf8");
121
136
  const parsed = JSON.parse(raw);
122
137
  if (!isServicesPlan(parsed)) {
123
138
  throw new Error(`Invalid services plan: ${servicesPath}`);
@@ -125,7 +140,7 @@ const readServicesPlan = async (servicesPath) => {
125
140
  return parsed;
126
141
  };
127
142
  const writeSetupPlan = async (setupPath, plan) => {
128
- await fs.writeFile(setupPath, JSON.stringify(plan, null, 2), "utf8");
143
+ await fsPromises.writeFile(setupPath, JSON.stringify(plan, null, 2), "utf8");
129
144
  };
130
145
  const mergeSetupScans = ({ envSecrets, external, extraArtifacts, services, }) => {
131
146
  const dedupeBy = (items, key) => {
@@ -167,7 +182,7 @@ const mergeSetupScans = ({ envSecrets, external, extraArtifacts, services, }) =>
167
182
  };
168
183
  };
169
184
  const writeServicesPlan = async (servicesPath, plan) => {
170
- await fs.writeFile(servicesPath, JSON.stringify(plan, null, 2), "utf8");
185
+ await fsPromises.writeFile(servicesPath, JSON.stringify(plan, null, 2), "utf8");
171
186
  };
172
187
  export { readSetupPlan, readSetupEnvSecretsPlan, readSetupExternalPlan, readSetupExtraArtifactsPlan, readServicesPlan, writeSetupPlan, mergeSetupScans, writeSetupEnvSecretsSchema, writeSetupExternalSchema, writeSetupExtraArtifactsSchema, writeServicesPlan, writeServicesSchema, };
173
188
  //# sourceMappingURL=plan.js.map