@rayu-dev/rayu-cli 1.4.478 → 1.4.480

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.
Files changed (2) hide show
  1. package/dist/rayu.js +745 -342
  2. package/package.json +1 -1
package/dist/rayu.js CHANGED
@@ -149022,7 +149022,7 @@ var init_isEqual = __esm(() => {
149022
149022
 
149023
149023
  // src/utils/userAgent.ts
149024
149024
  function getRayuUserAgent() {
149025
- return `rayu/${"1.4.478"}`;
149025
+ return `rayu/${"1.4.480"}`;
149026
149026
  }
149027
149027
  var getClaudeCodeUserAgent;
149028
149028
  var init_userAgent = __esm(() => {
@@ -149048,7 +149048,7 @@ function getUserAgent() {
149048
149048
  const clientApp = process.env.RAYU_AGENT_SDK_CLIENT_APP ? `, client-app/${process.env.RAYU_AGENT_SDK_CLIENT_APP}` : "";
149049
149049
  const workload = getWorkload();
149050
149050
  const workloadSuffix = workload ? `, workload/${workload}` : "";
149051
- return `rayu/${"1.4.478"} (${"external"}, ${process.env.RAYU_ENTRYPOINT ?? "cli"}${agentSdkVersion}${clientApp}${workloadSuffix})`;
149051
+ return `rayu/${"1.4.480"} (${"external"}, ${process.env.RAYU_ENTRYPOINT ?? "cli"}${agentSdkVersion}${clientApp}${workloadSuffix})`;
149052
149052
  }
149053
149053
  function getMCPUserAgent() {
149054
149054
  const parts = [];
@@ -149062,7 +149062,7 @@ function getMCPUserAgent() {
149062
149062
  parts.push(`client-app/${process.env.RAYU_AGENT_SDK_CLIENT_APP}`);
149063
149063
  }
149064
149064
  const suffix = parts.length > 0 ? ` (${parts.join(", ")})` : "";
149065
- return `rayu/${"1.4.478"}${suffix}`;
149065
+ return `rayu/${"1.4.480"}${suffix}`;
149066
149066
  }
149067
149067
  function getWebFetchUserAgent() {
149068
149068
  return `Rayu-User (${getRayuUserAgent()})`;
@@ -205506,7 +205506,7 @@ function getAttributionHeader(fingerprint) {
205506
205506
  if (!isAttributionHeaderEnabled()) {
205507
205507
  return "";
205508
205508
  }
205509
- const version2 = `${"1.4.478"}.${fingerprint}`;
205509
+ const version2 = `${"1.4.480"}.${fingerprint}`;
205510
205510
  const entrypoint = process.env.CLAUDE_CODE_ENTRYPOINT ?? "unknown";
205511
205511
  const cch = "";
205512
205512
  const workload = getWorkload();
@@ -259477,7 +259477,7 @@ var init_metadata = __esm(() => {
259477
259477
  COMPOUND_OPERATOR_REGEX = /\s*(?:&&|\|\||[;|])\s*/;
259478
259478
  WHITESPACE_REGEX = /\s+/;
259479
259479
  getVersionBase = memoize_default(() => {
259480
- const match = "1.4.478".match(/^\d+\.\d+\.\d+(?:-[a-z]+)?/);
259480
+ const match = "1.4.480".match(/^\d+\.\d+\.\d+(?:-[a-z]+)?/);
259481
259481
  return match ? match[0] : undefined;
259482
259482
  });
259483
259483
  buildEnvContext = memoize_default(async () => {
@@ -259516,7 +259516,7 @@ var init_metadata = __esm(() => {
259516
259516
  },
259517
259517
  isGithubAction: isEnvTruthy(process.env.GITHUB_ACTIONS),
259518
259518
  isRayuAction: isEnvTruthy(process.env.RAYU_ACTION),
259519
- version: "1.4.478",
259519
+ version: "1.4.480",
259520
259520
  versionBase: getVersionBase(),
259521
259521
  buildTime: "",
259522
259522
  deploymentEnvironment: env3.detectDeploymentEnvironment(),
@@ -291632,7 +291632,7 @@ function getTelemetryAttributes() {
291632
291632
  attributes["session.id"] = sessionId;
291633
291633
  }
291634
291634
  if (shouldIncludeAttribute("OTEL_METRICS_INCLUDE_VERSION")) {
291635
- attributes["app.version"] = "1.4.478";
291635
+ attributes["app.version"] = "1.4.480";
291636
291636
  }
291637
291637
  const oauthAccount = getOauthAccountInfo();
291638
291638
  if (oauthAccount) {
@@ -401989,7 +401989,7 @@ function getInstallationEnv() {
401989
401989
  return;
401990
401990
  }
401991
401991
  function getClaudeCodeVersion() {
401992
- return "1.4.478";
401992
+ return "1.4.480";
401993
401993
  }
401994
401994
  async function getInstalledVSCodeExtensionVersion(command) {
401995
401995
  const { stdout } = await execFileNoThrow(command, ["--list-extensions", "--show-versions"], {
@@ -407227,7 +407227,7 @@ async function setupSdkMcpClients(sdkMcpConfigs, sendMcpMessage) {
407227
407227
  const client3 = new Client({
407228
407228
  name: "claude-code",
407229
407229
  title: "RAYU",
407230
- version: "1.4.478",
407230
+ version: "1.4.480",
407231
407231
  description: "Anthropic's agentic coding tool",
407232
407232
  websiteUrl: PRODUCT_URL
407233
407233
  }, {
@@ -407544,7 +407544,7 @@ var init_client7 = __esm(() => {
407544
407544
  const client3 = new Client({
407545
407545
  name: "claude-code",
407546
407546
  title: "RAYU",
407547
- version: "1.4.478",
407547
+ version: "1.4.480",
407548
407548
  description: "Anthropic's agentic coding tool",
407549
407549
  websiteUrl: PRODUCT_URL
407550
407550
  }, {
@@ -422363,7 +422363,7 @@ function computeFingerprint(messageText, version2) {
422363
422363
  }
422364
422364
  function computeFingerprintFromMessages(messages) {
422365
422365
  const firstMessageText = extractFirstMessageText(messages);
422366
- return computeFingerprint(firstMessageText, "1.4.478");
422366
+ return computeFingerprint(firstMessageText, "1.4.480");
422367
422367
  }
422368
422368
  var FINGERPRINT_SALT = "59cf53e54c78";
422369
422369
  var init_fingerprint = () => {};
@@ -422405,7 +422405,7 @@ async function sideQuery(opts) {
422405
422405
  betas.push(STRUCTURED_OUTPUTS_BETA_HEADER);
422406
422406
  }
422407
422407
  const messageText = extractFirstUserMessageText(messages);
422408
- const fingerprint = computeFingerprint(messageText, "1.4.478");
422408
+ const fingerprint = computeFingerprint(messageText, "1.4.480");
422409
422409
  const attributionHeader = getAttributionHeader(fingerprint);
422410
422410
  const systemBlocks = [
422411
422411
  attributionHeader ? { type: "text", text: attributionHeader } : null,
@@ -510351,12 +510351,16 @@ function coerceAskUserQuestionInput(input) {
510351
510351
  const question = firstNonEmptyString(q2, ASK_Q_TEXT_KEYS);
510352
510352
  if (question !== undefined)
510353
510353
  q2.question = question;
510354
+ else
510355
+ delete q2.question;
510354
510356
  let header = firstNonEmptyString(q2, ASK_Q_HEADER_KEYS);
510355
510357
  if (header === undefined && question !== undefined) {
510356
510358
  header = deriveAskQuestionHeader(question, ASK_USER_QUESTION_TOOL_CHIP_WIDTH);
510357
510359
  }
510358
510360
  if (header !== undefined)
510359
510361
  q2.header = header;
510362
+ else
510363
+ delete q2.header;
510360
510364
  const rawOptions = Array.isArray(q2.options) ? q2.options : Array.isArray(q2.choices) ? q2.choices : undefined;
510361
510365
  if (Array.isArray(rawOptions)) {
510362
510366
  q2.options = rawOptions.map((rawOpt) => {
@@ -510372,8 +510376,12 @@ function coerceAskUserQuestionInput(input) {
510372
510376
  const finalDescription = description ?? label;
510373
510377
  if (finalLabel !== undefined)
510374
510378
  opt.label = finalLabel;
510379
+ else
510380
+ delete opt.label;
510375
510381
  if (finalDescription !== undefined)
510376
510382
  opt.description = finalDescription;
510383
+ else
510384
+ delete opt.description;
510377
510385
  return opt;
510378
510386
  });
510379
510387
  }
@@ -513523,7 +513531,7 @@ async function hasPermissionsToUseToolInner(tool, input, context) {
513523
513531
  throw new AbortError;
513524
513532
  }
513525
513533
  let appState = context.getAppState();
513526
- if (appState.toolPermissionContext.mode === "fullManage") {
513534
+ if (appState.toolPermissionContext.mode === "fullManage" && !tool.requiresUserInteraction?.()) {
513527
513535
  return {
513528
513536
  behavior: "allow",
513529
513537
  updatedInput: input,
@@ -521920,9 +521928,9 @@ async function assertMinVersion() {
521920
521928
  if (false) {}
521921
521929
  try {
521922
521930
  const versionConfig = await getDynamicConfig_BLOCKS_ON_INIT("tengu_version_config", { minVersion: "0.0.0" });
521923
- if (versionConfig.minVersion && lt("1.4.478", versionConfig.minVersion)) {
521931
+ if (versionConfig.minVersion && lt("1.4.480", versionConfig.minVersion)) {
521924
521932
  console.error(`
521925
- It looks like your version of RAYU (${"1.4.478"}) needs an update.
521933
+ It looks like your version of RAYU (${"1.4.480"}) needs an update.
521926
521934
  A newer version (${versionConfig.minVersion} or higher) is required to continue.
521927
521935
 
521928
521936
  To update, please run:
@@ -522148,7 +522156,7 @@ async function installGlobalPackage(specificVersion) {
522148
522156
  logError2(new AutoUpdaterError("Another process is currently installing an update"));
522149
522157
  logEvent("tengu_auto_updater_lock_contention", {
522150
522158
  pid: process.pid,
522151
- currentVersion: "1.4.478"
522159
+ currentVersion: "1.4.480"
522152
522160
  });
522153
522161
  return "in_progress";
522154
522162
  }
@@ -522157,7 +522165,7 @@ async function installGlobalPackage(specificVersion) {
522157
522165
  if (!env3.isRunningWithBun() && env3.isNpmFromWindowsPath()) {
522158
522166
  logError2(new Error("Windows NPM detected in WSL environment"));
522159
522167
  logEvent("tengu_auto_updater_windows_npm_in_wsl", {
522160
- currentVersion: "1.4.478"
522168
+ currentVersion: "1.4.480"
522161
522169
  });
522162
522170
  console.error(`
522163
522171
  Error: Windows NPM detected in WSL
@@ -522685,7 +522693,7 @@ function detectLinuxGlobPatternWarnings() {
522685
522693
  }
522686
522694
  async function getDoctorDiagnostic() {
522687
522695
  const installationType = await getCurrentInstallationType();
522688
- const version2 = typeof MACRO !== "undefined" ? "1.4.478" : "unknown";
522696
+ const version2 = typeof MACRO !== "undefined" ? "1.4.480" : "unknown";
522689
522697
  const installationPath = await getInstallationPath();
522690
522698
  const invokedBinary = getInvokedBinary();
522691
522699
  const multipleInstallations = await detectMultipleInstallations();
@@ -523230,6 +523238,10 @@ function getPlatform3() {
523230
523238
  function getBinaryName(platform4) {
523231
523239
  return platform4.startsWith("win32") ? "rayu.exe" : "rayu";
523232
523240
  }
523241
+ function isStaleWindowsExecutable(fileName, binaryName) {
523242
+ const escaped = binaryName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
523243
+ return new RegExp(`^${escaped}\\.old\\.\\d+$`).test(fileName);
523244
+ }
523233
523245
  function getBaseDirectories() {
523234
523246
  const platform4 = getPlatform3();
523235
523247
  const executableName = getBinaryName(platform4);
@@ -523476,8 +523488,8 @@ async function updateLatest(channelOrVersion, forceReinstall = false) {
523476
523488
  const maxVersion = await getMaxVersion();
523477
523489
  if (maxVersion && gt(version2, maxVersion)) {
523478
523490
  logForDebugging(`Native installer: maxVersion ${maxVersion} is set, capping update from ${version2} to ${maxVersion}`);
523479
- if (gte("1.4.478", maxVersion)) {
523480
- logForDebugging(`Native installer: current version ${"1.4.478"} is already at or above maxVersion ${maxVersion}, skipping update`);
523491
+ if (gte("1.4.480", maxVersion)) {
523492
+ logForDebugging(`Native installer: current version ${"1.4.480"} is already at or above maxVersion ${maxVersion}, skipping update`);
523481
523493
  logEvent("tengu_native_update_skipped_max_version", {
523482
523494
  latency_ms: Date.now() - startTime2,
523483
523495
  max_version: maxVersion,
@@ -523488,7 +523500,7 @@ async function updateLatest(channelOrVersion, forceReinstall = false) {
523488
523500
  version2 = maxVersion;
523489
523501
  }
523490
523502
  }
523491
- if (!forceReinstall && version2 === "1.4.478" && await versionIsAvailable(version2) && await isPossibleClaudeBinary(executablePath)) {
523503
+ if (!forceReinstall && version2 === "1.4.480" && await versionIsAvailable(version2) && await isPossibleClaudeBinary(executablePath)) {
523492
523504
  logForDebugging(`Found ${version2} at ${executablePath}, skipping install`);
523493
523505
  logEvent("tengu_native_update_complete", {
523494
523506
  latency_ms: Date.now() - startTime2,
@@ -523898,7 +523910,7 @@ async function cleanupOldVersions() {
523898
523910
  const files2 = await readdir23(executableDir);
523899
523911
  let cleanedCount = 0;
523900
523912
  for (const file2 of files2) {
523901
- if (!/^claude\.exe\.old\.\d+$/.test(file2))
523913
+ if (!isStaleWindowsExecutable(file2, getBinaryName(getPlatform3())))
523902
523914
  continue;
523903
523915
  try {
523904
523916
  await unlink15(join127(executableDir, file2));
@@ -524696,7 +524708,7 @@ function buildPrimarySection() {
524696
524708
  });
524697
524709
  return [{
524698
524710
  label: "Version",
524699
- value: "1.4.478"
524711
+ value: "1.4.480"
524700
524712
  }, {
524701
524713
  label: "Session name",
524702
524714
  value: nameValue
@@ -528367,7 +528379,7 @@ function Config({
528367
528379
  }
528368
528380
  })
528369
528381
  }) : showSubmenu === "ChannelDowngrade" ? /* @__PURE__ */ jsx_runtime168.jsx(ChannelDowngradeDialog, {
528370
- currentVersion: "1.4.478",
528382
+ currentVersion: "1.4.480",
528371
528383
  onChoice: (choice) => {
528372
528384
  setShowSubmenu(null);
528373
528385
  setTabsHidden(false);
@@ -528379,7 +528391,7 @@ function Config({
528379
528391
  autoUpdatesChannel: "stable"
528380
528392
  };
528381
528393
  if (choice === "stay") {
528382
- newSettings.minimumVersion = "1.4.478";
528394
+ newSettings.minimumVersion = "1.4.480";
528383
528395
  }
528384
528396
  updateSettingsForSource("userSettings", newSettings);
528385
528397
  setSettingsData((prev_27) => ({
@@ -536440,7 +536452,7 @@ function HelpV2(t0) {
536440
536452
  let t6;
536441
536453
  if ($3[31] !== tabs) {
536442
536454
  t6 = /* @__PURE__ */ jsx_runtime195.jsx(Tabs, {
536443
- title: `Rayu-CLI v${"1.4.478"}`,
536455
+ title: `Rayu-CLI v${"1.4.480"}`,
536444
536456
  color: "professionalBlue",
536445
536457
  defaultTab: "general",
536446
536458
  children: tabs
@@ -554559,12 +554571,25 @@ function setTelegramMode(mode) {
554559
554571
  cfg.mode = mode;
554560
554572
  writeTelegramConfig(cfg);
554561
554573
  }
554562
- function setLinkedChat(chatId, username) {
554574
+ function setLinkedChat(chatId, username, botUsername) {
554563
554575
  const cfg = readTelegramConfig();
554564
554576
  cfg.linkedChatId = chatId;
554565
554577
  cfg.linkedUsername = username;
554578
+ if (botUsername)
554579
+ cfg.linkedBotUsername = botUsername;
554566
554580
  writeTelegramConfig(cfg);
554567
554581
  }
554582
+ function setLinkedBotUsername(botUsername) {
554583
+ const cfg = readTelegramConfig();
554584
+ cfg.linkedBotUsername = botUsername;
554585
+ writeTelegramConfig(cfg);
554586
+ }
554587
+ function normalizeBotToken(raw) {
554588
+ return raw.replace(/\u001b\[20[01]~/g, "").replace(/\u001b\[[0-9;?]*[ -/]*[@-~]/g, "").replace(/[\u0000-\u001f\u007f]/g, "").replace(/\s+/g, "").replace(/^["']|["']$/g, "").trim();
554589
+ }
554590
+ function isValidBotToken(raw) {
554591
+ return BOT_TOKEN_RE.test(normalizeBotToken(raw));
554592
+ }
554568
554593
  function getBotToken() {
554569
554594
  const cfg = readTelegramConfig();
554570
554595
  if (cfg.botToken && cfg.botToken.trim().length > 0)
@@ -554574,7 +554599,7 @@ function getBotToken() {
554574
554599
  }
554575
554600
  function saveBotToken(token) {
554576
554601
  const cfg = readTelegramConfig();
554577
- cfg.botToken = token.trim();
554602
+ cfg.botToken = normalizeBotToken(token);
554578
554603
  writeTelegramConfig(cfg);
554579
554604
  }
554580
554605
  function clearBotToken() {
@@ -554626,11 +554651,17 @@ function consumePendingToken(token, chatId, username) {
554626
554651
  return next;
554627
554652
  }
554628
554653
  function unlink18() {
554629
- const current = readTelegramConfig();
554630
- writeTelegramConfig({ botToken: current.botToken });
554654
+ const next = { ...readTelegramConfig() };
554655
+ delete next.linkedChatId;
554656
+ delete next.linkedUsername;
554657
+ delete next.linkedBotUsername;
554658
+ delete next.pendingToken;
554659
+ writeTelegramConfig(next);
554631
554660
  }
554661
+ var BOT_TOKEN_RE;
554632
554662
  var init_telegramConfig = __esm(() => {
554633
554663
  init_envUtils();
554664
+ BOT_TOKEN_RE = /^\d+:[A-Za-z0-9_-]{10,}$/;
554634
554665
  });
554635
554666
 
554636
554667
  // src/telegram/telegramApi.ts
@@ -554956,27 +554987,41 @@ __export(exports_telegram_bot, {
554956
554987
  });
554957
554988
  import { randomUUID as randomUUID29 } from "crypto";
554958
554989
  function useKeyPress(target, handler) {
554959
- import_react132.useEffect(() => {
554960
- const onData = (data) => {
554961
- const ch2 = data.toString().trim().toLowerCase();
554962
- if (ch2 === target)
554963
- handler();
554964
- };
554965
- process.stdin.on("data", onData);
554966
- return () => {
554967
- process.stdin.off("data", onData);
554968
- };
554969
- }, [target, handler]);
554990
+ use_input_default((input) => {
554991
+ if (input.trim().toLowerCase() === target)
554992
+ handler();
554993
+ });
554994
+ }
554995
+ function useEscapeToCancel(onCancel) {
554996
+ use_input_default((_input, key2) => {
554997
+ if (key2.escape)
554998
+ onCancel();
554999
+ });
555000
+ }
555001
+ function CancelHint() {
555002
+ return /* @__PURE__ */ jsx_runtime222.jsxs(ThemedText, {
555003
+ dimColor: true,
555004
+ children: [
555005
+ "Press ",
555006
+ /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
555007
+ bold: true,
555008
+ children: "Esc"
555009
+ }),
555010
+ " to cancel."
555011
+ ]
555012
+ });
554970
555013
  }
554971
555014
  function HostedStep({
554972
555015
  onDone,
554973
- onUseByo
555016
+ onUseByo,
555017
+ onCancel
554974
555018
  }) {
554975
555019
  const [status, setStatus] = import_react132.useState("loading");
554976
555020
  const [pairing, setPairing] = import_react132.useState(null);
554977
555021
  const [qr, setQr] = import_react132.useState("");
554978
555022
  const setAppState = useSetAppState();
554979
555023
  useKeyPress("b", onUseByo);
555024
+ useEscapeToCancel(onCancel);
554980
555025
  import_react132.useEffect(() => {
554981
555026
  let cancelled = false;
554982
555027
  (async () => {
@@ -555020,14 +555065,17 @@ function HostedStep({
555020
555065
  if (!link5.linked)
555021
555066
  return;
555022
555067
  clearInterval(timer);
555023
- if (link5.chatId)
555024
- setLinkedChat(Number(link5.chatId), link5.username ?? undefined);
555068
+ if (link5.chatId) {
555069
+ setLinkedChat(Number(link5.chatId), link5.username ?? undefined, pairing?.botUsername ?? undefined);
555070
+ } else if (pairing?.botUsername) {
555071
+ setLinkedBotUsername(pairing.botUsername);
555072
+ }
555025
555073
  setAppState((prev) => ({ ...prev, telegramBridgeActive: true }));
555026
555074
  onDone();
555027
555075
  });
555028
555076
  }, 1500);
555029
555077
  return () => clearInterval(timer);
555030
- }, [status, onDone, setAppState]);
555078
+ }, [status, onDone, setAppState, pairing]);
555031
555079
  if (status === "loading") {
555032
555080
  return /* @__PURE__ */ jsx_runtime222.jsx(Pane, {
555033
555081
  children: /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
@@ -555065,7 +555113,8 @@ function HostedStep({
555065
555113
  }),
555066
555114
  " to connect your own bot token instead."
555067
555115
  ]
555068
- })
555116
+ }),
555117
+ /* @__PURE__ */ jsx_runtime222.jsx(CancelHint, {})
555069
555118
  ]
555070
555119
  })
555071
555120
  });
@@ -555098,7 +555147,8 @@ function HostedStep({
555098
555147
  }),
555099
555148
  " to connect your own bot token instead."
555100
555149
  ]
555101
- })
555150
+ }),
555151
+ /* @__PURE__ */ jsx_runtime222.jsx(CancelHint, {})
555102
555152
  ]
555103
555153
  })
555104
555154
  });
@@ -555154,48 +555204,155 @@ function HostedStep({
555154
555204
  }),
555155
555205
  " to use your own bot token instead."
555156
555206
  ]
555157
- })
555207
+ }),
555208
+ /* @__PURE__ */ jsx_runtime222.jsx(CancelHint, {})
555158
555209
  ]
555159
555210
  })
555160
555211
  });
555161
555212
  }
555162
- function TokenInputStep({ onReady }) {
555213
+ function TokenInputStep({
555214
+ onReady,
555215
+ onCancel
555216
+ }) {
555163
555217
  const [existing, setExisting] = import_react132.useState(() => getBotToken());
555218
+ const [editing, setEditing] = import_react132.useState(() => getBotToken() === undefined);
555219
+ const connect5 = import_react132.useCallback(() => {
555220
+ setTelegramMode("byo");
555221
+ onReady();
555222
+ }, [onReady]);
555223
+ if (existing && !editing) {
555224
+ return /* @__PURE__ */ jsx_runtime222.jsx(ExistingTokenMenu, {
555225
+ token: existing,
555226
+ onConnect: connect5,
555227
+ onReplace: () => setEditing(true),
555228
+ onDelete: () => {
555229
+ clearBotToken();
555230
+ setExisting(undefined);
555231
+ setEditing(true);
555232
+ },
555233
+ onCancel
555234
+ });
555235
+ }
555236
+ return /* @__PURE__ */ jsx_runtime222.jsx(TokenPrompt, {
555237
+ hasExisting: existing !== undefined,
555238
+ onSaved: connect5,
555239
+ onCancel,
555240
+ onCancelReplace: existing !== undefined ? () => setEditing(false) : undefined
555241
+ });
555242
+ }
555243
+ function ExistingTokenMenu({
555244
+ token,
555245
+ onConnect,
555246
+ onReplace,
555247
+ onDelete,
555248
+ onCancel
555249
+ }) {
555250
+ useEscapeToCancel(onCancel);
555251
+ use_input_default((input, key2) => {
555252
+ if (key2.return) {
555253
+ onConnect();
555254
+ return;
555255
+ }
555256
+ const ch2 = input.trim().toLowerCase();
555257
+ if (ch2 === "1")
555258
+ onConnect();
555259
+ else if (ch2 === "2" || ch2 === "r")
555260
+ onReplace();
555261
+ else if (ch2 === "3" || ch2 === "d")
555262
+ onDelete();
555263
+ });
555264
+ return /* @__PURE__ */ jsx_runtime222.jsx(Pane, {
555265
+ children: /* @__PURE__ */ jsx_runtime222.jsxs(ThemedBox_default, {
555266
+ flexDirection: "column",
555267
+ children: [
555268
+ /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
555269
+ bold: true,
555270
+ children: "\uD83D\uDCF1 Your Telegram bot token"
555271
+ }),
555272
+ /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
555273
+ children: " "
555274
+ }),
555275
+ /* @__PURE__ */ jsx_runtime222.jsxs(ThemedText, {
555276
+ children: [
555277
+ "A bot token is already saved (…",
555278
+ token.slice(-6),
555279
+ ")."
555280
+ ]
555281
+ }),
555282
+ /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
555283
+ children: " "
555284
+ }),
555285
+ /* @__PURE__ */ jsx_runtime222.jsxs(ThemedText, {
555286
+ children: [
555287
+ /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
555288
+ bold: true,
555289
+ children: "Enter"
555290
+ }),
555291
+ " connect with it",
555292
+ " ",
555293
+ /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
555294
+ bold: true,
555295
+ children: "r"
555296
+ }),
555297
+ " replace it",
555298
+ " ",
555299
+ /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
555300
+ bold: true,
555301
+ children: "d"
555302
+ }),
555303
+ " remove it"
555304
+ ]
555305
+ }),
555306
+ /* @__PURE__ */ jsx_runtime222.jsx(CancelHint, {})
555307
+ ]
555308
+ })
555309
+ });
555310
+ }
555311
+ function TokenPrompt({
555312
+ hasExisting,
555313
+ onSaved,
555314
+ onCancel,
555315
+ onCancelReplace
555316
+ }) {
555317
+ const [value, setValue] = import_react132.useState("");
555318
+ const [cursorOffset, setCursorOffset] = import_react132.useState(0);
555164
555319
  const [error54, setError] = import_react132.useState("");
555165
- const [waiting, setWaiting] = import_react132.useState(false);
555166
- import_react132.useEffect(() => {
555167
- const handler = (data) => {
555168
- const line = data.toString().trim();
555169
- if (existing) {
555170
- if (line === "") {
555171
- setTelegramMode("byo");
555172
- onReady();
555173
- return;
555174
- }
555175
- if (line.toLowerCase() === "d") {
555176
- clearBotToken();
555177
- setExisting(undefined);
555178
- setError("");
555179
- return;
555180
- }
555181
- }
555182
- if (!line)
555320
+ const [status, setStatus] = import_react132.useState("idle");
555321
+ use_input_default((_input, key2) => {
555322
+ if (!key2.escape)
555323
+ return;
555324
+ if (onCancelReplace)
555325
+ onCancelReplace();
555326
+ else
555327
+ onCancel();
555328
+ }, { isActive: status === "idle" });
555329
+ const handleSubmit = import_react132.useCallback((submitted) => {
555330
+ if (status !== "idle")
555331
+ return;
555332
+ const token = normalizeBotToken(submitted);
555333
+ if (!token) {
555334
+ setError("Paste the token from @BotFather, then press Enter.");
555335
+ return;
555336
+ }
555337
+ if (!isValidBotToken(token)) {
555338
+ setError("That doesn't look like a bot token. It should be like: 123456789:ABCDefGHI…");
555339
+ return;
555340
+ }
555341
+ setError("");
555342
+ setStatus("verifying");
555343
+ getBotUsername(token).then((username) => {
555344
+ if (!username) {
555345
+ setStatus("idle");
555346
+ setError("Telegram rejected this token. Check it in @BotFather (or /revoke and paste the new one).");
555183
555347
  return;
555184
- if (/^\d+:[A-Za-z0-9_-]+$/.test(line)) {
555185
- saveBotToken(line);
555186
- setTelegramMode("byo");
555187
- setWaiting(true);
555188
- setTimeout(() => onReady(), 300);
555189
- } else {
555190
- setError("That doesn't look like a valid bot token. It should be like: 123456789:ABCDefGHI...");
555191
555348
  }
555192
- };
555193
- process.stdin.on("data", handler);
555194
- return () => {
555195
- process.stdin.off("data", handler);
555196
- };
555197
- }, [existing, onReady]);
555198
- if (waiting) {
555349
+ saveBotToken(token);
555350
+ setTelegramMode("byo");
555351
+ setStatus("saved");
555352
+ setTimeout(onSaved, 300);
555353
+ });
555354
+ }, [status, onSaved]);
555355
+ if (status === "saved") {
555199
555356
  return /* @__PURE__ */ jsx_runtime222.jsx(Pane, {
555200
555357
  children: /* @__PURE__ */ jsx_runtime222.jsxs(ThemedBox_default, {
555201
555358
  flexDirection: "column",
@@ -555212,65 +555369,13 @@ function TokenInputStep({ onReady }) {
555212
555369
  })
555213
555370
  });
555214
555371
  }
555215
- if (existing) {
555216
- return /* @__PURE__ */ jsx_runtime222.jsx(Pane, {
555217
- children: /* @__PURE__ */ jsx_runtime222.jsxs(ThemedBox_default, {
555218
- flexDirection: "column",
555219
- children: [
555220
- /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
555221
- bold: true,
555222
- children: "\uD83D\uDCF1 Your Telegram bot token"
555223
- }),
555224
- /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
555225
- children: " "
555226
- }),
555227
- /* @__PURE__ */ jsx_runtime222.jsxs(ThemedText, {
555228
- children: [
555229
- "A bot token is already saved (…",
555230
- existing.slice(-6),
555231
- ")."
555232
- ]
555233
- }),
555234
- /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
555235
- children: " "
555236
- }),
555237
- /* @__PURE__ */ jsx_runtime222.jsxs(ThemedText, {
555238
- children: [
555239
- /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
555240
- bold: true,
555241
- children: "Enter"
555242
- }),
555243
- " connect with it",
555244
- " ",
555245
- /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
555246
- bold: true,
555247
- children: "d"
555248
- }),
555249
- " remove it",
555250
- " ",
555251
- "or paste a ",
555252
- /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
555253
- bold: true,
555254
- children: "new"
555255
- }),
555256
- " token to replace it."
555257
- ]
555258
- }),
555259
- error54 ? /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
555260
- color: "red",
555261
- children: error54
555262
- }) : null
555263
- ]
555264
- })
555265
- });
555266
- }
555267
555372
  return /* @__PURE__ */ jsx_runtime222.jsx(Pane, {
555268
555373
  children: /* @__PURE__ */ jsx_runtime222.jsxs(ThemedBox_default, {
555269
555374
  flexDirection: "column",
555270
555375
  children: [
555271
555376
  /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
555272
555377
  bold: true,
555273
- children: "\uD83D\uDCF1 Connect your own Telegram bot"
555378
+ children: hasExisting ? "\uD83D\uDCF1 Replace your Telegram bot token" : "\uD83D\uDCF1 Connect your own Telegram bot"
555274
555379
  }),
555275
555380
  /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
555276
555381
  children: " "
@@ -555301,31 +555406,64 @@ function TokenInputStep({ onReady }) {
555301
555406
  /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
555302
555407
  children: " 3. Copy the bot token (looks like: 123456789:ABCDef...)"
555303
555408
  }),
555304
- /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
555305
- children: " 4. Paste it below:"
555409
+ /* @__PURE__ */ jsx_runtime222.jsxs(ThemedText, {
555410
+ children: [
555411
+ " 4. Paste it below and press ",
555412
+ /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
555413
+ bold: true,
555414
+ children: "Enter"
555415
+ }),
555416
+ ":"
555417
+ ]
555306
555418
  }),
555307
555419
  /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
555308
555420
  children: " "
555309
555421
  }),
555310
- /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
555311
- bold: true,
555312
- color: "cyan",
555313
- children: "⌨ Paste your bot token: "
555422
+ /* @__PURE__ */ jsx_runtime222.jsxs(ThemedBox_default, {
555423
+ children: [
555424
+ /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
555425
+ bold: true,
555426
+ color: "cyan",
555427
+ children: "⌨ Bot token: "
555428
+ }),
555429
+ /* @__PURE__ */ jsx_runtime222.jsx(TextInput, {
555430
+ value,
555431
+ onChange: setValue,
555432
+ onSubmit: handleSubmit,
555433
+ cursorOffset,
555434
+ onChangeCursorOffset: setCursorOffset,
555435
+ columns: 80,
555436
+ focus: status === "idle",
555437
+ showCursor: true
555438
+ })
555439
+ ]
555314
555440
  }),
555441
+ status === "verifying" ? /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
555442
+ dimColor: true,
555443
+ children: "Checking the token with Telegram…"
555444
+ }) : null,
555315
555445
  error54 ? /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
555316
555446
  color: "red",
555317
555447
  children: error54
555318
- }) : null
555448
+ }) : null,
555449
+ onCancelReplace ? /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
555450
+ dimColor: true,
555451
+ children: "Press Esc to keep the token you already have."
555452
+ }) : /* @__PURE__ */ jsx_runtime222.jsx(CancelHint, {})
555319
555453
  ]
555320
555454
  })
555321
555455
  });
555322
555456
  }
555323
- function LinkStep({ onDone }) {
555457
+ function LinkStep({
555458
+ onDone,
555459
+ onCancel
555460
+ }) {
555324
555461
  const token = getBotToken();
555325
555462
  const [pairToken] = import_react132.useState(() => randomUUID29().slice(0, 8));
555326
555463
  const [qr, setQr] = import_react132.useState("");
555327
555464
  const [botUsername, setBotUsername] = import_react132.useState(undefined);
555328
555465
  const setAppState = useSetAppState();
555466
+ useEscapeToCancel(onCancel);
555329
555467
  import_react132.useEffect(() => {
555330
555468
  saveBotToken(token);
555331
555469
  setAppState((prev) => ({ ...prev, telegramBridgeActive: true }));
@@ -555342,11 +555480,13 @@ function LinkStep({ onDone }) {
555342
555480
  const timer = setInterval(() => {
555343
555481
  if (readTelegramConfig().linkedChatId !== undefined) {
555344
555482
  clearInterval(timer);
555483
+ if (botUsername)
555484
+ setLinkedBotUsername(botUsername);
555345
555485
  onDone();
555346
555486
  }
555347
555487
  }, 1500);
555348
555488
  return () => clearInterval(timer);
555349
- }, [onDone]);
555489
+ }, [onDone, botUsername]);
555350
555490
  const lines2 = qr.split(`
555351
555491
  `).filter((l3) => l3.length > 0);
555352
555492
  return /* @__PURE__ */ jsx_runtime222.jsx(Pane, {
@@ -555379,35 +555519,30 @@ function LinkStep({ onDone }) {
555379
555519
  /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
555380
555520
  dimColor: true,
555381
555521
  children: "Waiting for link… (token valid 10 min)"
555382
- })
555522
+ }),
555523
+ /* @__PURE__ */ jsx_runtime222.jsx(CancelHint, {})
555383
555524
  ]
555384
555525
  })
555385
555526
  });
555386
555527
  }
555387
555528
  function ChooseModeStep({
555388
- onChoose
555529
+ onChoose,
555530
+ onCancel
555389
555531
  }) {
555390
555532
  const [sel, setSel] = import_react132.useState(0);
555391
- import_react132.useEffect(() => {
555392
- const onData = (data) => {
555393
- const s2 = data.toString();
555394
- const t2 = s2.trim();
555395
- if (t2 === "1")
555396
- onChoose("hosted");
555397
- else if (t2 === "2")
555398
- onChoose("byo");
555399
- else if (s2 === "\r" || s2 === `
555400
- ` || t2 === "")
555401
- onChoose(sel === 0 ? "hosted" : "byo");
555402
- else if (s2 === "\x1B[A" || s2 === "\x1B[B" || t2 === "j" || t2 === "k") {
555403
- setSel((p) => p === 0 ? 1 : 0);
555404
- }
555405
- };
555406
- process.stdin.on("data", onData);
555407
- return () => {
555408
- process.stdin.off("data", onData);
555409
- };
555410
- }, [onChoose, sel]);
555533
+ useEscapeToCancel(onCancel);
555534
+ use_input_default((input, key2) => {
555535
+ const t2 = input.trim();
555536
+ if (t2 === "1")
555537
+ onChoose("hosted");
555538
+ else if (t2 === "2")
555539
+ onChoose("byo");
555540
+ else if (key2.return)
555541
+ onChoose(sel === 0 ? "hosted" : "byo");
555542
+ else if (key2.upArrow || key2.downArrow || t2 === "j" || t2 === "k") {
555543
+ setSel((p) => p === 0 ? 1 : 0);
555544
+ }
555545
+ });
555411
555546
  return /* @__PURE__ */ jsx_runtime222.jsx(Pane, {
555412
555547
  children: /* @__PURE__ */ jsx_runtime222.jsxs(ThemedBox_default, {
555413
555548
  flexDirection: "column",
@@ -555449,22 +555584,66 @@ function ChooseModeStep({
555449
555584
  /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
555450
555585
  dimColor: true,
555451
555586
  children: "Press 1 or 2 (or ↑/↓ then Enter). Enter = shared bot."
555452
- })
555587
+ }),
555588
+ /* @__PURE__ */ jsx_runtime222.jsx(CancelHint, {})
555453
555589
  ]
555454
555590
  })
555455
555591
  });
555456
555592
  }
555457
- function TelegramBotConnect({ onDone }) {
555458
- const alreadyLinked = readTelegramConfig().linkedChatId !== undefined;
555459
- const setAppState = useSetAppState();
555460
- const [screen, setScreen] = import_react132.useState("choose");
555461
- import_react132.useEffect(() => {
555462
- if (alreadyLinked) {
555463
- setAppState((prev) => ({ ...prev, telegramBridgeActive: true }));
555464
- onDone();
555593
+ async function resolveCurrentBotUsername() {
555594
+ if (getTelegramMode() === "hosted") {
555595
+ if (!hasRayuSession())
555596
+ return;
555597
+ const info = await getHostedBotInfo();
555598
+ return info.username ?? undefined;
555599
+ }
555600
+ const token = getBotToken();
555601
+ return token ? await getBotUsername(token) : undefined;
555602
+ }
555603
+ function VerifyLinkStep({
555604
+ onReconnect,
555605
+ onRepair,
555606
+ onCancel
555607
+ }) {
555608
+ const [check3, setCheck] = import_react132.useState({ kind: "checking" });
555609
+ useEscapeToCancel(onCancel);
555610
+ use_input_default((input, key2) => {
555611
+ if (check3.kind === "checking")
555612
+ return;
555613
+ if (key2.return) {
555614
+ if (check3.kind === "changed")
555615
+ onRepair();
555616
+ else {
555617
+ setLinkedBotUsername(check3.current);
555618
+ onReconnect();
555619
+ }
555620
+ return;
555465
555621
  }
555466
- }, [alreadyLinked, onDone, setAppState]);
555467
- if (alreadyLinked) {
555622
+ if (input.trim().toLowerCase() === "r")
555623
+ onRepair();
555624
+ }, { isActive: check3.kind !== "checking" });
555625
+ import_react132.useEffect(() => {
555626
+ let cancelled = false;
555627
+ (async () => {
555628
+ const recorded = readTelegramConfig().linkedBotUsername;
555629
+ const current = await resolveCurrentBotUsername();
555630
+ if (cancelled)
555631
+ return;
555632
+ if (!current) {
555633
+ onReconnect();
555634
+ return;
555635
+ }
555636
+ if (recorded && recorded.toLowerCase() === current.toLowerCase()) {
555637
+ onReconnect();
555638
+ return;
555639
+ }
555640
+ setCheck(recorded ? { kind: "changed", linkedTo: recorded, current } : { kind: "unverifiable", current });
555641
+ })();
555642
+ return () => {
555643
+ cancelled = true;
555644
+ };
555645
+ }, [onReconnect]);
555646
+ if (check3.kind === "checking") {
555468
555647
  return /* @__PURE__ */ jsx_runtime222.jsx(Pane, {
555469
555648
  children: /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
555470
555649
  dimColor: true,
@@ -555472,8 +555651,153 @@ function TelegramBotConnect({ onDone }) {
555472
555651
  })
555473
555652
  });
555474
555653
  }
555654
+ if (check3.kind === "changed") {
555655
+ return /* @__PURE__ */ jsx_runtime222.jsx(Pane, {
555656
+ children: /* @__PURE__ */ jsx_runtime222.jsxs(ThemedBox_default, {
555657
+ flexDirection: "column",
555658
+ children: [
555659
+ /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
555660
+ bold: true,
555661
+ children: "\uD83D\uDCF1 Telegram bot changed"
555662
+ }),
555663
+ /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
555664
+ children: " "
555665
+ }),
555666
+ /* @__PURE__ */ jsx_runtime222.jsxs(ThemedText, {
555667
+ children: [
555668
+ "Your saved link points at ",
555669
+ /* @__PURE__ */ jsx_runtime222.jsxs(ThemedText, {
555670
+ bold: true,
555671
+ children: [
555672
+ "@",
555673
+ check3.linkedTo
555674
+ ]
555675
+ }),
555676
+ ", but Rayu now uses ",
555677
+ /* @__PURE__ */ jsx_runtime222.jsxs(ThemedText, {
555678
+ bold: true,
555679
+ children: [
555680
+ "@",
555681
+ check3.current
555682
+ ]
555683
+ }),
555684
+ "."
555685
+ ]
555686
+ }),
555687
+ /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
555688
+ dimColor: true,
555689
+ children: "The old link can't receive messages from the new bot."
555690
+ }),
555691
+ /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
555692
+ children: " "
555693
+ }),
555694
+ /* @__PURE__ */ jsx_runtime222.jsxs(ThemedText, {
555695
+ children: [
555696
+ /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
555697
+ bold: true,
555698
+ children: "Enter"
555699
+ }),
555700
+ " link with @",
555701
+ check3.current
555702
+ ]
555703
+ }),
555704
+ /* @__PURE__ */ jsx_runtime222.jsx(CancelHint, {})
555705
+ ]
555706
+ })
555707
+ });
555708
+ }
555709
+ return /* @__PURE__ */ jsx_runtime222.jsx(Pane, {
555710
+ children: /* @__PURE__ */ jsx_runtime222.jsxs(ThemedBox_default, {
555711
+ flexDirection: "column",
555712
+ children: [
555713
+ /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
555714
+ bold: true,
555715
+ children: "\uD83D\uDCF1 Telegram is already linked"
555716
+ }),
555717
+ /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
555718
+ children: " "
555719
+ }),
555720
+ /* @__PURE__ */ jsx_runtime222.jsxs(ThemedText, {
555721
+ children: [
555722
+ "Rayu currently uses ",
555723
+ /* @__PURE__ */ jsx_runtime222.jsxs(ThemedText, {
555724
+ bold: true,
555725
+ children: [
555726
+ "@",
555727
+ check3.current
555728
+ ]
555729
+ }),
555730
+ "."
555731
+ ]
555732
+ }),
555733
+ /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
555734
+ dimColor: true,
555735
+ children: "This link was saved before Rayu recorded which bot it belongs to, so it may point at an older bot."
555736
+ }),
555737
+ /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
555738
+ children: " "
555739
+ }),
555740
+ /* @__PURE__ */ jsx_runtime222.jsxs(ThemedText, {
555741
+ children: [
555742
+ /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
555743
+ bold: true,
555744
+ children: "Enter"
555745
+ }),
555746
+ " reconnect with the saved link",
555747
+ " ",
555748
+ /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
555749
+ bold: true,
555750
+ children: "r"
555751
+ }),
555752
+ " re-link with @",
555753
+ check3.current
555754
+ ]
555755
+ }),
555756
+ /* @__PURE__ */ jsx_runtime222.jsx(CancelHint, {})
555757
+ ]
555758
+ })
555759
+ });
555760
+ }
555761
+ function TelegramBotConnect({ onDone }) {
555762
+ const setAppState = useSetAppState();
555763
+ const [screen, setScreen] = import_react132.useState(() => readTelegramConfig().linkedChatId === undefined ? "choose" : "verify");
555764
+ const [unlinking, setUnlinking] = import_react132.useState(false);
555765
+ const reconnect = import_react132.useCallback(() => {
555766
+ setAppState((prev) => ({ ...prev, telegramBridgeActive: true }));
555767
+ onDone();
555768
+ }, [onDone, setAppState]);
555769
+ const repair = import_react132.useCallback(() => {
555770
+ setUnlinking(true);
555771
+ (async () => {
555772
+ if (getTelegramMode() === "hosted")
555773
+ await deleteHostedLink();
555774
+ unlink18();
555775
+ setUnlinking(false);
555776
+ setScreen("choose");
555777
+ })();
555778
+ }, []);
555779
+ const cancel = import_react132.useCallback(() => {
555780
+ setAppState((prev) => ({ ...prev, telegramBridgeActive: false }));
555781
+ onDone();
555782
+ }, [onDone, setAppState]);
555783
+ if (unlinking) {
555784
+ return /* @__PURE__ */ jsx_runtime222.jsx(Pane, {
555785
+ children: /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
555786
+ dimColor: true,
555787
+ children: "Removing the old Telegram link…"
555788
+ })
555789
+ });
555790
+ }
555791
+ if (screen === "verify") {
555792
+ return /* @__PURE__ */ jsx_runtime222.jsx(VerifyLinkStep, {
555793
+ onReconnect: reconnect,
555794
+ onRepair: repair,
555795
+ onCancel: cancel
555796
+ });
555797
+ }
555475
555798
  if (screen === "choose") {
555476
555799
  return /* @__PURE__ */ jsx_runtime222.jsx(ChooseModeStep, {
555800
+ onCancel: cancel,
555477
555801
  onChoose: (mode) => {
555478
555802
  if (mode === "hosted") {
555479
555803
  setTelegramMode("hosted");
@@ -555488,16 +555812,19 @@ function TelegramBotConnect({ onDone }) {
555488
555812
  if (screen === "hosted") {
555489
555813
  return /* @__PURE__ */ jsx_runtime222.jsx(HostedStep, {
555490
555814
  onDone,
555491
- onUseByo: () => setScreen("byo-token")
555815
+ onUseByo: () => setScreen("byo-token"),
555816
+ onCancel: cancel
555492
555817
  });
555493
555818
  }
555494
555819
  if (screen === "byo-token") {
555495
555820
  return /* @__PURE__ */ jsx_runtime222.jsx(TokenInputStep, {
555496
- onReady: () => setScreen("byo-link")
555821
+ onReady: () => setScreen("byo-link"),
555822
+ onCancel: cancel
555497
555823
  });
555498
555824
  }
555499
555825
  return /* @__PURE__ */ jsx_runtime222.jsx(LinkStep, {
555500
- onDone
555826
+ onDone,
555827
+ onCancel: cancel
555501
555828
  });
555502
555829
  }
555503
555830
  async function call20(onDone) {
@@ -555509,6 +555836,7 @@ var import_react132, jsx_runtime222, TOKEN_TTL_MS;
555509
555836
  var init_telegram_bot = __esm(() => {
555510
555837
  init_server();
555511
555838
  init_Pane();
555839
+ init_TextInput();
555512
555840
  init_ink2();
555513
555841
  init_telegramConfig();
555514
555842
  init_telegramApi();
@@ -557018,7 +557346,7 @@ function getRecentReleaseNotes(currentVersion, previousVersion, changelogContent
557018
557346
  }
557019
557347
  return [];
557020
557348
  }
557021
- async function checkForReleaseNotes(lastSeenVersion, currentVersion = "1.4.478") {
557349
+ async function checkForReleaseNotes(lastSeenVersion, currentVersion = "1.4.480") {
557022
557350
  if (false) {}
557023
557351
  const cachedChangelog = await getStoredChangelog();
557024
557352
  if (lastSeenVersion !== currentVersion || !cachedChangelog) {
@@ -557031,7 +557359,7 @@ async function checkForReleaseNotes(lastSeenVersion, currentVersion = "1.4.478")
557031
557359
  releaseNotes
557032
557360
  };
557033
557361
  }
557034
- function checkForReleaseNotesSync(lastSeenVersion, currentVersion = "1.4.478") {
557362
+ function checkForReleaseNotesSync(lastSeenVersion, currentVersion = "1.4.480") {
557035
557363
  if (false) {}
557036
557364
  const releaseNotes = getRecentReleaseNotes(currentVersion, lastSeenVersion);
557037
557365
  return {
@@ -557159,7 +557487,7 @@ function getRecentActivitySync() {
557159
557487
  return cachedActivity;
557160
557488
  }
557161
557489
  function getLogoDisplayData() {
557162
- const version2 = process.env.DEMO_VERSION ?? "1.4.478";
557490
+ const version2 = process.env.DEMO_VERSION ?? "1.4.480";
557163
557491
  const serverUrl = getDirectConnectServerUrl();
557164
557492
  const displayPath = process.env.DEMO_VERSION ? "/code/claude" : getDisplayPath(getCwd());
557165
557493
  const cwd2 = serverUrl ? `${displayPath} in ${serverUrl.replace(/^https?:\/\//, "")}` : displayPath;
@@ -558324,7 +558652,7 @@ function LogoV2() {
558324
558652
  if ($3[2] === Symbol.for("react.memo_cache_sentinel")) {
558325
558653
  t2 = () => {
558326
558654
  const currentConfig = getGlobalConfig();
558327
- if (currentConfig.lastReleaseNotesSeen === "1.4.478") {
558655
+ if (currentConfig.lastReleaseNotesSeen === "1.4.480") {
558328
558656
  return;
558329
558657
  }
558330
558658
  saveGlobalConfig(_temp327);
@@ -558803,7 +559131,7 @@ function LogoV2() {
558803
559131
  t24 = $3[61];
558804
559132
  }
558805
559133
  const _latestNpm = getCachedLatestNpmVersionSync();
558806
- const _updateFeeds = _latestNpm && gt(_latestNpm, "1.4.478") ? [createUpdateAvailableFeed("1.4.478", _latestNpm)] : [];
559134
+ const _updateFeeds = _latestNpm && gt(_latestNpm, "1.4.480") ? [createUpdateAvailableFeed("1.4.480", _latestNpm)] : [];
558807
559135
  const t25 = layoutMode === "horizontal" && /* @__PURE__ */ jsx_runtime236.jsx(FeedColumn, {
558808
559136
  feeds: showOnboarding ? [createProjectOnboardingFeed(getSteps()), createRecentActivityFeed(activities)] : showGuestPassesUpsell ? [createRecentActivityFeed(activities), createGuestPassesFeed()] : showOverageCreditUpsell ? [createRecentActivityFeed(activities), createOverageCreditFeed()] : [createRecentActivityFeed(activities), ..._updateFeeds, createWhatsNewFeed(changelog)],
558809
559137
  maxWidth: rightWidth
@@ -559003,12 +559331,12 @@ function LogoV2() {
559003
559331
  return t41;
559004
559332
  }
559005
559333
  function _temp327(current) {
559006
- if (current.lastReleaseNotesSeen === "1.4.478") {
559334
+ if (current.lastReleaseNotesSeen === "1.4.480") {
559007
559335
  return current;
559008
559336
  }
559009
559337
  return {
559010
559338
  ...current,
559011
- lastReleaseNotesSeen: "1.4.478"
559339
+ lastReleaseNotesSeen: "1.4.480"
559012
559340
  };
559013
559341
  }
559014
559342
  function _temp241(s_0) {
@@ -584007,7 +584335,7 @@ async function captureMemoryDiagnostics(trigger, dumpNumber = 0) {
584007
584335
  smapsRollup,
584008
584336
  platform: process.platform,
584009
584337
  nodeVersion: process.version,
584010
- ccVersion: "1.4.478"
584338
+ ccVersion: "1.4.480"
584011
584339
  };
584012
584340
  }
584013
584341
  async function performHeapDump(trigger = "manual", dumpNumber = 0) {
@@ -584529,7 +584857,7 @@ var init_bridge_kick = __esm(() => {
584529
584857
  var call50 = async () => {
584530
584858
  return {
584531
584859
  type: "text",
584532
- value: "1.4.478"
584860
+ value: "1.4.480"
584533
584861
  };
584534
584862
  }, version2, version_default;
584535
584863
  var init_version = __esm(() => {
@@ -595025,7 +595353,7 @@ function generateHtmlReport(data, insights) {
595025
595353
  </html>`;
595026
595354
  }
595027
595355
  function buildExportData(data, insights, facets, remoteStats) {
595028
- const version3 = typeof MACRO !== "undefined" ? "1.4.478" : "unknown";
595356
+ const version3 = typeof MACRO !== "undefined" ? "1.4.480" : "unknown";
595029
595357
  const remote_hosts_collected = remoteStats?.hosts.filter((h3) => h3.sessionCount > 0).map((h3) => h3.name);
595030
595358
  const facets_summary = {
595031
595359
  total: facets.size,
@@ -598939,7 +599267,7 @@ var init_sessionStorage = __esm(() => {
598939
599267
  init_settings2();
598940
599268
  init_slowOperations();
598941
599269
  init_uuid();
598942
- VERSION6 = typeof MACRO !== "undefined" ? "1.4.478" : "unknown";
599270
+ VERSION6 = typeof MACRO !== "undefined" ? "1.4.480" : "unknown";
598943
599271
  MAX_TOMBSTONE_REWRITE_BYTES = 50 * 1024 * 1024;
598944
599272
  SKIP_FIRST_PROMPT_PATTERN = /^(?:\s*<[a-z][\w-]*[\s>]|\[Request interrupted by user[^\]]*\])/;
598945
599273
  EPHEMERAL_PROGRESS_TYPES = new Set([
@@ -600157,7 +600485,7 @@ var init_filesystem = __esm(() => {
600157
600485
  });
600158
600486
  getBundledSkillsRoot = memoize_default(function getBundledSkillsRoot2() {
600159
600487
  const nonce = randomBytes19(16).toString("hex");
600160
- return join153(getClaudeTempDir(), "bundled-skills", "1.4.478", nonce);
600488
+ return join153(getClaudeTempDir(), "bundled-skills", "1.4.480", nonce);
600161
600489
  });
600162
600490
  getResolvedWorkingDirPaths = memoize_default(getPathsForPermissionCheck);
600163
600491
  });
@@ -605265,8 +605593,10 @@ var init_worktree = __esm(() => {
605265
605593
  });
605266
605594
 
605267
605595
  // src/utils/npmExec.ts
605268
- import { execFileSync as execFileSync3 } from "node:child_process";
605269
- import { homedir as homedir35 } from "os";
605596
+ import { spawn as spawn13, execFileSync as execFileSync3 } from "node:child_process";
605597
+ import { writeFileSync as writeFileSync18 } from "node:fs";
605598
+ import { homedir as homedir35, tmpdir as tmpdir16 } from "os";
605599
+ import { join as join156 } from "path";
605270
605600
  function execNpmSync(npmArgs, options) {
605271
605601
  if (IS_WINDOWS2) {
605272
605602
  for (const a2 of npmArgs) {
@@ -605290,6 +605620,16 @@ function execNpmSync(npmArgs, options) {
605290
605620
  stdio: options.stdio
605291
605621
  });
605292
605622
  }
605623
+ function stderrOf(err2) {
605624
+ if (!(err2 instanceof Error))
605625
+ return "";
605626
+ const anyErr = err2;
605627
+ if (typeof anyErr.stderr === "string")
605628
+ return anyErr.stderr;
605629
+ if (Buffer.isBuffer(anyErr.stderr))
605630
+ return anyErr.stderr.toString("utf8");
605631
+ return "";
605632
+ }
605293
605633
  function describeNpmError(err2) {
605294
605634
  if (!(err2 instanceof Error))
605295
605635
  return String(err2);
@@ -605297,8 +605637,7 @@ function describeNpmError(err2) {
605297
605637
  const parts = [];
605298
605638
  if (anyErr.code)
605299
605639
  parts.push(`code: ${anyErr.code}`);
605300
- const stderrText = typeof anyErr.stderr === "string" ? anyErr.stderr : Buffer.isBuffer(anyErr.stderr) ? anyErr.stderr.toString("utf8") : "";
605301
- const trimmedStderr = stderrText.trim();
605640
+ const trimmedStderr = stderrOf(err2).trim();
605302
605641
  if (trimmedStderr) {
605303
605642
  parts.push(trimmedStderr);
605304
605643
  } else if (err2.message) {
@@ -605313,9 +605652,96 @@ function isLikelyEacces(err2) {
605313
605652
  const anyErr = err2;
605314
605653
  if (anyErr.code === "EACCES" || anyErr.code === "EPERM")
605315
605654
  return true;
605316
- const stderrText = typeof anyErr.stderr === "string" ? anyErr.stderr : Buffer.isBuffer(anyErr.stderr) ? anyErr.stderr.toString("utf8") : "";
605655
+ const stderrText = stderrOf(err2);
605317
605656
  return /EACCES|permission denied/i.test(stderrText) || /EACCES|permission denied/i.test(err2.message);
605318
605657
  }
605658
+ function isLikelyWindowsFileLock(err2) {
605659
+ if (!(err2 instanceof Error))
605660
+ return false;
605661
+ const code = err2.code;
605662
+ if (code === "EBUSY" || code === "ETXTBSY")
605663
+ return true;
605664
+ const haystack = `${stderrOf(err2)}
605665
+ ${err2.message}`;
605666
+ return /\bEBUSY\b|\bETXTBSY\b/i.test(haystack) || /\bEPERM\b/i.test(haystack) || /operation not permitted/i.test(haystack) || /being used by another process/i.test(haystack) || /cannot access the file/i.test(haystack) || /resource busy or locked/i.test(haystack);
605667
+ }
605668
+ function buildNpmRemediation(action2, packageSpec, err2, platform4 = process.platform) {
605669
+ const isWin = platform4 === "win32";
605670
+ const cmd = `npm ${action2} -g ${packageSpec}`;
605671
+ const lines2 = ["", "Try manually:", ` ${cmd}`];
605672
+ if (isWin) {
605673
+ if (isLikelyWindowsFileLock(err2)) {
605674
+ lines2.push("", "Windows could not replace the Rayu files because they are still in", 'use. This happens when npm rewrites the "rayu" launcher while the', "terminal that started it (cmd.exe in particular) still holds it open.", "", "Fix it by running the command from a shell that is NOT running Rayu:", " 1. Close every terminal that has Rayu running", " 2. Open a new PowerShell or Command Prompt", ` 3. Run: ${cmd}`, "", "If it still fails, an antivirus or a stray rayu.exe/node.exe may be", "holding the file. Check with:", " tasklist | findstr /i rayu");
605675
+ } else {
605676
+ lines2.push("", "If npm could not write to its global folder, run the command from an", "elevated (Administrator) terminal, or move npm's global prefix", "somewhere you own:", " npm config set prefix %LOCALAPPDATA%\\npm-global", ' setx PATH "%LOCALAPPDATA%\\npm-global;%PATH%"', " (then open a NEW terminal so the PATH change is picked up)");
605677
+ }
605678
+ return lines2.join(`
605679
+ `);
605680
+ }
605681
+ if (isLikelyEacces(err2)) {
605682
+ lines2.push("", "This looks like a permissions error on npm's global install", "directory. If Node was installed via nvm, Homebrew, Volta, or fnm,", "do NOT use sudo — it installs into a root-owned path that will", "conflict with your user-owned Node version. Instead fix npm's", "global prefix, e.g.:", " mkdir -p ~/.npm-global", " npm config set prefix ~/.npm-global", " export PATH=~/.npm-global/bin:$PATH # add to your shell rc file", "Only use sudo if Node was installed system-wide (e.g. via apt/yum", "or the nodejs.org installer):", ` sudo ${cmd}`);
605683
+ } else {
605684
+ lines2.push("", "Or with sudo if you have permission issues:", ` sudo ${cmd}`);
605685
+ }
605686
+ return lines2.join(`
605687
+ `);
605688
+ }
605689
+ function buildWindowsDeferredInstallScript(packageSpec, pid) {
605690
+ if (!Number.isInteger(pid) || pid <= 0) {
605691
+ throw new Error(`buildWindowsDeferredInstallScript: invalid pid ${pid}`);
605692
+ }
605693
+ if (packageSpec.includes('"')) {
605694
+ throw new Error(`buildWindowsDeferredInstallScript: refusing to quote a spec containing a double quote: ${JSON.stringify(packageSpec)}`);
605695
+ }
605696
+ return [
605697
+ "@echo off",
605698
+ "title Rayu update",
605699
+ "echo Waiting for Rayu to exit...",
605700
+ "set /a _tries=0",
605701
+ ":wait",
605702
+ `tasklist /FI "PID eq ${pid}" /NH 2>nul | find "${pid}" >nul`,
605703
+ "if errorlevel 1 goto run",
605704
+ "set /a _tries+=1",
605705
+ "if %_tries% GEQ 60 goto run",
605706
+ "timeout /t 1 /nobreak >nul 2>&1 || ping -n 2 127.0.0.1 >nul",
605707
+ "goto wait",
605708
+ ":run",
605709
+ "echo Installing Rayu CLI...",
605710
+ "echo.",
605711
+ `call npm install -g "${packageSpec}"`,
605712
+ "if errorlevel 1 (",
605713
+ " echo.",
605714
+ " echo Update FAILED. Close all Rayu windows and run this in a new terminal:",
605715
+ ` echo npm install -g ${packageSpec}`,
605716
+ " echo If npm cannot write to its global folder, run that terminal as Administrator.",
605717
+ ") else (",
605718
+ " echo.",
605719
+ " echo Rayu CLI updated successfully.",
605720
+ ")",
605721
+ "echo.",
605722
+ "echo Press any key to close this window.",
605723
+ "pause >nul",
605724
+ ""
605725
+ ].join(`\r
605726
+ `);
605727
+ }
605728
+ function scheduleWindowsDeferredInstall(packageSpec) {
605729
+ if (!IS_WINDOWS2)
605730
+ return false;
605731
+ try {
605732
+ const scriptPath = join156(tmpdir16(), `rayu-update-${process.pid}.cmd`);
605733
+ writeFileSync18(scriptPath, buildWindowsDeferredInstallScript(packageSpec, process.pid), "utf8");
605734
+ const child = spawn13("cmd.exe", ["/d", "/s", "/c", "start", "", scriptPath], {
605735
+ detached: true,
605736
+ stdio: "ignore",
605737
+ windowsHide: false
605738
+ });
605739
+ child.unref();
605740
+ return true;
605741
+ } catch {
605742
+ return false;
605743
+ }
605744
+ }
605319
605745
  var IS_WINDOWS2;
605320
605746
  var init_npmExec = __esm(() => {
605321
605747
  IS_WINDOWS2 = process.platform === "win32";
@@ -605327,7 +605753,7 @@ __export(exports_update, {
605327
605753
  update: () => update
605328
605754
  });
605329
605755
  async function update() {
605330
- writeToStdout(`Current version: ${"1.4.478"}
605756
+ writeToStdout(`Current version: ${"1.4.480"}
605331
605757
  `);
605332
605758
  const isBundled = isInBundledMode();
605333
605759
  if (isBundled) {
@@ -605358,13 +605784,13 @@ Manual check: npm view ${"@rayu-dev/rayu-cli"} version
605358
605784
  process.exit(1);
605359
605785
  return;
605360
605786
  }
605361
- if (latestVersion === "1.4.478") {
605787
+ if (latestVersion === "1.4.480") {
605362
605788
  writeToStdout(source_default.green(`
605363
- Rayu CLI is up to date (${"1.4.478"})
605789
+ Rayu CLI is up to date (${"1.4.480"})
605364
605790
  `));
605365
605791
  process.exit(0);
605366
605792
  }
605367
- writeToStdout(`New version available: ${latestVersion} (current: ${"1.4.478"})
605793
+ writeToStdout(`New version available: ${latestVersion} (current: ${"1.4.480"})
605368
605794
  `);
605369
605795
  writeToStdout(`Installing update...
605370
605796
 
@@ -605379,31 +605805,21 @@ Failed to install update
605379
605805
  if (detail)
605380
605806
  process.stderr.write(`${detail}
605381
605807
  `);
605382
- process.stderr.write(`
605383
- Try manually:
605384
- `);
605385
- process.stderr.write(source_default.bold(` npm install -g ${"@rayu-dev/rayu-cli"}@latest
605808
+ if (IS_WINDOWS2 && isLikelyWindowsFileLock(err2)) {
605809
+ const spec = `${"@rayu-dev/rayu-cli"}@latest`;
605810
+ if (scheduleWindowsDeferredInstall(spec)) {
605811
+ process.stderr.write(source_default.yellow(`
605812
+ Rayu could not replace its own files while it is running.
605386
605813
  `));
605387
- if (isLikelyEacces(err2)) {
605388
- process.stderr.write(`
605389
- This looks like a permissions error on npm's global install
605390
- ` + `directory. If Node was installed via nvm, Homebrew, Volta, or fnm,
605391
- ` + `do NOT use sudo — it installs into a root-owned path that will
605392
- ` + `conflict with your user-owned Node version. Instead fix npm's
605393
- ` + `global prefix, e.g.:
605394
- ` + ` mkdir -p ~/.npm-global
605395
- ` + ` npm config set prefix ~/.npm-global
605396
- ` + ` export PATH=~/.npm-global/bin:$PATH # add to your shell rc file
605397
- ` + `Only use sudo if Node was installed system-wide (e.g. via apt/yum
605398
- ` + `or the nodejs.org installer):
605399
- ` + ` sudo npm install -g ${"@rayu-dev/rayu-cli"}@latest
605400
- `);
605401
- } else {
605402
- process.stderr.write(`Or with sudo if you have permission issues:
605814
+ writeToStdout(`A new window has opened to finish the update as soon as Rayu exits.
605815
+ ` + `Leave it open until it reports success, then reopen your terminal.
605403
605816
  `);
605404
- process.stderr.write(source_default.bold(` sudo npm install -g ${"@rayu-dev/rayu-cli"}@latest
605405
- `));
605817
+ process.exit(1);
605818
+ return;
605819
+ }
605406
605820
  }
605821
+ process.stderr.write(`${buildNpmRemediation("install", `${"@rayu-dev/rayu-cli"}@latest`, err2)}
605822
+ `);
605407
605823
  process.exit(1);
605408
605824
  return;
605409
605825
  }
@@ -605431,14 +605847,14 @@ async function updateNativeBinary() {
605431
605847
  } catch {
605432
605848
  latestVersion = "";
605433
605849
  }
605434
- if (latestVersion && latestVersion === "1.4.478") {
605850
+ if (latestVersion && latestVersion === "1.4.480") {
605435
605851
  writeToStdout(source_default.green(`
605436
- Rayu CLI is up to date (1.4.478)
605852
+ Rayu CLI is up to date (1.4.480)
605437
605853
  `));
605438
605854
  process.exit(0);
605439
605855
  }
605440
605856
  if (latestVersion) {
605441
- writeToStdout(`New version available: ${latestVersion} (current: 1.4.478)
605857
+ writeToStdout(`New version available: ${latestVersion} (current: 1.4.480)
605442
605858
  `);
605443
605859
  }
605444
605860
  writeToStdout(`Downloading and installing update...
@@ -605453,13 +605869,13 @@ Rayu CLI is up to date (1.4.478)
605453
605869
  return;
605454
605870
  }
605455
605871
  writeToStdout(source_default.green(`
605456
- Rayu CLI is up to date (1.4.478)
605872
+ Rayu CLI is up to date (1.4.480)
605457
605873
  `));
605458
605874
  process.exit(0);
605459
605875
  }
605460
605876
  const updatedTo = result.latestVersion ?? latestVersion ?? "latest";
605461
605877
  writeToStdout(source_default.green(`
605462
- Successfully updated from 1.4.478 to ${updatedTo}
605878
+ Successfully updated from 1.4.480 to ${updatedTo}
605463
605879
  `));
605464
605880
  writeToStdout(`Restart your terminal to use the new version.
605465
605881
  `);
@@ -605524,7 +605940,7 @@ async function removeDataDir(dir) {
605524
605940
  async function uninstall(args = []) {
605525
605941
  const yes = args.includes("--yes") || args.includes("-y");
605526
605942
  const keepData = args.includes("--keep-data");
605527
- writeToStdout(`Uninstalling Rayu CLI (${"1.4.478"})...
605943
+ writeToStdout(`Uninstalling Rayu CLI (${"1.4.480"})...
605528
605944
  `);
605529
605945
  writeToStdout(`Running: npm uninstall -g ${"@rayu-dev/rayu-cli"}
605530
605946
 
@@ -605535,30 +605951,17 @@ async function uninstall(args = []) {
605535
605951
  process.stderr.write(source_default.red(`
605536
605952
  Failed to uninstall ${"@rayu-dev/rayu-cli"}
605537
605953
  `));
605538
- process.stderr.write(`
605539
- Try running manually:
605540
- `);
605541
- process.stderr.write(source_default.bold(` npm uninstall -g ${"@rayu-dev/rayu-cli"}
605542
- `));
605543
- if (isLikelyEacces(err2)) {
605544
- process.stderr.write(`
605545
- This looks like a permissions error on npm's global install
605546
- ` + `directory. If Node was installed via nvm, Homebrew, Volta, or fnm,
605547
- ` + `do NOT use sudo. Only use sudo if Node was installed system-wide
605548
- ` + `(e.g. via apt/yum or the nodejs.org installer):
605549
- ` + ` sudo npm uninstall -g ${"@rayu-dev/rayu-cli"}
605954
+ const detail = describeNpmError(err2);
605955
+ if (detail)
605956
+ process.stderr.write(`${detail}
605550
605957
  `);
605551
- } else {
605552
- process.stderr.write(`Or with sudo if you installed with elevated permissions:
605958
+ process.stderr.write(`${buildNpmRemediation("uninstall", "@rayu-dev/rayu-cli", err2)}
605553
605959
  `);
605554
- process.stderr.write(source_default.bold(` sudo npm uninstall -g ${"@rayu-dev/rayu-cli"}
605555
- `));
605556
- }
605557
605960
  process.exit(1);
605558
605961
  return;
605559
605962
  }
605560
605963
  writeToStdout(source_default.green(`
605561
- Successfully uninstalled ${"@rayu-dev/rayu-cli"} ${"1.4.478"}
605964
+ Successfully uninstalled ${"@rayu-dev/rayu-cli"} ${"1.4.480"}
605562
605965
  `));
605563
605966
  const configDir = getRayuConfigHomeDir();
605564
605967
  const dataExists = existsSync28(configDir);
@@ -605604,10 +606007,10 @@ var exports_firstRun = {};
605604
606007
  __export(exports_firstRun, {
605605
606008
  showFirstRunWelcome: () => showFirstRunWelcome
605606
606009
  });
605607
- import { existsSync as existsSync29, mkdirSync as mkdirSync16, writeFileSync as writeFileSync18 } from "node:fs";
605608
- import { join as join156 } from "node:path";
606010
+ import { existsSync as existsSync29, mkdirSync as mkdirSync16, writeFileSync as writeFileSync19 } from "node:fs";
606011
+ import { join as join157 } from "node:path";
605609
606012
  function markerPath() {
605610
- return join156(getRayuConfigHomeDir(), ".installed");
606013
+ return join157(getRayuConfigHomeDir(), ".installed");
605611
606014
  }
605612
606015
  function showFirstRunWelcome() {
605613
606016
  try {
@@ -605641,7 +606044,7 @@ function showFirstRunWelcome() {
605641
606044
  `);
605642
606045
  try {
605643
606046
  mkdirSync16(getRayuConfigHomeDir(), { recursive: true });
605644
- writeFileSync18(markerPath(), "1.4.478", "utf8");
606047
+ writeFileSync19(markerPath(), "1.4.480", "utf8");
605645
606048
  } catch {}
605646
606049
  }
605647
606050
  var init_firstRun = __esm(() => {
@@ -621827,7 +622230,7 @@ async function initializeBetaTracing(resource) {
621827
622230
  });
621828
622231
  import_api_logs.logs.setGlobalLoggerProvider(loggerProvider);
621829
622232
  setLoggerProvider(loggerProvider);
621830
- const eventLogger = import_api_logs.logs.getLogger("com.anthropic.claude_code.events", "1.4.478");
622233
+ const eventLogger = import_api_logs.logs.getLogger("com.anthropic.claude_code.events", "1.4.480");
621831
622234
  setEventLogger(eventLogger);
621832
622235
  process.on("beforeExit", async () => {
621833
622236
  await loggerProvider?.forceFlush();
@@ -621867,7 +622270,7 @@ async function initializeTelemetry() {
621867
622270
  const platform4 = getPlatform();
621868
622271
  const baseAttributes = {
621869
622272
  [import_semantic_conventions.ATTR_SERVICE_NAME]: "claude-code",
621870
- [import_semantic_conventions.ATTR_SERVICE_VERSION]: "1.4.478"
622273
+ [import_semantic_conventions.ATTR_SERVICE_VERSION]: "1.4.480"
621871
622274
  };
621872
622275
  if (platform4 === "wsl") {
621873
622276
  const wslVersion = getWslVersion();
@@ -621912,7 +622315,7 @@ async function initializeTelemetry() {
621912
622315
  } catch {}
621913
622316
  };
621914
622317
  registerCleanup(shutdownTelemetry2);
621915
- return meterProvider2.getMeter("com.anthropic.claude_code", "1.4.478");
622318
+ return meterProvider2.getMeter("com.anthropic.claude_code", "1.4.480");
621916
622319
  }
621917
622320
  const meterProvider = new import_sdk_metrics2.MeterProvider({
621918
622321
  resource,
@@ -621932,7 +622335,7 @@ async function initializeTelemetry() {
621932
622335
  });
621933
622336
  import_api_logs.logs.setGlobalLoggerProvider(loggerProvider);
621934
622337
  setLoggerProvider(loggerProvider);
621935
- const eventLogger = import_api_logs.logs.getLogger("com.anthropic.claude_code.events", "1.4.478");
622338
+ const eventLogger = import_api_logs.logs.getLogger("com.anthropic.claude_code.events", "1.4.480");
621936
622339
  setEventLogger(eventLogger);
621937
622340
  logForDebugging("[3P telemetry] Event logger set successfully");
621938
622341
  process.on("beforeExit", async () => {
@@ -621994,7 +622397,7 @@ Current timeout: ${timeoutMs}ms
621994
622397
  }
621995
622398
  };
621996
622399
  registerCleanup(shutdownTelemetry);
621997
- return meterProvider.getMeter("com.anthropic.claude_code", "1.4.478");
622400
+ return meterProvider.getMeter("com.anthropic.claude_code", "1.4.480");
621998
622401
  }
621999
622402
  async function flushTelemetry() {
622000
622403
  const meterProvider = getMeterProvider();
@@ -623004,7 +623407,7 @@ var init_notifier = __esm(() => {
623004
623407
  });
623005
623408
 
623006
623409
  // src/services/preventSleep.ts
623007
- import { spawn as spawn13 } from "child_process";
623410
+ import { spawn as spawn14 } from "child_process";
623008
623411
  function startPreventSleep() {
623009
623412
  refCount++;
623010
623413
  if (refCount === 1) {
@@ -623062,7 +623465,7 @@ function spawnCaffeinate() {
623062
623465
  });
623063
623466
  }
623064
623467
  try {
623065
- caffeinateProcess = spawn13("caffeinate", ["-i", "-t", String(CAFFEINATE_TIMEOUT_SECONDS)], {
623468
+ caffeinateProcess = spawn14("caffeinate", ["-i", "-t", String(CAFFEINATE_TIMEOUT_SECONDS)], {
623066
623469
  stdio: "ignore"
623067
623470
  });
623068
623471
  caffeinateProcess.unref();
@@ -623496,7 +623899,7 @@ function buildSystemInitMessage(inputs) {
623496
623899
  slash_commands: inputs.commands.filter((c4) => c4.userInvocable !== false).map((c4) => c4.name),
623497
623900
  apiKeySource: getAnthropicApiKeyWithSource().source,
623498
623901
  betas: getSdkBetas(),
623499
- claude_code_version: "1.4.478",
623902
+ claude_code_version: "1.4.480",
623500
623903
  output_style: outputStyle2,
623501
623904
  agents: inputs.agents.map((agent) => agent.agentType),
623502
623905
  skills: inputs.skills.filter((s2) => s2.userInvocable !== false).map((skill) => skill.name),
@@ -624375,8 +624778,8 @@ var init_streamingMirror = __esm(() => {
624375
624778
 
624376
624779
  // src/telegram/telegramBridge.ts
624377
624780
  import { hostname as hostname3 } from "os";
624378
- import { closeSync as closeSync5, existsSync as existsSync30, openSync as openSync6, readFileSync as readFileSync30, unlinkSync as unlinkSync4, writeFileSync as writeFileSync19, writeSync as writeSync3 } from "fs";
624379
- import { join as join157 } from "path";
624781
+ import { closeSync as closeSync5, existsSync as existsSync30, openSync as openSync6, readFileSync as readFileSync30, unlinkSync as unlinkSync4, writeFileSync as writeFileSync20, writeSync as writeSync3 } from "fs";
624782
+ import { join as join158 } from "path";
624380
624783
  function linkedChatId() {
624381
624784
  return readTelegramConfig().linkedChatId;
624382
624785
  }
@@ -624604,7 +625007,7 @@ async function registerCommandsWithTelegram(token) {
624604
625007
  } catch {}
624605
625008
  }
624606
625009
  function lockFilePath() {
624607
- return join157(getRayuConfigHomeDir(), "telegram-bridge.lock");
625010
+ return join158(getRayuConfigHomeDir(), "telegram-bridge.lock");
624608
625011
  }
624609
625012
  function isPidAlive(pid) {
624610
625013
  try {
@@ -624665,7 +625068,7 @@ function acquireBridgeLock() {
624665
625068
  return false;
624666
625069
  }
624667
625070
  }
624668
- writeFileSync19(path27, content, { mode: 384 });
625071
+ writeFileSync20(path27, content, { mode: 384 });
624669
625072
  } catch {}
624670
625073
  return true;
624671
625074
  }
@@ -624677,7 +625080,7 @@ function updateHeartbeat() {
624677
625080
  const raw = readFileSync30(path27, "utf8").trim();
624678
625081
  const pid = parseInt(raw.split(":")[0] ?? "", 10);
624679
625082
  if (pid === process.pid) {
624680
- writeFileSync19(path27, buildLockContent(), { mode: 384 });
625083
+ writeFileSync20(path27, buildLockContent(), { mode: 384 });
624681
625084
  }
624682
625085
  } catch {}
624683
625086
  }
@@ -631263,7 +631666,7 @@ var init_ShowInIDEPrompt = __esm(() => {
631263
631666
 
631264
631667
  // src/components/permissions/FilePermissionDialog/permissionOptions.tsx
631265
631668
  import { homedir as homedir36 } from "os";
631266
- import { basename as basename52, join as join158, sep as sep40 } from "path";
631669
+ import { basename as basename52, join as join159, sep as sep40 } from "path";
631267
631670
  function isInRayuFolder(filePath) {
631268
631671
  const absolutePath = expandPath(filePath);
631269
631672
  const rayuFolderPath = expandPath(`${getOriginalCwd()}/.rayu`);
@@ -631273,7 +631676,7 @@ function isInRayuFolder(filePath) {
631273
631676
  }
631274
631677
  function isInGlobalRayuFolder(filePath) {
631275
631678
  const absolutePath = expandPath(filePath);
631276
- const globalRayuFolderPath = join158(homedir36(), ".rayu");
631679
+ const globalRayuFolderPath = join159(homedir36(), ".rayu");
631277
631680
  const normalizedAbsolutePath = normalizeCaseForComparison2(absolutePath);
631278
631681
  const normalizedGlobalRayuFolderPath = normalizeCaseForComparison2(globalRayuFolderPath);
631279
631682
  return normalizedAbsolutePath.startsWith(normalizedGlobalRayuFolderPath + sep40.toLowerCase()) || normalizedAbsolutePath.startsWith(normalizedGlobalRayuFolderPath + "/");
@@ -639870,7 +640273,7 @@ var init_useVoiceEnabled = __esm(() => {
639870
640273
  function getSemverPart(version3) {
639871
640274
  return `${import_semver12.major(version3, { loose: true })}.${import_semver12.minor(version3, { loose: true })}.${import_semver12.patch(version3, { loose: true })}`;
639872
640275
  }
639873
- function useUpdateNotification(updatedVersion, initialVersion = "1.4.478") {
640276
+ function useUpdateNotification(updatedVersion, initialVersion = "1.4.480") {
639874
640277
  const [lastNotifiedSemver, setLastNotifiedSemver] = import_react217.useState(() => getSemverPart(initialVersion));
639875
640278
  if (!updatedVersion) {
639876
640279
  return null;
@@ -639910,7 +640313,7 @@ function AutoUpdater({
639910
640313
  return;
639911
640314
  }
639912
640315
  if (false) {}
639913
- const currentVersion = "1.4.478";
640316
+ const currentVersion = "1.4.480";
639914
640317
  const channel2 = getInitialSettings()?.autoUpdatesChannel ?? "latest";
639915
640318
  let latestVersion = await getLatestVersion(channel2);
639916
640319
  const isDisabled = isAutoUpdaterDisabled();
@@ -640123,12 +640526,12 @@ function NativeAutoUpdater({
640123
640526
  logEvent("tengu_native_auto_updater_start", {});
640124
640527
  try {
640125
640528
  const maxVersion = await getMaxVersion();
640126
- if (maxVersion && gt("1.4.478", maxVersion)) {
640529
+ if (maxVersion && gt("1.4.480", maxVersion)) {
640127
640530
  const msg = await getMaxVersionMessage();
640128
640531
  setMaxVersionIssue(msg ?? "affects your version");
640129
640532
  }
640130
640533
  const result = await installLatest(channel2);
640131
- const currentVersion = "1.4.478";
640534
+ const currentVersion = "1.4.480";
640132
640535
  const latencyMs = Date.now() - startTime2;
640133
640536
  if (result.lockFailed) {
640134
640537
  logEvent("tengu_native_auto_updater_lock_contention", {
@@ -640265,17 +640668,17 @@ function PackageManagerAutoUpdater(t0) {
640265
640668
  const maxVersion = await getMaxVersion();
640266
640669
  if (maxVersion && latest && gt(latest, maxVersion)) {
640267
640670
  logForDebugging(`PackageManagerAutoUpdater: maxVersion ${maxVersion} is set, capping update from ${latest} to ${maxVersion}`);
640268
- if (gte("1.4.478", maxVersion)) {
640269
- logForDebugging(`PackageManagerAutoUpdater: current version ${"1.4.478"} is already at or above maxVersion ${maxVersion}, skipping update`);
640671
+ if (gte("1.4.480", maxVersion)) {
640672
+ logForDebugging(`PackageManagerAutoUpdater: current version ${"1.4.480"} is already at or above maxVersion ${maxVersion}, skipping update`);
640270
640673
  setUpdateAvailable(false);
640271
640674
  return;
640272
640675
  }
640273
640676
  latest = maxVersion;
640274
640677
  }
640275
- const hasUpdate = latest && !gte("1.4.478", latest) && !shouldSkipVersion(latest);
640678
+ const hasUpdate = latest && !gte("1.4.480", latest) && !shouldSkipVersion(latest);
640276
640679
  setUpdateAvailable(!!hasUpdate);
640277
640680
  if (hasUpdate) {
640278
- logForDebugging(`PackageManagerAutoUpdater: Update available ${"1.4.478"} -> ${latest}`);
640681
+ logForDebugging(`PackageManagerAutoUpdater: Update available ${"1.4.480"} -> ${latest}`);
640279
640682
  }
640280
640683
  };
640281
640684
  $3[0] = t1;
@@ -640309,7 +640712,7 @@ function PackageManagerAutoUpdater(t0) {
640309
640712
  wrap: "truncate",
640310
640713
  children: [
640311
640714
  "currentVersion: ",
640312
- "1.4.478"
640715
+ "1.4.480"
640313
640716
  ]
640314
640717
  });
640315
640718
  $3[3] = verbose;
@@ -648473,7 +648876,7 @@ function buildStatusLineCommandInput(permissionMode, exceeds200kTokens, settings
648473
648876
  project_dir: getOriginalCwd(),
648474
648877
  added_dirs: addedDirs
648475
648878
  },
648476
- version: "1.4.478",
648879
+ version: "1.4.480",
648477
648880
  output_style: {
648478
648881
  name: outputStyleName
648479
648882
  },
@@ -650652,7 +651055,7 @@ var init_user = __esm(() => {
650652
651055
  deviceId,
650653
651056
  sessionId: getSessionId(),
650654
651057
  email: getEmail(),
650655
- appVersion: "1.4.478",
651058
+ appVersion: "1.4.480",
650656
651059
  platform: getHostPlatformForAnalytics(),
650657
651060
  organizationUuid,
650658
651061
  accountUuid,
@@ -654689,9 +655092,9 @@ function initSkillImprovement() {
654689
655092
  async function applySkillImprovement(skillName, updates) {
654690
655093
  if (!skillName)
654691
655094
  return;
654692
- const { join: join159 } = await import("path");
655095
+ const { join: join160 } = await import("path");
654693
655096
  const fs15 = await import("fs/promises");
654694
- const filePath = join159(getCwd(), ".rayu", "skills", skillName, "SKILL.md");
655097
+ const filePath = join160(getCwd(), ".rayu", "skills", skillName, "SKILL.md");
654695
655098
  let currentContent;
654696
655099
  try {
654697
655100
  currentContent = await fs15.readFile(filePath, "utf-8");
@@ -654842,7 +655245,7 @@ function useMoreRight(_args) {
654842
655245
  }
654843
655246
 
654844
655247
  // src/utils/cleanup.ts
654845
- import { join as join159 } from "path";
655248
+ import { join as join160 } from "path";
654846
655249
  function getCutoffDate() {
654847
655250
  const settings = getSettings_DEPRECATED() || {};
654848
655251
  const cleanupPeriodDays = settings.cleanupPeriodDays ?? DEFAULT_CLEANUP_PERIOD_DAYS;
@@ -654867,7 +655270,7 @@ async function cleanupOldFilesInDirectory(dirPath, cutoffDate, isMessagePath) {
654867
655270
  try {
654868
655271
  const timestamp = convertFileNameToDate(file2.name);
654869
655272
  if (timestamp < cutoffDate) {
654870
- await getFsImplementation().unlink(join159(dirPath, file2.name));
655273
+ await getFsImplementation().unlink(join160(dirPath, file2.name));
654871
655274
  if (isMessagePath) {
654872
655275
  result.messages++;
654873
655276
  } else {
@@ -654898,7 +655301,7 @@ async function cleanupOldMessageFiles() {
654898
655301
  } catch {
654899
655302
  return result;
654900
655303
  }
654901
- const mcpLogDirs = dirents.filter((dirent) => dirent.isDirectory() && dirent.name.startsWith("mcp-logs-")).map((dirent) => join159(baseCachePath, dirent.name));
655304
+ const mcpLogDirs = dirents.filter((dirent) => dirent.isDirectory() && dirent.name.startsWith("mcp-logs-")).map((dirent) => join160(baseCachePath, dirent.name));
654902
655305
  for (const mcpLogDir of mcpLogDirs) {
654903
655306
  result = addCleanupResults(result, await cleanupOldFilesInDirectory(mcpLogDir, cutoffDate, true));
654904
655307
  await tryRmdir(mcpLogDir, fsImpl);
@@ -654937,7 +655340,7 @@ async function cleanupOldSessionFiles() {
654937
655340
  for (const projectDirent of projectDirents) {
654938
655341
  if (!projectDirent.isDirectory())
654939
655342
  continue;
654940
- const projectDir = join159(projectsDir, projectDirent.name);
655343
+ const projectDir = join160(projectsDir, projectDirent.name);
654941
655344
  let entries;
654942
655345
  try {
654943
655346
  entries = await fsImpl.readdir(projectDir);
@@ -654951,15 +655354,15 @@ async function cleanupOldSessionFiles() {
654951
655354
  continue;
654952
655355
  }
654953
655356
  try {
654954
- if (await unlinkIfOld(join159(projectDir, entry.name), cutoffDate, fsImpl)) {
655357
+ if (await unlinkIfOld(join160(projectDir, entry.name), cutoffDate, fsImpl)) {
654955
655358
  result.messages++;
654956
655359
  }
654957
655360
  } catch {
654958
655361
  result.errors++;
654959
655362
  }
654960
655363
  } else if (entry.isDirectory()) {
654961
- const sessionDir = join159(projectDir, entry.name);
654962
- const toolResultsDir = join159(sessionDir, TOOL_RESULTS_SUBDIR);
655364
+ const sessionDir = join160(projectDir, entry.name);
655365
+ const toolResultsDir = join160(sessionDir, TOOL_RESULTS_SUBDIR);
654963
655366
  let toolDirs;
654964
655367
  try {
654965
655368
  toolDirs = await fsImpl.readdir(toolResultsDir);
@@ -654970,14 +655373,14 @@ async function cleanupOldSessionFiles() {
654970
655373
  for (const toolEntry of toolDirs) {
654971
655374
  if (toolEntry.isFile()) {
654972
655375
  try {
654973
- if (await unlinkIfOld(join159(toolResultsDir, toolEntry.name), cutoffDate, fsImpl)) {
655376
+ if (await unlinkIfOld(join160(toolResultsDir, toolEntry.name), cutoffDate, fsImpl)) {
654974
655377
  result.messages++;
654975
655378
  }
654976
655379
  } catch {
654977
655380
  result.errors++;
654978
655381
  }
654979
655382
  } else if (toolEntry.isDirectory()) {
654980
- const toolDirPath = join159(toolResultsDir, toolEntry.name);
655383
+ const toolDirPath = join160(toolResultsDir, toolEntry.name);
654981
655384
  let toolFiles;
654982
655385
  try {
654983
655386
  toolFiles = await fsImpl.readdir(toolDirPath);
@@ -654988,7 +655391,7 @@ async function cleanupOldSessionFiles() {
654988
655391
  if (!tf.isFile())
654989
655392
  continue;
654990
655393
  try {
654991
- if (await unlinkIfOld(join159(toolDirPath, tf.name), cutoffDate, fsImpl)) {
655394
+ if (await unlinkIfOld(join160(toolDirPath, tf.name), cutoffDate, fsImpl)) {
654992
655395
  result.messages++;
654993
655396
  }
654994
655397
  } catch {
@@ -655020,7 +655423,7 @@ async function cleanupSingleDirectory(dirPath, extension2, removeEmptyDir = true
655020
655423
  if (!dirent.isFile() || !dirent.name.endsWith(extension2))
655021
655424
  continue;
655022
655425
  try {
655023
- if (await unlinkIfOld(join159(dirPath, dirent.name), cutoffDate, fsImpl)) {
655426
+ if (await unlinkIfOld(join160(dirPath, dirent.name), cutoffDate, fsImpl)) {
655024
655427
  result.messages++;
655025
655428
  }
655026
655429
  } catch {
@@ -655033,7 +655436,7 @@ async function cleanupSingleDirectory(dirPath, extension2, removeEmptyDir = true
655033
655436
  return result;
655034
655437
  }
655035
655438
  function cleanupOldPlanFiles() {
655036
- const plansDir = join159(getRayuConfigHomeDir(), "plans");
655439
+ const plansDir = join160(getRayuConfigHomeDir(), "plans");
655037
655440
  return cleanupSingleDirectory(plansDir, ".md");
655038
655441
  }
655039
655442
  async function cleanupOldFileHistoryBackups() {
@@ -655042,14 +655445,14 @@ async function cleanupOldFileHistoryBackups() {
655042
655445
  const fsImpl = getFsImplementation();
655043
655446
  try {
655044
655447
  const configDir = getRayuConfigHomeDir();
655045
- const fileHistoryStorageDir = join159(configDir, "file-history");
655448
+ const fileHistoryStorageDir = join160(configDir, "file-history");
655046
655449
  let dirents;
655047
655450
  try {
655048
655451
  dirents = await fsImpl.readdir(fileHistoryStorageDir);
655049
655452
  } catch {
655050
655453
  return result;
655051
655454
  }
655052
- const fileHistorySessionsDirs = dirents.filter((dirent) => dirent.isDirectory()).map((dirent) => join159(fileHistoryStorageDir, dirent.name));
655455
+ const fileHistorySessionsDirs = dirents.filter((dirent) => dirent.isDirectory()).map((dirent) => join160(fileHistoryStorageDir, dirent.name));
655053
655456
  await Promise.all(fileHistorySessionsDirs.map(async (fileHistorySessionDir) => {
655054
655457
  try {
655055
655458
  const stats3 = await fsImpl.stat(fileHistorySessionDir);
@@ -655076,14 +655479,14 @@ async function cleanupOldSessionEnvDirs() {
655076
655479
  const fsImpl = getFsImplementation();
655077
655480
  try {
655078
655481
  const configDir = getRayuConfigHomeDir();
655079
- const sessionEnvBaseDir = join159(configDir, "session-env");
655482
+ const sessionEnvBaseDir = join160(configDir, "session-env");
655080
655483
  let dirents;
655081
655484
  try {
655082
655485
  dirents = await fsImpl.readdir(sessionEnvBaseDir);
655083
655486
  } catch {
655084
655487
  return result;
655085
655488
  }
655086
- const sessionEnvDirs = dirents.filter((dirent) => dirent.isDirectory()).map((dirent) => join159(sessionEnvBaseDir, dirent.name));
655489
+ const sessionEnvDirs = dirents.filter((dirent) => dirent.isDirectory()).map((dirent) => join160(sessionEnvBaseDir, dirent.name));
655087
655490
  for (const sessionEnvDir of sessionEnvDirs) {
655088
655491
  try {
655089
655492
  const stats3 = await fsImpl.stat(sessionEnvDir);
@@ -655105,7 +655508,7 @@ async function cleanupOldDebugLogs() {
655105
655508
  const cutoffDate = getCutoffDate();
655106
655509
  const result = { messages: 0, errors: 0 };
655107
655510
  const fsImpl = getFsImplementation();
655108
- const debugDir = join159(getRayuConfigHomeDir(), "debug");
655511
+ const debugDir = join160(getRayuConfigHomeDir(), "debug");
655109
655512
  let dirents;
655110
655513
  try {
655111
655514
  dirents = await fsImpl.readdir(debugDir);
@@ -655117,7 +655520,7 @@ async function cleanupOldDebugLogs() {
655117
655520
  continue;
655118
655521
  }
655119
655522
  try {
655120
- if (await unlinkIfOld(join159(debugDir, dirent.name), cutoffDate, fsImpl)) {
655523
+ if (await unlinkIfOld(join160(debugDir, dirent.name), cutoffDate, fsImpl)) {
655121
655524
  result.messages++;
655122
655525
  }
655123
655526
  } catch {
@@ -658429,7 +658832,7 @@ __export(exports_asciicast, {
658429
658832
  _resetRecordingStateForTesting: () => _resetRecordingStateForTesting
658430
658833
  });
658431
658834
  import { appendFile as appendFile5, rename as rename13 } from "fs/promises";
658432
- import { basename as basename61, dirname as dirname67, join as join161 } from "path";
658835
+ import { basename as basename61, dirname as dirname67, join as join162 } from "path";
658433
658836
  function getRecordFilePath() {
658434
658837
  if (recordingState.filePath !== null) {
658435
658838
  return recordingState.filePath;
@@ -658440,10 +658843,10 @@ function getRecordFilePath() {
658440
658843
  if (!isEnvTruthy(process.env.CLAUDE_CODE_TERMINAL_RECORDING)) {
658441
658844
  return null;
658442
658845
  }
658443
- const projectsDir = join161(getRayuConfigHomeDir(), "projects");
658444
- const projectDir = join161(projectsDir, sanitizePath2(getOriginalCwd()));
658846
+ const projectsDir = join162(getRayuConfigHomeDir(), "projects");
658847
+ const projectDir = join162(projectsDir, sanitizePath2(getOriginalCwd()));
658445
658848
  recordingState.timestamp = Date.now();
658446
- recordingState.filePath = join161(projectDir, `${getSessionId()}-${recordingState.timestamp}.cast`);
658849
+ recordingState.filePath = join162(projectDir, `${getSessionId()}-${recordingState.timestamp}.cast`);
658447
658850
  return recordingState.filePath;
658448
658851
  }
658449
658852
  function _resetRecordingStateForTesting() {
@@ -658452,13 +658855,13 @@ function _resetRecordingStateForTesting() {
658452
658855
  }
658453
658856
  function getSessionRecordingPaths() {
658454
658857
  const sessionId = getSessionId();
658455
- const projectsDir = join161(getRayuConfigHomeDir(), "projects");
658456
- const projectDir = join161(projectsDir, sanitizePath2(getOriginalCwd()));
658858
+ const projectsDir = join162(getRayuConfigHomeDir(), "projects");
658859
+ const projectDir = join162(projectsDir, sanitizePath2(getOriginalCwd()));
658457
658860
  try {
658458
658861
  const entries = getFsImplementation().readdirSync(projectDir);
658459
658862
  const names = typeof entries[0] === "string" ? entries : entries.map((e2) => e2.name);
658460
658863
  const files3 = names.filter((f3) => f3.startsWith(sessionId) && f3.endsWith(".cast")).sort();
658461
- return files3.map((f3) => join161(projectDir, f3));
658864
+ return files3.map((f3) => join162(projectDir, f3));
658462
658865
  } catch {
658463
658866
  return [];
658464
658867
  }
@@ -658468,9 +658871,9 @@ async function renameRecordingForSession() {
658468
658871
  if (!oldPath || recordingState.timestamp === 0) {
658469
658872
  return;
658470
658873
  }
658471
- const projectsDir = join161(getRayuConfigHomeDir(), "projects");
658472
- const projectDir = join161(projectsDir, sanitizePath2(getOriginalCwd()));
658473
- const newPath = join161(projectDir, `${getSessionId()}-${recordingState.timestamp}.cast`);
658874
+ const projectsDir = join162(getRayuConfigHomeDir(), "projects");
658875
+ const projectDir = join162(projectsDir, sanitizePath2(getOriginalCwd()));
658876
+ const newPath = join162(projectDir, `${getSessionId()}-${recordingState.timestamp}.cast`);
658474
658877
  if (oldPath === newPath) {
658475
658878
  return;
658476
658879
  }
@@ -660091,7 +660494,7 @@ async function submitTranscriptShare(messages, trigger, appearanceId) {
660091
660494
  } catch {}
660092
660495
  const data = {
660093
660496
  trigger,
660094
- version: "1.4.478",
660497
+ version: "1.4.480",
660095
660498
  platform: process.platform,
660096
660499
  transcript,
660097
660500
  subagentTranscripts: Object.keys(subagentTranscripts).length > 0 ? subagentTranscripts : undefined,
@@ -661313,7 +661716,7 @@ var init_useAwaySummary = __esm(() => {
661313
661716
  });
661314
661717
 
661315
661718
  // src/utils/plugins/officialMarketplaceStartupCheck.ts
661316
- import { join as join162 } from "path";
661719
+ import { join as join163 } from "path";
661317
661720
  function isOfficialMarketplaceAutoInstallDisabled() {
661318
661721
  return isEnvTruthy(process.env.CLAUDE_CODE_DISABLE_OFFICIAL_MARKETPLACE_AUTOINSTALL);
661319
661722
  }
@@ -661396,7 +661799,7 @@ async function checkAndInstallOfficialMarketplace() {
661396
661799
  return { installed: false, skipped: true, reason: "policy_blocked" };
661397
661800
  }
661398
661801
  const cacheDir = getMarketplacesCacheDir();
661399
- const installLocation = join162(cacheDir, OFFICIAL_MARKETPLACE_NAME);
661802
+ const installLocation = join163(cacheDir, OFFICIAL_MARKETPLACE_NAME);
661400
661803
  const gcsSha = await fetchOfficialMarketplaceFromGcs(installLocation, cacheDir);
661401
661804
  if (gcsSha !== null) {
661402
661805
  const known = await loadKnownMarketplacesConfig();
@@ -661653,7 +662056,7 @@ var init_tipHistory = __esm(() => {
661653
662056
 
661654
662057
  // src/utils/desktopDeepLink.ts
661655
662058
  import { readdir as readdir30 } from "fs/promises";
661656
- import { join as join163 } from "path";
662059
+ import { join as join164 } from "path";
661657
662060
  function isDevMode() {
661658
662061
  if (false) {}
661659
662062
  const pathsToCheck = [process.argv[1] || "", process.execPath || ""];
@@ -661714,7 +662117,7 @@ async function getDesktopVersion() {
661714
662117
  if (!localAppData) {
661715
662118
  return null;
661716
662119
  }
661717
- const installDir = join163(localAppData, "AnthropicClaude");
662120
+ const installDir = join164(localAppData, "AnthropicClaude");
661718
662121
  try {
661719
662122
  const entries = await readdir30(installDir);
661720
662123
  const versions2 = entries.filter((e2) => e2.startsWith("app-")).map((e2) => e2.slice(4)).filter((v2) => import_semver16.coerce(v2) !== null).sort((a2, b3) => {
@@ -664708,7 +665111,7 @@ var init_usePluginRecommendationBase = __esm(() => {
664708
665111
  });
664709
665112
 
664710
665113
  // src/hooks/useLspPluginRecommendation.tsx
664711
- import { extname as extname15, join as join164 } from "path";
665114
+ import { extname as extname15, join as join165 } from "path";
664712
665115
  function useLspPluginRecommendation() {
664713
665116
  const $3 = import_compiler_runtime328.c(12);
664714
665117
  const trackedFiles = useAppState(_temp201);
@@ -664793,7 +665196,7 @@ function useLspPluginRecommendation() {
664793
665196
  case "yes": {
664794
665197
  installPluginAndNotify(pluginId, pluginName, "lsp-plugin", addNotification, async (pluginData) => {
664795
665198
  logForDebugging(`[useLspPluginRecommendation] Installing plugin: ${pluginId}`);
664796
- const localSourcePath = typeof pluginData.entry.source === "string" ? join164(pluginData.marketplaceInstallLocation, pluginData.entry.source) : undefined;
665199
+ const localSourcePath = typeof pluginData.entry.source === "string" ? join165(pluginData.marketplaceInstallLocation, pluginData.entry.source) : undefined;
664797
665200
  await cacheAndRegisterPlugin(pluginId, pluginData.entry, "user", undefined, localSourcePath);
664798
665201
  const settings = getSettingsForSource("userSettings");
664799
665202
  updateSettingsForSource("userSettings", {
@@ -667561,8 +667964,8 @@ var exports_REPL = {};
667561
667964
  __export(exports_REPL, {
667562
667965
  REPL: () => REPL
667563
667966
  });
667564
- import { dirname as dirname69, join as join165 } from "path";
667565
- import { tmpdir as tmpdir16 } from "os";
667967
+ import { dirname as dirname69, join as join166 } from "path";
667968
+ import { tmpdir as tmpdir17 } from "os";
667566
667969
  import { writeFile as writeFile45 } from "fs/promises";
667567
667970
  import { randomUUID as randomUUID50 } from "crypto";
667568
667971
  function TranscriptModeFooter(t0) {
@@ -670163,7 +670566,7 @@ Note: ctrl + z now suspends RAYU, ctrl + _ undoes input.
670163
670566
  const w2 = Math.max(80, (process.stdout.columns ?? 80) - 6);
670164
670567
  const raw = await renderMessagesToPlainText(deferredMessages, tools, w2);
670165
670568
  const text2 = raw.replace(/[ \t]+$/gm, "");
670166
- const path29 = join165(tmpdir16(), `cc-transcript-${Date.now()}.txt`);
670569
+ const path29 = join166(tmpdir17(), `cc-transcript-${Date.now()}.txt`);
670167
670570
  await writeFile45(path29, text2);
670168
670571
  const opened = openFileInExternalEditor(path29);
670169
670572
  setStatus(opened ? `opening ${path29}` : `wrote ${path29} · no $VISUAL/$EDITOR set`);
@@ -672060,7 +672463,7 @@ function WelcomeV2() {
672060
672463
  dimColor: true,
672061
672464
  children: [
672062
672465
  "v",
672063
- "1.4.478"
672466
+ "1.4.480"
672064
672467
  ]
672065
672468
  })
672066
672469
  ]
@@ -673067,7 +673470,7 @@ function completeOnboarding() {
673067
673470
  saveGlobalConfig((current) => ({
673068
673471
  ...current,
673069
673472
  hasCompletedOnboarding: true,
673070
- lastOnboardingVersion: "1.4.478"
673473
+ lastOnboardingVersion: "1.4.480"
673071
673474
  }));
673072
673475
  }
673073
673476
  function showDialog(root2, renderer) {
@@ -677951,12 +678354,12 @@ var init_createDirectConnectSession = __esm(() => {
677951
678354
  });
677952
678355
 
677953
678356
  // src/utils/errorLogSink.ts
677954
- import { dirname as dirname71, join as join166 } from "path";
678357
+ import { dirname as dirname71, join as join167 } from "path";
677955
678358
  function getErrorsPath() {
677956
- return join166(CACHE_PATHS.errors(), DATE + ".jsonl");
678359
+ return join167(CACHE_PATHS.errors(), DATE + ".jsonl");
677957
678360
  }
677958
678361
  function getMCPLogsPath(serverName) {
677959
- return join166(CACHE_PATHS.mcpLogs(serverName), DATE + ".jsonl");
678362
+ return join167(CACHE_PATHS.mcpLogs(serverName), DATE + ".jsonl");
677960
678363
  }
677961
678364
  function createJsonlWriter(options) {
677962
678365
  const writer = createBufferedWriter(options);
@@ -678000,7 +678403,7 @@ function appendToLog(path29, message) {
678000
678403
  cwd: getFsImplementation().cwd(),
678001
678404
  userType: "external",
678002
678405
  sessionId: getSessionId(),
678003
- version: "1.4.478"
678406
+ version: "1.4.480"
678004
678407
  };
678005
678408
  getLogWriter(path29).write(messageWithTimestamp);
678006
678409
  }
@@ -678291,7 +678694,7 @@ var init_sessionMemory = __esm(() => {
678291
678694
  // src/utils/iTermBackup.ts
678292
678695
  import { copyFile as copyFile12, stat as stat47 } from "fs/promises";
678293
678696
  import { homedir as homedir38 } from "os";
678294
- import { join as join167 } from "path";
678697
+ import { join as join168 } from "path";
678295
678698
  function markITerm2SetupComplete() {
678296
678699
  saveGlobalConfig((current) => ({
678297
678700
  ...current,
@@ -678306,7 +678709,7 @@ function getIterm2RecoveryInfo() {
678306
678709
  };
678307
678710
  }
678308
678711
  function getITerm2PlistPath() {
678309
- return join167(homedir38(), "Library", "Preferences", "com.googlecode.iterm2.plist");
678712
+ return join168(homedir38(), "Library", "Preferences", "com.googlecode.iterm2.plist");
678310
678713
  }
678311
678714
  async function checkAndRestoreITerm2Backup() {
678312
678715
  const { inProgress, backupPath } = getIterm2RecoveryInfo();
@@ -681799,7 +682202,7 @@ var init_idleTimeout = __esm(() => {
681799
682202
  // src/bridge/inboundAttachments.ts
681800
682203
  import { randomUUID as randomUUID53 } from "crypto";
681801
682204
  import { mkdir as mkdir43, writeFile as writeFile47 } from "fs/promises";
681802
- import { basename as basename62, join as join168 } from "path";
682205
+ import { basename as basename62, join as join169 } from "path";
681803
682206
  function debug3(msg) {
681804
682207
  logForDebugging(`[bridge:inbound-attach] ${msg}`);
681805
682208
  }
@@ -681815,7 +682218,7 @@ function sanitizeFileName(name) {
681815
682218
  return base2 || "attachment";
681816
682219
  }
681817
682220
  function uploadsDir() {
681818
- return join168(getRayuConfigHomeDir(), "uploads", getSessionId());
682221
+ return join169(getRayuConfigHomeDir(), "uploads", getSessionId());
681819
682222
  }
681820
682223
  async function resolveOne(att) {
681821
682224
  const token = getBridgeAccessToken();
@@ -681844,7 +682247,7 @@ async function resolveOne(att) {
681844
682247
  const safeName = sanitizeFileName(att.file_name);
681845
682248
  const prefix = (att.file_uuid.slice(0, 8) || randomUUID53().slice(0, 8)).replace(/[^a-zA-Z0-9_-]/g, "_");
681846
682249
  const dir = uploadsDir();
681847
- const outPath = join168(dir, `${prefix}-${safeName}`);
682250
+ const outPath = join169(dir, `${prefix}-${safeName}`);
681848
682251
  try {
681849
682252
  await mkdir43(dir, { recursive: true });
681850
682253
  await writeFile47(outPath, data);
@@ -681944,7 +682347,7 @@ var init_sessionUrl = __esm(() => {
681944
682347
 
681945
682348
  // src/utils/plugins/zipCacheAdapters.ts
681946
682349
  import { readFile as readFile54 } from "fs/promises";
681947
- import { join as join169 } from "path";
682350
+ import { join as join170 } from "path";
681948
682351
  async function readZipCacheKnownMarketplaces() {
681949
682352
  try {
681950
682353
  const content = await readFile54(getZipCacheKnownMarketplacesPath(), "utf-8");
@@ -681969,13 +682372,13 @@ async function saveMarketplaceJsonToZipCache(marketplaceName, installLocation) {
681969
682372
  const content = await readMarketplaceJsonContent(installLocation);
681970
682373
  if (content !== null) {
681971
682374
  const relPath = getMarketplaceJsonRelativePath(marketplaceName);
681972
- await atomicWriteToZipCache(join169(zipCachePath, relPath), content);
682375
+ await atomicWriteToZipCache(join170(zipCachePath, relPath), content);
681973
682376
  }
681974
682377
  }
681975
682378
  async function readMarketplaceJsonContent(dir) {
681976
682379
  const candidates = [
681977
- join169(dir, ".claude-plugin", "marketplace.json"),
681978
- join169(dir, "marketplace.json"),
682380
+ join170(dir, ".claude-plugin", "marketplace.json"),
682381
+ join170(dir, "marketplace.json"),
681979
682382
  dir
681980
682383
  ];
681981
682384
  for (const candidate of candidates) {
@@ -682105,8 +682508,8 @@ async function getEnvLessBridgeConfig() {
682105
682508
  }
682106
682509
  async function checkEnvLessBridgeMinVersion() {
682107
682510
  const cfg = await getEnvLessBridgeConfig();
682108
- if (cfg.min_version && lt("1.4.478", cfg.min_version)) {
682109
- return `Your version of RAYU (${"1.4.478"}) is too old for Remote Control.
682511
+ if (cfg.min_version && lt("1.4.480", cfg.min_version)) {
682512
+ return `Your version of RAYU (${"1.4.480"}) is too old for Remote Control.
682110
682513
  Version ${cfg.min_version} or higher is required. Run \`claude update\` to update.`;
682111
682514
  }
682112
682515
  return null;
@@ -682433,9 +682836,9 @@ __export(exports_bridgePointer, {
682433
682836
  BRIDGE_POINTER_TTL_MS: () => BRIDGE_POINTER_TTL_MS
682434
682837
  });
682435
682838
  import { mkdir as mkdir44, readFile as readFile55, stat as stat48, unlink as unlink25, writeFile as writeFile48 } from "fs/promises";
682436
- import { dirname as dirname72, join as join170 } from "path";
682839
+ import { dirname as dirname72, join as join171 } from "path";
682437
682840
  function getBridgePointerPath(dir) {
682438
- return join170(getProjectsDir(), sanitizePath2(dir), "bridge-pointer.json");
682841
+ return join171(getProjectsDir(), sanitizePath2(dir), "bridge-pointer.json");
682439
682842
  }
682440
682843
  async function writeBridgePointer(dir, pointer) {
682441
682844
  const path29 = getBridgePointerPath(dir);
@@ -682579,7 +682982,7 @@ async function initBridgeCore(params) {
682579
682982
  const rawApi = createBridgeApiClient({
682580
682983
  baseUrl,
682581
682984
  getAccessToken,
682582
- runnerVersion: "1.4.478",
682985
+ runnerVersion: "1.4.480",
682583
682986
  onDebug: logForDebugging,
682584
682987
  onAuth401,
682585
682988
  getTrustedDeviceToken
@@ -687934,7 +688337,7 @@ async function startMCPServer(cwd3, debug4, verbose) {
687934
688337
  setCwd(cwd3);
687935
688338
  const server = new Server({
687936
688339
  name: "claude/tengu",
687937
- version: "1.4.478"
688340
+ version: "1.4.480"
687938
688341
  }, {
687939
688342
  capabilities: {
687940
688343
  tools: {}
@@ -688916,12 +689319,12 @@ __export(exports_install, {
688916
689319
  install: () => install
688917
689320
  });
688918
689321
  import { homedir as homedir39 } from "node:os";
688919
- import { join as join171 } from "node:path";
689322
+ import { join as join172 } from "node:path";
688920
689323
  function getInstallationPath2() {
688921
689324
  const isWindows2 = env3.platform === "win32";
688922
689325
  const homeDir = homedir39();
688923
689326
  if (isWindows2) {
688924
- const windowsPath = join171(homeDir, ".local", "bin", "claude.exe");
689327
+ const windowsPath = join172(homeDir, ".local", "bin", "claude.exe");
688925
689328
  return windowsPath.replace(/\//g, "\\");
688926
689329
  }
688927
689330
  return "~/.local/bin/claude";
@@ -690463,7 +690866,7 @@ ${customInstructions}` : customInstructions;
690463
690866
  }
690464
690867
  }
690465
690868
  logForDiagnosticsNoPII("info", "started", {
690466
- version: "1.4.478",
690869
+ version: "1.4.480",
690467
690870
  is_native_binary: isInBundledMode()
690468
690871
  });
690469
690872
  registerCleanup(async () => {
@@ -691182,7 +691585,7 @@ Usage: rayu --remote "your task description"`, () => gracefulShutdown(1));
691182
691585
  pendingHookMessages
691183
691586
  }, renderAndRun);
691184
691587
  }
691185
- }).version(`1.4.478 (${PRODUCT_NAME})`, "-v, --version", "Output the version number");
691588
+ }).version(`1.4.480 (${PRODUCT_NAME})`, "-v, --version", "Output the version number");
691186
691589
  program.option("-w, --worktree [name]", "Create a new git worktree for this session (optionally specify a name)");
691187
691590
  program.option("--tmux", "Create a tmux session for the worktree (requires --worktree). Uses iTerm2 native panes when available; use --tmux=classic for traditional tmux.");
691188
691591
  if (canUserConfigureAdvisor()) {
@@ -691642,7 +692045,7 @@ if (false) {}
691642
692045
  async function main2() {
691643
692046
  const args = process.argv.slice(2);
691644
692047
  if (args.length === 1 && (args[0] === "--version" || args[0] === "-v" || args[0] === "-V")) {
691645
- console.log(`${"1.4.478"} (Rayu-CLI)`);
692048
+ console.log(`${"1.4.480"} (Rayu-CLI)`);
691646
692049
  return;
691647
692050
  }
691648
692051
  if (!isEnvTruthy(process.env.CLAUDE_CODE_DISABLE_TERMINAL_TITLE)) {