@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/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
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
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
|
-
|
|
433
|
-
|
|
434
|
-
|
|
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
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
4663
|
+
let delay2 = Math.min(
|
|
4538
4664
|
MAXIMUM_REFRESH_DELAY,
|
|
4539
4665
|
(tokenValiditySeconds - this.refreshTokenLeewaySeconds) * 1e3
|
|
4540
4666
|
);
|
|
4541
|
-
if (
|
|
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
|
-
|
|
4671
|
+
delay2 = 0;
|
|
4546
4672
|
}
|
|
4547
4673
|
const refetchTokenTimeoutId = setTimeout(() => {
|
|
4548
4674
|
this._logVerbose("running scheduled token refetch");
|
|
4549
4675
|
void this.refetchToken();
|
|
4550
|
-
},
|
|
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 ${
|
|
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":"
|
|
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
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import fsPromises from "node:fs/promises";
|
|
3
4
|
const resolveSchemaPath = (fileName) => {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
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
|
|
27
|
+
const schemaContents = await fsPromises.readFile(sourceSchemaPath, "utf8");
|
|
13
28
|
const schemaPath = path.join(dir, "setup-env-secrets-schema.json");
|
|
14
|
-
await
|
|
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
|
|
34
|
+
const schemaContents = await fsPromises.readFile(sourceSchemaPath, "utf8");
|
|
20
35
|
const schemaPath = path.join(dir, "setup-external-schema.json");
|
|
21
|
-
await
|
|
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
|
|
41
|
+
const schemaContents = await fsPromises.readFile(sourceSchemaPath, "utf8");
|
|
27
42
|
const schemaPath = path.join(dir, "setup-extra-artifacts-schema.json");
|
|
28
|
-
await
|
|
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
|
|
48
|
+
const schemaContents = await fsPromises.readFile(sourceSchemaPath, "utf8");
|
|
34
49
|
const schemaPath = path.join(dir, "services-schema.json");
|
|
35
|
-
await
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|