@vibelet/cli 1.2.137 → 1.2.139
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/index.cjs +1 -1
- package/dist/runtime-version.cjs +1 -1
- package/dist/vibelet.mjs +152 -42
- package/package.json +1 -1
package/dist/runtime-version.cjs
CHANGED
|
@@ -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.
|
|
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.139"}var a=l();process.stdout.write(`${a}
|
|
2
2
|
`);
|
package/dist/vibelet.mjs
CHANGED
|
@@ -11768,7 +11768,7 @@ __nccwpck_require__.d(__webpack_exports__, {
|
|
|
11768
11768
|
gJ: () => (/* binding */ terminalControlTokenPath)
|
|
11769
11769
|
});
|
|
11770
11770
|
|
|
11771
|
-
// UNUSED EXPORTS: buildClaudeSessionIdArgs, buildClaudeTerminalArgs, buildResumeNativeArgs, cleanupClaudeTerminalHookFiles, collectProcessTreePids, createClaudeTerminalHookFiles, createTerminalModeState, exitCodeFromChildExit, extractInitialSessionId, formatTerminalControlScreen, hasClaudeContinueArg, hasClaudeResumePickerArg, hasClaudeSettingsArg, requestSwitchBackWhenReady, resolveNativeAgentCommand, stopNativeChild
|
|
11771
|
+
// UNUSED EXPORTS: buildClaudeSessionIdArgs, buildClaudeTerminalArgs, buildResumeNativeArgs, cleanupClaudeTerminalHookFiles, collectProcessTreePids, connectTerminalControl, createClaudeTerminalHookFiles, createTerminalModeState, exitCodeFromChildExit, extractInitialSessionId, formatTerminalControlScreen, hasClaudeContinueArg, hasClaudeResumePickerArg, hasClaudeSettingsArg, monitorTerminalControlUntilChildExit, requestSwitchBackWhenReady, resolveNativeAgentCommand, stopNativeChild
|
|
11772
11772
|
|
|
11773
11773
|
// EXTERNAL MODULE: external "node:child_process"
|
|
11774
11774
|
var external_node_child_process_ = __nccwpck_require__(1421);
|
|
@@ -11814,13 +11814,13 @@ const TAKEOVER_STOP_TIMEOUT_MS = 3000;
|
|
|
11814
11814
|
const TAKEOVER_MODE_SETTLE_TIMEOUT_MS = TAKEOVER_STOP_TIMEOUT_MS + 2000;
|
|
11815
11815
|
const SWITCHBACK_RESTORE_NOTICE_MS = 1200;
|
|
11816
11816
|
const SWITCHBACK_BUSY_RETRY_DELAY_MS = 750;
|
|
11817
|
+
const TERMINAL_CONTROL_RECONNECT_DELAY_MS = 1000;
|
|
11817
11818
|
const CLAUDE_HOOK_SECRET_HEADER = 'x-vibelet-claude-hook-secret';
|
|
11818
11819
|
const ANSI_CLEAR_SCREEN = '\x1b[2J\x1b[H';
|
|
11819
11820
|
const ANSI_HIDE_CURSOR = '\x1b[?25l';
|
|
11820
11821
|
const ANSI_SHOW_CURSOR = '\x1b[?25h';
|
|
11821
11822
|
const ANSI_RESET = '\x1b[0m';
|
|
11822
11823
|
const ANSI_BOLD = '\x1b[1m';
|
|
11823
|
-
const ANSI_DIM = '\x1b[2m';
|
|
11824
11824
|
const ANSI_CYAN = '\x1b[36m';
|
|
11825
11825
|
const ANSI_GREEN = '\x1b[32m';
|
|
11826
11826
|
const ANSI_YELLOW = '\x1b[33m';
|
|
@@ -12226,13 +12226,6 @@ function wrapText(text, width) {
|
|
|
12226
12226
|
return lines;
|
|
12227
12227
|
}
|
|
12228
12228
|
|
|
12229
|
-
function centerText(text, width) {
|
|
12230
|
-
const value = String(text);
|
|
12231
|
-
if (value.length >= width) return value.slice(0, width);
|
|
12232
|
-
const left = Math.floor((width - value.length) / 2);
|
|
12233
|
-
return `${' '.repeat(left)}${value}`;
|
|
12234
|
-
}
|
|
12235
|
-
|
|
12236
12229
|
function padRight(text, width) {
|
|
12237
12230
|
const value = String(text);
|
|
12238
12231
|
if (value.length >= width) return value.slice(0, width);
|
|
@@ -12240,7 +12233,7 @@ function padRight(text, width) {
|
|
|
12240
12233
|
}
|
|
12241
12234
|
|
|
12242
12235
|
function colorize(enabled, style, text) {
|
|
12243
|
-
if (!enabled) return text;
|
|
12236
|
+
if (!enabled || !style) return text;
|
|
12244
12237
|
return `${style}${text}${ANSI_RESET}`;
|
|
12245
12238
|
}
|
|
12246
12239
|
|
|
@@ -12257,7 +12250,7 @@ function getTerminalControlScreenPalette(tone) {
|
|
|
12257
12250
|
subtitle: ANSI_RED,
|
|
12258
12251
|
separator: ANSI_RED,
|
|
12259
12252
|
label: ANSI_YELLOW,
|
|
12260
|
-
body:
|
|
12253
|
+
body: '',
|
|
12261
12254
|
footer: `${ANSI_BOLD}${ANSI_YELLOW}`,
|
|
12262
12255
|
};
|
|
12263
12256
|
}
|
|
@@ -12267,7 +12260,7 @@ function getTerminalControlScreenPalette(tone) {
|
|
|
12267
12260
|
subtitle: ANSI_CYAN,
|
|
12268
12261
|
separator: ANSI_CYAN,
|
|
12269
12262
|
label: ANSI_CYAN,
|
|
12270
|
-
body:
|
|
12263
|
+
body: '',
|
|
12271
12264
|
footer: `${ANSI_BOLD}${ANSI_GREEN}`,
|
|
12272
12265
|
};
|
|
12273
12266
|
}
|
|
@@ -12276,7 +12269,7 @@ function getTerminalControlScreenPalette(tone) {
|
|
|
12276
12269
|
subtitle: ANSI_GREEN,
|
|
12277
12270
|
separator: ANSI_GREEN,
|
|
12278
12271
|
label: ANSI_CYAN,
|
|
12279
|
-
body:
|
|
12272
|
+
body: '',
|
|
12280
12273
|
footer: `${ANSI_BOLD}${ANSI_YELLOW}`,
|
|
12281
12274
|
};
|
|
12282
12275
|
}
|
|
@@ -12305,7 +12298,6 @@ function formatTerminalControlScreen({
|
|
|
12305
12298
|
const width = screenWidth < 60 ? screenWidth : Math.min(100, screenWidth);
|
|
12306
12299
|
const height = Math.max(20, Number(rows) || 24);
|
|
12307
12300
|
const innerWidth = width - 8;
|
|
12308
|
-
const gutter = ' '.repeat(Math.max(0, Math.floor((screenWidth - width) / 2)));
|
|
12309
12301
|
const separator = '='.repeat(width);
|
|
12310
12302
|
const tone = getTerminalControlScreenTone(title);
|
|
12311
12303
|
const palette = getTerminalControlScreenPalette(tone);
|
|
@@ -12315,12 +12307,12 @@ function formatTerminalControlScreen({
|
|
|
12315
12307
|
['Directory', cwd || process.cwd()],
|
|
12316
12308
|
].map(([label, value]) => {
|
|
12317
12309
|
const parts = formatTerminalFieldParts(label, value, innerWidth);
|
|
12318
|
-
return `${colorize(color, palette.label, parts.label)}${
|
|
12310
|
+
return `${colorize(color, palette.label, parts.label)}${parts.value}`;
|
|
12319
12311
|
});
|
|
12320
12312
|
const block = [
|
|
12321
12313
|
colorize(color, palette.separator, separator),
|
|
12322
|
-
colorize(color, palette.title, padRight(
|
|
12323
|
-
subtitle ? colorize(color, palette.subtitle, padRight(
|
|
12314
|
+
colorize(color, palette.title, padRight(title, width)),
|
|
12315
|
+
subtitle ? colorize(color, palette.subtitle, padRight(subtitle, width)) : '',
|
|
12324
12316
|
colorize(color, palette.separator, separator),
|
|
12325
12317
|
'',
|
|
12326
12318
|
...fieldLines,
|
|
@@ -12329,20 +12321,20 @@ function formatTerminalControlScreen({
|
|
|
12329
12321
|
|
|
12330
12322
|
for (const line of bodyLines) {
|
|
12331
12323
|
for (const wrapped of wrapText(line, innerWidth)) {
|
|
12332
|
-
block.push(colorize(color, palette.body, padRight(
|
|
12324
|
+
block.push(colorize(color, palette.body, padRight(wrapped, width)));
|
|
12333
12325
|
}
|
|
12334
12326
|
}
|
|
12335
12327
|
|
|
12336
12328
|
block.push('');
|
|
12337
12329
|
for (const line of footerLines) {
|
|
12338
12330
|
for (const wrapped of wrapText(line, innerWidth)) {
|
|
12339
|
-
block.push(colorize(color, palette.footer, padRight(
|
|
12331
|
+
block.push(colorize(color, palette.footer, padRight(wrapped, width)));
|
|
12340
12332
|
}
|
|
12341
12333
|
}
|
|
12342
12334
|
block.push(colorize(color, palette.separator, separator));
|
|
12343
12335
|
|
|
12344
12336
|
const verticalPadding = Math.max(0, Math.floor((height - block.length) / 3));
|
|
12345
|
-
return `${'\n'.repeat(verticalPadding)}${block.
|
|
12337
|
+
return `${'\n'.repeat(verticalPadding)}${block.join('\n')}\n`;
|
|
12346
12338
|
}
|
|
12347
12339
|
|
|
12348
12340
|
function renderTerminalControlScreen(stream, options) {
|
|
@@ -12549,6 +12541,25 @@ async function connectTerminalControl({
|
|
|
12549
12541
|
let activeChild = child;
|
|
12550
12542
|
let activeChildExit = childExit;
|
|
12551
12543
|
let heartbeatTimer = null;
|
|
12544
|
+
let resolveClosed;
|
|
12545
|
+
let closedResolved = false;
|
|
12546
|
+
const closed = new Promise((resolve) => {
|
|
12547
|
+
resolveClosed = resolve;
|
|
12548
|
+
});
|
|
12549
|
+
|
|
12550
|
+
function resolveCloseOnce(code, reason) {
|
|
12551
|
+
if (heartbeatTimer) {
|
|
12552
|
+
clearInterval(heartbeatTimer);
|
|
12553
|
+
heartbeatTimer = null;
|
|
12554
|
+
}
|
|
12555
|
+
requester.rejectAll('terminal_control_closed');
|
|
12556
|
+
if (closedResolved) return;
|
|
12557
|
+
closedResolved = true;
|
|
12558
|
+
resolveClosed({
|
|
12559
|
+
code,
|
|
12560
|
+
reason: Buffer.isBuffer(reason) ? reason.toString('utf8') : String(reason ?? ''),
|
|
12561
|
+
});
|
|
12562
|
+
}
|
|
12552
12563
|
|
|
12553
12564
|
async function sendSession(mode = getMode()) {
|
|
12554
12565
|
if (!terminalId || !currentSessionId) return { ok: true };
|
|
@@ -12613,9 +12624,8 @@ async function connectTerminalControl({
|
|
|
12613
12624
|
sendResponse(msg.id, true, { mode: 'remoteDaemon' });
|
|
12614
12625
|
});
|
|
12615
12626
|
|
|
12616
|
-
ws.on('close', () => {
|
|
12617
|
-
|
|
12618
|
-
requester.rejectAll('terminal_control_closed');
|
|
12627
|
+
ws.on('close', (code, reason) => {
|
|
12628
|
+
resolveCloseOnce(code, reason);
|
|
12619
12629
|
});
|
|
12620
12630
|
|
|
12621
12631
|
const hello = await requester.sendRequest('terminal.hello', {
|
|
@@ -12651,6 +12661,10 @@ async function connectTerminalControl({
|
|
|
12651
12661
|
if (typeof heartbeatTimer.unref === 'function') heartbeatTimer.unref();
|
|
12652
12662
|
|
|
12653
12663
|
return {
|
|
12664
|
+
closed,
|
|
12665
|
+
getTerminalId() {
|
|
12666
|
+
return terminalId;
|
|
12667
|
+
},
|
|
12654
12668
|
getSessionId() {
|
|
12655
12669
|
return currentSessionId;
|
|
12656
12670
|
},
|
|
@@ -12673,12 +12687,68 @@ async function connectTerminalControl({
|
|
|
12673
12687
|
});
|
|
12674
12688
|
},
|
|
12675
12689
|
close() {
|
|
12676
|
-
if (heartbeatTimer)
|
|
12677
|
-
|
|
12690
|
+
if (heartbeatTimer) {
|
|
12691
|
+
clearInterval(heartbeatTimer);
|
|
12692
|
+
heartbeatTimer = null;
|
|
12693
|
+
}
|
|
12694
|
+
if (ws.readyState === wrapper.OPEN || ws.readyState === wrapper.CONNECTING) {
|
|
12695
|
+
ws.close();
|
|
12696
|
+
}
|
|
12678
12697
|
},
|
|
12679
12698
|
};
|
|
12680
12699
|
}
|
|
12681
12700
|
|
|
12701
|
+
async function monitorTerminalControlUntilChildExit({
|
|
12702
|
+
childExit,
|
|
12703
|
+
getControl,
|
|
12704
|
+
setControl,
|
|
12705
|
+
connectControl,
|
|
12706
|
+
shouldReconnect = () => true,
|
|
12707
|
+
retryDelayMs = TERMINAL_CONTROL_RECONNECT_DELAY_MS,
|
|
12708
|
+
onControlDisconnected,
|
|
12709
|
+
onReconnectFailure,
|
|
12710
|
+
}) {
|
|
12711
|
+
const delayMs = Math.max(1, Number(retryDelayMs) || TERMINAL_CONTROL_RECONNECT_DELAY_MS);
|
|
12712
|
+
const childExitEvent = childExit.then((exit) => ({ type: 'childExit', exit }));
|
|
12713
|
+
|
|
12714
|
+
while (true) {
|
|
12715
|
+
const currentControl = getControl();
|
|
12716
|
+
const waiters = [childExitEvent];
|
|
12717
|
+
if (currentControl?.closed) {
|
|
12718
|
+
waiters.push(
|
|
12719
|
+
currentControl.closed.then((closeInfo) => ({
|
|
12720
|
+
type: 'controlClosed',
|
|
12721
|
+
control: currentControl,
|
|
12722
|
+
closeInfo,
|
|
12723
|
+
})),
|
|
12724
|
+
);
|
|
12725
|
+
}
|
|
12726
|
+
if (!currentControl || !shouldReconnect()) {
|
|
12727
|
+
waiters.push(waitMs(delayMs).then(() => ({ type: 'retry' })));
|
|
12728
|
+
}
|
|
12729
|
+
|
|
12730
|
+
const event = await Promise.race(waiters);
|
|
12731
|
+
if (event.type === 'childExit') {
|
|
12732
|
+
return event.exit;
|
|
12733
|
+
}
|
|
12734
|
+
|
|
12735
|
+
if (event.type === 'controlClosed' && getControl() === event.control) {
|
|
12736
|
+
setControl(null);
|
|
12737
|
+
onControlDisconnected?.(event.control, event.closeInfo);
|
|
12738
|
+
}
|
|
12739
|
+
|
|
12740
|
+
if (getControl() || !shouldReconnect()) {
|
|
12741
|
+
continue;
|
|
12742
|
+
}
|
|
12743
|
+
|
|
12744
|
+
try {
|
|
12745
|
+
setControl(await connectControl());
|
|
12746
|
+
} catch (error) {
|
|
12747
|
+
onReconnectFailure?.(error);
|
|
12748
|
+
}
|
|
12749
|
+
}
|
|
12750
|
+
}
|
|
12751
|
+
|
|
12682
12752
|
async function runManagedNativeTerminal({
|
|
12683
12753
|
agent,
|
|
12684
12754
|
args,
|
|
@@ -12716,11 +12786,49 @@ async function runManagedNativeTerminal({
|
|
|
12716
12786
|
let signalHandlers = null;
|
|
12717
12787
|
const modeState = createTerminalModeState('localNative');
|
|
12718
12788
|
let control = null;
|
|
12789
|
+
let terminalId = claudeHookFiles?.terminalId ?? null;
|
|
12790
|
+
|
|
12791
|
+
function rememberControlState(nextControl) {
|
|
12792
|
+
const nextTerminalId = nextControl?.getTerminalId?.();
|
|
12793
|
+
if (nextTerminalId) terminalId = nextTerminalId;
|
|
12794
|
+
const nextSessionId = nextControl?.getSessionId?.();
|
|
12795
|
+
if (nextSessionId) initialSessionId = nextSessionId;
|
|
12796
|
+
}
|
|
12719
12797
|
|
|
12720
12798
|
try {
|
|
12721
12799
|
while (true) {
|
|
12722
12800
|
activeChild = await spawnNativeChild(command, nativeArgs, { cwd, env });
|
|
12723
12801
|
const childExit = waitForChildExit(activeChild);
|
|
12802
|
+
let reportedTerminalControlFailure = false;
|
|
12803
|
+
const reportTerminalControlFailure = (prefix, error) => {
|
|
12804
|
+
if (reportedTerminalControlFailure) return;
|
|
12805
|
+
reportedTerminalControlFailure = true;
|
|
12806
|
+
stderr.write(`${prefix}: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
12807
|
+
};
|
|
12808
|
+
const connectActiveControl = async () => {
|
|
12809
|
+
const nextControl = await connectTerminalControl({
|
|
12810
|
+
agent,
|
|
12811
|
+
cwd,
|
|
12812
|
+
argv,
|
|
12813
|
+
child: activeChild,
|
|
12814
|
+
childExit,
|
|
12815
|
+
cliVersion,
|
|
12816
|
+
port,
|
|
12817
|
+
token,
|
|
12818
|
+
initialSessionId,
|
|
12819
|
+
requestedTerminalId: terminalId ?? claudeHookFiles?.terminalId,
|
|
12820
|
+
getMode: () => modeState.getMode(),
|
|
12821
|
+
setMode: (nextMode) => modeState.setMode(nextMode),
|
|
12822
|
+
stderr,
|
|
12823
|
+
});
|
|
12824
|
+
rememberControlState(nextControl);
|
|
12825
|
+
reportedTerminalControlFailure = false;
|
|
12826
|
+
return nextControl;
|
|
12827
|
+
};
|
|
12828
|
+
const setActiveControl = (nextControl) => {
|
|
12829
|
+
control = nextControl;
|
|
12830
|
+
rememberControlState(nextControl);
|
|
12831
|
+
};
|
|
12724
12832
|
if (!signalHandlers) {
|
|
12725
12833
|
signalHandlers = installTerminalSignalHandlers(
|
|
12726
12834
|
() => activeChild,
|
|
@@ -12732,30 +12840,32 @@ async function runManagedNativeTerminal({
|
|
|
12732
12840
|
stderr.write('Vibelet terminal control is unavailable; running native TUI without App takeover.\n');
|
|
12733
12841
|
} else if (!control) {
|
|
12734
12842
|
try {
|
|
12735
|
-
|
|
12736
|
-
agent,
|
|
12737
|
-
cwd,
|
|
12738
|
-
argv,
|
|
12739
|
-
child: activeChild,
|
|
12740
|
-
childExit,
|
|
12741
|
-
cliVersion,
|
|
12742
|
-
port,
|
|
12743
|
-
token,
|
|
12744
|
-
initialSessionId,
|
|
12745
|
-
requestedTerminalId: claudeHookFiles?.terminalId,
|
|
12746
|
-
getMode: () => modeState.getMode(),
|
|
12747
|
-
setMode: (nextMode) => modeState.setMode(nextMode),
|
|
12748
|
-
stderr,
|
|
12749
|
-
});
|
|
12843
|
+
setActiveControl(await connectActiveControl());
|
|
12750
12844
|
} catch (error) {
|
|
12751
|
-
|
|
12845
|
+
reportTerminalControlFailure('Vibelet terminal control failed', error);
|
|
12752
12846
|
}
|
|
12753
12847
|
} else {
|
|
12754
12848
|
control.setChild(activeChild, childExit);
|
|
12755
12849
|
await control.sendSession('localNative');
|
|
12850
|
+
rememberControlState(control);
|
|
12756
12851
|
}
|
|
12757
12852
|
|
|
12758
|
-
const exit =
|
|
12853
|
+
const exit = token
|
|
12854
|
+
? await monitorTerminalControlUntilChildExit({
|
|
12855
|
+
childExit,
|
|
12856
|
+
getControl: () => control,
|
|
12857
|
+
setControl: setActiveControl,
|
|
12858
|
+
connectControl: connectActiveControl,
|
|
12859
|
+
shouldReconnect: () => modeState.getMode() === 'localNative',
|
|
12860
|
+
onControlDisconnected: (closedControl) => {
|
|
12861
|
+
rememberControlState(closedControl);
|
|
12862
|
+
stderr.write('Vibelet terminal control disconnected; reconnecting so App takeover can resume.\n');
|
|
12863
|
+
},
|
|
12864
|
+
onReconnectFailure: (error) => {
|
|
12865
|
+
reportTerminalControlFailure('Vibelet terminal control reconnect failed', error);
|
|
12866
|
+
},
|
|
12867
|
+
})
|
|
12868
|
+
: await childExit;
|
|
12759
12869
|
if (modeState.getMode() === 'switchingToRemote') {
|
|
12760
12870
|
await modeState.waitUntilModeLeaves('switchingToRemote', TAKEOVER_MODE_SETTLE_TIMEOUT_MS);
|
|
12761
12871
|
}
|