@boxes-dev/dvb 1.0.60 → 1.0.61

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  "use strict";
3
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="785204a7-1bc2-5318-801f-4ad682a364a7")}catch(e){}}();
3
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="b4643c26-df5e-5ece-b58a-108a9965ffde")}catch(e){}}();
4
4
 
5
5
  var __create = Object.create;
6
6
  var __defProp = Object.defineProperty;
@@ -88683,8 +88683,8 @@ var init_otel = __esm({
88683
88683
  return trimmed && trimmed.length > 0 ? trimmed : void 0;
88684
88684
  };
88685
88685
  readBuildMetadata = () => {
88686
- const rawPackageVersion = "1.0.60";
88687
- const rawGitSha = "5d6099c6753665655e7ad622e1aa388d91ea0bf7";
88686
+ const rawPackageVersion = "1.0.61";
88687
+ const rawGitSha = "ef3417e1e95b9ccc6114ef7c44fa645a1704b688";
88688
88688
  const packageVersion = typeof rawPackageVersion === "string" ? rawPackageVersion : void 0;
88689
88689
  const gitSha = typeof rawGitSha === "string" ? rawGitSha : void 0;
88690
88690
  return { packageVersion, gitSha };
@@ -120672,9 +120672,9 @@ var init_sentry = __esm({
120672
120672
  sentryEnabled = false;
120673
120673
  uncaughtExceptionMonitorInstalled = false;
120674
120674
  readBuildMetadata2 = () => {
120675
- const rawPackageVersion = "1.0.60";
120676
- const rawGitSha = "5d6099c6753665655e7ad622e1aa388d91ea0bf7";
120677
- const rawSentryRelease = "boxes-dev-dvb@1.0.60+5d6099c6753665655e7ad622e1aa388d91ea0bf7";
120675
+ const rawPackageVersion = "1.0.61";
120676
+ const rawGitSha = "ef3417e1e95b9ccc6114ef7c44fa645a1704b688";
120677
+ const rawSentryRelease = "boxes-dev-dvb@1.0.61+ef3417e1e95b9ccc6114ef7c44fa645a1704b688";
120678
120678
  const packageVersion = typeof rawPackageVersion === "string" ? rawPackageVersion : void 0;
120679
120679
  const gitSha = typeof rawGitSha === "string" ? rawGitSha : void 0;
120680
120680
  const sentryRelease = typeof rawSentryRelease === "string" ? rawSentryRelease : void 0;
@@ -129291,8 +129291,148 @@ var init_parse = __esm({
129291
129291
  });
129292
129292
 
129293
129293
  // ../../node_modules/smol-toml/dist/stringify.js
129294
+ function extendedTypeOf(obj) {
129295
+ let type = typeof obj;
129296
+ if (type === "object") {
129297
+ if (Array.isArray(obj))
129298
+ return "array";
129299
+ if (obj instanceof Date)
129300
+ return "date";
129301
+ }
129302
+ return type;
129303
+ }
129304
+ function isArrayOfTables(obj) {
129305
+ for (let i2 = 0; i2 < obj.length; i2++) {
129306
+ if (extendedTypeOf(obj[i2]) !== "object")
129307
+ return false;
129308
+ }
129309
+ return obj.length != 0;
129310
+ }
129311
+ function formatString(s2) {
129312
+ return JSON.stringify(s2).replace(/\x7f/g, "\\u007f");
129313
+ }
129314
+ function stringifyValue2(val, type, depth, numberAsFloat) {
129315
+ if (depth === 0) {
129316
+ throw new Error("Could not stringify the object: maximum object depth exceeded");
129317
+ }
129318
+ if (type === "number") {
129319
+ if (isNaN(val))
129320
+ return "nan";
129321
+ if (val === Infinity)
129322
+ return "inf";
129323
+ if (val === -Infinity)
129324
+ return "-inf";
129325
+ if (numberAsFloat && Number.isInteger(val))
129326
+ return val.toFixed(1);
129327
+ return val.toString();
129328
+ }
129329
+ if (type === "bigint" || type === "boolean") {
129330
+ return val.toString();
129331
+ }
129332
+ if (type === "string") {
129333
+ return formatString(val);
129334
+ }
129335
+ if (type === "date") {
129336
+ if (isNaN(val.getTime())) {
129337
+ throw new TypeError("cannot serialize invalid date");
129338
+ }
129339
+ return val.toISOString();
129340
+ }
129341
+ if (type === "object") {
129342
+ return stringifyInlineTable(val, depth, numberAsFloat);
129343
+ }
129344
+ if (type === "array") {
129345
+ return stringifyArray(val, depth, numberAsFloat);
129346
+ }
129347
+ }
129348
+ function stringifyInlineTable(obj, depth, numberAsFloat) {
129349
+ let keys = Object.keys(obj);
129350
+ if (keys.length === 0)
129351
+ return "{}";
129352
+ let res = "{ ";
129353
+ for (let i2 = 0; i2 < keys.length; i2++) {
129354
+ let k3 = keys[i2];
129355
+ if (i2)
129356
+ res += ", ";
129357
+ res += BARE_KEY.test(k3) ? k3 : formatString(k3);
129358
+ res += " = ";
129359
+ res += stringifyValue2(obj[k3], extendedTypeOf(obj[k3]), depth - 1, numberAsFloat);
129360
+ }
129361
+ return res + " }";
129362
+ }
129363
+ function stringifyArray(array, depth, numberAsFloat) {
129364
+ if (array.length === 0)
129365
+ return "[]";
129366
+ let res = "[ ";
129367
+ for (let i2 = 0; i2 < array.length; i2++) {
129368
+ if (i2)
129369
+ res += ", ";
129370
+ if (array[i2] === null || array[i2] === void 0) {
129371
+ throw new TypeError("arrays cannot contain null or undefined values");
129372
+ }
129373
+ res += stringifyValue2(array[i2], extendedTypeOf(array[i2]), depth - 1, numberAsFloat);
129374
+ }
129375
+ return res + " ]";
129376
+ }
129377
+ function stringifyArrayTable(array, key, depth, numberAsFloat) {
129378
+ if (depth === 0) {
129379
+ throw new Error("Could not stringify the object: maximum object depth exceeded");
129380
+ }
129381
+ let res = "";
129382
+ for (let i2 = 0; i2 < array.length; i2++) {
129383
+ res += `${res && "\n"}[[${key}]]
129384
+ `;
129385
+ res += stringifyTable(0, array[i2], key, depth, numberAsFloat);
129386
+ }
129387
+ return res;
129388
+ }
129389
+ function stringifyTable(tableKey, obj, prefix, depth, numberAsFloat) {
129390
+ if (depth === 0) {
129391
+ throw new Error("Could not stringify the object: maximum object depth exceeded");
129392
+ }
129393
+ let preamble = "";
129394
+ let tables = "";
129395
+ let keys = Object.keys(obj);
129396
+ for (let i2 = 0; i2 < keys.length; i2++) {
129397
+ let k3 = keys[i2];
129398
+ if (obj[k3] !== null && obj[k3] !== void 0) {
129399
+ let type = extendedTypeOf(obj[k3]);
129400
+ if (type === "symbol" || type === "function") {
129401
+ throw new TypeError(`cannot serialize values of type '${type}'`);
129402
+ }
129403
+ let key = BARE_KEY.test(k3) ? k3 : formatString(k3);
129404
+ if (type === "array" && isArrayOfTables(obj[k3])) {
129405
+ tables += (tables && "\n") + stringifyArrayTable(obj[k3], prefix ? `${prefix}.${key}` : key, depth - 1, numberAsFloat);
129406
+ } else if (type === "object") {
129407
+ let tblKey = prefix ? `${prefix}.${key}` : key;
129408
+ tables += (tables && "\n") + stringifyTable(tblKey, obj[k3], tblKey, depth - 1, numberAsFloat);
129409
+ } else {
129410
+ preamble += key;
129411
+ preamble += " = ";
129412
+ preamble += stringifyValue2(obj[k3], type, depth, numberAsFloat);
129413
+ preamble += "\n";
129414
+ }
129415
+ }
129416
+ }
129417
+ if (tableKey && (preamble || !tables))
129418
+ preamble = preamble ? `[${tableKey}]
129419
+ ${preamble}` : `[${tableKey}]`;
129420
+ return preamble && tables ? `${preamble}
129421
+ ${tables}` : preamble || tables;
129422
+ }
129423
+ function stringify(obj, { maxDepth = 1e3, numbersAsFloat = false } = {}) {
129424
+ if (extendedTypeOf(obj) !== "object") {
129425
+ throw new TypeError("stringify can only be called with an object");
129426
+ }
129427
+ let str = stringifyTable(0, obj, "", maxDepth, numbersAsFloat);
129428
+ if (str[str.length - 1] !== "\n")
129429
+ return str + "\n";
129430
+ return str;
129431
+ }
129432
+ var BARE_KEY;
129294
129433
  var init_stringify2 = __esm({
129295
129434
  "../../node_modules/smol-toml/dist/stringify.js"() {
129435
+ BARE_KEY = /^[a-z0-9-_]+$/i;
129296
129436
  }
129297
129437
  });
129298
129438
 
@@ -199291,7 +199431,7 @@ var init_sessionUtils = __esm({
199291
199431
  });
199292
199432
 
199293
199433
  // src/devbox/commands/connect.ts
199294
- var import_node_child_process4, import_node_crypto9, import_node_os10, import_node_path17, import_node_readline3, import_promises13, resolveInitialSessionId, shouldAttachToExistingSession, resolveSessionSpecifierFromExplicitTarget, isAttachReplacedCloseCode, DEFAULT_TTY_COLS, DEFAULT_TTY_ROWS, DEFAULT_MODAL_APP_NAME, TERMINAL_INPUT_MODE_RESET, resetTerminalInputModes, openBrowser2, warnSetupStatus, resolveTtyEnv, formatEnvExports, parseEnvSize, readStreamSize, resolveTtySize, resolveSessionEnv, parseReachabilityState, runCommand, checkReachability, watchReachabilityWithScutil, watchReachabilityWithNotifyutil, waitForNetworkOnline, parseConnectArgs, parseConnectTarget, isSessionNotFoundError, SESSION_NAME_TOKEN_KEY, encodeSessionNameToken, decodeSessionNameToken, extractSessionNameFromCommand, SESSION_LOG_FLUSH_BYTES, SESSION_LOG_EOF_MARKER, createRemoteSessionLogSink, CONNECT_SHELL_CANDIDATES, resolveConnectShell, confirmNewSession, promptRenameSession, HEARTBEAT_INTERVAL_MS, HEARTBEAT_TIMEOUT_MS, INPUT_PROBE_TIMEOUT_MS, WS_OPEN_STATE, streamExecSession, runConnect;
199434
+ var import_node_child_process4, import_node_crypto9, import_node_os10, import_node_path17, import_node_readline3, import_promises13, resolveInitialSessionId, shouldAttachToExistingSession, resolveSessionSpecifierFromExplicitTarget, isAttachReplacedCloseCode, shouldCancelConnectOnSigint, DEFAULT_TTY_COLS, DEFAULT_TTY_ROWS, DEFAULT_MODAL_APP_NAME, TERMINAL_INPUT_MODE_RESET, resetTerminalInputModes, openBrowser2, warnSetupStatus, resolveTtyEnv, formatEnvExports, parseEnvSize, readStreamSize, resolveTtySize, resolveSessionEnv, parseReachabilityState, runCommand, checkReachability, watchReachabilityWithScutil, watchReachabilityWithNotifyutil, waitForNetworkOnline, parseConnectArgs, parseConnectTarget, isSessionNotFoundError, SESSION_NAME_TOKEN_KEY, encodeSessionNameToken, decodeSessionNameToken, extractSessionNameFromCommand, SESSION_LOG_FLUSH_BYTES, SESSION_LOG_EOF_MARKER, createRemoteSessionLogSink, CONNECT_SHELL_CANDIDATES, resolveConnectShell, confirmNewSession, promptRenameSession, HEARTBEAT_INTERVAL_MS, HEARTBEAT_TIMEOUT_MS, INPUT_PROBE_TIMEOUT_MS, CONNECT_OPEN_TIMEOUT_MS, WS_OPEN_STATE, streamExecSession, runConnect;
199295
199435
  var init_connect2 = __esm({
199296
199436
  "src/devbox/commands/connect.ts"() {
199297
199437
  "use strict";
@@ -199349,6 +199489,7 @@ var init_connect2 = __esm({
199349
199489
  return { sessionName: void 0, sessionIdOverride: match2.id };
199350
199490
  };
199351
199491
  isAttachReplacedCloseCode = (closeCode) => closeCode === 1012;
199492
+ shouldCancelConnectOnSigint = (phase) => phase !== "attached";
199352
199493
  DEFAULT_TTY_COLS = 80;
199353
199494
  DEFAULT_TTY_ROWS = 24;
199354
199495
  DEFAULT_MODAL_APP_NAME = "sandbox-modal-smoke";
@@ -199834,6 +199975,7 @@ var init_connect2 = __esm({
199834
199975
  HEARTBEAT_INTERVAL_MS = 4e3;
199835
199976
  HEARTBEAT_TIMEOUT_MS = 8e3;
199836
199977
  INPUT_PROBE_TIMEOUT_MS = 1e3;
199978
+ CONNECT_OPEN_TIMEOUT_MS = 2e4;
199837
199979
  WS_OPEN_STATE = 1;
199838
199980
  streamExecSession = async (ws, options) => new Promise((resolve2, reject) => {
199839
199981
  let exitCode = null;
@@ -199846,6 +199988,7 @@ var init_connect2 = __esm({
199846
199988
  let lastSeenAt = Date.now();
199847
199989
  let heartbeatTimer = null;
199848
199990
  let inputProbeTimer = null;
199991
+ let openTimer = null;
199849
199992
  let inputProbeStamp = 0;
199850
199993
  let disconnectNoted = false;
199851
199994
  let errorMessage;
@@ -200073,6 +200216,12 @@ var init_connect2 = __esm({
200073
200216
  inputProbeTimer = null;
200074
200217
  }
200075
200218
  };
200219
+ const stopOpenTimer = () => {
200220
+ if (openTimer) {
200221
+ clearTimeout(openTimer);
200222
+ openTimer = null;
200223
+ }
200224
+ };
200076
200225
  const onPong = () => {
200077
200226
  markAlive();
200078
200227
  latency?.notePong();
@@ -200167,6 +200316,7 @@ var init_connect2 = __esm({
200167
200316
  ws.removeEventListener("error", onError);
200168
200317
  ws.removeEventListener("open", onOpen);
200169
200318
  stopInputProbe();
200319
+ stopOpenTimer();
200170
200320
  stopHeartbeat();
200171
200321
  stopInput();
200172
200322
  };
@@ -200210,6 +200360,7 @@ var init_connect2 = __esm({
200210
200360
  resolve2(result);
200211
200361
  };
200212
200362
  const onOpen = () => {
200363
+ stopOpenTimer();
200213
200364
  opened = true;
200214
200365
  markAlive();
200215
200366
  latency?.noteConnectOpen();
@@ -200224,6 +200375,20 @@ var init_connect2 = __esm({
200224
200375
  ws.addEventListener("error", onError);
200225
200376
  ws.addEventListener("open", onOpen);
200226
200377
  sendResize();
200378
+ const openTimeoutMs = options.openTimeoutMs ?? CONNECT_OPEN_TIMEOUT_MS;
200379
+ if (openTimeoutMs > 0) {
200380
+ openTimer = setTimeout(() => {
200381
+ if (resolved || opened) return;
200382
+ noteDisconnect();
200383
+ forceClose();
200384
+ onError({
200385
+ data: new Error(
200386
+ `Timed out waiting for session connection after ${openTimeoutMs}ms.`
200387
+ )
200388
+ });
200389
+ }, openTimeoutMs);
200390
+ openTimer.unref();
200391
+ }
200227
200392
  });
200228
200393
  runConnect = async (args, overrides) => {
200229
200394
  const parsed = parseConnectArgs(args);
@@ -200769,6 +200934,11 @@ var init_connect2 = __esm({
200769
200934
  let retryDelayMs = 250;
200770
200935
  let printedSessionInfo = false;
200771
200936
  let sawOutput = false;
200937
+ let connectPhase = "connecting";
200938
+ let activeSocket = null;
200939
+ let localCancelRequested = false;
200940
+ let attemptedAttach = false;
200941
+ let sigintListenerInstalled = false;
200772
200942
  const printSessionInfo = (message) => {
200773
200943
  if (process.stderr.isTTY && process.stdout.isTTY) {
200774
200944
  process.stderr.write(`\x1B7\r
@@ -200796,208 +200966,262 @@ ${message}\r
200796
200966
  status.stop();
200797
200967
  }
200798
200968
  };
200799
- while (true) {
200969
+ const onSigint = () => {
200970
+ localCancelRequested = true;
200971
+ if (!activeSocket) return;
200800
200972
  try {
200801
- await refreshSessionMapping();
200802
- } catch (error2) {
200803
- logger7.warn("session_refresh_failed", { error: String(error2) });
200804
- }
200805
- if (explicitName && sessionName && !sessionId && !confirmedCreateExplicit) {
200806
- pauseStatus();
200807
- const confirmed = await confirmNewSession(sessionName);
200808
- if (!confirmed) {
200809
- throw new Error(`Session "${sessionName}" not created.`);
200810
- }
200811
- confirmedCreateExplicit = true;
200812
- }
200813
- let createdNew = false;
200814
- let mappingWrite = null;
200815
- latency?.noteConnectStart();
200816
- const canAttach = shouldAttachToExistingSession({
200817
- supportsAttachExecSession,
200818
- sessionId,
200819
- requireFreshSessionOpen
200820
- });
200821
- stage(canAttach ? "Attaching to session" : "Opening session");
200822
- let ws;
200823
- if (canAttach) {
200824
- if (!sessionId) {
200825
- throw new Error("Missing session id for attach.");
200826
- }
200827
- ws = client2.attachExecSession(spriteAlias, sessionId);
200828
- } else {
200829
- createdNew = true;
200830
- ws = client2.openExecSession(spriteAlias, {
200831
- cmd: execCommand2,
200832
- tty: isTty,
200833
- stdin: openStdin,
200834
- ...ttySize ? { cols: ttySize.cols, rows: ttySize.rows } : {},
200835
- ...modalSessionLogPath ? { logPath: modalSessionLogPath } : {}
200836
- });
200973
+ activeSocket.terminate?.();
200974
+ } catch {
200837
200975
  }
200838
- const shouldSendInitialInput = createdNew && Boolean(pendingInitialInput);
200839
- const initialInputToSend = shouldSendInitialInput ? pendingInitialInput : void 0;
200840
- const result = await streamExecSession(ws, {
200841
- tty: isTty,
200842
- stdin: localStdin,
200843
- supportsResizeControlMessages,
200844
- ...latency ? { latency } : {},
200845
- onOutput: noteOutput,
200846
- onOutputChunk: (chunk) => {
200847
- sessionLogSink?.write(chunk);
200848
- },
200849
- onInputChunk: (chunk) => {
200850
- sessionLogSink?.write(chunk);
200851
- },
200852
- onOpen: () => {
200853
- if (shouldSendInitialInput) {
200854
- pendingInitialInput = void 0;
200855
- }
200856
- if (sessionId) {
200857
- reportSessionInfo(sessionId);
200976
+ try {
200977
+ activeSocket.close();
200978
+ } catch {
200979
+ }
200980
+ };
200981
+ const setConnectPhase = (phase) => {
200982
+ connectPhase = phase;
200983
+ const shouldInstallListener = shouldReconnect && shouldCancelConnectOnSigint(connectPhase);
200984
+ if (shouldInstallListener && !sigintListenerInstalled) {
200985
+ process.on("SIGINT", onSigint);
200986
+ sigintListenerInstalled = true;
200987
+ return;
200988
+ }
200989
+ if (!shouldInstallListener && sigintListenerInstalled) {
200990
+ process.removeListener("SIGINT", onSigint);
200991
+ sigintListenerInstalled = false;
200992
+ }
200993
+ };
200994
+ setConnectPhase("connecting");
200995
+ try {
200996
+ while (true) {
200997
+ if (localCancelRequested) {
200998
+ process.exitCode = 130;
200999
+ break;
201000
+ }
201001
+ setConnectPhase(attemptedAttach ? "reconnecting" : "connecting");
201002
+ attemptedAttach = true;
201003
+ try {
201004
+ await refreshSessionMapping();
201005
+ } catch (error2) {
201006
+ logger7.warn("session_refresh_failed", { error: String(error2) });
201007
+ }
201008
+ if (explicitName && sessionName && !sessionId && !confirmedCreateExplicit) {
201009
+ pauseStatus();
201010
+ const confirmed = await confirmNewSession(sessionName);
201011
+ if (!confirmed) {
201012
+ throw new Error(`Session "${sessionName}" not created.`);
200858
201013
  }
200859
- },
200860
- ...initialInputToSend ? { initialInput: initialInputToSend } : {},
200861
- onSessionInfo: (id) => {
200862
- if (supportsAttachExecSession) {
200863
- if (createdNew) {
200864
- requireFreshSessionOpen = false;
200865
- }
200866
- sessionId = sessionId ?? id;
201014
+ confirmedCreateExplicit = true;
201015
+ }
201016
+ let createdNew = false;
201017
+ let mappingWrite = null;
201018
+ latency?.noteConnectStart();
201019
+ const canAttach = shouldAttachToExistingSession({
201020
+ supportsAttachExecSession,
201021
+ sessionId,
201022
+ requireFreshSessionOpen
201023
+ });
201024
+ stage(canAttach ? "Attaching to session" : "Opening session");
201025
+ let ws;
201026
+ if (canAttach) {
201027
+ if (!sessionId) {
201028
+ throw new Error("Missing session id for attach.");
200867
201029
  }
200868
- if (sessionName && createdNew) {
200869
- if (autoNamed) {
200870
- mappingWrite = finalizeAutoSession(id);
200871
- if (mappingWrite) {
200872
- mappingWrite.then(() => {
200873
- reportSessionInfo(id);
200874
- }).catch((error2) => {
200875
- logger7.warn("session_auto_rename_failed", {
200876
- error: String(error2)
200877
- });
201030
+ ws = client2.attachExecSession(spriteAlias, sessionId);
201031
+ } else {
201032
+ createdNew = true;
201033
+ ws = client2.openExecSession(spriteAlias, {
201034
+ cmd: execCommand2,
201035
+ tty: isTty,
201036
+ stdin: openStdin,
201037
+ ...ttySize ? { cols: ttySize.cols, rows: ttySize.rows } : {},
201038
+ ...modalSessionLogPath ? { logPath: modalSessionLogPath } : {}
201039
+ });
201040
+ }
201041
+ activeSocket = ws;
201042
+ const shouldSendInitialInput = createdNew && Boolean(pendingInitialInput);
201043
+ const initialInputToSend = shouldSendInitialInput ? pendingInitialInput : void 0;
201044
+ let result;
201045
+ try {
201046
+ result = await streamExecSession(ws, {
201047
+ tty: isTty,
201048
+ stdin: localStdin,
201049
+ supportsResizeControlMessages,
201050
+ ...latency ? { latency } : {},
201051
+ openTimeoutMs: CONNECT_OPEN_TIMEOUT_MS,
201052
+ onOutput: noteOutput,
201053
+ onOutputChunk: (chunk) => {
201054
+ sessionLogSink?.write(chunk);
201055
+ },
201056
+ onInputChunk: (chunk) => {
201057
+ sessionLogSink?.write(chunk);
201058
+ },
201059
+ onOpen: () => {
201060
+ setConnectPhase("attached");
201061
+ if (shouldSendInitialInput) {
201062
+ pendingInitialInput = void 0;
201063
+ }
201064
+ if (sessionId) {
201065
+ reportSessionInfo(sessionId);
201066
+ }
201067
+ },
201068
+ ...initialInputToSend ? { initialInput: initialInputToSend } : {},
201069
+ onSessionInfo: (id) => {
201070
+ if (supportsAttachExecSession) {
201071
+ if (createdNew) {
201072
+ requireFreshSessionOpen = false;
201073
+ }
201074
+ sessionId = sessionId ?? id;
201075
+ }
201076
+ if (sessionName && createdNew) {
201077
+ if (autoNamed) {
201078
+ mappingWrite = finalizeAutoSession(id);
201079
+ if (mappingWrite) {
201080
+ mappingWrite.then(() => {
201081
+ reportSessionInfo(id);
201082
+ }).catch((error2) => {
201083
+ logger7.warn("session_auto_rename_failed", {
201084
+ error: String(error2)
201085
+ });
201086
+ reportSessionInfo(id);
201087
+ });
201088
+ } else {
201089
+ reportSessionInfo(id);
201090
+ }
201091
+ } else {
201092
+ sessions[sessionName] = id;
201093
+ mappingWrite = writeSpriteSessions(
201094
+ client2,
201095
+ spriteAlias,
201096
+ sessions
201097
+ );
200878
201098
  reportSessionInfo(id);
200879
- });
201099
+ }
200880
201100
  } else {
200881
201101
  reportSessionInfo(id);
200882
201102
  }
200883
- } else {
200884
- sessions[sessionName] = id;
200885
- mappingWrite = writeSpriteSessions(
200886
- client2,
200887
- spriteAlias,
200888
- sessions
200889
- );
200890
- reportSessionInfo(id);
200891
- }
200892
- } else {
200893
- reportSessionInfo(id);
200894
- }
200895
- if (isDetached) {
200896
- ws.close();
201103
+ if (isDetached) {
201104
+ ws.close();
201105
+ }
201106
+ },
201107
+ onPortEvent: notifyPortEvent,
201108
+ ...shouldReconnect ? {
201109
+ onDisconnectNotice: () => {
201110
+ setConnectPhase("reconnecting");
201111
+ resetTerminalInputModes();
201112
+ if (!reconnectNoticeShown) {
201113
+ console.error(
201114
+ "Connection lost. Reconnecting... (Ctrl+C to cancel)"
201115
+ );
201116
+ reconnectNoticeShown = true;
201117
+ }
201118
+ }
201119
+ } : {}
201120
+ });
201121
+ } finally {
201122
+ activeSocket = null;
201123
+ }
201124
+ if (mappingWrite) {
201125
+ try {
201126
+ await mappingWrite;
201127
+ } catch (error2) {
201128
+ logger7.warn("session_write_failed", { error: String(error2) });
200897
201129
  }
200898
- },
200899
- onPortEvent: notifyPortEvent,
200900
- ...shouldReconnect ? {
200901
- onDisconnectNotice: () => {
200902
- resetTerminalInputModes();
200903
- if (!reconnectNoticeShown) {
200904
- console.error(
200905
- "Connection lost. Reconnecting... (Ctrl+C to cancel)"
200906
- );
200907
- reconnectNoticeShown = true;
201130
+ }
201131
+ if (localCancelRequested) {
201132
+ process.exitCode = 130;
201133
+ break;
201134
+ }
201135
+ if (result.kind === "exit") {
201136
+ process.exitCode = result.code;
201137
+ break;
201138
+ }
201139
+ if (result.kind === "detach") {
201140
+ if (autoNamed && sessionName && sessionId) {
201141
+ const nextName = await promptRenameSession(sessionName);
201142
+ if (nextName && nextName !== sessionName) {
201143
+ try {
201144
+ await renameSessionMapping(sessionName, nextName, sessionId);
201145
+ } catch (error2) {
201146
+ console.error(
201147
+ `Failed to rename session: ${error2 instanceof Error ? error2.message : String(error2)}`
201148
+ );
201149
+ }
200908
201150
  }
200909
201151
  }
200910
- } : {}
200911
- });
200912
- if (mappingWrite) {
200913
- try {
200914
- await mappingWrite;
200915
- } catch (error2) {
200916
- logger7.warn("session_write_failed", { error: String(error2) });
201152
+ process.exitCode = 0;
201153
+ break;
200917
201154
  }
200918
- }
200919
- if (result.kind === "exit") {
200920
- process.exitCode = result.code;
200921
- break;
200922
- }
200923
- if (result.kind === "detach") {
200924
- if (autoNamed && sessionName && sessionId) {
200925
- const nextName = await promptRenameSession(sessionName);
200926
- if (nextName && nextName !== sessionName) {
200927
- try {
200928
- await renameSessionMapping(sessionName, nextName, sessionId);
200929
- } catch (error2) {
200930
- console.error(
200931
- `Failed to rename session: ${error2 instanceof Error ? error2.message : String(error2)}`
200932
- );
200933
- }
201155
+ if (isDetached) {
201156
+ process.exitCode = 0;
201157
+ break;
201158
+ }
201159
+ if (isAttachReplacedCloseCode(result.closeCode)) {
201160
+ resetTerminalInputModes();
201161
+ console.error(
201162
+ "Session attached from another client. Closing this window."
201163
+ );
201164
+ process.exitCode = 0;
201165
+ break;
201166
+ }
201167
+ if (!shouldReconnect) {
201168
+ if (result.errorMessage) {
201169
+ throw new Error(`Connection lost: ${result.errorMessage}`);
200934
201170
  }
201171
+ throw new Error("Connection lost.");
200935
201172
  }
200936
- process.exitCode = 0;
200937
- break;
200938
- }
200939
- if (isDetached) {
200940
- process.exitCode = 0;
200941
- break;
200942
- }
200943
- if (isAttachReplacedCloseCode(result.closeCode)) {
201173
+ setConnectPhase("reconnecting");
200944
201174
  resetTerminalInputModes();
200945
- console.error(
200946
- "Session attached from another client. Closing this window."
200947
- );
200948
- process.exitCode = 0;
200949
- break;
200950
- }
200951
- if (!shouldReconnect) {
200952
- if (result.errorMessage) {
200953
- throw new Error(`Connection lost: ${result.errorMessage}`);
201175
+ if (!reconnectNoticeShown) {
201176
+ console.error(
201177
+ "Connection lost. Reconnecting... (Ctrl+C to cancel)"
201178
+ );
201179
+ reconnectNoticeShown = true;
200954
201180
  }
200955
- throw new Error("Connection lost.");
200956
- }
200957
- resetTerminalInputModes();
200958
- if (!reconnectNoticeShown) {
200959
- console.error("Connection lost. Reconnecting... (Ctrl+C to cancel)");
200960
- reconnectNoticeShown = true;
200961
- }
200962
- if (sessionId && supportsAttachExecSession) {
200963
- if (computeProvider === "modal" && isSessionNotFoundError(result.errorMessage)) {
200964
- if (sessionName) {
200965
- delete sessions[sessionName];
200966
- await writeSpriteSessions(client2, spriteAlias, sessions);
200967
- }
200968
- sessionId = void 0;
200969
- } else if (computeProvider !== "modal" && result.opened === false && supportsListExecSessions) {
200970
- try {
200971
- const available = await client2.listExecSessions(spriteAlias);
200972
- const match2 = available.find(
200973
- (session) => session.id === sessionId
200974
- );
200975
- if (!match2 || match2.tty === false) {
200976
- if (sessionName) {
200977
- delete sessions[sessionName];
200978
- await writeSpriteSessions(client2, spriteAlias, sessions);
201181
+ if (sessionId && supportsAttachExecSession) {
201182
+ if (computeProvider === "modal" && isSessionNotFoundError(result.errorMessage)) {
201183
+ if (sessionName) {
201184
+ delete sessions[sessionName];
201185
+ await writeSpriteSessions(client2, spriteAlias, sessions);
201186
+ }
201187
+ sessionId = void 0;
201188
+ } else if (computeProvider !== "modal" && result.opened === false && supportsListExecSessions) {
201189
+ try {
201190
+ const available = await client2.listExecSessions(spriteAlias);
201191
+ const match2 = available.find(
201192
+ (session) => session.id === sessionId
201193
+ );
201194
+ if (!match2 || match2.tty === false) {
201195
+ if (sessionName) {
201196
+ delete sessions[sessionName];
201197
+ await writeSpriteSessions(client2, spriteAlias, sessions);
201198
+ }
201199
+ sessionId = void 0;
200979
201200
  }
200980
- sessionId = void 0;
201201
+ } catch (error2) {
201202
+ logger7.warn("session_lookup_failed", { error: String(error2) });
200981
201203
  }
200982
- } catch (error2) {
200983
- logger7.warn("session_lookup_failed", { error: String(error2) });
200984
201204
  }
200985
201205
  }
201206
+ const networkWait = await waitForNetworkOnline({
201207
+ targetHost: networkTargetHost,
201208
+ onStatus: stage,
201209
+ onNotice: (message) => console.error(message)
201210
+ });
201211
+ if (networkWait === "aborted" || localCancelRequested) {
201212
+ process.exitCode = 130;
201213
+ break;
201214
+ }
201215
+ if (networkWait === "waited") {
201216
+ retryDelayMs = 250;
201217
+ }
201218
+ await new Promise((resolve2) => setTimeout(resolve2, retryDelayMs));
201219
+ retryDelayMs = Math.min(5e3, Math.round(retryDelayMs * 1.6));
200986
201220
  }
200987
- const networkWait = await waitForNetworkOnline({
200988
- targetHost: networkTargetHost,
200989
- onStatus: stage,
200990
- onNotice: (message) => console.error(message)
200991
- });
200992
- if (networkWait === "aborted") {
200993
- process.exitCode = 130;
200994
- break;
200995
- }
200996
- if (networkWait === "waited") {
200997
- retryDelayMs = 250;
201221
+ } finally {
201222
+ if (sigintListenerInstalled) {
201223
+ process.removeListener("SIGINT", onSigint);
200998
201224
  }
200999
- await new Promise((resolve2) => setTimeout(resolve2, retryDelayMs));
201000
- retryDelayMs = Math.min(5e3, Math.round(retryDelayMs * 1.6));
201001
201225
  }
201002
201226
  } finally {
201003
201227
  const exitCode = typeof process.exitCode === "number" ? process.exitCode : void 0;
@@ -201876,6 +202100,7 @@ var init_state = __esm({
201876
202100
  "workdirProvisioned",
201877
202101
  "gitSafeDirectoryConfigured",
201878
202102
  "setupUploaded",
202103
+ "codexConfigUpdated",
201879
202104
  "setupArtifactsStaged",
201880
202105
  "servicesEnabled",
201881
202106
  "codexCliEnsured",
@@ -202538,14 +202763,64 @@ var init_weztermMux = __esm({
202538
202763
  }
202539
202764
  });
202540
202765
 
202766
+ // src/devbox/commands/init/codex/config.ts
202767
+ var isRecord, parseExistingConfig, normalizeTrustedPaths, ensureNoticeConfig, ensureTrustedProjects, mergeCodexInitConfig;
202768
+ var init_config2 = __esm({
202769
+ "src/devbox/commands/init/codex/config.ts"() {
202770
+ "use strict";
202771
+ init_dist2();
202772
+ isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
202773
+ parseExistingConfig = (content) => {
202774
+ if (!content) return {};
202775
+ try {
202776
+ const parsed = parse(content);
202777
+ return isRecord(parsed) ? { ...parsed } : {};
202778
+ } catch {
202779
+ return {};
202780
+ }
202781
+ };
202782
+ normalizeTrustedPaths = (trustedPaths) => [
202783
+ ...new Set(trustedPaths.map((path38) => path38.trim()).filter(Boolean))
202784
+ ];
202785
+ ensureNoticeConfig = (config4) => {
202786
+ const notice = isRecord(config4.notice) ? { ...config4.notice } : {};
202787
+ notice.hide_full_access_warning = true;
202788
+ config4.notice = notice;
202789
+ };
202790
+ ensureTrustedProjects = (config4, trustedPaths) => {
202791
+ const projects = isRecord(config4.projects) ? { ...config4.projects } : {};
202792
+ for (const trustedPath of normalizeTrustedPaths(trustedPaths)) {
202793
+ const existingProject = isRecord(projects[trustedPath]) ? { ...projects[trustedPath] } : {};
202794
+ existingProject.trust_level = "trusted";
202795
+ projects[trustedPath] = existingProject;
202796
+ }
202797
+ config4.projects = projects;
202798
+ };
202799
+ mergeCodexInitConfig = ({
202800
+ existingContent,
202801
+ trustedPaths
202802
+ }) => {
202803
+ const config4 = parseExistingConfig(existingContent);
202804
+ config4.approval_policy = "never";
202805
+ config4.sandbox_mode = "danger-full-access";
202806
+ ensureNoticeConfig(config4);
202807
+ ensureTrustedProjects(config4, trustedPaths);
202808
+ const rendered = stringify(config4);
202809
+ return rendered.endsWith("\n") ? rendered : `${rendered}
202810
+ `;
202811
+ };
202812
+ }
202813
+ });
202814
+
202541
202815
  // src/devbox/commands/init/remote.ts
202542
- var import_node_crypto11, DAEMON_DIR, DAEMON_TARBALL, DAEMON_BUNDLE_DIR, DAEMON_ENTRY, DAEMON_WRAPPER, DAEMON_SERVICE_NAME, DAEMON_CONFIG_FILE, MODAL_DAEMON_HEALTH_PORT, DEFAULT_DAEMON_BASE_URL, DEFAULT_HEARTBEAT_MS, BOOTSTRAP_EXEC_TIMEOUT_MS, BOOTSTRAP_EXEC_HANDSHAKE_TIMEOUT_MS, BASHRC_PATH, ZSHRC_PATH, BASIC_ALIASES_MARKER, LEGACY_BASH_TRAP, SAFE_BASH_TRAP, BASH_HISTORY_BLOCK, ZSH_HISTORY_BLOCK, HISTORY_BLOCK_PATTERN, BASH_HISTORY_LINE_PATTERN, ZSH_HISTORY_LINE_PATTERN, logger8, truncateTail, shellQuote4, expandHome2, execWithLog, writeRemoteFile, readRemoteFile, ensureTrailingNewline, upsertHistoryBlock, patchBashrcContent, patchZshrcContent, bootstrapDevbox, buildWeztermMuxConfig, buildWeztermMuxRunner, patchRemoteRcFile, patchBashrc, patchZshrc, stageRemoteSetupArtifacts, resolveDaemonUrl, fetchDaemonBinary, buildDaemonConfig, buildDaemonWrapperScript, isSameArgs, ensureSpriteDaemonService, installWeztermMux, ensureWeztermMuxService, hasWeztermMuxBinary, isWeztermMuxHealthy, installSpriteDaemon;
202816
+ var import_node_crypto11, DAEMON_DIR, DAEMON_TARBALL, DAEMON_BUNDLE_DIR, DAEMON_ENTRY, DAEMON_WRAPPER, DAEMON_SERVICE_NAME, DAEMON_CONFIG_FILE, MODAL_DAEMON_HEALTH_PORT, DEFAULT_DAEMON_BASE_URL, DEFAULT_HEARTBEAT_MS, BOOTSTRAP_EXEC_TIMEOUT_MS, BOOTSTRAP_EXEC_HANDSHAKE_TIMEOUT_MS, BASHRC_PATH, ZSHRC_PATH, CODEX_CONFIG_DIR, CODEX_CONFIG_PATH, BASIC_ALIASES_MARKER, LEGACY_BASH_TRAP, SAFE_BASH_TRAP, BASH_HISTORY_BLOCK, ZSH_HISTORY_BLOCK, HISTORY_BLOCK_PATTERN, BASH_HISTORY_LINE_PATTERN, ZSH_HISTORY_LINE_PATTERN, logger8, truncateTail, shellQuote4, expandHome2, execWithLog, writeRemoteFile, readRemoteFile, ensureTrailingNewline, upsertHistoryBlock, patchBashrcContent, patchZshrcContent, bootstrapDevbox, buildWeztermMuxConfig, buildWeztermMuxRunner, patchRemoteRcFile, patchBashrc, patchZshrc, ensureRemoteCodexConfig, stageRemoteSetupArtifacts, resolveDaemonUrl, fetchDaemonBinary, buildDaemonConfig, buildDaemonWrapperScript, isSameArgs, ensureSpriteDaemonService, installWeztermMux, ensureWeztermMuxService, hasWeztermMuxBinary, isWeztermMuxHealthy, installSpriteDaemon;
202543
202817
  var init_remote = __esm({
202544
202818
  "src/devbox/commands/init/remote.ts"() {
202545
202819
  "use strict";
202546
202820
  import_node_crypto11 = require("node:crypto");
202547
202821
  init_src();
202548
202822
  init_weztermMux();
202823
+ init_config2();
202549
202824
  DAEMON_DIR = "/home/sprite/.devbox/daemon";
202550
202825
  DAEMON_TARBALL = `${DAEMON_DIR}/sprite-daemon.tar.gz`;
202551
202826
  DAEMON_BUNDLE_DIR = `${DAEMON_DIR}/bundle`;
@@ -202560,6 +202835,8 @@ var init_remote = __esm({
202560
202835
  BOOTSTRAP_EXEC_HANDSHAKE_TIMEOUT_MS = 2e4;
202561
202836
  BASHRC_PATH = "/home/sprite/.bashrc";
202562
202837
  ZSHRC_PATH = "/home/sprite/.zshrc";
202838
+ CODEX_CONFIG_DIR = "/home/sprite/.codex";
202839
+ CODEX_CONFIG_PATH = `${CODEX_CONFIG_DIR}/config.toml`;
202563
202840
  BASIC_ALIASES_MARKER = "\n# Basic aliases";
202564
202841
  LEGACY_BASH_TRAP = `trap 'echo -ne "\\033]0;\${BASH_COMMAND}\\007"' DEBUG`;
202565
202842
  SAFE_BASH_TRAP = `trap 'printf "\\033]0;%s\\007" "\${BASH_COMMAND//[^[:print:]]/}"' DEBUG`;
@@ -202975,6 +203252,59 @@ ${canonicalBlock}
202975
203252
  errorLabel: "zshrc",
202976
203253
  transform: patchZshrcContent
202977
203254
  });
203255
+ ensureRemoteCodexConfig = async ({
203256
+ client: client2,
203257
+ spriteAlias,
203258
+ trustedPaths
203259
+ }) => {
203260
+ const mkdirResult = await execWithLog(
203261
+ client2,
203262
+ spriteAlias,
203263
+ [
203264
+ "set -euo pipefail",
203265
+ `mkdir -p ${shellQuote4(CODEX_CONFIG_DIR)}`,
203266
+ `chmod 700 ${shellQuote4(CODEX_CONFIG_DIR)}`
203267
+ ].join("\n"),
203268
+ "codex-config-mkdir"
203269
+ );
203270
+ if (mkdirResult.exitCode !== 0) {
203271
+ const details = mkdirResult.stderr || mkdirResult.stdout || "";
203272
+ throw new Error(
203273
+ details ? `codex config mkdir failed: ${details}` : `codex config mkdir failed (exit ${mkdirResult.exitCode})`
203274
+ );
203275
+ }
203276
+ const existing = await readRemoteFile(
203277
+ client2,
203278
+ spriteAlias,
203279
+ CODEX_CONFIG_PATH,
203280
+ "codex-config-read"
203281
+ );
203282
+ const next = mergeCodexInitConfig({
203283
+ existingContent: existing,
203284
+ trustedPaths
203285
+ });
203286
+ await writeRemoteFile(
203287
+ client2,
203288
+ spriteAlias,
203289
+ CODEX_CONFIG_PATH,
203290
+ next,
203291
+ "codex-config-write"
203292
+ );
203293
+ const chmodResult = await execWithLog(
203294
+ client2,
203295
+ spriteAlias,
203296
+ ["set -euo pipefail", `chmod 600 ${shellQuote4(CODEX_CONFIG_PATH)}`].join(
203297
+ "\n"
203298
+ ),
203299
+ "codex-config-chmod"
203300
+ );
203301
+ if (chmodResult.exitCode !== 0) {
203302
+ const details = chmodResult.stderr || chmodResult.stdout || "";
203303
+ throw new Error(
203304
+ details ? `codex config chmod failed: ${details}` : `codex config chmod failed (exit ${chmodResult.exitCode})`
203305
+ );
203306
+ }
203307
+ };
202978
203308
  stageRemoteSetupArtifacts = async ({
202979
203309
  client: client2,
202980
203310
  spriteAlias,
@@ -208710,7 +209040,7 @@ ${sshResult.stderr}`.trim();
208710
209040
  });
208711
209041
 
208712
209042
  // src/devbox/commands/servicesToml.ts
208713
- var splitShellCommand, normalizeSectionName, isRecord, asString2, asStringArray, asNumber, parseServicesToml, formatSectionName, renderServiceBlock, mergeServicesToml;
209043
+ var splitShellCommand, normalizeSectionName, isRecord2, asString2, asStringArray, asNumber, parseServicesToml, formatSectionName, renderServiceBlock, mergeServicesToml;
208714
209044
  var init_servicesToml = __esm({
208715
209045
  "src/devbox/commands/servicesToml.ts"() {
208716
209046
  "use strict";
@@ -208766,7 +209096,7 @@ var init_servicesToml = __esm({
208766
209096
  }
208767
209097
  return trimmed;
208768
209098
  };
208769
- isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
209099
+ isRecord2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
208770
209100
  asString2 = (value) => typeof value === "string" ? value : null;
208771
209101
  asStringArray = (value) => {
208772
209102
  if (!Array.isArray(value)) return null;
@@ -208790,14 +209120,14 @@ var init_servicesToml = __esm({
208790
209120
  };
208791
209121
  parseServicesToml = (content) => {
208792
209122
  const parsed = parse(content);
208793
- if (!isRecord(parsed)) return {};
209123
+ if (!isRecord2(parsed)) return {};
208794
209124
  const servicesRoot = parsed.services;
208795
- if (!isRecord(servicesRoot)) return {};
209125
+ if (!isRecord2(servicesRoot)) return {};
208796
209126
  const services = {};
208797
209127
  for (const [rawName, value] of Object.entries(servicesRoot)) {
208798
209128
  const name = String(rawName);
208799
209129
  if (!name) continue;
208800
- if (!isRecord(value)) continue;
209130
+ if (!isRecord2(value)) continue;
208801
209131
  const entry = { name };
208802
209132
  const cmd = asString2(value.cmd);
208803
209133
  if (cmd) entry.cmd = cmd;
@@ -209475,6 +209805,27 @@ var init_finalizeFlow = __esm({
209475
209805
  });
209476
209806
  }
209477
209807
  });
209808
+ const skipCodexConfigUpdate = Boolean(
209809
+ shouldResume && getInitState()?.steps.codexConfigUpdated
209810
+ );
209811
+ if (!skipCodexConfigUpdate) {
209812
+ await runInitStep({
209813
+ enabled: progressEnabled,
209814
+ title: "Updating Codex config",
209815
+ fn: async ({ status }) => {
209816
+ await retryInitStep2({
209817
+ status,
209818
+ title: "Updating Codex config",
209819
+ fn: async () => await ensureRemoteCodexConfig({
209820
+ client: client2,
209821
+ spriteAlias,
209822
+ trustedPaths: ["/home/sprite", expandedWorkdir]
209823
+ })
209824
+ });
209825
+ }
209826
+ });
209827
+ await updateInitState({ steps: { codexConfigUpdated: true } });
209828
+ }
209478
209829
  const skipSetupArtifactsStage = Boolean(
209479
209830
  skipCodexApply || shouldResume && getInitState()?.steps.setupArtifactsStaged
209480
209831
  );
@@ -217083,4 +217434,4 @@ smol-toml/dist/index.js:
217083
217434
  */
217084
217435
  //# sourceMappingURL=dvb.cjs.map
217085
217436
 
217086
- //# debugId=785204a7-1bc2-5318-801f-4ad682a364a7
217437
+ //# debugId=b4643c26-df5e-5ece-b58a-108a9965ffde