vibelet 1.2.136 → 1.2.138
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 +142 -23
- 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.138"}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,6 +11814,7 @@ 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';
|
|
@@ -12549,6 +12550,25 @@ async function connectTerminalControl({
|
|
|
12549
12550
|
let activeChild = child;
|
|
12550
12551
|
let activeChildExit = childExit;
|
|
12551
12552
|
let heartbeatTimer = null;
|
|
12553
|
+
let resolveClosed;
|
|
12554
|
+
let closedResolved = false;
|
|
12555
|
+
const closed = new Promise((resolve) => {
|
|
12556
|
+
resolveClosed = resolve;
|
|
12557
|
+
});
|
|
12558
|
+
|
|
12559
|
+
function resolveCloseOnce(code, reason) {
|
|
12560
|
+
if (heartbeatTimer) {
|
|
12561
|
+
clearInterval(heartbeatTimer);
|
|
12562
|
+
heartbeatTimer = null;
|
|
12563
|
+
}
|
|
12564
|
+
requester.rejectAll('terminal_control_closed');
|
|
12565
|
+
if (closedResolved) return;
|
|
12566
|
+
closedResolved = true;
|
|
12567
|
+
resolveClosed({
|
|
12568
|
+
code,
|
|
12569
|
+
reason: Buffer.isBuffer(reason) ? reason.toString('utf8') : String(reason ?? ''),
|
|
12570
|
+
});
|
|
12571
|
+
}
|
|
12552
12572
|
|
|
12553
12573
|
async function sendSession(mode = getMode()) {
|
|
12554
12574
|
if (!terminalId || !currentSessionId) return { ok: true };
|
|
@@ -12613,9 +12633,8 @@ async function connectTerminalControl({
|
|
|
12613
12633
|
sendResponse(msg.id, true, { mode: 'remoteDaemon' });
|
|
12614
12634
|
});
|
|
12615
12635
|
|
|
12616
|
-
ws.on('close', () => {
|
|
12617
|
-
|
|
12618
|
-
requester.rejectAll('terminal_control_closed');
|
|
12636
|
+
ws.on('close', (code, reason) => {
|
|
12637
|
+
resolveCloseOnce(code, reason);
|
|
12619
12638
|
});
|
|
12620
12639
|
|
|
12621
12640
|
const hello = await requester.sendRequest('terminal.hello', {
|
|
@@ -12651,6 +12670,10 @@ async function connectTerminalControl({
|
|
|
12651
12670
|
if (typeof heartbeatTimer.unref === 'function') heartbeatTimer.unref();
|
|
12652
12671
|
|
|
12653
12672
|
return {
|
|
12673
|
+
closed,
|
|
12674
|
+
getTerminalId() {
|
|
12675
|
+
return terminalId;
|
|
12676
|
+
},
|
|
12654
12677
|
getSessionId() {
|
|
12655
12678
|
return currentSessionId;
|
|
12656
12679
|
},
|
|
@@ -12673,12 +12696,68 @@ async function connectTerminalControl({
|
|
|
12673
12696
|
});
|
|
12674
12697
|
},
|
|
12675
12698
|
close() {
|
|
12676
|
-
if (heartbeatTimer)
|
|
12677
|
-
|
|
12699
|
+
if (heartbeatTimer) {
|
|
12700
|
+
clearInterval(heartbeatTimer);
|
|
12701
|
+
heartbeatTimer = null;
|
|
12702
|
+
}
|
|
12703
|
+
if (ws.readyState === wrapper.OPEN || ws.readyState === wrapper.CONNECTING) {
|
|
12704
|
+
ws.close();
|
|
12705
|
+
}
|
|
12678
12706
|
},
|
|
12679
12707
|
};
|
|
12680
12708
|
}
|
|
12681
12709
|
|
|
12710
|
+
async function monitorTerminalControlUntilChildExit({
|
|
12711
|
+
childExit,
|
|
12712
|
+
getControl,
|
|
12713
|
+
setControl,
|
|
12714
|
+
connectControl,
|
|
12715
|
+
shouldReconnect = () => true,
|
|
12716
|
+
retryDelayMs = TERMINAL_CONTROL_RECONNECT_DELAY_MS,
|
|
12717
|
+
onControlDisconnected,
|
|
12718
|
+
onReconnectFailure,
|
|
12719
|
+
}) {
|
|
12720
|
+
const delayMs = Math.max(1, Number(retryDelayMs) || TERMINAL_CONTROL_RECONNECT_DELAY_MS);
|
|
12721
|
+
const childExitEvent = childExit.then((exit) => ({ type: 'childExit', exit }));
|
|
12722
|
+
|
|
12723
|
+
while (true) {
|
|
12724
|
+
const currentControl = getControl();
|
|
12725
|
+
const waiters = [childExitEvent];
|
|
12726
|
+
if (currentControl?.closed) {
|
|
12727
|
+
waiters.push(
|
|
12728
|
+
currentControl.closed.then((closeInfo) => ({
|
|
12729
|
+
type: 'controlClosed',
|
|
12730
|
+
control: currentControl,
|
|
12731
|
+
closeInfo,
|
|
12732
|
+
})),
|
|
12733
|
+
);
|
|
12734
|
+
}
|
|
12735
|
+
if (!currentControl || !shouldReconnect()) {
|
|
12736
|
+
waiters.push(waitMs(delayMs).then(() => ({ type: 'retry' })));
|
|
12737
|
+
}
|
|
12738
|
+
|
|
12739
|
+
const event = await Promise.race(waiters);
|
|
12740
|
+
if (event.type === 'childExit') {
|
|
12741
|
+
return event.exit;
|
|
12742
|
+
}
|
|
12743
|
+
|
|
12744
|
+
if (event.type === 'controlClosed' && getControl() === event.control) {
|
|
12745
|
+
setControl(null);
|
|
12746
|
+
onControlDisconnected?.(event.control, event.closeInfo);
|
|
12747
|
+
}
|
|
12748
|
+
|
|
12749
|
+
if (getControl() || !shouldReconnect()) {
|
|
12750
|
+
continue;
|
|
12751
|
+
}
|
|
12752
|
+
|
|
12753
|
+
try {
|
|
12754
|
+
setControl(await connectControl());
|
|
12755
|
+
} catch (error) {
|
|
12756
|
+
onReconnectFailure?.(error);
|
|
12757
|
+
}
|
|
12758
|
+
}
|
|
12759
|
+
}
|
|
12760
|
+
|
|
12682
12761
|
async function runManagedNativeTerminal({
|
|
12683
12762
|
agent,
|
|
12684
12763
|
args,
|
|
@@ -12716,11 +12795,49 @@ async function runManagedNativeTerminal({
|
|
|
12716
12795
|
let signalHandlers = null;
|
|
12717
12796
|
const modeState = createTerminalModeState('localNative');
|
|
12718
12797
|
let control = null;
|
|
12798
|
+
let terminalId = claudeHookFiles?.terminalId ?? null;
|
|
12799
|
+
|
|
12800
|
+
function rememberControlState(nextControl) {
|
|
12801
|
+
const nextTerminalId = nextControl?.getTerminalId?.();
|
|
12802
|
+
if (nextTerminalId) terminalId = nextTerminalId;
|
|
12803
|
+
const nextSessionId = nextControl?.getSessionId?.();
|
|
12804
|
+
if (nextSessionId) initialSessionId = nextSessionId;
|
|
12805
|
+
}
|
|
12719
12806
|
|
|
12720
12807
|
try {
|
|
12721
12808
|
while (true) {
|
|
12722
12809
|
activeChild = await spawnNativeChild(command, nativeArgs, { cwd, env });
|
|
12723
12810
|
const childExit = waitForChildExit(activeChild);
|
|
12811
|
+
let reportedTerminalControlFailure = false;
|
|
12812
|
+
const reportTerminalControlFailure = (prefix, error) => {
|
|
12813
|
+
if (reportedTerminalControlFailure) return;
|
|
12814
|
+
reportedTerminalControlFailure = true;
|
|
12815
|
+
stderr.write(`${prefix}: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
12816
|
+
};
|
|
12817
|
+
const connectActiveControl = async () => {
|
|
12818
|
+
const nextControl = await connectTerminalControl({
|
|
12819
|
+
agent,
|
|
12820
|
+
cwd,
|
|
12821
|
+
argv,
|
|
12822
|
+
child: activeChild,
|
|
12823
|
+
childExit,
|
|
12824
|
+
cliVersion,
|
|
12825
|
+
port,
|
|
12826
|
+
token,
|
|
12827
|
+
initialSessionId,
|
|
12828
|
+
requestedTerminalId: terminalId ?? claudeHookFiles?.terminalId,
|
|
12829
|
+
getMode: () => modeState.getMode(),
|
|
12830
|
+
setMode: (nextMode) => modeState.setMode(nextMode),
|
|
12831
|
+
stderr,
|
|
12832
|
+
});
|
|
12833
|
+
rememberControlState(nextControl);
|
|
12834
|
+
reportedTerminalControlFailure = false;
|
|
12835
|
+
return nextControl;
|
|
12836
|
+
};
|
|
12837
|
+
const setActiveControl = (nextControl) => {
|
|
12838
|
+
control = nextControl;
|
|
12839
|
+
rememberControlState(nextControl);
|
|
12840
|
+
};
|
|
12724
12841
|
if (!signalHandlers) {
|
|
12725
12842
|
signalHandlers = installTerminalSignalHandlers(
|
|
12726
12843
|
() => activeChild,
|
|
@@ -12732,30 +12849,32 @@ async function runManagedNativeTerminal({
|
|
|
12732
12849
|
stderr.write('Vibelet terminal control is unavailable; running native TUI without App takeover.\n');
|
|
12733
12850
|
} else if (!control) {
|
|
12734
12851
|
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
|
-
});
|
|
12852
|
+
setActiveControl(await connectActiveControl());
|
|
12750
12853
|
} catch (error) {
|
|
12751
|
-
|
|
12854
|
+
reportTerminalControlFailure('Vibelet terminal control failed', error);
|
|
12752
12855
|
}
|
|
12753
12856
|
} else {
|
|
12754
12857
|
control.setChild(activeChild, childExit);
|
|
12755
12858
|
await control.sendSession('localNative');
|
|
12859
|
+
rememberControlState(control);
|
|
12756
12860
|
}
|
|
12757
12861
|
|
|
12758
|
-
const exit =
|
|
12862
|
+
const exit = token
|
|
12863
|
+
? await monitorTerminalControlUntilChildExit({
|
|
12864
|
+
childExit,
|
|
12865
|
+
getControl: () => control,
|
|
12866
|
+
setControl: setActiveControl,
|
|
12867
|
+
connectControl: connectActiveControl,
|
|
12868
|
+
shouldReconnect: () => modeState.getMode() === 'localNative',
|
|
12869
|
+
onControlDisconnected: (closedControl) => {
|
|
12870
|
+
rememberControlState(closedControl);
|
|
12871
|
+
stderr.write('Vibelet terminal control disconnected; reconnecting so App takeover can resume.\n');
|
|
12872
|
+
},
|
|
12873
|
+
onReconnectFailure: (error) => {
|
|
12874
|
+
reportTerminalControlFailure('Vibelet terminal control reconnect failed', error);
|
|
12875
|
+
},
|
|
12876
|
+
})
|
|
12877
|
+
: await childExit;
|
|
12759
12878
|
if (modeState.getMode() === 'switchingToRemote') {
|
|
12760
12879
|
await modeState.waitUntilModeLeaves('switchingToRemote', TAKEOVER_MODE_SETTLE_TIMEOUT_MS);
|
|
12761
12880
|
}
|