@rayu-dev/rayu-cli 1.3.439 → 1.3.441

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 +778 -276
  2. package/package.json +5 -2
package/dist/rayu.js CHANGED
@@ -19391,7 +19391,7 @@ var init_contextPrepCache = __esm(() => {
19391
19391
  });
19392
19392
 
19393
19393
  // src/utils/curatedProviderModels.ts
19394
- var DOUBLEWORD_MODELS, CURATED_PROVIDER_MODELS;
19394
+ var DOUBLEWORD_MODELS, FUGU_MODELS, CURATED_PROVIDER_MODELS;
19395
19395
  var init_curatedProviderModels = __esm(() => {
19396
19396
  DOUBLEWORD_MODELS = [
19397
19397
  "Qwen/Qwen3-14B-FP8",
@@ -19412,8 +19412,10 @@ var init_curatedProviderModels = __esm(() => {
19412
19412
  "openai/gpt-oss-20b",
19413
19413
  "zai-org/GLM-5.1-FP8"
19414
19414
  ];
19415
+ FUGU_MODELS = ["fugu", "fugu-ultra"];
19415
19416
  CURATED_PROVIDER_MODELS = {
19416
- doubleword: DOUBLEWORD_MODELS
19417
+ doubleword: DOUBLEWORD_MODELS,
19418
+ fugu: FUGU_MODELS
19417
19419
  };
19418
19420
  });
19419
19421
 
@@ -36083,6 +36085,15 @@ var init_rayuProviders = __esm(() => {
36083
36085
  smallFastModel: "kimi-for-coding",
36084
36086
  envKeys: ["KIMI_FOR_CODE_API_KEY"]
36085
36087
  },
36088
+ {
36089
+ id: "fugu",
36090
+ label: "Fugu — Sakana AI (api.sakana.ai)",
36091
+ kind: "openai-compatible",
36092
+ baseURL: "https://api.sakana.ai/v1",
36093
+ defaultModel: "fugu",
36094
+ smallFastModel: "fugu",
36095
+ envKeys: ["SAKANA_API_KEY"]
36096
+ },
36086
36097
  {
36087
36098
  id: "openai",
36088
36099
  label: "OpenAI (api.openai.com)",
@@ -36238,6 +36249,7 @@ var init_rayuProviders = __esm(() => {
36238
36249
  deepseek: "DeepSeek",
36239
36250
  "kimi-moonshot": "Kimi",
36240
36251
  "kimi-for-code": "Kimi for Code",
36252
+ fugu: "Fugu",
36241
36253
  openai: "OpenAI",
36242
36254
  gemini: "Gemini",
36243
36255
  [GEMINI_VERTEX_PROVIDER_ID]: "Vertex AI",
@@ -37045,7 +37057,9 @@ var init_rayuConfig = __esm(() => {
37045
37057
  [/gemini/i, 1048576],
37046
37058
  [/deepseek[-/]?v4[-/]?(flash|pro)/i, 1e6],
37047
37059
  [/minimax/i, 1e6],
37060
+ [/fugu/i, 1e6],
37048
37061
  [/kimi-k1|kimi.*long/i, 200000],
37062
+ [/kimi[-_.]?k2[-_.]?(thinking|\d{4}|[5-9])/i, 256000],
37049
37063
  [/kimi|moonshot/i, 131072],
37050
37064
  [/qwen[-.]?3[-.]?(coder|next)/i, 256000],
37051
37065
  [/jamba/i, 256000],
@@ -81313,7 +81327,6 @@ var init_PermissionMode = __esm(() => {
81313
81327
  ...{}
81314
81328
  };
81315
81329
  });
81316
-
81317
81330
  // src/entrypoints/sdk/coreTypes.generated.ts
81318
81331
  var init_coreTypes_generated = () => {};
81319
81332
 
@@ -148546,7 +148559,7 @@ var init_auth = __esm(() => {
148546
148559
 
148547
148560
  // src/utils/userAgent.ts
148548
148561
  function getRayuUserAgent() {
148549
- return `rayu/${"1.3.439"}`;
148562
+ return `rayu/${"1.3.441"}`;
148550
148563
  }
148551
148564
  var getClaudeCodeUserAgent;
148552
148565
  var init_userAgent = __esm(() => {
@@ -148572,7 +148585,7 @@ function getUserAgent() {
148572
148585
  const clientApp = process.env.RAYU_AGENT_SDK_CLIENT_APP ? `, client-app/${process.env.RAYU_AGENT_SDK_CLIENT_APP}` : "";
148573
148586
  const workload = getWorkload();
148574
148587
  const workloadSuffix = workload ? `, workload/${workload}` : "";
148575
- return `rayu/${"1.3.439"} (${"external"}, ${process.env.RAYU_ENTRYPOINT ?? "cli"}${agentSdkVersion}${clientApp}${workloadSuffix})`;
148588
+ return `rayu/${"1.3.441"} (${"external"}, ${process.env.RAYU_ENTRYPOINT ?? "cli"}${agentSdkVersion}${clientApp}${workloadSuffix})`;
148576
148589
  }
148577
148590
  function getMCPUserAgent() {
148578
148591
  const parts = [];
@@ -148586,7 +148599,7 @@ function getMCPUserAgent() {
148586
148599
  parts.push(`client-app/${process.env.RAYU_AGENT_SDK_CLIENT_APP}`);
148587
148600
  }
148588
148601
  const suffix = parts.length > 0 ? ` (${parts.join(", ")})` : "";
148589
- return `rayu/${"1.3.439"}${suffix}`;
148602
+ return `rayu/${"1.3.441"}${suffix}`;
148590
148603
  }
148591
148604
  function getWebFetchUserAgent() {
148592
148605
  return `Rayu-User (${getRayuUserAgent()})`;
@@ -148709,7 +148722,7 @@ var init_user = __esm(() => {
148709
148722
  deviceId,
148710
148723
  sessionId: getSessionId(),
148711
148724
  email: getEmail(),
148712
- appVersion: "1.3.439",
148725
+ appVersion: "1.3.441",
148713
148726
  platform: getHostPlatformForAnalytics(),
148714
148727
  organizationUuid,
148715
148728
  accountUuid,
@@ -165682,11 +165695,11 @@ function isUseRayuOAuthEnabled() {
165682
165695
  return isEnvTruthy("false");
165683
165696
  }
165684
165697
  function getRayuApiBaseUrl() {
165685
- const base2 = process.env.RAYU_API_URL || "" || "http://localhost:4000/api";
165698
+ const base2 = process.env.RAYU_API_URL || "http://localhost:4000/api";
165686
165699
  return base2.replace(/\/$/, "");
165687
165700
  }
165688
165701
  function getRayuWebBaseUrl() {
165689
- const base2 = process.env.RAYU_WEB_URL || "" || "http://localhost:3000";
165702
+ const base2 = process.env.RAYU_WEB_URL || "http://localhost:3000";
165690
165703
  return base2.replace(/\/$/, "");
165691
165704
  }
165692
165705
  function getRayuGatewayBaseUrl() {
@@ -165891,6 +165904,9 @@ function makeGatewayRoutingFetch(provider, inner = globalThis.fetch) {
165891
165904
  headers.set("X-Rayu-Provider", provider.id);
165892
165905
  try {
165893
165906
  const res = await inner(gatewayUrl, { ...init, headers });
165907
+ if (res.headers.get(LIMIT_HEADER)) {
165908
+ return res;
165909
+ }
165894
165910
  if (!res.headers.get(PROXIED_HEADER)) {
165895
165911
  return inner(input, init);
165896
165912
  }
@@ -165901,7 +165917,7 @@ function makeGatewayRoutingFetch(provider, inner = globalThis.fetch) {
165901
165917
  };
165902
165918
  return wrapped;
165903
165919
  }
165904
- var PROXIED_HEADER = "x-rayu-proxied";
165920
+ var PROXIED_HEADER = "x-rayu-proxied", LIMIT_HEADER = "x-rayu-limit";
165905
165921
  var init_gatewayRouting = __esm(() => {
165906
165922
  init_rayuSession();
165907
165923
  init_envUtils();
@@ -184593,7 +184609,7 @@ var init_metadata = __esm(() => {
184593
184609
  COMPOUND_OPERATOR_REGEX = /\s*(?:&&|\|\||[;|])\s*/;
184594
184610
  WHITESPACE_REGEX = /\s+/;
184595
184611
  getVersionBase = memoize_default(() => {
184596
- const match = "1.3.439".match(/^\d+\.\d+\.\d+(?:-[a-z]+)?/);
184612
+ const match = "1.3.441".match(/^\d+\.\d+\.\d+(?:-[a-z]+)?/);
184597
184613
  return match ? match[0] : undefined;
184598
184614
  });
184599
184615
  buildEnvContext = memoize_default(async () => {
@@ -184632,7 +184648,7 @@ var init_metadata = __esm(() => {
184632
184648
  },
184633
184649
  isGithubAction: isEnvTruthy(process.env.GITHUB_ACTIONS),
184634
184650
  isRayuAction: isEnvTruthy(process.env.RAYU_ACTION),
184635
- version: "1.3.439",
184651
+ version: "1.3.441",
184636
184652
  versionBase: getVersionBase(),
184637
184653
  buildTime: "",
184638
184654
  deploymentEnvironment: env4.detectDeploymentEnvironment(),
@@ -185246,7 +185262,7 @@ function initialize1PEventLogging() {
185246
185262
  const platform2 = getPlatform();
185247
185263
  const attributes = {
185248
185264
  [import_semantic_conventions.ATTR_SERVICE_NAME]: "rayu",
185249
- [import_semantic_conventions.ATTR_SERVICE_VERSION]: "1.3.439"
185265
+ [import_semantic_conventions.ATTR_SERVICE_VERSION]: "1.3.441"
185250
185266
  };
185251
185267
  if (platform2 === "wsl") {
185252
185268
  const wslVersion = getWslVersion();
@@ -185273,7 +185289,7 @@ function initialize1PEventLogging() {
185273
185289
  })
185274
185290
  ]
185275
185291
  });
185276
- firstPartyEventLogger = firstPartyEventLoggerProvider.getLogger("io.rayu.events", "1.3.439");
185292
+ firstPartyEventLogger = firstPartyEventLoggerProvider.getLogger("io.rayu.events", "1.3.441");
185277
185293
  }
185278
185294
  async function reinitialize1PEventLoggingIfConfigChanged() {
185279
185295
  if (!is1PEventLoggingEnabled() || !firstPartyEventLoggerProvider) {
@@ -221189,7 +221205,7 @@ function getAttributionHeader(fingerprint) {
221189
221205
  if (!isAttributionHeaderEnabled()) {
221190
221206
  return "";
221191
221207
  }
221192
- const version2 = `${"1.3.439"}.${fingerprint}`;
221208
+ const version2 = `${"1.3.441"}.${fingerprint}`;
221193
221209
  const entrypoint = process.env.CLAUDE_CODE_ENTRYPOINT ?? "unknown";
221194
221210
  const cch = "";
221195
221211
  const workload = getWorkload();
@@ -306109,7 +306125,7 @@ function getTelemetryAttributes() {
306109
306125
  attributes["session.id"] = sessionId;
306110
306126
  }
306111
306127
  if (shouldIncludeAttribute("OTEL_METRICS_INCLUDE_VERSION")) {
306112
- attributes["app.version"] = "1.3.439";
306128
+ attributes["app.version"] = "1.3.441";
306113
306129
  }
306114
306130
  const oauthAccount = getOauthAccountInfo();
306115
306131
  if (oauthAccount) {
@@ -416464,7 +416480,7 @@ function getInstallationEnv() {
416464
416480
  return;
416465
416481
  }
416466
416482
  function getClaudeCodeVersion() {
416467
- return "1.3.439";
416483
+ return "1.3.441";
416468
416484
  }
416469
416485
  async function getInstalledVSCodeExtensionVersion(command) {
416470
416486
  const { stdout } = await execFileNoThrow(command, ["--list-extensions", "--show-versions"], {
@@ -421702,7 +421718,7 @@ async function setupSdkMcpClients(sdkMcpConfigs, sendMcpMessage) {
421702
421718
  const client4 = new Client({
421703
421719
  name: "claude-code",
421704
421720
  title: "RAYU",
421705
- version: "1.3.439",
421721
+ version: "1.3.441",
421706
421722
  description: "Anthropic's agentic coding tool",
421707
421723
  websiteUrl: PRODUCT_URL
421708
421724
  }, {
@@ -422019,7 +422035,7 @@ var init_client7 = __esm(() => {
422019
422035
  const client4 = new Client({
422020
422036
  name: "claude-code",
422021
422037
  title: "RAYU",
422022
- version: "1.3.439",
422038
+ version: "1.3.441",
422023
422039
  description: "Anthropic's agentic coding tool",
422024
422040
  websiteUrl: PRODUCT_URL
422025
422041
  }, {
@@ -436824,7 +436840,7 @@ function computeFingerprint(messageText, version2) {
436824
436840
  }
436825
436841
  function computeFingerprintFromMessages(messages) {
436826
436842
  const firstMessageText = extractFirstMessageText(messages);
436827
- return computeFingerprint(firstMessageText, "1.3.439");
436843
+ return computeFingerprint(firstMessageText, "1.3.441");
436828
436844
  }
436829
436845
  var FINGERPRINT_SALT = "59cf53e54c78";
436830
436846
  var init_fingerprint = () => {};
@@ -436866,7 +436882,7 @@ async function sideQuery(opts) {
436866
436882
  betas.push(STRUCTURED_OUTPUTS_BETA_HEADER);
436867
436883
  }
436868
436884
  const messageText = extractFirstUserMessageText(messages);
436869
- const fingerprint = computeFingerprint(messageText, "1.3.439");
436885
+ const fingerprint = computeFingerprint(messageText, "1.3.441");
436870
436886
  const attributionHeader = getAttributionHeader(fingerprint);
436871
436887
  const systemBlocks = [
436872
436888
  attributionHeader ? { type: "text", text: attributionHeader } : null,
@@ -439419,7 +439435,8 @@ function AssistantThinkingMessage({
439419
439435
  isTranscriptMode,
439420
439436
  verbose,
439421
439437
  hideInTranscript = false,
439422
- isThinking = false
439438
+ isThinking = false,
439439
+ liveStreamingPreview = false
439423
439440
  }) {
439424
439441
  if (!thinking) {
439425
439442
  return null;
@@ -439428,6 +439445,40 @@ function AssistantThinkingMessage({
439428
439445
  return null;
439429
439446
  }
439430
439447
  const shouldShowFullThinking = isTranscriptMode || verbose;
439448
+ if (liveStreamingPreview && isThinking && !shouldShowFullThinking) {
439449
+ const previewLines = thinking.split(`
439450
+ `).map((line) => line.trimEnd()).filter((line) => line.length > 0).slice(-THINKING_PREVIEW_LINES);
439451
+ const preview = previewLines.join(`
439452
+ `);
439453
+ return /* @__PURE__ */ jsx_dev_runtime71.jsxDEV(ThemedBox_default, {
439454
+ flexDirection: "column",
439455
+ marginTop: addMargin ? 1 : 0,
439456
+ width: "100%",
439457
+ children: [
439458
+ /* @__PURE__ */ jsx_dev_runtime71.jsxDEV(ThinkingHeader, {}, undefined, false, undefined, this),
439459
+ /* @__PURE__ */ jsx_dev_runtime71.jsxDEV(ThemedBox_default, {
439460
+ paddingLeft: 2,
439461
+ flexDirection: "column",
439462
+ children: [
439463
+ preview ? /* @__PURE__ */ jsx_dev_runtime71.jsxDEV(ThemedBox_default, {
439464
+ height: Math.min(THINKING_PREVIEW_LINES, previewLines.length),
439465
+ flexDirection: "column",
439466
+ overflow: "hidden",
439467
+ children: /* @__PURE__ */ jsx_dev_runtime71.jsxDEV(ThemedText, {
439468
+ dimColor: true,
439469
+ children: preview
439470
+ }, undefined, false, undefined, this)
439471
+ }, undefined, false, undefined, this) : null,
439472
+ /* @__PURE__ */ jsx_dev_runtime71.jsxDEV(ThemedText, {
439473
+ dimColor: true,
439474
+ italic: true,
439475
+ children: /* @__PURE__ */ jsx_dev_runtime71.jsxDEV(CtrlOToExpand, {}, undefined, false, undefined, this)
439476
+ }, undefined, false, undefined, this)
439477
+ ]
439478
+ }, undefined, true, undefined, this)
439479
+ ]
439480
+ }, undefined, true, undefined, this);
439481
+ }
439431
439482
  if (!shouldShowFullThinking) {
439432
439483
  return /* @__PURE__ */ jsx_dev_runtime71.jsxDEV(ThemedBox_default, {
439433
439484
  marginTop: addMargin ? 1 : 0,
@@ -439473,7 +439524,7 @@ function AssistantThinkingMessage({
439473
439524
  ]
439474
439525
  }, undefined, true, undefined, this);
439475
439526
  }
439476
- var jsx_dev_runtime71, THINK_PULSE, THINK_FRAMES, THINK_ICON_COLOR = "#F5F5F5";
439527
+ var jsx_dev_runtime71, THINK_PULSE, THINK_FRAMES, THINK_ICON_COLOR = "#F5F5F5", THINKING_PREVIEW_LINES = 3;
439477
439528
  var init_AssistantThinkingMessage = __esm(() => {
439478
439529
  init_figures();
439479
439530
  init_ink2();
@@ -447735,7 +447786,7 @@ function TurnDurationMessage(t0) {
447735
447786
  } else {
447736
447787
  t6 = $3[8];
447737
447788
  }
447738
- const t7 = showTurnDuration && `${verb} for ${duration3}`;
447789
+ const t7 = showTurnDuration && `Rayu ${verb.toLowerCase()} for ${duration3}`;
447739
447790
  const t8 = backgroundTaskSummary && ` · ${backgroundTaskSummary} still running`;
447740
447791
  let t9;
447741
447792
  if ($3[9] !== budgetSuffix || $3[10] !== t7 || $3[11] !== t8) {
@@ -468690,34 +468741,41 @@ function classifySource(rawSource, localExists) {
468690
468741
  }
468691
468742
  return { type: "local", path: source };
468692
468743
  }
468693
- async function locateSkillDir(root2) {
468744
+ async function locateSkillDirs(root2) {
468694
468745
  if (await fileExists(join92(root2, "SKILL.md")))
468695
- return root2;
468696
- const found = await findSkillDirRecursive(root2, 0, 5);
468697
- if (found)
468746
+ return [root2];
468747
+ const skillsContainer = join92(root2, "skills");
468748
+ if (await fileExists(skillsContainer)) {
468749
+ const collected = await collectSkillDirs(skillsContainer, 0, 4, []);
468750
+ if (collected.length > 0)
468751
+ return collected;
468752
+ }
468753
+ const found = await collectSkillDirs(root2, 0, 5, []);
468754
+ if (found.length > 0)
468698
468755
  return found;
468699
- throw new InstallSkillError("No SKILL.md found. Check that the source has a SKILL.md file at the root, or " + "specify a subdirectory: owner/repo/tree/main/path/to/skill");
468756
+ throw new InstallSkillError("No SKILL.md found. The source should contain a SKILL.md (a single skill), " + 'a "skills/" directory of skills, or you can point at a subdirectory: ' + "owner/repo/tree/main/path/to/skill");
468700
468757
  }
468701
- async function findSkillDirRecursive(dir, depth, maxDepth) {
468702
- if (depth >= maxDepth)
468703
- return null;
468758
+ async function collectSkillDirs(dir, depth, maxDepth, out) {
468759
+ if (depth > maxDepth)
468760
+ return out;
468761
+ if (await fileExists(join92(dir, "SKILL.md"))) {
468762
+ out.push(dir);
468763
+ return out;
468764
+ }
468704
468765
  let entries;
468705
468766
  try {
468706
468767
  entries = await readdir13(dir, { withFileTypes: true });
468707
468768
  } catch {
468708
- return null;
468769
+ return out;
468709
468770
  }
468710
468771
  for (const e2 of entries) {
468711
468772
  if (!e2.isDirectory())
468712
468773
  continue;
468713
- const candidate = join92(dir, e2.name);
468714
- if (await fileExists(join92(candidate, "SKILL.md")))
468715
- return candidate;
468716
- const deeper = await findSkillDirRecursive(candidate, depth + 1, maxDepth);
468717
- if (deeper)
468718
- return deeper;
468774
+ if (e2.name.startsWith(".") || e2.name === "node_modules")
468775
+ continue;
468776
+ await collectSkillDirs(join92(dir, e2.name), depth + 1, maxDepth, out);
468719
468777
  }
468720
- return null;
468778
+ return out;
468721
468779
  }
468722
468780
  async function fileExists(p) {
468723
468781
  try {
@@ -468750,9 +468808,9 @@ async function installSkillFromSource(rawSource, options = {}) {
468750
468808
  const kind = classifySource(source, localExists);
468751
468809
  const staging = await mkdtemp3(join92(tmpdir10(), "rayu-skill-"));
468752
468810
  try {
468753
- let skillDir;
468811
+ let scanRoot;
468754
468812
  if (kind.type === "local") {
468755
- skillDir = await locateSkillDir(expandHome(kind.path));
468813
+ scanRoot = expandHome(kind.path);
468756
468814
  } else if (kind.type === "github") {
468757
468815
  const cloneDir = join92(staging, "repo");
468758
468816
  await cloneGitHub(kind.owner, kind.repo, cloneDir);
@@ -468760,41 +468818,57 @@ async function installSkillFromSource(rawSource, options = {}) {
468760
468818
  if (!resolve38(root2).startsWith(resolve38(cloneDir))) {
468761
468819
  throw new InstallSkillError("Invalid subdir in GitHub source.");
468762
468820
  }
468763
- skillDir = await locateSkillDir(root2);
468821
+ scanRoot = root2;
468764
468822
  } else {
468765
468823
  const dlDir = join92(staging, "dl");
468766
468824
  await mkdir19(dlDir, { recursive: true });
468767
468825
  const md3 = await downloadText(kind.url);
468768
468826
  await writeFile17(join92(dlDir, "SKILL.md"), md3, "utf-8");
468769
- skillDir = dlDir;
468770
- }
468771
- const skillFile = join92(skillDir, "SKILL.md");
468772
- let content;
468773
- try {
468774
- content = await readFile24(skillFile, { encoding: "utf-8" });
468775
- } catch {
468776
- throw new InstallSkillError(`SKILL.md not readable at ${skillFile}.`);
468827
+ scanRoot = dlDir;
468777
468828
  }
468778
- const { frontmatter, content: markdown } = parseFrontmatter(content, skillFile);
468779
- const nameSource = (frontmatter.name != null ? String(frontmatter.name) : "") || basename27(skillDir);
468780
- const name = sanitizeSkillName(nameSource);
468781
- const description = (frontmatter.description != null ? String(frontmatter.description) : "") || firstLine(markdown) || "Installed skill";
468829
+ const skillDirs = await locateSkillDirs(scanRoot);
468782
468830
  const skillsRoot = getUserSkillsDir();
468783
- const dest = join92(skillsRoot, name);
468784
- if (!resolve38(dest).startsWith(resolve38(skillsRoot) + sep25)) {
468785
- throw new InstallSkillError(`Refusing to install outside ${skillsRoot}.`);
468786
- }
468787
- if (await fileExists(dest) && !options.overwrite) {
468788
- throw new InstallSkillError(`A skill named "${name}" is already installed. Re-run with overwrite to replace it.`);
468831
+ const planned = [];
468832
+ const seenNames = new Set;
468833
+ for (const skillDir of skillDirs) {
468834
+ const skillFile = join92(skillDir, "SKILL.md");
468835
+ let content;
468836
+ try {
468837
+ content = await readFile24(skillFile, { encoding: "utf-8" });
468838
+ } catch {
468839
+ throw new InstallSkillError(`SKILL.md not readable at ${skillFile}.`);
468840
+ }
468841
+ const { frontmatter, content: markdown } = parseFrontmatter(content, skillFile);
468842
+ const nameSource = (frontmatter.name != null ? String(frontmatter.name) : "") || basename27(skillDir);
468843
+ const name = sanitizeSkillName(nameSource);
468844
+ if (seenNames.has(name))
468845
+ continue;
468846
+ seenNames.add(name);
468847
+ const description = (frontmatter.description != null ? String(frontmatter.description) : "") || firstLine(markdown) || "Installed skill";
468848
+ const dest = join92(skillsRoot, name);
468849
+ if (!resolve38(dest).startsWith(resolve38(skillsRoot) + sep25)) {
468850
+ throw new InstallSkillError(`Refusing to install outside ${skillsRoot}.`);
468851
+ }
468852
+ planned.push({ skillDir, name, description, dest });
468789
468853
  }
468790
468854
  await mkdir19(skillsRoot, { recursive: true, mode: 448 });
468791
- const tmpDest = join92(skillsRoot, `.${name}.installing-${randomUUID21()}`);
468792
- await cp2(skillDir, tmpDest, { recursive: true });
468793
- await rm7(dest, { recursive: true, force: true });
468794
- await rename4(tmpDest, dest);
468855
+ const installed = [];
468856
+ for (const p of planned) {
468857
+ const replaced = await fileExists(p.dest);
468858
+ const tmpDest = join92(skillsRoot, `.${p.name}.installing-${randomUUID21()}`);
468859
+ await cp2(p.skillDir, tmpDest, { recursive: true });
468860
+ await rm7(p.dest, { recursive: true, force: true });
468861
+ await rename4(tmpDest, p.dest);
468862
+ installed.push({
468863
+ name: p.name,
468864
+ description: p.description,
468865
+ path: p.dest,
468866
+ replaced
468867
+ });
468868
+ }
468795
468869
  clearSkillCaches();
468796
468870
  clearCommandMemoizationCaches();
468797
- return { name, description, path: dest };
468871
+ return installed;
468798
468872
  } finally {
468799
468873
  await rm7(staging, { recursive: true, force: true }).catch((e2) => logError2(e2));
468800
468874
  }
@@ -468852,8 +468926,11 @@ The "source" can be:
468852
468926
  - a direct URL to a SKILL.md file
468853
468927
  - a local directory path containing a SKILL.md
468854
468928
 
468929
+ If the source is a collection — a repo with a "skills/" directory, or any tree
468930
+ containing multiple SKILL.md files — every skill it contains is installed.
468931
+
468855
468932
  Skills are installed into the Rayu user skills directory (~/.rayu/skills/<name>/).
468856
- Set "overwrite" to true to replace a skill that is already installed.`, inputSchema17, outputSchema15, InstallSkillTool;
468933
+ Reinstalling overwrites an existing skill of the same name and reports it as replaced.`, inputSchema17, outputSchema15, InstallSkillTool;
468857
468934
  var init_InstallSkillTool = __esm(() => {
468858
468935
  init_v4();
468859
468936
  init_Tool();
@@ -468863,9 +468940,12 @@ var init_InstallSkillTool = __esm(() => {
468863
468940
  overwrite: exports_external.boolean().optional().describe("Replace an already-installed skill with the same name")
468864
468941
  }));
468865
468942
  outputSchema15 = lazySchema(() => exports_external.object({
468866
- name: exports_external.string(),
468867
- description: exports_external.string(),
468868
- path: exports_external.string()
468943
+ skills: exports_external.array(exports_external.object({
468944
+ name: exports_external.string(),
468945
+ description: exports_external.string(),
468946
+ path: exports_external.string(),
468947
+ replaced: exports_external.boolean()
468948
+ }))
468869
468949
  }));
468870
468950
  InstallSkillTool = buildTool({
468871
468951
  name: INSTALL_SKILL_TOOL_NAME,
@@ -468912,17 +468992,21 @@ var init_InstallSkillTool = __esm(() => {
468912
468992
  };
468913
468993
  },
468914
468994
  async call(input, _context) {
468915
- const skill = await installSkillFromSource(input.source, {
468995
+ const skills = await installSkillFromSource(input.source, {
468916
468996
  overwrite: input.overwrite
468917
468997
  });
468918
- return { data: skill };
468998
+ return { data: { skills } };
468919
468999
  },
468920
469000
  mapToolResultToToolResultBlockParam(output, toolUseID) {
469001
+ const replaced = output.skills.filter((s2) => s2.replaced);
469002
+ const header = output.skills.length === 1 ? `Installed skill "${output.skills[0].name}"${output.skills[0].replaced ? " (a skill of the same name already existed and was overwritten)" : ""}.` : `Installed ${output.skills.length} skills` + (replaced.length ? ` (${replaced.length} already existed and ${replaced.length === 1 ? "was" : "were"} overwritten: ${replaced.map((s2) => s2.name).join(", ")})` : "") + ".";
469003
+ const lines2 = output.skills.map((s2) => `- /${s2.name}${s2.replaced ? " [overwritten]" : ""} (${s2.path}): ${s2.description}`);
468921
469004
  return {
468922
469005
  tool_use_id: toolUseID,
468923
469006
  type: "tool_result",
468924
- content: `Installed skill "${output.name}" into ${output.path}. It is now invocable as /${output.name} or via the Skill tool.
468925
- Description: ${output.description}`
469007
+ content: `${header} Each is now invocable as /<name> or via the Skill tool.
469008
+ ${lines2.join(`
469009
+ `)}`
468926
469010
  };
468927
469011
  }
468928
469012
  });
@@ -491479,12 +491563,13 @@ function rayuFeatureAllowed(featureKey) {
491479
491563
  if (!isUseRayuOAuthEnabled())
491480
491564
  return true;
491481
491565
  const ent = getCachedEntitlements();
491482
- if (!ent || !ent.features)
491483
- return true;
491484
- const f3 = ent.features[featureKey];
491485
- if (!f3)
491486
- return true;
491487
- return f3.enabled !== false;
491566
+ if (ent && ent.features) {
491567
+ const f3 = ent.features[featureKey];
491568
+ if (!f3)
491569
+ return true;
491570
+ return f3.enabled !== false;
491571
+ }
491572
+ return !hasRayuSession();
491488
491573
  }
491489
491574
  var FILE = "rayu-entitlements.json", REFRESH_COOLDOWN_MS = 30000, cache5 = null, loadedFromDisk = false, fetching = false, lastAttempt = 0;
491490
491575
  var init_rayuEntitlements = __esm(() => {
@@ -491493,6 +491578,191 @@ var init_rayuEntitlements = __esm(() => {
491493
491578
  init_rayuSession();
491494
491579
  });
491495
491580
 
491581
+ // src/services/rayuAuth/rayuFeatureUsage.ts
491582
+ function getFeatureUsage(featureKey) {
491583
+ maybeRefreshFeatureUsage();
491584
+ if (!cache6)
491585
+ return null;
491586
+ return cache6[featureKey] ?? null;
491587
+ }
491588
+ function maybeRefreshFeatureUsage() {
491589
+ if (isUseRayuOAuthEnabled() && hasRayuSession() && !fetching2 && Date.now() - lastAttempt2 > REFRESH_COOLDOWN_MS2) {
491590
+ refreshFeatureUsage();
491591
+ }
491592
+ }
491593
+ async function refreshFeatureUsage() {
491594
+ if (!isUseRayuOAuthEnabled() || !hasRayuSession() || fetching2)
491595
+ return;
491596
+ fetching2 = true;
491597
+ lastAttempt2 = Date.now();
491598
+ try {
491599
+ const token = await getValidRayuAccessToken();
491600
+ if (!token)
491601
+ return;
491602
+ const res = await globalThis.fetch(`${getRayuApiBaseUrl()}/usage/features`, { headers: { Authorization: `Bearer ${token}` } });
491603
+ if (!res.ok)
491604
+ return;
491605
+ const data = await res.json();
491606
+ if (data && typeof data === "object") {
491607
+ const next = {};
491608
+ for (const [k2, v2] of Object.entries(data)) {
491609
+ if (v2 && typeof v2 === "object") {
491610
+ const rawUsed = v2.used;
491611
+ const rawLimit = v2.limit;
491612
+ const used = typeof rawUsed === "number" && Number.isFinite(rawUsed) ? rawUsed : 0;
491613
+ const limit3 = typeof rawLimit === "number" && Number.isFinite(rawLimit) ? rawLimit : null;
491614
+ next[k2] = { used, limit: limit3 };
491615
+ }
491616
+ }
491617
+ cache6 = next;
491618
+ }
491619
+ } catch {} finally {
491620
+ fetching2 = false;
491621
+ }
491622
+ }
491623
+ function bumpFeatureUsage(featureKey) {
491624
+ if (!cache6)
491625
+ return;
491626
+ const cur = cache6[featureKey];
491627
+ if (cur)
491628
+ cache6[featureKey] = { ...cur, used: cur.used + 1 };
491629
+ }
491630
+ function clearFeatureUsage() {
491631
+ cache6 = null;
491632
+ lastAttempt2 = 0;
491633
+ }
491634
+ var REFRESH_COOLDOWN_MS2 = 60000, cache6 = null, fetching2 = false, lastAttempt2 = 0;
491635
+ var init_rayuFeatureUsage = __esm(() => {
491636
+ init_rayuSession();
491637
+ });
491638
+
491639
+ // src/services/rayuAuth/rayuPlansCatalog.ts
491640
+ function getEntryPaidPlan() {
491641
+ maybeRefreshPlansCatalog();
491642
+ if (!cache7)
491643
+ return null;
491644
+ let best = null;
491645
+ for (const p of cache7) {
491646
+ if (p.availability === "active" && p.priceCents > 0) {
491647
+ if (!best || p.priceCents < best.priceCents)
491648
+ best = p;
491649
+ }
491650
+ }
491651
+ return best;
491652
+ }
491653
+ function maybeRefreshPlansCatalog() {
491654
+ if (isUseRayuOAuthEnabled() && !fetching3 && Date.now() - lastAttempt3 > REFRESH_COOLDOWN_MS3) {
491655
+ refreshPlansCatalog();
491656
+ }
491657
+ }
491658
+ async function refreshPlansCatalog() {
491659
+ if (!isUseRayuOAuthEnabled() || fetching3)
491660
+ return;
491661
+ fetching3 = true;
491662
+ lastAttempt3 = Date.now();
491663
+ try {
491664
+ const res = await globalThis.fetch(`${getRayuApiBaseUrl()}/plans`);
491665
+ if (!res.ok)
491666
+ return;
491667
+ const data = await res.json();
491668
+ if (Array.isArray(data)) {
491669
+ cache7 = data.filter((p) => !!p && typeof p === "object" && typeof p.name === "string" && typeof p.priceCents === "number").map((p) => ({
491670
+ code: String(p.code),
491671
+ name: p.name,
491672
+ priceCents: p.priceCents,
491673
+ availability: String(p.availability)
491674
+ }));
491675
+ }
491676
+ } catch {} finally {
491677
+ fetching3 = false;
491678
+ }
491679
+ }
491680
+ var REFRESH_COOLDOWN_MS3 = 60000, cache7 = null, fetching3 = false, lastAttempt3 = 0;
491681
+ var init_rayuPlansCatalog = __esm(() => {
491682
+ init_rayuSession();
491683
+ });
491684
+
491685
+ // src/services/rayuAuth/paidFeatureGate.ts
491686
+ function isPaidFeatureLocked(featureKey) {
491687
+ return !rayuFeatureAllowed(featureKey);
491688
+ }
491689
+ function capitalize3(s2) {
491690
+ return s2.length ? s2[0].toUpperCase() + s2.slice(1) : s2;
491691
+ }
491692
+ function usd(cents) {
491693
+ return `$${(cents / 100).toFixed(cents % 100 === 0 ? 0 : 2)}`;
491694
+ }
491695
+ function upgradeTargetLabel() {
491696
+ const plan = getEntryPaidPlan();
491697
+ if (plan) {
491698
+ const price = plan.priceCents > 0 ? ` (${usd(plan.priceCents)}/mo)` : "";
491699
+ return `the ${plan.name} plan${price}`;
491700
+ }
491701
+ return "a paid plan";
491702
+ }
491703
+ function upgradePromptForUser(featureLabel) {
491704
+ return `${capitalize3(featureLabel)} is a paid feature. Please upgrade to ${upgradeTargetLabel()} to unlock it and all other premium features.`;
491705
+ }
491706
+ function paidFeatureUpgradeNote(featureLabel) {
491707
+ return `
491708
+
491709
+ ---
491710
+ > \uD83D\uDD12 **Paid feature — requires ${upgradeTargetLabel()}.**
491711
+ >
491712
+ > The signed-in user is on the **Free** plan, which does not include ${featureLabel}. This tool will refuse to run for them and return an error.
491713
+ >
491714
+ > If the user asks for ${featureLabel}, do **not** call this tool — it will fail. Instead, tell the user: "${upgradePromptForUser(featureLabel)}"
491715
+ >
491716
+ > Users on a paid plan get unlimited access to this tool.`;
491717
+ }
491718
+ function paidFeatureDescriptionSuffix() {
491719
+ return ` (Requires ${upgradeTargetLabel()}.)`;
491720
+ }
491721
+ function paidFeatureBlockedMessage(featureLabel) {
491722
+ return `\uD83D\uDD12 ${capitalize3(featureLabel)} requires ${upgradeTargetLabel()}. The signed-in user is on the Free plan, so this tool is locked. Tell the user: "${upgradePromptForUser(featureLabel)}" Do not retry this tool until they upgrade.`;
491723
+ }
491724
+ function featureLimitReached(featureKey) {
491725
+ if (!isUseRayuOAuthEnabled())
491726
+ return false;
491727
+ if (!rayuFeatureAllowed(featureKey))
491728
+ return false;
491729
+ const u4 = getFeatureUsage(featureKey);
491730
+ if (!u4 || u4.limit == null)
491731
+ return false;
491732
+ return u4.used >= u4.limit;
491733
+ }
491734
+ function usageSuffix(featureKey) {
491735
+ const u4 = getFeatureUsage(featureKey);
491736
+ if (!u4 || u4.limit == null)
491737
+ return "";
491738
+ return ` (${u4.used}/${u4.limit} used this month)`;
491739
+ }
491740
+ function featureLimitUpgradePrompt(featureLabel) {
491741
+ return `You've reached this month's ${featureLabel} limit. Upgrade to ${upgradeTargetLabel()} for unlimited ${featureLabel}, or wait until it resets next month.`;
491742
+ }
491743
+ function featureLimitReachedNote(featureKey, featureLabel) {
491744
+ return `
491745
+
491746
+ ---
491747
+ > \uD83D\uDD12 **Monthly ${featureLabel} limit reached${usageSuffix(featureKey)}.**
491748
+ >
491749
+ > The signed-in user has used their ${featureLabel} allowance for this month on their current plan. This tool will refuse to run until the limit resets next month (UTC) or they upgrade.
491750
+ >
491751
+ > If the user asks for ${featureLabel}, do **not** call this tool — it will fail. Instead, tell the user: "${featureLimitUpgradePrompt(featureLabel)}"`;
491752
+ }
491753
+ function featureLimitDescriptionSuffix(featureKey) {
491754
+ return ` (Monthly limit reached${usageSuffix(featureKey)} — upgrade for unlimited.)`;
491755
+ }
491756
+ function featureLimitReachedMessage(featureKey, featureLabel) {
491757
+ return `\uD83D\uDD12 Monthly ${featureLabel} limit reached${usageSuffix(featureKey)}. Tell the user: "${featureLimitUpgradePrompt(featureLabel)}" Do not retry this tool until the limit resets next month or they upgrade.`;
491758
+ }
491759
+ var init_paidFeatureGate = __esm(() => {
491760
+ init_rayuEntitlements();
491761
+ init_rayuFeatureUsage();
491762
+ init_rayuPlansCatalog();
491763
+ init_rayuSession();
491764
+ });
491765
+
491496
491766
  // src/tools/ImageGenTool/ImageGenTool.ts
491497
491767
  import { mkdir as mkdir21, readFile as readFile26, writeFile as writeFile19 } from "fs/promises";
491498
491768
  import { dirname as dirname43, isAbsolute as isAbsolute28, relative as relative20 } from "path";
@@ -491529,7 +491799,7 @@ function extForMedia(mediaType) {
491529
491799
  const ext = mediaType.split("/")[1] || "png";
491530
491800
  return ext === "jpeg" ? "jpg" : ext;
491531
491801
  }
491532
- var inputSchema21, outputSchema19, ImageGenTool;
491802
+ var IMAGE_GEN_FEATURE = "image_generation", IMAGE_GEN_LABEL = "image generation", inputSchema21, outputSchema19, ImageGenTool;
491533
491803
  var init_ImageGenTool = __esm(() => {
491534
491804
  init_v4();
491535
491805
  init_Tool();
@@ -491542,7 +491812,8 @@ var init_ImageGenTool = __esm(() => {
491542
491812
  init_vertexImageClient();
491543
491813
  init_prompt17();
491544
491814
  init_UI16();
491545
- init_rayuEntitlements();
491815
+ init_paidFeatureGate();
491816
+ init_rayuFeatureUsage();
491546
491817
  inputSchema21 = lazySchema(() => exports_external.strictObject({
491547
491818
  prompt: exports_external.string().min(1).describe("Text description of the image to generate, or the edit to make"),
491548
491819
  output_path: exports_external.string().optional().describe("Where to save the PNG (inside the working directory). Default: ./generated-image-<timestamp>.png"),
@@ -491575,7 +491846,7 @@ var init_ImageGenTool = __esm(() => {
491575
491846
  return outputSchema19();
491576
491847
  },
491577
491848
  isEnabled() {
491578
- return (getNvidiaApiKey() != null || isGeminiVertexImageAvailable()) && rayuFeatureAllowed("image_generation");
491849
+ return getNvidiaApiKey() != null || isGeminiVertexImageAvailable();
491579
491850
  },
491580
491851
  isReadOnly() {
491581
491852
  return false;
@@ -491587,6 +491858,12 @@ var init_ImageGenTool = __esm(() => {
491587
491858
  return `GenerateImage: ${input.prompt}`;
491588
491859
  },
491589
491860
  async description() {
491861
+ if (isPaidFeatureLocked(IMAGE_GEN_FEATURE)) {
491862
+ return DESCRIPTION13 + paidFeatureDescriptionSuffix();
491863
+ }
491864
+ if (featureLimitReached(IMAGE_GEN_FEATURE)) {
491865
+ return DESCRIPTION13 + featureLimitDescriptionSuffix(IMAGE_GEN_FEATURE);
491866
+ }
491590
491867
  return DESCRIPTION13;
491591
491868
  },
491592
491869
  userFacingName() {
@@ -491596,7 +491873,14 @@ var init_ImageGenTool = __esm(() => {
491596
491873
  return input?.prompt ? `Generating image: ${input.prompt}` : "Generating image";
491597
491874
  },
491598
491875
  async prompt() {
491599
- return getImageGenPrompt();
491876
+ const base2 = getImageGenPrompt();
491877
+ if (isPaidFeatureLocked(IMAGE_GEN_FEATURE)) {
491878
+ return base2 + paidFeatureUpgradeNote(IMAGE_GEN_LABEL);
491879
+ }
491880
+ if (featureLimitReached(IMAGE_GEN_FEATURE)) {
491881
+ return base2 + featureLimitReachedNote(IMAGE_GEN_FEATURE, IMAGE_GEN_LABEL);
491882
+ }
491883
+ return base2;
491600
491884
  },
491601
491885
  async validateInput(input) {
491602
491886
  const { ok } = resolveOutputPath(input.output_path);
@@ -491624,6 +491908,12 @@ var init_ImageGenTool = __esm(() => {
491624
491908
  };
491625
491909
  },
491626
491910
  async call(input, context) {
491911
+ if (isPaidFeatureLocked(IMAGE_GEN_FEATURE)) {
491912
+ throw new Error(paidFeatureBlockedMessage(IMAGE_GEN_LABEL));
491913
+ }
491914
+ if (featureLimitReached(IMAGE_GEN_FEATURE)) {
491915
+ throw new Error(featureLimitReachedMessage(IMAGE_GEN_FEATURE, IMAGE_GEN_LABEL));
491916
+ }
491627
491917
  if (input.output_path && !resolveOutputPath(input.output_path).ok) {
491628
491918
  throw new Error("output_path must be a file inside the working directory.");
491629
491919
  }
@@ -491685,6 +491975,7 @@ var init_ImageGenTool = __esm(() => {
491685
491975
  inlineMedia = `image/${r2.mediaType}`;
491686
491976
  } catch {}
491687
491977
  const dims = imageDimensions(buffer);
491978
+ bumpFeatureUsage(IMAGE_GEN_FEATURE);
491688
491979
  return {
491689
491980
  data: {
491690
491981
  path: path22,
@@ -492308,7 +492599,7 @@ function resolveOutputPath2(output_path) {
492308
492599
  const ok = rel.length > 0 && !rel.startsWith("..") && !isAbsolute29(rel);
492309
492600
  return { ok, path: path22 };
492310
492601
  }
492311
- var inputSchema22, outputSchema20, VideoGenTool;
492602
+ var VIDEO_GEN_FEATURE = "video_generation", VIDEO_GEN_LABEL = "video generation", inputSchema22, outputSchema20, VideoGenTool;
492312
492603
  var init_VideoGenTool = __esm(() => {
492313
492604
  init_v4();
492314
492605
  init_Tool();
@@ -492321,7 +492612,8 @@ var init_VideoGenTool = __esm(() => {
492321
492612
  init_vertexVideoClient();
492322
492613
  init_prompt18();
492323
492614
  init_UI17();
492324
- init_rayuEntitlements();
492615
+ init_paidFeatureGate();
492616
+ init_rayuFeatureUsage();
492325
492617
  inputSchema22 = lazySchema(() => exports_external.strictObject({
492326
492618
  prompt: exports_external.string().min(1).describe("Text description of the video to generate, or the motion to apply"),
492327
492619
  output_path: exports_external.string().optional().describe("Where to save the MP4 (inside the working directory). Default: ./generated-video-<timestamp>.mp4"),
@@ -492355,7 +492647,7 @@ var init_VideoGenTool = __esm(() => {
492355
492647
  return outputSchema20();
492356
492648
  },
492357
492649
  isEnabled() {
492358
- return (isVideoEnabled() || isGeminiVertexVideoAvailable()) && rayuFeatureAllowed("video_generation");
492650
+ return isVideoEnabled() || isGeminiVertexVideoAvailable();
492359
492651
  },
492360
492652
  isReadOnly() {
492361
492653
  return false;
@@ -492367,6 +492659,12 @@ var init_VideoGenTool = __esm(() => {
492367
492659
  return `GenerateVideo: ${input.prompt}`;
492368
492660
  },
492369
492661
  async description() {
492662
+ if (isPaidFeatureLocked(VIDEO_GEN_FEATURE)) {
492663
+ return DESCRIPTION14 + paidFeatureDescriptionSuffix();
492664
+ }
492665
+ if (featureLimitReached(VIDEO_GEN_FEATURE)) {
492666
+ return DESCRIPTION14 + featureLimitDescriptionSuffix(VIDEO_GEN_FEATURE);
492667
+ }
492370
492668
  return DESCRIPTION14;
492371
492669
  },
492372
492670
  userFacingName() {
@@ -492376,7 +492674,14 @@ var init_VideoGenTool = __esm(() => {
492376
492674
  return input?.prompt ? `Generating video (please wait ~1-2 min): ${input.prompt}` : "Generating video — please wait, this takes ~1-2 minutes";
492377
492675
  },
492378
492676
  async prompt() {
492379
- return getVideoGenPrompt();
492677
+ const base2 = getVideoGenPrompt();
492678
+ if (isPaidFeatureLocked(VIDEO_GEN_FEATURE)) {
492679
+ return base2 + paidFeatureUpgradeNote(VIDEO_GEN_LABEL);
492680
+ }
492681
+ if (featureLimitReached(VIDEO_GEN_FEATURE)) {
492682
+ return base2 + featureLimitReachedNote(VIDEO_GEN_FEATURE, VIDEO_GEN_LABEL);
492683
+ }
492684
+ return base2;
492380
492685
  },
492381
492686
  async validateInput(input) {
492382
492687
  const { ok } = resolveOutputPath2(input.output_path);
@@ -492404,6 +492709,12 @@ var init_VideoGenTool = __esm(() => {
492404
492709
  };
492405
492710
  },
492406
492711
  async call(input, context) {
492712
+ if (isPaidFeatureLocked(VIDEO_GEN_FEATURE)) {
492713
+ throw new Error(paidFeatureBlockedMessage(VIDEO_GEN_LABEL));
492714
+ }
492715
+ if (featureLimitReached(VIDEO_GEN_FEATURE)) {
492716
+ throw new Error(featureLimitReachedMessage(VIDEO_GEN_FEATURE, VIDEO_GEN_LABEL));
492717
+ }
492407
492718
  const { ok, path: path22 } = resolveOutputPath2(input.output_path);
492408
492719
  if (!ok) {
492409
492720
  throw new Error("output_path must be a file inside the working directory.");
@@ -492455,6 +492766,7 @@ var init_VideoGenTool = __esm(() => {
492455
492766
  await mkdir22(dirname44(path22), { recursive: true });
492456
492767
  await writeFile20(path22, buffer);
492457
492768
  const preview = await extractPreviewFrame(path22);
492769
+ bumpFeatureUsage(VIDEO_GEN_FEATURE);
492458
492770
  return {
492459
492771
  data: {
492460
492772
  path: path22,
@@ -507479,7 +507791,7 @@ async function* handleOrphanedPermission(orphanedPermission, tools, mutableMessa
507479
507791
  }
507480
507792
  }
507481
507793
  function extractReadFilesFromMessages(messages, cwd2, maxSize = ASK_READ_FILE_STATE_CACHE_SIZE) {
507482
- const cache6 = createFileStateCacheWithSizeLimit(maxSize);
507794
+ const cache8 = createFileStateCacheWithSizeLimit(maxSize);
507483
507795
  const fileReadToolUseIds = new Map;
507484
507796
  const fileWriteToolUseIds = new Map;
507485
507797
  const fileEditToolUseIds = new Map;
@@ -507523,7 +507835,7 @@ function extractReadFilesFromMessages(messages, cwd2, maxSize = ASK_READ_FILE_ST
507523
507835
  `).trim();
507524
507836
  if (message.timestamp) {
507525
507837
  const timestamp = new Date(message.timestamp).getTime();
507526
- cache6.set(readFilePath, {
507838
+ cache8.set(readFilePath, {
507527
507839
  content: fileContent,
507528
507840
  timestamp,
507529
507841
  offset: undefined,
@@ -507534,7 +507846,7 @@ function extractReadFilesFromMessages(messages, cwd2, maxSize = ASK_READ_FILE_ST
507534
507846
  const writeToolData = fileWriteToolUseIds.get(content.tool_use_id);
507535
507847
  if (writeToolData && message.timestamp) {
507536
507848
  const timestamp = new Date(message.timestamp).getTime();
507537
- cache6.set(writeToolData.filePath, {
507849
+ cache8.set(writeToolData.filePath, {
507538
507850
  content: writeToolData.content,
507539
507851
  timestamp,
507540
507852
  offset: undefined,
@@ -507545,7 +507857,7 @@ function extractReadFilesFromMessages(messages, cwd2, maxSize = ASK_READ_FILE_ST
507545
507857
  if (editFilePath && content.is_error !== true) {
507546
507858
  try {
507547
507859
  const { content: diskContent } = readFileSyncWithMetadata(editFilePath);
507548
- cache6.set(editFilePath, {
507860
+ cache8.set(editFilePath, {
507549
507861
  content: diskContent,
507550
507862
  timestamp: getFileModificationTime(editFilePath),
507551
507863
  offset: undefined,
@@ -507561,7 +507873,7 @@ function extractReadFilesFromMessages(messages, cwd2, maxSize = ASK_READ_FILE_ST
507561
507873
  }
507562
507874
  }
507563
507875
  }
507564
- return cache6;
507876
+ return cache8;
507565
507877
  }
507566
507878
  function extractBashToolsFromMessages(messages) {
507567
507879
  const tools = new Set;
@@ -512254,7 +512566,7 @@ ${m3.content}`,
512254
512566
  }
512255
512567
  return wrapMessagesInSystemReminder([
512256
512568
  createUserMessage({
512257
- content: `The following skills are available for use with the Skill tool:
512569
+ content: `The following skills are available via the Skill tool. Before you start the user's task, you MUST first scan this list and decide whether any skill matches what is being asked. A skill is a pre-built, validated procedure for that kind of task — if one clearly matches, invoke it with the Skill tool BEFORE doing any work or writing any other response, and follow the skill's procedure instead of improvising your own. Pick the single most relevant skill (if several could apply, choose the most specific). Only skip this when no listed skill genuinely fits the task — do not force a skill that does not match, and do not claim to use a skill without actually calling the tool.
512258
512570
 
512259
512571
  ${attachment.content}`,
512260
512572
  isMeta: true
@@ -522478,6 +522790,7 @@ function getSessionSpecificGuidanceSection(enabledTools, skillToolCommands) {
522478
522790
  `For simple, directed codebase searches (e.g. for a specific file/class/function) use ${searchTools} directly.`,
522479
522791
  `For broader codebase exploration and deep research, use the ${AGENT_TOOL_NAME} tool with subagent_type=${EXPLORE_AGENT.agentType}. This is slower than using ${searchTools} directly, so use this only when a simple, directed search proves to be insufficient or when your task will clearly require more than ${EXPLORE_AGENT_MIN_QUERIES} queries.`
522480
522792
  ] : [],
522793
+ hasSkills ? `Skills are pre-built, validated procedures for specific tasks. At the START of every task, FIRST review the available skills (listed via the ${SKILL_TOOL_NAME} tool and in system-reminder messages) and decide whether one matches the user's request. If a skill clearly matches, invoke it with the ${SKILL_TOOL_NAME} tool BEFORE doing the work and follow its procedure rather than improvising — prefer a matching skill over an ad-hoc approach. Choose the single most relevant skill; if none clearly fits, proceed normally without forcing one.` : null,
522481
522794
  hasSkills ? `/<skill-name> (e.g., /commit) is shorthand for users to invoke a user-invocable skill. When executed, the skill gets expanded to a full prompt. Use the ${SKILL_TOOL_NAME} tool to execute them. IMPORTANT: Only use ${SKILL_TOOL_NAME} for skills listed in its user-invocable skills section - do not guess or use built-in CLI commands.` : null,
522482
522795
  DISCOVER_SKILLS_TOOL_NAME !== null && hasSkills && enabledTools.has(DISCOVER_SKILLS_TOOL_NAME) ? getDiscoverSkillsGuidance() : null,
522483
522796
  null
@@ -522785,8 +523098,8 @@ function filterSwarmFieldsFromSchema(toolName2, schema) {
522785
523098
  }
522786
523099
  async function toolToAPISchema(tool, options) {
522787
523100
  const cacheKey = "inputJSONSchema" in tool && tool.inputJSONSchema ? `${tool.name}:${jsonStringify(tool.inputJSONSchema)}` : tool.name;
522788
- const cache6 = getToolSchemaCache();
522789
- let base2 = cache6.get(cacheKey);
523101
+ const cache8 = getToolSchemaCache();
523102
+ let base2 = cache8.get(cacheKey);
522790
523103
  if (!base2) {
522791
523104
  const strictToolsEnabled = checkStatsigFeatureGate_CACHED_MAY_BE_STALE("tengu_tool_pear");
522792
523105
  let input_schema = "inputJSONSchema" in tool && tool.inputJSONSchema ? tool.inputJSONSchema : zodToJsonSchema(tool.inputSchema);
@@ -522809,7 +523122,7 @@ async function toolToAPISchema(tool, options) {
522809
523122
  if (getAPIProvider() === "anthropic" && !isOpenAICompatibleActive() && isFirstPartyAnthropicBaseUrl() && (getFeatureValue_CACHED_MAY_BE_STALE("tengu_fgts", false) || isEnvTruthy(process.env.CLAUDE_CODE_ENABLE_FINE_GRAINED_TOOL_STREAMING))) {
522810
523123
  base2.eager_input_streaming = true;
522811
523124
  }
522812
- cache6.set(cacheKey, base2);
523125
+ cache8.set(cacheKey, base2);
522813
523126
  }
522814
523127
  const schema = {
522815
523128
  name: base2.name,
@@ -529926,13 +530239,14 @@ class HighlightSegmenter {
529926
530239
  this.stringPos += token.code.length;
529927
530240
  this.tokenIdx++;
529928
530241
  } else {
530242
+ const charValue = token.value;
529929
530243
  const charsNeeded = targetVisiblePos - this.visiblePos;
529930
- const charsAvailable = token.value.length - this.charIdx;
530244
+ const charsAvailable = charValue.length - this.charIdx;
529931
530245
  const charsToTake = Math.min(charsNeeded, charsAvailable);
529932
530246
  this.stringPos += charsToTake;
529933
530247
  this.visiblePos += charsToTake;
529934
530248
  this.charIdx += charsToTake;
529935
- if (this.charIdx >= token.value.length) {
530249
+ if (this.charIdx >= charValue.length) {
529936
530250
  this.tokenIdx++;
529937
530251
  this.charIdx = 0;
529938
530252
  }
@@ -532043,7 +532357,7 @@ function Feedback({
532043
532357
  platform: env4.platform,
532044
532358
  gitRepo: envInfo.isGit,
532045
532359
  terminal: env4.terminal,
532046
- version: "1.3.439",
532360
+ version: "1.3.441",
532047
532361
  transcript: normalizeMessagesForAPI(messages),
532048
532362
  errors: sanitizedErrors,
532049
532363
  lastApiRequest: getLastAPIRequest(),
@@ -532235,7 +532549,7 @@ function Feedback({
532235
532549
  ", ",
532236
532550
  env4.terminal,
532237
532551
  ", v",
532238
- "1.3.439"
532552
+ "1.3.441"
532239
532553
  ]
532240
532554
  }, undefined, true, undefined, this)
532241
532555
  ]
@@ -532341,7 +532655,7 @@ ${sanitizedDescription}
532341
532655
  ` + `**Environment Info**
532342
532656
  ` + `- Platform: ${env4.platform}
532343
532657
  ` + `- Terminal: ${env4.terminal}
532344
- ` + `- Version: ${"1.3.439"}
532658
+ ` + `- Version: ${"1.3.441"}
532345
532659
  ` + `- Feedback ID: ${feedbackId}
532346
532660
  ` + `
532347
532661
  **Errors**
@@ -535181,9 +535495,9 @@ async function assertMinVersion() {
535181
535495
  if (false) {}
535182
535496
  try {
535183
535497
  const versionConfig = await getDynamicConfig_BLOCKS_ON_INIT("tengu_version_config", { minVersion: "0.0.0" });
535184
- if (versionConfig.minVersion && lt("1.3.439", versionConfig.minVersion)) {
535498
+ if (versionConfig.minVersion && lt("1.3.441", versionConfig.minVersion)) {
535185
535499
  console.error(`
535186
- It looks like your version of RAYU (${"1.3.439"}) needs an update.
535500
+ It looks like your version of RAYU (${"1.3.441"}) needs an update.
535187
535501
  A newer version (${versionConfig.minVersion} or higher) is required to continue.
535188
535502
 
535189
535503
  To update, please run:
@@ -535409,7 +535723,7 @@ async function installGlobalPackage(specificVersion) {
535409
535723
  logError2(new AutoUpdaterError("Another process is currently installing an update"));
535410
535724
  logEvent("tengu_auto_updater_lock_contention", {
535411
535725
  pid: process.pid,
535412
- currentVersion: "1.3.439"
535726
+ currentVersion: "1.3.441"
535413
535727
  });
535414
535728
  return "in_progress";
535415
535729
  }
@@ -535418,7 +535732,7 @@ async function installGlobalPackage(specificVersion) {
535418
535732
  if (!env4.isRunningWithBun() && env4.isNpmFromWindowsPath()) {
535419
535733
  logError2(new Error("Windows NPM detected in WSL environment"));
535420
535734
  logEvent("tengu_auto_updater_windows_npm_in_wsl", {
535421
- currentVersion: "1.3.439"
535735
+ currentVersion: "1.3.441"
535422
535736
  });
535423
535737
  console.error(`
535424
535738
  Error: Windows NPM detected in WSL
@@ -535954,7 +536268,7 @@ function detectLinuxGlobPatternWarnings() {
535954
536268
  }
535955
536269
  async function getDoctorDiagnostic() {
535956
536270
  const installationType = await getCurrentInstallationType();
535957
- const version2 = typeof MACRO !== "undefined" ? "1.3.439" : "unknown";
536271
+ const version2 = typeof MACRO !== "undefined" ? "1.3.441" : "unknown";
535958
536272
  const installationPath = await getInstallationPath();
535959
536273
  const invokedBinary = getInvokedBinary();
535960
536274
  const multipleInstallations = await detectMultipleInstallations();
@@ -536749,8 +537063,8 @@ async function updateLatest(channelOrVersion, forceReinstall = false) {
536749
537063
  const maxVersion = await getMaxVersion();
536750
537064
  if (maxVersion && gt(version2, maxVersion)) {
536751
537065
  logForDebugging(`Native installer: maxVersion ${maxVersion} is set, capping update from ${version2} to ${maxVersion}`);
536752
- if (gte("1.3.439", maxVersion)) {
536753
- logForDebugging(`Native installer: current version ${"1.3.439"} is already at or above maxVersion ${maxVersion}, skipping update`);
537066
+ if (gte("1.3.441", maxVersion)) {
537067
+ logForDebugging(`Native installer: current version ${"1.3.441"} is already at or above maxVersion ${maxVersion}, skipping update`);
536754
537068
  logEvent("tengu_native_update_skipped_max_version", {
536755
537069
  latency_ms: Date.now() - startTime,
536756
537070
  max_version: maxVersion,
@@ -536761,7 +537075,7 @@ async function updateLatest(channelOrVersion, forceReinstall = false) {
536761
537075
  version2 = maxVersion;
536762
537076
  }
536763
537077
  }
536764
- if (!forceReinstall && version2 === "1.3.439" && await versionIsAvailable(version2) && await isPossibleClaudeBinary(executablePath)) {
537078
+ if (!forceReinstall && version2 === "1.3.441" && await versionIsAvailable(version2) && await isPossibleClaudeBinary(executablePath)) {
536765
537079
  logForDebugging(`Found ${version2} at ${executablePath}, skipping install`);
536766
537080
  logEvent("tengu_native_update_complete", {
536767
537081
  latency_ms: Date.now() - startTime,
@@ -537957,7 +538271,7 @@ function buildPrimarySection() {
537957
538271
  }, undefined, false, undefined, this);
537958
538272
  return [{
537959
538273
  label: "Version",
537960
- value: "1.3.439"
538274
+ value: "1.3.441"
537961
538275
  }, {
537962
538276
  label: "Session name",
537963
538277
  value: nameValue
@@ -541648,7 +541962,7 @@ function Config({
541648
541962
  }
541649
541963
  }, undefined, false, undefined, this)
541650
541964
  }, undefined, false, undefined, this) : showSubmenu === "ChannelDowngrade" ? /* @__PURE__ */ jsx_dev_runtime170.jsxDEV(ChannelDowngradeDialog, {
541651
- currentVersion: "1.3.439",
541965
+ currentVersion: "1.3.441",
541652
541966
  onChoice: (choice) => {
541653
541967
  setShowSubmenu(null);
541654
541968
  setTabsHidden(false);
@@ -541660,7 +541974,7 @@ function Config({
541660
541974
  autoUpdatesChannel: "stable"
541661
541975
  };
541662
541976
  if (choice === "stay") {
541663
- newSettings.minimumVersion = "1.3.439";
541977
+ newSettings.minimumVersion = "1.3.441";
541664
541978
  }
541665
541979
  updateSettingsForSource("userSettings", newSettings);
541666
541980
  setSettingsData((prev_27) => ({
@@ -544487,14 +544801,14 @@ function computeTurnStats(turn) {
544487
544801
  };
544488
544802
  }
544489
544803
  function useTurnDiffs(messages) {
544490
- const cache6 = import_react108.useRef({
544804
+ const cache8 = import_react108.useRef({
544491
544805
  completedTurns: [],
544492
544806
  currentTurn: null,
544493
544807
  lastProcessedIndex: 0,
544494
544808
  lastTurnIndex: 0
544495
544809
  });
544496
544810
  return import_react108.useMemo(() => {
544497
- const c4 = cache6.current;
544811
+ const c4 = cache8.current;
544498
544812
  if (messages.length < c4.lastProcessedIndex) {
544499
544813
  c4.completedTurns = [];
544500
544814
  c4.currentTurn = null;
@@ -549722,7 +550036,7 @@ function HelpV2(t0) {
549722
550036
  let t6;
549723
550037
  if ($3[31] !== tabs) {
549724
550038
  t6 = /* @__PURE__ */ jsx_dev_runtime197.jsxDEV(Tabs, {
549725
- title: `Rayu-CLI v${"1.3.439"}`,
550039
+ title: `Rayu-CLI v${"1.3.441"}`,
549726
550040
  color: "professionalBlue",
549727
550041
  defaultTab: "general",
549728
550042
  children: tabs
@@ -555644,21 +555958,21 @@ async function loadInstallCountsCache() {
555644
555958
  logForDebugging("Install counts cache has invalid structure");
555645
555959
  return null;
555646
555960
  }
555647
- const cache6 = parsed;
555648
- if (cache6.version !== INSTALL_COUNTS_CACHE_VERSION) {
555649
- logForDebugging(`Install counts cache version mismatch (got ${cache6.version}, expected ${INSTALL_COUNTS_CACHE_VERSION})`);
555961
+ const cache8 = parsed;
555962
+ if (cache8.version !== INSTALL_COUNTS_CACHE_VERSION) {
555963
+ logForDebugging(`Install counts cache version mismatch (got ${cache8.version}, expected ${INSTALL_COUNTS_CACHE_VERSION})`);
555650
555964
  return null;
555651
555965
  }
555652
- if (typeof cache6.fetchedAt !== "string" || !Array.isArray(cache6.counts)) {
555966
+ if (typeof cache8.fetchedAt !== "string" || !Array.isArray(cache8.counts)) {
555653
555967
  logForDebugging("Install counts cache has invalid structure");
555654
555968
  return null;
555655
555969
  }
555656
- const fetchedAt = new Date(cache6.fetchedAt).getTime();
555970
+ const fetchedAt = new Date(cache8.fetchedAt).getTime();
555657
555971
  if (Number.isNaN(fetchedAt)) {
555658
555972
  logForDebugging("Install counts cache has invalid fetchedAt timestamp");
555659
555973
  return null;
555660
555974
  }
555661
- const validCounts = cache6.counts.every((entry) => typeof entry === "object" && entry !== null && typeof entry.plugin === "string" && typeof entry.unique_installs === "number");
555975
+ const validCounts = cache8.counts.every((entry) => typeof entry === "object" && entry !== null && typeof entry.plugin === "string" && typeof entry.unique_installs === "number");
555662
555976
  if (!validCounts) {
555663
555977
  logForDebugging("Install counts cache has malformed entries");
555664
555978
  return null;
@@ -555669,9 +555983,9 @@ async function loadInstallCountsCache() {
555669
555983
  return null;
555670
555984
  }
555671
555985
  return {
555672
- version: cache6.version,
555673
- fetchedAt: cache6.fetchedAt,
555674
- counts: cache6.counts
555986
+ version: cache8.version,
555987
+ fetchedAt: cache8.fetchedAt,
555988
+ counts: cache8.counts
555675
555989
  };
555676
555990
  } catch (error54) {
555677
555991
  const code = getErrnoCode(error54);
@@ -555681,13 +555995,13 @@ async function loadInstallCountsCache() {
555681
555995
  return null;
555682
555996
  }
555683
555997
  }
555684
- async function saveInstallCountsCache(cache6) {
555998
+ async function saveInstallCountsCache(cache8) {
555685
555999
  const cachePath = getInstallCountsCachePath();
555686
556000
  const tempPath = `${cachePath}.${randomBytes15(8).toString("hex")}.tmp`;
555687
556001
  try {
555688
556002
  const pluginsDir = getPluginsDirectory();
555689
556003
  await getFsImplementation().mkdir(pluginsDir);
555690
- const content = jsonStringify(cache6, null, 2);
556004
+ const content = jsonStringify(cache8, null, 2);
555691
556005
  await writeFile38(tempPath, content, {
555692
556006
  encoding: "utf-8",
555693
556007
  mode: 384
@@ -555719,12 +556033,12 @@ async function fetchInstallCountsFromGitHub() {
555719
556033
  }
555720
556034
  }
555721
556035
  async function getInstallCounts() {
555722
- const cache6 = await loadInstallCountsCache();
555723
- if (cache6) {
556036
+ const cache8 = await loadInstallCountsCache();
556037
+ if (cache8) {
555724
556038
  logForDebugging("Using cached install counts");
555725
556039
  logPluginFetch("install_counts", INSTALL_COUNTS_URL, "cache_hit", 0);
555726
556040
  const map4 = new Map;
555727
- for (const entry of cache6.counts) {
556041
+ for (const entry of cache8.counts) {
555728
556042
  map4.set(entry.plugin, entry.unique_installs);
555729
556043
  }
555730
556044
  return map4;
@@ -560137,7 +560451,7 @@ async function writeToDisk(plugins) {
560137
560451
  mode: 384
560138
560452
  });
560139
560453
  await rename11(tempPath, filePath);
560140
- cache6 = plugins;
560454
+ cache8 = plugins;
560141
560455
  } catch (error54) {
560142
560456
  logError2(error54);
560143
560457
  try {
@@ -560155,20 +560469,20 @@ async function loadFlaggedPlugins() {
560155
560469
  changed = true;
560156
560470
  }
560157
560471
  }
560158
- cache6 = all4;
560472
+ cache8 = all4;
560159
560473
  if (changed) {
560160
560474
  await writeToDisk(all4);
560161
560475
  }
560162
560476
  }
560163
560477
  function getFlaggedPlugins() {
560164
- return cache6 ?? {};
560478
+ return cache8 ?? {};
560165
560479
  }
560166
560480
  async function addFlaggedPlugin(pluginId) {
560167
- if (cache6 === null) {
560168
- cache6 = await readFromDisk();
560481
+ if (cache8 === null) {
560482
+ cache8 = await readFromDisk();
560169
560483
  }
560170
560484
  const updated = {
560171
- ...cache6,
560485
+ ...cache8,
560172
560486
  [pluginId]: {
560173
560487
  flaggedAt: new Date().toISOString()
560174
560488
  }
@@ -560177,12 +560491,12 @@ async function addFlaggedPlugin(pluginId) {
560177
560491
  logForDebugging(`Flagged plugin: ${pluginId}`);
560178
560492
  }
560179
560493
  async function markFlaggedPluginsSeen(pluginIds) {
560180
- if (cache6 === null) {
560181
- cache6 = await readFromDisk();
560494
+ if (cache8 === null) {
560495
+ cache8 = await readFromDisk();
560182
560496
  }
560183
560497
  const now2 = new Date().toISOString();
560184
560498
  let changed = false;
560185
- const updated = { ...cache6 };
560499
+ const updated = { ...cache8 };
560186
560500
  for (const id of pluginIds) {
560187
560501
  const entry = updated[id];
560188
560502
  if (entry && !entry.seenAt) {
@@ -560195,16 +560509,16 @@ async function markFlaggedPluginsSeen(pluginIds) {
560195
560509
  }
560196
560510
  }
560197
560511
  async function removeFlaggedPlugin(pluginId) {
560198
- if (cache6 === null) {
560199
- cache6 = await readFromDisk();
560512
+ if (cache8 === null) {
560513
+ cache8 = await readFromDisk();
560200
560514
  }
560201
- if (!(pluginId in cache6))
560515
+ if (!(pluginId in cache8))
560202
560516
  return;
560203
- const { [pluginId]: _2, ...rest } = cache6;
560204
- cache6 = rest;
560517
+ const { [pluginId]: _2, ...rest } = cache8;
560518
+ cache8 = rest;
560205
560519
  await writeToDisk(rest);
560206
560520
  }
560207
- var FLAGGED_PLUGINS_FILENAME = "flagged-plugins.json", SEEN_EXPIRY_MS, cache6 = null;
560521
+ var FLAGGED_PLUGINS_FILENAME = "flagged-plugins.json", SEEN_EXPIRY_MS, cache8 = null;
560208
560522
  var init_pluginFlagging = __esm(() => {
560209
560523
  init_debug();
560210
560524
  init_fsOperations();
@@ -569809,7 +570123,7 @@ function getRecentReleaseNotes(currentVersion, previousVersion, changelogContent
569809
570123
  }
569810
570124
  return [];
569811
570125
  }
569812
- async function checkForReleaseNotes(lastSeenVersion, currentVersion = "1.3.439") {
570126
+ async function checkForReleaseNotes(lastSeenVersion, currentVersion = "1.3.441") {
569813
570127
  if (false) {}
569814
570128
  const cachedChangelog = await getStoredChangelog();
569815
570129
  if (lastSeenVersion !== currentVersion || !cachedChangelog) {
@@ -569822,7 +570136,7 @@ async function checkForReleaseNotes(lastSeenVersion, currentVersion = "1.3.439")
569822
570136
  releaseNotes
569823
570137
  };
569824
570138
  }
569825
- function checkForReleaseNotesSync(lastSeenVersion, currentVersion = "1.3.439") {
570139
+ function checkForReleaseNotesSync(lastSeenVersion, currentVersion = "1.3.441") {
569826
570140
  if (false) {}
569827
570141
  const releaseNotes = getRecentReleaseNotes(currentVersion, lastSeenVersion);
569828
570142
  return {
@@ -569950,7 +570264,7 @@ function getRecentActivitySync() {
569950
570264
  return cachedActivity;
569951
570265
  }
569952
570266
  function getLogoDisplayData() {
569953
- const version2 = process.env.DEMO_VERSION ?? "1.3.439";
570267
+ const version2 = process.env.DEMO_VERSION ?? "1.3.441";
569954
570268
  const serverUrl = getDirectConnectServerUrl();
569955
570269
  const displayPath = process.env.DEMO_VERSION ? "/code/claude" : getDisplayPath(getCwd());
569956
570270
  const cwd2 = serverUrl ? `${displayPath} in ${serverUrl.replace(/^https?:\/\//, "")}` : displayPath;
@@ -571197,7 +571511,7 @@ function LogoV2() {
571197
571511
  if ($3[2] === Symbol.for("react.memo_cache_sentinel")) {
571198
571512
  t2 = () => {
571199
571513
  const currentConfig = getGlobalConfig();
571200
- if (currentConfig.lastReleaseNotesSeen === "1.3.439") {
571514
+ if (currentConfig.lastReleaseNotesSeen === "1.3.441") {
571201
571515
  return;
571202
571516
  }
571203
571517
  saveGlobalConfig(_temp327);
@@ -571675,7 +571989,7 @@ function LogoV2() {
571675
571989
  t24 = $3[61];
571676
571990
  }
571677
571991
  const _latestNpm = getCachedLatestNpmVersionSync();
571678
- const _updateFeeds = _latestNpm && gt(_latestNpm, "1.3.439") ? [createUpdateAvailableFeed("1.3.439", _latestNpm)] : [];
571992
+ const _updateFeeds = _latestNpm && gt(_latestNpm, "1.3.441") ? [createUpdateAvailableFeed("1.3.441", _latestNpm)] : [];
571679
571993
  const t25 = layoutMode === "horizontal" && /* @__PURE__ */ jsx_dev_runtime239.jsxDEV(FeedColumn, {
571680
571994
  feeds: showOnboarding ? [createProjectOnboardingFeed(getSteps()), createRecentActivityFeed(activities)] : showGuestPassesUpsell ? [createRecentActivityFeed(activities), createGuestPassesFeed()] : showOverageCreditUpsell ? [createRecentActivityFeed(activities), createOverageCreditFeed()] : [createRecentActivityFeed(activities), ..._updateFeeds, createWhatsNewFeed(changelog)],
571681
571995
  maxWidth: rightWidth
@@ -571875,12 +572189,12 @@ function LogoV2() {
571875
572189
  return t41;
571876
572190
  }
571877
572191
  function _temp327(current) {
571878
- if (current.lastReleaseNotesSeen === "1.3.439") {
572192
+ if (current.lastReleaseNotesSeen === "1.3.441") {
571879
572193
  return current;
571880
572194
  }
571881
572195
  return {
571882
572196
  ...current,
571883
- lastReleaseNotesSeen: "1.3.439"
572197
+ lastReleaseNotesSeen: "1.3.441"
571884
572198
  };
571885
572199
  }
571886
572200
  function _temp241(s_0) {
@@ -574489,6 +574803,7 @@ function shouldRenderStatically(message, streamingToolUseIDs, inProgressToolUseI
574489
574803
  return false;
574490
574804
  }
574491
574805
  }
574806
+ return false;
574492
574807
  }
574493
574808
  var import_compiler_runtime186, React76, import_react148, jsx_dev_runtime248, LogoHeader, proactiveModule2 = null, BRIEF_TOOL_NAME4 = null, SEND_USER_FILE_TOOL_NAME2 = null, MAX_MESSAGES_TO_SHOW_IN_TRANSCRIPT_MODE = 30, MAX_MESSAGES_WITHOUT_VIRTUALIZATION = 200, MESSAGE_CAP_STEP = 50, MessagesImpl = ({
574494
574809
  messages,
@@ -574789,10 +575104,11 @@ var import_compiler_runtime186, React76, import_react148, jsx_dev_runtime248, Lo
574789
575104
  thinking: streamingThinking.thinking
574790
575105
  },
574791
575106
  addMargin: false,
574792
- isTranscriptMode: true,
575107
+ isTranscriptMode,
574793
575108
  verbose,
574794
575109
  hideInTranscript: false,
574795
- isThinking: streamingThinking.isStreaming
575110
+ isThinking: streamingThinking.isStreaming,
575111
+ liveStreamingPreview: true
574796
575112
  }, undefined, false, undefined, this)
574797
575113
  }, undefined, false, undefined, this),
574798
575114
  streamingText && !isBriefOnly && /* @__PURE__ */ jsx_dev_runtime248.jsxDEV(ThemedBox_default, {
@@ -596787,7 +597103,7 @@ async function captureMemoryDiagnostics(trigger, dumpNumber = 0) {
596787
597103
  smapsRollup,
596788
597104
  platform: process.platform,
596789
597105
  nodeVersion: process.version,
596790
- ccVersion: "1.3.439"
597106
+ ccVersion: "1.3.441"
596791
597107
  };
596792
597108
  }
596793
597109
  async function performHeapDump(trigger = "manual", dumpNumber = 0) {
@@ -597309,7 +597625,7 @@ var init_bridge_kick = __esm(() => {
597309
597625
  var call49 = async () => {
597310
597626
  return {
597311
597627
  type: "text",
597312
- value: "1.3.439"
597628
+ value: "1.3.441"
597313
597629
  };
597314
597630
  }, version2, version_default;
597315
597631
  var init_version = __esm(() => {
@@ -598766,10 +599082,12 @@ async function call53() {
598766
599082
  }
598767
599083
  clearRayuSession();
598768
599084
  clearRayuEntitlements();
599085
+ clearFeatureUsage();
598769
599086
  return { type: "text", value: "Signed out of Rayu." };
598770
599087
  }
598771
599088
  var init_logout = __esm(() => {
598772
599089
  init_rayuEntitlements();
599090
+ init_rayuFeatureUsage();
598773
599091
  init_rayuSession();
598774
599092
  });
598775
599093
 
@@ -598814,12 +599132,12 @@ function fmtReset(seconds) {
598814
599132
  return `${h3}h ${m3}m`;
598815
599133
  return `${m3}m`;
598816
599134
  }
598817
- function usd(cents) {
599135
+ function usd2(cents) {
598818
599136
  return `$${(cents / 100).toFixed(cents % 100 === 0 ? 0 : 2)}`;
598819
599137
  }
598820
599138
  function formatRayuUsageSummary(c4) {
598821
599139
  const lines2 = [];
598822
- const price = c4.priceCents > 0 ? ` (${usd(c4.priceCents)}/mo)` : "";
599140
+ const price = c4.priceCents > 0 ? ` (${usd2(c4.priceCents)}/mo)` : "";
598823
599141
  lines2.push(`Plan: ${c4.planName || c4.plan}${price}`);
598824
599142
  if (c4.periodEnd) {
598825
599143
  lines2.push(`Renews: ${new Date(c4.periodEnd).toLocaleDateString()}`);
@@ -598836,6 +599154,11 @@ function formatRayuUsageSummary(c4) {
598836
599154
  if (c4.topUpEnabled) {
598837
599155
  lines2.push(`Top-up balance: ${c4.topupBalance.toLocaleString()} credits`);
598838
599156
  }
599157
+ if (c4.maxDailyTurns != null && c4.maxDailyTurns > 0) {
599158
+ const used = c4.turnsUsedToday ?? 0;
599159
+ const left = c4.turnsRemaining ?? Math.max(0, c4.maxDailyTurns - used);
599160
+ lines2.push(`Daily turns: ${used.toLocaleString()} / ${c4.maxDailyTurns.toLocaleString()} used · ${left.toLocaleString()} left (resets in ${fmtReset(c4.turnsResetSeconds ?? 0)})`);
599161
+ }
598839
599162
  return lines2.join(`
598840
599163
  `);
598841
599164
  }
@@ -601554,11 +601877,18 @@ function InstallSkillFlow({
601554
601877
  let cancelled = false;
601555
601878
  (async () => {
601556
601879
  try {
601557
- const skill = await installSkillFromSource(source, { overwrite });
601880
+ const skills3 = await installSkillFromSource(source, { overwrite });
601558
601881
  if (cancelled)
601559
601882
  return;
601560
- setState({ status: "done", skill });
601561
- onDone(`Installed skill "${skill.name}" ${skill.path}`);
601883
+ setState({ status: "done", skills: skills3 });
601884
+ const replaced = skills3.filter((s2) => s2.replaced).map((s2) => s2.name);
601885
+ const fresh = skills3.filter((s2) => !s2.replaced).map((s2) => s2.name);
601886
+ const parts = [];
601887
+ if (fresh.length)
601888
+ parts.push(`installed ${fresh.join(", ")}`);
601889
+ if (replaced.length)
601890
+ parts.push(`overwrote already-installed ${replaced.join(", ")}`);
601891
+ onDone(`Skill install complete — ${parts.join("; ")}.`);
601562
601892
  } catch (e2) {
601563
601893
  if (cancelled)
601564
601894
  return;
@@ -601601,39 +601931,54 @@ function InstallSkillFlow({
601601
601931
  }, undefined, true, undefined, this)
601602
601932
  }, undefined, false, undefined, this);
601603
601933
  }
601934
+ const { skills: skills2 } = state;
601935
+ const replacedCount = skills2.filter((s2) => s2.replaced).length;
601604
601936
  return /* @__PURE__ */ jsx_dev_runtime329.jsxDEV(ThemedBox_default, {
601605
601937
  flexDirection: "column",
601606
601938
  paddingLeft: 1,
601607
601939
  children: [
601608
601940
  /* @__PURE__ */ jsx_dev_runtime329.jsxDEV(ThemedText, {
601609
601941
  color: "green",
601610
- children: "Installed skill: "
601611
- }, undefined, false, undefined, this),
601612
- /* @__PURE__ */ jsx_dev_runtime329.jsxDEV(ThemedText, {
601613
- bold: true,
601614
601942
  children: [
601615
- "/",
601616
- state.skill.name
601943
+ "Installed ",
601944
+ skills2.length,
601945
+ " skill",
601946
+ skills2.length === 1 ? "" : "s",
601947
+ replacedCount > 0 ? ` (${replacedCount} already existed and ${replacedCount === 1 ? "was" : "were"} overwritten)` : "",
601948
+ ":"
601617
601949
  ]
601618
601950
  }, undefined, true, undefined, this),
601619
- /* @__PURE__ */ jsx_dev_runtime329.jsxDEV(ThemedText, {
601620
- dimColor: true,
601621
- children: state.skill.description
601622
- }, undefined, false, undefined, this),
601623
- /* @__PURE__ */ jsx_dev_runtime329.jsxDEV(ThemedText, {
601624
- dimColor: true,
601951
+ skills2.map((s2) => /* @__PURE__ */ jsx_dev_runtime329.jsxDEV(ThemedBox_default, {
601952
+ flexDirection: "column",
601953
+ marginTop: 1,
601625
601954
  children: [
601626
- "Location: ",
601627
- state.skill.path
601955
+ /* @__PURE__ */ jsx_dev_runtime329.jsxDEV(ThemedText, {
601956
+ bold: true,
601957
+ children: [
601958
+ "/",
601959
+ s2.name,
601960
+ s2.replaced ? /* @__PURE__ */ jsx_dev_runtime329.jsxDEV(ThemedText, {
601961
+ color: "yellow",
601962
+ children: " (overwritten)"
601963
+ }, undefined, false, undefined, this) : null
601964
+ ]
601965
+ }, undefined, true, undefined, this),
601966
+ s2.description ? /* @__PURE__ */ jsx_dev_runtime329.jsxDEV(ThemedText, {
601967
+ dimColor: true,
601968
+ children: s2.description
601969
+ }, undefined, false, undefined, this) : null,
601970
+ /* @__PURE__ */ jsx_dev_runtime329.jsxDEV(ThemedText, {
601971
+ dimColor: true,
601972
+ children: [
601973
+ "Location: ",
601974
+ s2.path
601975
+ ]
601976
+ }, undefined, true, undefined, this)
601628
601977
  ]
601629
- }, undefined, true, undefined, this),
601978
+ }, s2.name, true, undefined, this)),
601630
601979
  /* @__PURE__ */ jsx_dev_runtime329.jsxDEV(ThemedText, {
601631
- children: [
601632
- "It is available now as /",
601633
- state.skill.name,
601634
- " or via the Skill tool."
601635
- ]
601636
- }, undefined, true, undefined, this)
601980
+ children: skills2.length === 1 ? `It is available now as /${skills2[0].name} or via the Skill tool.` : "They are available now via /<name> or the Skill tool."
601981
+ }, undefined, false, undefined, this)
601637
601982
  ]
601638
601983
  }, undefined, true, undefined, this);
601639
601984
  }
@@ -603068,7 +603413,7 @@ async function loadStatsCache() {
603068
603413
  return getEmptyCache();
603069
603414
  }
603070
603415
  }
603071
- async function saveStatsCache(cache7) {
603416
+ async function saveStatsCache(cache9) {
603072
603417
  const fs15 = getFsImplementation();
603073
603418
  const cachePath = getStatsCachePath();
603074
603419
  const tempPath = `${cachePath}.${randomBytes18(8).toString("hex")}.tmp`;
@@ -603077,7 +603422,7 @@ async function saveStatsCache(cache7) {
603077
603422
  try {
603078
603423
  await fs15.mkdir(configDir);
603079
603424
  } catch {}
603080
- const content = jsonStringify(cache7, null, 2);
603425
+ const content = jsonStringify(cache9, null, 2);
603081
603426
  const handle = await open15(tempPath, "w", 384);
603082
603427
  try {
603083
603428
  await handle.writeFile(content, { encoding: "utf-8" });
@@ -603086,7 +603431,7 @@ async function saveStatsCache(cache7) {
603086
603431
  await handle.close();
603087
603432
  }
603088
603433
  await fs15.rename(tempPath, cachePath);
603089
- logForDebugging(`Stats cache saved successfully (lastComputedDate: ${cache7.lastComputedDate})`);
603434
+ logForDebugging(`Stats cache saved successfully (lastComputedDate: ${cache9.lastComputedDate})`);
603090
603435
  } catch (error54) {
603091
603436
  logError2(error54);
603092
603437
  try {
@@ -603945,9 +604290,9 @@ async function getAllSessionFiles() {
603945
604290
  }));
603946
604291
  return projectResults.flat();
603947
604292
  }
603948
- function cacheToStats(cache7, todayStats) {
604293
+ function cacheToStats(cache9, todayStats) {
603949
604294
  const dailyActivityMap = new Map;
603950
- for (const day of cache7.dailyActivity) {
604295
+ for (const day of cache9.dailyActivity) {
603951
604296
  dailyActivityMap.set(day.date, { ...day });
603952
604297
  }
603953
604298
  if (todayStats) {
@@ -603963,7 +604308,7 @@ function cacheToStats(cache7, todayStats) {
603963
604308
  }
603964
604309
  }
603965
604310
  const dailyModelTokensMap = new Map;
603966
- for (const day of cache7.dailyModelTokens) {
604311
+ for (const day of cache9.dailyModelTokens) {
603967
604312
  dailyModelTokensMap.set(day.date, { ...day.tokensByModel });
603968
604313
  }
603969
604314
  if (todayStats) {
@@ -603978,7 +604323,7 @@ function cacheToStats(cache7, todayStats) {
603978
604323
  }
603979
604324
  }
603980
604325
  }
603981
- const modelUsage = { ...cache7.modelUsage };
604326
+ const modelUsage = { ...cache9.modelUsage };
603982
604327
  if (todayStats) {
603983
604328
  for (const [model, usage2] of Object.entries(todayStats.modelUsage)) {
603984
604329
  if (modelUsage[model]) {
@@ -603998,7 +604343,7 @@ function cacheToStats(cache7, todayStats) {
603998
604343
  }
603999
604344
  }
604000
604345
  const hourCountsMap = new Map;
604001
- for (const [hour, count4] of Object.entries(cache7.hourCounts)) {
604346
+ for (const [hour, count4] of Object.entries(cache9.hourCounts)) {
604002
604347
  hourCountsMap.set(parseInt(hour, 10), count4);
604003
604348
  }
604004
604349
  if (todayStats) {
@@ -604010,9 +604355,9 @@ function cacheToStats(cache7, todayStats) {
604010
604355
  const dailyActivityArray = Array.from(dailyActivityMap.values()).sort((a2, b3) => a2.date.localeCompare(b3.date));
604011
604356
  const streaks = calculateStreaks(dailyActivityArray);
604012
604357
  const dailyModelTokens = Array.from(dailyModelTokensMap.entries()).map(([date6, tokensByModel]) => ({ date: date6, tokensByModel })).sort((a2, b3) => a2.date.localeCompare(b3.date));
604013
- const totalSessions = cache7.totalSessions + (todayStats?.sessionStats.length || 0);
604014
- const totalMessages = cache7.totalMessages + (todayStats?.totalMessages || 0);
604015
- let longestSession = cache7.longestSession;
604358
+ const totalSessions = cache9.totalSessions + (todayStats?.sessionStats.length || 0);
604359
+ const totalMessages = cache9.totalMessages + (todayStats?.totalMessages || 0);
604360
+ let longestSession = cache9.longestSession;
604016
604361
  if (todayStats) {
604017
604362
  for (const session2 of todayStats.sessionStats) {
604018
604363
  if (!longestSession || session2.duration > longestSession.duration) {
@@ -604020,7 +604365,7 @@ function cacheToStats(cache7, todayStats) {
604020
604365
  }
604021
604366
  }
604022
604367
  }
604023
- let firstSessionDate = cache7.firstSessionDate;
604368
+ let firstSessionDate = cache9.firstSessionDate;
604024
604369
  let lastSessionDate = null;
604025
604370
  if (todayStats) {
604026
604371
  for (const session2 of todayStats.sessionStats) {
@@ -604038,7 +604383,7 @@ function cacheToStats(cache7, todayStats) {
604038
604383
  const peakActivityDay = dailyActivityArray.length > 0 ? dailyActivityArray.reduce((max2, d2) => d2.messageCount > max2.messageCount ? d2 : max2).date : null;
604039
604384
  const peakActivityHour = hourCountsMap.size > 0 ? Array.from(hourCountsMap.entries()).reduce((max2, [hour, count4]) => count4 > max2[1] ? [hour, count4] : max2)[0] : null;
604040
604385
  const totalDays = firstSessionDate && lastSessionDate ? Math.ceil((new Date(lastSessionDate).getTime() - new Date(firstSessionDate).getTime()) / (1000 * 60 * 60 * 24)) + 1 : 0;
604041
- const totalSpeculationTimeSavedMs = cache7.totalSpeculationTimeSavedMs + (todayStats?.totalSpeculationTimeSavedMs || 0);
604386
+ const totalSpeculationTimeSavedMs = cache9.totalSpeculationTimeSavedMs + (todayStats?.totalSpeculationTimeSavedMs || 0);
604042
604387
  const result = {
604043
604388
  totalSessions,
604044
604389
  totalMessages,
@@ -604064,30 +604409,30 @@ async function aggregateClaudeCodeStats() {
604064
604409
  return getEmptyStats();
604065
604410
  }
604066
604411
  const updatedCache = await withStatsCacheLock(async () => {
604067
- const cache7 = await loadStatsCache();
604412
+ const cache9 = await loadStatsCache();
604068
604413
  const yesterday = getYesterdayDateString();
604069
- let result = cache7;
604070
- if (!cache7.lastComputedDate) {
604414
+ let result = cache9;
604415
+ if (!cache9.lastComputedDate) {
604071
604416
  logForDebugging("Stats cache empty, processing all historical data");
604072
604417
  const historicalStats = await processSessionFiles(allSessionFiles, {
604073
604418
  toDate: yesterday
604074
604419
  });
604075
604420
  if (historicalStats.sessionStats.length > 0 || historicalStats.dailyActivity.length > 0) {
604076
- result = mergeCacheWithNewStats(cache7, historicalStats, yesterday);
604421
+ result = mergeCacheWithNewStats(cache9, historicalStats, yesterday);
604077
604422
  await saveStatsCache(result);
604078
604423
  }
604079
- } else if (isDateBefore(cache7.lastComputedDate, yesterday)) {
604080
- const nextDay = getNextDay(cache7.lastComputedDate);
604081
- logForDebugging(`Stats cache stale (${cache7.lastComputedDate}), processing ${nextDay} to ${yesterday}`);
604424
+ } else if (isDateBefore(cache9.lastComputedDate, yesterday)) {
604425
+ const nextDay = getNextDay(cache9.lastComputedDate);
604426
+ logForDebugging(`Stats cache stale (${cache9.lastComputedDate}), processing ${nextDay} to ${yesterday}`);
604082
604427
  const newStats = await processSessionFiles(allSessionFiles, {
604083
604428
  fromDate: nextDay,
604084
604429
  toDate: yesterday
604085
604430
  });
604086
604431
  if (newStats.sessionStats.length > 0 || newStats.dailyActivity.length > 0) {
604087
- result = mergeCacheWithNewStats(cache7, newStats, yesterday);
604432
+ result = mergeCacheWithNewStats(cache9, newStats, yesterday);
604088
604433
  await saveStatsCache(result);
604089
604434
  } else {
604090
- result = { ...cache7, lastComputedDate: yesterday };
604435
+ result = { ...cache9, lastComputedDate: yesterday };
604091
604436
  await saveStatsCache(result);
604092
604437
  }
604093
604438
  }
@@ -607233,7 +607578,7 @@ function generateHtmlReport(data, insights) {
607233
607578
  </html>`;
607234
607579
  }
607235
607580
  function buildExportData(data, insights, facets, remoteStats) {
607236
- const version3 = typeof MACRO !== "undefined" ? "1.3.439" : "unknown";
607581
+ const version3 = typeof MACRO !== "undefined" ? "1.3.441" : "unknown";
607237
607582
  const remote_hosts_collected = remoteStats?.hosts.filter((h3) => h3.sessionCount > 0).map((h3) => h3.name);
607238
607583
  const facets_summary = {
607239
607584
  total: facets.size,
@@ -611143,7 +611488,7 @@ var init_sessionStorage = __esm(() => {
611143
611488
  init_settings2();
611144
611489
  init_slowOperations();
611145
611490
  init_uuid();
611146
- VERSION6 = typeof MACRO !== "undefined" ? "1.3.439" : "unknown";
611491
+ VERSION6 = typeof MACRO !== "undefined" ? "1.3.441" : "unknown";
611147
611492
  MAX_TOMBSTONE_REWRITE_BYTES = 50 * 1024 * 1024;
611148
611493
  SKIP_FIRST_PROMPT_PATTERN = /^(?:\s*<[a-z][\w-]*[\s>]|\[Request interrupted by user[^\]]*\])/;
611149
611494
  EPHEMERAL_PROGRESS_TYPES = new Set([
@@ -612363,7 +612708,7 @@ var init_filesystem = __esm(() => {
612363
612708
  });
612364
612709
  getBundledSkillsRoot = memoize_default(function getBundledSkillsRoot2() {
612365
612710
  const nonce = randomBytes19(16).toString("hex");
612366
- return join154(getClaudeTempDir(), "bundled-skills", "1.3.439", nonce);
612711
+ return join154(getClaudeTempDir(), "bundled-skills", "1.3.441", nonce);
612367
612712
  });
612368
612713
  getResolvedWorkingDirPaths = memoize_default(getPathsForPermissionCheck);
612369
612714
  });
@@ -617478,7 +617823,7 @@ __export(exports_update, {
617478
617823
  import { execFileSync as execFileSync3 } from "node:child_process";
617479
617824
  import { homedir as homedir35 } from "os";
617480
617825
  async function update() {
617481
- writeToStdout(`Current version: ${"1.3.439"}
617826
+ writeToStdout(`Current version: ${"1.3.441"}
617482
617827
  `);
617483
617828
  const isBundled = isInBundledMode();
617484
617829
  if (isBundled) {
@@ -617504,13 +617849,13 @@ Manual check: npm view ${"@rayu-dev/rayu-cli"} version
617504
617849
  process.exit(1);
617505
617850
  return;
617506
617851
  }
617507
- if (latestVersion === "1.3.439") {
617852
+ if (latestVersion === "1.3.441") {
617508
617853
  writeToStdout(source_default.green(`
617509
- Rayu CLI is up to date (${"1.3.439"})
617854
+ Rayu CLI is up to date (${"1.3.441"})
617510
617855
  `));
617511
617856
  process.exit(0);
617512
617857
  }
617513
- writeToStdout(`New version available: ${latestVersion} (current: ${"1.3.439"})
617858
+ writeToStdout(`New version available: ${latestVersion} (current: ${"1.3.441"})
617514
617859
  `);
617515
617860
  writeToStdout(`Installing update...
617516
617861
 
@@ -617534,7 +617879,7 @@ Try manually:
617534
617879
  return;
617535
617880
  }
617536
617881
  writeToStdout(source_default.green(`
617537
- Successfully updated from ${"1.3.439"} to ${latestVersion}
617882
+ Successfully updated from ${"1.3.441"} to ${latestVersion}
617538
617883
  `));
617539
617884
  process.exit(0);
617540
617885
  }
@@ -617548,14 +617893,14 @@ async function updateNativeBinary() {
617548
617893
  } catch {
617549
617894
  latestVersion = "";
617550
617895
  }
617551
- if (latestVersion && latestVersion === "1.3.439") {
617896
+ if (latestVersion && latestVersion === "1.3.441") {
617552
617897
  writeToStdout(source_default.green(`
617553
- Rayu CLI is up to date (1.3.439)
617898
+ Rayu CLI is up to date (1.3.441)
617554
617899
  `));
617555
617900
  process.exit(0);
617556
617901
  }
617557
617902
  if (latestVersion) {
617558
- writeToStdout(`New version available: ${latestVersion} (current: 1.3.439)
617903
+ writeToStdout(`New version available: ${latestVersion} (current: 1.3.441)
617559
617904
  `);
617560
617905
  }
617561
617906
  writeToStdout(`Downloading and installing update...
@@ -617570,13 +617915,13 @@ Rayu CLI is up to date (1.3.439)
617570
617915
  return;
617571
617916
  }
617572
617917
  writeToStdout(source_default.green(`
617573
- Rayu CLI is up to date (1.3.439)
617918
+ Rayu CLI is up to date (1.3.441)
617574
617919
  `));
617575
617920
  process.exit(0);
617576
617921
  }
617577
617922
  const updatedTo = result.latestVersion ?? latestVersion ?? "latest";
617578
617923
  writeToStdout(source_default.green(`
617579
- Successfully updated from 1.3.439 to ${updatedTo}
617924
+ Successfully updated from 1.3.441 to ${updatedTo}
617580
617925
  `));
617581
617926
  writeToStdout(`Restart your terminal to use the new version.
617582
617927
  `);
@@ -617607,7 +617952,7 @@ __export(exports_uninstall, {
617607
617952
  import { execFileSync as execFileSync4 } from "node:child_process";
617608
617953
  import { homedir as homedir36 } from "os";
617609
617954
  async function uninstall() {
617610
- writeToStdout(`Uninstalling Rayu CLI (${"1.3.439"})...
617955
+ writeToStdout(`Uninstalling Rayu CLI (${"1.3.441"})...
617611
617956
  `);
617612
617957
  writeToStdout(`Running: npm uninstall -g ${"@rayu-dev/rayu-cli"}
617613
617958
 
@@ -617630,7 +617975,7 @@ Try running manually:
617630
617975
  process.exit(1);
617631
617976
  }
617632
617977
  writeToStdout(source_default.green(`
617633
- Successfully uninstalled ${"@rayu-dev/rayu-cli"} ${"1.3.439"}
617978
+ Successfully uninstalled ${"@rayu-dev/rayu-cli"} ${"1.3.441"}
617634
617979
  `));
617635
617980
  writeToStdout(`Thanks for using Rayu CLI!
617636
617981
  `);
@@ -617682,7 +618027,7 @@ function showFirstRunWelcome() {
617682
618027
  `);
617683
618028
  try {
617684
618029
  mkdirSync16(getRayuConfigHomeDir(), { recursive: true });
617685
- writeFileSync18(markerPath(), "1.3.439", "utf8");
618030
+ writeFileSync18(markerPath(), "1.3.441", "utf8");
617686
618031
  } catch {}
617687
618032
  }
617688
618033
  var init_firstRun = __esm(() => {
@@ -629525,7 +629870,7 @@ async function initializeBetaTracing(resource) {
629525
629870
  });
629526
629871
  import_api_logs.logs.setGlobalLoggerProvider(loggerProvider);
629527
629872
  setLoggerProvider(loggerProvider);
629528
- const eventLogger = import_api_logs.logs.getLogger("com.anthropic.claude_code.events", "1.3.439");
629873
+ const eventLogger = import_api_logs.logs.getLogger("com.anthropic.claude_code.events", "1.3.441");
629529
629874
  setEventLogger(eventLogger);
629530
629875
  process.on("beforeExit", async () => {
629531
629876
  await loggerProvider?.forceFlush();
@@ -629565,7 +629910,7 @@ async function initializeTelemetry() {
629565
629910
  const platform4 = getPlatform();
629566
629911
  const baseAttributes = {
629567
629912
  [import_semantic_conventions2.ATTR_SERVICE_NAME]: "claude-code",
629568
- [import_semantic_conventions2.ATTR_SERVICE_VERSION]: "1.3.439"
629913
+ [import_semantic_conventions2.ATTR_SERVICE_VERSION]: "1.3.441"
629569
629914
  };
629570
629915
  if (platform4 === "wsl") {
629571
629916
  const wslVersion = getWslVersion();
@@ -629610,7 +629955,7 @@ async function initializeTelemetry() {
629610
629955
  } catch {}
629611
629956
  };
629612
629957
  registerCleanup(shutdownTelemetry2);
629613
- return meterProvider2.getMeter("com.anthropic.claude_code", "1.3.439");
629958
+ return meterProvider2.getMeter("com.anthropic.claude_code", "1.3.441");
629614
629959
  }
629615
629960
  const meterProvider = new import_sdk_metrics2.MeterProvider({
629616
629961
  resource,
@@ -629630,7 +629975,7 @@ async function initializeTelemetry() {
629630
629975
  });
629631
629976
  import_api_logs.logs.setGlobalLoggerProvider(loggerProvider);
629632
629977
  setLoggerProvider(loggerProvider);
629633
- const eventLogger = import_api_logs.logs.getLogger("com.anthropic.claude_code.events", "1.3.439");
629978
+ const eventLogger = import_api_logs.logs.getLogger("com.anthropic.claude_code.events", "1.3.441");
629634
629979
  setEventLogger(eventLogger);
629635
629980
  logForDebugging("[3P telemetry] Event logger set successfully");
629636
629981
  process.on("beforeExit", async () => {
@@ -629692,7 +630037,7 @@ Current timeout: ${timeoutMs}ms
629692
630037
  }
629693
630038
  };
629694
630039
  registerCleanup(shutdownTelemetry);
629695
- return meterProvider.getMeter("com.anthropic.claude_code", "1.3.439");
630040
+ return meterProvider.getMeter("com.anthropic.claude_code", "1.3.441");
629696
630041
  }
629697
630042
  async function flushTelemetry() {
629698
630043
  const meterProvider = getMeterProvider();
@@ -631205,7 +631550,7 @@ function buildSystemInitMessage(inputs) {
631205
631550
  slash_commands: inputs.commands.filter((c4) => c4.userInvocable !== false).map((c4) => c4.name),
631206
631551
  apiKeySource: getAnthropicApiKeyWithSource().source,
631207
631552
  betas: getSdkBetas(),
631208
- claude_code_version: "1.3.439",
631553
+ claude_code_version: "1.3.441",
631209
631554
  output_style: outputStyle2,
631210
631555
  agents: inputs.agents.map((agent) => agent.agentType),
631211
631556
  skills: inputs.skills.filter((s2) => s2.userInvocable !== false).map((skill) => skill.name),
@@ -647539,7 +647884,7 @@ var init_useVoiceEnabled = __esm(() => {
647539
647884
  function getSemverPart(version3) {
647540
647885
  return `${import_semver12.major(version3, { loose: true })}.${import_semver12.minor(version3, { loose: true })}.${import_semver12.patch(version3, { loose: true })}`;
647541
647886
  }
647542
- function useUpdateNotification(updatedVersion, initialVersion = "1.3.439") {
647887
+ function useUpdateNotification(updatedVersion, initialVersion = "1.3.441") {
647543
647888
  const [lastNotifiedSemver, setLastNotifiedSemver] = import_react217.useState(() => getSemverPart(initialVersion));
647544
647889
  if (!updatedVersion) {
647545
647890
  return null;
@@ -647579,7 +647924,7 @@ function AutoUpdater({
647579
647924
  return;
647580
647925
  }
647581
647926
  if (false) {}
647582
- const currentVersion = "1.3.439";
647927
+ const currentVersion = "1.3.441";
647583
647928
  const channel = getInitialSettings()?.autoUpdatesChannel ?? "latest";
647584
647929
  let latestVersion = await getLatestVersion(channel);
647585
647930
  const isDisabled = isAutoUpdaterDisabled();
@@ -647792,12 +648137,12 @@ function NativeAutoUpdater({
647792
648137
  logEvent("tengu_native_auto_updater_start", {});
647793
648138
  try {
647794
648139
  const maxVersion = await getMaxVersion();
647795
- if (maxVersion && gt("1.3.439", maxVersion)) {
648140
+ if (maxVersion && gt("1.3.441", maxVersion)) {
647796
648141
  const msg = await getMaxVersionMessage();
647797
648142
  setMaxVersionIssue(msg ?? "affects your version");
647798
648143
  }
647799
648144
  const result = await installLatest(channel);
647800
- const currentVersion = "1.3.439";
648145
+ const currentVersion = "1.3.441";
647801
648146
  const latencyMs = Date.now() - startTime;
647802
648147
  if (result.lockFailed) {
647803
648148
  logEvent("tengu_native_auto_updater_lock_contention", {
@@ -647934,17 +648279,17 @@ function PackageManagerAutoUpdater(t0) {
647934
648279
  const maxVersion = await getMaxVersion();
647935
648280
  if (maxVersion && latest && gt(latest, maxVersion)) {
647936
648281
  logForDebugging(`PackageManagerAutoUpdater: maxVersion ${maxVersion} is set, capping update from ${latest} to ${maxVersion}`);
647937
- if (gte("1.3.439", maxVersion)) {
647938
- logForDebugging(`PackageManagerAutoUpdater: current version ${"1.3.439"} is already at or above maxVersion ${maxVersion}, skipping update`);
648282
+ if (gte("1.3.441", maxVersion)) {
648283
+ logForDebugging(`PackageManagerAutoUpdater: current version ${"1.3.441"} is already at or above maxVersion ${maxVersion}, skipping update`);
647939
648284
  setUpdateAvailable(false);
647940
648285
  return;
647941
648286
  }
647942
648287
  latest = maxVersion;
647943
648288
  }
647944
- const hasUpdate = latest && !gte("1.3.439", latest) && !shouldSkipVersion(latest);
648289
+ const hasUpdate = latest && !gte("1.3.441", latest) && !shouldSkipVersion(latest);
647945
648290
  setUpdateAvailable(!!hasUpdate);
647946
648291
  if (hasUpdate) {
647947
- logForDebugging(`PackageManagerAutoUpdater: Update available ${"1.3.439"} -> ${latest}`);
648292
+ logForDebugging(`PackageManagerAutoUpdater: Update available ${"1.3.441"} -> ${latest}`);
647948
648293
  }
647949
648294
  };
647950
648295
  $3[0] = t1;
@@ -647978,7 +648323,7 @@ function PackageManagerAutoUpdater(t0) {
647978
648323
  wrap: "truncate",
647979
648324
  children: [
647980
648325
  "currentVersion: ",
647981
- "1.3.439"
648326
+ "1.3.441"
647982
648327
  ]
647983
648328
  }, undefined, true, undefined, this);
647984
648329
  $3[3] = verbose;
@@ -649672,7 +650017,7 @@ function get2(obj, path29) {
649672
650017
  return arr ? list : list[0];
649673
650018
  }
649674
650019
  function norm(weight = 1, mantissa = 3) {
649675
- const cache7 = new Map;
650020
+ const cache9 = new Map;
649676
650021
  const m3 = Math.pow(10, mantissa);
649677
650022
  return {
649678
650023
  get(value) {
@@ -649688,15 +650033,15 @@ function norm(weight = 1, mantissa = 3) {
649688
650033
  inSpace = false;
649689
650034
  }
649690
650035
  }
649691
- if (cache7.has(numTokens)) {
649692
- return cache7.get(numTokens);
650036
+ if (cache9.has(numTokens)) {
650037
+ return cache9.get(numTokens);
649693
650038
  }
649694
650039
  const n3 = Math.round(m3 / Math.pow(numTokens, 0.5 * weight)) / m3;
649695
- cache7.set(numTokens, n3);
650040
+ cache9.set(numTokens, n3);
649696
650041
  return n3;
649697
650042
  },
649698
650043
  clear() {
649699
- cache7.clear();
650044
+ cache9.clear();
649700
650045
  }
649701
650046
  };
649702
650047
  }
@@ -651936,7 +652281,7 @@ function mcpQueryFor(searchToken) {
651936
652281
  function findReusableCacheEntry(mcpQuery, searchToken) {
651937
652282
  let best;
651938
652283
  let bestLen = 0;
651939
- for (const [key2, channels] of cache7) {
652284
+ for (const [key2, channels] of cache9) {
651940
652285
  if (mcpQuery.startsWith(key2) && key2.length > bestLen && channels.some((c4) => c4.startsWith(searchToken))) {
651941
652286
  best = channels;
651942
652287
  bestLen = key2.length;
@@ -651949,7 +652294,7 @@ async function getSlackChannelSuggestions(clients, searchToken) {
651949
652294
  return [];
651950
652295
  const mcpQuery = mcpQueryFor(searchToken);
651951
652296
  const lower2 = searchToken.toLowerCase();
651952
- let channels = cache7.get(mcpQuery) ?? findReusableCacheEntry(mcpQuery, lower2);
652297
+ let channels = cache9.get(mcpQuery) ?? findReusableCacheEntry(mcpQuery, lower2);
651953
652298
  if (!channels) {
651954
652299
  if (inflightQuery === mcpQuery && inflightPromise) {
651955
652300
  channels = await inflightPromise;
@@ -651957,7 +652302,7 @@ async function getSlackChannelSuggestions(clients, searchToken) {
651957
652302
  inflightQuery = mcpQuery;
651958
652303
  inflightPromise = fetchChannels(clients, mcpQuery);
651959
652304
  channels = await inflightPromise;
651960
- cache7.set(mcpQuery, channels);
652305
+ cache9.set(mcpQuery, channels);
651961
652306
  const before = knownChannels.size;
651962
652307
  for (const c4 of channels)
651963
652308
  knownChannels.add(c4);
@@ -651965,8 +652310,8 @@ async function getSlackChannelSuggestions(clients, searchToken) {
651965
652310
  knownChannelsVersion++;
651966
652311
  knownChannelsChanged.emit();
651967
652312
  }
651968
- if (cache7.size > 50) {
651969
- cache7.delete(cache7.keys().next().value);
652313
+ if (cache9.size > 50) {
652314
+ cache9.delete(cache9.keys().next().value);
651970
652315
  }
651971
652316
  if (inflightQuery === mcpQuery) {
651972
652317
  inflightQuery = null;
@@ -651979,12 +652324,12 @@ async function getSlackChannelSuggestions(clients, searchToken) {
651979
652324
  displayText: `#${c4}`
651980
652325
  }));
651981
652326
  }
651982
- var SLACK_SEARCH_TOOL = "slack_search_channels", cache7, knownChannels, knownChannelsVersion = 0, knownChannelsChanged, subscribeKnownChannels, inflightQuery = null, inflightPromise = null, resultsEnvelopeSchema;
652327
+ var SLACK_SEARCH_TOOL = "slack_search_channels", cache9, knownChannels, knownChannelsVersion = 0, knownChannelsChanged, subscribeKnownChannels, inflightQuery = null, inflightPromise = null, resultsEnvelopeSchema;
651983
652328
  var init_slackChannelSuggestions = __esm(() => {
651984
652329
  init_zod3();
651985
652330
  init_debug();
651986
652331
  init_slowOperations();
651987
- cache7 = new Map;
652332
+ cache9 = new Map;
651988
652333
  knownChannels = new Set;
651989
652334
  knownChannelsChanged = createSignal();
651990
652335
  subscribeKnownChannels = knownChannelsChanged.subscribe;
@@ -656143,7 +656488,7 @@ function buildStatusLineCommandInput(permissionMode, exceeds200kTokens, settings
656143
656488
  project_dir: getOriginalCwd(),
656144
656489
  added_dirs: addedDirs
656145
656490
  },
656146
- version: "1.3.439",
656491
+ version: "1.3.441",
656147
656492
  output_style: {
656148
656493
  name: outputStyleName
656149
656494
  },
@@ -665890,6 +666235,100 @@ var init_useIdeSelection = __esm(() => {
665890
666235
  }));
665891
666236
  });
665892
666237
 
666238
+ // src/utils/progressCoalescing.ts
666239
+ function coalesceEphemeralProgressMessages(oldMessages, newMessage) {
666240
+ const next = newMessage;
666241
+ const matches = (m3) => {
666242
+ if (m3.type !== "progress") {
666243
+ return false;
666244
+ }
666245
+ const candidate = m3;
666246
+ return candidate.parentToolUseID === next.parentToolUseID && candidate.data.type === next.data.type;
666247
+ };
666248
+ const last2 = oldMessages[oldMessages.length - 1];
666249
+ if (last2 !== undefined && matches(last2)) {
666250
+ const copy2 = oldMessages.slice();
666251
+ copy2[copy2.length - 1] = newMessage;
666252
+ return copy2;
666253
+ }
666254
+ const result = [];
666255
+ for (const m3 of oldMessages) {
666256
+ if (!matches(m3)) {
666257
+ result.push(m3);
666258
+ }
666259
+ }
666260
+ result.push(newMessage);
666261
+ return result;
666262
+ }
666263
+
666264
+ // src/utils/memProbe.ts
666265
+ function isMemProbeEnabled() {
666266
+ return isEnvTruthy(process.env.RAYU_MEM_PROBE);
666267
+ }
666268
+ function reportMemProbeValue(name, value) {
666269
+ if (!isMemProbeEnabled()) {
666270
+ return;
666271
+ }
666272
+ reported2.set(name, value);
666273
+ }
666274
+ function setMemProbeFpsTracker(tracker) {
666275
+ fpsTrackerRef = tracker;
666276
+ }
666277
+ function activeCount(method) {
666278
+ try {
666279
+ const fn = process[method];
666280
+ return typeof fn === "function" ? fn.call(process).length : undefined;
666281
+ } catch {
666282
+ return;
666283
+ }
666284
+ }
666285
+ function formatMemProbeLine() {
666286
+ const mu = process.memoryUsage();
666287
+ const toMB = (bytes) => (bytes / 1024 / 1024).toFixed(1);
666288
+ const parts = [
666289
+ `heapUsed=${toMB(mu.heapUsed)}MB`,
666290
+ `rss=${toMB(mu.rss)}MB`,
666291
+ `external=${toMB(mu.external)}MB`
666292
+ ];
666293
+ const handles = activeCount("_getActiveHandles");
666294
+ if (handles !== undefined) {
666295
+ parts.push(`handles=${handles}`);
666296
+ }
666297
+ const requests = activeCount("_getActiveRequests");
666298
+ if (requests !== undefined) {
666299
+ parts.push(`requests=${requests}`);
666300
+ }
666301
+ try {
666302
+ parts.push(`yogaLiveNodes=${getYogaCounters().live}`);
666303
+ } catch {}
666304
+ if (fpsTrackerRef) {
666305
+ try {
666306
+ parts.push(`fpsBuffer=${fpsTrackerRef.bufferSize()}`);
666307
+ } catch {}
666308
+ }
666309
+ for (const [name, value] of reported2) {
666310
+ parts.push(`${name}=${value}`);
666311
+ }
666312
+ return `[mem-probe] ${parts.join(" ")}`;
666313
+ }
666314
+ function startMemProbeIfEnabled(intervalMs = DEFAULT_INTERVAL_MS) {
666315
+ if (interval || !isMemProbeEnabled()) {
666316
+ return;
666317
+ }
666318
+ logForDebugging(`[mem-probe] enabled — sampling every ${Math.round(intervalMs / 1000)}s`);
666319
+ interval = setInterval(() => {
666320
+ logForDebugging(formatMemProbeLine());
666321
+ }, intervalMs);
666322
+ interval.unref?.();
666323
+ }
666324
+ var DEFAULT_INTERVAL_MS = 30000, interval = null, reported2, fpsTrackerRef = null;
666325
+ var init_memProbe = __esm(() => {
666326
+ init_yoga_layout();
666327
+ init_debug();
666328
+ init_envUtils();
666329
+ reported2 = new Map;
666330
+ });
666331
+
665893
666332
  // src/utils/asciicast.ts
665894
666333
  var exports_asciicast = {};
665895
666334
  __export(exports_asciicast, {
@@ -667547,7 +667986,7 @@ async function submitTranscriptShare(messages, trigger, appearanceId) {
667547
667986
  } catch {}
667548
667987
  const data = {
667549
667988
  trigger,
667550
- version: "1.3.439",
667989
+ version: "1.3.441",
667551
667990
  platform: process.platform,
667552
667991
  transcript,
667553
667992
  subagentTranscripts: Object.keys(subagentTranscripts).length > 0 ? subagentTranscripts : undefined,
@@ -675243,8 +675682,8 @@ function AnimatedTerminalTitle(t0) {
675243
675682
  if (disabled || noPrefix || !isAnimating || !terminalFocused) {
675244
675683
  return;
675245
675684
  }
675246
- const interval = setInterval(_temp289, TITLE_ANIMATION_INTERVAL_MS, setFrame);
675247
- return () => clearInterval(interval);
675685
+ const interval2 = setInterval(_temp289, TITLE_ANIMATION_INTERVAL_MS, setFrame);
675686
+ return () => clearInterval(interval2);
675248
675687
  };
675249
675688
  t2 = [disabled, noPrefix, isAnimating, terminalFocused];
675250
675689
  $3[0] = disabled;
@@ -676480,13 +676919,12 @@ Error: sandbox required but unavailable: ${reason}
676480
676919
  if (false) {}
676481
676920
  } else if (newMessage.type === "progress" && isEphemeralToolProgress(newMessage.data.type)) {
676482
676921
  setMessages((oldMessages) => {
676483
- const last2 = oldMessages.at(-1);
676484
- if (last2?.type === "progress" && last2.parentToolUseID === newMessage.parentToolUseID && last2.data.type === newMessage.data.type) {
676485
- const copy2 = oldMessages.slice();
676486
- copy2[copy2.length - 1] = newMessage;
676487
- return copy2;
676922
+ const next = coalesceEphemeralProgressMessages(oldMessages, newMessage);
676923
+ if (isMemProbeEnabled()) {
676924
+ reportMemProbeValue("messages", next.length);
676925
+ reportMemProbeValue("ephemeralProgress", next.reduce((n3, m3) => n3 + (m3.type === "progress" ? 1 : 0), 0));
676488
676926
  }
676489
- return [...oldMessages, newMessage];
676927
+ return next;
676490
676928
  });
676491
676929
  } else {
676492
676930
  setMessages((oldMessages) => [...oldMessages, newMessage]);
@@ -678523,6 +678961,7 @@ var init_REPL = __esm(() => {
678523
678961
  init_AppState();
678524
678962
  init_plans();
678525
678963
  init_sessionStorage();
678964
+ init_memProbe();
678526
678965
  init_conversationRecovery();
678527
678966
  init_queryHelpers();
678528
678967
  init_microCompact();
@@ -679441,28 +679880,43 @@ var init_terminalPreference = __esm(() => {
679441
679880
 
679442
679881
  // src/utils/fpsTracker.ts
679443
679882
  class FpsTracker {
679444
- frameDurations = [];
679883
+ now;
679884
+ reservoir = [];
679885
+ totalFrames = 0;
679445
679886
  firstRenderTime;
679446
679887
  lastRenderTime;
679888
+ constructor(now2 = () => performance.now()) {
679889
+ this.now = now2;
679890
+ }
679447
679891
  record(durationMs) {
679448
- const now2 = performance.now();
679892
+ const now2 = this.now();
679449
679893
  if (this.firstRenderTime === undefined) {
679450
679894
  this.firstRenderTime = now2;
679451
679895
  }
679452
679896
  this.lastRenderTime = now2;
679453
- this.frameDurations.push(durationMs);
679897
+ this.totalFrames++;
679898
+ if (this.reservoir.length < RESERVOIR_SIZE2) {
679899
+ this.reservoir.push(durationMs);
679900
+ } else {
679901
+ const j3 = Math.floor(Math.random() * this.totalFrames);
679902
+ if (j3 < RESERVOIR_SIZE2) {
679903
+ this.reservoir[j3] = durationMs;
679904
+ }
679905
+ }
679906
+ }
679907
+ bufferSize() {
679908
+ return this.reservoir.length;
679454
679909
  }
679455
679910
  getMetrics() {
679456
- if (this.frameDurations.length === 0 || this.firstRenderTime === undefined || this.lastRenderTime === undefined) {
679911
+ if (this.totalFrames === 0 || this.firstRenderTime === undefined || this.lastRenderTime === undefined) {
679457
679912
  return;
679458
679913
  }
679459
679914
  const totalTimeMs = this.lastRenderTime - this.firstRenderTime;
679460
679915
  if (totalTimeMs <= 0) {
679461
679916
  return;
679462
679917
  }
679463
- const totalFrames = this.frameDurations.length;
679464
- const averageFps = totalFrames / (totalTimeMs / 1000);
679465
- const sorted = this.frameDurations.slice().sort((a2, b3) => b3 - a2);
679918
+ const averageFps = this.totalFrames / (totalTimeMs / 1000);
679919
+ const sorted = this.reservoir.slice().sort((a2, b3) => b3 - a2);
679466
679920
  const p99Index = Math.max(0, Math.ceil(sorted.length * 0.01) - 1);
679467
679921
  const p99FrameTimeMs = sorted[p99Index];
679468
679922
  const low1PctFps = p99FrameTimeMs > 0 ? 1000 / p99FrameTimeMs : 0;
@@ -679472,6 +679926,49 @@ class FpsTracker {
679472
679926
  };
679473
679927
  }
679474
679928
  }
679929
+ var RESERVOIR_SIZE2 = 1024;
679930
+
679931
+ // src/utils/interactiveHeapDumpMonitor.ts
679932
+ function isAutoHeapDumpEnabled() {
679933
+ return !isEnvDefinedFalsy(process.env.RAYU_AUTO_HEAPDUMP);
679934
+ }
679935
+ async function checkHeapForAutoDump(getHeapUsed = () => process.memoryUsage().heapUsed, dump = performHeapDump) {
679936
+ if (inFlight || dumpsTaken >= MAX_AUTO_DUMPS) {
679937
+ return false;
679938
+ }
679939
+ if (getHeapUsed() < AUTO_HEAPDUMP_THRESHOLD_BYTES) {
679940
+ return false;
679941
+ }
679942
+ inFlight = true;
679943
+ dumpsTaken++;
679944
+ try {
679945
+ const result = await dump("auto-1.5GB", dumpsTaken);
679946
+ if (result.success) {
679947
+ logForDebugging(`[auto-heapdump] heap crossed 1.5GB — snapshot written to ${result.heapPath} (diagnostics: ${result.diagPath})`);
679948
+ } else {
679949
+ logForDebugging(`[auto-heapdump] snapshot failed: ${result.error}`);
679950
+ }
679951
+ return true;
679952
+ } finally {
679953
+ inFlight = false;
679954
+ }
679955
+ }
679956
+ function startInteractiveHeapDumpMonitor() {
679957
+ if (interval2 || !isAutoHeapDumpEnabled()) {
679958
+ return;
679959
+ }
679960
+ interval2 = setInterval(() => {
679961
+ checkHeapForAutoDump();
679962
+ }, CHECK_INTERVAL_MS);
679963
+ interval2.unref?.();
679964
+ }
679965
+ var AUTO_HEAPDUMP_THRESHOLD_BYTES, CHECK_INTERVAL_MS = 1e4, MAX_AUTO_DUMPS = 1, interval2 = null, dumpsTaken = 0, inFlight = false;
679966
+ var init_interactiveHeapDumpMonitor = __esm(() => {
679967
+ init_debug();
679968
+ init_envUtils();
679969
+ init_heapDumpService();
679970
+ AUTO_HEAPDUMP_THRESHOLD_BYTES = 1.5 * 1024 * 1024 * 1024;
679971
+ });
679475
679972
 
679476
679973
  // src/utils/githubRepoPathMapping.ts
679477
679974
  import { realpath as realpath13 } from "fs/promises";
@@ -679592,7 +680089,7 @@ function WelcomeV2() {
679592
680089
  dimColor: true,
679593
680090
  children: [
679594
680091
  "v",
679595
- "1.3.439"
680092
+ "1.3.441"
679596
680093
  ]
679597
680094
  }, undefined, true, undefined, this)
679598
680095
  ]
@@ -681326,7 +681823,7 @@ function completeOnboarding() {
681326
681823
  saveGlobalConfig((current) => ({
681327
681824
  ...current,
681328
681825
  hasCompletedOnboarding: true,
681329
- lastOnboardingVersion: "1.3.439"
681826
+ lastOnboardingVersion: "1.3.441"
681330
681827
  }));
681331
681828
  }
681332
681829
  function showDialog(root2, renderer) {
@@ -681463,6 +681960,9 @@ function getRenderContext(exitOnCtrlC) {
681463
681960
  const fpsTracker = new FpsTracker;
681464
681961
  const stats3 = createStatsStore();
681465
681962
  setStatsStore(stats3);
681963
+ setMemProbeFpsTracker(fpsTracker);
681964
+ startMemProbeIfEnabled();
681965
+ startInteractiveHeapDumpMonitor();
681466
681966
  const frameTimingLogPath = process.env.CLAUDE_CODE_FRAME_TIMING_LOG;
681467
681967
  return {
681468
681968
  getFpsMetrics: () => fpsTracker.getMetrics(),
@@ -681523,6 +682023,8 @@ var init_interactiveHelpers = __esm(() => {
681523
682023
  init_config2();
681524
682024
  init_terminalPreference();
681525
682025
  init_envUtils();
682026
+ init_memProbe();
682027
+ init_interactiveHeapDumpMonitor();
681526
682028
  init_githubRepoPathMapping();
681527
682029
  init_managedEnv();
681528
682030
  init_renderOptions();
@@ -686269,7 +686771,7 @@ function appendToLog(path30, message) {
686269
686771
  cwd: getFsImplementation().cwd(),
686270
686772
  userType: "external",
686271
686773
  sessionId: getSessionId(),
686272
- version: "1.3.439"
686774
+ version: "1.3.441"
686273
686775
  };
686274
686776
  getLogWriter(path30).write(messageWithTimestamp);
686275
686777
  }
@@ -690377,8 +690879,8 @@ async function getEnvLessBridgeConfig() {
690377
690879
  }
690378
690880
  async function checkEnvLessBridgeMinVersion() {
690379
690881
  const cfg = await getEnvLessBridgeConfig();
690380
- if (cfg.min_version && lt("1.3.439", cfg.min_version)) {
690381
- return `Your version of RAYU (${"1.3.439"}) is too old for Remote Control.
690882
+ if (cfg.min_version && lt("1.3.441", cfg.min_version)) {
690883
+ return `Your version of RAYU (${"1.3.441"}) is too old for Remote Control.
690382
690884
  Version ${cfg.min_version} or higher is required. Run \`claude update\` to update.`;
690383
690885
  }
690384
690886
  return null;
@@ -690852,7 +691354,7 @@ async function initBridgeCore(params) {
690852
691354
  const rawApi = createBridgeApiClient({
690853
691355
  baseUrl,
690854
691356
  getAccessToken,
690855
- runnerVersion: "1.3.439",
691357
+ runnerVersion: "1.3.441",
690856
691358
  onDebug: logForDebugging,
690857
691359
  onAuth401,
690858
691360
  getTrustedDeviceToken
@@ -693560,8 +694062,8 @@ function runHeadlessStreaming(structuredIO, mcpClients, commands, tools, initial
693560
694062
  jsonSchema: getInitJsonSchema() ?? options.jsonSchema,
693561
694063
  mutableMessages,
693562
694064
  getReadFileCache: () => pendingSeeds.size === 0 ? readFileState : mergeFileStateCaches(readFileState, pendingSeeds),
693563
- setReadFileCache: (cache8) => {
693564
- readFileState = cache8;
694065
+ setReadFileCache: (cache10) => {
694066
+ readFileState = cache10;
693565
694067
  for (const [path30, seed] of pendingSeeds.entries()) {
693566
694068
  const existing = readFileState.get(path30);
693567
694069
  if (!existing || seed.timestamp > existing.timestamp) {
@@ -696214,7 +696716,7 @@ async function startMCPServer(cwd3, debug4, verbose) {
696214
696716
  setCwd(cwd3);
696215
696717
  const server = new Server({
696216
696718
  name: "claude/tengu",
696217
- version: "1.3.439"
696719
+ version: "1.3.441"
696218
696720
  }, {
696219
696721
  capabilities: {
696220
696722
  tools: {}
@@ -698740,7 +699242,7 @@ ${customInstructions}` : customInstructions;
698740
699242
  }
698741
699243
  }
698742
699244
  logForDiagnosticsNoPII("info", "started", {
698743
- version: "1.3.439",
699245
+ version: "1.3.441",
698744
699246
  is_native_binary: isInBundledMode()
698745
699247
  });
698746
699248
  registerCleanup(async () => {
@@ -699459,7 +699961,7 @@ Usage: rayu --remote "your task description"`, () => gracefulShutdown(1));
699459
699961
  pendingHookMessages
699460
699962
  }, renderAndRun);
699461
699963
  }
699462
- }).version("1.3.439 (Rayu-CLI)", "-v, --version", "Output the version number");
699964
+ }).version("1.3.441 (Rayu-CLI)", "-v, --version", "Output the version number");
699463
699965
  program.option("-w, --worktree [name]", "Create a new git worktree for this session (optionally specify a name)");
699464
699966
  program.option("--tmux", "Create a tmux session for the worktree (requires --worktree). Uses iTerm2 native panes when available; use --tmux=classic for traditional tmux.");
699465
699967
  if (canUserConfigureAdvisor()) {
@@ -699925,7 +700427,7 @@ if (false) {}
699925
700427
  async function main2() {
699926
700428
  const args = process.argv.slice(2);
699927
700429
  if (args.length === 1 && (args[0] === "--version" || args[0] === "-v" || args[0] === "-V")) {
699928
- console.log(`${"1.3.439"} (Rayu-CLI)`);
700430
+ console.log(`${"1.3.441"} (Rayu-CLI)`);
699929
700431
  return;
699930
700432
  }
699931
700433
  const {