@rayu-dev/rayu-cli 1.4.474 → 1.4.476

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 +788 -147
  2. package/package.json +1 -1
package/dist/rayu.js CHANGED
@@ -148992,7 +148992,7 @@ var init_isEqual = __esm(() => {
148992
148992
 
148993
148993
  // src/utils/userAgent.ts
148994
148994
  function getRayuUserAgent() {
148995
- return `rayu/${"1.4.474"}`;
148995
+ return `rayu/${"1.4.476"}`;
148996
148996
  }
148997
148997
  var getClaudeCodeUserAgent;
148998
148998
  var init_userAgent = __esm(() => {
@@ -149018,7 +149018,7 @@ function getUserAgent() {
149018
149018
  const clientApp = process.env.RAYU_AGENT_SDK_CLIENT_APP ? `, client-app/${process.env.RAYU_AGENT_SDK_CLIENT_APP}` : "";
149019
149019
  const workload = getWorkload();
149020
149020
  const workloadSuffix = workload ? `, workload/${workload}` : "";
149021
- return `rayu/${"1.4.474"} (${"external"}, ${process.env.RAYU_ENTRYPOINT ?? "cli"}${agentSdkVersion}${clientApp}${workloadSuffix})`;
149021
+ return `rayu/${"1.4.476"} (${"external"}, ${process.env.RAYU_ENTRYPOINT ?? "cli"}${agentSdkVersion}${clientApp}${workloadSuffix})`;
149022
149022
  }
149023
149023
  function getMCPUserAgent() {
149024
149024
  const parts = [];
@@ -149032,7 +149032,7 @@ function getMCPUserAgent() {
149032
149032
  parts.push(`client-app/${process.env.RAYU_AGENT_SDK_CLIENT_APP}`);
149033
149033
  }
149034
149034
  const suffix = parts.length > 0 ? ` (${parts.join(", ")})` : "";
149035
- return `rayu/${"1.4.474"}${suffix}`;
149035
+ return `rayu/${"1.4.476"}${suffix}`;
149036
149036
  }
149037
149037
  function getWebFetchUserAgent() {
149038
149038
  return `Rayu-User (${getRayuUserAgent()})`;
@@ -200387,6 +200387,12 @@ var init_theme = __esm(() => {
200387
200387
  ];
200388
200388
  THEME_SETTINGS = ["auto", ...THEME_NAMES];
200389
200389
  lightTheme = {
200390
+ toolExecute: "rgb(176,122,0)",
200391
+ toolRead: "rgb(34,134,80)",
200392
+ toolSearch: "rgb(0,132,150)",
200393
+ toolEdit: "rgb(196,90,20)",
200394
+ toolWeb: "rgb(124,58,205)",
200395
+ toolTask: "rgb(37,99,235)",
200390
200396
  autoAccept: "rgb(135,0,255)",
200391
200397
  bashBorder: "rgb(255,0,135)",
200392
200398
  brand: "rgb(45,140,80)",
@@ -200459,6 +200465,12 @@ var init_theme = __esm(() => {
200459
200465
  rainbow_violet_shimmer: "rgb(230,180,210)"
200460
200466
  };
200461
200467
  lightAnsiTheme = {
200468
+ toolExecute: "ansi:yellow",
200469
+ toolRead: "ansi:green",
200470
+ toolSearch: "ansi:cyan",
200471
+ toolEdit: "ansi:red",
200472
+ toolWeb: "ansi:magenta",
200473
+ toolTask: "ansi:blue",
200462
200474
  autoAccept: "ansi:magenta",
200463
200475
  bashBorder: "ansi:magenta",
200464
200476
  brand: "ansi:greenBright",
@@ -200531,6 +200543,12 @@ var init_theme = __esm(() => {
200531
200543
  rainbow_violet_shimmer: "ansi:magentaBright"
200532
200544
  };
200533
200545
  darkAnsiTheme = {
200546
+ toolExecute: "ansi:yellowBright",
200547
+ toolRead: "ansi:greenBright",
200548
+ toolSearch: "ansi:cyanBright",
200549
+ toolEdit: "ansi:redBright",
200550
+ toolWeb: "ansi:magentaBright",
200551
+ toolTask: "ansi:blueBright",
200534
200552
  autoAccept: "ansi:magentaBright",
200535
200553
  bashBorder: "ansi:magentaBright",
200536
200554
  brand: "ansi:greenBright",
@@ -200603,6 +200621,12 @@ var init_theme = __esm(() => {
200603
200621
  rainbow_violet_shimmer: "ansi:magentaBright"
200604
200622
  };
200605
200623
  lightDaltonizedTheme = {
200624
+ toolExecute: "rgb(150,110,0)",
200625
+ toolRead: "rgb(0,140,140)",
200626
+ toolSearch: "rgb(0,102,204)",
200627
+ toolEdit: "rgb(204,102,0)",
200628
+ toolWeb: "rgb(128,0,128)",
200629
+ toolTask: "rgb(199,42,140)",
200606
200630
  autoAccept: "rgb(135,0,255)",
200607
200631
  bashBorder: "rgb(0,102,204)",
200608
200632
  brand: "rgb(0,153,136)",
@@ -200675,6 +200699,12 @@ var init_theme = __esm(() => {
200675
200699
  rainbow_violet_shimmer: "rgb(230,180,210)"
200676
200700
  };
200677
200701
  darkTheme = {
200702
+ toolExecute: "rgb(255,199,89)",
200703
+ toolRead: "rgb(94,201,138)",
200704
+ toolSearch: "rgb(86,194,214)",
200705
+ toolEdit: "rgb(240,150,90)",
200706
+ toolWeb: "rgb(197,160,255)",
200707
+ toolTask: "rgb(122,162,247)",
200678
200708
  autoAccept: "rgb(175,135,255)",
200679
200709
  bashBorder: "rgb(253,93,177)",
200680
200710
  brand: "rgb(70,190,130)",
@@ -200747,6 +200777,12 @@ var init_theme = __esm(() => {
200747
200777
  rainbow_violet_shimmer: "rgb(230,180,210)"
200748
200778
  };
200749
200779
  darkDaltonizedTheme = {
200780
+ toolExecute: "rgb(240,220,90)",
200781
+ toolRead: "rgb(102,204,204)",
200782
+ toolSearch: "rgb(102,178,255)",
200783
+ toolEdit: "rgb(255,178,102)",
200784
+ toolWeb: "rgb(178,102,255)",
200785
+ toolTask: "rgb(255,153,204)",
200750
200786
  autoAccept: "rgb(175,135,255)",
200751
200787
  bashBorder: "rgb(51,153,255)",
200752
200788
  brand: "rgb(0,180,150)",
@@ -205364,7 +205400,7 @@ function getAttributionHeader(fingerprint) {
205364
205400
  if (!isAttributionHeaderEnabled()) {
205365
205401
  return "";
205366
205402
  }
205367
- const version2 = `${"1.4.474"}.${fingerprint}`;
205403
+ const version2 = `${"1.4.476"}.${fingerprint}`;
205368
205404
  const entrypoint = process.env.CLAUDE_CODE_ENTRYPOINT ?? "unknown";
205369
205405
  const cch = "";
205370
205406
  const workload = getWorkload();
@@ -259333,7 +259369,7 @@ var init_metadata = __esm(() => {
259333
259369
  COMPOUND_OPERATOR_REGEX = /\s*(?:&&|\|\||[;|])\s*/;
259334
259370
  WHITESPACE_REGEX = /\s+/;
259335
259371
  getVersionBase = memoize_default(() => {
259336
- const match = "1.4.474".match(/^\d+\.\d+\.\d+(?:-[a-z]+)?/);
259372
+ const match = "1.4.476".match(/^\d+\.\d+\.\d+(?:-[a-z]+)?/);
259337
259373
  return match ? match[0] : undefined;
259338
259374
  });
259339
259375
  buildEnvContext = memoize_default(async () => {
@@ -259372,7 +259408,7 @@ var init_metadata = __esm(() => {
259372
259408
  },
259373
259409
  isGithubAction: isEnvTruthy(process.env.GITHUB_ACTIONS),
259374
259410
  isRayuAction: isEnvTruthy(process.env.RAYU_ACTION),
259375
- version: "1.4.474",
259411
+ version: "1.4.476",
259376
259412
  versionBase: getVersionBase(),
259377
259413
  buildTime: "",
259378
259414
  deploymentEnvironment: env3.detectDeploymentEnvironment(),
@@ -291388,7 +291424,7 @@ function getTelemetryAttributes() {
291388
291424
  attributes["session.id"] = sessionId;
291389
291425
  }
291390
291426
  if (shouldIncludeAttribute("OTEL_METRICS_INCLUDE_VERSION")) {
291391
- attributes["app.version"] = "1.4.474";
291427
+ attributes["app.version"] = "1.4.476";
291392
291428
  }
291393
291429
  const oauthAccount = getOauthAccountInfo();
291394
291430
  if (oauthAccount) {
@@ -401745,7 +401781,7 @@ function getInstallationEnv() {
401745
401781
  return;
401746
401782
  }
401747
401783
  function getClaudeCodeVersion() {
401748
- return "1.4.474";
401784
+ return "1.4.476";
401749
401785
  }
401750
401786
  async function getInstalledVSCodeExtensionVersion(command) {
401751
401787
  const { stdout } = await execFileNoThrow(command, ["--list-extensions", "--show-versions"], {
@@ -406983,7 +407019,7 @@ async function setupSdkMcpClients(sdkMcpConfigs, sendMcpMessage) {
406983
407019
  const client3 = new Client({
406984
407020
  name: "claude-code",
406985
407021
  title: "RAYU",
406986
- version: "1.4.474",
407022
+ version: "1.4.476",
406987
407023
  description: "Anthropic's agentic coding tool",
406988
407024
  websiteUrl: PRODUCT_URL
406989
407025
  }, {
@@ -407300,7 +407336,7 @@ var init_client7 = __esm(() => {
407300
407336
  const client3 = new Client({
407301
407337
  name: "claude-code",
407302
407338
  title: "RAYU",
407303
- version: "1.4.474",
407339
+ version: "1.4.476",
407304
407340
  description: "Anthropic's agentic coding tool",
407305
407341
  websiteUrl: PRODUCT_URL
407306
407342
  }, {
@@ -422119,7 +422155,7 @@ function computeFingerprint(messageText, version2) {
422119
422155
  }
422120
422156
  function computeFingerprintFromMessages(messages) {
422121
422157
  const firstMessageText = extractFirstMessageText(messages);
422122
- return computeFingerprint(firstMessageText, "1.4.474");
422158
+ return computeFingerprint(firstMessageText, "1.4.476");
422123
422159
  }
422124
422160
  var FINGERPRINT_SALT = "59cf53e54c78";
422125
422161
  var init_fingerprint = () => {};
@@ -422161,7 +422197,7 @@ async function sideQuery(opts) {
422161
422197
  betas.push(STRUCTURED_OUTPUTS_BETA_HEADER);
422162
422198
  }
422163
422199
  const messageText = extractFirstUserMessageText(messages);
422164
- const fingerprint = computeFingerprint(messageText, "1.4.474");
422200
+ const fingerprint = computeFingerprint(messageText, "1.4.476");
422165
422201
  const attributionHeader = getAttributionHeader(fingerprint);
422166
422202
  const systemBlocks = [
422167
422203
  attributionHeader ? { type: "text", text: attributionHeader } : null,
@@ -424824,6 +424860,63 @@ var init_classifierApprovalsHook = __esm(() => {
424824
424860
  import_react51 = __toESM(require_react(), 1);
424825
424861
  });
424826
424862
 
424863
+ // src/utils/toolColors.ts
424864
+ function getToolNameColor(toolName2) {
424865
+ if (!toolName2)
424866
+ return;
424867
+ if (EXECUTE_TOOLS.has(toolName2))
424868
+ return "toolExecute";
424869
+ if (READ_TOOLS2.has(toolName2))
424870
+ return "toolRead";
424871
+ if (SEARCH_TOOLS2.has(toolName2))
424872
+ return "toolSearch";
424873
+ if (EDIT_TOOLS.has(toolName2))
424874
+ return "toolEdit";
424875
+ if (WEB_TOOLS.has(toolName2))
424876
+ return "toolWeb";
424877
+ if (TASK_TOOLS.has(toolName2))
424878
+ return "toolTask";
424879
+ return;
424880
+ }
424881
+ var EXECUTE_TOOLS, READ_TOOLS2, SEARCH_TOOLS2, EDIT_TOOLS, WEB_TOOLS, TASK_TOOLS;
424882
+ var init_toolColors = __esm(() => {
424883
+ EXECUTE_TOOLS = new Set(["Bash", "PowerShell", "REPL"]);
424884
+ READ_TOOLS2 = new Set(["Read", "LSP"]);
424885
+ SEARCH_TOOLS2 = new Set([
424886
+ "Grep",
424887
+ "Glob",
424888
+ "WebSearch",
424889
+ "ToolSearch",
424890
+ "ListMcpResourcesTool"
424891
+ ]);
424892
+ EDIT_TOOLS = new Set([
424893
+ "Edit",
424894
+ "Write",
424895
+ "NotebookEdit",
424896
+ "TodoWrite"
424897
+ ]);
424898
+ WEB_TOOLS = new Set([
424899
+ "WebFetch",
424900
+ "GenerateImage",
424901
+ "GenerateVideo"
424902
+ ]);
424903
+ TASK_TOOLS = new Set([
424904
+ "Agent",
424905
+ "Task",
424906
+ "TaskCreate",
424907
+ "TaskGet",
424908
+ "TaskUpdate",
424909
+ "TaskList",
424910
+ "TaskOutput",
424911
+ "TaskStop",
424912
+ "TeamCreate",
424913
+ "TeamDelete",
424914
+ "SendMessage",
424915
+ "Skill",
424916
+ "InstallSkill"
424917
+ ]);
424918
+ });
424919
+
424827
424920
  // src/components/SentryErrorBoundary.ts
424828
424921
  var React23, SentryErrorBoundary;
424829
424922
  var init_SentryErrorBoundary = __esm(() => {
@@ -425178,7 +425271,7 @@ function AssistantToolUseMessage(t0) {
425178
425271
  } else {
425179
425272
  t7 = $3[37];
425180
425273
  }
425181
- const t8 = userFacingToolNameBackgroundColor ? "inverseText" : undefined;
425274
+ const t8 = userFacingToolNameBackgroundColor ? "inverseText" : getToolNameColor(tool_0.name);
425182
425275
  let t9;
425183
425276
  if ($3[38] !== t8 || $3[39] !== userFacingToolName || $3[40] !== userFacingToolNameBackgroundColor) {
425184
425277
  t9 = /* @__PURE__ */ jsx_runtime73.jsx(ThemedBox_default, {
@@ -425410,6 +425503,7 @@ var init_AssistantToolUseMessage = __esm(() => {
425410
425503
  init_Tool();
425411
425504
  init_classifierApprovalsHook();
425412
425505
  init_log2();
425506
+ init_toolColors();
425413
425507
  init_MessageResponse();
425414
425508
  init_messageActions();
425415
425509
  init_SentryErrorBoundary();
@@ -433703,6 +433797,7 @@ function UserToolSuccessMessage({
433703
433797
  isTranscriptMode
433704
433798
  }) {
433705
433799
  const [theme] = useTheme();
433800
+ const outerHoverColor = React31.useContext(TextHoverColorContext);
433706
433801
  const isBriefOnly = false;
433707
433802
  const [classifierRule] = React31.useState(() => getClassifierApproval(toolUseID));
433708
433803
  const [yoloReason] = React31.useState(() => getYoloClassifierApproval(toolUseID));
@@ -433730,7 +433825,8 @@ function UserToolSuccessMessage({
433730
433825
  return null;
433731
433826
  }
433732
433827
  const rendersAsAssistantText = tool.userFacingName(undefined) === "";
433733
- return /* @__PURE__ */ jsx_runtime105.jsxs(ThemedBox_default, {
433828
+ const toolColor = rendersAsAssistantText ? undefined : getToolNameColor(tool.name);
433829
+ const resultBody = /* @__PURE__ */ jsx_runtime105.jsxs(ThemedBox_default, {
433734
433830
  flexDirection: "column",
433735
433831
  children: [
433736
433832
  /* @__PURE__ */ jsx_runtime105.jsxs(ThemedBox_default, {
@@ -433753,6 +433849,10 @@ function UserToolSuccessMessage({
433753
433849
  })
433754
433850
  ]
433755
433851
  });
433852
+ return toolColor ? /* @__PURE__ */ jsx_runtime105.jsx(TextHoverColorContext.Provider, {
433853
+ value: outerHoverColor ?? toolColor,
433854
+ children: resultBody
433855
+ }) : resultBody;
433756
433856
  }
433757
433857
  var React31, jsx_runtime105;
433758
433858
  var init_UserToolSuccessMessage = __esm(() => {
@@ -433762,6 +433862,8 @@ var init_UserToolSuccessMessage = __esm(() => {
433762
433862
  init_Tool();
433763
433863
  init_classifierApprovals();
433764
433864
  init_MessageResponse();
433865
+ init_ThemedText();
433866
+ init_toolColors();
433765
433867
  init_HookProgressMessage();
433766
433868
  React31 = __toESM(require_react(), 1);
433767
433869
  jsx_runtime105 = __toESM(require_jsx_runtime(), 1);
@@ -454537,10 +454639,9 @@ function isPreapprovedHost(hostname3, pathname) {
454537
454639
  var PREAPPROVED_HOSTS, HOSTNAME_ONLY, PATH_PREFIXES;
454538
454640
  var init_preapproved = __esm(() => {
454539
454641
  PREAPPROVED_HOSTS = new Set([
454540
- "platform.claude.com",
454541
- "code.claude.com",
454642
+ "rayucode.com",
454643
+ "github.com/Choeng-Rayu",
454542
454644
  "modelcontextprotocol.io",
454543
- "github.com/anthropics",
454544
454645
  "agentskills.io",
454545
454646
  "docs.python.org",
454546
454647
  "en.cppreference.com",
@@ -471268,6 +471369,7 @@ __export(exports_utils2, {
471268
471369
  isPermittedRedirect: () => isPermittedRedirect,
471269
471370
  getWithPermittedRedirects: () => getWithPermittedRedirects,
471270
471371
  getURLMarkdownContent: () => getURLMarkdownContent,
471372
+ formatWebFetchModelError: () => formatWebFetchModelError,
471271
471373
  clearWebFetchCache: () => clearWebFetchCache,
471272
471374
  checkDomainBlocklist: () => checkDomainBlocklist,
471273
471375
  applyPromptToMarkdown: () => applyPromptToMarkdown,
@@ -471312,26 +471414,7 @@ function validateURL(url3) {
471312
471414
  return true;
471313
471415
  }
471314
471416
  async function checkDomainBlocklist(domain2) {
471315
- if (DOMAIN_CHECK_CACHE.has(domain2)) {
471316
- return { status: "allowed" };
471317
- }
471318
- try {
471319
- const response = await axios_default.get(`https://api.anthropic.com/api/web/domain_info?domain=${encodeURIComponent(domain2)}`, { timeout: DOMAIN_CHECK_TIMEOUT_MS });
471320
- if (response.status === 200) {
471321
- if (response.data.can_fetch === true) {
471322
- DOMAIN_CHECK_CACHE.set(domain2, true);
471323
- return { status: "allowed" };
471324
- }
471325
- return { status: "blocked" };
471326
- }
471327
- return {
471328
- status: "check_failed",
471329
- error: new Error(`Domain check returned status ${response.status}`)
471330
- };
471331
- } catch (e2) {
471332
- logError2(e2);
471333
- return { status: "check_failed", error: e2 };
471334
- }
471417
+ return { status: "allowed" };
471335
471418
  }
471336
471419
  function isPermittedRedirect(originalUrl, redirectUrl) {
471337
471420
  try {
@@ -471482,24 +471565,40 @@ async function getURLMarkdownContent(url3, abortController) {
471482
471565
  URL_CACHE.set(url3, entry, { size: Math.max(1, contentBytes) });
471483
471566
  return entry;
471484
471567
  }
471568
+ function formatWebFetchModelError(error54, model) {
471569
+ const modelPart = model && !/claude/i.test(model) ? ` ("${model}")` : "";
471570
+ return `The page was fetched successfully, but the WebFetch model${modelPart} ` + `could not summarize it — the model is not available on your current ` + `provider/plan.
471571
+
471572
+ Tell the user to run /webfetch_model and choose a small, available model from their provider (a small/instant model is enough for page summaries), then retry this fetch.`;
471573
+ }
471485
471574
  async function applyPromptToMarkdown(prompt, markdownContent, signal, isNonInteractiveSession, isPreapprovedDomain) {
471486
471575
  const truncatedContent = markdownContent.length > MAX_MARKDOWN_LENGTH ? markdownContent.slice(0, MAX_MARKDOWN_LENGTH) + `
471487
471576
 
471488
471577
  [Content truncated due to length...]` : markdownContent;
471489
471578
  const modelPrompt = makeSecondaryModelPrompt(truncatedContent, prompt, isPreapprovedDomain);
471490
- const assistantMessage = await queryHaiku({
471491
- systemPrompt: asSystemPrompt([]),
471492
- userPrompt: modelPrompt,
471493
- signal,
471494
- model: getWebFetchModel(),
471495
- options: {
471496
- querySource: "web_fetch_apply",
471497
- agents: [],
471498
- isNonInteractiveSession,
471499
- hasAppendSystemPrompt: false,
471500
- mcpTools: []
471579
+ const webFetchModel = getWebFetchModel();
471580
+ let assistantMessage;
471581
+ try {
471582
+ assistantMessage = await queryHaiku({
471583
+ systemPrompt: asSystemPrompt([]),
471584
+ userPrompt: modelPrompt,
471585
+ signal,
471586
+ model: webFetchModel,
471587
+ options: {
471588
+ querySource: "web_fetch_apply",
471589
+ agents: [],
471590
+ isNonInteractiveSession,
471591
+ hasAppendSystemPrompt: false,
471592
+ mcpTools: []
471593
+ }
471594
+ });
471595
+ } catch (e2) {
471596
+ if (signal.aborted) {
471597
+ throw new AbortError;
471501
471598
  }
471502
- });
471599
+ logError2(e2);
471600
+ return formatWebFetchModelError(e2, webFetchModel);
471601
+ }
471503
471602
  if (signal.aborted) {
471504
471603
  throw new AbortError;
471505
471604
  }
@@ -471512,7 +471611,7 @@ async function applyPromptToMarkdown(prompt, markdownContent, signal, isNonInter
471512
471611
  }
471513
471612
  return "No response from model";
471514
471613
  }
471515
- var DomainBlockedError, DomainCheckFailedError, EgressBlockedError, CACHE_TTL_MS, MAX_CACHE_SIZE_BYTES, URL_CACHE, DOMAIN_CHECK_CACHE, turndownServicePromise, MAX_URL_LENGTH = 2000, MAX_HTTP_CONTENT_LENGTH = 10485760, FETCH_TIMEOUT_MS2 = 60000, DOMAIN_CHECK_TIMEOUT_MS = 1e4, MAX_REDIRECTS = 10, MAX_MARKDOWN_LENGTH = 1e5;
471614
+ var DomainBlockedError, DomainCheckFailedError, EgressBlockedError, CACHE_TTL_MS, MAX_CACHE_SIZE_BYTES, URL_CACHE, DOMAIN_CHECK_CACHE, turndownServicePromise, MAX_URL_LENGTH = 2000, MAX_HTTP_CONTENT_LENGTH = 10485760, FETCH_TIMEOUT_MS2 = 60000, MAX_REDIRECTS = 10, MAX_MARKDOWN_LENGTH = 1e5;
471516
471615
  var init_utils13 = __esm(() => {
471517
471616
  init_axios2();
471518
471617
  init_index_min();
@@ -471533,7 +471632,7 @@ var init_utils13 = __esm(() => {
471533
471632
  };
471534
471633
  DomainCheckFailedError = class DomainCheckFailedError extends Error {
471535
471634
  constructor(domain2) {
471536
- super(`Unable to verify if domain ${domain2} is safe to fetch. This may be due to network restrictions or enterprise security policies blocking claude.ai.`);
471635
+ super(`Unable to verify if domain ${domain2} is safe to fetch. This may be due to network restrictions or enterprise security policies.`);
471537
471636
  this.name = "DomainCheckFailedError";
471538
471637
  }
471539
471638
  };
@@ -471615,9 +471714,9 @@ var init_WebFetchTool = __esm(() => {
471615
471714
  const { url: url3 } = input;
471616
471715
  try {
471617
471716
  const hostname3 = new URL(url3).hostname;
471618
- return `Claude wants to fetch content from ${hostname3}`;
471717
+ return `Rayu wants to fetch content from ${hostname3}`;
471619
471718
  } catch {
471620
- return `Claude wants to fetch content from this URL`;
471719
+ return `Rayu wants to fetch content from this URL`;
471621
471720
  }
471622
471721
  },
471623
471722
  userFacingName() {
@@ -471673,7 +471772,7 @@ var init_WebFetchTool = __esm(() => {
471673
471772
  if (askRule) {
471674
471773
  return {
471675
471774
  behavior: "ask",
471676
- message: `Claude requested permissions to use ${WebFetchTool.name}, but you haven't granted it yet.`,
471775
+ message: `Rayu requested permissions to use ${WebFetchTool.name}, but you haven't granted it yet.`,
471677
471776
  decisionReason: {
471678
471777
  type: "rule",
471679
471778
  rule: askRule
@@ -471694,7 +471793,7 @@ var init_WebFetchTool = __esm(() => {
471694
471793
  }
471695
471794
  return {
471696
471795
  behavior: "ask",
471697
- message: `Claude requested permissions to use ${WebFetchTool.name}, but you haven't granted it yet.`,
471796
+ message: `Rayu requested permissions to use ${WebFetchTool.name}, but you haven't granted it yet.`,
471698
471797
  suggestions: buildSuggestions(ruleContent)
471699
471798
  };
471700
471799
  },
@@ -498596,6 +498695,9 @@ function getContentText(content) {
498596
498695
  }
498597
498696
  return null;
498598
498697
  }
498698
+ function finalizeStreamingThinkingOnTurnEnd(current) {
498699
+ return current && current.isStreaming ? null : current;
498700
+ }
498599
498701
  function handleMessageFromStream(message, onMessage2, onUpdateLength, onSetStreamMode, onStreamingToolUses, onTombstone, onStreamingThinking, onApiMetrics, onStreamingText) {
498600
498702
  if (message.type !== "stream_event" && message.type !== "stream_request_start") {
498601
498703
  if (message.type === "tombstone") {
@@ -521504,9 +521606,9 @@ async function assertMinVersion() {
521504
521606
  if (false) {}
521505
521607
  try {
521506
521608
  const versionConfig = await getDynamicConfig_BLOCKS_ON_INIT("tengu_version_config", { minVersion: "0.0.0" });
521507
- if (versionConfig.minVersion && lt("1.4.474", versionConfig.minVersion)) {
521609
+ if (versionConfig.minVersion && lt("1.4.476", versionConfig.minVersion)) {
521508
521610
  console.error(`
521509
- It looks like your version of RAYU (${"1.4.474"}) needs an update.
521611
+ It looks like your version of RAYU (${"1.4.476"}) needs an update.
521510
521612
  A newer version (${versionConfig.minVersion} or higher) is required to continue.
521511
521613
 
521512
521614
  To update, please run:
@@ -521732,7 +521834,7 @@ async function installGlobalPackage(specificVersion) {
521732
521834
  logError2(new AutoUpdaterError("Another process is currently installing an update"));
521733
521835
  logEvent("tengu_auto_updater_lock_contention", {
521734
521836
  pid: process.pid,
521735
- currentVersion: "1.4.474"
521837
+ currentVersion: "1.4.476"
521736
521838
  });
521737
521839
  return "in_progress";
521738
521840
  }
@@ -521741,7 +521843,7 @@ async function installGlobalPackage(specificVersion) {
521741
521843
  if (!env3.isRunningWithBun() && env3.isNpmFromWindowsPath()) {
521742
521844
  logError2(new Error("Windows NPM detected in WSL environment"));
521743
521845
  logEvent("tengu_auto_updater_windows_npm_in_wsl", {
521744
- currentVersion: "1.4.474"
521846
+ currentVersion: "1.4.476"
521745
521847
  });
521746
521848
  console.error(`
521747
521849
  Error: Windows NPM detected in WSL
@@ -522269,7 +522371,7 @@ function detectLinuxGlobPatternWarnings() {
522269
522371
  }
522270
522372
  async function getDoctorDiagnostic() {
522271
522373
  const installationType = await getCurrentInstallationType();
522272
- const version2 = typeof MACRO !== "undefined" ? "1.4.474" : "unknown";
522374
+ const version2 = typeof MACRO !== "undefined" ? "1.4.476" : "unknown";
522273
522375
  const installationPath = await getInstallationPath();
522274
522376
  const invokedBinary = getInvokedBinary();
522275
522377
  const multipleInstallations = await detectMultipleInstallations();
@@ -523060,8 +523162,8 @@ async function updateLatest(channelOrVersion, forceReinstall = false) {
523060
523162
  const maxVersion = await getMaxVersion();
523061
523163
  if (maxVersion && gt(version2, maxVersion)) {
523062
523164
  logForDebugging(`Native installer: maxVersion ${maxVersion} is set, capping update from ${version2} to ${maxVersion}`);
523063
- if (gte("1.4.474", maxVersion)) {
523064
- logForDebugging(`Native installer: current version ${"1.4.474"} is already at or above maxVersion ${maxVersion}, skipping update`);
523165
+ if (gte("1.4.476", maxVersion)) {
523166
+ logForDebugging(`Native installer: current version ${"1.4.476"} is already at or above maxVersion ${maxVersion}, skipping update`);
523065
523167
  logEvent("tengu_native_update_skipped_max_version", {
523066
523168
  latency_ms: Date.now() - startTime2,
523067
523169
  max_version: maxVersion,
@@ -523072,7 +523174,7 @@ async function updateLatest(channelOrVersion, forceReinstall = false) {
523072
523174
  version2 = maxVersion;
523073
523175
  }
523074
523176
  }
523075
- if (!forceReinstall && version2 === "1.4.474" && await versionIsAvailable(version2) && await isPossibleClaudeBinary(executablePath)) {
523177
+ if (!forceReinstall && version2 === "1.4.476" && await versionIsAvailable(version2) && await isPossibleClaudeBinary(executablePath)) {
523076
523178
  logForDebugging(`Found ${version2} at ${executablePath}, skipping install`);
523077
523179
  logEvent("tengu_native_update_complete", {
523078
523180
  latency_ms: Date.now() - startTime2,
@@ -524280,7 +524382,7 @@ function buildPrimarySection() {
524280
524382
  });
524281
524383
  return [{
524282
524384
  label: "Version",
524283
- value: "1.4.474"
524385
+ value: "1.4.476"
524284
524386
  }, {
524285
524387
  label: "Session name",
524286
524388
  value: nameValue
@@ -527951,7 +528053,7 @@ function Config({
527951
528053
  }
527952
528054
  })
527953
528055
  }) : showSubmenu === "ChannelDowngrade" ? /* @__PURE__ */ jsx_runtime168.jsx(ChannelDowngradeDialog, {
527954
- currentVersion: "1.4.474",
528056
+ currentVersion: "1.4.476",
527955
528057
  onChoice: (choice) => {
527956
528058
  setShowSubmenu(null);
527957
528059
  setTabsHidden(false);
@@ -527963,7 +528065,7 @@ function Config({
527963
528065
  autoUpdatesChannel: "stable"
527964
528066
  };
527965
528067
  if (choice === "stay") {
527966
- newSettings.minimumVersion = "1.4.474";
528068
+ newSettings.minimumVersion = "1.4.476";
527967
528069
  }
527968
528070
  updateSettingsForSource("userSettings", newSettings);
527969
528071
  setSettingsData((prev_27) => ({
@@ -536024,7 +536126,7 @@ function HelpV2(t0) {
536024
536126
  let t6;
536025
536127
  if ($3[31] !== tabs) {
536026
536128
  t6 = /* @__PURE__ */ jsx_runtime195.jsx(Tabs, {
536027
- title: `Rayu-CLI v${"1.4.474"}`,
536129
+ title: `Rayu-CLI v${"1.4.476"}`,
536028
536130
  color: "professionalBlue",
536029
536131
  defaultTab: "general",
536030
536132
  children: tabs
@@ -554132,6 +554234,23 @@ import { join as join137 } from "path";
554132
554234
  function configPath2() {
554133
554235
  return join137(getRayuConfigHomeDir(), "telegram.json");
554134
554236
  }
554237
+ function getTelegramMode() {
554238
+ const cfg = readTelegramConfig();
554239
+ if (cfg.mode === "hosted" || cfg.mode === "byo")
554240
+ return cfg.mode;
554241
+ return cfg.botToken && cfg.botToken.trim().length > 0 ? "byo" : "hosted";
554242
+ }
554243
+ function setTelegramMode(mode) {
554244
+ const cfg = readTelegramConfig();
554245
+ cfg.mode = mode;
554246
+ writeTelegramConfig(cfg);
554247
+ }
554248
+ function setLinkedChat(chatId, username) {
554249
+ const cfg = readTelegramConfig();
554250
+ cfg.linkedChatId = chatId;
554251
+ cfg.linkedUsername = username;
554252
+ writeTelegramConfig(cfg);
554253
+ }
554135
554254
  function getBotToken() {
554136
554255
  const cfg = readTelegramConfig();
554137
554256
  if (cfg.botToken && cfg.botToken.trim().length > 0)
@@ -554144,6 +554263,14 @@ function saveBotToken(token) {
554144
554263
  cfg.botToken = token.trim();
554145
554264
  writeTelegramConfig(cfg);
554146
554265
  }
554266
+ function clearBotToken() {
554267
+ const cfg = readTelegramConfig();
554268
+ delete cfg.botToken;
554269
+ delete cfg.pendingToken;
554270
+ delete cfg.linkedChatId;
554271
+ delete cfg.linkedUsername;
554272
+ writeTelegramConfig(cfg);
554273
+ }
554147
554274
  function readTelegramConfig() {
554148
554275
  const path27 = configPath2();
554149
554276
  if (!existsSync25(path27))
@@ -554195,6 +554322,9 @@ var init_telegramConfig = __esm(() => {
554195
554322
  // src/telegram/telegramApi.ts
554196
554323
  import { readFile as readFile45 } from "fs/promises";
554197
554324
  import { existsSync as existsSync26, statSync as statSync13 } from "fs";
554325
+ function setHostedRouter(router) {
554326
+ hostedRouter = router;
554327
+ }
554198
554328
  function escapeHtml(text2) {
554199
554329
  return text2.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
554200
554330
  }
@@ -554202,6 +554332,8 @@ function url3(token, method) {
554202
554332
  return `${API_BASE2}/bot${token}/${method}`;
554203
554333
  }
554204
554334
  async function callApi(token, method, body) {
554335
+ if (hostedRouter)
554336
+ return hostedRouter.call(method, body);
554205
554337
  const res = await fetch(url3(token, method), {
554206
554338
  method: "POST",
554207
554339
  headers: { "content-type": "application/json" },
@@ -554219,6 +554351,8 @@ async function callApi(token, method, body) {
554219
554351
  return json2.result;
554220
554352
  }
554221
554353
  async function getBotUsername(token) {
554354
+ if (hostedRouter)
554355
+ return hostedRouter.botUsername();
554222
554356
  try {
554223
554357
  const result = await callApi(token, "getMe", {});
554224
554358
  return result.username;
@@ -554227,6 +554361,13 @@ async function getBotUsername(token) {
554227
554361
  }
554228
554362
  }
554229
554363
  async function getUpdates(token, offset, timeoutSec = 50) {
554364
+ if (hostedRouter) {
554365
+ try {
554366
+ return await hostedRouter.getUpdates(offset);
554367
+ } catch {
554368
+ return [];
554369
+ }
554370
+ }
554230
554371
  try {
554231
554372
  const result = await callApi(token, "getUpdates", { offset, timeout: timeoutSec });
554232
554373
  return Array.isArray(result) ? result : [];
@@ -554278,6 +554419,10 @@ async function editMessageText(token, chatId, messageId, text2, parseMode) {
554278
554419
  }
554279
554420
  }
554280
554421
  async function sendPhoto(token, chatId, base64Data, mediaType, caption) {
554422
+ if (hostedRouter) {
554423
+ await sendMessage3(token, chatId, caption ?? "\uD83D\uDDBC Image generated (view it in the CLI).");
554424
+ return;
554425
+ }
554281
554426
  const ext = mediaType.includes("jpeg") || mediaType.includes("jpg") ? "jpg" : "png";
554282
554427
  const buffer = Buffer.from(base64Data, "base64");
554283
554428
  const blob2 = new Blob([buffer], { type: mediaType });
@@ -554293,6 +554438,10 @@ async function sendPhoto(token, chatId, base64Data, mediaType, caption) {
554293
554438
  }
554294
554439
  }
554295
554440
  async function sendVideo(token, chatId, filePath, caption) {
554441
+ if (hostedRouter) {
554442
+ await sendMessage3(token, chatId, caption ?? "\uD83C\uDFAC Video generated (view it in the CLI).");
554443
+ return;
554444
+ }
554296
554445
  if (!existsSync26(filePath)) {
554297
554446
  await sendMessage3(token, chatId, `\uD83C\uDFAC Video generated but file not found: ${filePath}`);
554298
554447
  return;
@@ -554371,6 +554520,8 @@ async function setMyCommands(token, commands) {
554371
554520
  } catch {}
554372
554521
  }
554373
554522
  async function getFile(token, fileId) {
554523
+ if (hostedRouter)
554524
+ return;
554374
554525
  try {
554375
554526
  const result = await callApi(token, "getFile", { file_id: fileId });
554376
554527
  return result.file_path;
@@ -554379,6 +554530,8 @@ async function getFile(token, fileId) {
554379
554530
  }
554380
554531
  }
554381
554532
  async function downloadFileAsBase64(token, filePath) {
554533
+ if (hostedRouter)
554534
+ return;
554382
554535
  try {
554383
554536
  const fileUrl = `${API_BASE2}/file/bot${token}/${filePath}`;
554384
554537
  const res = await fetch(fileUrl);
@@ -554404,31 +554557,321 @@ async function downloadFileAsBase64(token, filePath) {
554404
554557
  return;
554405
554558
  }
554406
554559
  }
554407
- var API_BASE2 = "https://api.telegram.org", MAX_MESSAGE_CHARS = 4096, MAX_FILE_BYTES;
554560
+ var API_BASE2 = "https://api.telegram.org", MAX_MESSAGE_CHARS = 4096, hostedRouter = null, MAX_FILE_BYTES;
554408
554561
  var init_telegramApi = __esm(() => {
554409
554562
  MAX_FILE_BYTES = 50 * 1024 * 1024;
554410
554563
  });
554411
554564
 
554565
+ // src/telegram/telegramHostedApi.ts
554566
+ async function authedFetch(path27, init2) {
554567
+ const token = await getValidRayuAccessToken();
554568
+ if (!token)
554569
+ throw new Error("Not signed in to Rayu");
554570
+ return globalThis.fetch(`${getRayuApiBaseUrl()}${path27}`, {
554571
+ method: init2?.method ?? "GET",
554572
+ headers: {
554573
+ Authorization: `Bearer ${token}`,
554574
+ ...init2?.body ? { "content-type": "application/json" } : {}
554575
+ },
554576
+ ...init2?.body ? { body: init2.body } : {}
554577
+ });
554578
+ }
554579
+ async function getHostedBotInfo() {
554580
+ try {
554581
+ const res = await authedFetch("/telegram/bot");
554582
+ if (!res.ok)
554583
+ return { configured: false, username: null };
554584
+ return await res.json();
554585
+ } catch {
554586
+ return { configured: false, username: null };
554587
+ }
554588
+ }
554589
+ async function createHostedPairing() {
554590
+ try {
554591
+ const res = await authedFetch("/telegram/pair", { method: "POST" });
554592
+ if (!res.ok)
554593
+ return null;
554594
+ return await res.json();
554595
+ } catch {
554596
+ return null;
554597
+ }
554598
+ }
554599
+ async function getHostedLink() {
554600
+ try {
554601
+ const res = await authedFetch("/telegram/link");
554602
+ if (!res.ok)
554603
+ return { linked: false };
554604
+ return await res.json();
554605
+ } catch {
554606
+ return { linked: false };
554607
+ }
554608
+ }
554609
+ async function deleteHostedLink() {
554610
+ try {
554611
+ await authedFetch("/telegram/link", { method: "DELETE" });
554612
+ } catch {}
554613
+ }
554614
+ async function getHostedUpdates(after) {
554615
+ try {
554616
+ const res = await authedFetch(`/telegram/updates?after=${after}`);
554617
+ if (!res.ok)
554618
+ return { linked: false, updates: [] };
554619
+ return await res.json();
554620
+ } catch {
554621
+ return { linked: false, updates: [] };
554622
+ }
554623
+ }
554624
+ async function relayHostedSend(method, params) {
554625
+ const res = await authedFetch("/telegram/send", {
554626
+ method: "POST",
554627
+ body: JSON.stringify({ method, params })
554628
+ });
554629
+ if (!res.ok)
554630
+ throw new Error(`hosted relay ${method} failed: ${res.status}`);
554631
+ const json2 = await res.json();
554632
+ return json2.result;
554633
+ }
554634
+ var init_telegramHostedApi = __esm(() => {
554635
+ init_rayuSession();
554636
+ });
554637
+
554412
554638
  // src/commands/telegram-bot/telegram-bot.tsx
554413
554639
  var exports_telegram_bot = {};
554414
554640
  __export(exports_telegram_bot, {
554415
554641
  call: () => call20
554416
554642
  });
554417
554643
  import { randomUUID as randomUUID29 } from "crypto";
554418
- function TokenInputStep({ onTokenSaved }) {
554419
- const [input, setInput] = import_react132.useState("");
554644
+ function useKeyPress(target, handler) {
554645
+ import_react132.useEffect(() => {
554646
+ const onData = (data) => {
554647
+ const ch2 = data.toString().trim().toLowerCase();
554648
+ if (ch2 === target)
554649
+ handler();
554650
+ };
554651
+ process.stdin.on("data", onData);
554652
+ return () => {
554653
+ process.stdin.off("data", onData);
554654
+ };
554655
+ }, [target, handler]);
554656
+ }
554657
+ function HostedStep({
554658
+ onDone,
554659
+ onUseByo
554660
+ }) {
554661
+ const [status, setStatus] = import_react132.useState("loading");
554662
+ const [pairing, setPairing] = import_react132.useState(null);
554663
+ const [qr, setQr] = import_react132.useState("");
554664
+ const setAppState = useSetAppState();
554665
+ useKeyPress("b", onUseByo);
554666
+ import_react132.useEffect(() => {
554667
+ let cancelled = false;
554668
+ (async () => {
554669
+ if (!hasRayuSession()) {
554670
+ if (!cancelled)
554671
+ setStatus("nosession");
554672
+ return;
554673
+ }
554674
+ const info = await getHostedBotInfo();
554675
+ if (cancelled)
554676
+ return;
554677
+ if (!info.configured) {
554678
+ setStatus("unconfigured");
554679
+ return;
554680
+ }
554681
+ const p = await createHostedPairing();
554682
+ if (cancelled)
554683
+ return;
554684
+ if (!p) {
554685
+ setStatus("error");
554686
+ return;
554687
+ }
554688
+ setTelegramMode("hosted");
554689
+ setPairing(p);
554690
+ setStatus("ready");
554691
+ if (p.deepLink) {
554692
+ try {
554693
+ setQr(await $toString(p.deepLink, { type: "utf8", errorCorrectionLevel: "L" }));
554694
+ } catch {}
554695
+ }
554696
+ })();
554697
+ return () => {
554698
+ cancelled = true;
554699
+ };
554700
+ }, []);
554701
+ import_react132.useEffect(() => {
554702
+ if (status !== "ready")
554703
+ return;
554704
+ const timer = setInterval(() => {
554705
+ getHostedLink().then((link5) => {
554706
+ if (!link5.linked)
554707
+ return;
554708
+ clearInterval(timer);
554709
+ if (link5.chatId)
554710
+ setLinkedChat(Number(link5.chatId), link5.username ?? undefined);
554711
+ setAppState((prev) => ({ ...prev, telegramBridgeActive: true }));
554712
+ onDone();
554713
+ });
554714
+ }, 1500);
554715
+ return () => clearInterval(timer);
554716
+ }, [status, onDone, setAppState]);
554717
+ if (status === "loading") {
554718
+ return /* @__PURE__ */ jsx_runtime222.jsx(Pane, {
554719
+ children: /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
554720
+ dimColor: true,
554721
+ children: "Connecting to the Rayu Telegram bot…"
554722
+ })
554723
+ });
554724
+ }
554725
+ if (status === "nosession") {
554726
+ return /* @__PURE__ */ jsx_runtime222.jsx(Pane, {
554727
+ children: /* @__PURE__ */ jsx_runtime222.jsxs(ThemedBox_default, {
554728
+ flexDirection: "column",
554729
+ children: [
554730
+ /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
554731
+ bold: true,
554732
+ children: "\uD83D\uDCF1 Connect Telegram"
554733
+ }),
554734
+ /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
554735
+ children: " "
554736
+ }),
554737
+ /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
554738
+ color: "yellow",
554739
+ children: "Sign in first: run /login to use the shared Rayu bot."
554740
+ }),
554741
+ /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
554742
+ children: " "
554743
+ }),
554744
+ /* @__PURE__ */ jsx_runtime222.jsxs(ThemedText, {
554745
+ dimColor: true,
554746
+ children: [
554747
+ "Or press ",
554748
+ /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
554749
+ bold: true,
554750
+ children: "b"
554751
+ }),
554752
+ " to connect your own bot token instead."
554753
+ ]
554754
+ })
554755
+ ]
554756
+ })
554757
+ });
554758
+ }
554759
+ if (status === "unconfigured" || status === "error") {
554760
+ return /* @__PURE__ */ jsx_runtime222.jsx(Pane, {
554761
+ children: /* @__PURE__ */ jsx_runtime222.jsxs(ThemedBox_default, {
554762
+ flexDirection: "column",
554763
+ children: [
554764
+ /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
554765
+ bold: true,
554766
+ children: "\uD83D\uDCF1 Connect Telegram"
554767
+ }),
554768
+ /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
554769
+ children: " "
554770
+ }),
554771
+ /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
554772
+ color: "yellow",
554773
+ children: status === "unconfigured" ? "The shared Rayu Telegram bot isn't available right now." : "Couldn't reach the Rayu Telegram service."
554774
+ }),
554775
+ /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
554776
+ children: " "
554777
+ }),
554778
+ /* @__PURE__ */ jsx_runtime222.jsxs(ThemedText, {
554779
+ children: [
554780
+ "Press ",
554781
+ /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
554782
+ bold: true,
554783
+ children: "b"
554784
+ }),
554785
+ " to connect your own bot token instead."
554786
+ ]
554787
+ })
554788
+ ]
554789
+ })
554790
+ });
554791
+ }
554792
+ const lines2 = qr.split(`
554793
+ `).filter((l3) => l3.length > 0);
554794
+ const bot = pairing?.botUsername;
554795
+ return /* @__PURE__ */ jsx_runtime222.jsx(Pane, {
554796
+ children: /* @__PURE__ */ jsx_runtime222.jsxs(ThemedBox_default, {
554797
+ flexDirection: "column",
554798
+ children: [
554799
+ /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
554800
+ bold: true,
554801
+ children: "\uD83D\uDCF1 Connect Telegram (Rayu bot — no setup needed)"
554802
+ }),
554803
+ /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
554804
+ children: " "
554805
+ }),
554806
+ lines2.map((line, i4) => /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
554807
+ children: line
554808
+ }, i4)),
554809
+ /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
554810
+ children: " "
554811
+ }),
554812
+ /* @__PURE__ */ jsx_runtime222.jsxs(ThemedText, {
554813
+ children: [
554814
+ "Scan the QR",
554815
+ bot ? ` to open @${bot}` : "",
554816
+ ", or open the bot and send:"
554817
+ ]
554818
+ }),
554819
+ /* @__PURE__ */ jsx_runtime222.jsxs(ThemedText, {
554820
+ bold: true,
554821
+ children: [
554822
+ " /start ",
554823
+ pairing?.code
554824
+ ]
554825
+ }),
554826
+ /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
554827
+ children: " "
554828
+ }),
554829
+ /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
554830
+ dimColor: true,
554831
+ children: "Waiting for you to link… (code valid 10 min)"
554832
+ }),
554833
+ /* @__PURE__ */ jsx_runtime222.jsxs(ThemedText, {
554834
+ dimColor: true,
554835
+ children: [
554836
+ "Press ",
554837
+ /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
554838
+ bold: true,
554839
+ children: "b"
554840
+ }),
554841
+ " to use your own bot token instead."
554842
+ ]
554843
+ })
554844
+ ]
554845
+ })
554846
+ });
554847
+ }
554848
+ function TokenInputStep({ onReady }) {
554849
+ const [existing, setExisting] = import_react132.useState(() => getBotToken());
554420
554850
  const [error54, setError] = import_react132.useState("");
554421
554851
  const [waiting, setWaiting] = import_react132.useState(false);
554422
554852
  import_react132.useEffect(() => {
554423
554853
  const handler = (data) => {
554424
554854
  const line = data.toString().trim();
554855
+ if (existing) {
554856
+ if (line === "") {
554857
+ setTelegramMode("byo");
554858
+ onReady();
554859
+ return;
554860
+ }
554861
+ if (line.toLowerCase() === "d") {
554862
+ clearBotToken();
554863
+ setExisting(undefined);
554864
+ setError("");
554865
+ return;
554866
+ }
554867
+ }
554425
554868
  if (!line)
554426
554869
  return;
554427
- setInput(line);
554428
554870
  if (/^\d+:[A-Za-z0-9_-]+$/.test(line)) {
554429
- setWaiting(true);
554430
554871
  saveBotToken(line);
554431
- setTimeout(() => onTokenSaved(), 300);
554872
+ setTelegramMode("byo");
554873
+ setWaiting(true);
554874
+ setTimeout(() => onReady(), 300);
554432
554875
  } else {
554433
554876
  setError("That doesn't look like a valid bot token. It should be like: 123456789:ABCDefGHI...");
554434
554877
  }
@@ -554437,7 +554880,7 @@ function TokenInputStep({ onTokenSaved }) {
554437
554880
  return () => {
554438
554881
  process.stdin.off("data", handler);
554439
554882
  };
554440
- }, [onTokenSaved]);
554883
+ }, [existing, onReady]);
554441
554884
  if (waiting) {
554442
554885
  return /* @__PURE__ */ jsx_runtime222.jsx(Pane, {
554443
554886
  children: /* @__PURE__ */ jsx_runtime222.jsxs(ThemedBox_default, {
@@ -554455,19 +554898,65 @@ function TokenInputStep({ onTokenSaved }) {
554455
554898
  })
554456
554899
  });
554457
554900
  }
554901
+ if (existing) {
554902
+ return /* @__PURE__ */ jsx_runtime222.jsx(Pane, {
554903
+ children: /* @__PURE__ */ jsx_runtime222.jsxs(ThemedBox_default, {
554904
+ flexDirection: "column",
554905
+ children: [
554906
+ /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
554907
+ bold: true,
554908
+ children: "\uD83D\uDCF1 Your Telegram bot token"
554909
+ }),
554910
+ /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
554911
+ children: " "
554912
+ }),
554913
+ /* @__PURE__ */ jsx_runtime222.jsxs(ThemedText, {
554914
+ children: [
554915
+ "A bot token is already saved (…",
554916
+ existing.slice(-6),
554917
+ ")."
554918
+ ]
554919
+ }),
554920
+ /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
554921
+ children: " "
554922
+ }),
554923
+ /* @__PURE__ */ jsx_runtime222.jsxs(ThemedText, {
554924
+ children: [
554925
+ /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
554926
+ bold: true,
554927
+ children: "Enter"
554928
+ }),
554929
+ " connect with it",
554930
+ " ",
554931
+ /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
554932
+ bold: true,
554933
+ children: "d"
554934
+ }),
554935
+ " remove it",
554936
+ " ",
554937
+ "or paste a ",
554938
+ /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
554939
+ bold: true,
554940
+ children: "new"
554941
+ }),
554942
+ " token to replace it."
554943
+ ]
554944
+ }),
554945
+ error54 ? /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
554946
+ color: "red",
554947
+ children: error54
554948
+ }) : null
554949
+ ]
554950
+ })
554951
+ });
554952
+ }
554458
554953
  return /* @__PURE__ */ jsx_runtime222.jsx(Pane, {
554459
554954
  children: /* @__PURE__ */ jsx_runtime222.jsxs(ThemedBox_default, {
554460
554955
  flexDirection: "column",
554461
554956
  children: [
554462
554957
  /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
554463
554958
  bold: true,
554464
- children: "\uD83D\uDCF1 Connect Telegram Bot"
554465
- }),
554466
- /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
554467
- children: " "
554468
- }),
554469
- /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
554470
- children: "To connect rayu-cli to Telegram, you need a bot token:"
554959
+ children: "\uD83D\uDCF1 Connect your own Telegram bot"
554471
554960
  }),
554472
554961
  /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
554473
554962
  children: " "
@@ -554581,18 +555070,116 @@ function LinkStep({ onDone }) {
554581
555070
  })
554582
555071
  });
554583
555072
  }
555073
+ function ChooseModeStep({
555074
+ onChoose
555075
+ }) {
555076
+ const [sel, setSel] = import_react132.useState(0);
555077
+ import_react132.useEffect(() => {
555078
+ const onData = (data) => {
555079
+ const s2 = data.toString();
555080
+ const t2 = s2.trim();
555081
+ if (t2 === "1")
555082
+ onChoose("hosted");
555083
+ else if (t2 === "2")
555084
+ onChoose("byo");
555085
+ else if (s2 === "\r" || s2 === `
555086
+ ` || t2 === "")
555087
+ onChoose(sel === 0 ? "hosted" : "byo");
555088
+ else if (s2 === "\x1B[A" || s2 === "\x1B[B" || t2 === "j" || t2 === "k") {
555089
+ setSel((p) => p === 0 ? 1 : 0);
555090
+ }
555091
+ };
555092
+ process.stdin.on("data", onData);
555093
+ return () => {
555094
+ process.stdin.off("data", onData);
555095
+ };
555096
+ }, [onChoose, sel]);
555097
+ return /* @__PURE__ */ jsx_runtime222.jsx(Pane, {
555098
+ children: /* @__PURE__ */ jsx_runtime222.jsxs(ThemedBox_default, {
555099
+ flexDirection: "column",
555100
+ children: [
555101
+ /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
555102
+ bold: true,
555103
+ children: "\uD83D\uDCF1 Connect Telegram — choose how"
555104
+ }),
555105
+ /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
555106
+ children: " "
555107
+ }),
555108
+ /* @__PURE__ */ jsx_runtime222.jsxs(ThemedText, {
555109
+ color: sel === 0 ? "cyan" : undefined,
555110
+ children: [
555111
+ sel === 0 ? "▶ " : " ",
555112
+ "1. Rayu shared bot",
555113
+ " ",
555114
+ /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
555115
+ dimColor: true,
555116
+ children: "(recommended — no setup, hosted by Rayu)"
555117
+ })
555118
+ ]
555119
+ }),
555120
+ /* @__PURE__ */ jsx_runtime222.jsxs(ThemedText, {
555121
+ color: sel === 1 ? "cyan" : undefined,
555122
+ children: [
555123
+ sel === 1 ? "▶ " : " ",
555124
+ "2. Your own bot token",
555125
+ " ",
555126
+ /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
555127
+ dimColor: true,
555128
+ children: "(private — direct to Telegram, no server)"
555129
+ })
555130
+ ]
555131
+ }),
555132
+ /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
555133
+ children: " "
555134
+ }),
555135
+ /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
555136
+ dimColor: true,
555137
+ children: "Press 1 or 2 (or ↑/↓ then Enter). Enter = shared bot."
555138
+ })
555139
+ ]
555140
+ })
555141
+ });
555142
+ }
554584
555143
  function TelegramBotConnect({ onDone }) {
554585
- const [hasToken, setHasToken] = import_react132.useState(() => !!getBotToken());
555144
+ const alreadyLinked = readTelegramConfig().linkedChatId !== undefined;
554586
555145
  const setAppState = useSetAppState();
555146
+ const [screen, setScreen] = import_react132.useState("choose");
554587
555147
  import_react132.useEffect(() => {
554588
- if (hasToken && readTelegramConfig().linkedChatId !== undefined) {
555148
+ if (alreadyLinked) {
554589
555149
  setAppState((prev) => ({ ...prev, telegramBridgeActive: true }));
554590
555150
  onDone();
554591
555151
  }
554592
- }, [hasToken, onDone, setAppState]);
554593
- if (!hasToken) {
555152
+ }, [alreadyLinked, onDone, setAppState]);
555153
+ if (alreadyLinked) {
555154
+ return /* @__PURE__ */ jsx_runtime222.jsx(Pane, {
555155
+ children: /* @__PURE__ */ jsx_runtime222.jsx(ThemedText, {
555156
+ dimColor: true,
555157
+ children: "Reconnecting Telegram…"
555158
+ })
555159
+ });
555160
+ }
555161
+ if (screen === "choose") {
555162
+ return /* @__PURE__ */ jsx_runtime222.jsx(ChooseModeStep, {
555163
+ onChoose: (mode) => {
555164
+ if (mode === "hosted") {
555165
+ setTelegramMode("hosted");
555166
+ setScreen("hosted");
555167
+ } else {
555168
+ setTelegramMode("byo");
555169
+ setScreen("byo-token");
555170
+ }
555171
+ }
555172
+ });
555173
+ }
555174
+ if (screen === "hosted") {
555175
+ return /* @__PURE__ */ jsx_runtime222.jsx(HostedStep, {
555176
+ onDone,
555177
+ onUseByo: () => setScreen("byo-token")
555178
+ });
555179
+ }
555180
+ if (screen === "byo-token") {
554594
555181
  return /* @__PURE__ */ jsx_runtime222.jsx(TokenInputStep, {
554595
- onTokenSaved: () => setHasToken(true)
555182
+ onReady: () => setScreen("byo-link")
554596
555183
  });
554597
555184
  }
554598
555185
  return /* @__PURE__ */ jsx_runtime222.jsx(LinkStep, {
@@ -554611,6 +555198,8 @@ var init_telegram_bot = __esm(() => {
554611
555198
  init_ink2();
554612
555199
  init_telegramConfig();
554613
555200
  init_telegramApi();
555201
+ init_telegramHostedApi();
555202
+ init_rayuSession();
554614
555203
  init_AppState();
554615
555204
  import_react132 = __toESM(require_react(), 1);
554616
555205
  jsx_runtime222 = __toESM(require_jsx_runtime(), 1);
@@ -554641,9 +555230,16 @@ async function call21() {
554641
555230
  return { type: "text", value: "Telegram bot is not currently linked." };
554642
555231
  }
554643
555232
  const username = config5.linkedUsername ? `@${config5.linkedUsername}` : "the linked chat";
554644
- const token = getBotToken();
554645
- if (token) {
554646
- sendMessage3(token, config5.linkedChatId, "\uD83D\uDD0C CLI disconnected. Run `/telegram-bot` to link again.").catch(() => {});
555233
+ if (getTelegramMode() === "hosted") {
555234
+ await relayHostedSend("sendMessage", {
555235
+ text: "\uD83D\uDD0C CLI disconnected. Run /telegram-bot to link again."
555236
+ }).catch(() => {});
555237
+ await deleteHostedLink();
555238
+ } else {
555239
+ const token = getBotToken();
555240
+ if (token) {
555241
+ sendMessage3(token, config5.linkedChatId, "\uD83D\uDD0C CLI disconnected. Run `/telegram-bot` to link again.").catch(() => {});
555242
+ }
554647
555243
  }
554648
555244
  unlink18();
554649
555245
  return { type: "text", value: `Disconnected Telegram bot (was linked to ${username}).` };
@@ -554651,6 +555247,7 @@ async function call21() {
554651
555247
  var init_disconnect = __esm(() => {
554652
555248
  init_telegramConfig();
554653
555249
  init_telegramApi();
555250
+ init_telegramHostedApi();
554654
555251
  });
554655
555252
 
554656
555253
  // src/commands/telegram-bot/disconnect-index.ts
@@ -556107,7 +556704,7 @@ function getRecentReleaseNotes(currentVersion, previousVersion, changelogContent
556107
556704
  }
556108
556705
  return [];
556109
556706
  }
556110
- async function checkForReleaseNotes(lastSeenVersion, currentVersion = "1.4.474") {
556707
+ async function checkForReleaseNotes(lastSeenVersion, currentVersion = "1.4.476") {
556111
556708
  if (false) {}
556112
556709
  const cachedChangelog = await getStoredChangelog();
556113
556710
  if (lastSeenVersion !== currentVersion || !cachedChangelog) {
@@ -556120,7 +556717,7 @@ async function checkForReleaseNotes(lastSeenVersion, currentVersion = "1.4.474")
556120
556717
  releaseNotes
556121
556718
  };
556122
556719
  }
556123
- function checkForReleaseNotesSync(lastSeenVersion, currentVersion = "1.4.474") {
556720
+ function checkForReleaseNotesSync(lastSeenVersion, currentVersion = "1.4.476") {
556124
556721
  if (false) {}
556125
556722
  const releaseNotes = getRecentReleaseNotes(currentVersion, lastSeenVersion);
556126
556723
  return {
@@ -556248,7 +556845,7 @@ function getRecentActivitySync() {
556248
556845
  return cachedActivity;
556249
556846
  }
556250
556847
  function getLogoDisplayData() {
556251
- const version2 = process.env.DEMO_VERSION ?? "1.4.474";
556848
+ const version2 = process.env.DEMO_VERSION ?? "1.4.476";
556252
556849
  const serverUrl = getDirectConnectServerUrl();
556253
556850
  const displayPath = process.env.DEMO_VERSION ? "/code/claude" : getDisplayPath(getCwd());
556254
556851
  const cwd2 = serverUrl ? `${displayPath} in ${serverUrl.replace(/^https?:\/\//, "")}` : displayPath;
@@ -557413,7 +558010,7 @@ function LogoV2() {
557413
558010
  if ($3[2] === Symbol.for("react.memo_cache_sentinel")) {
557414
558011
  t2 = () => {
557415
558012
  const currentConfig = getGlobalConfig();
557416
- if (currentConfig.lastReleaseNotesSeen === "1.4.474") {
558013
+ if (currentConfig.lastReleaseNotesSeen === "1.4.476") {
557417
558014
  return;
557418
558015
  }
557419
558016
  saveGlobalConfig(_temp327);
@@ -557892,7 +558489,7 @@ function LogoV2() {
557892
558489
  t24 = $3[61];
557893
558490
  }
557894
558491
  const _latestNpm = getCachedLatestNpmVersionSync();
557895
- const _updateFeeds = _latestNpm && gt(_latestNpm, "1.4.474") ? [createUpdateAvailableFeed("1.4.474", _latestNpm)] : [];
558492
+ const _updateFeeds = _latestNpm && gt(_latestNpm, "1.4.476") ? [createUpdateAvailableFeed("1.4.476", _latestNpm)] : [];
557896
558493
  const t25 = layoutMode === "horizontal" && /* @__PURE__ */ jsx_runtime236.jsx(FeedColumn, {
557897
558494
  feeds: showOnboarding ? [createProjectOnboardingFeed(getSteps()), createRecentActivityFeed(activities)] : showGuestPassesUpsell ? [createRecentActivityFeed(activities), createGuestPassesFeed()] : showOverageCreditUpsell ? [createRecentActivityFeed(activities), createOverageCreditFeed()] : [createRecentActivityFeed(activities), ..._updateFeeds, createWhatsNewFeed(changelog)],
557898
558495
  maxWidth: rightWidth
@@ -558092,12 +558689,12 @@ function LogoV2() {
558092
558689
  return t41;
558093
558690
  }
558094
558691
  function _temp327(current) {
558095
- if (current.lastReleaseNotesSeen === "1.4.474") {
558692
+ if (current.lastReleaseNotesSeen === "1.4.476") {
558096
558693
  return current;
558097
558694
  }
558098
558695
  return {
558099
558696
  ...current,
558100
- lastReleaseNotesSeen: "1.4.474"
558697
+ lastReleaseNotesSeen: "1.4.476"
558101
558698
  };
558102
558699
  }
558103
558700
  function _temp241(s_0) {
@@ -583096,7 +583693,7 @@ async function captureMemoryDiagnostics(trigger, dumpNumber = 0) {
583096
583693
  smapsRollup,
583097
583694
  platform: process.platform,
583098
583695
  nodeVersion: process.version,
583099
- ccVersion: "1.4.474"
583696
+ ccVersion: "1.4.476"
583100
583697
  };
583101
583698
  }
583102
583699
  async function performHeapDump(trigger = "manual", dumpNumber = 0) {
@@ -583618,7 +584215,7 @@ var init_bridge_kick = __esm(() => {
583618
584215
  var call50 = async () => {
583619
584216
  return {
583620
584217
  type: "text",
583621
- value: "1.4.474"
584218
+ value: "1.4.476"
583622
584219
  };
583623
584220
  }, version2, version_default;
583624
584221
  var init_version = __esm(() => {
@@ -594114,7 +594711,7 @@ function generateHtmlReport(data, insights) {
594114
594711
  </html>`;
594115
594712
  }
594116
594713
  function buildExportData(data, insights, facets, remoteStats) {
594117
- const version3 = typeof MACRO !== "undefined" ? "1.4.474" : "unknown";
594714
+ const version3 = typeof MACRO !== "undefined" ? "1.4.476" : "unknown";
594118
594715
  const remote_hosts_collected = remoteStats?.hosts.filter((h3) => h3.sessionCount > 0).map((h3) => h3.name);
594119
594716
  const facets_summary = {
594120
594717
  total: facets.size,
@@ -598028,7 +598625,7 @@ var init_sessionStorage = __esm(() => {
598028
598625
  init_settings2();
598029
598626
  init_slowOperations();
598030
598627
  init_uuid();
598031
- VERSION6 = typeof MACRO !== "undefined" ? "1.4.474" : "unknown";
598628
+ VERSION6 = typeof MACRO !== "undefined" ? "1.4.476" : "unknown";
598032
598629
  MAX_TOMBSTONE_REWRITE_BYTES = 50 * 1024 * 1024;
598033
598630
  SKIP_FIRST_PROMPT_PATTERN = /^(?:\s*<[a-z][\w-]*[\s>]|\[Request interrupted by user[^\]]*\])/;
598034
598631
  EPHEMERAL_PROGRESS_TYPES = new Set([
@@ -599246,7 +599843,7 @@ var init_filesystem = __esm(() => {
599246
599843
  });
599247
599844
  getBundledSkillsRoot = memoize_default(function getBundledSkillsRoot2() {
599248
599845
  const nonce = randomBytes19(16).toString("hex");
599249
- return join153(getClaudeTempDir(), "bundled-skills", "1.4.474", nonce);
599846
+ return join153(getClaudeTempDir(), "bundled-skills", "1.4.476", nonce);
599250
599847
  });
599251
599848
  getResolvedWorkingDirPaths = memoize_default(getPathsForPermissionCheck);
599252
599849
  });
@@ -604416,7 +605013,7 @@ __export(exports_update, {
604416
605013
  update: () => update
604417
605014
  });
604418
605015
  async function update() {
604419
- writeToStdout(`Current version: ${"1.4.474"}
605016
+ writeToStdout(`Current version: ${"1.4.476"}
604420
605017
  `);
604421
605018
  const isBundled = isInBundledMode();
604422
605019
  if (isBundled) {
@@ -604447,13 +605044,13 @@ Manual check: npm view ${"@rayu-dev/rayu-cli"} version
604447
605044
  process.exit(1);
604448
605045
  return;
604449
605046
  }
604450
- if (latestVersion === "1.4.474") {
605047
+ if (latestVersion === "1.4.476") {
604451
605048
  writeToStdout(source_default.green(`
604452
- Rayu CLI is up to date (${"1.4.474"})
605049
+ Rayu CLI is up to date (${"1.4.476"})
604453
605050
  `));
604454
605051
  process.exit(0);
604455
605052
  }
604456
- writeToStdout(`New version available: ${latestVersion} (current: ${"1.4.474"})
605053
+ writeToStdout(`New version available: ${latestVersion} (current: ${"1.4.476"})
604457
605054
  `);
604458
605055
  writeToStdout(`Installing update...
604459
605056
 
@@ -604520,14 +605117,14 @@ async function updateNativeBinary() {
604520
605117
  } catch {
604521
605118
  latestVersion = "";
604522
605119
  }
604523
- if (latestVersion && latestVersion === "1.4.474") {
605120
+ if (latestVersion && latestVersion === "1.4.476") {
604524
605121
  writeToStdout(source_default.green(`
604525
- Rayu CLI is up to date (1.4.474)
605122
+ Rayu CLI is up to date (1.4.476)
604526
605123
  `));
604527
605124
  process.exit(0);
604528
605125
  }
604529
605126
  if (latestVersion) {
604530
- writeToStdout(`New version available: ${latestVersion} (current: 1.4.474)
605127
+ writeToStdout(`New version available: ${latestVersion} (current: 1.4.476)
604531
605128
  `);
604532
605129
  }
604533
605130
  writeToStdout(`Downloading and installing update...
@@ -604542,13 +605139,13 @@ Rayu CLI is up to date (1.4.474)
604542
605139
  return;
604543
605140
  }
604544
605141
  writeToStdout(source_default.green(`
604545
- Rayu CLI is up to date (1.4.474)
605142
+ Rayu CLI is up to date (1.4.476)
604546
605143
  `));
604547
605144
  process.exit(0);
604548
605145
  }
604549
605146
  const updatedTo = result.latestVersion ?? latestVersion ?? "latest";
604550
605147
  writeToStdout(source_default.green(`
604551
- Successfully updated from 1.4.474 to ${updatedTo}
605148
+ Successfully updated from 1.4.476 to ${updatedTo}
604552
605149
  `));
604553
605150
  writeToStdout(`Restart your terminal to use the new version.
604554
605151
  `);
@@ -604613,7 +605210,7 @@ async function removeDataDir(dir) {
604613
605210
  async function uninstall(args = []) {
604614
605211
  const yes = args.includes("--yes") || args.includes("-y");
604615
605212
  const keepData = args.includes("--keep-data");
604616
- writeToStdout(`Uninstalling Rayu CLI (${"1.4.474"})...
605213
+ writeToStdout(`Uninstalling Rayu CLI (${"1.4.476"})...
604617
605214
  `);
604618
605215
  writeToStdout(`Running: npm uninstall -g ${"@rayu-dev/rayu-cli"}
604619
605216
 
@@ -604647,7 +605244,7 @@ This looks like a permissions error on npm's global install
604647
605244
  return;
604648
605245
  }
604649
605246
  writeToStdout(source_default.green(`
604650
- Successfully uninstalled ${"@rayu-dev/rayu-cli"} ${"1.4.474"}
605247
+ Successfully uninstalled ${"@rayu-dev/rayu-cli"} ${"1.4.476"}
604651
605248
  `));
604652
605249
  const configDir = getRayuConfigHomeDir();
604653
605250
  const dataExists = existsSync28(configDir);
@@ -604730,7 +605327,7 @@ function showFirstRunWelcome() {
604730
605327
  `);
604731
605328
  try {
604732
605329
  mkdirSync16(getRayuConfigHomeDir(), { recursive: true });
604733
- writeFileSync18(markerPath(), "1.4.474", "utf8");
605330
+ writeFileSync18(markerPath(), "1.4.476", "utf8");
604734
605331
  } catch {}
604735
605332
  }
604736
605333
  var init_firstRun = __esm(() => {
@@ -620916,7 +621513,7 @@ async function initializeBetaTracing(resource) {
620916
621513
  });
620917
621514
  import_api_logs.logs.setGlobalLoggerProvider(loggerProvider);
620918
621515
  setLoggerProvider(loggerProvider);
620919
- const eventLogger = import_api_logs.logs.getLogger("com.anthropic.claude_code.events", "1.4.474");
621516
+ const eventLogger = import_api_logs.logs.getLogger("com.anthropic.claude_code.events", "1.4.476");
620920
621517
  setEventLogger(eventLogger);
620921
621518
  process.on("beforeExit", async () => {
620922
621519
  await loggerProvider?.forceFlush();
@@ -620956,7 +621553,7 @@ async function initializeTelemetry() {
620956
621553
  const platform4 = getPlatform();
620957
621554
  const baseAttributes = {
620958
621555
  [import_semantic_conventions.ATTR_SERVICE_NAME]: "claude-code",
620959
- [import_semantic_conventions.ATTR_SERVICE_VERSION]: "1.4.474"
621556
+ [import_semantic_conventions.ATTR_SERVICE_VERSION]: "1.4.476"
620960
621557
  };
620961
621558
  if (platform4 === "wsl") {
620962
621559
  const wslVersion = getWslVersion();
@@ -621001,7 +621598,7 @@ async function initializeTelemetry() {
621001
621598
  } catch {}
621002
621599
  };
621003
621600
  registerCleanup(shutdownTelemetry2);
621004
- return meterProvider2.getMeter("com.anthropic.claude_code", "1.4.474");
621601
+ return meterProvider2.getMeter("com.anthropic.claude_code", "1.4.476");
621005
621602
  }
621006
621603
  const meterProvider = new import_sdk_metrics2.MeterProvider({
621007
621604
  resource,
@@ -621021,7 +621618,7 @@ async function initializeTelemetry() {
621021
621618
  });
621022
621619
  import_api_logs.logs.setGlobalLoggerProvider(loggerProvider);
621023
621620
  setLoggerProvider(loggerProvider);
621024
- const eventLogger = import_api_logs.logs.getLogger("com.anthropic.claude_code.events", "1.4.474");
621621
+ const eventLogger = import_api_logs.logs.getLogger("com.anthropic.claude_code.events", "1.4.476");
621025
621622
  setEventLogger(eventLogger);
621026
621623
  logForDebugging("[3P telemetry] Event logger set successfully");
621027
621624
  process.on("beforeExit", async () => {
@@ -621083,7 +621680,7 @@ Current timeout: ${timeoutMs}ms
621083
621680
  }
621084
621681
  };
621085
621682
  registerCleanup(shutdownTelemetry);
621086
- return meterProvider.getMeter("com.anthropic.claude_code", "1.4.474");
621683
+ return meterProvider.getMeter("com.anthropic.claude_code", "1.4.476");
621087
621684
  }
621088
621685
  async function flushTelemetry() {
621089
621686
  const meterProvider = getMeterProvider();
@@ -622585,7 +623182,7 @@ function buildSystemInitMessage(inputs) {
622585
623182
  slash_commands: inputs.commands.filter((c4) => c4.userInvocable !== false).map((c4) => c4.name),
622586
623183
  apiKeySource: getAnthropicApiKeyWithSource().source,
622587
623184
  betas: getSdkBetas(),
622588
- claude_code_version: "1.4.474",
623185
+ claude_code_version: "1.4.476",
622589
623186
  output_style: outputStyle2,
622590
623187
  agents: inputs.agents.map((agent) => agent.agentType),
622591
623188
  skills: inputs.skills.filter((s2) => s2.userInvocable !== false).map((skill) => skill.name),
@@ -623998,6 +624595,37 @@ var init_telegramBridge = __esm(() => {
623998
624595
  ]);
623999
624596
  });
624000
624597
 
624598
+ // src/telegram/telegramTransport.ts
624599
+ function createHostedRouter() {
624600
+ let after = 0;
624601
+ return {
624602
+ async getUpdates() {
624603
+ const batch = await getHostedUpdates(after);
624604
+ for (const row of batch.updates) {
624605
+ if (row.id > after)
624606
+ after = row.id;
624607
+ }
624608
+ return batch.updates.map((row) => row.update);
624609
+ },
624610
+ async call(method, params) {
624611
+ if (method === "getMe") {
624612
+ const info = await getHostedBotInfo();
624613
+ return { username: info.username ?? undefined };
624614
+ }
624615
+ if (method === "setMyCommands")
624616
+ return {};
624617
+ return relayHostedSend(method, params);
624618
+ },
624619
+ async botUsername() {
624620
+ const info = await getHostedBotInfo();
624621
+ return info.username ?? undefined;
624622
+ }
624623
+ };
624624
+ }
624625
+ var init_telegramTransport = __esm(() => {
624626
+ init_telegramHostedApi();
624627
+ });
624628
+
624001
624629
  // src/hooks/useTelegramBridge.tsx
624002
624630
  function isToolResultMessage2(msg) {
624003
624631
  if (msg.type !== "user")
@@ -624016,19 +624644,29 @@ function useTelegramBridge(messages) {
624016
624644
  import_react187.useEffect(() => {
624017
624645
  if (!bridgeActive)
624018
624646
  return;
624019
- const token = getBotToken();
624020
- if (!token)
624021
- return;
624647
+ const mode = getTelegramMode();
624648
+ let token;
624649
+ if (mode === "hosted") {
624650
+ if (!hasRayuSession())
624651
+ return;
624652
+ setHostedRouter(createHostedRouter());
624653
+ token = "hosted";
624654
+ } else {
624655
+ const byo = getBotToken();
624656
+ if (!byo)
624657
+ return;
624658
+ setHostedRouter(null);
624659
+ token = byo;
624660
+ }
624022
624661
  const handle = initTelegramBridge({ token });
624023
624662
  handleRef.current = handle;
624024
624663
  setAppState((prev) => ({ ...prev, telegramPermissionCallbacks: handle.permissionCallbacks }));
624025
624664
  return () => {
624026
624665
  handle.endTurn();
624027
624666
  const chatId = readTelegramConfig().linkedChatId;
624028
- if (chatId && token) {
624029
- sendMessage3(token, chatId, "\uD83D\uDD0C Session closed — rayu-cli disconnected.").catch(() => {});
624030
- }
624667
+ const notice = chatId !== undefined ? sendMessage3(token, chatId, "\uD83D\uDD0C Session closed — rayu-cli disconnected.").catch(() => {}) : Promise.resolve();
624031
624668
  handle.stop();
624669
+ notice.finally(() => setHostedRouter(null));
624032
624670
  handleRef.current = null;
624033
624671
  lastSentIndexRef.current = 0;
624034
624672
  inTurnRef.current = false;
@@ -624086,6 +624724,8 @@ var init_useTelegramBridge = __esm(() => {
624086
624724
  init_telegramBridge();
624087
624725
  init_formatActivity();
624088
624726
  init_telegramApi();
624727
+ init_telegramTransport();
624728
+ init_rayuSession();
624089
624729
  init_AppState();
624090
624730
  import_react187 = __toESM(require_react(), 1);
624091
624731
  });
@@ -638916,7 +639556,7 @@ var init_useVoiceEnabled = __esm(() => {
638916
639556
  function getSemverPart(version3) {
638917
639557
  return `${import_semver12.major(version3, { loose: true })}.${import_semver12.minor(version3, { loose: true })}.${import_semver12.patch(version3, { loose: true })}`;
638918
639558
  }
638919
- function useUpdateNotification(updatedVersion, initialVersion = "1.4.474") {
639559
+ function useUpdateNotification(updatedVersion, initialVersion = "1.4.476") {
638920
639560
  const [lastNotifiedSemver, setLastNotifiedSemver] = import_react217.useState(() => getSemverPart(initialVersion));
638921
639561
  if (!updatedVersion) {
638922
639562
  return null;
@@ -638956,7 +639596,7 @@ function AutoUpdater({
638956
639596
  return;
638957
639597
  }
638958
639598
  if (false) {}
638959
- const currentVersion = "1.4.474";
639599
+ const currentVersion = "1.4.476";
638960
639600
  const channel2 = getInitialSettings()?.autoUpdatesChannel ?? "latest";
638961
639601
  let latestVersion = await getLatestVersion(channel2);
638962
639602
  const isDisabled = isAutoUpdaterDisabled();
@@ -639169,12 +639809,12 @@ function NativeAutoUpdater({
639169
639809
  logEvent("tengu_native_auto_updater_start", {});
639170
639810
  try {
639171
639811
  const maxVersion = await getMaxVersion();
639172
- if (maxVersion && gt("1.4.474", maxVersion)) {
639812
+ if (maxVersion && gt("1.4.476", maxVersion)) {
639173
639813
  const msg = await getMaxVersionMessage();
639174
639814
  setMaxVersionIssue(msg ?? "affects your version");
639175
639815
  }
639176
639816
  const result = await installLatest(channel2);
639177
- const currentVersion = "1.4.474";
639817
+ const currentVersion = "1.4.476";
639178
639818
  const latencyMs = Date.now() - startTime2;
639179
639819
  if (result.lockFailed) {
639180
639820
  logEvent("tengu_native_auto_updater_lock_contention", {
@@ -639311,17 +639951,17 @@ function PackageManagerAutoUpdater(t0) {
639311
639951
  const maxVersion = await getMaxVersion();
639312
639952
  if (maxVersion && latest && gt(latest, maxVersion)) {
639313
639953
  logForDebugging(`PackageManagerAutoUpdater: maxVersion ${maxVersion} is set, capping update from ${latest} to ${maxVersion}`);
639314
- if (gte("1.4.474", maxVersion)) {
639315
- logForDebugging(`PackageManagerAutoUpdater: current version ${"1.4.474"} is already at or above maxVersion ${maxVersion}, skipping update`);
639954
+ if (gte("1.4.476", maxVersion)) {
639955
+ logForDebugging(`PackageManagerAutoUpdater: current version ${"1.4.476"} is already at or above maxVersion ${maxVersion}, skipping update`);
639316
639956
  setUpdateAvailable(false);
639317
639957
  return;
639318
639958
  }
639319
639959
  latest = maxVersion;
639320
639960
  }
639321
- const hasUpdate = latest && !gte("1.4.474", latest) && !shouldSkipVersion(latest);
639961
+ const hasUpdate = latest && !gte("1.4.476", latest) && !shouldSkipVersion(latest);
639322
639962
  setUpdateAvailable(!!hasUpdate);
639323
639963
  if (hasUpdate) {
639324
- logForDebugging(`PackageManagerAutoUpdater: Update available ${"1.4.474"} -> ${latest}`);
639964
+ logForDebugging(`PackageManagerAutoUpdater: Update available ${"1.4.476"} -> ${latest}`);
639325
639965
  }
639326
639966
  };
639327
639967
  $3[0] = t1;
@@ -639355,7 +639995,7 @@ function PackageManagerAutoUpdater(t0) {
639355
639995
  wrap: "truncate",
639356
639996
  children: [
639357
639997
  "currentVersion: ",
639358
- "1.4.474"
639998
+ "1.4.476"
639359
639999
  ]
639360
640000
  });
639361
640001
  $3[3] = verbose;
@@ -647519,7 +648159,7 @@ function buildStatusLineCommandInput(permissionMode, exceeds200kTokens, settings
647519
648159
  project_dir: getOriginalCwd(),
647520
648160
  added_dirs: addedDirs
647521
648161
  },
647522
- version: "1.4.474",
648162
+ version: "1.4.476",
647523
648163
  output_style: {
647524
648164
  name: outputStyleName
647525
648165
  },
@@ -649698,7 +650338,7 @@ var init_user = __esm(() => {
649698
650338
  deviceId,
649699
650339
  sessionId: getSessionId(),
649700
650340
  email: getEmail(),
649701
- appVersion: "1.4.474",
650341
+ appVersion: "1.4.476",
649702
650342
  platform: getHostPlatformForAnalytics(),
649703
650343
  organizationUuid,
649704
650344
  accountUuid,
@@ -659137,7 +659777,7 @@ async function submitTranscriptShare(messages, trigger, appearanceId) {
659137
659777
  } catch {}
659138
659778
  const data = {
659139
659779
  trigger,
659140
- version: "1.4.474",
659780
+ version: "1.4.476",
659141
659781
  platform: process.platform,
659142
659782
  transcript,
659143
659783
  subagentTranscripts: Object.keys(subagentTranscripts).length > 0 ? subagentTranscripts : undefined,
@@ -667415,6 +668055,7 @@ function REPL({
667415
668055
  apiMetricsRef2.current = [];
667416
668056
  setStreamingText(null);
667417
668057
  setStreamingToolUses([]);
668058
+ setStreamingThinking(finalizeStreamingThinkingOnTurnEnd);
667418
668059
  setSpinnerMessage(null);
667419
668060
  setSpinnerColor(null);
667420
668061
  setSpinnerShimmerColor(null);
@@ -671105,7 +671746,7 @@ function WelcomeV2() {
671105
671746
  dimColor: true,
671106
671747
  children: [
671107
671748
  "v",
671108
- "1.4.474"
671749
+ "1.4.476"
671109
671750
  ]
671110
671751
  })
671111
671752
  ]
@@ -672112,7 +672753,7 @@ function completeOnboarding() {
672112
672753
  saveGlobalConfig((current) => ({
672113
672754
  ...current,
672114
672755
  hasCompletedOnboarding: true,
672115
- lastOnboardingVersion: "1.4.474"
672756
+ lastOnboardingVersion: "1.4.476"
672116
672757
  }));
672117
672758
  }
672118
672759
  function showDialog(root2, renderer) {
@@ -677045,7 +677686,7 @@ function appendToLog(path29, message) {
677045
677686
  cwd: getFsImplementation().cwd(),
677046
677687
  userType: "external",
677047
677688
  sessionId: getSessionId(),
677048
- version: "1.4.474"
677689
+ version: "1.4.476"
677049
677690
  };
677050
677691
  getLogWriter(path29).write(messageWithTimestamp);
677051
677692
  }
@@ -681150,8 +681791,8 @@ async function getEnvLessBridgeConfig() {
681150
681791
  }
681151
681792
  async function checkEnvLessBridgeMinVersion() {
681152
681793
  const cfg = await getEnvLessBridgeConfig();
681153
- if (cfg.min_version && lt("1.4.474", cfg.min_version)) {
681154
- return `Your version of RAYU (${"1.4.474"}) is too old for Remote Control.
681794
+ if (cfg.min_version && lt("1.4.476", cfg.min_version)) {
681795
+ return `Your version of RAYU (${"1.4.476"}) is too old for Remote Control.
681155
681796
  Version ${cfg.min_version} or higher is required. Run \`claude update\` to update.`;
681156
681797
  }
681157
681798
  return null;
@@ -681624,7 +682265,7 @@ async function initBridgeCore(params) {
681624
682265
  const rawApi = createBridgeApiClient({
681625
682266
  baseUrl,
681626
682267
  getAccessToken,
681627
- runnerVersion: "1.4.474",
682268
+ runnerVersion: "1.4.476",
681628
682269
  onDebug: logForDebugging,
681629
682270
  onAuth401,
681630
682271
  getTrustedDeviceToken
@@ -686979,7 +687620,7 @@ async function startMCPServer(cwd3, debug4, verbose) {
686979
687620
  setCwd(cwd3);
686980
687621
  const server = new Server({
686981
687622
  name: "claude/tengu",
686982
- version: "1.4.474"
687623
+ version: "1.4.476"
686983
687624
  }, {
686984
687625
  capabilities: {
686985
687626
  tools: {}
@@ -689508,7 +690149,7 @@ ${customInstructions}` : customInstructions;
689508
690149
  }
689509
690150
  }
689510
690151
  logForDiagnosticsNoPII("info", "started", {
689511
- version: "1.4.474",
690152
+ version: "1.4.476",
689512
690153
  is_native_binary: isInBundledMode()
689513
690154
  });
689514
690155
  registerCleanup(async () => {
@@ -690227,7 +690868,7 @@ Usage: rayu --remote "your task description"`, () => gracefulShutdown(1));
690227
690868
  pendingHookMessages
690228
690869
  }, renderAndRun);
690229
690870
  }
690230
- }).version(`1.4.474 (${PRODUCT_NAME})`, "-v, --version", "Output the version number");
690871
+ }).version(`1.4.476 (${PRODUCT_NAME})`, "-v, --version", "Output the version number");
690231
690872
  program.option("-w, --worktree [name]", "Create a new git worktree for this session (optionally specify a name)");
690232
690873
  program.option("--tmux", "Create a tmux session for the worktree (requires --worktree). Uses iTerm2 native panes when available; use --tmux=classic for traditional tmux.");
690233
690874
  if (canUserConfigureAdvisor()) {
@@ -690687,7 +691328,7 @@ if (false) {}
690687
691328
  async function main2() {
690688
691329
  const args = process.argv.slice(2);
690689
691330
  if (args.length === 1 && (args[0] === "--version" || args[0] === "-v" || args[0] === "-V")) {
690690
- console.log(`${"1.4.474"} (Rayu-CLI)`);
691331
+ console.log(`${"1.4.476"} (Rayu-CLI)`);
690691
691332
  return;
690692
691333
  }
690693
691334
  if (!isEnvTruthy(process.env.CLAUDE_CODE_DISABLE_TERMINAL_TITLE)) {