vibelet 1.2.211 → 1.2.216

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.
@@ -1,2 +1,2 @@
1
- var c=require("node:fs"),n=require("node:path"),p="@vibelet/cli";function i(r){try{let e=JSON.parse((0,c.readFileSync)(r,"utf8"));if(e.name===p&&typeof e.version=="string"&&e.version.length>0)return e.version}catch{}return null}function l(){return"1.2.211"}var a=l();process.stdout.write(`${a}
1
+ var c=require("node:fs"),n=require("node:path"),p="@vibelet/cli";function i(r){try{let e=JSON.parse((0,c.readFileSync)(r,"utf8"));if(e.name===p&&typeof e.version=="string"&&e.version.length>0)return e.version}catch{}return null}function l(){return"1.2.216"}var a=l();process.stdout.write(`${a}
2
2
  `);
package/dist/vibelet.mjs CHANGED
@@ -12442,7 +12442,7 @@ function canUseSystemdUserManager({ spawnSyncImpl = node_child_process__WEBPACK_
12442
12442
 
12443
12443
  /***/ }),
12444
12444
 
12445
- /***/ 877:
12445
+ /***/ 5028:
12446
12446
  /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __nccwpck_require__) => {
12447
12447
 
12448
12448
 
@@ -12773,6 +12773,191 @@ var websocket_server = __nccwpck_require__(3261);
12773
12773
 
12774
12774
  /* harmony default export */ const wrapper = (websocket);
12775
12775
 
12776
+ ;// CONCATENATED MODULE: ./bin/terminal-screen.mjs
12777
+ const ANSI_CLEAR_SCREEN = '\x1b[2J\x1b[H';
12778
+ const ANSI_HIDE_CURSOR = '\x1b[?25l';
12779
+ const terminal_screen_ANSI_RESET = '\x1b[0m';
12780
+ const ANSI_BOLD = '\x1b[1m';
12781
+ const ANSI_CYAN = '\x1b[36m';
12782
+ const ANSI_GREEN = '\x1b[32m';
12783
+ const ANSI_YELLOW = '\x1b[33m';
12784
+ const ANSI_RED = '\x1b[31m';
12785
+ const ANSI_BG_BLUE = '\x1b[44m';
12786
+ const ANSI_WHITE = '\x1b[97m';
12787
+
12788
+ function truncateMiddle(value, maxLength) {
12789
+ const text = String(value ?? '');
12790
+ if (text.length <= maxLength) return text;
12791
+ if (maxLength <= 5) return text.slice(0, maxLength);
12792
+ const headLength = Math.ceil((maxLength - 3) / 2);
12793
+ const tailLength = Math.floor((maxLength - 3) / 2);
12794
+ return `${text.slice(0, headLength)}...${text.slice(text.length - tailLength)}`;
12795
+ }
12796
+
12797
+ function truncateEnd(value, maxLength) {
12798
+ const text = String(value ?? '');
12799
+ if (text.length <= maxLength) return text;
12800
+ if (maxLength <= 5) return text.slice(0, maxLength);
12801
+ return `${text.slice(0, maxLength - 3)}...`;
12802
+ }
12803
+
12804
+ function wrapText(text, width) {
12805
+ const words = String(text).split(/\s+/).filter(Boolean);
12806
+ if (words.length === 0) return [''];
12807
+ const lines = [];
12808
+ let current = '';
12809
+ for (const word of words) {
12810
+ if (word.length > width) {
12811
+ if (current) {
12812
+ lines.push(current);
12813
+ current = '';
12814
+ }
12815
+ for (let index = 0; index < word.length; index += width) {
12816
+ lines.push(word.slice(index, index + width));
12817
+ }
12818
+ continue;
12819
+ }
12820
+ const next = current ? `${current} ${word}` : word;
12821
+ if (next.length > width) {
12822
+ lines.push(current);
12823
+ current = word;
12824
+ } else {
12825
+ current = next;
12826
+ }
12827
+ }
12828
+ if (current) lines.push(current);
12829
+ return lines;
12830
+ }
12831
+
12832
+ function padRight(text, width) {
12833
+ const value = String(text);
12834
+ if (value.length >= width) return value.slice(0, width);
12835
+ return `${value}${' '.repeat(width - value.length)}`;
12836
+ }
12837
+
12838
+ function colorize(enabled, style, text) {
12839
+ if (!enabled || !style) return text;
12840
+ return `${style}${text}${terminal_screen_ANSI_RESET}`;
12841
+ }
12842
+
12843
+ function getTerminalControlScreenTone(title) {
12844
+ if (/\bFAILED\b|\bBLOCKED\b/i.test(title)) return 'danger';
12845
+ if (/\bRESTORING\b|\bSTARTING\b/i.test(title)) return 'restore';
12846
+ return 'takeover';
12847
+ }
12848
+
12849
+ function getTerminalControlScreenPalette(tone) {
12850
+ if (tone === 'danger') {
12851
+ return {
12852
+ title: `${ANSI_BOLD}${ANSI_RED}`,
12853
+ subtitle: ANSI_RED,
12854
+ separator: ANSI_RED,
12855
+ label: ANSI_YELLOW,
12856
+ body: '',
12857
+ footer: `${ANSI_BOLD}${ANSI_YELLOW}`,
12858
+ };
12859
+ }
12860
+ if (tone === 'restore') {
12861
+ return {
12862
+ title: `${ANSI_BOLD}${ANSI_CYAN}`,
12863
+ subtitle: ANSI_CYAN,
12864
+ separator: ANSI_CYAN,
12865
+ label: ANSI_CYAN,
12866
+ body: '',
12867
+ footer: `${ANSI_BOLD}${ANSI_GREEN}`,
12868
+ };
12869
+ }
12870
+ return {
12871
+ title: `${ANSI_BOLD}${ANSI_BG_BLUE}${ANSI_WHITE}`,
12872
+ subtitle: ANSI_GREEN,
12873
+ separator: ANSI_GREEN,
12874
+ label: ANSI_CYAN,
12875
+ body: '',
12876
+ footer: `${ANSI_BOLD}${ANSI_YELLOW}`,
12877
+ };
12878
+ }
12879
+
12880
+ function formatTerminalFieldParts(label, value, width, { truncate = 'middle' } = {}) {
12881
+ const prefix = `${label}: `;
12882
+ const maxValueLength = Math.max(8, width - prefix.length);
12883
+ return {
12884
+ label: prefix,
12885
+ value: truncate === 'end' ? truncateEnd(value, maxValueLength) : truncateMiddle(value, maxValueLength),
12886
+ };
12887
+ }
12888
+
12889
+ function formatTerminalControlScreen({
12890
+ title,
12891
+ subtitle,
12892
+ agent,
12893
+ cwd,
12894
+ sessionId,
12895
+ task,
12896
+ bodyLines = [],
12897
+ footerLines = [],
12898
+ columns = 80,
12899
+ rows = 24,
12900
+ color = false,
12901
+ }) {
12902
+ const screenWidth = Math.max(20, Number(columns) || 80);
12903
+ const width = screenWidth < 60 ? screenWidth : Math.min(100, screenWidth);
12904
+ const height = Math.max(20, Number(rows) || 24);
12905
+ const innerWidth = width - 8;
12906
+ const separator = '='.repeat(width);
12907
+ const tone = getTerminalControlScreenTone(title);
12908
+ const palette = getTerminalControlScreenPalette(tone);
12909
+ const fieldLines = [
12910
+ { label: 'Agent', value: agent || 'unknown' },
12911
+ { label: 'Session', value: sessionId || 'pending' },
12912
+ ...(task ? [{ label: 'Task', value: task, truncate: 'end' }] : []),
12913
+ { label: 'Directory', value: cwd || process.cwd() },
12914
+ ].map(({ label, value, truncate }) => {
12915
+ const parts = formatTerminalFieldParts(label, value, innerWidth, { truncate });
12916
+ return `${colorize(color, palette.label, parts.label)}${parts.value}`;
12917
+ });
12918
+ const block = [
12919
+ colorize(color, palette.separator, separator),
12920
+ colorize(color, palette.title, padRight(title, width)),
12921
+ subtitle ? colorize(color, palette.subtitle, padRight(subtitle, width)) : '',
12922
+ colorize(color, palette.separator, separator),
12923
+ '',
12924
+ ...fieldLines,
12925
+ '',
12926
+ ];
12927
+
12928
+ for (const line of bodyLines) {
12929
+ for (const wrapped of wrapText(line, innerWidth)) {
12930
+ block.push(colorize(color, palette.body, padRight(wrapped, width)));
12931
+ }
12932
+ }
12933
+
12934
+ block.push('');
12935
+ for (const line of footerLines) {
12936
+ for (const wrapped of wrapText(line, innerWidth)) {
12937
+ block.push(colorize(color, palette.footer, padRight(wrapped, width)));
12938
+ }
12939
+ }
12940
+ block.push(colorize(color, palette.separator, separator));
12941
+
12942
+ const verticalPadding = Math.max(0, Math.floor((height - block.length) / 3));
12943
+ return `${'\n'.repeat(verticalPadding)}${block.join('\n')}\n`;
12944
+ }
12945
+
12946
+ function normalizeTerminalScreenForTty(screen) {
12947
+ return `\r${String(screen).replace(/\r?\n/g, '\r\n')}`;
12948
+ }
12949
+
12950
+ function renderTerminalControlScreen(stream, options) {
12951
+ const columns = Number(stream?.columns) || 80;
12952
+ const rows = Number(stream?.rows) || 24;
12953
+ const screen = formatTerminalControlScreen({ ...options, columns, rows, color: Boolean(stream?.isTTY) });
12954
+ if (stream?.isTTY) {
12955
+ stream.write(`${ANSI_CLEAR_SCREEN}${ANSI_HIDE_CURSOR}${normalizeTerminalScreenForTty(screen)}`);
12956
+ return;
12957
+ }
12958
+ stream.write(`\n${screen}`);
12959
+ }
12960
+
12776
12961
  ;// CONCATENATED MODULE: ./bin/terminal-wrapper.mjs
12777
12962
 
12778
12963
 
@@ -12788,6 +12973,8 @@ var websocket_server = __nccwpck_require__(3261);
12788
12973
 
12789
12974
 
12790
12975
 
12976
+
12977
+
12791
12978
  const terminalControlTokenPath = (0,external_node_path_.join)((0,external_node_os_.homedir)(), '.vibelet', 'runtime', 'terminal-control-token');
12792
12979
 
12793
12980
  const terminal_wrapper_TAKEOVER_STOP_TIMEOUT_MS = 3000;
@@ -12796,21 +12983,25 @@ const SWITCHBACK_RESTORE_NOTICE_MS = 1200;
12796
12983
  const SWITCHBACK_BUSY_RETRY_DELAY_MS = 750;
12797
12984
  const TERMINAL_CONTROL_RECONNECT_DELAY_MS = 1000;
12798
12985
  const CLAUDE_HOOK_SECRET_HEADER = 'x-vibelet-claude-hook-secret';
12799
- const ANSI_CLEAR_SCREEN = '\x1b[2J\x1b[H';
12800
- const ANSI_HIDE_CURSOR = '\x1b[?25l';
12801
- const terminal_wrapper_ANSI_RESET = '\x1b[0m';
12802
- const ANSI_BOLD = '\x1b[1m';
12803
- const ANSI_CYAN = '\x1b[36m';
12804
- const ANSI_GREEN = '\x1b[32m';
12805
- const ANSI_YELLOW = '\x1b[33m';
12806
- const ANSI_RED = '\x1b[31m';
12807
- const ANSI_BG_BLUE = '\x1b[44m';
12808
- const ANSI_WHITE = '\x1b[97m';
12809
-
12810
12986
  function isTerminalAgentCommand(command) {
12811
12987
  return command === 'claude' || command === 'codex';
12812
12988
  }
12813
12989
 
12990
+ async function waitForTakeoverResponseSent(control, timeoutMs = 5000) {
12991
+ if (!control) return false;
12992
+ let timer;
12993
+ try {
12994
+ return await Promise.race([
12995
+ control.takeoverResponseSent,
12996
+ new Promise((resolve) => {
12997
+ timer = setTimeout(() => resolve(false), timeoutMs);
12998
+ }),
12999
+ ]);
13000
+ } finally {
13001
+ clearTimeout(timer);
13002
+ }
13003
+ }
13004
+
12814
13005
  function resolveNativeAgentCommand(agent, env = process.env) {
12815
13006
  if (agent === 'claude') return env.CLAUDE_PATH || 'claude';
12816
13007
  if (agent === 'codex') return env.CODEX_PATH || 'codex';
@@ -13163,179 +13354,6 @@ function createTerminalModeState(initialMode = 'localNative') {
13163
13354
  };
13164
13355
  }
13165
13356
 
13166
- function truncateMiddle(value, maxLength) {
13167
- const text = String(value ?? '');
13168
- if (text.length <= maxLength) return text;
13169
- if (maxLength <= 5) return text.slice(0, maxLength);
13170
- const headLength = Math.ceil((maxLength - 3) / 2);
13171
- const tailLength = Math.floor((maxLength - 3) / 2);
13172
- return `${text.slice(0, headLength)}...${text.slice(text.length - tailLength)}`;
13173
- }
13174
-
13175
- function truncateEnd(value, maxLength) {
13176
- const text = String(value ?? '');
13177
- if (text.length <= maxLength) return text;
13178
- if (maxLength <= 5) return text.slice(0, maxLength);
13179
- return `${text.slice(0, maxLength - 3)}...`;
13180
- }
13181
-
13182
- function wrapText(text, width) {
13183
- const words = String(text).split(/\s+/).filter(Boolean);
13184
- if (words.length === 0) return [''];
13185
- const lines = [];
13186
- let current = '';
13187
- for (const word of words) {
13188
- if (word.length > width) {
13189
- if (current) {
13190
- lines.push(current);
13191
- current = '';
13192
- }
13193
- for (let index = 0; index < word.length; index += width) {
13194
- lines.push(word.slice(index, index + width));
13195
- }
13196
- continue;
13197
- }
13198
- const next = current ? `${current} ${word}` : word;
13199
- if (next.length > width) {
13200
- lines.push(current);
13201
- current = word;
13202
- } else {
13203
- current = next;
13204
- }
13205
- }
13206
- if (current) lines.push(current);
13207
- return lines;
13208
- }
13209
-
13210
- function padRight(text, width) {
13211
- const value = String(text);
13212
- if (value.length >= width) return value.slice(0, width);
13213
- return `${value}${' '.repeat(width - value.length)}`;
13214
- }
13215
-
13216
- function colorize(enabled, style, text) {
13217
- if (!enabled || !style) return text;
13218
- return `${style}${text}${terminal_wrapper_ANSI_RESET}`;
13219
- }
13220
-
13221
- function getTerminalControlScreenTone(title) {
13222
- if (/\bFAILED\b|\bBLOCKED\b/i.test(title)) return 'danger';
13223
- if (/\bRESTORING\b|\bSTARTING\b/i.test(title)) return 'restore';
13224
- return 'takeover';
13225
- }
13226
-
13227
- function getTerminalControlScreenPalette(tone) {
13228
- if (tone === 'danger') {
13229
- return {
13230
- title: `${ANSI_BOLD}${ANSI_RED}`,
13231
- subtitle: ANSI_RED,
13232
- separator: ANSI_RED,
13233
- label: ANSI_YELLOW,
13234
- body: '',
13235
- footer: `${ANSI_BOLD}${ANSI_YELLOW}`,
13236
- };
13237
- }
13238
- if (tone === 'restore') {
13239
- return {
13240
- title: `${ANSI_BOLD}${ANSI_CYAN}`,
13241
- subtitle: ANSI_CYAN,
13242
- separator: ANSI_CYAN,
13243
- label: ANSI_CYAN,
13244
- body: '',
13245
- footer: `${ANSI_BOLD}${ANSI_GREEN}`,
13246
- };
13247
- }
13248
- return {
13249
- title: `${ANSI_BOLD}${ANSI_BG_BLUE}${ANSI_WHITE}`,
13250
- subtitle: ANSI_GREEN,
13251
- separator: ANSI_GREEN,
13252
- label: ANSI_CYAN,
13253
- body: '',
13254
- footer: `${ANSI_BOLD}${ANSI_YELLOW}`,
13255
- };
13256
- }
13257
-
13258
- function formatTerminalFieldParts(label, value, width, { truncate = 'middle' } = {}) {
13259
- const prefix = `${label}: `;
13260
- const maxValueLength = Math.max(8, width - prefix.length);
13261
- return {
13262
- label: prefix,
13263
- value: truncate === 'end' ? truncateEnd(value, maxValueLength) : truncateMiddle(value, maxValueLength),
13264
- };
13265
- }
13266
-
13267
- function formatTerminalControlScreen({
13268
- title,
13269
- subtitle,
13270
- agent,
13271
- cwd,
13272
- sessionId,
13273
- task,
13274
- bodyLines = [],
13275
- footerLines = [],
13276
- columns = 80,
13277
- rows = 24,
13278
- color = false,
13279
- }) {
13280
- const screenWidth = Math.max(20, Number(columns) || 80);
13281
- const width = screenWidth < 60 ? screenWidth : Math.min(100, screenWidth);
13282
- const height = Math.max(20, Number(rows) || 24);
13283
- const innerWidth = width - 8;
13284
- const separator = '='.repeat(width);
13285
- const tone = getTerminalControlScreenTone(title);
13286
- const palette = getTerminalControlScreenPalette(tone);
13287
- const fieldLines = [
13288
- { label: 'Agent', value: agent || 'unknown' },
13289
- { label: 'Session', value: sessionId || 'pending' },
13290
- ...(task ? [{ label: 'Task', value: task, truncate: 'end' }] : []),
13291
- { label: 'Directory', value: cwd || process.cwd() },
13292
- ].map(({ label, value, truncate }) => {
13293
- const parts = formatTerminalFieldParts(label, value, innerWidth, { truncate });
13294
- return `${colorize(color, palette.label, parts.label)}${parts.value}`;
13295
- });
13296
- const block = [
13297
- colorize(color, palette.separator, separator),
13298
- colorize(color, palette.title, padRight(title, width)),
13299
- subtitle ? colorize(color, palette.subtitle, padRight(subtitle, width)) : '',
13300
- colorize(color, palette.separator, separator),
13301
- '',
13302
- ...fieldLines,
13303
- '',
13304
- ];
13305
-
13306
- for (const line of bodyLines) {
13307
- for (const wrapped of wrapText(line, innerWidth)) {
13308
- block.push(colorize(color, palette.body, padRight(wrapped, width)));
13309
- }
13310
- }
13311
-
13312
- block.push('');
13313
- for (const line of footerLines) {
13314
- for (const wrapped of wrapText(line, innerWidth)) {
13315
- block.push(colorize(color, palette.footer, padRight(wrapped, width)));
13316
- }
13317
- }
13318
- block.push(colorize(color, palette.separator, separator));
13319
-
13320
- const verticalPadding = Math.max(0, Math.floor((height - block.length) / 3));
13321
- return `${'\n'.repeat(verticalPadding)}${block.join('\n')}\n`;
13322
- }
13323
-
13324
- function normalizeTerminalScreenForTty(screen) {
13325
- return `\r${String(screen).replace(/\r?\n/g, '\r\n')}`;
13326
- }
13327
-
13328
- function renderTerminalControlScreen(stream, options) {
13329
- const columns = Number(stream?.columns) || 80;
13330
- const rows = Number(stream?.rows) || 24;
13331
- const screen = formatTerminalControlScreen({ ...options, columns, rows, color: Boolean(stream?.isTTY) });
13332
- if (stream?.isTTY) {
13333
- stream.write(`${ANSI_CLEAR_SCREEN}${ANSI_HIDE_CURSOR}${normalizeTerminalScreenForTty(screen)}`);
13334
- return;
13335
- }
13336
- stream.write(`\n${screen}`);
13337
- }
13338
-
13339
13357
  async function waitForRetryOrSignal(signalExit, delayMs) {
13340
13358
  let timer;
13341
13359
  const retry = new Promise((resolve) => {
@@ -13461,6 +13479,10 @@ async function connectTerminalControl({
13461
13479
  let heartbeatTimer = null;
13462
13480
  let resolveClosed;
13463
13481
  let closedResolved = false;
13482
+ let resolveTakeoverResponseSent;
13483
+ const takeoverResponseSent = new Promise((resolve) => {
13484
+ resolveTakeoverResponseSent = resolve;
13485
+ });
13464
13486
  const closed = new Promise((resolve) => {
13465
13487
  resolveClosed = resolve;
13466
13488
  });
@@ -13471,6 +13493,7 @@ async function connectTerminalControl({
13471
13493
  heartbeatTimer = null;
13472
13494
  }
13473
13495
  requester.rejectAll('terminal_control_closed');
13496
+ resolveTakeoverResponseSent(false);
13474
13497
  if (closedResolved) return;
13475
13498
  closedResolved = true;
13476
13499
  resolveClosed({
@@ -13491,7 +13514,7 @@ async function connectTerminalControl({
13491
13514
  });
13492
13515
  }
13493
13516
 
13494
- function sendResponse(id, ok, data, error) {
13517
+ function sendResponse(id, ok, data, error, onSent) {
13495
13518
  ws.send(
13496
13519
  JSON.stringify({
13497
13520
  type: 'response',
@@ -13500,6 +13523,7 @@ async function connectTerminalControl({
13500
13523
  ...(data === undefined ? {} : { data }),
13501
13524
  ...(error ? { error } : {}),
13502
13525
  }),
13526
+ onSent,
13503
13527
  );
13504
13528
  }
13505
13529
 
@@ -13527,21 +13551,28 @@ async function connectTerminalControl({
13527
13551
  restoreTerminalAfterNativeTui(stderr, process.stdin, terminalLineDiscipline);
13528
13552
  setMode('remoteDaemon');
13529
13553
  await sendSession('remoteDaemon');
13530
- renderTerminalControlScreen(stderr, {
13531
- title: 'VIBELET APP CONTROL',
13532
- subtitle: 'Remote takeover is active',
13533
- agent,
13534
- cwd,
13535
- sessionId: currentSessionId,
13536
- task: currentTaskPreview,
13537
- bodyLines: [
13538
- 'The Vibelet app is now controlling this session.',
13539
- 'The native terminal UI is paused so messages and tool output stay in the app.',
13540
- 'Leave this terminal open while you work from the app.',
13541
- ],
13542
- footerLines: ['Press any key to restore the native terminal UI.', 'Press Ctrl-C to close this terminal monitor.'],
13554
+ if (agent !== 'codex') {
13555
+ renderTerminalControlScreen(stderr, {
13556
+ title: 'VIBELET APP CONTROL',
13557
+ subtitle: 'Remote takeover is active',
13558
+ agent,
13559
+ cwd,
13560
+ sessionId: currentSessionId,
13561
+ task: currentTaskPreview,
13562
+ bodyLines: [
13563
+ 'The Vibelet app is now controlling this session.',
13564
+ 'The native terminal UI is paused so messages and tool output stay in the app.',
13565
+ 'Leave this terminal open while you work from the app.',
13566
+ ],
13567
+ footerLines: [
13568
+ 'Press any key to restore the native terminal UI.',
13569
+ 'Press Ctrl-C to close this terminal monitor.',
13570
+ ],
13571
+ });
13572
+ }
13573
+ sendResponse(msg.id, true, { mode: 'remoteDaemon' }, undefined, (error) => {
13574
+ resolveTakeoverResponseSent(!error);
13543
13575
  });
13544
- sendResponse(msg.id, true, { mode: 'remoteDaemon' });
13545
13576
  });
13546
13577
 
13547
13578
  ws.on('close', (code, reason) => {
@@ -13582,6 +13613,7 @@ async function connectTerminalControl({
13582
13613
 
13583
13614
  return {
13584
13615
  closed,
13616
+ takeoverResponseSent,
13585
13617
  getTerminalId() {
13586
13618
  return terminalId;
13587
13619
  },
@@ -13677,9 +13709,10 @@ async function runManagedNativeTerminal({
13677
13709
  cwd = process.cwd(),
13678
13710
  env = process.env,
13679
13711
  stderr = process.stderr,
13712
+ controlToken,
13680
13713
  }) {
13681
13714
  const command = resolveNativeAgentCommand(agent, env);
13682
- const token = readTerminalControlToken();
13715
+ const token = controlToken ?? readTerminalControlToken();
13683
13716
  const terminalLineDiscipline = captureTerminalLineDiscipline();
13684
13717
  let initialSessionId = extractInitialSessionId(agent, args);
13685
13718
  let nativeArgs = args;
@@ -13796,6 +13829,15 @@ async function runManagedNativeTerminal({
13796
13829
  if (modeState.getMode() !== 'remoteDaemon') {
13797
13830
  return exitCodeFromChildExit(exit);
13798
13831
  }
13832
+ if (agent === 'codex') {
13833
+ const acknowledged = await waitForTakeoverResponseSent(control);
13834
+ stderr.write(
13835
+ acknowledged
13836
+ ? 'Codex session moved to Vibelet. This terminal session is closed.\n'
13837
+ : 'Codex terminal stopped, but Vibelet takeover was not acknowledged.\n',
13838
+ );
13839
+ return acknowledged ? 0 : 1;
13840
+ }
13799
13841
 
13800
13842
  const monitorAction = await waitForRemoteMonitorInput(signalHandlers.signalExit);
13801
13843
  if (monitorAction.type === 'exit') {
@@ -16043,7 +16085,7 @@ __nccwpck_require__.a(__webpack_module__, async (__webpack_handle_async_dependen
16043
16085
  /* harmony import */ var _vibelet_help_mjs__WEBPACK_IMPORTED_MODULE_16__ = __nccwpck_require__(4162);
16044
16086
  /* harmony import */ var _vibelet_tailcat_config_mjs__WEBPACK_IMPORTED_MODULE_9__ = __nccwpck_require__(5798);
16045
16087
  /* harmony import */ var _vibelet_runtime_policy_mjs__WEBPACK_IMPORTED_MODULE_12__ = __nccwpck_require__(4);
16046
- /* harmony import */ var _terminal_wrapper_mjs__WEBPACK_IMPORTED_MODULE_10__ = __nccwpck_require__(877);
16088
+ /* harmony import */ var _terminal_wrapper_mjs__WEBPACK_IMPORTED_MODULE_10__ = __nccwpck_require__(5028);
16047
16089
  /* harmony import */ var _vibelet_pairing_connections_mjs__WEBPACK_IMPORTED_MODULE_15__ = __nccwpck_require__(7721);
16048
16090
  /* harmony import */ var _vibelet_pairing_output_mjs__WEBPACK_IMPORTED_MODULE_11__ = __nccwpck_require__(9485);
16049
16091
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibelet",
3
- "version": "1.2.211",
3
+ "version": "1.2.216",
4
4
  "description": "Cross-platform CLI for installing and running the Vibelet daemon",
5
5
  "homepage": "https://vibelet.icu",
6
6
  "files": [