@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/dvb.cjs +348 -180
- package/dist/bin/dvbd.cjs +254 -128
- package/dist/devbox/commands/init/codex/plan.d.ts.map +1 -1
- package/dist/devbox/commands/init/codex/plan.js +34 -19
- package/dist/devbox/commands/init/codex/plan.js.map +1 -1
- package/dist/devbox/commands/init/codex/prompts.d.ts.map +1 -1
- package/dist/devbox/commands/init/codex/prompts.js +20 -5
- package/dist/devbox/commands/init/codex/prompts.js.map +1 -1
- package/dist/devbox/commands/init/remote.d.ts.map +1 -1
- package/dist/devbox/commands/init/remote.js +22 -5
- package/dist/devbox/commands/init/remote.js.map +1 -1
- package/package.json +1 -1
package/dist/bin/dvb.cjs
CHANGED
|
@@ -423,7 +423,7 @@ var init_repo = __esm({
|
|
|
423
423
|
});
|
|
424
424
|
|
|
425
425
|
// ../core/src/sprites.ts
|
|
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;
|
|
426
|
+
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;
|
|
427
427
|
var init_sprites = __esm({
|
|
428
428
|
"../core/src/sprites.ts"() {
|
|
429
429
|
"use strict";
|
|
@@ -491,39 +491,126 @@ var init_sprites = __esm({
|
|
|
491
491
|
return new URL(path26, `${protocol}//${base.host}`);
|
|
492
492
|
};
|
|
493
493
|
shellQuote = (value) => `'${value.replace(/'/g, `'\\''`)}'`;
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
const
|
|
505
|
-
|
|
506
|
-
|
|
494
|
+
DEFAULT_SPRITES_HTTP_TIMEOUT_MS_IDEMPOTENT = 5e3;
|
|
495
|
+
DEFAULT_SPRITES_HTTP_TIMEOUT_MS_NON_IDEMPOTENT = 2e4;
|
|
496
|
+
DEFAULT_SPRITES_HTTP_MAX_ATTEMPTS = 5;
|
|
497
|
+
SPRITES_HTTP_RETRYABLE_STATUSES = /* @__PURE__ */ new Set([408, 409, 425, 429, 500, 502, 503, 504]);
|
|
498
|
+
delay = async (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
499
|
+
isIdempotentMethod = (method) => {
|
|
500
|
+
const normalized = method.toUpperCase();
|
|
501
|
+
return normalized === "GET" || normalized === "HEAD" || normalized === "PUT" || normalized === "DELETE" || normalized === "OPTIONS";
|
|
502
|
+
};
|
|
503
|
+
computeRetryDelayMs = (attempt) => {
|
|
504
|
+
const base = 250;
|
|
505
|
+
const cap = 2500;
|
|
506
|
+
const exp = Math.min(cap, base * 2 ** Math.max(0, attempt - 1));
|
|
507
|
+
const jitter = Math.floor(Math.random() * 120);
|
|
508
|
+
return exp + jitter;
|
|
509
|
+
};
|
|
510
|
+
isAbortError = (error) => error instanceof Error && (error.name === "AbortError" || error.message.includes("aborted"));
|
|
511
|
+
getErrorCode = (error) => {
|
|
512
|
+
if (!error || typeof error !== "object") return void 0;
|
|
513
|
+
const record = error;
|
|
514
|
+
const code2 = record.code;
|
|
515
|
+
return typeof code2 === "string" || typeof code2 === "number" ? String(code2) : void 0;
|
|
516
|
+
};
|
|
517
|
+
isRetryableFetchError = (error) => {
|
|
518
|
+
if (isAbortError(error)) return true;
|
|
519
|
+
if (error instanceof TypeError) return true;
|
|
520
|
+
const code2 = getErrorCode(error);
|
|
521
|
+
return code2 === "ECONNRESET" || code2 === "ETIMEDOUT" || code2 === "EAI_AGAIN" || code2 === "ENOTFOUND" || code2 === "ECONNREFUSED";
|
|
522
|
+
};
|
|
523
|
+
shouldRetrySpritesRequest = (method, error) => {
|
|
524
|
+
if (!isIdempotentMethod(method)) return false;
|
|
525
|
+
if (error instanceof SpritesApiError) {
|
|
526
|
+
return SPRITES_HTTP_RETRYABLE_STATUSES.has(error.status);
|
|
527
|
+
}
|
|
528
|
+
return isRetryableFetchError(error);
|
|
529
|
+
};
|
|
530
|
+
withSpritesRetry = async (options) => {
|
|
531
|
+
const opId = (0, import_node_crypto.randomUUID)();
|
|
532
|
+
const timeoutMs = options.timeoutMs ?? (isIdempotentMethod(options.method) ? DEFAULT_SPRITES_HTTP_TIMEOUT_MS_IDEMPOTENT : DEFAULT_SPRITES_HTTP_TIMEOUT_MS_NON_IDEMPOTENT);
|
|
533
|
+
const maxAttemptsRaw = options.maxAttempts ?? DEFAULT_SPRITES_HTTP_MAX_ATTEMPTS;
|
|
534
|
+
const maxAttempts = isIdempotentMethod(options.method) ? Math.max(1, maxAttemptsRaw) : 1;
|
|
535
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
|
|
536
|
+
const requestId = (0, import_node_crypto.randomUUID)();
|
|
537
|
+
const controller = new AbortController();
|
|
538
|
+
const timeoutHandle = typeof timeoutMs === "number" && timeoutMs > 0 ? setTimeout(() => controller.abort(), timeoutMs) : null;
|
|
539
|
+
try {
|
|
540
|
+
logger.info("sprites_request", {
|
|
541
|
+
opId,
|
|
542
|
+
attempt,
|
|
543
|
+
requestId,
|
|
544
|
+
method: options.method,
|
|
545
|
+
path: options.path,
|
|
546
|
+
timeoutMs
|
|
547
|
+
});
|
|
548
|
+
return await options.run(controller.signal, requestId);
|
|
549
|
+
} catch (error) {
|
|
550
|
+
const retryable = shouldRetrySpritesRequest(options.method, error);
|
|
551
|
+
const remaining = maxAttempts - attempt;
|
|
552
|
+
if (!retryable || remaining <= 0) {
|
|
553
|
+
throw error;
|
|
554
|
+
}
|
|
555
|
+
const delayMs = computeRetryDelayMs(attempt);
|
|
556
|
+
logger.warn("sprites_http_retry", {
|
|
557
|
+
opId,
|
|
558
|
+
attempt,
|
|
559
|
+
requestId,
|
|
560
|
+
method: options.method,
|
|
561
|
+
path: options.path,
|
|
562
|
+
timeoutMs,
|
|
563
|
+
delayMs,
|
|
564
|
+
remainingAttempts: remaining,
|
|
565
|
+
errorName: error instanceof Error ? error.name : void 0,
|
|
566
|
+
errorMessage: error instanceof Error ? error.message : String(error),
|
|
567
|
+
errorCode: getErrorCode(error),
|
|
568
|
+
...error instanceof SpritesApiError ? { status: error.status } : {}
|
|
569
|
+
});
|
|
570
|
+
await delay(delayMs);
|
|
571
|
+
} finally {
|
|
572
|
+
if (timeoutHandle) clearTimeout(timeoutHandle);
|
|
573
|
+
}
|
|
507
574
|
}
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
requestId,
|
|
575
|
+
throw new Error(`Sprites request failed: ${options.method} ${options.path}`);
|
|
576
|
+
};
|
|
577
|
+
requestJson = async (apiBaseUrl, token, method, path26, body) => {
|
|
578
|
+
return await withSpritesRetry({
|
|
513
579
|
method,
|
|
514
580
|
path: path26,
|
|
515
|
-
|
|
581
|
+
run: async (signal, requestId) => {
|
|
582
|
+
const url = new URL(path26, apiBaseUrl);
|
|
583
|
+
const headers = {
|
|
584
|
+
authorization: `Bearer ${token}`,
|
|
585
|
+
"x-request-id": requestId
|
|
586
|
+
};
|
|
587
|
+
if (body) {
|
|
588
|
+
headers["content-type"] = "application/json";
|
|
589
|
+
}
|
|
590
|
+
const init = { method, headers, signal };
|
|
591
|
+
if (body) {
|
|
592
|
+
init.body = JSON.stringify(body);
|
|
593
|
+
}
|
|
594
|
+
const response = await fetch(url, init);
|
|
595
|
+
const text = await response.text();
|
|
596
|
+
logger.info("sprites_response", {
|
|
597
|
+
requestId,
|
|
598
|
+
method,
|
|
599
|
+
path: path26,
|
|
600
|
+
status: response.status
|
|
601
|
+
});
|
|
602
|
+
if (!response.ok) {
|
|
603
|
+
const snippet = text.trim().slice(0, 200);
|
|
604
|
+
throw new SpritesApiError(response.status, method, path26, snippet);
|
|
605
|
+
}
|
|
606
|
+
if (!text) return null;
|
|
607
|
+
try {
|
|
608
|
+
return JSON.parse(text);
|
|
609
|
+
} catch {
|
|
610
|
+
return text;
|
|
611
|
+
}
|
|
612
|
+
}
|
|
516
613
|
});
|
|
517
|
-
if (!response.ok) {
|
|
518
|
-
const snippet = text.trim().slice(0, 200);
|
|
519
|
-
throw new SpritesApiError(response.status, method, path26, snippet);
|
|
520
|
-
}
|
|
521
|
-
if (!text) return null;
|
|
522
|
-
try {
|
|
523
|
-
return JSON.parse(text);
|
|
524
|
-
} catch {
|
|
525
|
-
return text;
|
|
526
|
-
}
|
|
527
614
|
};
|
|
528
615
|
listSprites = async (apiBaseUrl, token, options) => {
|
|
529
616
|
const params = new URLSearchParams();
|
|
@@ -564,88 +651,99 @@ var init_sprites = __esm({
|
|
|
564
651
|
return response;
|
|
565
652
|
};
|
|
566
653
|
requestNdjson = async (apiBaseUrl, token, method, path26, body) => {
|
|
567
|
-
|
|
568
|
-
const url = new URL(path26, apiBaseUrl);
|
|
569
|
-
const headers = {
|
|
570
|
-
authorization: `Bearer ${token}`,
|
|
571
|
-
"x-request-id": requestId
|
|
572
|
-
};
|
|
573
|
-
if (body) {
|
|
574
|
-
headers["content-type"] = "application/json";
|
|
575
|
-
}
|
|
576
|
-
const init = { method, headers };
|
|
577
|
-
if (body) {
|
|
578
|
-
init.body = JSON.stringify(body);
|
|
579
|
-
}
|
|
580
|
-
logger.info("sprites_request", { requestId, method, path: path26 });
|
|
581
|
-
const response = await fetch(url, init);
|
|
582
|
-
logger.info("sprites_response", {
|
|
583
|
-
requestId,
|
|
654
|
+
return await withSpritesRetry({
|
|
584
655
|
method,
|
|
585
656
|
path: path26,
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
657
|
+
run: async (signal, requestId) => {
|
|
658
|
+
const url = new URL(path26, apiBaseUrl);
|
|
659
|
+
const headers = {
|
|
660
|
+
authorization: `Bearer ${token}`,
|
|
661
|
+
"x-request-id": requestId
|
|
662
|
+
};
|
|
663
|
+
if (body) {
|
|
664
|
+
headers["content-type"] = "application/json";
|
|
665
|
+
}
|
|
666
|
+
const init = { method, headers, signal };
|
|
667
|
+
if (body) {
|
|
668
|
+
init.body = JSON.stringify(body);
|
|
669
|
+
}
|
|
670
|
+
const response = await fetch(url, init);
|
|
671
|
+
logger.info("sprites_response", {
|
|
672
|
+
requestId,
|
|
673
|
+
method,
|
|
674
|
+
path: path26,
|
|
675
|
+
status: response.status
|
|
676
|
+
});
|
|
677
|
+
const text = await response.text();
|
|
678
|
+
if (!response.ok) {
|
|
679
|
+
const snippet = text.trim().slice(0, 200);
|
|
680
|
+
throw new SpritesApiError(response.status, method, path26, snippet);
|
|
681
|
+
}
|
|
682
|
+
const lines = text.split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0);
|
|
683
|
+
const events = [];
|
|
684
|
+
for (const line of lines) {
|
|
685
|
+
try {
|
|
686
|
+
const parsed = JSON.parse(line);
|
|
687
|
+
if (Array.isArray(parsed)) {
|
|
688
|
+
for (const entry of parsed) {
|
|
689
|
+
if (entry && typeof entry === "object") {
|
|
690
|
+
events.push(entry);
|
|
691
|
+
} else {
|
|
692
|
+
events.push({ value: entry });
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
continue;
|
|
604
696
|
}
|
|
697
|
+
if (parsed && typeof parsed === "object") {
|
|
698
|
+
events.push(parsed);
|
|
699
|
+
continue;
|
|
700
|
+
}
|
|
701
|
+
events.push({ value: parsed });
|
|
702
|
+
} catch {
|
|
703
|
+
events.push({ raw: line });
|
|
605
704
|
}
|
|
606
|
-
continue;
|
|
607
705
|
}
|
|
608
|
-
|
|
609
|
-
events.push(parsed);
|
|
610
|
-
continue;
|
|
611
|
-
}
|
|
612
|
-
events.push({ value: parsed });
|
|
613
|
-
} catch {
|
|
614
|
-
events.push({ raw: line });
|
|
706
|
+
return events;
|
|
615
707
|
}
|
|
616
|
-
}
|
|
617
|
-
return events;
|
|
708
|
+
});
|
|
618
709
|
};
|
|
619
710
|
writeFile = async (apiBaseUrl, token, name, remotePath, data) => {
|
|
620
|
-
const requestId = (0, import_node_crypto.randomUUID)();
|
|
621
711
|
const path26 = `/v1/sprites/${name}/fs/write`;
|
|
622
712
|
const url = new URL(path26, apiBaseUrl);
|
|
623
713
|
url.searchParams.set("path", remotePath);
|
|
624
714
|
url.searchParams.set("mkdir", "true");
|
|
625
|
-
|
|
626
|
-
requestId,
|
|
627
|
-
path: path26,
|
|
628
|
-
name,
|
|
629
|
-
remotePath,
|
|
630
|
-
size: data.length
|
|
631
|
-
});
|
|
632
|
-
const response = await fetch(url, {
|
|
715
|
+
await withSpritesRetry({
|
|
633
716
|
method: "PUT",
|
|
634
|
-
headers: {
|
|
635
|
-
authorization: `Bearer ${token}`,
|
|
636
|
-
"content-type": "application/octet-stream",
|
|
637
|
-
"x-request-id": requestId
|
|
638
|
-
},
|
|
639
|
-
body: data
|
|
640
|
-
});
|
|
641
|
-
logger.info("sprites_fs_write_response", {
|
|
642
|
-
requestId,
|
|
643
717
|
path: path26,
|
|
644
|
-
|
|
718
|
+
run: async (signal, requestId) => {
|
|
719
|
+
logger.info("sprites_fs_write", {
|
|
720
|
+
requestId,
|
|
721
|
+
path: path26,
|
|
722
|
+
name,
|
|
723
|
+
remotePath,
|
|
724
|
+
size: data.length
|
|
725
|
+
});
|
|
726
|
+
const response = await fetch(url, {
|
|
727
|
+
method: "PUT",
|
|
728
|
+
headers: {
|
|
729
|
+
authorization: `Bearer ${token}`,
|
|
730
|
+
"content-type": "application/octet-stream",
|
|
731
|
+
"x-request-id": requestId
|
|
732
|
+
},
|
|
733
|
+
body: data,
|
|
734
|
+
signal
|
|
735
|
+
});
|
|
736
|
+
logger.info("sprites_fs_write_response", {
|
|
737
|
+
requestId,
|
|
738
|
+
path: path26,
|
|
739
|
+
status: response.status
|
|
740
|
+
});
|
|
741
|
+
if (!response.ok) {
|
|
742
|
+
const snippet = (await response.text()).trim().slice(0, 200);
|
|
743
|
+
throw new SpritesApiError(response.status, "PUT", path26, snippet);
|
|
744
|
+
}
|
|
745
|
+
}
|
|
645
746
|
});
|
|
646
|
-
if (!response.ok) {
|
|
647
|
-
throw new Error(`Sprites FS write failed: ${response.status}`);
|
|
648
|
-
}
|
|
649
747
|
};
|
|
650
748
|
normalizeServiceRecord = (entry) => {
|
|
651
749
|
const rawName = entry.name;
|
|
@@ -676,38 +774,44 @@ var init_sprites = __esm({
|
|
|
676
774
|
return service;
|
|
677
775
|
};
|
|
678
776
|
readFile = async (apiBaseUrl, token, name, options) => {
|
|
679
|
-
const requestId = (0, import_node_crypto.randomUUID)();
|
|
680
777
|
const path26 = `/v1/sprites/${name}/fs/read`;
|
|
681
778
|
const url = new URL(path26, apiBaseUrl);
|
|
682
779
|
url.searchParams.set("path", options.path);
|
|
683
780
|
if (options.workingDir) {
|
|
684
781
|
url.searchParams.set("workingDir", options.workingDir);
|
|
685
782
|
}
|
|
686
|
-
|
|
687
|
-
requestId,
|
|
688
|
-
path: path26,
|
|
689
|
-
name,
|
|
690
|
-
remotePath: options.path,
|
|
691
|
-
workingDir: options.workingDir
|
|
692
|
-
});
|
|
693
|
-
const response = await fetch(url, {
|
|
783
|
+
return await withSpritesRetry({
|
|
694
784
|
method: "GET",
|
|
695
|
-
headers: {
|
|
696
|
-
authorization: `Bearer ${token}`,
|
|
697
|
-
"x-request-id": requestId
|
|
698
|
-
}
|
|
699
|
-
});
|
|
700
|
-
logger.info("sprites_fs_read_response", {
|
|
701
|
-
requestId,
|
|
702
785
|
path: path26,
|
|
703
|
-
|
|
786
|
+
run: async (signal, requestId) => {
|
|
787
|
+
logger.info("sprites_fs_read", {
|
|
788
|
+
requestId,
|
|
789
|
+
path: path26,
|
|
790
|
+
name,
|
|
791
|
+
remotePath: options.path,
|
|
792
|
+
workingDir: options.workingDir
|
|
793
|
+
});
|
|
794
|
+
const response = await fetch(url, {
|
|
795
|
+
method: "GET",
|
|
796
|
+
headers: {
|
|
797
|
+
authorization: `Bearer ${token}`,
|
|
798
|
+
"x-request-id": requestId
|
|
799
|
+
},
|
|
800
|
+
signal
|
|
801
|
+
});
|
|
802
|
+
logger.info("sprites_fs_read_response", {
|
|
803
|
+
requestId,
|
|
804
|
+
path: path26,
|
|
805
|
+
status: response.status
|
|
806
|
+
});
|
|
807
|
+
if (!response.ok) {
|
|
808
|
+
const snippet = (await response.text()).trim().slice(0, 200);
|
|
809
|
+
throw new SpritesApiError(response.status, "GET", path26, snippet);
|
|
810
|
+
}
|
|
811
|
+
const buffer = await response.arrayBuffer();
|
|
812
|
+
return new Uint8Array(buffer);
|
|
813
|
+
}
|
|
704
814
|
});
|
|
705
|
-
if (!response.ok) {
|
|
706
|
-
const snippet = (await response.text()).trim().slice(0, 200);
|
|
707
|
-
throw new SpritesApiError(response.status, "GET", path26, snippet);
|
|
708
|
-
}
|
|
709
|
-
const buffer = await response.arrayBuffer();
|
|
710
|
-
return new Uint8Array(buffer);
|
|
711
815
|
};
|
|
712
816
|
openExecSocket = (apiBaseUrl, token, name, options) => {
|
|
713
817
|
const url = toWsUrl(apiBaseUrl, `/v1/sprites/${name}/exec`);
|
|
@@ -931,7 +1035,7 @@ var init_sprites = __esm({
|
|
|
931
1035
|
await internalServicesRequest(apiBaseUrl, token, name, command);
|
|
932
1036
|
return [];
|
|
933
1037
|
};
|
|
934
|
-
execCommand = async (apiBaseUrl, token, name, cmd, requestId) => {
|
|
1038
|
+
execCommand = async (apiBaseUrl, token, name, cmd, requestId, options) => {
|
|
935
1039
|
const path26 = `/v1/sprites/${name}/exec`;
|
|
936
1040
|
const url = toWsUrl(apiBaseUrl, path26);
|
|
937
1041
|
cmd.forEach((part) => url.searchParams.append("cmd", part));
|
|
@@ -942,11 +1046,28 @@ var init_sprites = __esm({
|
|
|
942
1046
|
const stderr = [];
|
|
943
1047
|
let exitCode = null;
|
|
944
1048
|
let resolved = false;
|
|
1049
|
+
const timeoutMs = options?.timeoutMs;
|
|
1050
|
+
const handshakeTimeoutMs = options?.handshakeTimeoutMs ?? (typeof timeoutMs === "number" ? Math.min(timeoutMs, 6e4) : void 0);
|
|
1051
|
+
const timeoutHandle = typeof timeoutMs === "number" && timeoutMs > 0 ? setTimeout(() => {
|
|
1052
|
+
if (resolved) return;
|
|
1053
|
+
resolved = true;
|
|
1054
|
+
logger.warn("sprites_exec_timeout", {
|
|
1055
|
+
requestId,
|
|
1056
|
+
path: path26,
|
|
1057
|
+
timeoutMs
|
|
1058
|
+
});
|
|
1059
|
+
try {
|
|
1060
|
+
ws.terminate();
|
|
1061
|
+
} catch {
|
|
1062
|
+
}
|
|
1063
|
+
reject(new Error(`Exec websocket timed out after ${timeoutMs}ms`));
|
|
1064
|
+
}, timeoutMs) : null;
|
|
945
1065
|
const ws = new import_ws.default(url.toString(), {
|
|
946
1066
|
headers: {
|
|
947
1067
|
Authorization: `Bearer ${token}`,
|
|
948
1068
|
"x-request-id": requestId
|
|
949
|
-
}
|
|
1069
|
+
},
|
|
1070
|
+
...typeof handshakeTimeoutMs === "number" && handshakeTimeoutMs > 0 ? { handshakeTimeout: handshakeTimeoutMs } : {}
|
|
950
1071
|
});
|
|
951
1072
|
const readResponseSnippet = async (response, limit = 800) => new Promise((resolveBody) => {
|
|
952
1073
|
let body = "";
|
|
@@ -972,6 +1093,8 @@ var init_sprites = __esm({
|
|
|
972
1093
|
bodySnippet: snippet ? snippet.slice(0, 800) : void 0
|
|
973
1094
|
});
|
|
974
1095
|
if (!resolved) {
|
|
1096
|
+
if (timeoutHandle) clearTimeout(timeoutHandle);
|
|
1097
|
+
resolved = true;
|
|
975
1098
|
const suffix = snippet ? ` (${snippet.slice(0, 800)})` : "";
|
|
976
1099
|
reject(new Error(`Exec websocket error: Unexpected server response: ${status}${suffix}`));
|
|
977
1100
|
}
|
|
@@ -980,6 +1103,7 @@ var init_sprites = __esm({
|
|
|
980
1103
|
const finish = (code2) => {
|
|
981
1104
|
if (resolved) return;
|
|
982
1105
|
resolved = true;
|
|
1106
|
+
if (timeoutHandle) clearTimeout(timeoutHandle);
|
|
983
1107
|
logger.info("sprites_exec_response", { requestId, path: path26, status: code2 });
|
|
984
1108
|
resolve({
|
|
985
1109
|
exitCode: code2,
|
|
@@ -1037,6 +1161,8 @@ var init_sprites = __esm({
|
|
|
1037
1161
|
errorStack: errorInfo.stack
|
|
1038
1162
|
});
|
|
1039
1163
|
if (!resolved) {
|
|
1164
|
+
if (timeoutHandle) clearTimeout(timeoutHandle);
|
|
1165
|
+
resolved = true;
|
|
1040
1166
|
reject(new Error(`Exec websocket error: ${errorMessage}`));
|
|
1041
1167
|
}
|
|
1042
1168
|
};
|
|
@@ -1091,7 +1217,7 @@ var init_sprites = __esm({
|
|
|
1091
1217
|
await writeFile(apiBaseUrl, token, name, remotePath, data);
|
|
1092
1218
|
},
|
|
1093
1219
|
readFile: async (name, options) => readFile(apiBaseUrl, token, name, options),
|
|
1094
|
-
exec: async (name, cmd) => {
|
|
1220
|
+
exec: async (name, cmd, options) => {
|
|
1095
1221
|
const requestId = (0, import_node_crypto.randomUUID)();
|
|
1096
1222
|
logger.info("sprites_exec", {
|
|
1097
1223
|
requestId,
|
|
@@ -1099,7 +1225,7 @@ var init_sprites = __esm({
|
|
|
1099
1225
|
cmd,
|
|
1100
1226
|
path: `/v1/sprites/${name}/exec`
|
|
1101
1227
|
});
|
|
1102
|
-
return execCommand(apiBaseUrl, token, name, cmd, requestId);
|
|
1228
|
+
return execCommand(apiBaseUrl, token, name, cmd, requestId, options);
|
|
1103
1229
|
},
|
|
1104
1230
|
listExecSessions: async (name) => listExecSessions(apiBaseUrl, token, name),
|
|
1105
1231
|
listServices: async (name) => USE_INTERNAL_SERVICE_API ? listServicesInternal(apiBaseUrl, token, name) : listServices(apiBaseUrl, token, name),
|
|
@@ -4726,27 +4852,27 @@ var init_authentication_manager = __esm({
|
|
|
4726
4852
|
);
|
|
4727
4853
|
return;
|
|
4728
4854
|
}
|
|
4729
|
-
let
|
|
4855
|
+
let delay3 = Math.min(
|
|
4730
4856
|
MAXIMUM_REFRESH_DELAY,
|
|
4731
4857
|
(tokenValiditySeconds - this.refreshTokenLeewaySeconds) * 1e3
|
|
4732
4858
|
);
|
|
4733
|
-
if (
|
|
4859
|
+
if (delay3 <= 0) {
|
|
4734
4860
|
this.logger.warn(
|
|
4735
4861
|
`Refetching auth token immediately, configured leeway ${this.refreshTokenLeewaySeconds}s is larger than the token's lifetime ${tokenValiditySeconds}s`
|
|
4736
4862
|
);
|
|
4737
|
-
|
|
4863
|
+
delay3 = 0;
|
|
4738
4864
|
}
|
|
4739
4865
|
const refetchTokenTimeoutId = setTimeout(() => {
|
|
4740
4866
|
this._logVerbose("running scheduled token refetch");
|
|
4741
4867
|
void this.refetchToken();
|
|
4742
|
-
},
|
|
4868
|
+
}, delay3);
|
|
4743
4869
|
this.setAuthState({
|
|
4744
4870
|
state: "waitingForScheduledRefetch",
|
|
4745
4871
|
refetchTokenTimeoutId,
|
|
4746
4872
|
config: this.authState.config
|
|
4747
4873
|
});
|
|
4748
4874
|
this._logVerbose(
|
|
4749
|
-
`scheduled preemptive auth token refetching in ${
|
|
4875
|
+
`scheduled preemptive auth token refetching in ${delay3}ms`
|
|
4750
4876
|
);
|
|
4751
4877
|
}
|
|
4752
4878
|
// Protects against simultaneous calls to `setConfig`
|
|
@@ -19741,8 +19867,8 @@ var init_connect = __esm({
|
|
|
19741
19867
|
pendingPortLogs.set(event.port, token2);
|
|
19742
19868
|
const delays = [30, 60, 120, 200];
|
|
19743
19869
|
void (async () => {
|
|
19744
|
-
for (const
|
|
19745
|
-
await new Promise((resolve) => setTimeout(resolve,
|
|
19870
|
+
for (const delay3 of delays) {
|
|
19871
|
+
await new Promise((resolve) => setTimeout(resolve, delay3));
|
|
19746
19872
|
if (pendingPortLogs.get(event.port) !== token2) {
|
|
19747
19873
|
return;
|
|
19748
19874
|
}
|
|
@@ -22317,7 +22443,7 @@ var init_weztermMux = __esm({
|
|
|
22317
22443
|
});
|
|
22318
22444
|
|
|
22319
22445
|
// src/devbox/commands/init/remote.ts
|
|
22320
|
-
var import_node_crypto10, DAEMON_DIR, DAEMON_TARBALL, DAEMON_BUNDLE_DIR, DAEMON_ENTRY, DAEMON_WRAPPER, DAEMON_SERVICE_NAME, DAEMON_CONFIG_FILE, DEFAULT_DAEMON_BASE_URL, DEFAULT_HEARTBEAT_MS, logger8, truncateTail, shellQuote3, expandHome2, execWithLog, writeRemoteFile, bootstrapDevbox, buildWeztermMuxConfig, buildWeztermMuxRunner, patchBashrc, writeRemoteCodexConfig, stageRemoteSetupArtifacts, resolveDaemonUrl, fetchDaemonBinary, buildDaemonConfig, isSameArgs, ensureSpriteDaemonService, installWeztermMux, ensureWeztermMuxService, hasWeztermMuxBinary, isWeztermMuxHealthy, installSpriteDaemon;
|
|
22446
|
+
var import_node_crypto10, DAEMON_DIR, DAEMON_TARBALL, DAEMON_BUNDLE_DIR, DAEMON_ENTRY, DAEMON_WRAPPER, DAEMON_SERVICE_NAME, DAEMON_CONFIG_FILE, DEFAULT_DAEMON_BASE_URL, DEFAULT_HEARTBEAT_MS, BOOTSTRAP_EXEC_TIMEOUT_MS, BOOTSTRAP_EXEC_RETRY_DELAY_MS, logger8, truncateTail, shellQuote3, expandHome2, execWithLog, isExecTimeoutError, delay2, writeRemoteFile, bootstrapDevbox, buildWeztermMuxConfig, buildWeztermMuxRunner, patchBashrc, writeRemoteCodexConfig, stageRemoteSetupArtifacts, resolveDaemonUrl, fetchDaemonBinary, buildDaemonConfig, isSameArgs, ensureSpriteDaemonService, installWeztermMux, ensureWeztermMuxService, hasWeztermMuxBinary, isWeztermMuxHealthy, installSpriteDaemon;
|
|
22321
22447
|
var init_remote = __esm({
|
|
22322
22448
|
"src/devbox/commands/init/remote.ts"() {
|
|
22323
22449
|
"use strict";
|
|
@@ -22335,6 +22461,8 @@ var init_remote = __esm({
|
|
|
22335
22461
|
DAEMON_CONFIG_FILE = `${DAEMON_DIR}/config.json`;
|
|
22336
22462
|
DEFAULT_DAEMON_BASE_URL = process.env.SPRITE_DAEMON_BASE_URL?.trim() || "https://deploy-dev.boxes.dev";
|
|
22337
22463
|
DEFAULT_HEARTBEAT_MS = 3e4;
|
|
22464
|
+
BOOTSTRAP_EXEC_TIMEOUT_MS = 9e4;
|
|
22465
|
+
BOOTSTRAP_EXEC_RETRY_DELAY_MS = 1e4;
|
|
22338
22466
|
logger8 = createLogger("devbox-init");
|
|
22339
22467
|
truncateTail = (value, maxChars) => {
|
|
22340
22468
|
if (value.length <= maxChars) return value;
|
|
@@ -22348,7 +22476,7 @@ var init_remote = __esm({
|
|
|
22348
22476
|
}
|
|
22349
22477
|
return value;
|
|
22350
22478
|
};
|
|
22351
|
-
execWithLog = async (client, canonical, script, stage) => {
|
|
22479
|
+
execWithLog = async (client, canonical, script, stage, options) => {
|
|
22352
22480
|
const requestId = (0, import_node_crypto10.randomUUID)();
|
|
22353
22481
|
const startedAt2 = Date.now();
|
|
22354
22482
|
logger8.info("sprites_request", {
|
|
@@ -22358,7 +22486,11 @@ var init_remote = __esm({
|
|
|
22358
22486
|
box: canonical,
|
|
22359
22487
|
stage
|
|
22360
22488
|
});
|
|
22361
|
-
const result = await client.exec(
|
|
22489
|
+
const result = await client.exec(
|
|
22490
|
+
canonical,
|
|
22491
|
+
["/bin/bash", "-lc", script],
|
|
22492
|
+
options
|
|
22493
|
+
);
|
|
22362
22494
|
const durationMs = Date.now() - startedAt2;
|
|
22363
22495
|
logger8.info("sprites_response", {
|
|
22364
22496
|
requestId,
|
|
@@ -22378,6 +22510,8 @@ var init_remote = __esm({
|
|
|
22378
22510
|
});
|
|
22379
22511
|
return result;
|
|
22380
22512
|
};
|
|
22513
|
+
isExecTimeoutError = (error) => error instanceof Error && typeof error.message === "string" && error.message.startsWith("Exec websocket timed out after ");
|
|
22514
|
+
delay2 = async (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
22381
22515
|
writeRemoteFile = async (client, canonical, path26, content, stage) => {
|
|
22382
22516
|
const requestId = (0, import_node_crypto10.randomUUID)();
|
|
22383
22517
|
logger8.info("sprites_request", {
|
|
@@ -22409,12 +22543,28 @@ var init_remote = __esm({
|
|
|
22409
22543
|
" sudo -n chown -R sprite:sprite /home/sprite/.devbox || true",
|
|
22410
22544
|
"fi"
|
|
22411
22545
|
].join("\n");
|
|
22412
|
-
|
|
22546
|
+
let permsResult = await execWithLog(
|
|
22413
22547
|
client,
|
|
22414
22548
|
canonical,
|
|
22415
22549
|
permissionsScript,
|
|
22416
|
-
"bootstrap-permissions"
|
|
22417
|
-
|
|
22550
|
+
"bootstrap-permissions",
|
|
22551
|
+
{ timeoutMs: BOOTSTRAP_EXEC_TIMEOUT_MS }
|
|
22552
|
+
).catch(async (error) => {
|
|
22553
|
+
if (!isExecTimeoutError(error)) throw error;
|
|
22554
|
+
logger8.warn("sprites_exec_retry_after_timeout", {
|
|
22555
|
+
stage: "bootstrap-permissions",
|
|
22556
|
+
timeoutMs: BOOTSTRAP_EXEC_TIMEOUT_MS,
|
|
22557
|
+
delayMs: BOOTSTRAP_EXEC_RETRY_DELAY_MS
|
|
22558
|
+
});
|
|
22559
|
+
await delay2(BOOTSTRAP_EXEC_RETRY_DELAY_MS);
|
|
22560
|
+
return await execWithLog(
|
|
22561
|
+
client,
|
|
22562
|
+
canonical,
|
|
22563
|
+
permissionsScript,
|
|
22564
|
+
"bootstrap-permissions",
|
|
22565
|
+
{ timeoutMs: BOOTSTRAP_EXEC_TIMEOUT_MS }
|
|
22566
|
+
);
|
|
22567
|
+
});
|
|
22418
22568
|
if (permsResult.exitCode !== 0) {
|
|
22419
22569
|
const details = permsResult.stderr || permsResult.stdout || "";
|
|
22420
22570
|
throw new Error(
|
|
@@ -22434,7 +22584,8 @@ var init_remote = __esm({
|
|
|
22434
22584
|
client,
|
|
22435
22585
|
canonical,
|
|
22436
22586
|
ipv4PreferenceScript,
|
|
22437
|
-
"bootstrap-ipv4-preference"
|
|
22587
|
+
"bootstrap-ipv4-preference",
|
|
22588
|
+
{ timeoutMs: BOOTSTRAP_EXEC_TIMEOUT_MS }
|
|
22438
22589
|
);
|
|
22439
22590
|
if (ipv4Result.exitCode !== 0) {
|
|
22440
22591
|
const details = ipv4Result.stderr || ipv4Result.stdout || "";
|
|
@@ -23079,30 +23230,34 @@ chmod 755 ${WEZTERM_MUX_RUNNER_PATH}`,
|
|
|
23079
23230
|
DAEMON_CONFIG_FILE,
|
|
23080
23231
|
Buffer.from(buildDaemonConfig(convexUrl, heartbeatToken))
|
|
23081
23232
|
);
|
|
23082
|
-
const result = await client.exec(
|
|
23083
|
-
|
|
23084
|
-
"--noprofile",
|
|
23085
|
-
"--norc",
|
|
23086
|
-
"-e",
|
|
23087
|
-
"-u",
|
|
23088
|
-
"-o",
|
|
23089
|
-
"pipefail",
|
|
23090
|
-
"-c",
|
|
23233
|
+
const result = await client.exec(
|
|
23234
|
+
spriteName,
|
|
23091
23235
|
[
|
|
23092
|
-
|
|
23093
|
-
|
|
23094
|
-
|
|
23095
|
-
|
|
23096
|
-
|
|
23097
|
-
|
|
23236
|
+
"/bin/bash",
|
|
23237
|
+
"--noprofile",
|
|
23238
|
+
"--norc",
|
|
23239
|
+
"-e",
|
|
23240
|
+
"-u",
|
|
23241
|
+
"-o",
|
|
23242
|
+
"pipefail",
|
|
23243
|
+
"-c",
|
|
23098
23244
|
[
|
|
23099
|
-
|
|
23100
|
-
|
|
23101
|
-
|
|
23102
|
-
|
|
23103
|
-
|
|
23104
|
-
|
|
23105
|
-
|
|
23245
|
+
`mkdir -p ${DAEMON_DIR}`,
|
|
23246
|
+
`rm -rf ${DAEMON_BUNDLE_DIR}`,
|
|
23247
|
+
`mkdir -p ${DAEMON_BUNDLE_DIR}`,
|
|
23248
|
+
`tar -xzf ${DAEMON_TARBALL} -C ${DAEMON_BUNDLE_DIR}`,
|
|
23249
|
+
`chmod 755 ${DAEMON_ENTRY} || true`,
|
|
23250
|
+
`chmod 755 ${DAEMON_BUNDLE_DIR}/bin/* || true`,
|
|
23251
|
+
[
|
|
23252
|
+
`${DAEMON_ENTRY} daemonctl install --json --timeout-ms 20000`,
|
|
23253
|
+
`--tarball ${DAEMON_TARBALL}`,
|
|
23254
|
+
`--release-sha ${release.sha256}`,
|
|
23255
|
+
`--config-path ${DAEMON_CONFIG_FILE}`
|
|
23256
|
+
].join(" ")
|
|
23257
|
+
].join("\n")
|
|
23258
|
+
],
|
|
23259
|
+
{ timeoutMs: 12e4 }
|
|
23260
|
+
);
|
|
23106
23261
|
if (result.exitCode !== 0) {
|
|
23107
23262
|
throw new Error(result.stderr || result.stdout || "Daemon install failed.");
|
|
23108
23263
|
}
|
|
@@ -23892,17 +24047,26 @@ var init_template = __esm({
|
|
|
23892
24047
|
});
|
|
23893
24048
|
|
|
23894
24049
|
// src/devbox/commands/init/codex/prompts.ts
|
|
23895
|
-
var import_promises23, import_node_path17, resolvePromptsDir, readPromptTemplate, loadPrompt, loadLocalEnvSecretsScanPrompt, loadLocalExternalScanPrompt, loadLocalExtraArtifactsScanPrompt, loadLocalServicesScanPrompt;
|
|
24050
|
+
var import_node_fs5, import_promises23, import_node_path17, resolvePromptsDir, readPromptTemplate, loadPrompt, loadLocalEnvSecretsScanPrompt, loadLocalExternalScanPrompt, loadLocalExtraArtifactsScanPrompt, loadLocalServicesScanPrompt;
|
|
23896
24051
|
var init_prompts = __esm({
|
|
23897
24052
|
"src/devbox/commands/init/codex/prompts.ts"() {
|
|
23898
24053
|
"use strict";
|
|
24054
|
+
import_node_fs5 = __toESM(require("node:fs"), 1);
|
|
23899
24055
|
import_promises23 = __toESM(require("node:fs/promises"), 1);
|
|
23900
24056
|
import_node_path17 = __toESM(require("node:path"), 1);
|
|
23901
24057
|
init_template();
|
|
23902
24058
|
resolvePromptsDir = () => {
|
|
23903
|
-
const
|
|
23904
|
-
if (
|
|
23905
|
-
|
|
24059
|
+
const argv1 = typeof process.argv[1] === "string" ? process.argv[1] : "";
|
|
24060
|
+
if (argv1) {
|
|
24061
|
+
try {
|
|
24062
|
+
const real = import_node_fs5.default.realpathSync(argv1);
|
|
24063
|
+
return import_node_path17.default.resolve(import_node_path17.default.dirname(real), "..", "prompts");
|
|
24064
|
+
} catch {
|
|
24065
|
+
}
|
|
24066
|
+
try {
|
|
24067
|
+
return import_node_path17.default.resolve(import_node_path17.default.dirname(argv1), "..", "prompts");
|
|
24068
|
+
} catch {
|
|
24069
|
+
}
|
|
23906
24070
|
}
|
|
23907
24071
|
return import_node_path17.default.resolve(process.cwd(), "prompts");
|
|
23908
24072
|
};
|
|
@@ -24424,21 +24588,25 @@ fi`
|
|
|
24424
24588
|
});
|
|
24425
24589
|
|
|
24426
24590
|
// src/devbox/commands/init/codex/plan.ts
|
|
24427
|
-
var import_node_path18, import_promises24, resolveSchemaPath, writeSetupEnvSecretsSchema, writeSetupExternalSchema, writeSetupExtraArtifactsSchema, writeServicesSchema, isObject4, isServicesSelection, isSetupPlan, isSetupEnvSecretsPlan, isSetupExternalPlan, isSetupExtraArtifactsPlan, isServicesPlan, readSetupPlan, readSetupEnvSecretsPlan, readSetupExternalPlan, readSetupExtraArtifactsPlan, readServicesPlan, writeSetupPlan, mergeSetupScans;
|
|
24591
|
+
var import_node_path18, import_node_fs6, import_promises24, resolveSchemaPath, writeSetupEnvSecretsSchema, writeSetupExternalSchema, writeSetupExtraArtifactsSchema, writeServicesSchema, isObject4, isServicesSelection, isSetupPlan, isSetupEnvSecretsPlan, isSetupExternalPlan, isSetupExtraArtifactsPlan, isServicesPlan, readSetupPlan, readSetupEnvSecretsPlan, readSetupExternalPlan, readSetupExtraArtifactsPlan, readServicesPlan, writeSetupPlan, mergeSetupScans;
|
|
24428
24592
|
var init_plan = __esm({
|
|
24429
24593
|
"src/devbox/commands/init/codex/plan.ts"() {
|
|
24430
24594
|
"use strict";
|
|
24431
24595
|
import_node_path18 = __toESM(require("node:path"), 1);
|
|
24596
|
+
import_node_fs6 = __toESM(require("node:fs"), 1);
|
|
24432
24597
|
import_promises24 = __toESM(require("node:fs/promises"), 1);
|
|
24433
24598
|
resolveSchemaPath = (fileName) => {
|
|
24434
|
-
const
|
|
24435
|
-
if (
|
|
24436
|
-
|
|
24437
|
-
|
|
24438
|
-
"..",
|
|
24439
|
-
|
|
24440
|
-
|
|
24441
|
-
|
|
24599
|
+
const argv1 = typeof process.argv[1] === "string" ? process.argv[1] : "";
|
|
24600
|
+
if (argv1) {
|
|
24601
|
+
try {
|
|
24602
|
+
const real = import_node_fs6.default.realpathSync(argv1);
|
|
24603
|
+
return import_node_path18.default.resolve(import_node_path18.default.dirname(real), "..", "codex", fileName);
|
|
24604
|
+
} catch {
|
|
24605
|
+
}
|
|
24606
|
+
try {
|
|
24607
|
+
return import_node_path18.default.resolve(import_node_path18.default.dirname(argv1), "..", "codex", fileName);
|
|
24608
|
+
} catch {
|
|
24609
|
+
}
|
|
24442
24610
|
}
|
|
24443
24611
|
return import_node_path18.default.resolve(process.cwd(), "codex", fileName);
|
|
24444
24612
|
};
|
|
@@ -24728,12 +24896,12 @@ ${bottom}
|
|
|
24728
24896
|
});
|
|
24729
24897
|
|
|
24730
24898
|
// src/devbox/commands/init/codex/local.ts
|
|
24731
|
-
var import_node_child_process9,
|
|
24899
|
+
var import_node_child_process9, import_node_fs7, import_promises25, import_node_path19, stripAnsi3, extractBoldText2, runCodexExec, runLocalSetupEnvSecretsScan, runLocalSetupExternalScan, runLocalSetupExtraArtifactsScan, runLocalServicesScan, toPosixPath, toRepoRelativePath, countSecretVars, buildEnvFileHint, buildExternalDependencyLabel, promptForPlanApproval, promptForServicesApproval;
|
|
24732
24900
|
var init_local = __esm({
|
|
24733
24901
|
"src/devbox/commands/init/codex/local.ts"() {
|
|
24734
24902
|
"use strict";
|
|
24735
24903
|
import_node_child_process9 = require("node:child_process");
|
|
24736
|
-
|
|
24904
|
+
import_node_fs7 = require("node:fs");
|
|
24737
24905
|
import_promises25 = __toESM(require("node:fs/promises"), 1);
|
|
24738
24906
|
import_node_path19 = __toESM(require("node:path"), 1);
|
|
24739
24907
|
init_dist2();
|
|
@@ -24752,11 +24920,11 @@ var init_local = __esm({
|
|
|
24752
24920
|
try {
|
|
24753
24921
|
if (stdoutLogPath) {
|
|
24754
24922
|
await import_promises25.default.mkdir(import_node_path19.default.dirname(stdoutLogPath), { recursive: true });
|
|
24755
|
-
stdoutStream = (0,
|
|
24923
|
+
stdoutStream = (0, import_node_fs7.createWriteStream)(stdoutLogPath, { flags: "a" });
|
|
24756
24924
|
}
|
|
24757
24925
|
if (stderrLogPath) {
|
|
24758
24926
|
await import_promises25.default.mkdir(import_node_path19.default.dirname(stderrLogPath), { recursive: true });
|
|
24759
|
-
stderrStream = (0,
|
|
24927
|
+
stderrStream = (0, import_node_fs7.createWriteStream)(stderrLogPath, { flags: "a" });
|
|
24760
24928
|
}
|
|
24761
24929
|
} catch {
|
|
24762
24930
|
stdoutStream = null;
|
|
@@ -32199,7 +32367,7 @@ var init_cli = __esm({
|
|
|
32199
32367
|
});
|
|
32200
32368
|
|
|
32201
32369
|
// src/bin/dvb.ts
|
|
32202
|
-
var
|
|
32370
|
+
var import_node_fs8 = __toESM(require("node:fs"), 1);
|
|
32203
32371
|
var import_node_os11 = __toESM(require("node:os"), 1);
|
|
32204
32372
|
var import_node_path26 = __toESM(require("node:path"), 1);
|
|
32205
32373
|
init_src();
|
|
@@ -32257,8 +32425,8 @@ run().catch((error) => {
|
|
|
32257
32425
|
if (homeDir) {
|
|
32258
32426
|
try {
|
|
32259
32427
|
const logDir = import_node_path26.default.join(resolveDevboxDir(homeDir), "wezterm");
|
|
32260
|
-
|
|
32261
|
-
|
|
32428
|
+
import_node_fs8.default.mkdirSync(logDir, { recursive: true });
|
|
32429
|
+
import_node_fs8.default.appendFileSync(
|
|
32262
32430
|
import_node_path26.default.join(logDir, "proxy.log"),
|
|
32263
32431
|
`${(/* @__PURE__ */ new Date()).toISOString()} ${message}
|
|
32264
32432
|
`
|