vibelet 1.2.193 → 1.2.196

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.193"}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.196"}var a=l();process.stdout.write(`${a}
2
2
  `);
package/dist/vibelet.mjs CHANGED
@@ -982,7 +982,7 @@ module.exports = KanjiData
982
982
 
983
983
  /***/ }),
984
984
 
985
- /***/ 433:
985
+ /***/ 2814:
986
986
  /***/ ((__unused_webpack_module, exports) => {
987
987
 
988
988
  /**
@@ -1525,7 +1525,7 @@ const BitBuffer = __nccwpck_require__(5654)
1525
1525
  const BitMatrix = __nccwpck_require__(7765)
1526
1526
  const AlignmentPattern = __nccwpck_require__(3062)
1527
1527
  const FinderPattern = __nccwpck_require__(5837)
1528
- const MaskPattern = __nccwpck_require__(433)
1528
+ const MaskPattern = __nccwpck_require__(2814)
1529
1529
  const ECCode = __nccwpck_require__(9261)
1530
1530
  const ReedSolomonEncoder = __nccwpck_require__(4449)
1531
1531
  const Version = __nccwpck_require__(1796)
@@ -7417,7 +7417,7 @@ function inflateOnError(err) {
7417
7417
 
7418
7418
  /***/ }),
7419
7419
 
7420
- /***/ 2814:
7420
+ /***/ 433:
7421
7421
  /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
7422
7422
 
7423
7423
 
@@ -9780,7 +9780,7 @@ const { Duplex, Readable } = __nccwpck_require__(2203);
9780
9780
  const { URL } = __nccwpck_require__(7016);
9781
9781
 
9782
9782
  const PerMessageDeflate = __nccwpck_require__(7388);
9783
- const Receiver = __nccwpck_require__(2814);
9783
+ const Receiver = __nccwpck_require__(433);
9784
9784
  const Sender = __nccwpck_require__(5601);
9785
9785
  const { isBlob } = __nccwpck_require__(155);
9786
9786
 
@@ -12369,7 +12369,7 @@ function canUseSystemdUserManager({ spawnSyncImpl = node_child_process__WEBPACK_
12369
12369
 
12370
12370
  /***/ }),
12371
12371
 
12372
- /***/ 1168:
12372
+ /***/ 877:
12373
12373
  /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __nccwpck_require__) => {
12374
12374
 
12375
12375
 
@@ -12380,7 +12380,7 @@ __nccwpck_require__.d(__webpack_exports__, {
12380
12380
  gJ: () => (/* binding */ terminalControlTokenPath)
12381
12381
  });
12382
12382
 
12383
- // UNUSED EXPORTS: buildClaudeSessionIdArgs, buildClaudeTerminalArgs, buildResumeNativeArgs, cleanupClaudeTerminalHookFiles, collectProcessTreePids, connectTerminalControl, createClaudeTerminalHookFiles, createTerminalModeState, exitCodeFromChildExit, extractInitialSessionId, extractTerminalPromptPreview, formatTerminalControlScreen, hasClaudeContinueArg, hasClaudeResumePickerArg, hasClaudeSettingsArg, installTerminalSignalHandlers, monitorTerminalControlUntilChildExit, normalizeTerminalScreenForTty, requestSwitchBackWhenReady, resolveNativeAgentCommand, stopNativeChild, waitForRemoteMonitorInput
12383
+ // UNUSED EXPORTS: buildClaudeSessionIdArgs, buildClaudeTerminalArgs, buildResumeNativeArgs, captureTerminalLineDiscipline, cleanupClaudeTerminalHookFiles, collectProcessTreePids, connectTerminalControl, createClaudeTerminalHookFiles, createTerminalModeState, exitCodeFromChildExit, extractInitialSessionId, extractTerminalPromptPreview, formatTerminalControlScreen, hasClaudeContinueArg, hasClaudeResumePickerArg, hasClaudeSettingsArg, installTerminalSignalHandlers, monitorTerminalControlUntilChildExit, normalizeTerminalScreenForTty, requestSwitchBackWhenReady, resolveNativeAgentCommand, restoreTerminalAfterNativeTui, stopNativeChild, waitForRemoteMonitorInput
12384
12384
 
12385
12385
  // EXTERNAL MODULE: external "node:child_process"
12386
12386
  var external_node_child_process_ = __nccwpck_require__(1421);
@@ -12543,6 +12543,125 @@ function installTerminalSignalHandlers(
12543
12543
  };
12544
12544
  }
12545
12545
 
12546
+ ;// CONCATENATED MODULE: ./bin/terminal-state.mjs
12547
+
12548
+
12549
+ const ANSI_SHOW_CURSOR = '\x1b[?25h';
12550
+ const ANSI_RESET = '\x1b[0m';
12551
+ const ANSI_RESET_TERMINAL_INPUT_MODES = [
12552
+ '\x1b[?1000l', // X10 mouse reporting
12553
+ '\x1b[?1002l', // button-event mouse reporting
12554
+ '\x1b[?1003l', // any-event mouse reporting
12555
+ '\x1b[?1004l', // focus reporting
12556
+ '\x1b[?1006l', // SGR mouse coordinates
12557
+ '\x1b[?2004l', // bracketed paste
12558
+ '\x1b[<1u', // pop kitty keyboard enhancement flags
12559
+ '\x1b[=0u', // reset kitty keyboard enhancement flags
12560
+ '\x1b[>4;0m', // disable xterm modifyOtherKeys
12561
+ ].join('');
12562
+
12563
+ function captureTerminalLineDiscipline(
12564
+ stdin = process.stdin,
12565
+ { platform = process.platform, execFile = external_node_child_process_.execFileSync } = {},
12566
+ ) {
12567
+ if (platform === 'win32' || !stdin?.isTTY) return null;
12568
+ try {
12569
+ const state = execFile('stty', ['-g'], {
12570
+ encoding: 'utf8',
12571
+ stdio: [Number.isInteger(stdin.fd) ? stdin.fd : 0, 'pipe', 'ignore'],
12572
+ });
12573
+ return String(state).trim() || null;
12574
+ } catch {
12575
+ return null;
12576
+ }
12577
+ }
12578
+
12579
+ function restoreTerminalAfterNativeTui(
12580
+ stream,
12581
+ stdin = process.stdin,
12582
+ lineDiscipline = null,
12583
+ { platform = process.platform, execFile = external_node_child_process_.execFileSync } = {},
12584
+ ) {
12585
+ let restoredLineDiscipline = false;
12586
+ if (platform !== 'win32' && lineDiscipline && stdin?.isTTY) {
12587
+ try {
12588
+ execFile('stty', [lineDiscipline], {
12589
+ stdio: [Number.isInteger(stdin.fd) ? stdin.fd : 0, 'ignore', 'ignore'],
12590
+ });
12591
+ restoredLineDiscipline = true;
12592
+ } catch {
12593
+ // Fall through to Node's portable cooked-mode reset.
12594
+ }
12595
+ }
12596
+ if (!restoredLineDiscipline && stdin?.isTTY && typeof stdin.setRawMode === 'function') {
12597
+ try {
12598
+ stdin.setRawMode(false);
12599
+ } catch {
12600
+ // The controlling terminal may already be detached during shutdown.
12601
+ }
12602
+ }
12603
+ if (stream?.isTTY) {
12604
+ stream.write(`${ANSI_RESET_TERMINAL_INPUT_MODES}${ANSI_SHOW_CURSOR}${ANSI_RESET}`);
12605
+ }
12606
+ }
12607
+
12608
+ function installRemoteMonitorSignalListeners(processObj, finish) {
12609
+ if (!processObj || typeof processObj.once !== 'function') return () => {};
12610
+ const off =
12611
+ typeof processObj.off === 'function'
12612
+ ? processObj.off.bind(processObj)
12613
+ : typeof processObj.removeListener === 'function'
12614
+ ? processObj.removeListener.bind(processObj)
12615
+ : null;
12616
+ const onSigint = () => finish({ type: 'exit', code: 130 });
12617
+ const onSigterm = () => finish({ type: 'exit', code: 143 });
12618
+ processObj.once('SIGINT', onSigint);
12619
+ processObj.once('SIGTERM', onSigterm);
12620
+ return () => {
12621
+ if (!off) return;
12622
+ off('SIGINT', onSigint);
12623
+ off('SIGTERM', onSigterm);
12624
+ };
12625
+ }
12626
+
12627
+ function waitForRemoteMonitorInput(signalExit, stdin = process.stdin, processObj = process) {
12628
+ return new Promise((resolve) => {
12629
+ let settled = false;
12630
+ let cleanupInput = () => {};
12631
+ const cleanupSignals = installRemoteMonitorSignalListeners(processObj, (result) => finish(result));
12632
+ const finish = (result) => {
12633
+ if (settled) return;
12634
+ settled = true;
12635
+ cleanupSignals();
12636
+ cleanupInput();
12637
+ resolve(result);
12638
+ };
12639
+
12640
+ if (stdin.isTTY && typeof stdin.setRawMode === 'function') {
12641
+ const onData = (chunk) => {
12642
+ const text = Buffer.isBuffer(chunk) ? chunk.toString('utf8') : String(chunk);
12643
+ const userInput = text.replaceAll('\x1b[I', '').replaceAll('\x1b[O', '');
12644
+ if (!userInput) return;
12645
+ if (userInput.includes('\u0003')) {
12646
+ finish({ type: 'exit', code: 130 });
12647
+ return;
12648
+ }
12649
+ finish({ type: 'switchBack' });
12650
+ };
12651
+ cleanupInput = () => {
12652
+ stdin.off('data', onData);
12653
+ stdin.setRawMode(false);
12654
+ if (typeof stdin.pause === 'function') stdin.pause();
12655
+ };
12656
+ stdin.setRawMode(true);
12657
+ stdin.resume();
12658
+ stdin.on('data', onData);
12659
+ }
12660
+
12661
+ signalExit.then((code) => finish({ type: 'exit', code }));
12662
+ });
12663
+ }
12664
+
12546
12665
  ;// CONCATENATED MODULE: external "node:crypto"
12547
12666
  const external_node_crypto_namespaceObject = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("node:crypto");
12548
12667
  // EXTERNAL MODULE: external "node:fs"
@@ -12558,7 +12677,7 @@ var extension = __nccwpck_require__(387);
12558
12677
  // EXTERNAL MODULE: ../../node_modules/ws/lib/permessage-deflate.js
12559
12678
  var permessage_deflate = __nccwpck_require__(7388);
12560
12679
  // EXTERNAL MODULE: ../../node_modules/ws/lib/receiver.js
12561
- var receiver = __nccwpck_require__(2814);
12680
+ var receiver = __nccwpck_require__(433);
12562
12681
  // EXTERNAL MODULE: ../../node_modules/ws/lib/sender.js
12563
12682
  var sender = __nccwpck_require__(5601);
12564
12683
  // EXTERNAL MODULE: ../../node_modules/ws/lib/subprotocol.js
@@ -12594,6 +12713,8 @@ var websocket_server = __nccwpck_require__(3261);
12594
12713
 
12595
12714
 
12596
12715
 
12716
+
12717
+
12597
12718
  const terminalControlTokenPath = (0,external_node_path_.join)((0,external_node_os_.homedir)(), '.vibelet', 'runtime', 'terminal-control-token');
12598
12719
 
12599
12720
  const terminal_wrapper_TAKEOVER_STOP_TIMEOUT_MS = 3000;
@@ -12604,8 +12725,7 @@ const TERMINAL_CONTROL_RECONNECT_DELAY_MS = 1000;
12604
12725
  const CLAUDE_HOOK_SECRET_HEADER = 'x-vibelet-claude-hook-secret';
12605
12726
  const ANSI_CLEAR_SCREEN = '\x1b[2J\x1b[H';
12606
12727
  const ANSI_HIDE_CURSOR = '\x1b[?25l';
12607
- const ANSI_SHOW_CURSOR = '\x1b[?25h';
12608
- const ANSI_RESET = '\x1b[0m';
12728
+ const terminal_wrapper_ANSI_RESET = '\x1b[0m';
12609
12729
  const ANSI_BOLD = '\x1b[1m';
12610
12730
  const ANSI_CYAN = '\x1b[36m';
12611
12731
  const ANSI_GREEN = '\x1b[32m';
@@ -13022,7 +13142,7 @@ function padRight(text, width) {
13022
13142
 
13023
13143
  function colorize(enabled, style, text) {
13024
13144
  if (!enabled || !style) return text;
13025
- return `${style}${text}${ANSI_RESET}`;
13145
+ return `${style}${text}${terminal_wrapper_ANSI_RESET}`;
13026
13146
  }
13027
13147
 
13028
13148
  function getTerminalControlScreenTone(title) {
@@ -13143,65 +13263,6 @@ function renderTerminalControlScreen(stream, options) {
13143
13263
  stream.write(`\n${screen}`);
13144
13264
  }
13145
13265
 
13146
- function restoreTerminalCursor(stream) {
13147
- if (stream?.isTTY) stream.write(`${ANSI_SHOW_CURSOR}${ANSI_RESET}`);
13148
- }
13149
-
13150
- function installRemoteMonitorSignalListeners(processObj, finish) {
13151
- if (!processObj || typeof processObj.once !== 'function') return () => {};
13152
- const off =
13153
- typeof processObj.off === 'function'
13154
- ? processObj.off.bind(processObj)
13155
- : typeof processObj.removeListener === 'function'
13156
- ? processObj.removeListener.bind(processObj)
13157
- : null;
13158
- const onSigint = () => finish({ type: 'exit', code: 130 });
13159
- const onSigterm = () => finish({ type: 'exit', code: 143 });
13160
- processObj.once('SIGINT', onSigint);
13161
- processObj.once('SIGTERM', onSigterm);
13162
- return () => {
13163
- if (!off) return;
13164
- off('SIGINT', onSigint);
13165
- off('SIGTERM', onSigterm);
13166
- };
13167
- }
13168
-
13169
- function waitForRemoteMonitorInput(signalExit, stdin = process.stdin, processObj = process) {
13170
- return new Promise((resolve) => {
13171
- let settled = false;
13172
- let cleanupInput = () => {};
13173
- const cleanupSignals = installRemoteMonitorSignalListeners(processObj, (result) => finish(result));
13174
- const finish = (result) => {
13175
- if (settled) return;
13176
- settled = true;
13177
- cleanupSignals();
13178
- cleanupInput();
13179
- resolve(result);
13180
- };
13181
-
13182
- if (stdin.isTTY && typeof stdin.setRawMode === 'function') {
13183
- const onData = (chunk) => {
13184
- const text = Buffer.isBuffer(chunk) ? chunk.toString('utf8') : String(chunk);
13185
- if (text.includes('\u0003')) {
13186
- finish({ type: 'exit', code: 130 });
13187
- return;
13188
- }
13189
- finish({ type: 'switchBack' });
13190
- };
13191
- cleanupInput = () => {
13192
- stdin.off('data', onData);
13193
- stdin.setRawMode(false);
13194
- if (typeof stdin.pause === 'function') stdin.pause();
13195
- };
13196
- stdin.setRawMode(true);
13197
- stdin.resume();
13198
- stdin.on('data', onData);
13199
- }
13200
-
13201
- signalExit.then((code) => finish({ type: 'exit', code }));
13202
- });
13203
- }
13204
-
13205
13266
  async function waitForRetryOrSignal(signalExit, delayMs) {
13206
13267
  let timer;
13207
13268
  const retry = new Promise((resolve) => {
@@ -13311,6 +13372,7 @@ async function connectTerminalControl({
13311
13372
  initialSessionId,
13312
13373
  requestedTerminalId,
13313
13374
  taskPreview,
13375
+ terminalLineDiscipline,
13314
13376
  getMode,
13315
13377
  setMode,
13316
13378
  stderr = process.stderr,
@@ -13389,6 +13451,7 @@ async function connectTerminalControl({
13389
13451
  sendResponse(msg.id, false, undefined, 'failed_to_stop_native_terminal');
13390
13452
  return;
13391
13453
  }
13454
+ restoreTerminalAfterNativeTui(stderr, process.stdin, terminalLineDiscipline);
13392
13455
  setMode('remoteDaemon');
13393
13456
  await sendSession('remoteDaemon');
13394
13457
  renderTerminalControlScreen(stderr, {
@@ -13544,6 +13607,7 @@ async function runManagedNativeTerminal({
13544
13607
  }) {
13545
13608
  const command = resolveNativeAgentCommand(agent, env);
13546
13609
  const token = readTerminalControlToken();
13610
+ const terminalLineDiscipline = captureTerminalLineDiscipline();
13547
13611
  let initialSessionId = extractInitialSessionId(agent, args);
13548
13612
  let nativeArgs = args;
13549
13613
  const taskPreview = extractTerminalPromptPreview(agent, args);
@@ -13603,6 +13667,7 @@ async function runManagedNativeTerminal({
13603
13667
  initialSessionId,
13604
13668
  requestedTerminalId: terminalId ?? claudeHookFiles?.terminalId,
13605
13669
  taskPreview,
13670
+ terminalLineDiscipline,
13606
13671
  getMode: () => modeState.getMode(),
13607
13672
  setMode: (nextMode) => modeState.setMode(nextMode),
13608
13673
  stderr,
@@ -13661,7 +13726,7 @@ async function runManagedNativeTerminal({
13661
13726
 
13662
13727
  const monitorAction = await waitForRemoteMonitorInput(signalHandlers.signalExit);
13663
13728
  if (monitorAction.type === 'exit') {
13664
- restoreTerminalCursor(stderr);
13729
+ restoreTerminalAfterNativeTui(stderr, process.stdin, terminalLineDiscipline);
13665
13730
  return monitorAction.code;
13666
13731
  }
13667
13732
 
@@ -13717,7 +13782,7 @@ async function runManagedNativeTerminal({
13717
13782
  },
13718
13783
  });
13719
13784
  if (typeof switchBack.exitCode === 'number') {
13720
- restoreTerminalCursor(stderr);
13785
+ restoreTerminalAfterNativeTui(stderr, process.stdin, terminalLineDiscipline);
13721
13786
  return switchBack.exitCode;
13722
13787
  }
13723
13788
  if (!switchBack.ok) {
@@ -13737,6 +13802,7 @@ async function runManagedNativeTerminal({
13737
13802
  continue;
13738
13803
  }
13739
13804
  modeState.setMode('localNative');
13805
+ restoreTerminalAfterNativeTui(stderr, process.stdin, terminalLineDiscipline);
13740
13806
  renderTerminalControlScreen(stderr, {
13741
13807
  title: 'NATIVE TERMINAL UI STARTING',
13742
13808
  subtitle: 'Vibelet app control has been released',
@@ -13758,7 +13824,7 @@ async function runManagedNativeTerminal({
13758
13824
  argv = [command, ...nativeArgs];
13759
13825
  }
13760
13826
  } finally {
13761
- restoreTerminalCursor(stderr);
13827
+ restoreTerminalAfterNativeTui(stderr, process.stdin, terminalLineDiscipline);
13762
13828
  control?.close();
13763
13829
  signalHandlers?.restore();
13764
13830
  cleanupClaudeTerminalHookFiles(claudeHookFiles);
@@ -14260,7 +14326,8 @@ function describeLaunchctlResult(result) {
14260
14326
  /* harmony export */ YP: () => (/* binding */ createCompactPairingPayload),
14261
14327
  /* harmony export */ dE: () => (/* binding */ findUnsafeCleartextHosts),
14262
14328
  /* harmony export */ mp: () => (/* binding */ applyRelayUrlToPairingPayload),
14263
- /* harmony export */ uR: () => (/* binding */ formatConnectionSummary)
14329
+ /* harmony export */ uR: () => (/* binding */ formatConnectionSummary),
14330
+ /* harmony export */ u_: () => (/* binding */ createScannablePairingPayload)
14264
14331
  /* harmony export */ });
14265
14332
  /* unused harmony exports normalizeHostValue, isIpv4Host, isTailscaleHost, isSharedIpv4Host, isLocalNetworkHost, isLoopbackHost, isPlainLocalHostname, isTrustedCleartextHost, parseCommaSeparatedHosts, isQuickTunnelHost, buildLegacyConnection, formatConnectionSourceLabel, buildConnectionHttpUrl, isPreferredWebUiHost, encodePairingPayloadForUrlFragment */
14266
14333
  function normalizeHostValue(host) {
@@ -14529,6 +14596,59 @@ function createCompactPairingPayload(pairingPayload) {
14529
14596
  return compactPayload;
14530
14597
  }
14531
14598
 
14599
+ /**
14600
+ * Keep camera-scanned QR codes small enough for reliable terminal capture.
14601
+ * The canonical target is sufficient for the initial /pair/create request;
14602
+ * that response returns the daemon's complete connection list for subsequent
14603
+ * reconnects. Preserve the primary tuple only when h/p cannot represent the
14604
+ * transport capability on its own.
14605
+ */
14606
+ function createScannablePairingPayload(pairingPayload) {
14607
+ const compactPayload = {
14608
+ t: 'vp',
14609
+ d: pairingPayload.daemonId,
14610
+ n: pairingPayload.displayName,
14611
+ h: pairingPayload.canonicalHost,
14612
+ p: pairingPayload.port,
14613
+ c: pairingPayload.pairNonce,
14614
+ e: pairingPayload.expiresAt,
14615
+ };
14616
+ const connections = normalizePairingConnections(pairingPayload);
14617
+ const [primary] = connections;
14618
+ const needsExplicitTransport =
14619
+ primary && (Boolean(primary.tailcat) || (primary.secure === true && primary.port !== 443));
14620
+ const compactFallback = !needsExplicitTransport
14621
+ ? connections
14622
+ .slice(1)
14623
+ .find(
14624
+ (target) =>
14625
+ primary?.secure !== true &&
14626
+ target.kind === 'direct' &&
14627
+ target.secure !== true &&
14628
+ !target.tailcat &&
14629
+ target.port === primary.port,
14630
+ )
14631
+ : undefined;
14632
+ if (compactFallback) {
14633
+ compactPayload.f = [compactFallback.host];
14634
+ }
14635
+ if (needsExplicitTransport) {
14636
+ const tuple = [
14637
+ primary.kind,
14638
+ primary.host,
14639
+ primary.port,
14640
+ primary.source,
14641
+ primary.stability,
14642
+ primary.secure === true,
14643
+ ];
14644
+ if (primary.tailcat) {
14645
+ tuple.push(primary.tailcat.serverAddress, primary.tailcat.remotePort);
14646
+ }
14647
+ compactPayload.o = [tuple];
14648
+ }
14649
+ return compactPayload;
14650
+ }
14651
+
14532
14652
  function formatConnectionSourceLabel(source) {
14533
14653
  switch (source) {
14534
14654
  case 'configured_relay':
@@ -14600,6 +14720,47 @@ function buildWebUiUrl(target, pairingPayload) {
14600
14720
  }
14601
14721
 
14602
14722
 
14723
+ /***/ }),
14724
+
14725
+ /***/ 4021:
14726
+ /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __nccwpck_require__) => {
14727
+
14728
+ /* harmony export */ __nccwpck_require__.d(__webpack_exports__, {
14729
+ /* harmony export */ p: () => (/* binding */ writePairingOutput)
14730
+ /* harmony export */ });
14731
+ /* harmony import */ var node_fs__WEBPACK_IMPORTED_MODULE_0__ = __nccwpck_require__(3024);
14732
+ /* harmony import */ var qrcode__WEBPACK_IMPORTED_MODULE_1__ = __nccwpck_require__(7514);
14733
+ /* harmony import */ var _vibelet_pairing_connections_mjs__WEBPACK_IMPORTED_MODULE_2__ = __nccwpck_require__(7721);
14734
+
14735
+
14736
+
14737
+
14738
+ async function writePairingOutput(pairingPayload, { directory, pairingCodePath, pairingQrPngPath, stdout }) {
14739
+ const payload = JSON.stringify((0,_vibelet_pairing_connections_mjs__WEBPACK_IMPORTED_MODULE_2__/* .createCompactPairingPayload */ .YP)(pairingPayload));
14740
+ const qrPayload = JSON.stringify((0,_vibelet_pairing_connections_mjs__WEBPACK_IMPORTED_MODULE_2__/* .createScannablePairingPayload */ .u_)(pairingPayload));
14741
+ const deepLink = (0,_vibelet_pairing_connections_mjs__WEBPACK_IMPORTED_MODULE_2__/* .buildPairingDeepLink */ .N7)(payload);
14742
+ (0,node_fs__WEBPACK_IMPORTED_MODULE_0__.mkdirSync)(directory, { recursive: true });
14743
+ await qrcode__WEBPACK_IMPORTED_MODULE_1__.toFile(pairingQrPngPath, qrPayload, {
14744
+ type: 'png',
14745
+ errorCorrectionLevel: 'M',
14746
+ margin: 4,
14747
+ scale: 8,
14748
+ });
14749
+ const qr = await qrcode__WEBPACK_IMPORTED_MODULE_1__.toString(qrPayload, {
14750
+ type: 'utf8',
14751
+ errorCorrectionLevel: 'M',
14752
+ margin: 4,
14753
+ });
14754
+ (0,node_fs__WEBPACK_IMPORTED_MODULE_0__.writeFileSync)(pairingCodePath, `${payload}\n`, 'utf8');
14755
+ stdout.write(`\nScan this QR code with the Vibelet app:\n\n\x1b[47m\x1b[30m${qr}\x1b[0m\n`);
14756
+ stdout.write(`If Vibelet app can't scan the terminal QR, open this PNG instead:\n${pairingQrPngPath}\n`);
14757
+ stdout.write(`This pairing QR expires at: ${pairingPayload.expiresAt}\n`);
14758
+ stdout.write(`If this device can't scan, paste this pairing code in Vibelet:\n${payload}\n`);
14759
+ stdout.write(`Pairing code saved to:\n${pairingCodePath}\n`);
14760
+ stdout.write(`Or open this deep link on a device with Vibelet installed:\n${deepLink}\n`);
14761
+ }
14762
+
14763
+
14603
14764
  /***/ }),
14604
14765
 
14605
14766
  /***/ 4:
@@ -14870,18 +15031,18 @@ __nccwpck_require__.a(__webpack_module__, async (__webpack_handle_async_dependen
14870
15031
  /* harmony import */ var node_os__WEBPACK_IMPORTED_MODULE_3__ = __nccwpck_require__(8161);
14871
15032
  /* harmony import */ var node_path__WEBPACK_IMPORTED_MODULE_4__ = __nccwpck_require__(6760);
14872
15033
  /* harmony import */ var node_url__WEBPACK_IMPORTED_MODULE_5__ = __nccwpck_require__(3136);
14873
- /* harmony import */ var qrcode__WEBPACK_IMPORTED_MODULE_6__ = __nccwpck_require__(7514);
14874
15034
  /* harmony import */ var _vibelet_cli_args_mjs__WEBPACK_IMPORTED_MODULE_17__ = __nccwpck_require__(6927);
14875
- /* harmony import */ var _cloudflared_tunnel_manager_mjs__WEBPACK_IMPORTED_MODULE_7__ = __nccwpck_require__(2755);
14876
- /* harmony import */ var _vibelet_cloudflare_runtime_mjs__WEBPACK_IMPORTED_MODULE_8__ = __nccwpck_require__(3869);
15035
+ /* harmony import */ var _cloudflared_tunnel_manager_mjs__WEBPACK_IMPORTED_MODULE_6__ = __nccwpck_require__(2755);
15036
+ /* harmony import */ var _vibelet_cloudflare_runtime_mjs__WEBPACK_IMPORTED_MODULE_7__ = __nccwpck_require__(3869);
14877
15037
  /* harmony import */ var _vibelet_launchd_mjs__WEBPACK_IMPORTED_MODULE_13__ = __nccwpck_require__(1010);
14878
- /* harmony import */ var _linux_systemd_mjs__WEBPACK_IMPORTED_MODULE_9__ = __nccwpck_require__(4217);
15038
+ /* harmony import */ var _linux_systemd_mjs__WEBPACK_IMPORTED_MODULE_8__ = __nccwpck_require__(4217);
14879
15039
  /* harmony import */ var _vibelet_stop_logic_mjs__WEBPACK_IMPORTED_MODULE_14__ = __nccwpck_require__(6274);
14880
15040
  /* harmony import */ var _vibelet_help_mjs__WEBPACK_IMPORTED_MODULE_16__ = __nccwpck_require__(4162);
14881
- /* harmony import */ var _vibelet_tailcat_config_mjs__WEBPACK_IMPORTED_MODULE_10__ = __nccwpck_require__(5798);
15041
+ /* harmony import */ var _vibelet_tailcat_config_mjs__WEBPACK_IMPORTED_MODULE_9__ = __nccwpck_require__(5798);
14882
15042
  /* harmony import */ var _vibelet_runtime_policy_mjs__WEBPACK_IMPORTED_MODULE_12__ = __nccwpck_require__(4);
14883
- /* harmony import */ var _terminal_wrapper_mjs__WEBPACK_IMPORTED_MODULE_11__ = __nccwpck_require__(1168);
15043
+ /* harmony import */ var _terminal_wrapper_mjs__WEBPACK_IMPORTED_MODULE_10__ = __nccwpck_require__(877);
14884
15044
  /* harmony import */ var _vibelet_pairing_connections_mjs__WEBPACK_IMPORTED_MODULE_15__ = __nccwpck_require__(7721);
15045
+ /* harmony import */ var _vibelet_pairing_output_mjs__WEBPACK_IMPORTED_MODULE_11__ = __nccwpck_require__(4021);
14885
15046
 
14886
15047
 
14887
15048
 
@@ -14916,12 +15077,12 @@ const runtimeDir = (0,node_path__WEBPACK_IMPORTED_MODULE_4__.join)(vibeletDir, '
14916
15077
  const runtimeCurrentDir = (0,node_path__WEBPACK_IMPORTED_MODULE_4__.join)(runtimeDir, 'current');
14917
15078
  const runtimeMetadataPath = (0,node_path__WEBPACK_IMPORTED_MODULE_4__.join)(runtimeCurrentDir, 'runtime.json');
14918
15079
  const runtimeDaemonEntryPath = (0,node_path__WEBPACK_IMPORTED_MODULE_4__.join)(runtimeCurrentDir, 'dist', 'index.cjs');
14919
- const runtimeTerminalControlTokenPath = _terminal_wrapper_mjs__WEBPACK_IMPORTED_MODULE_11__/* .terminalControlTokenPath */ .gJ;
15080
+ const runtimeTerminalControlTokenPath = _terminal_wrapper_mjs__WEBPACK_IMPORTED_MODULE_10__/* .terminalControlTokenPath */ .gJ;
14920
15081
  const stdoutLogPath = (0,node_path__WEBPACK_IMPORTED_MODULE_4__.join)(logDir, 'daemon.stdout.log');
14921
15082
  const stderrLogPath = (0,node_path__WEBPACK_IMPORTED_MODULE_4__.join)(logDir, 'daemon.stderr.log');
14922
15083
  const pidFilePath = (0,node_path__WEBPACK_IMPORTED_MODULE_4__.join)(vibeletDir, 'daemon.pid');
14923
- const relayConfig = (0,_vibelet_cloudflare_runtime_mjs__WEBPACK_IMPORTED_MODULE_8__/* .createRelayConfigStore */ .T7)((0,node_path__WEBPACK_IMPORTED_MODULE_4__.join)(vibeletDir, 'relay.json'));
14924
- const tailcatConfig = (0,_vibelet_tailcat_config_mjs__WEBPACK_IMPORTED_MODULE_10__/* .createTailcatConfigStore */ .S)((0,node_path__WEBPACK_IMPORTED_MODULE_4__.join)(vibeletDir, 'tailcat.json'), vibeletDir);
15084
+ const relayConfig = (0,_vibelet_cloudflare_runtime_mjs__WEBPACK_IMPORTED_MODULE_7__/* .createRelayConfigStore */ .T7)((0,node_path__WEBPACK_IMPORTED_MODULE_4__.join)(vibeletDir, 'relay.json'));
15085
+ const tailcatConfig = (0,_vibelet_tailcat_config_mjs__WEBPACK_IMPORTED_MODULE_9__/* .createTailcatConfigStore */ .S)((0,node_path__WEBPACK_IMPORTED_MODULE_4__.join)(vibeletDir, 'tailcat.json'), vibeletDir);
14925
15086
  const tunnelStatePath = (0,node_path__WEBPACK_IMPORTED_MODULE_4__.join)(vibeletDir, 'tunnel.json');
14926
15087
  const cloudflaredUpdateStatePath = (0,node_path__WEBPACK_IMPORTED_MODULE_4__.join)(vibeletDir, 'cloudflared-update.json');
14927
15088
  const updateCheckPath = (0,node_path__WEBPACK_IMPORTED_MODULE_4__.join)(vibeletDir, 'update-check.json');
@@ -15409,10 +15570,10 @@ function createLinuxBackend() {
15409
15570
  return [result?.stderr, result?.stdout].filter(Boolean).join('\n').trim();
15410
15571
  }
15411
15572
 
15412
- let useSystemd = (0,_linux_systemd_mjs__WEBPACK_IMPORTED_MODULE_9__/* .canUseSystemdUserManager */ .X)();
15573
+ let useSystemd = (0,_linux_systemd_mjs__WEBPACK_IMPORTED_MODULE_8__/* .canUseSystemdUserManager */ .X)();
15413
15574
 
15414
15575
  function demoteToDetachedIfSystemdUnavailable(result) {
15415
- if (!(0,_linux_systemd_mjs__WEBPACK_IMPORTED_MODULE_9__/* .isSystemdUserManagerUnavailable */ .a)(resultOutput(result))) {
15576
+ if (!(0,_linux_systemd_mjs__WEBPACK_IMPORTED_MODULE_8__/* .isSystemdUserManagerUnavailable */ .a)(resultOutput(result))) {
15416
15577
  return false;
15417
15578
  }
15418
15579
  useSystemd = false;
@@ -15711,7 +15872,7 @@ function isDaemonStartCommand(command) {
15711
15872
  }
15712
15873
 
15713
15874
  function retireTrackedQuickTunnel({ required = false } = {}) {
15714
- return (0,_vibelet_cloudflare_runtime_mjs__WEBPACK_IMPORTED_MODULE_8__/* .retireTrackedQuickTunnel */ .zj)({
15875
+ return (0,_vibelet_cloudflare_runtime_mjs__WEBPACK_IMPORTED_MODULE_7__/* .retireTrackedQuickTunnel */ .zj)({
15715
15876
  tunnelStatePath,
15716
15877
  isAlive: isProcessAlive,
15717
15878
  required,
@@ -15764,26 +15925,12 @@ function validateExplicitCleartextHosts({ hostArg, fallbackHostsArg }) {
15764
15925
  }
15765
15926
 
15766
15927
  async function printPairingQr(pairingPayload) {
15767
- const payload = JSON.stringify((0,_vibelet_pairing_connections_mjs__WEBPACK_IMPORTED_MODULE_15__/* .createCompactPairingPayload */ .YP)(pairingPayload));
15768
- const deepLink = (0,_vibelet_pairing_connections_mjs__WEBPACK_IMPORTED_MODULE_15__/* .buildPairingDeepLink */ .N7)(payload);
15769
- (0,node_fs__WEBPACK_IMPORTED_MODULE_1__.mkdirSync)(vibeletDir, { recursive: true });
15770
- await qrcode__WEBPACK_IMPORTED_MODULE_6__.toFile(pairingQrPngPath, payload, {
15771
- type: 'png',
15772
- errorCorrectionLevel: 'M',
15773
- margin: 1,
15774
- scale: 4,
15775
- });
15776
- const qr = await qrcode__WEBPACK_IMPORTED_MODULE_6__.toString(payload, {
15777
- type: 'terminal',
15778
- small: true,
15779
- errorCorrectionLevel: 'M',
15928
+ await (0,_vibelet_pairing_output_mjs__WEBPACK_IMPORTED_MODULE_11__/* .writePairingOutput */ .p)(pairingPayload, {
15929
+ directory: vibeletDir,
15930
+ pairingCodePath,
15931
+ pairingQrPngPath,
15932
+ stdout: process.stdout,
15780
15933
  });
15781
- (0,node_fs__WEBPACK_IMPORTED_MODULE_1__.writeFileSync)(pairingCodePath, `${payload}\n`, 'utf8');
15782
- process.stdout.write(`\nScan this QR code with the Vibelet app:\n\n${qr}\n`);
15783
- process.stdout.write(`If Vibelet app can't scan the terminal QR, open this PNG instead:\n${pairingQrPngPath}\n`);
15784
- process.stdout.write(`If this device can't scan, paste this pairing code in Vibelet:\n${payload}\n`);
15785
- process.stdout.write(`Pairing code saved to:\n${pairingCodePath}\n`);
15786
- process.stdout.write(`Or open this deep link on a device with Vibelet installed:\n${deepLink}\n`);
15787
15934
  }
15788
15935
 
15789
15936
  // ─── Commands ───────────────────────────────────────────────────────────────────
@@ -15892,7 +16039,7 @@ function parseCommandArg(argv) {
15892
16039
  }
15893
16040
 
15894
16041
  async function tryUpdateRunningDaemonRelay(relayUrl) {
15895
- return await (0,_vibelet_cloudflare_runtime_mjs__WEBPACK_IMPORTED_MODULE_8__/* .tryUpdateRunningDaemonRelay */ .BT)({ port, relayUrl, probeHealth });
16042
+ return await (0,_vibelet_cloudflare_runtime_mjs__WEBPACK_IMPORTED_MODULE_7__/* .tryUpdateRunningDaemonRelay */ .BT)({ port, relayUrl, probeHealth });
15896
16043
  }
15897
16044
 
15898
16045
  async function main() {
@@ -15924,10 +16071,10 @@ async function main() {
15924
16071
  return;
15925
16072
  }
15926
16073
 
15927
- if ((0,_terminal_wrapper_mjs__WEBPACK_IMPORTED_MODULE_11__/* .isTerminalAgentCommand */ .$c)(command)) {
16074
+ if ((0,_terminal_wrapper_mjs__WEBPACK_IMPORTED_MODULE_10__/* .isTerminalAgentCommand */ .$c)(command)) {
15928
16075
  const backend = resolveBackend();
15929
16076
  await ensureDaemonForTerminalControl(backend);
15930
- process.exitCode = await (0,_terminal_wrapper_mjs__WEBPACK_IMPORTED_MODULE_11__/* .runManagedNativeTerminal */ .WA)({
16077
+ process.exitCode = await (0,_terminal_wrapper_mjs__WEBPACK_IMPORTED_MODULE_10__/* .runManagedNativeTerminal */ .WA)({
15931
16078
  agent: command,
15932
16079
  args: process.argv.slice(3),
15933
16080
  port,
@@ -16030,7 +16177,7 @@ async function main() {
16030
16177
  }
16031
16178
 
16032
16179
  if (shouldManageTunnel) {
16033
- const managedTunnel = await (0,_vibelet_cloudflare_runtime_mjs__WEBPACK_IMPORTED_MODULE_8__/* .prepareManagedQuickTunnel */ .kS)({
16180
+ const managedTunnel = await (0,_vibelet_cloudflare_runtime_mjs__WEBPACK_IMPORTED_MODULE_7__/* .prepareManagedQuickTunnel */ .kS)({
16034
16181
  force: forceFlag,
16035
16182
  port,
16036
16183
  logDir,
@@ -16093,7 +16240,7 @@ async function main() {
16093
16240
  if (command === 'status') {
16094
16241
  process.stdout.write(`Service (${backend.name}): ${backend.statusLabel()}\n`);
16095
16242
  process.stdout.write(`Runtime: ${(0,node_fs__WEBPACK_IMPORTED_MODULE_1__.existsSync)(runtimeDaemonEntryPath) ? runtimeDaemonEntryPath : 'not installed'}\n`);
16096
- const tunnelState = await (0,_cloudflared_tunnel_manager_mjs__WEBPACK_IMPORTED_MODULE_7__/* .getAliveManagedQuickTunnel */ .M)({
16243
+ const tunnelState = await (0,_cloudflared_tunnel_manager_mjs__WEBPACK_IMPORTED_MODULE_6__/* .getAliveManagedQuickTunnel */ .M)({
16097
16244
  tunnelStatePath,
16098
16245
  isAlive: isProcessAlive,
16099
16246
  managerId: 'vibelet-cli',
@@ -16245,7 +16392,11 @@ async function main() {
16245
16392
  const runningDriver = normalizeDriver(existingHealth.claudeDriverMode);
16246
16393
  const driverMismatch = requestedDriver !== null && runningDriver !== requestedDriver;
16247
16394
  const needsRestart = Boolean(isOutdated) || driverMismatch;
16248
- if (needsRestart && activeSessions === 0 && !canApplyConnectionConfigWithoutRestart) {
16395
+ // A relay refresh is only safe when it is applied by the daemon that will
16396
+ // actually serve the new pairing QR. If the installed runtime is older,
16397
+ // restart it before printing the QR; otherwise the QR can advertise a new
16398
+ // relay while the running daemon remains bound to the old one.
16399
+ if (needsRestart && activeSessions === 0) {
16249
16400
  process.stdout.write(
16250
16401
  isOutdated
16251
16402
  ? `Daemon is running v${runningVersion}, CLI is v${packageJson.version}. Restarting daemon to upgrade...\n`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibelet",
3
- "version": "1.2.193",
3
+ "version": "1.2.196",
4
4
  "description": "Cross-platform CLI for installing and running the Vibelet daemon",
5
5
  "homepage": "https://vibelet.icu",
6
6
  "files": [