@rayu-dev/rayu-cli 1.3.434 → 1.3.435

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 +879 -160
  2. package/package.json +1 -1
package/dist/rayu.js CHANGED
@@ -148347,7 +148347,7 @@ var init_auth = __esm(() => {
148347
148347
 
148348
148348
  // src/utils/userAgent.ts
148349
148349
  function getRayuUserAgent() {
148350
- return `rayu/${"1.3.434"}`;
148350
+ return `rayu/${"1.3.435"}`;
148351
148351
  }
148352
148352
  var getClaudeCodeUserAgent;
148353
148353
  var init_userAgent = __esm(() => {
@@ -148373,7 +148373,7 @@ function getUserAgent() {
148373
148373
  const clientApp = process.env.RAYU_AGENT_SDK_CLIENT_APP ? `, client-app/${process.env.RAYU_AGENT_SDK_CLIENT_APP}` : "";
148374
148374
  const workload = getWorkload();
148375
148375
  const workloadSuffix = workload ? `, workload/${workload}` : "";
148376
- return `rayu/${"1.3.434"} (${"external"}, ${process.env.RAYU_ENTRYPOINT ?? "cli"}${agentSdkVersion}${clientApp}${workloadSuffix})`;
148376
+ return `rayu/${"1.3.435"} (${"external"}, ${process.env.RAYU_ENTRYPOINT ?? "cli"}${agentSdkVersion}${clientApp}${workloadSuffix})`;
148377
148377
  }
148378
148378
  function getMCPUserAgent() {
148379
148379
  const parts = [];
@@ -148387,7 +148387,7 @@ function getMCPUserAgent() {
148387
148387
  parts.push(`client-app/${process.env.RAYU_AGENT_SDK_CLIENT_APP}`);
148388
148388
  }
148389
148389
  const suffix = parts.length > 0 ? ` (${parts.join(", ")})` : "";
148390
- return `rayu/${"1.3.434"}${suffix}`;
148390
+ return `rayu/${"1.3.435"}${suffix}`;
148391
148391
  }
148392
148392
  function getWebFetchUserAgent() {
148393
148393
  return `Rayu-User (${getRayuUserAgent()})`;
@@ -148510,7 +148510,7 @@ var init_user = __esm(() => {
148510
148510
  deviceId,
148511
148511
  sessionId: getSessionId(),
148512
148512
  email: getEmail(),
148513
- appVersion: "1.3.434",
148513
+ appVersion: "1.3.435",
148514
148514
  platform: getHostPlatformForAnalytics(),
148515
148515
  organizationUuid,
148516
148516
  accountUuid,
@@ -184022,7 +184022,7 @@ var init_metadata = __esm(() => {
184022
184022
  COMPOUND_OPERATOR_REGEX = /\s*(?:&&|\|\||[;|])\s*/;
184023
184023
  WHITESPACE_REGEX = /\s+/;
184024
184024
  getVersionBase = memoize_default(() => {
184025
- const match = "1.3.434".match(/^\d+\.\d+\.\d+(?:-[a-z]+)?/);
184025
+ const match = "1.3.435".match(/^\d+\.\d+\.\d+(?:-[a-z]+)?/);
184026
184026
  return match ? match[0] : undefined;
184027
184027
  });
184028
184028
  buildEnvContext = memoize_default(async () => {
@@ -184061,7 +184061,7 @@ var init_metadata = __esm(() => {
184061
184061
  },
184062
184062
  isGithubAction: isEnvTruthy(process.env.GITHUB_ACTIONS),
184063
184063
  isRayuAction: isEnvTruthy(process.env.RAYU_ACTION),
184064
- version: "1.3.434",
184064
+ version: "1.3.435",
184065
184065
  versionBase: getVersionBase(),
184066
184066
  buildTime: "",
184067
184067
  deploymentEnvironment: env4.detectDeploymentEnvironment(),
@@ -184675,7 +184675,7 @@ function initialize1PEventLogging() {
184675
184675
  const platform2 = getPlatform();
184676
184676
  const attributes = {
184677
184677
  [import_semantic_conventions.ATTR_SERVICE_NAME]: "rayu",
184678
- [import_semantic_conventions.ATTR_SERVICE_VERSION]: "1.3.434"
184678
+ [import_semantic_conventions.ATTR_SERVICE_VERSION]: "1.3.435"
184679
184679
  };
184680
184680
  if (platform2 === "wsl") {
184681
184681
  const wslVersion = getWslVersion();
@@ -184702,7 +184702,7 @@ function initialize1PEventLogging() {
184702
184702
  })
184703
184703
  ]
184704
184704
  });
184705
- firstPartyEventLogger = firstPartyEventLoggerProvider.getLogger("io.rayu.events", "1.3.434");
184705
+ firstPartyEventLogger = firstPartyEventLoggerProvider.getLogger("io.rayu.events", "1.3.435");
184706
184706
  }
184707
184707
  async function reinitialize1PEventLoggingIfConfigChanged() {
184708
184708
  if (!is1PEventLoggingEnabled() || !firstPartyEventLoggerProvider) {
@@ -220618,7 +220618,7 @@ function getAttributionHeader(fingerprint) {
220618
220618
  if (!isAttributionHeaderEnabled()) {
220619
220619
  return "";
220620
220620
  }
220621
- const version2 = `${"1.3.434"}.${fingerprint}`;
220621
+ const version2 = `${"1.3.435"}.${fingerprint}`;
220622
220622
  const entrypoint = process.env.CLAUDE_CODE_ENTRYPOINT ?? "unknown";
220623
220623
  const cch = "";
220624
220624
  const workload = getWorkload();
@@ -271527,7 +271527,7 @@ var init_generalPurposeAgent = __esm(() => {
271527
271527
  });
271528
271528
 
271529
271529
  // src/tools/AgentTool/built-in/subagents/common.ts
271530
- var EPHEMERAL_FRAMING = `You are a one-shot subagent: a fresh session with NO memory of past work and NO future. You receive a single self-contained task packet, perform exactly ONE job, and return a concise structured result to the agent that spawned you. Do NOT ask follow-up questions — everything you need is in the task packet; if something is genuinely missing, state the assumption you made and proceed. Keep going until the job is fully done. Work in PARALLEL where steps are independent: batch your reads/greps/searches into a single message (multiple tool calls, ~3–5 at a time — parallel is ~3–5x faster than one-at-a-time); go sequential only when one call genuinely needs another's output. Report high-signal results only (the output + the few facts that matter, not a play-by-play). Do not create report files; report back as your final message.`, SKILL_SEEKING = `Before starting, check whether any installed skill (via the Skill tool) is relevant to this task and would improve the result — if so, use it. Skills are installed by the user via /install-skill or /find-skill; if none apply, proceed without one.`;
271530
+ var EPHEMERAL_FRAMING = `You are a one-shot subagent: a fresh session with NO memory of past work and NO future. You receive a single self-contained task packet, perform exactly ONE job, and return a concise structured result to the agent that spawned you. Do NOT ask follow-up questions — everything you need is in the task packet; if something is genuinely missing, state the assumption you made and proceed. Keep going until the job is fully done. Work in PARALLEL where steps are independent: batch your reads/greps/searches into a single message (multiple tool calls, ~3–5 at a time — parallel is ~3–5x faster than one-at-a-time); go sequential only when one call genuinely needs another's output. Report high-signal results only (the output + the few facts that matter, not a play-by-play). Do not create report files; report back as your final message.`, SKILL_SEEKING = `Before starting, check whether a skill (via the Skill tool) is relevant to this task and would improve the result — if so, use it. Any available skill is usable: rayu ships bundled skills (e.g. rayu-frontend-design, rayu-design-system, rayu-web-testing, rayu-api-design, rayu-mcp-builder, rayu-doc-export) with no install; you may also use any skill the user installed, or install a relevant one on demand from the official Anthropic skills repo (anthropics/skills) via the InstallSkill tool. If none apply, proceed without one.`;
271531
271531
 
271532
271532
  // src/tools/AgentTool/built-in/subagents/asset-generation.ts
271533
271533
  function getAssetGenSystemPrompt() {
@@ -271537,6 +271537,8 @@ ${EPHEMERAL_FRAMING}
271537
271537
 
271538
271538
  ${SKILL_SEEKING}
271539
271539
 
271540
+ The bundled \`rayu-algorithmic-art\` and \`rayu-canvas-design\` skills are directly relevant to this work — pull them via the Skill tool.
271541
+
271540
271542
  ## Your job (from the task packet)
271541
271543
  - Generate the requested images (hero backgrounds, illustrations, product/teaser imagery, etc.) using the image generation tool.
271542
271544
  - Match the EXACT style, mood, color palette, and dimensions from the Design PRD / packet.
@@ -271571,6 +271573,8 @@ ${EPHEMERAL_FRAMING}
271571
271573
 
271572
271574
  ${SKILL_SEEKING}
271573
271575
 
271576
+ The bundled \`rayu-api-design\` skill is directly relevant to this work — pull it via the Skill tool before defining the contract.
271577
+
271574
271578
  ## Your job
271575
271579
  Define, precisely and concretely, the backend contract so every downstream agent builds against the SAME shapes:
271576
271580
 
@@ -271616,6 +271620,8 @@ ${EPHEMERAL_FRAMING}
271616
271620
 
271617
271621
  ${SKILL_SEEKING}
271618
271622
 
271623
+ The bundled \`rayu-frontend-design\`, \`rayu-design-system\`, \`rayu-theme-factory\`, and \`rayu-brand-guidelines\` skills are directly relevant to this work — pull them via the Skill tool before designing.
271624
+
271619
271625
  ## Your job
271620
271626
  Define, precisely and concretely, the visual + interaction system so every downstream agent can build pixel-perfect without guessing:
271621
271627
  - **Color palette** — exact hex codes (background, surface, text, accents, states).
@@ -272285,7 +272291,7 @@ function buildCollaboratorPrompt(s2) {
272285
272291
  "## How you work",
272286
272292
  "- You implement AND iterate: write real, production-ready code/config in your domain and refine until it meets the brief. You have the full toolset; request permission for sensitive actions through the normal permission flow.",
272287
272293
  "- Work in PARALLEL where independent: batch reads/greps and independent edits into one message (multiple tool calls, ~3–5 at a time) — parallel is ~3–5x faster. Go sequential only on a true dependency.",
272288
- `- Seek relevant INSTALLED skills (via the Skill tool) that improve your output — ${s2.skillHint}. Skills are installed by the user via /install-skill or /find-skill; if none are installed, proceed without one.`,
272294
+ `- Use the relevant skill (via the Skill tool) to raise your output quality — ${s2.skillHint}. rayu ships these as BUNDLED skills (always available, no install needed). You may ALSO use any skill the user installed, or install a relevant one on demand from the official Anthropic skills repo (anthropics/skills) via the InstallSkill tool. If none apply, proceed without one.`,
272289
272295
  "- You may use MCP servers and dispatch the Tier-3 subagents (e.g. asset-generation, review, fix, linter) for atomic jobs — the same subagents the orchestrator uses.",
272290
272296
  "- Be autonomous: keep going until your piece is complete; state assumptions and continue rather than stopping for approval unless genuinely blocked.",
272291
272297
  "",
@@ -272377,7 +272383,7 @@ var init_backend = __esm(() => {
272377
272383
  title: "Backend Collaborator",
272378
272384
  whenToUse: "Server-side implementation: API routes/services/business logic, AND the data layer (schema, models, migrations, queries). Implements the security/auth flow. Builds and iterates on real backend + database code.",
272379
272385
  role: "You build the backend end-to-end: API endpoints, the service layer and business logic, middleware/error handling, env config, and the data layer (schema design, models, relations, indexes, migrations). You implement the auth/security flow that the security collaborator defines.",
272380
- skillHint: "e.g. an API-design skill for clean, consistent endpoint and schema design",
272386
+ skillHint: "the bundled rayu-api-design skill for clean endpoint/schema contracts, and rayu-mcp-builder when building an MCP server",
272381
272387
  withStackAwareness: true,
272382
272388
  allowedSubagents: [
272383
272389
  "backend-design",
@@ -272407,7 +272413,7 @@ var init_deploy = __esm(() => {
272407
272413
  title: "Deploy Collaborator",
272408
272414
  whenToUse: "DevOps & deployment: containerization, CI/CD, environment/secrets config, build pipelines, and shipping to the hosting target. Runs the production build, fixes build errors, and iterates until the app is deployable/live.",
272409
272415
  role: "You package and ship what the other collaborators built: Dockerfile/compose, CI/CD pipeline, environment and secrets configuration, health checks, and deployment to the target platform. You run the production build, resolve build errors, and iterate until deployment succeeds, then report the result/URL.",
272410
- skillHint: "e.g. a deployment/CI skill for the target platform (Docker, Vercel, etc.)",
272416
+ skillHint: "the bundled rayu-web-testing skill for post-deploy smoke checks, plus any deployment/CI skill for the target platform (Docker, Vercel, etc.)",
272411
272417
  allowedSubagents: ["review", "fix", "linter", "Explore", "general-purpose"],
272412
272418
  owns: [
272413
272419
  "Dockerfile (multi-stage) and docker-compose",
@@ -272429,7 +272435,7 @@ var init_frontend = __esm(() => {
272429
272435
  title: "Frontend Collaborator",
272430
272436
  whenToUse: "Web UI implementation: page/screen architecture, components, state management, styling/design-system, animations, and API integration against the backend. Builds and iterates on real frontend code.",
272431
272437
  role: "You build the web frontend end-to-end against the design and the backend contracts: page structure and navigation, the component tree, state management, the design system (tokens, spacing, typography), motion/interactions, and wiring to the API. You produce working, production-ready UI — not just layouts.",
272432
- skillHint: "e.g. a UI/UX design skill such as ui-ux-pro-max for stronger visual/UX decisions",
272438
+ skillHint: "the bundled rayu-frontend-design, rayu-design-system, and rayu-web-artifacts-builder skills for strong visual/UX decisions, a consistent token system, and self-contained interactive artifacts",
272433
272439
  withStackAwareness: true,
272434
272440
  allowedSubagents: [
272435
272441
  "design",
@@ -272461,7 +272467,7 @@ var init_mobile = __esm(() => {
272461
272467
  title: "Mobile Collaborator",
272462
272468
  whenToUse: "Mobile app implementation (Flutter-first, fallback React Native): screens, navigation, state, the API/auth layer against the backend, and offline strategy. Builds and iterates on real mobile code.",
272463
272469
  role: "You build the mobile app against the backend contracts and the auth flow: screen architecture and navigation, state management, the API service layer, auth implementation, and offline support. You produce working, production-ready mobile code.",
272464
- skillHint: "e.g. a mobile/Flutter UI skill for idiomatic screens and navigation",
272470
+ skillHint: "the bundled rayu-frontend-design and rayu-design-system skills for idiomatic UI and a consistent token system",
272465
272471
  withStackAwareness: true,
272466
272472
  allowedSubagents: [
272467
272473
  "design",
@@ -272493,7 +272499,7 @@ var init_security = __esm(() => {
272493
272499
  title: "Security Collaborator",
272494
272500
  whenToUse: "Security work: design AND implement auth/authorization (RBAC), input validation, secret/sensitive-data handling, and harden endpoints. Reviews other collaborators’ code for vulnerabilities and fixes them. Its security decisions are authoritative.",
272495
272501
  role: "You own security end-to-end: design the auth flow and authorization model, then implement and enforce it — guards/middleware, validation, secret handling, security headers, and OWASP Top-10 hardening. You also audit the backend/frontend for vulnerabilities and fix them. Your security decisions are the source of truth and override convenience.",
272496
- skillHint: "e.g. a security-review or OWASP skill for systematic threat coverage",
272502
+ skillHint: "the bundled rayu-web-testing skill to verify behavior, plus any installed OWASP/security-review skill for systematic threat coverage",
272497
272503
  allowedSubagents: [
272498
272504
  "backend-design",
272499
272505
  "review",
@@ -273371,7 +273377,7 @@ var init_prompt5 = __esm(() => {
273371
273377
  getPrompt = memoize_default(async (_cwd) => {
273372
273378
  return `Execute a skill within the main conversation
273373
273379
 
273374
- When users ask you to perform tasks, check if any of the available skills match. Skills provide specialized capabilities and domain knowledge.
273380
+ When users ask you to perform tasks, check if any of the available skills match. Skills provide specialized capabilities and domain knowledge. Any available skill is usable whenever it helps — rayu's bundled skills, any skill the user has installed, and MCP skills — there is no per-task restriction on which you may invoke.
273375
273381
 
273376
273382
  When users reference a "slash command" or "/<something>" (e.g., "/commit", "/review-pr"), they are referring to a skill. Use this tool to invoke it.
273377
273383
 
@@ -273385,6 +273391,7 @@ How to invoke:
273385
273391
 
273386
273392
  Important:
273387
273393
  - Available skills are listed in system-reminder messages in the conversation
273394
+ - Beyond the listed skills, you may install a relevant one on demand from the official Anthropic skills repository (\`anthropics/skills\`) or any other source — via the InstallSkill tool or \`/install-skill anthropics/skills/skills/<name>\` — and then invoke it
273388
273395
  - When a skill matches the user's request, this is a BLOCKING REQUIREMENT: invoke the relevant Skill tool BEFORE generating any other response about the task
273389
273396
  - NEVER mention a skill without actually calling this tool
273390
273397
  - Do not invoke a skill that is already running
@@ -281032,9 +281039,15 @@ var init_claudemd = __esm(() => {
281032
281039
  init_settings2();
281033
281040
  import_ignore2 = __toESM(require_ignore(), 1);
281034
281041
  import_picomatch = __toESM(require_picomatch2(), 1);
281035
- PROJECT_MEMORY_FILENAMES = ["RAYU.md", "AGENTS.md", "CLAUDE.md"];
281036
- PROJECT_CONFIG_DIRS = [".rayu", ".agents"];
281042
+ PROJECT_MEMORY_FILENAMES = [
281043
+ "RAYU.md",
281044
+ "AGENTS.md",
281045
+ "AGENT.md",
281046
+ "CLAUDE.md"
281047
+ ];
281048
+ PROJECT_CONFIG_DIRS = [".rayu", ".agents", "claude"];
281037
281049
  TEXT_FILE_EXTENSIONS = new Set([
281050
+ ".env",
281038
281051
  ".md",
281039
281052
  ".txt",
281040
281053
  ".text",
@@ -281441,6 +281454,13 @@ function getClaudeCodeSkillsDirIfEnabled() {
281441
281454
  return;
281442
281455
  return getClaudeCodeSkillsDir();
281443
281456
  }
281457
+ function getProjectClaudeSkillsDirIfEnabled() {
281458
+ const settings = getInitialSettings();
281459
+ const enabled2 = settings.claudeSkillsEnabled !== false;
281460
+ if (!enabled2)
281461
+ return;
281462
+ return existingDir(join58(getCwd(), ".claude", "skills"));
281463
+ }
281444
281464
  function getExtraSkillDirsFromSettings() {
281445
281465
  const settings = getInitialSettings();
281446
281466
  const raw = settings.extraSkillDirs;
@@ -281463,6 +281483,9 @@ function getExternalSkillDirs() {
281463
281483
  const claudeDir = getClaudeCodeSkillsDirIfEnabled();
281464
281484
  if (claudeDir)
281465
281485
  candidates.push(claudeDir);
281486
+ const projectClaudeDir = getProjectClaudeSkillsDirIfEnabled();
281487
+ if (projectClaudeDir)
281488
+ candidates.push(projectClaudeDir);
281466
281489
  candidates.push(...getExtraSkillDirsFromSettings());
281467
281490
  candidates.push(...getExtraSkillDirsFromEnv());
281468
281491
  const seen = new Set;
@@ -281482,6 +281505,7 @@ var init_externalSkillDiscovery = __esm(() => {
281482
281505
  init_debug();
281483
281506
  init_fsOperations();
281484
281507
  init_settings2();
281508
+ init_cwd2();
281485
281509
  });
281486
281510
 
281487
281511
  // src/utils/argumentSubstitution.ts
@@ -305309,7 +305333,7 @@ function getTelemetryAttributes() {
305309
305333
  attributes["session.id"] = sessionId;
305310
305334
  }
305311
305335
  if (shouldIncludeAttribute("OTEL_METRICS_INCLUDE_VERSION")) {
305312
- attributes["app.version"] = "1.3.434";
305336
+ attributes["app.version"] = "1.3.435";
305313
305337
  }
305314
305338
  const oauthAccount = getOauthAccountInfo();
305315
305339
  if (oauthAccount) {
@@ -410535,6 +410559,7 @@ var init_mcpPluginIntegration = __esm(() => {
410535
410559
 
410536
410560
  // src/services/mcp/config.ts
410537
410561
  import { chmod as chmod2, open as open8, rename as rename3, stat as stat21, unlink as unlink6 } from "fs/promises";
410562
+ import { homedir as homedir21 } from "os";
410538
410563
  import { dirname as dirname33, join as join71, parse as parse10 } from "path";
410539
410564
  function getEnterpriseMcpFilePath() {
410540
410565
  return join71(getManagedFilePath(), "managed-mcp.json");
@@ -411111,6 +411136,49 @@ function getMcpConfigByName(name) {
411111
411136
  }
411112
411137
  return null;
411113
411138
  }
411139
+ function getClaudeFallbackMcpServers() {
411140
+ const settings = getInitialSettings();
411141
+ if (settings.claudeMcpEnabled === false)
411142
+ return {};
411143
+ const fs13 = getFsImplementation();
411144
+ const cwd2 = getCwd();
411145
+ const home = homedir21();
411146
+ const readJson = (path19) => {
411147
+ try {
411148
+ const parsed = safeParseJSON(fs13.readFileSync(path19, { encoding: "utf8" }));
411149
+ return parsed && typeof parsed === "object" ? parsed : null;
411150
+ } catch {
411151
+ return null;
411152
+ }
411153
+ };
411154
+ const rawSources = [];
411155
+ const claudeJson = readJson(join71(home, ".claude.json"));
411156
+ if (claudeJson) {
411157
+ rawSources.push(claudeJson.mcpServers);
411158
+ const projects = claudeJson.projects;
411159
+ rawSources.push(projects?.[cwd2]?.mcpServers);
411160
+ }
411161
+ for (const p of [
411162
+ join71(cwd2, ".claude", "settings.json"),
411163
+ join71(home, ".claude", "settings.json")
411164
+ ]) {
411165
+ const s2 = readJson(p);
411166
+ if (s2)
411167
+ rawSources.push(s2.mcpServers);
411168
+ }
411169
+ const validated = {};
411170
+ for (const raw of rawSources) {
411171
+ if (!raw || typeof raw !== "object")
411172
+ continue;
411173
+ for (const [name, cfg] of Object.entries(raw)) {
411174
+ const parsed = McpServerConfigSchema().safeParse(cfg);
411175
+ if (parsed.success) {
411176
+ validated[name] = parsed.data;
411177
+ }
411178
+ }
411179
+ }
411180
+ return addScopeToServers(validated, "user");
411181
+ }
411114
411182
  async function getRayuMcpConfigs(dynamicServers = {}) {
411115
411183
  const { servers: enterpriseServers } = getMcpConfigsByScope("enterprise");
411116
411184
  if (doesEnterpriseMcpConfigExist()) {
@@ -411130,6 +411198,7 @@ async function getRayuMcpConfigs(dynamicServers = {}) {
411130
411198
  const { servers: userServers } = mcpLocked ? noServers : getMcpConfigsByScope("user");
411131
411199
  const { servers: projectServers } = mcpLocked ? noServers : getMcpConfigsByScope("project");
411132
411200
  const { servers: localServers } = mcpLocked ? noServers : getMcpConfigsByScope("local");
411201
+ const claudeFallbackServers = mcpLocked ? {} : getClaudeFallbackMcpServers();
411133
411202
  const pluginMcpServers = {};
411134
411203
  const pluginResult = await loadAllPluginsCacheOnly();
411135
411204
  const mcpErrors = [];
@@ -411196,7 +411265,7 @@ async function getRayuMcpConfigs(dynamicServers = {}) {
411196
411265
  duplicateOf
411197
411266
  });
411198
411267
  }
411199
- const configs = Object.assign({}, dedupedPluginServers, userServers, approvedProjectServers, localServers);
411268
+ const configs = Object.assign({}, claudeFallbackServers, dedupedPluginServers, userServers, approvedProjectServers, localServers);
411200
411269
  const filtered = {};
411201
411270
  for (const [name, serverConfig] of Object.entries(configs)) {
411202
411271
  if (!isMcpServerAllowedByPolicy(name, serverConfig)) {
@@ -414192,10 +414261,10 @@ var init_capitalize = __esm(() => {
414192
414261
  });
414193
414262
 
414194
414263
  // src/utils/jetbrains.ts
414195
- import { homedir as homedir21, platform as platform2 } from "os";
414264
+ import { homedir as homedir22, platform as platform2 } from "os";
414196
414265
  import { join as join75 } from "path";
414197
414266
  function buildCommonPluginDirectoryPaths(ideName) {
414198
- const homeDir = homedir21();
414267
+ const homeDir = homedir22();
414199
414268
  const directories = [];
414200
414269
  const idePatterns = ideNameToDirMap[ideName.toLowerCase()];
414201
414270
  if (!idePatterns) {
@@ -415619,7 +415688,7 @@ function getInstallationEnv() {
415619
415688
  return;
415620
415689
  }
415621
415690
  function getClaudeCodeVersion() {
415622
- return "1.3.434";
415691
+ return "1.3.435";
415623
415692
  }
415624
415693
  async function getInstalledVSCodeExtensionVersion(command) {
415625
415694
  const { stdout } = await execFileNoThrow(command, ["--list-extensions", "--show-versions"], {
@@ -420857,7 +420926,7 @@ async function setupSdkMcpClients(sdkMcpConfigs, sendMcpMessage) {
420857
420926
  const client4 = new Client({
420858
420927
  name: "claude-code",
420859
420928
  title: "RAYU",
420860
- version: "1.3.434",
420929
+ version: "1.3.435",
420861
420930
  description: "Anthropic's agentic coding tool",
420862
420931
  websiteUrl: PRODUCT_URL
420863
420932
  }, {
@@ -421174,7 +421243,7 @@ var init_client7 = __esm(() => {
421174
421243
  const client4 = new Client({
421175
421244
  name: "claude-code",
421176
421245
  title: "RAYU",
421177
- version: "1.3.434",
421246
+ version: "1.3.435",
421178
421247
  description: "Anthropic's agentic coding tool",
421179
421248
  websiteUrl: PRODUCT_URL
421180
421249
  }, {
@@ -435979,7 +436048,7 @@ function computeFingerprint(messageText, version2) {
435979
436048
  }
435980
436049
  function computeFingerprintFromMessages(messages) {
435981
436050
  const firstMessageText = extractFirstMessageText(messages);
435982
- return computeFingerprint(firstMessageText, "1.3.434");
436051
+ return computeFingerprint(firstMessageText, "1.3.435");
435983
436052
  }
435984
436053
  var FINGERPRINT_SALT = "59cf53e54c78";
435985
436054
  var init_fingerprint = () => {};
@@ -436021,7 +436090,7 @@ async function sideQuery(opts) {
436021
436090
  betas.push(STRUCTURED_OUTPUTS_BETA_HEADER);
436022
436091
  }
436023
436092
  const messageText = extractFirstUserMessageText(messages);
436024
- const fingerprint = computeFingerprint(messageText, "1.3.434");
436093
+ const fingerprint = computeFingerprint(messageText, "1.3.435");
436025
436094
  const attributionHeader = getAttributionHeader(fingerprint);
436026
436095
  const systemBlocks = [
436027
436096
  attributionHeader ? { type: "text", text: attributionHeader } : null,
@@ -458917,7 +458986,7 @@ var init_InProcessBackend = __esm(() => {
458917
458986
  });
458918
458987
 
458919
458988
  // src/utils/swarm/backends/it2Setup.ts
458920
- import { homedir as homedir23 } from "os";
458989
+ import { homedir as homedir24 } from "os";
458921
458990
  async function detectPythonPackageManager() {
458922
458991
  const uvResult = await execFileNoThrow("which", ["uv"]);
458923
458992
  if (uvResult.code === 0) {
@@ -458952,18 +459021,18 @@ async function installIt2(packageManager) {
458952
459021
  switch (packageManager) {
458953
459022
  case "uvx":
458954
459023
  result = await execFileNoThrowWithCwd("uv", ["tool", "install", "it2"], {
458955
- cwd: homedir23()
459024
+ cwd: homedir24()
458956
459025
  });
458957
459026
  break;
458958
459027
  case "pipx":
458959
459028
  result = await execFileNoThrowWithCwd("pipx", ["install", "it2"], {
458960
- cwd: homedir23()
459029
+ cwd: homedir24()
458961
459030
  });
458962
459031
  break;
458963
459032
  case "pip":
458964
- result = await execFileNoThrowWithCwd("pip", ["install", "--user", "it2"], { cwd: homedir23() });
459033
+ result = await execFileNoThrowWithCwd("pip", ["install", "--user", "it2"], { cwd: homedir24() });
458965
459034
  if (result.code !== 0) {
458966
- result = await execFileNoThrowWithCwd("pip3", ["install", "--user", "it2"], { cwd: homedir23() });
459035
+ result = await execFileNoThrowWithCwd("pip3", ["install", "--user", "it2"], { cwd: homedir24() });
458967
459036
  }
458968
459037
  break;
458969
459038
  }
@@ -467784,7 +467853,7 @@ ${result.result}`
467784
467853
  // src/skills/installSkill.ts
467785
467854
  import { randomUUID as randomUUID21 } from "crypto";
467786
467855
  import { cp as cp2, mkdir as mkdir19, mkdtemp as mkdtemp3, readFile as readFile24, readdir as readdir13, rename as rename4, rm as rm7, stat as stat24, writeFile as writeFile17 } from "fs/promises";
467787
- import { homedir as homedir24, tmpdir as tmpdir10 } from "os";
467856
+ import { homedir as homedir25, tmpdir as tmpdir10 } from "os";
467788
467857
  import { basename as basename27, isAbsolute as isAbsolute27, join as join91, resolve as resolve38, sep as sep25 } from "path";
467789
467858
  function sanitizeSkillName(raw) {
467790
467859
  const name = raw.trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^[-.]+|[-.]+$/g, "");
@@ -467936,9 +468005,9 @@ async function installSkillFromSource(rawSource, options = {}) {
467936
468005
  }
467937
468006
  function expandHome(p) {
467938
468007
  if (p === "~")
467939
- return homedir24();
468008
+ return homedir25();
467940
468009
  if (p.startsWith("~/"))
467941
- return join91(homedir24(), p.slice(2));
468010
+ return join91(homedir25(), p.slice(2));
467942
468011
  return p;
467943
468012
  }
467944
468013
  function firstLine(markdown) {
@@ -526445,7 +526514,7 @@ var init_projectOnboardingState = __esm(() => {
526445
526514
 
526446
526515
  // src/utils/appleTerminalBackup.ts
526447
526516
  import { stat as stat35 } from "fs/promises";
526448
- import { homedir as homedir25 } from "os";
526517
+ import { homedir as homedir26 } from "os";
526449
526518
  import { join as join111 } from "path";
526450
526519
  function markTerminalSetupInProgress(backupPath) {
526451
526520
  saveGlobalConfig((current) => ({
@@ -526468,7 +526537,7 @@ function getTerminalRecoveryInfo() {
526468
526537
  };
526469
526538
  }
526470
526539
  function getTerminalPlistPath() {
526471
- return join111(homedir25(), "Library", "Preferences", "com.apple.Terminal.plist");
526540
+ return join111(homedir26(), "Library", "Preferences", "com.apple.Terminal.plist");
526472
526541
  }
526473
526542
  async function backupTerminalPreferences() {
526474
526543
  const terminalPlistPath = getTerminalPlistPath();
@@ -526562,7 +526631,7 @@ __export(exports_terminalSetup, {
526562
526631
  });
526563
526632
  import { randomBytes as randomBytes14 } from "crypto";
526564
526633
  import { copyFile as copyFile8, mkdir as mkdir28, readFile as readFile36, writeFile as writeFile28 } from "fs/promises";
526565
- import { homedir as homedir26, platform as platform3 } from "os";
526634
+ import { homedir as homedir27, platform as platform3 } from "os";
526566
526635
  import { dirname as dirname54, join as join112 } from "path";
526567
526636
  import { pathToFileURL as pathToFileURL7 } from "url";
526568
526637
  function isVSCodeRemoteSSH() {
@@ -526698,7 +526767,7 @@ async function installBindingsForVSCodeTerminal(editor = "VSCode", theme) {
526698
526767
  ]`)}${EOL6}`;
526699
526768
  }
526700
526769
  const editorDir = editor === "VSCode" ? "Code" : editor;
526701
- const userDirPath = join112(homedir26(), platform3() === "win32" ? join112("AppData", "Roaming", editorDir, "User") : platform3() === "darwin" ? join112("Library", "Application Support", editorDir, "User") : join112(".config", editorDir, "User"));
526770
+ const userDirPath = join112(homedir27(), platform3() === "win32" ? join112("AppData", "Roaming", editorDir, "User") : platform3() === "darwin" ? join112("Library", "Application Support", editorDir, "User") : join112(".config", editorDir, "User"));
526702
526771
  const keybindingsPath = join112(userDirPath, "keybindings.json");
526703
526772
  try {
526704
526773
  await mkdir28(userDirPath, {
@@ -526842,7 +526911,7 @@ chars = "\\u001B\\r"`;
526842
526911
  if (xdgConfigHome) {
526843
526912
  configPaths.push(join112(xdgConfigHome, "alacritty", "alacritty.toml"));
526844
526913
  } else {
526845
- configPaths.push(join112(homedir26(), ".config", "alacritty", "alacritty.toml"));
526914
+ configPaths.push(join112(homedir27(), ".config", "alacritty", "alacritty.toml"));
526846
526915
  }
526847
526916
  if (platform3() === "win32") {
526848
526917
  const appData = process.env.APPDATA;
@@ -526908,7 +526977,7 @@ chars = "\\u001B\\r"`;
526908
526977
  }
526909
526978
  }
526910
526979
  async function installBindingsForZed(theme) {
526911
- const zedDir = join112(homedir26(), ".config", "zed");
526980
+ const zedDir = join112(homedir27(), ".config", "zed");
526912
526981
  const keymapPath = join112(zedDir, "keymap.json");
526913
526982
  try {
526914
526983
  await mkdir28(zedDir, {
@@ -531012,7 +531081,7 @@ function Feedback({
531012
531081
  platform: env4.platform,
531013
531082
  gitRepo: envInfo.isGit,
531014
531083
  terminal: env4.terminal,
531015
- version: "1.3.434",
531084
+ version: "1.3.435",
531016
531085
  transcript: normalizeMessagesForAPI(messages),
531017
531086
  errors: sanitizedErrors,
531018
531087
  lastApiRequest: getLastAPIRequest(),
@@ -531204,7 +531273,7 @@ function Feedback({
531204
531273
  ", ",
531205
531274
  env4.terminal,
531206
531275
  ", v",
531207
- "1.3.434"
531276
+ "1.3.435"
531208
531277
  ]
531209
531278
  }, undefined, true, undefined, this)
531210
531279
  ]
@@ -531310,7 +531379,7 @@ ${sanitizedDescription}
531310
531379
  ` + `**Environment Info**
531311
531380
  ` + `- Platform: ${env4.platform}
531312
531381
  ` + `- Terminal: ${env4.terminal}
531313
- ` + `- Version: ${"1.3.434"}
531382
+ ` + `- Version: ${"1.3.435"}
531314
531383
  ` + `- Feedback ID: ${feedbackId}
531315
531384
  ` + `
531316
531385
  **Errors**
@@ -534144,15 +534213,15 @@ var init_shellConfig = __esm(() => {
534144
534213
  // src/utils/autoUpdater.ts
534145
534214
  import { constants as fsConstants3 } from "fs";
534146
534215
  import { access as access5, writeFile as writeFile33 } from "fs/promises";
534147
- import { homedir as homedir27 } from "os";
534216
+ import { homedir as homedir28 } from "os";
534148
534217
  import { join as join121 } from "path";
534149
534218
  async function assertMinVersion() {
534150
534219
  if (false) {}
534151
534220
  try {
534152
534221
  const versionConfig = await getDynamicConfig_BLOCKS_ON_INIT("tengu_version_config", { minVersion: "0.0.0" });
534153
- if (versionConfig.minVersion && lt("1.3.434", versionConfig.minVersion)) {
534222
+ if (versionConfig.minVersion && lt("1.3.435", versionConfig.minVersion)) {
534154
534223
  console.error(`
534155
- It looks like your version of RAYU (${"1.3.434"}) needs an update.
534224
+ It looks like your version of RAYU (${"1.3.435"}) needs an update.
534156
534225
  A newer version (${versionConfig.minVersion} or higher) is required to continue.
534157
534226
 
534158
534227
  To update, please run:
@@ -534277,10 +534346,10 @@ async function getInstallationPrefix() {
534277
534346
  let prefixResult = null;
534278
534347
  if (isBun) {
534279
534348
  prefixResult = await execFileNoThrowWithCwd("bun", ["pm", "bin", "-g"], {
534280
- cwd: homedir27()
534349
+ cwd: homedir28()
534281
534350
  });
534282
534351
  } else {
534283
- prefixResult = await execFileNoThrowWithCwd("npm", ["-g", "config", "get", "prefix"], { cwd: homedir27() });
534352
+ prefixResult = await execFileNoThrowWithCwd("npm", ["-g", "config", "get", "prefix"], { cwd: homedir28() });
534284
534353
  }
534285
534354
  if (prefixResult.code !== 0) {
534286
534355
  logError2(new Error(`Failed to check ${isBun ? "bun" : "npm"} permissions`));
@@ -534308,7 +534377,7 @@ async function checkGlobalInstallPermissions() {
534308
534377
  }
534309
534378
  async function getLatestVersion(channel) {
534310
534379
  const npmTag = channel === "stable" ? "stable" : "latest";
534311
- const result = await execFileNoThrowWithCwd("npm", ["view", `${"@rayu-dev/rayu-cli"}@${npmTag}`, "version", "--prefer-online"], { abortSignal: AbortSignal.timeout(5000), cwd: homedir27() });
534380
+ const result = await execFileNoThrowWithCwd("npm", ["view", `${"@rayu-dev/rayu-cli"}@${npmTag}`, "version", "--prefer-online"], { abortSignal: AbortSignal.timeout(5000), cwd: homedir28() });
534312
534381
  if (result.code !== 0) {
534313
534382
  logForDebugging(`npm view failed with code ${result.code}`);
534314
534383
  if (result.stderr) {
@@ -534324,7 +534393,7 @@ async function getLatestVersion(channel) {
534324
534393
  return result.stdout.trim();
534325
534394
  }
534326
534395
  async function getNpmDistTags() {
534327
- const result = await execFileNoThrowWithCwd("npm", ["view", "@rayu-dev/rayu-cli", "dist-tags", "--json", "--prefer-online"], { abortSignal: AbortSignal.timeout(5000), cwd: homedir27() });
534396
+ const result = await execFileNoThrowWithCwd("npm", ["view", "@rayu-dev/rayu-cli", "dist-tags", "--json", "--prefer-online"], { abortSignal: AbortSignal.timeout(5000), cwd: homedir28() });
534328
534397
  if (result.code !== 0) {
534329
534398
  logForDebugging(`npm view dist-tags failed with code ${result.code}`);
534330
534399
  return { latest: null, stable: null };
@@ -534378,7 +534447,7 @@ async function installGlobalPackage(specificVersion) {
534378
534447
  logError2(new AutoUpdaterError("Another process is currently installing an update"));
534379
534448
  logEvent("tengu_auto_updater_lock_contention", {
534380
534449
  pid: process.pid,
534381
- currentVersion: "1.3.434"
534450
+ currentVersion: "1.3.435"
534382
534451
  });
534383
534452
  return "in_progress";
534384
534453
  }
@@ -534387,7 +534456,7 @@ async function installGlobalPackage(specificVersion) {
534387
534456
  if (!env4.isRunningWithBun() && env4.isNpmFromWindowsPath()) {
534388
534457
  logError2(new Error("Windows NPM detected in WSL environment"));
534389
534458
  logEvent("tengu_auto_updater_windows_npm_in_wsl", {
534390
- currentVersion: "1.3.434"
534459
+ currentVersion: "1.3.435"
534391
534460
  });
534392
534461
  console.error(`
534393
534462
  Error: Windows NPM detected in WSL
@@ -534408,7 +534477,7 @@ To fix this issue:
534408
534477
  }
534409
534478
  const packageSpec = specificVersion ? `${"@rayu-dev/rayu-cli"}@${specificVersion}` : "@rayu-dev/rayu-cli";
534410
534479
  const packageManager = env4.isRunningWithBun() ? "bun" : "npm";
534411
- const installResult = await execFileNoThrowWithCwd(packageManager, ["install", "-g", packageSpec], { cwd: homedir27() });
534480
+ const installResult = await execFileNoThrowWithCwd(packageManager, ["install", "-g", packageSpec], { cwd: homedir28() });
534412
534481
  if (installResult.code !== 0) {
534413
534482
  const error54 = new AutoUpdaterError(`Failed to install new version of claude: ${installResult.stdout} ${installResult.stderr}`);
534414
534483
  logError2(error54);
@@ -534646,7 +534715,7 @@ var init_packageManagers = __esm(() => {
534646
534715
 
534647
534716
  // src/utils/doctorDiagnostic.ts
534648
534717
  import { readFile as readFile41, realpath as realpath11 } from "fs/promises";
534649
- import { homedir as homedir28 } from "os";
534718
+ import { homedir as homedir29 } from "os";
534650
534719
  import { delimiter as delimiter3, join as join122, posix as posix6, win32 as win323 } from "path";
534651
534720
  function getNormalizedPaths() {
534652
534721
  let invokedPath = process.argv[1] || "";
@@ -534710,8 +534779,8 @@ async function getInstallationPath() {
534710
534779
  }
534711
534780
  } catch {}
534712
534781
  try {
534713
- await getFsImplementation().stat(join122(homedir28(), ".local/bin/claude"));
534714
- return join122(homedir28(), ".local/bin/claude");
534782
+ await getFsImplementation().stat(join122(homedir29(), ".local/bin/claude"));
534783
+ return join122(homedir29(), ".local/bin/claude");
534715
534784
  } catch {}
534716
534785
  return "native";
534717
534786
  }
@@ -534781,14 +534850,14 @@ async function detectMultipleInstallations() {
534781
534850
  }
534782
534851
  }
534783
534852
  }
534784
- const nativeBinPath = join122(homedir28(), ".local", "bin", "claude");
534853
+ const nativeBinPath = join122(homedir29(), ".local", "bin", "claude");
534785
534854
  try {
534786
534855
  await fs14.stat(nativeBinPath);
534787
534856
  installations.push({ type: "native", path: nativeBinPath });
534788
534857
  } catch {}
534789
534858
  const config4 = getGlobalConfig();
534790
534859
  if (config4.installMethod === "native") {
534791
- const nativeDataPath = join122(homedir28(), ".local", "share", "claude");
534860
+ const nativeDataPath = join122(homedir29(), ".local", "share", "claude");
534792
534861
  try {
534793
534862
  await fs14.stat(nativeDataPath);
534794
534863
  if (!installations.some((i4) => i4.type === "native")) {
@@ -534828,7 +534897,7 @@ async function detectConfigurationIssues(type) {
534828
534897
  if (type === "native") {
534829
534898
  const path25 = process.env.PATH || "";
534830
534899
  const pathDirectories = path25.split(delimiter3);
534831
- const homeDir = homedir28();
534900
+ const homeDir = homedir29();
534832
534901
  const localBinPath = join122(homeDir, ".local", "bin");
534833
534902
  let normalizedLocalBinPath = localBinPath;
534834
534903
  if (getPlatform() === "windows") {
@@ -534855,7 +534924,7 @@ async function detectConfigurationIssues(type) {
534855
534924
  const shellType = getShellType();
534856
534925
  const configPaths = getShellConfigPaths();
534857
534926
  const configFile = configPaths[shellType];
534858
- const displayPath = configFile ? configFile.replace(homedir28(), "~") : "your shell config file";
534927
+ const displayPath = configFile ? configFile.replace(homedir29(), "~") : "your shell config file";
534859
534928
  warnings.push({
534860
534929
  issue: "Native installation exists but ~/.local/bin is not in your PATH",
534861
534930
  fix: `Run: echo 'export PATH="$HOME/.local/bin:$PATH"' >> ${displayPath} then open a new terminal or run: source ${displayPath}`
@@ -534923,7 +534992,7 @@ function detectLinuxGlobPatternWarnings() {
534923
534992
  }
534924
534993
  async function getDoctorDiagnostic() {
534925
534994
  const installationType = await getCurrentInstallationType();
534926
- const version2 = typeof MACRO !== "undefined" ? "1.3.434" : "unknown";
534995
+ const version2 = typeof MACRO !== "undefined" ? "1.3.435" : "unknown";
534927
534996
  const installationPath = await getInstallationPath();
534928
534997
  const invokedBinary = getInvokedBinary();
534929
534998
  const multipleInstallations = await detectMultipleInstallations();
@@ -535454,7 +535523,7 @@ import {
535454
535523
  unlink as unlink16,
535455
535524
  writeFile as writeFile35
535456
535525
  } from "fs/promises";
535457
- import { homedir as homedir29 } from "os";
535526
+ import { homedir as homedir30 } from "os";
535458
535527
  import { basename as basename41, delimiter as delimiter4, dirname as dirname57, join as join126, resolve as resolve45 } from "path";
535459
535528
  function getPlatform3() {
535460
535529
  const os7 = env4.platform;
@@ -535718,8 +535787,8 @@ async function updateLatest(channelOrVersion, forceReinstall = false) {
535718
535787
  const maxVersion = await getMaxVersion();
535719
535788
  if (maxVersion && gt(version2, maxVersion)) {
535720
535789
  logForDebugging(`Native installer: maxVersion ${maxVersion} is set, capping update from ${version2} to ${maxVersion}`);
535721
- if (gte("1.3.434", maxVersion)) {
535722
- logForDebugging(`Native installer: current version ${"1.3.434"} is already at or above maxVersion ${maxVersion}, skipping update`);
535790
+ if (gte("1.3.435", maxVersion)) {
535791
+ logForDebugging(`Native installer: current version ${"1.3.435"} is already at or above maxVersion ${maxVersion}, skipping update`);
535723
535792
  logEvent("tengu_native_update_skipped_max_version", {
535724
535793
  latency_ms: Date.now() - startTime,
535725
535794
  max_version: maxVersion,
@@ -535730,7 +535799,7 @@ async function updateLatest(channelOrVersion, forceReinstall = false) {
535730
535799
  version2 = maxVersion;
535731
535800
  }
535732
535801
  }
535733
- if (!forceReinstall && version2 === "1.3.434" && await versionIsAvailable(version2) && await isPossibleClaudeBinary(executablePath)) {
535802
+ if (!forceReinstall && version2 === "1.3.435" && await versionIsAvailable(version2) && await isPossibleClaudeBinary(executablePath)) {
535734
535803
  logForDebugging(`Found ${version2} at ${executablePath}, skipping install`);
535735
535804
  logEvent("tengu_native_update_complete", {
535736
535805
  latency_ms: Date.now() - startTime,
@@ -535982,7 +536051,7 @@ async function checkInstall(force = false) {
535982
536051
  const shellType = getShellType();
535983
536052
  const configPaths = getShellConfigPaths();
535984
536053
  const configFile = configPaths[shellType];
535985
- const displayPath = configFile ? configFile.replace(homedir29(), "~") : "your shell config file";
536054
+ const displayPath = configFile ? configFile.replace(homedir30(), "~") : "your shell config file";
535986
536055
  messages.push({
535987
536056
  message: `Native installation exists but ~/.local/bin is not in your PATH. Run:
535988
536057
 
@@ -536483,7 +536552,7 @@ async function cleanupNpmInstallations() {
536483
536552
  errors6.push(macroPackageResult.error);
536484
536553
  }
536485
536554
  }
536486
- const localInstallDir = join126(homedir29(), ".claude", "local");
536555
+ const localInstallDir = join126(homedir30(), ".claude", "local");
536487
536556
  try {
536488
536557
  await rm15(localInstallDir, { recursive: true });
536489
536558
  removed++;
@@ -536926,7 +536995,7 @@ function buildPrimarySection() {
536926
536995
  }, undefined, false, undefined, this);
536927
536996
  return [{
536928
536997
  label: "Version",
536929
- value: "1.3.434"
536998
+ value: "1.3.435"
536930
536999
  }, {
536931
537000
  label: "Session name",
536932
537001
  value: nameValue
@@ -540617,7 +540686,7 @@ function Config({
540617
540686
  }
540618
540687
  }, undefined, false, undefined, this)
540619
540688
  }, undefined, false, undefined, this) : showSubmenu === "ChannelDowngrade" ? /* @__PURE__ */ jsx_dev_runtime170.jsxDEV(ChannelDowngradeDialog, {
540620
- currentVersion: "1.3.434",
540689
+ currentVersion: "1.3.435",
540621
540690
  onChoice: (choice) => {
540622
540691
  setShowSubmenu(null);
540623
540692
  setTabsHidden(false);
@@ -540629,7 +540698,7 @@ function Config({
540629
540698
  autoUpdatesChannel: "stable"
540630
540699
  };
540631
540700
  if (choice === "stay") {
540632
- newSettings.minimumVersion = "1.3.434";
540701
+ newSettings.minimumVersion = "1.3.435";
540633
540702
  }
540634
540703
  updateSettingsForSource("userSettings", newSettings);
540635
540704
  setSettingsData((prev_27) => ({
@@ -547494,10 +547563,10 @@ var init_MemoryFileSelector = __esm(() => {
547494
547563
  });
547495
547564
 
547496
547565
  // src/components/memory/MemoryUpdateNotification.tsx
547497
- import { homedir as homedir30 } from "os";
547566
+ import { homedir as homedir31 } from "os";
547498
547567
  import { relative as relative29 } from "path";
547499
547568
  function getRelativeMemoryPath(path25) {
547500
- const homeDir = homedir30();
547569
+ const homeDir = homedir31();
547501
547570
  const cwd2 = getCwd();
547502
547571
  const relativeToHome = path25.startsWith(homeDir) ? "~" + path25.slice(homeDir.length) : null;
547503
547572
  const relativeToCwd = path25.startsWith(cwd2) ? "./" + relative29(cwd2, path25) : null;
@@ -548691,7 +548760,7 @@ function HelpV2(t0) {
548691
548760
  let t6;
548692
548761
  if ($3[31] !== tabs) {
548693
548762
  t6 = /* @__PURE__ */ jsx_dev_runtime197.jsxDEV(Tabs, {
548694
- title: `Rayu-CLI v${"1.3.434"}`,
548763
+ title: `Rayu-CLI v${"1.3.435"}`,
548695
548764
  color: "professionalBlue",
548696
548765
  defaultTab: "general",
548697
548766
  children: tabs
@@ -550110,6 +550179,9 @@ Domain-locked so each agent uses only what fits its specialty:
550110
550179
  - **deploy:** review, fix, linter, Explore, general-purpose.
550111
550180
  \`PA\` and \`global-setup\` are ORCHESTRATOR-ONLY — collaborators implement; they never re-plan or re-scaffold. (These limits are also enforced in code.)
550112
550181
 
550182
+ ## Bundled skills (use them — no install needed)
550183
+ rayu ships original skills, always available via the Skill tool: \`rayu-frontend-design\`, \`rayu-design-system\`, \`rayu-theme-factory\`, \`rayu-brand-guidelines\` (UI / design / brand), \`rayu-canvas-design\` + \`rayu-algorithmic-art\` (generated graphics & generative art), \`rayu-web-artifacts-builder\` (standalone interactive pages), \`rayu-api-design\` + \`rayu-mcp-builder\` (backend), \`rayu-web-testing\` (QA/verification), \`rayu-doc-export\` (docx/xlsx/pptx/pdf deliverables). Tell each collaborator to pull the skill that fits its task — frontend/mobile → design / theme / artifacts; design & asset-generation → canvas / algorithmic-art / brand; backend → api / mcp; review/security → web-testing; any document deliverable → doc-export. Beyond the bundled set, you and the collaborators may also use any skill the user has installed, or install a relevant one on demand from the official Anthropic skills repo (\`anthropics/skills\`) via the InstallSkill tool.
550184
+
550113
550185
  ## DEFAULT TO PARALLEL (the single most important rule)
550114
550186
  Parallel execution is ~3–5x faster than sequential. Unless one call genuinely needs another's output, dispatch independent agents/tools TOGETHER in ONE assistant message (multiple Agent calls), not one-per-message. Plan all the calls you'll need upfront, then fire them together. Cap each batch at ~3–5 calls to avoid timeouts. Sequential is the exception, allowed ONLY on a true dependency. One-per-message dispatch is the #1 cause of slow swarm runs — avoid it.
550115
550187
 
@@ -554307,7 +554379,7 @@ var init_pluginStartupCheck = __esm(() => {
554307
554379
  });
554308
554380
 
554309
554381
  // src/utils/plugins/parseMarketplaceInput.ts
554310
- import { homedir as homedir31 } from "os";
554382
+ import { homedir as homedir32 } from "os";
554311
554383
  import { resolve as resolve47 } from "path";
554312
554384
  async function parseMarketplaceInput(input) {
554313
554385
  const trimmed = input.trim();
@@ -554343,7 +554415,7 @@ async function parseMarketplaceInput(input) {
554343
554415
  const isWindows2 = process.platform === "win32";
554344
554416
  const isWindowsPath = isWindows2 && (trimmed.startsWith(".\\") || trimmed.startsWith("..\\") || /^[a-zA-Z]:[/\\]/.test(trimmed));
554345
554417
  if (trimmed.startsWith("./") || trimmed.startsWith("../") || trimmed.startsWith("/") || trimmed.startsWith("~") || isWindowsPath) {
554346
- const resolvedPath = resolve47(trimmed.startsWith("~") ? trimmed.replace(/^~/, homedir31()) : trimmed);
554418
+ const resolvedPath = resolve47(trimmed.startsWith("~") ? trimmed.replace(/^~/, homedir32()) : trimmed);
554347
554419
  let stats2;
554348
554420
  try {
554349
554421
  stats2 = await fs14.stat(resolvedPath);
@@ -568723,7 +568795,7 @@ function getRecentReleaseNotes(currentVersion, previousVersion, changelogContent
568723
568795
  }
568724
568796
  return [];
568725
568797
  }
568726
- async function checkForReleaseNotes(lastSeenVersion, currentVersion = "1.3.434") {
568798
+ async function checkForReleaseNotes(lastSeenVersion, currentVersion = "1.3.435") {
568727
568799
  if (false) {}
568728
568800
  const cachedChangelog = await getStoredChangelog();
568729
568801
  if (lastSeenVersion !== currentVersion || !cachedChangelog) {
@@ -568736,7 +568808,7 @@ async function checkForReleaseNotes(lastSeenVersion, currentVersion = "1.3.434")
568736
568808
  releaseNotes
568737
568809
  };
568738
568810
  }
568739
- function checkForReleaseNotesSync(lastSeenVersion, currentVersion = "1.3.434") {
568811
+ function checkForReleaseNotesSync(lastSeenVersion, currentVersion = "1.3.435") {
568740
568812
  if (false) {}
568741
568813
  const releaseNotes = getRecentReleaseNotes(currentVersion, lastSeenVersion);
568742
568814
  return {
@@ -568864,7 +568936,7 @@ function getRecentActivitySync() {
568864
568936
  return cachedActivity;
568865
568937
  }
568866
568938
  function getLogoDisplayData() {
568867
- const version2 = process.env.DEMO_VERSION ?? "1.3.434";
568939
+ const version2 = process.env.DEMO_VERSION ?? "1.3.435";
568868
568940
  const serverUrl = getDirectConnectServerUrl();
568869
568941
  const displayPath = process.env.DEMO_VERSION ? "/code/claude" : getDisplayPath(getCwd());
568870
568942
  const cwd2 = serverUrl ? `${displayPath} in ${serverUrl.replace(/^https?:\/\//, "")}` : displayPath;
@@ -569338,7 +569410,7 @@ var init_referral = __esm(() => {
569338
569410
  });
569339
569411
 
569340
569412
  // src/components/LogoV2/feedConfigs.tsx
569341
- import { homedir as homedir32 } from "os";
569413
+ import { homedir as homedir33 } from "os";
569342
569414
  function createRecentActivityFeed(activities) {
569343
569415
  const lines2 = activities.map((log3) => {
569344
569416
  const time3 = formatRelativeTimeAgo(log3.modified);
@@ -569394,7 +569466,7 @@ function createProjectOnboardingFeed(steps) {
569394
569466
  text: `${checkmark}${text2}`
569395
569467
  };
569396
569468
  });
569397
- const warningText = getCwd() === homedir32() ? "Note: You have launched Rayu in your home directory. For the best experience, launch it in a project directory instead." : undefined;
569469
+ const warningText = getCwd() === homedir33() ? "Note: You have launched Rayu in your home directory. For the best experience, launch it in a project directory instead." : undefined;
569398
569470
  if (warningText) {
569399
569471
  lines2.push({
569400
569472
  text: warningText
@@ -569418,7 +569490,7 @@ function createGuestPassesFeed() {
569418
569490
  marginY: 1,
569419
569491
  children: /* @__PURE__ */ jsx_dev_runtime231.jsxDEV(ThemedText, {
569420
569492
  color: "claude",
569421
- children: "[] [] []"
569493
+ children: `[${getBrandGlyph()}] [${getBrandGlyph()}] [${getBrandGlyph()}]`
569422
569494
  }, undefined, false, undefined, this)
569423
569495
  }, undefined, false, undefined, this),
569424
569496
  /* @__PURE__ */ jsx_dev_runtime231.jsxDEV(ThemedText, {
@@ -569436,6 +569508,7 @@ var jsx_dev_runtime231;
569436
569508
  var init_feedConfigs = __esm(() => {
569437
569509
  init_figures();
569438
569510
  init_ink2();
569511
+ init_figures2();
569439
569512
  init_referral();
569440
569513
  init_cwd2();
569441
569514
  init_format();
@@ -570110,7 +570183,7 @@ function LogoV2() {
570110
570183
  if ($3[2] === Symbol.for("react.memo_cache_sentinel")) {
570111
570184
  t2 = () => {
570112
570185
  const currentConfig = getGlobalConfig();
570113
- if (currentConfig.lastReleaseNotesSeen === "1.3.434") {
570186
+ if (currentConfig.lastReleaseNotesSeen === "1.3.435") {
570114
570187
  return;
570115
570188
  }
570116
570189
  saveGlobalConfig(_temp327);
@@ -570588,7 +570661,7 @@ function LogoV2() {
570588
570661
  t24 = $3[61];
570589
570662
  }
570590
570663
  const _latestNpm = getCachedLatestNpmVersionSync();
570591
- const _updateFeeds = _latestNpm && gt(_latestNpm, "1.3.434") ? [createUpdateAvailableFeed("1.3.434", _latestNpm)] : [];
570664
+ const _updateFeeds = _latestNpm && gt(_latestNpm, "1.3.435") ? [createUpdateAvailableFeed("1.3.435", _latestNpm)] : [];
570592
570665
  const t25 = layoutMode === "horizontal" && /* @__PURE__ */ jsx_dev_runtime239.jsxDEV(FeedColumn, {
570593
570666
  feeds: showOnboarding ? [createProjectOnboardingFeed(getSteps()), createRecentActivityFeed(activities)] : showGuestPassesUpsell ? [createRecentActivityFeed(activities), createGuestPassesFeed()] : showOverageCreditUpsell ? [createRecentActivityFeed(activities), createOverageCreditFeed()] : [createRecentActivityFeed(activities), ..._updateFeeds, createWhatsNewFeed(changelog)],
570594
570667
  maxWidth: rightWidth
@@ -570788,12 +570861,12 @@ function LogoV2() {
570788
570861
  return t41;
570789
570862
  }
570790
570863
  function _temp327(current) {
570791
- if (current.lastReleaseNotesSeen === "1.3.434") {
570864
+ if (current.lastReleaseNotesSeen === "1.3.435") {
570792
570865
  return current;
570793
570866
  }
570794
570867
  return {
570795
570868
  ...current,
570796
- lastReleaseNotesSeen: "1.3.434"
570869
+ lastReleaseNotesSeen: "1.3.435"
570797
570870
  };
570798
570871
  }
570799
570872
  function _temp241(s_0) {
@@ -584005,7 +584078,7 @@ var init_brand = __esm(() => {
584005
584078
  init_settings2();
584006
584079
  React86 = __toESM(require_react(), 1);
584007
584080
  jsx_dev_runtime272 = __toESM(require_jsx_dev_runtime(), 1);
584008
- GLYPH_OPTIONS = ["◈", "◆", "◇", "★", "✦", "❖", "●", "✻", "*"];
584081
+ GLYPH_OPTIONS = ["◈", "◆", "◇", "★", "✦", "❖", "●"];
584009
584082
  });
584010
584083
 
584011
584084
  // src/commands/brand/index.ts
@@ -595697,7 +595770,7 @@ async function captureMemoryDiagnostics(trigger, dumpNumber = 0) {
595697
595770
  smapsRollup,
595698
595771
  platform: process.platform,
595699
595772
  nodeVersion: process.version,
595700
- ccVersion: "1.3.434"
595773
+ ccVersion: "1.3.435"
595701
595774
  };
595702
595775
  }
595703
595776
  async function performHeapDump(trigger = "manual", dumpNumber = 0) {
@@ -596219,7 +596292,7 @@ var init_bridge_kick = __esm(() => {
596219
596292
  var call49 = async () => {
596220
596293
  return {
596221
596294
  type: "text",
596222
- value: "1.3.434"
596295
+ value: "1.3.435"
596223
596296
  };
596224
596297
  }, version2, version_default;
596225
596298
  var init_version = __esm(() => {
@@ -605995,7 +606068,7 @@ function generateHtmlReport(data, insights) {
605995
606068
  </html>`;
605996
606069
  }
605997
606070
  function buildExportData(data, insights, facets, remoteStats) {
605998
- const version3 = typeof MACRO !== "undefined" ? "1.3.434" : "unknown";
606071
+ const version3 = typeof MACRO !== "undefined" ? "1.3.435" : "unknown";
605999
606072
  const remote_hosts_collected = remoteStats?.hosts.filter((h3) => h3.sessionCount > 0).map((h3) => h3.name);
606000
606073
  const facets_summary = {
606001
606074
  total: facets.size,
@@ -609903,7 +609976,7 @@ var init_sessionStorage = __esm(() => {
609903
609976
  init_settings2();
609904
609977
  init_slowOperations();
609905
609978
  init_uuid();
609906
- VERSION6 = typeof MACRO !== "undefined" ? "1.3.434" : "unknown";
609979
+ VERSION6 = typeof MACRO !== "undefined" ? "1.3.435" : "unknown";
609907
609980
  MAX_TOMBSTONE_REWRITE_BYTES = 50 * 1024 * 1024;
609908
609981
  SKIP_FIRST_PROMPT_PATTERN = /^(?:\s*<[a-z][\w-]*[\s>]|\[Request interrupted by user[^\]]*\])/;
609909
609982
  EPHEMERAL_PROGRESS_TYPES = new Set([
@@ -610239,7 +610312,7 @@ var init_agentMemory = __esm(() => {
610239
610312
 
610240
610313
  // src/utils/permissions/filesystem.ts
610241
610314
  import { randomBytes as randomBytes19 } from "crypto";
610242
- import { homedir as homedir33, tmpdir as tmpdir15 } from "os";
610315
+ import { homedir as homedir34, tmpdir as tmpdir15 } from "os";
610243
610316
  import { join as join153, normalize as normalize18, posix as posix7, sep as sep39 } from "path";
610244
610317
  function normalizeCaseForComparison2(path28) {
610245
610318
  return path28.toLowerCase();
@@ -610257,11 +610330,11 @@ function getRayuSkillScope(filePath) {
610257
610330
  prefix: "/.agents/skills/"
610258
610331
  },
610259
610332
  {
610260
- dir: expandPath(join153(homedir33(), ".rayu", "skills")),
610333
+ dir: expandPath(join153(homedir34(), ".rayu", "skills")),
610261
610334
  prefix: "~/.rayu/skills/"
610262
610335
  },
610263
610336
  {
610264
- dir: expandPath(join153(homedir33(), ".agents", "skills")),
610337
+ dir: expandPath(join153(homedir34(), ".agents", "skills")),
610265
610338
  prefix: "~/.agents/skills/"
610266
610339
  }
610267
610340
  ];
@@ -610581,7 +610654,7 @@ function patternWithRoot(pattern, source) {
610581
610654
  } else if (pattern.startsWith(`~${DIR_SEP}`)) {
610582
610655
  return {
610583
610656
  relativePattern: pattern.slice(1),
610584
- root: homedir33().normalize("NFC")
610657
+ root: homedir34().normalize("NFC")
610585
610658
  };
610586
610659
  } else if (pattern.startsWith(DIR_SEP)) {
610587
610660
  return {
@@ -611124,7 +611197,7 @@ var init_filesystem = __esm(() => {
611124
611197
  });
611125
611198
  getBundledSkillsRoot = memoize_default(function getBundledSkillsRoot2() {
611126
611199
  const nonce = randomBytes19(16).toString("hex");
611127
- return join153(getClaudeTempDir(), "bundled-skills", "1.3.434", nonce);
611200
+ return join153(getClaudeTempDir(), "bundled-skills", "1.3.435", nonce);
611128
611201
  });
611129
611202
  getResolvedWorkingDirPaths = memoize_default(getPathsForPermissionCheck);
611130
611203
  });
@@ -616237,9 +616310,9 @@ __export(exports_update, {
616237
616310
  update: () => update
616238
616311
  });
616239
616312
  import { execFileSync as execFileSync3 } from "node:child_process";
616240
- import { homedir as homedir34 } from "os";
616313
+ import { homedir as homedir35 } from "os";
616241
616314
  async function update() {
616242
- writeToStdout(`Current version: ${"1.3.434"}
616315
+ writeToStdout(`Current version: ${"1.3.435"}
616243
616316
  `);
616244
616317
  const isBundled = isInBundledMode();
616245
616318
  if (isBundled) {
@@ -616253,7 +616326,7 @@ async function updateNpmPackage() {
616253
616326
  `);
616254
616327
  let latestVersion;
616255
616328
  try {
616256
- latestVersion = execFileSync3("npm", ["view", `${"@rayu-dev/rayu-cli"}@latest`, "version", "--prefer-online"], { encoding: "utf8", timeout: 15000, cwd: homedir34(), stdio: ["pipe", "pipe", "pipe"] }).trim();
616329
+ latestVersion = execFileSync3("npm", ["view", `${"@rayu-dev/rayu-cli"}@latest`, "version", "--prefer-online"], { encoding: "utf8", timeout: 15000, cwd: homedir35(), stdio: ["pipe", "pipe", "pipe"] }).trim();
616257
616330
  } catch {
616258
616331
  process.stderr.write(source_default.red(`Failed to check for updates
616259
616332
  `));
@@ -616265,19 +616338,19 @@ Manual check: npm view ${"@rayu-dev/rayu-cli"} version
616265
616338
  process.exit(1);
616266
616339
  return;
616267
616340
  }
616268
- if (latestVersion === "1.3.434") {
616341
+ if (latestVersion === "1.3.435") {
616269
616342
  writeToStdout(source_default.green(`
616270
- Rayu CLI is up to date (${"1.3.434"})
616343
+ Rayu CLI is up to date (${"1.3.435"})
616271
616344
  `));
616272
616345
  process.exit(0);
616273
616346
  }
616274
- writeToStdout(`New version available: ${latestVersion} (current: ${"1.3.434"})
616347
+ writeToStdout(`New version available: ${latestVersion} (current: ${"1.3.435"})
616275
616348
  `);
616276
616349
  writeToStdout(`Installing update...
616277
616350
 
616278
616351
  `);
616279
616352
  try {
616280
- execFileSync3("npm", ["install", "-g", `${"@rayu-dev/rayu-cli"}@latest`], { encoding: "utf8", cwd: homedir34(), stdio: "inherit" });
616353
+ execFileSync3("npm", ["install", "-g", `${"@rayu-dev/rayu-cli"}@latest`], { encoding: "utf8", cwd: homedir35(), stdio: "inherit" });
616281
616354
  } catch {
616282
616355
  process.stderr.write(source_default.red(`
616283
616356
  Failed to install update
@@ -616295,7 +616368,7 @@ Try manually:
616295
616368
  return;
616296
616369
  }
616297
616370
  writeToStdout(source_default.green(`
616298
- Successfully updated from ${"1.3.434"} to ${latestVersion}
616371
+ Successfully updated from ${"1.3.435"} to ${latestVersion}
616299
616372
  `));
616300
616373
  process.exit(0);
616301
616374
  }
@@ -616305,18 +616378,18 @@ async function updateNativeBinary() {
616305
616378
  const { installLatest: installLatest2 } = await Promise.resolve().then(() => (init_nativeInstaller(), exports_nativeInstaller));
616306
616379
  let latestVersion;
616307
616380
  try {
616308
- latestVersion = execFileSync3("npm", ["view", "@rayu-dev/rayu-cli@latest", "version", "--prefer-online"], { encoding: "utf8", timeout: 15000, cwd: homedir34(), stdio: ["pipe", "pipe", "pipe"] }).trim();
616381
+ latestVersion = execFileSync3("npm", ["view", "@rayu-dev/rayu-cli@latest", "version", "--prefer-online"], { encoding: "utf8", timeout: 15000, cwd: homedir35(), stdio: ["pipe", "pipe", "pipe"] }).trim();
616309
616382
  } catch {
616310
616383
  latestVersion = "";
616311
616384
  }
616312
- if (latestVersion && latestVersion === "1.3.434") {
616385
+ if (latestVersion && latestVersion === "1.3.435") {
616313
616386
  writeToStdout(source_default.green(`
616314
- Rayu CLI is up to date (1.3.434)
616387
+ Rayu CLI is up to date (1.3.435)
616315
616388
  `));
616316
616389
  process.exit(0);
616317
616390
  }
616318
616391
  if (latestVersion) {
616319
- writeToStdout(`New version available: ${latestVersion} (current: 1.3.434)
616392
+ writeToStdout(`New version available: ${latestVersion} (current: 1.3.435)
616320
616393
  `);
616321
616394
  }
616322
616395
  writeToStdout(`Downloading and installing update...
@@ -616331,13 +616404,13 @@ Rayu CLI is up to date (1.3.434)
616331
616404
  return;
616332
616405
  }
616333
616406
  writeToStdout(source_default.green(`
616334
- Rayu CLI is up to date (1.3.434)
616407
+ Rayu CLI is up to date (1.3.435)
616335
616408
  `));
616336
616409
  process.exit(0);
616337
616410
  }
616338
616411
  const updatedTo = result.latestVersion ?? latestVersion ?? "latest";
616339
616412
  writeToStdout(source_default.green(`
616340
- Successfully updated from 1.3.434 to ${updatedTo}
616413
+ Successfully updated from 1.3.435 to ${updatedTo}
616341
616414
  `));
616342
616415
  writeToStdout(`Restart your terminal to use the new version.
616343
616416
  `);
@@ -616366,15 +616439,15 @@ __export(exports_uninstall, {
616366
616439
  uninstall: () => uninstall
616367
616440
  });
616368
616441
  import { execFileSync as execFileSync4 } from "node:child_process";
616369
- import { homedir as homedir35 } from "os";
616442
+ import { homedir as homedir36 } from "os";
616370
616443
  async function uninstall() {
616371
- writeToStdout(`Uninstalling Rayu CLI (${"1.3.434"})...
616444
+ writeToStdout(`Uninstalling Rayu CLI (${"1.3.435"})...
616372
616445
  `);
616373
616446
  writeToStdout(`Running: npm uninstall -g ${"@rayu-dev/rayu-cli"}
616374
616447
 
616375
616448
  `);
616376
616449
  try {
616377
- execFileSync4("npm", ["uninstall", "-g", "@rayu-dev/rayu-cli"], { encoding: "utf8", cwd: homedir35(), stdio: "inherit" });
616450
+ execFileSync4("npm", ["uninstall", "-g", "@rayu-dev/rayu-cli"], { encoding: "utf8", cwd: homedir36(), stdio: "inherit" });
616378
616451
  } catch {
616379
616452
  process.stderr.write(source_default.red(`
616380
616453
  Failed to uninstall ${"@rayu-dev/rayu-cli"}
@@ -616391,7 +616464,7 @@ Try running manually:
616391
616464
  process.exit(1);
616392
616465
  }
616393
616466
  writeToStdout(source_default.green(`
616394
- Successfully uninstalled ${"@rayu-dev/rayu-cli"} ${"1.3.434"}
616467
+ Successfully uninstalled ${"@rayu-dev/rayu-cli"} ${"1.3.435"}
616395
616468
  `));
616396
616469
  writeToStdout(`Thanks for using Rayu CLI!
616397
616470
  `);
@@ -616443,7 +616516,7 @@ function showFirstRunWelcome() {
616443
616516
  `);
616444
616517
  try {
616445
616518
  mkdirSync14(getRayuConfigHomeDir(), { recursive: true });
616446
- writeFileSync16(markerPath(), "1.3.434", "utf8");
616519
+ writeFileSync16(markerPath(), "1.3.435", "utf8");
616447
616520
  } catch {}
616448
616521
  }
616449
616522
  var init_firstRun = __esm(() => {
@@ -619859,7 +619932,7 @@ __export(exports_upstreamproxy, {
619859
619932
  SESSION_TOKEN_PATH: () => SESSION_TOKEN_PATH
619860
619933
  });
619861
619934
  import { mkdir as mkdir44, readFile as readFile53, unlink as unlink26, writeFile as writeFile46 } from "fs/promises";
619862
- import { homedir as homedir36 } from "os";
619935
+ import { homedir as homedir37 } from "os";
619863
619936
  import { join as join157 } from "path";
619864
619937
  async function initUpstreamProxy(opts) {
619865
619938
  if (!isEnvTruthy(process.env.CLAUDE_CODE_REMOTE)) {
@@ -619881,7 +619954,7 @@ async function initUpstreamProxy(opts) {
619881
619954
  }
619882
619955
  setNonDumpable();
619883
619956
  const baseUrl = opts?.ccrBaseUrl ?? process.env.ANTHROPIC_BASE_URL ?? "https://api.anthropic.com";
619884
- const caBundlePath = opts?.caBundlePath ?? join157(homedir36(), ".ccr", "ca-bundle.crt");
619957
+ const caBundlePath = opts?.caBundlePath ?? join157(homedir37(), ".ccr", "ca-bundle.crt");
619885
619958
  const caOk = await downloadCaBundle(baseUrl, opts?.systemCaPath ?? SYSTEM_CA_BUNDLE, caBundlePath);
619886
619959
  if (!caOk)
619887
619960
  return state;
@@ -628286,7 +628359,7 @@ async function initializeBetaTracing(resource) {
628286
628359
  });
628287
628360
  import_api_logs.logs.setGlobalLoggerProvider(loggerProvider);
628288
628361
  setLoggerProvider(loggerProvider);
628289
- const eventLogger = import_api_logs.logs.getLogger("com.anthropic.claude_code.events", "1.3.434");
628362
+ const eventLogger = import_api_logs.logs.getLogger("com.anthropic.claude_code.events", "1.3.435");
628290
628363
  setEventLogger(eventLogger);
628291
628364
  process.on("beforeExit", async () => {
628292
628365
  await loggerProvider?.forceFlush();
@@ -628326,7 +628399,7 @@ async function initializeTelemetry() {
628326
628399
  const platform4 = getPlatform();
628327
628400
  const baseAttributes = {
628328
628401
  [import_semantic_conventions2.ATTR_SERVICE_NAME]: "claude-code",
628329
- [import_semantic_conventions2.ATTR_SERVICE_VERSION]: "1.3.434"
628402
+ [import_semantic_conventions2.ATTR_SERVICE_VERSION]: "1.3.435"
628330
628403
  };
628331
628404
  if (platform4 === "wsl") {
628332
628405
  const wslVersion = getWslVersion();
@@ -628371,7 +628444,7 @@ async function initializeTelemetry() {
628371
628444
  } catch {}
628372
628445
  };
628373
628446
  registerCleanup(shutdownTelemetry2);
628374
- return meterProvider2.getMeter("com.anthropic.claude_code", "1.3.434");
628447
+ return meterProvider2.getMeter("com.anthropic.claude_code", "1.3.435");
628375
628448
  }
628376
628449
  const meterProvider = new import_sdk_metrics2.MeterProvider({
628377
628450
  resource,
@@ -628391,7 +628464,7 @@ async function initializeTelemetry() {
628391
628464
  });
628392
628465
  import_api_logs.logs.setGlobalLoggerProvider(loggerProvider);
628393
628466
  setLoggerProvider(loggerProvider);
628394
- const eventLogger = import_api_logs.logs.getLogger("com.anthropic.claude_code.events", "1.3.434");
628467
+ const eventLogger = import_api_logs.logs.getLogger("com.anthropic.claude_code.events", "1.3.435");
628395
628468
  setEventLogger(eventLogger);
628396
628469
  logForDebugging("[3P telemetry] Event logger set successfully");
628397
628470
  process.on("beforeExit", async () => {
@@ -628453,7 +628526,7 @@ Current timeout: ${timeoutMs}ms
628453
628526
  }
628454
628527
  };
628455
628528
  registerCleanup(shutdownTelemetry);
628456
- return meterProvider.getMeter("com.anthropic.claude_code", "1.3.434");
628529
+ return meterProvider.getMeter("com.anthropic.claude_code", "1.3.435");
628457
628530
  }
628458
628531
  async function flushTelemetry() {
628459
628532
  const meterProvider = getMeterProvider();
@@ -629966,7 +630039,7 @@ function buildSystemInitMessage(inputs) {
629966
630039
  slash_commands: inputs.commands.filter((c4) => c4.userInvocable !== false).map((c4) => c4.name),
629967
630040
  apiKeySource: getAnthropicApiKeyWithSource().source,
629968
630041
  betas: getSdkBetas(),
629969
- claude_code_version: "1.3.434",
630042
+ claude_code_version: "1.3.435",
629970
630043
  output_style: outputStyle2,
629971
630044
  agents: inputs.agents.map((agent) => agent.agentType),
629972
630045
  skills: inputs.skills.filter((s2) => s2.userInvocable !== false).map((skill) => skill.name),
@@ -637166,7 +637239,7 @@ function useDiffInIDE({
637166
637239
  const isUnmounted = import_react199.useRef(false);
637167
637240
  const [hasError, setHasError] = import_react199.useState(false);
637168
637241
  const sha = import_react199.useMemo(() => randomUUID39().slice(0, 6), []);
637169
- const tabName = import_react199.useMemo(() => `◈ [RAYU] ${basename50(filePath)} (${sha}) ⧉`, [filePath, sha]);
637242
+ const tabName = import_react199.useMemo(() => `${getBrandGlyph()} [RAYU] ${basename50(filePath)} (${sha}) ⧉`, [filePath, sha]);
637170
637243
  const shouldShowDiffInIDE = hasAccessToIDEExtensionDiffFeature(toolUseContext.options.mcpClients) && getGlobalConfig().diffTool === "auto" && !filePath.endsWith(".ipynb");
637171
637244
  const ideName = getConnectedIdeName(toolUseContext.options.mcpClients) ?? "IDE";
637172
637245
  async function showDiff() {
@@ -637333,6 +637406,7 @@ function isSaveMessage(data) {
637333
637406
  }
637334
637407
  var import_react199;
637335
637408
  var init_useDiffInIDE = __esm(() => {
637409
+ init_figures2();
637336
637410
  init_analytics();
637337
637411
  init_fileRead();
637338
637412
  init_path();
@@ -637565,7 +637639,7 @@ var init_ShowInIDEPrompt = __esm(() => {
637565
637639
  });
637566
637640
 
637567
637641
  // src/components/permissions/FilePermissionDialog/permissionOptions.tsx
637568
- import { homedir as homedir37 } from "os";
637642
+ import { homedir as homedir38 } from "os";
637569
637643
  import { basename as basename52, join as join159, sep as sep40 } from "path";
637570
637644
  function isInRayuFolder(filePath) {
637571
637645
  const absolutePath = expandPath(filePath);
@@ -637576,7 +637650,7 @@ function isInRayuFolder(filePath) {
637576
637650
  }
637577
637651
  function isInGlobalRayuFolder(filePath) {
637578
637652
  const absolutePath = expandPath(filePath);
637579
- const globalRayuFolderPath = join159(homedir37(), ".rayu");
637653
+ const globalRayuFolderPath = join159(homedir38(), ".rayu");
637580
637654
  const normalizedAbsolutePath = normalizeCaseForComparison2(absolutePath);
637581
637655
  const normalizedGlobalRayuFolderPath = normalizeCaseForComparison2(globalRayuFolderPath);
637582
637656
  return normalizedAbsolutePath.startsWith(normalizedGlobalRayuFolderPath + sep40.toLowerCase()) || normalizedAbsolutePath.startsWith(normalizedGlobalRayuFolderPath + "/");
@@ -646175,7 +646249,7 @@ var init_useVoiceEnabled = __esm(() => {
646175
646249
  function getSemverPart(version3) {
646176
646250
  return `${import_semver12.major(version3, { loose: true })}.${import_semver12.minor(version3, { loose: true })}.${import_semver12.patch(version3, { loose: true })}`;
646177
646251
  }
646178
- function useUpdateNotification(updatedVersion, initialVersion = "1.3.434") {
646252
+ function useUpdateNotification(updatedVersion, initialVersion = "1.3.435") {
646179
646253
  const [lastNotifiedSemver, setLastNotifiedSemver] = import_react217.useState(() => getSemverPart(initialVersion));
646180
646254
  if (!updatedVersion) {
646181
646255
  return null;
@@ -646215,7 +646289,7 @@ function AutoUpdater({
646215
646289
  return;
646216
646290
  }
646217
646291
  if (false) {}
646218
- const currentVersion = "1.3.434";
646292
+ const currentVersion = "1.3.435";
646219
646293
  const channel = getInitialSettings()?.autoUpdatesChannel ?? "latest";
646220
646294
  let latestVersion = await getLatestVersion(channel);
646221
646295
  const isDisabled = isAutoUpdaterDisabled();
@@ -646428,12 +646502,12 @@ function NativeAutoUpdater({
646428
646502
  logEvent("tengu_native_auto_updater_start", {});
646429
646503
  try {
646430
646504
  const maxVersion = await getMaxVersion();
646431
- if (maxVersion && gt("1.3.434", maxVersion)) {
646505
+ if (maxVersion && gt("1.3.435", maxVersion)) {
646432
646506
  const msg = await getMaxVersionMessage();
646433
646507
  setMaxVersionIssue(msg ?? "affects your version");
646434
646508
  }
646435
646509
  const result = await installLatest(channel);
646436
- const currentVersion = "1.3.434";
646510
+ const currentVersion = "1.3.435";
646437
646511
  const latencyMs = Date.now() - startTime;
646438
646512
  if (result.lockFailed) {
646439
646513
  logEvent("tengu_native_auto_updater_lock_contention", {
@@ -646570,17 +646644,17 @@ function PackageManagerAutoUpdater(t0) {
646570
646644
  const maxVersion = await getMaxVersion();
646571
646645
  if (maxVersion && latest && gt(latest, maxVersion)) {
646572
646646
  logForDebugging(`PackageManagerAutoUpdater: maxVersion ${maxVersion} is set, capping update from ${latest} to ${maxVersion}`);
646573
- if (gte("1.3.434", maxVersion)) {
646574
- logForDebugging(`PackageManagerAutoUpdater: current version ${"1.3.434"} is already at or above maxVersion ${maxVersion}, skipping update`);
646647
+ if (gte("1.3.435", maxVersion)) {
646648
+ logForDebugging(`PackageManagerAutoUpdater: current version ${"1.3.435"} is already at or above maxVersion ${maxVersion}, skipping update`);
646575
646649
  setUpdateAvailable(false);
646576
646650
  return;
646577
646651
  }
646578
646652
  latest = maxVersion;
646579
646653
  }
646580
- const hasUpdate = latest && !gte("1.3.434", latest) && !shouldSkipVersion(latest);
646654
+ const hasUpdate = latest && !gte("1.3.435", latest) && !shouldSkipVersion(latest);
646581
646655
  setUpdateAvailable(!!hasUpdate);
646582
646656
  if (hasUpdate) {
646583
- logForDebugging(`PackageManagerAutoUpdater: Update available ${"1.3.434"} -> ${latest}`);
646657
+ logForDebugging(`PackageManagerAutoUpdater: Update available ${"1.3.435"} -> ${latest}`);
646584
646658
  }
646585
646659
  };
646586
646660
  $3[0] = t1;
@@ -646614,7 +646688,7 @@ function PackageManagerAutoUpdater(t0) {
646614
646688
  wrap: "truncate",
646615
646689
  children: [
646616
646690
  "currentVersion: ",
646617
- "1.3.434"
646691
+ "1.3.435"
646618
646692
  ]
646619
646693
  }, undefined, true, undefined, this);
646620
646694
  $3[3] = verbose;
@@ -654779,7 +654853,7 @@ function buildStatusLineCommandInput(permissionMode, exceeds200kTokens, settings
654779
654853
  project_dir: getOriginalCwd(),
654780
654854
  added_dirs: addedDirs
654781
654855
  },
654782
- version: "1.3.434",
654856
+ version: "1.3.435",
654783
654857
  output_style: {
654784
654858
  name: outputStyleName
654785
654859
  },
@@ -666183,7 +666257,7 @@ async function submitTranscriptShare(messages, trigger, appearanceId) {
666183
666257
  } catch {}
666184
666258
  const data = {
666185
666259
  trigger,
666186
- version: "1.3.434",
666260
+ version: "1.3.435",
666187
666261
  platform: process.platform,
666188
666262
  transcript,
666189
666263
  subagentTranscripts: Object.keys(subagentTranscripts).length > 0 ? subagentTranscripts : undefined,
@@ -677038,7 +677112,7 @@ Note: ctrl + z now suspends RAYU, ctrl + _ undoes input.
677038
677112
  var import_compiler_runtime341, React152, import_react309, jsx_dev_runtime451, useFrustrationDetection = () => ({
677039
677113
  state: "closed",
677040
677114
  handleTranscriptSelect: () => {}
677041
- }), useAntOrgWarningNotification = () => {}, getCoordinatorUserContext = () => ({}), proactiveModule5 = null, PROACTIVE_NO_OP_SUBSCRIBE = (_cb) => () => {}, PROACTIVE_FALSE = () => false, SUGGEST_BG_PR_NOOP = (_p, _n) => false, EMPTY_MCP_CLIENTS2, HISTORY_STUB, RECENT_SCROLL_REPIN_WINDOW_MS = 3000, TITLE_ANIMATION_FRAMES, TITLE_STATIC_PREFIX = "✳", TITLE_ANIMATION_INTERVAL_MS = 960;
677115
+ }), useAntOrgWarningNotification = () => {}, getCoordinatorUserContext = () => ({}), proactiveModule5 = null, PROACTIVE_NO_OP_SUBSCRIBE = (_cb) => () => {}, PROACTIVE_FALSE = () => false, SUGGEST_BG_PR_NOOP = (_p, _n) => false, EMPTY_MCP_CLIENTS2, HISTORY_STUB, RECENT_SCROLL_REPIN_WINDOW_MS = 3000, TITLE_ANIMATION_FRAMES, TITLE_STATIC_PREFIX, TITLE_ANIMATION_INTERVAL_MS = 960;
677042
677116
  var init_REPL = __esm(() => {
677043
677117
  init_state();
677044
677118
  init_tokenBudget();
@@ -677092,6 +677166,7 @@ var init_REPL = __esm(() => {
677092
677166
  init_useSkillImprovementSurvey();
677093
677167
  init_Spinner2();
677094
677168
  init_prompts3();
677169
+ init_figures2();
677095
677170
  init_systemPrompt();
677096
677171
  init_context2();
677097
677172
  init_claudemd();
@@ -677250,6 +677325,7 @@ var init_REPL = __esm(() => {
677250
677325
  maybeLoadOlder: (_2) => {}
677251
677326
  };
677252
677327
  TITLE_ANIMATION_FRAMES = ["⠂", "⠐"];
677328
+ TITLE_STATIC_PREFIX = getBrandGlyph();
677253
677329
  });
677254
677330
 
677255
677331
  // src/replLauncher.tsx
@@ -678226,7 +678302,7 @@ function WelcomeV2() {
678226
678302
  dimColor: true,
678227
678303
  children: [
678228
678304
  "v",
678229
- "1.3.434"
678305
+ "1.3.435"
678230
678306
  ]
678231
678307
  }, undefined, true, undefined, this)
678232
678308
  ]
@@ -678772,7 +678848,7 @@ var exports_TrustDialog = {};
678772
678848
  __export(exports_TrustDialog, {
678773
678849
  TrustDialog: () => TrustDialog
678774
678850
  });
678775
- import { homedir as homedir38 } from "os";
678851
+ import { homedir as homedir39 } from "os";
678776
678852
  function TrustDialog(t0) {
678777
678853
  const $3 = import_compiler_runtime347.c(33);
678778
678854
  const {
@@ -678883,7 +678959,7 @@ function TrustDialog(t0) {
678883
678959
  let t13;
678884
678960
  if ($3[13] !== hasAnyBashExecution) {
678885
678961
  t12 = () => {
678886
- const isHomeDir = homedir38() === getCwd();
678962
+ const isHomeDir = homedir39() === getCwd();
678887
678963
  logEvent("tengu_trust_dialog_shown", {
678888
678964
  isHomeDir,
678889
678965
  hasMcpServers,
@@ -678912,7 +678988,7 @@ function TrustDialog(t0) {
678912
678988
  gracefulShutdownSync(1);
678913
678989
  return;
678914
678990
  }
678915
- const isHomeDir_0 = homedir38() === getCwd();
678991
+ const isHomeDir_0 = homedir39() === getCwd();
678916
678992
  logEvent("tengu_trust_dialog_accept", {
678917
678993
  isHomeDir: isHomeDir_0,
678918
678994
  hasMcpServers,
@@ -679960,7 +680036,7 @@ function completeOnboarding() {
679960
680036
  saveGlobalConfig((current) => ({
679961
680037
  ...current,
679962
680038
  hasCompletedOnboarding: true,
679963
- lastOnboardingVersion: "1.3.434"
680039
+ lastOnboardingVersion: "1.3.435"
679964
680040
  }));
679965
680041
  }
679966
680042
  function showDialog(root2, renderer) {
@@ -682722,6 +682798,647 @@ var init_remember = __esm(() => {
682722
682798
  init_bundledSkills();
682723
682799
  });
682724
682800
 
682801
+ // src/skills/bundled/rayu/rayu-frontend-design/SKILL.md
682802
+ var SKILL_default = `---
682803
+ name: rayu-frontend-design
682804
+ description: Guidance for building distinctive, intentional web/mobile UI that doesn't read as a templated default. Use when designing or reshaping a UI — choosing visual direction, type, layout, motion, and microcopy. Pairs with the design subagent's PRD.
682805
+ ---
682806
+
682807
+ # Rayu Frontend Design
682808
+
682809
+ Build interfaces a real design studio would ship: opinionated, specific to the brief, and free of the generic "AI default" look. Your job is to make deliberate choices you can justify — not to assemble safe defaults.
682810
+
682811
+ ## 1. Ground the design in a real subject
682812
+
682813
+ Before any pixels, name three things and write them down:
682814
+
682815
+ - **Subject** — what the product actually is, in one concrete sentence.
682816
+ - **Audience** — who uses it and what they care about.
682817
+ - **The page's single job** — the one action or understanding the page must produce.
682818
+
682819
+ If the brief leaves these open, decide them and state your decision. Pull distinctive details from the subject's own world (its materials, vocabulary, artifacts). If a \`.rayu/swarm/\` design PRD or shared brief exists, treat it as the source of truth and build from it instead of re-deriving.
682820
+
682821
+ ## 2. Avoid the generic default
682822
+
682823
+ Current "AI-generated" UI clusters around a few tells. Treat these as smells, not destinations:
682824
+
682825
+ - Cream/off-white background + high-contrast serif + a single terracotta accent.
682826
+ - Near-black background + one acid-green or vermilion accent.
682827
+ - Hairline-rule "broadsheet" layouts with zero radius and dense columns.
682828
+ - Decorative \`01 / 02 / 03\` numbering applied to content that isn't actually a sequence.
682829
+
682830
+ These are fine *only* when the brief explicitly calls for them. Where the brief leaves an axis free, spend that freedom on a choice specific to the subject — not on a default.
682831
+
682832
+ ## 3. Make the type carry the personality
682833
+
682834
+ - Set a real type scale (e.g. a modular scale around 1.2–1.333) with intentional weights and spacing — not browser defaults.
682835
+ - Pair a characterful **display** face (used with restraint) with a clean **body** face; add a **utility/mono** face only if data/captions need it.
682836
+ - Decide line-height per role (tight for display, ~1.5 for body) and constrain measure (~60–75ch for body text).
682837
+
682838
+ ## 4. Structure should encode meaning
682839
+
682840
+ Eyebrows, dividers, numbering, and labels should reflect something true about the content, not decorate it. Ask "does this device carry information the reader needs?" before adding it. One memorable **signature element** per page; keep everything around it quiet.
682841
+
682842
+ ## 5. Motion, deliberately
682843
+
682844
+ Choose where motion serves the subject: a page-load reveal, a scroll-triggered moment, hover micro-interactions. An orchestrated moment beats scattered effects. Keep durations in the 150–300ms range for UI feedback. **Always** honor \`prefers-reduced-motion: reduce\` — gate non-essential animation behind it.
682845
+
682846
+ ## 6. The accessibility floor (non-negotiable)
682847
+
682848
+ - Contrast ≥ 4.5:1 for body text, ≥ 3:1 for large text and meaningful UI.
682849
+ - Visible keyboard focus on every interactive element; logical tab order.
682850
+ - Real semantic HTML (\`button\`, \`nav\`, \`main\`, headings in order); \`alt\` text; labels tied to inputs.
682851
+ - Touch targets ≥ 44×44px with spacing.
682852
+ - Responsive down to ~360px with no horizontal scroll.
682853
+
682854
+ ## 7. Microcopy is design material
682855
+
682856
+ Write from the user's side of the screen: name things by what people control, not how the system is built. Active voice on controls ("Save changes", not "Submit"), and keep an action's name consistent through its flow (a "Publish" button → a "Published" toast). Make empty and error states do real work: say what happened and what to do next.
682857
+
682858
+ ## 8. Process: plan → critique → build → critique
682859
+
682860
+ 1. **Plan** a compact token system: 4–6 named hex colors, 2+ type roles, a layout concept (sketch it in prose/ASCII), and the one signature element.
682861
+ 2. **Critique the plan against the brief** — if any part reads like the default you'd produce for any similar page, change it and say why.
682862
+ 3. **Build** from the revised plan; derive every color/type decision from the tokens (see the \`rayu-design-system\` skill for the token model).
682863
+ 4. **Critique again** while building — verify the a11y floor, responsiveness, and reduced-motion. Cut one decoration that doesn't serve the brief.
682864
+
682865
+ ## Working in the rayu swarm
682866
+
682867
+ When you're the \`frontend\` (or \`mobile\`) collaborator, implement against the \`design\` PRD and the backend contract from \`.rayu/swarm/\`. Use the \`Skill\` tool to also pull \`rayu-design-system\` for the token model. Report concisely; persist durable design decisions to your domain section.
682868
+ `;
682869
+ var init_SKILL = () => {};
682870
+
682871
+ // src/skills/bundled/rayu/rayu-design-system/SKILL.md
682872
+ var SKILL_default2 = "---\nname: rayu-design-system\ndescription: Build and apply a consistent design-token system — color, spacing, type, radius, shadow — with theming, dark mode, and responsive scales. Use when setting up a UI's foundation or enforcing visual consistency across components.\n---\n\n# Rayu Design System\n\nA design system is the small set of decisions every component obeys. Define the tokens once, name them by intent, and never hard-code a raw value in a component again.\n\n## 1. Two layers of tokens\n\n- **Primitive tokens** — the raw palette/scale: `color-blue-600: #2563eb`, `space-4: 1rem`, `font-size-lg: 1.125rem`. No meaning, just values.\n- **Semantic tokens** — intent mapped onto primitives: `color-bg`, `color-surface`, `color-text`, `color-text-muted`, `color-border`, `color-accent`, `color-danger`. **Components consume only semantic tokens.** This is what makes theming and dark mode a one-file change.\n\nExpose them as CSS custom properties (or your framework's theme object):\n\n```css\n:root {\n --color-bg: #ffffff;\n --color-surface: #f7f7f8;\n --color-text: #18181b;\n --color-text-muted: #52525b;\n --color-border: #e4e4e7;\n --color-accent: #2563eb;\n --radius-md: 0.5rem;\n --space-2: 0.5rem; --space-4: 1rem; --space-8: 2rem;\n}\n```\n\n## 2. The scales\n\n- **Spacing** — one scale, geometric or 4px-based (`2,4,8,12,16,24,32,48,64`). Every margin/padding/gap comes from it.\n- **Type** — a modular scale (ratio ~1.2–1.333) with defined roles (display, h1–h3, body, caption), each with weight + line-height. Body ≈ 16px / 1.5.\n- **Radius / shadow / border** — 2–4 steps each. Resist per-component one-offs.\n- **Z-index** — a named ladder (`dropdown, sticky, overlay, modal, toast`) so stacking is intentional.\n\n## 3. Theming and dark mode\n\nBecause components use semantic tokens, a theme is just a different mapping of semantic → primitive. Implement dark mode by overriding the semantic layer:\n\n```css\n:root[data-theme='dark'] {\n --color-bg: #0b0b0e;\n --color-surface: #18181b;\n --color-text: #fafafa;\n --color-text-muted: #a1a1aa;\n --color-border: #27272a;\n}\n```\n\nVerify **both** themes hit the contrast floor (≥ 4.5:1 body). Respect `prefers-color-scheme` for the default and let users override.\n\n## 4. Responsive scale\n\nMobile-first. Define a few breakpoints (`sm 640, md 768, lg 1024, xl 1280`) and a fluid type/space step if you want headings to scale (`clamp()` is your friend). Containers get a max-width + auto margins; never let content run edge-to-edge on wide screens.\n\n## 5. Component states\n\nEvery interactive component defines all of: `default, hover, active, focus-visible, disabled`, plus `loading` and `error` where relevant. Focus-visible must be clearly visible (don't remove outlines without replacing them). Document the states next to the component.\n\n## 6. Consistency checklist\n\n- [ ] No raw hex / px in components — only tokens.\n- [ ] One spacing scale, one type scale, used everywhere.\n- [ ] Semantic tokens only in components; primitives only in the theme map.\n- [ ] Light + dark both pass contrast.\n- [ ] All states defined incl. focus-visible.\n- [ ] Icons from one set; consistent stroke/size.\n\n## Working in the rayu swarm\n\nThe `design` subagent should emit these tokens in its PRD; the `frontend`/`mobile` collaborators implement against them (pair with the `rayu-frontend-design` skill). Persist the final token set to your `.rayu/swarm/` domain section so the whole swarm stays visually aligned.\n";
682873
+ var init_SKILL2 = () => {};
682874
+
682875
+ // src/skills/bundled/rayu/rayu-web-testing/SKILL.md
682876
+ var SKILL_default3 = `---
682877
+ name: rayu-web-testing
682878
+ description: Approach for testing and verifying local web applications end-to-end — driving a real browser, finding selectors, capturing screenshots/logs, and stabilizing flaky tests. Use when verifying frontend behavior or writing E2E tests.
682879
+ ---
682880
+
682881
+ # Rayu Web Testing
682882
+
682883
+ Verify what the user actually sees by driving a real browser against the running app. Prefer a mainstream automation library (Playwright recommended; Cypress/Puppeteer are fine) and write small, deterministic scripts.
682884
+
682885
+ ## Decision tree: pick the cheapest approach that works
682886
+
682887
+ \`\`\`
682888
+ Is the page static HTML (no JS rendering)?
682889
+ ├─ Yes → read the HTML directly, grab selectors, assert on the served markup.
682890
+ └─ No (dynamic app) → is the dev server already running?
682891
+ ├─ No → start it, wait until it's actually serving, THEN drive the browser.
682892
+ └─ Yes → reconnaissance-then-action:
682893
+ 1) navigate, wait for network idle / a known element
682894
+ 2) screenshot or dump the DOM to discover real selectors
682895
+ 3) act using the discovered selectors
682896
+ 4) assert on visible state, not internals
682897
+ \`\`\`
682898
+
682899
+ ## Server lifecycle
682900
+
682901
+ Don't assume the server is up. Start it (\`npm run dev\`, \`vite\`, etc.), poll the port/URL until it responds, run the test, then tear it down. For multi-service apps (API + web), start each, wait for each to be healthy, then drive. Never hard-code \`sleep\` — wait on a real readiness signal (port open, health route 200, or an element present).
682902
+
682903
+ ## Selectors: stable first
682904
+
682905
+ Priority order:
682906
+ 1. Role/label/text (\`getByRole('button', { name: 'Save' })\`, \`getByLabel\`) — closest to what users perceive.
682907
+ 2. \`data-testid\` hooks added intentionally for tests.
682908
+ 3. CSS/structure — last resort; brittle.
682909
+
682910
+ Avoid selectors tied to styling or DOM depth. If you can't find a stable hook, add a \`data-testid\` to the app rather than writing a fragile selector.
682911
+
682912
+ ## Minimal Playwright shape
682913
+
682914
+ \`\`\`js
682915
+ import { test, expect } from '@playwright/test'
682916
+
682917
+ test('user can submit the contact form', async ({ page }) => {
682918
+ await page.goto('http://localhost:5173/contact')
682919
+ await page.getByLabel('Email').fill('a@example.com')
682920
+ await page.getByRole('button', { name: 'Send' }).click()
682921
+ await expect(page.getByText('Thanks — we got it')).toBeVisible()
682922
+ })
682923
+ \`\`\`
682924
+
682925
+ ## Evidence: screenshots + logs
682926
+
682927
+ Capture a screenshot on failure (and at key steps for UI work) — "a picture is worth a thousand tokens" when diagnosing. Collect browser console errors and failed network requests; they explain most "it just doesn't work" reports. Surface those in the result rather than guessing.
682928
+
682929
+ ## Killing flakiness
682930
+
682931
+ - **Wait on conditions, not time.** Use auto-waiting assertions / \`waitFor\`, never fixed delays.
682932
+ - **Isolate state.** Reset DB/storage between tests; don't depend on test order.
682933
+ - **One reason to fail per test.** Small, focused specs localize breakage.
682934
+ - **Control the network.** Mock third-party calls so a flaky upstream doesn't fail your suite.
682935
+ - **Pin the viewport** for layout-sensitive assertions.
682936
+
682937
+ ## Coverage priorities for a web app
682938
+
682939
+ 1. Critical happy paths (auth, the primary conversion flow).
682940
+ 2. Form validation + error states.
682941
+ 3. Responsive behavior at one mobile + one desktop width.
682942
+ 4. Accessibility smoke (focus order, a labelled primary action).
682943
+
682944
+ ## Working in the rayu swarm
682945
+
682946
+ The \`review\` subagent and \`security\` collaborator use this to verify produced UI against the spec, returning a concrete pass/fail + a Fix List. Keep scripts black-box and short; report high-signal results (what failed, the screenshot/log), not a play-by-play.
682947
+ `;
682948
+ var init_SKILL3 = () => {};
682949
+
682950
+ // src/skills/bundled/rayu/rayu-api-design/SKILL.md
682951
+ var SKILL_default4 = "---\nname: rayu-api-design\ndescription: Conventions for designing clean, consistent HTTP/REST APIs — resources, request/response schemas, status codes, error envelopes, pagination, versioning, auth-per-route, and idempotency. Use when defining a backend contract. Pairs with the backend-design subagent.\n---\n\n# Rayu API Design\n\nDesign the contract before the implementation. A good API is predictable: a developer who has seen three endpoints can guess the fourth.\n\n## 1. Resources and routes\n\n- Model **nouns**, not verbs: `/users`, `/users/{id}`, `/users/{id}/orders`.\n- Use HTTP methods for the verb: `GET` (read, safe), `POST` (create), `PUT`/`PATCH` (replace/update), `DELETE` (remove).\n- Plural collection names; lowercase, hyphenated paths. Nest only one level deep — prefer `/orders?userId=…` over deep nesting.\n- Keep responses consistent in shape across endpoints.\n\n## 2. Request / response schemas\n\nDefine every field with name, type, required/optional, and validation. Keep wire names consistent (pick `camelCase` or `snake_case` and never mix). Echo created/updated resources back in the response so the client doesn't need a second round-trip.\n\n```http\nPOST /api/v1/users\nContent-Type: application/json\n\n{ \"email\": \"a@example.com\", \"password\": \"••••••\", \"name\": \"Ada\" }\n\n201 Created\n{ \"id\": \"usr_123\", \"email\": \"a@example.com\", \"name\": \"Ada\", \"createdAt\": \"2026-01-01T00:00:00Z\" }\n```\n\n## 3. Status codes (use them precisely)\n\n- `200` OK, `201` Created (+ `Location`), `204` No Content (deletes).\n- `400` malformed, `401` unauthenticated, `403` authenticated-but-forbidden, `404` not found, `409` conflict, `422` validation failed, `429` rate-limited.\n- `500` server error (never leak internals), `503` unavailable.\n\n## 4. One error envelope everywhere\n\nPick a single error shape and use it for *every* error:\n\n```json\n{ \"error\": { \"code\": \"validation_failed\",\n \"message\": \"Email is already registered.\",\n \"details\": [{ \"field\": \"email\", \"issue\": \"duplicate\" }] } }\n```\n\nMachine-readable `code`, human `message`, optional `details`. Never return HTML errors from a JSON API.\n\n## 5. Pagination, filtering, sorting\n\n- Cursor pagination for large/append-heavy sets (`?limit=20&cursor=…`), offset for small/admin lists (`?page=2&pageSize=20`).\n- Return pagination metadata (`nextCursor` or `total`/`page`).\n- Standardize filtering (`?status=active`) and sorting (`?sort=-createdAt`).\n\n## 6. Versioning\n\nVersion from day one: `/api/v1/…` (or an `Accept` header). Only break within a new version; add fields additively within a version (new optional fields aren't breaking).\n\n## 7. Auth per route (ties into security)\n\nFor each endpoint declare: public vs authenticated, and the role/permission required. Use `Authorization: Bearer <token>`; return `401` (no/invalid token) vs `403` (valid token, insufficient role). Keep the auth model centralized (middleware/guards), not per-handler. The `security` collaborator owns the auth decisions — design routes to fit them.\n\n## 8. Idempotency & safety\n\n- `GET`/`PUT`/`DELETE` are idempotent; `POST` is not — for money/critical creates, accept an `Idempotency-Key` header and dedupe.\n- Validate and normalize all input at the boundary; never trust the client.\n- Rate-limit public/auth endpoints; return `429` + `Retry-After`.\n\n## Working in the rayu swarm\n\nThe `backend-design` subagent emits the API contract + data model PRD using these conventions; the `backend` collaborator implements against it, and the `frontend`/`mobile` collaborators code their API layer to the same shapes. Keep the contract in `.rayu/swarm/` so every domain agrees on it.\n";
682952
+ var init_SKILL4 = () => {};
682953
+
682954
+ // src/skills/bundled/rayu/rayu-mcp-builder/SKILL.md
682955
+ var SKILL_default5 = `---
682956
+ name: rayu-mcp-builder
682957
+ description: Build a Model Context Protocol (MCP) server that exposes tools, resources, and prompts to AI agents. Use when creating an MCP server or integration — covers server anatomy, transports, input schemas, error handling, testing, and safe tool exposure.
682958
+ ---
682959
+
682960
+ # Rayu MCP Builder
682961
+
682962
+ The Model Context Protocol (MCP) is a standard way to expose capabilities to AI clients. A server offers three primitives — **tools** (actions the model can call), **resources** (readable data the model can pull in), and **prompts** (reusable templates) — over a JSON-RPC transport.
682963
+
682964
+ ## 1. Pick a transport
682965
+
682966
+ - **stdio** — the server is launched as a subprocess; it speaks JSON-RPC over stdin/stdout. Best for local tools a client spawns. (Most common.)
682967
+ - **HTTP + SSE / streamable HTTP** — the server runs as a network service. Use for remote/shared servers.
682968
+
682969
+ Start with stdio unless you need a networked server.
682970
+
682971
+ ## 2. Minimal server anatomy (TypeScript SDK)
682972
+
682973
+ \`\`\`ts
682974
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
682975
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
682976
+ import { z } from 'zod'
682977
+
682978
+ const server = new McpServer({ name: 'my-server', version: '1.0.0' })
682979
+
682980
+ server.tool(
682981
+ 'get_weather',
682982
+ 'Get current weather for a city',
682983
+ { city: z.string().describe('City name') }, // input schema (zod)
682984
+ async ({ city }) => {
682985
+ const data = await fetchWeather(city)
682986
+ return { content: [{ type: 'text', text: JSON.stringify(data) }] }
682987
+ },
682988
+ )
682989
+
682990
+ await server.connect(new StdioServerTransport())
682991
+ \`\`\`
682992
+
682993
+ (Python SDK mirrors this with \`FastMCP\` and \`@mcp.tool()\` decorators.)
682994
+
682995
+ ## 3. Design the tools well — the schema IS the UX
682996
+
682997
+ The model only sees names, descriptions, and schemas. So:
682998
+
682999
+ - **Name** tools by action (\`create_invoice\`, not \`invoices\`).
683000
+ - **Describe** what the tool does AND when to use it — the description drives selection.
683001
+ - **Schema**: every parameter typed, with a \`.describe()\`. Mark optionals; give safe defaults. Validate strictly (zod/pydantic) and reject bad input early.
683002
+ - Keep each tool **single-purpose**. Many small, clear tools beat one mega-tool with a mode flag.
683003
+ - Return concise, structured results; large blobs belong in **resources**, not tool output.
683004
+
683005
+ ## 4. Resources and prompts
683006
+
683007
+ - **Resources** expose readable content by URI (\`file://…\`, \`db://orders/123\`). Provide a list endpoint + a read endpoint; support templates (\`db://orders/{id}\`) when enumerable.
683008
+ - **Prompts** are named, parameterized templates the user can invoke. Use them for repeatable workflows.
683009
+
683010
+ ## 5. Error handling
683011
+
683012
+ - Validation failures → return a clear tool error the model can recover from (message says what was wrong), not an unhandled crash.
683013
+ - Distinguish *user/input* errors (fixable by changing args) from *system* errors (retryable/fatal).
683014
+ - Never let an exception kill the process on stdio — catch, return a structured error, keep serving.
683015
+
683016
+ ## 6. Security of tool exposure (critical)
683017
+
683018
+ A tool is an action you're handing to a model. Treat every input as untrusted:
683019
+
683020
+ - **Least privilege** — expose the narrowest capability that does the job. Don't expose \`run_shell(cmd)\` when \`list_files(dir)\` suffices.
683021
+ - **Validate + sanitize** all inputs; constrain paths (no traversal), allow-list commands, parameterize queries.
683022
+ - **Guard side effects** — destructive tools (delete, transfer, deploy) should require explicit args and ideally a confirmation/dry-run mode.
683023
+ - **Secrets** come from the environment, never from tool args or hard-coded values; never echo them in results.
683024
+ - **Rate/size limits** on anything that hits the network or returns large data.
683025
+
683026
+ ## 7. Test it
683027
+
683028
+ - Unit-test each tool's handler directly (input → output, incl. error paths).
683029
+ - Integration-test over the transport with the MCP Inspector or a scripted client: list tools, call each with valid + invalid input, assert the structured result.
683030
+ - Verify the server starts, advertises its tools/resources, and shuts down cleanly.
683031
+
683032
+ ## 8. Ship checklist
683033
+
683034
+ - [ ] Clear \`name\`/\`version\`; tools have action names + when-to-use descriptions.
683035
+ - [ ] Strict input schemas with descriptions and validation.
683036
+ - [ ] Structured errors; process never dies on bad input.
683037
+ - [ ] Least-privilege tools; destructive ops guarded; secrets from env.
683038
+ - [ ] Tested over the transport; documented setup (command, env vars).
683039
+
683040
+ ## Working in the rayu swarm
683041
+
683042
+ The \`backend\` collaborator uses this when a task needs an MCP server/integration. Pair with \`rayu-api-design\` for the underlying data/contract conventions. Record the exposed tool surface in \`.rayu/swarm/\` so the rest of the swarm knows the integration's capabilities.
683043
+ `;
683044
+ var init_SKILL5 = () => {};
683045
+
683046
+ // src/skills/bundled/rayu/rayu-doc-export/SKILL.md
683047
+ var SKILL_default6 = '---\nname: rayu-doc-export\ndescription: Generate office documents and PDFs (docx, xlsx, pptx, pdf) programmatically using open-source libraries. Use when a task needs to produce a Word, Excel, PowerPoint, or PDF deliverable from data or content.\n---\n\n# Rayu Doc Export\n\nProduce real office files with well-maintained open-source libraries. Pick the library by output format and ecosystem, install it, generate the file, and verify it opens. All guidance below is built on the libraries\' own public documentation.\n\n## Library map\n\n| Format | Python (recommended) | JavaScript/Node |\n|---|---|---|\n| **Word** `.docx` | `python-docx` | `docx` (npm) |\n| **Excel** `.xlsx` | `openpyxl` | `exceljs` |\n| **PowerPoint** `.pptx` | `python-pptx` | `pptxgenjs` |\n| **PDF** | `reportlab` (or `weasyprint` for HTML→PDF) | `pdf-lib` |\n\nPython has the most mature OOXML coverage; use it unless the project is JS-only.\n\n## Word — python-docx\n\n```bash\npip install python-docx # NOTE: package is "python-docx"; import is "docx"\n```\n\n```python\nfrom docx import Document\nfrom docx.shared import Pt, Inches\n\ndoc = Document()\ndoc.add_heading(\'Quarterly Report\', level=1)\ndoc.add_paragraph(\'Summary of results for Q1.\')\ndoc.add_paragraph(\'A bullet item\', style=\'List Bullet\')\n\ntable = doc.add_table(rows=1, cols=2)\ntable.style = \'Light Grid Accent 1\'\nhdr = table.rows[0].cells\nhdr[0].text, hdr[1].text = \'Metric\', \'Value\'\nrow = table.add_row().cells\nrow[0].text, row[1].text = \'Revenue\', \'$1.2M\'\n\ndoc.add_picture(\'chart.png\', width=Inches(5))\ndoc.save(\'report.docx\')\n```\n\nKey objects: `Document`, `add_heading`, `add_paragraph` (+ `style`), `add_table`/`add_row`, `add_picture`. Runs (`paragraph.add_run(\'x\').bold = True`) control inline formatting.\n\n## Excel — openpyxl\n\n```bash\npip install openpyxl\n```\n\n```python\nfrom openpyxl import Workbook\nfrom openpyxl.styles import Font\n\nwb = Workbook()\nws = wb.active\nws.title = \'Sales\'\nws.append([\'Month\', \'Revenue\']) # write a row\nws[\'A1\'].font = Font(bold=True)\nws.append([\'Jan\', 1200])\nws[\'B3\'] = \'=SUM(B2:B2)\' # formulas are just strings\nws.column_dimensions[\'A\'].width = 16\nwb.save(\'sales.xlsx\')\n```\n\nKey objects: `Workbook`, `wb.active`/`wb.create_sheet`, cell access (`ws[\'A1\']` or `ws.cell(row, column)`), `ws.append(list)`, styles (`Font`, `PatternFill`, `Alignment`), and `wb.save`. For huge sheets use `write_only=True`.\n\n## PowerPoint — python-pptx\n\n```bash\npip install python-pptx\n```\n\n```python\nfrom pptx import Presentation\nfrom pptx.util import Inches, Pt\n\nprs = Presentation()\ntitle_slide = prs.slides.add_slide(prs.slide_layouts[0]) # 0 = Title\ntitle_slide.shapes.title.text = \'Rayu Deck\'\ntitle_slide.placeholders[1].text = \'Generated with python-pptx\'\n\nbullets = prs.slides.add_slide(prs.slide_layouts[1]) # 1 = Title+Content\nbullets.shapes.title.text = \'Agenda\'\ntf = bullets.placeholders[1].text_frame\ntf.text = \'First point\'\ntf.add_paragraph().text = \'Second point\'\n\nprs.save(\'deck.pptx\')\n```\n\nKey objects: `Presentation`, `slide_layouts` (indexes into the template\'s layouts), `shapes.title`/`placeholders`, `text_frame` + `add_paragraph`, and `shapes.add_textbox`/`add_picture` for free placement.\n\n## PDF — reportlab (Python) or pdf-lib (JS)\n\n**reportlab, low-level canvas** (precise placement):\n\n```python\nfrom reportlab.pdfgen import canvas\nfrom reportlab.lib.pagesizes import letter\n\nc = canvas.Canvas(\'out.pdf\', pagesize=letter)\nc.drawString(72, 720, \'Hello World\') # origin is bottom-left\nc.showPage() # finish the page\nc.save()\n```\n\n**reportlab, Platypus** (flowing documents — paragraphs, tables, page breaks):\n\n```python\nfrom reportlab.platypus import SimpleDocTemplate, Paragraph, Table\nfrom reportlab.lib.styles import getSampleStyleSheet\n\nstyles = getSampleStyleSheet()\ndoc = SimpleDocTemplate(\'report.pdf\')\ndoc.build([\n Paragraph(\'Quarterly Report\', styles[\'Title\']),\n Paragraph(\'Summary text.\', styles[\'BodyText\']),\n Table([[\'Metric\', \'Value\'], [\'Revenue\', \'$1.2M\']]),\n])\n```\n\n**pdf-lib (Node/browser):**\n\n```js\nimport { PDFDocument, StandardFonts } from \'pdf-lib\'\n\nconst pdf = await PDFDocument.create()\nconst page = pdf.addPage([595, 842]) // A4 in points\nconst font = await pdf.embedFont(StandardFonts.Helvetica)\npage.drawText(\'Hello World\', { x: 72, y: 770, size: 18, font })\nconst bytes = await pdf.save() // Uint8Array → write to disk\n```\n\nUse Platypus/reportlab when generating from scratch; if you already have HTML/CSS, `weasyprint` (HTML→PDF) is often faster to a polished result.\n\n## Common pitfalls\n\n- **Wrong Word package:** install `python-docx` (not the abandoned `docx`); the import is still `import docx` / `from docx import Document`.\n- **reportlab coordinates** start at the bottom-left, and `showPage()` + `save()` are required or the file is empty/corrupt.\n- **pptx layout indexes** depend on the template; enumerate `prs.slide_layouts` rather than guessing.\n- **openpyxl formulas** are stored as strings and only evaluated when the file is opened in Excel (openpyxl won\'t compute them).\n- **Fonts/images:** embed fonts and reference image paths that exist at generate time; verify the output opens before reporting done.\n\n## Working in the rayu swarm\n\nUse this for any "produce a report/spreadsheet/deck/PDF" deliverable. Match the data to the right library, generate into the project\'s output path, and confirm the file is valid. These are open-source libraries — no proprietary document engine is required.\n';
683048
+ var init_SKILL6 = () => {};
683049
+
683050
+ // src/skills/bundled/rayu/rayu-canvas-design/SKILL.md
683051
+ var SKILL_default7 = `---
683052
+ name: rayu-canvas-design
683053
+ description: Compose static visual graphics on an HTML5 canvas — posters, social cards, diagrams, OG images, certificates. Use when generating a designed raster/vector image programmatically rather than a live UI.
683054
+ ---
683055
+
683056
+ # Rayu Canvas Design
683057
+
683058
+ Use the \`<canvas>\` 2D context (or a headless equivalent like \`node-canvas\`/\`@napi-rs/canvas\`/\`skia-canvas\`) to compose a finished image: an Open Graph card, a poster, a quote graphic, a diagram, a certificate. This is for *generated artwork*, not interactive UI.
683059
+
683060
+ ## Set up the surface
683061
+
683062
+ - Decide dimensions up front from the use case: OG image 1200×630, square social 1080×1080, story 1080×1920, A4 poster at 96dpi ≈ 794×1123 (×2–3 for print crispness).
683063
+ - **Render at 2× and scale down** for crisp text/edges, or set \`ctx.scale(dpr, dpr)\` with a backing store at \`width*dpr\`.
683064
+ - Establish a coordinate plan and a margin/safe-area before drawing.
683065
+
683066
+ \`\`\`js
683067
+ const W = 1200, H = 630, S = 2
683068
+ const canvas = createCanvas(W * S, H * S)
683069
+ const ctx = canvas.getContext('2d')
683070
+ ctx.scale(S, S)
683071
+ \`\`\`
683072
+
683073
+ ## Composition principles
683074
+
683075
+ - **Background first, foreground last.** Fill or gradient the bg, then layer shapes, then text on top.
683076
+ - **One focal point.** A single dominant element (a headline, a logo, a number) anchors the eye; everything else supports it.
683077
+ - **Grid + margins.** Keep content inside a safe margin (≈ 6–8% of width). Align to an invisible grid; don't eyeball every element.
683078
+ - **Type hierarchy.** 2–3 sizes max. Measure text (\`ctx.measureText\`) to wrap, center, and avoid overflow — never assume it fits.
683079
+ - **Contrast.** If text sits on an image, add a scrim (semi-opaque overlay) or shadow so it stays legible.
683080
+
683081
+ ## Core 2D recipes
683082
+
683083
+ \`\`\`js
683084
+ // Gradient background
683085
+ const g = ctx.createLinearGradient(0, 0, W, H)
683086
+ g.addColorStop(0, '#0f172a'); g.addColorStop(1, '#1e3a8a')
683087
+ ctx.fillStyle = g; ctx.fillRect(0, 0, W, H)
683088
+
683089
+ // Rounded rect (card)
683090
+ ctx.beginPath(); ctx.roundRect(80, 80, W - 160, H - 160, 24)
683091
+ ctx.fillStyle = 'rgba(255,255,255,0.06)'; ctx.fill()
683092
+
683093
+ // Text with manual wrap
683094
+ ctx.font = '700 64px Inter'; ctx.fillStyle = '#fff'
683095
+ ctx.textBaseline = 'top'
683096
+ wrapText(ctx, headline, 120, 140, W - 240, 76)
683097
+ \`\`\`
683098
+
683099
+ Helper: split words, accumulate until \`measureText(line).width > maxWidth\`, then break — write a small \`wrapText(ctx, text, x, y, maxWidth, lineHeight)\`.
683100
+
683101
+ ## Fonts and images
683102
+
683103
+ - **Register fonts** before drawing (headless libs need \`registerFont\`/\`GlobalFonts.register\`); a missing font silently falls back and ruins the layout.
683104
+ - **Await image loads** before \`drawImage\`; use \`drawImage(img, sx,sy,sw,sh, dx,dy,dw,dh)\` for crop-to-fit (cover/contain math).
683105
+ - Draw vector shapes for icons/logos when possible (crisp at any scale).
683106
+
683107
+ ## Export
683108
+
683109
+ \`\`\`js
683110
+ // PNG (lossless, transparency) — best for graphics with text
683111
+ const png = canvas.toBuffer('image/png')
683112
+ // JPEG (smaller, no transparency) — photographic backgrounds
683113
+ const jpg = canvas.toBuffer('image/jpeg', { quality: 0.9 })
683114
+ \`\`\`
683115
+
683116
+ Verify the output opens and the text isn't clipped before reporting done.
683117
+
683118
+ ## Pitfalls
683119
+
683120
+ - Forgetting \`textBaseline\` → vertical misalignment.
683121
+ - Not measuring text → overflow / clipping.
683122
+ - Unregistered fonts → wrong typeface.
683123
+ - Drawing before image/font load resolves → blank or fallback.
683124
+ - Low resolution → blurry text; render at 2×+.
683125
+
683126
+ ## Working in the rayu swarm
683127
+
683128
+ Use for generated image deliverables (OG/social cards, posters, diagrams). For *animated* or *interactive* visuals see \`rayu-algorithmic-art\`; for live product UI see \`rayu-frontend-design\`. Save assets to the project's image path and report each file with its dimensions.
683129
+ `;
683130
+ var init_SKILL7 = () => {};
683131
+
683132
+ // src/skills/bundled/rayu/rayu-web-artifacts-builder/SKILL.md
683133
+ var SKILL_default8 = `---
683134
+ name: rayu-web-artifacts-builder
683135
+ description: Build self-contained, single-file interactive web artifacts — a demo, calculator, visualization, mini-tool, or prototype that runs by opening one HTML file. Use when the deliverable is a standalone interactive page, not a full app.
683136
+ ---
683137
+
683138
+ # Rayu Web Artifacts Builder
683139
+
683140
+ An "artifact" is a single, self-contained interactive page that works by opening one file — no build step, no server, no install. Think: a unit converter, a data visualization, an interactive explainer, a game prototype, a configurator.
683141
+
683142
+ ## The contract
683143
+
683144
+ - **One file when possible.** Inline CSS in \`<style>\` and JS in \`<script>\`; embed small data as a JS object. The user can save it and double-click it.
683145
+ - **No build, no network by default.** It must run offline from \`file://\`. If you need a library, pull it from a CDN with an integrity hash and a graceful fallback — but prefer vanilla JS / the platform.
683146
+ - **Self-documenting.** A title, a one-line purpose, and obvious controls. No README required to use it.
683147
+
683148
+ ## Skeleton
683149
+
683150
+ \`\`\`html
683151
+ <!doctype html>
683152
+ <html lang="en">
683153
+ <head>
683154
+ <meta charset="utf-8" />
683155
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
683156
+ <title>Compound Interest Explorer</title>
683157
+ <style>
683158
+ :root { --bg:#0b0b0e; --fg:#fafafa; --accent:#22d3ee; }
683159
+ * { box-sizing: border-box }
683160
+ body { margin:0; font:16px/1.5 system-ui, sans-serif; background:var(--bg); color:var(--fg); }
683161
+ main { max-width: 720px; margin: 0 auto; padding: 2rem; }
683162
+ label { display:block; margin:.75rem 0 .25rem }
683163
+ input, button { font:inherit; padding:.5rem .75rem; border-radius:.5rem; }
683164
+ output { font-size:2rem; font-weight:700; color:var(--accent) }
683165
+ </style>
683166
+ </head>
683167
+ <body>
683168
+ <main>
683169
+ <h1>Compound Interest Explorer</h1>
683170
+ <label for="p">Principal</label>
683171
+ <input id="p" type="number" value="1000" />
683172
+ <output id="result">—</output>
683173
+ </main>
683174
+ <script>
683175
+ const p = document.getElementById('p')
683176
+ const result = document.getElementById('result')
683177
+ const fmt = new Intl.NumberFormat('en', { style:'currency', currency:'USD' })
683178
+ function update() { result.textContent = fmt.format(Number(p.value) * 1.05) }
683179
+ p.addEventListener('input', update); update()
683180
+ </script>
683181
+ </body>
683182
+ </html>
683183
+ \`\`\`
683184
+
683185
+ ## Build it well
683186
+
683187
+ - **State → render.** Keep a small state object; write one \`render()\` that reflects state into the DOM; event handlers mutate state then call \`render()\`. Avoid scattered DOM tweaks.
683188
+ - **Reach for the platform:** \`<input type=range>\`, \`<details>\`, \`<dialog>\`, \`Intl\`, \`requestAnimationFrame\`, \`<canvas>\`/SVG for graphics, \`localStorage\` for persistence.
683189
+ - **Make it responsive and keyboard-usable** even though it's "just" an artifact — labels on inputs, visible focus, works at mobile widths.
683190
+ - **Polish the empty/initial state** so it's obvious what to do.
683191
+ - **Performance:** debounce expensive recompute; for animation use \`requestAnimationFrame\`, not \`setInterval\`.
683192
+
683193
+ ## When NOT to use this
683194
+
683195
+ If it needs auth, a backend, multiple routes, or a real database, it's an app — use the \`frontend\`/\`backend\` collaborators and a real project scaffold instead. Artifacts are for one focused, client-only interaction.
683196
+
683197
+ ## Verify
683198
+
683199
+ Open the file (or load its markup) and exercise the controls: inputs update output, no console errors, works at a narrow width. Ship the single file.
683200
+
683201
+ ## Working in the rayu swarm
683202
+
683203
+ Use for quick interactive deliverables and prototypes. For visual styling depth pair with \`rayu-frontend-design\`; for generative graphics inside the artifact see \`rayu-algorithmic-art\`/\`rayu-canvas-design\`.
683204
+ `;
683205
+ var init_SKILL8 = () => {};
683206
+
683207
+ // src/skills/bundled/rayu/rayu-theme-factory/SKILL.md
683208
+ var SKILL_default9 = `---
683209
+ name: rayu-theme-factory
683210
+ description: Generate cohesive, distinctive visual themes — a coordinated palette, typography, and mood — and emit them as ready-to-use tokens. Use when you need to produce one or more complete theme options for a UI.
683211
+ ---
683212
+
683213
+ # Rayu Theme Factory
683214
+
683215
+ Produce a *complete, coherent theme* (or a few options) from a brief: a palette, type pairing, and supporting tokens that feel designed together — then emit them as usable tokens. This is theme *generation*; for the token *architecture* (semantic layering, dark mode mechanics) use \`rayu-design-system\`.
683216
+
683217
+ ## A theme is a coordinated set, not a random palette
683218
+
683219
+ Every theme has:
683220
+ 1. **A mood / direction** — one or two words (e.g. "warm editorial", "clinical precision", "retro arcade"). Decide this first; every choice serves it.
683221
+ 2. **A palette** — derived intentionally (below), not picked at random.
683222
+ 3. **A type pairing** — display + body that match the mood.
683223
+ 4. **Supporting tokens** — radius, shadow, spacing feel, motion character.
683224
+
683225
+ ## Build the palette intentionally
683226
+
683227
+ Work in **HSL/OKLCH**, not raw hex, so relationships are controllable:
683228
+
683229
+ - Pick **one base hue** that carries the mood.
683230
+ - Derive a **neutral ramp** (background → surface → border → muted text → text) by holding a slight hue tint and stepping lightness — neutrals with a hint of the brand hue feel cohesive; pure grey feels generic.
683231
+ - Choose an **accent** via a deliberate relationship to the base: analogous (calm), complementary (energetic), or triadic (playful).
683232
+ - Add **semantic states** (success/warning/danger/info) tuned to the palette, not stock bootstrap colors.
683233
+ - Generate **tints/shades** by stepping lightness in a consistent ratio (e.g. 50→900).
683234
+
683235
+ Always check contrast for text-on-surface pairs (≥ 4.5:1 body) in *both* light and dark.
683236
+
683237
+ ## Type pairing
683238
+
683239
+ Match faces to the mood: a high-contrast serif for editorial, a geometric sans for modern/tech, a grotesque for neutral/utility, a mono accent for data. Set the scale and weights (see \`rayu-design-system\` for the scale mechanics). Avoid the default "system-ui everywhere" unless the mood is deliberately plain.
683240
+
683241
+ ## Emit usable tokens
683242
+
683243
+ Output the theme as something a build can consume directly:
683244
+
683245
+ \`\`\`css
683246
+ :root {
683247
+ /* mood: warm editorial */
683248
+ --bg:#fbf7f0; --surface:#f3ece0; --border:#e3d8c6;
683249
+ --text:#241c14; --text-muted:#6b5d4b;
683250
+ --accent:#b4531f; --accent-contrast:#fff;
683251
+ --success:#3f7d3f; --danger:#a23b2d;
683252
+ --radius:0.375rem; --shadow:0 1px 2px rgba(36,28,20,.12);
683253
+ --font-display:'Fraunces', serif; --font-body:'Inter', sans-serif;
683254
+ }
683255
+ \`\`\`
683256
+
683257
+ Provide the matching **dark variant** by remapping the neutrals (don't just invert). If asked for multiple themes, give 2–3 *distinct* directions, each internally coherent — not three tints of the same idea.
683258
+
683259
+ ## Distinctiveness check
683260
+
683261
+ Before shipping a theme, ask: would this same palette/type show up for any random brief? If yes, push the base hue, the neutral tint, or the type pairing toward the specific mood. (See \`rayu-frontend-design\` on avoiding the generic default.)
683262
+
683263
+ ## Working in the rayu swarm
683264
+
683265
+ The \`design\` subagent uses this to generate the theme that goes into its PRD; the \`frontend\`/\`mobile\` collaborators implement the emitted tokens. Persist the chosen theme tokens to \`.rayu/swarm/\` so the build stays consistent.
683266
+ `;
683267
+ var init_SKILL9 = () => {};
683268
+
683269
+ // src/skills/bundled/rayu/rayu-brand-guidelines/SKILL.md
683270
+ var SKILL_default10 = `---
683271
+ name: rayu-brand-guidelines
683272
+ description: Define or apply a brand's identity system — logo usage, color, typography, voice, and imagery rules — so everything produced stays on-brand. Use when establishing a brand or enforcing consistency across deliverables.
683273
+ ---
683274
+
683275
+ # Rayu Brand Guidelines
683276
+
683277
+ A brand system is the rulebook that keeps every artifact recognizably the same author. Use this to *author* a brand guide from a brief, or to *apply* an existing one consistently.
683278
+
683279
+ ## What a brand system contains
683280
+
683281
+ 1. **Foundation** — mission/positioning in a sentence, and the personality in 3–5 adjectives (e.g. "precise, warm, confident"). Every other rule should trace back to these.
683282
+ 2. **Logo** — primary + secondary marks, clear-space (minimum padding around it), minimum size, and a do/don't list (don't stretch, recolor, rotate, add effects, place on busy backgrounds).
683283
+ 3. **Color** — primary, secondary, neutral ramp, and semantic colors, each with exact values (hex + the print/space equivalents if relevant). Specify which combinations are allowed and their contrast.
683284
+ 4. **Typography** — the brand typefaces (display, body, and a fallback stack), the type scale, and weight usage. Name when each is used.
683285
+ 5. **Voice & tone** — how the brand writes: person (we/you), formality, sentence length, words it uses and avoids, and how tone shifts by context (marketing vs error message vs docs).
683286
+ 6. **Imagery & iconography** — photography style, illustration style, icon set + stroke weight, and the overall visual texture.
683287
+ 7. **Layout** — grid, spacing rhythm, and composition tendencies (dense vs airy).
683288
+
683289
+ ## Authoring a brand from a brief
683290
+
683291
+ - Derive everything from the **personality adjectives** — they're the throughline. "Playful" → rounder type, brighter accent, looser spacing; "authoritative" → sturdier serif, restrained palette, tighter grid.
683292
+ - Make the color + type choices *specific* to the brand's world, not defaults (see \`rayu-frontend-design\` and \`rayu-theme-factory\`).
683293
+ - Write the voice section with **concrete examples**: a sample headline, a sample button label, a sample error message — show the voice, don't just describe it.
683294
+ - Output a structured guide (one markdown doc or a set of tokens) downstream agents can follow verbatim.
683295
+
683296
+ ## Voice: make it usable
683297
+
683298
+ Give do/don't pairs, not adjectives alone:
683299
+
683300
+ \`\`\`
683301
+ Personality: confident, plain-spoken, never hype.
683302
+ ✓ "Your changes are saved." ✗ "Awesome! We totally saved your stuff! 🎉"
683303
+ ✓ "Couldn't connect. Try again." ✗ "Oops! Something went wrong :("
683304
+ Use: clear verbs, sentence case, active voice.
683305
+ Avoid: exclamation points, jargon, anthropomorphizing the product.
683306
+ \`\`\`
683307
+
683308
+ ## Applying / auditing against a brand
683309
+
683310
+ When a guide exists, **conform to it** — don't reinvent. Audit deliverables against the rules: logo clear-space and min-size respected, only approved colors, correct typefaces and scale, voice consistent, imagery on-style. Flag each violation with the rule it breaks and the fix.
683311
+
683312
+ ## Working in the rayu swarm
683313
+
683314
+ The \`design\` subagent can author the brand section of its PRD with this; collaborators apply it and keep tokens/voice consistent across UI, copy, and generated assets (pairs with \`rayu-theme-factory\` for color/type and \`rayu-canvas-design\` for on-brand graphics). Persist the brand rules to \`.rayu/swarm/\` so the whole swarm stays on-brand.
683315
+ `;
683316
+ var init_SKILL10 = () => {};
683317
+
683318
+ // src/skills/bundled/rayu/rayu-algorithmic-art/SKILL.md
683319
+ var SKILL_default11 = `---
683320
+ name: rayu-algorithmic-art
683321
+ description: Create generative / algorithmic art with code — procedural patterns, flow fields, particle systems, fractals, and creative coding (Canvas, SVG, p5.js, shaders). Use when producing generative visuals, backgrounds, or animations from algorithms.
683322
+ ---
683323
+
683324
+ # Rayu Algorithmic Art
683325
+
683326
+ Make visuals from rules: a few parameters and an algorithm that produces something rich and often surprising. Use for generative backgrounds, abstract art, data-driven visuals, and ambient animation.
683327
+
683328
+ ## Pick the medium
683329
+
683330
+ - **Canvas 2D** — raster, fast for thousands of particles/strokes. Best general default.
683331
+ - **SVG** — vector, crisp + editable, great for plotter-style line art and scalable patterns (watch node counts).
683332
+ - **p5.js** — friendly creative-coding API (sketch \`setup()\`/\`draw()\`); good for quick exploration.
683333
+ - **WebGL / GLSL shaders** — per-pixel, GPU-fast; for fields, noise, fractals, and heavy real-time effects.
683334
+
683335
+ ## The generative toolkit
683336
+
683337
+ - **Randomness, controlled.** Use a **seeded** PRNG (e.g. mulberry32) so a result is reproducible — store the seed. Prefer *distributions* over flat \`Math.random()\`: gaussian for natural clustering, weighted choices for variety.
683338
+ - **Noise, not random, for organic form.** Perlin/Simplex noise gives smooth, coherent variation — the backbone of flow fields, terrain, clouds, and organic motion.
683339
+ - **Flow fields:** sample a noise field for an angle at each point; move particles along the angle, leaving trails. A handful of lines yields complex, elegant results.
683340
+ - **Particle systems:** each particle has position/velocity/lifespan; apply forces (noise, gravity, attraction); fade trails by drawing a translucent bg each frame.
683341
+ - **Tiling & symmetry:** rotate/mirror around a center, or tile a motif with jitter, for pattern and mandalas.
683342
+ - **Fractals / recursion:** subdivision, L-systems, and recursive shapes for self-similar structure.
683343
+
683344
+ ## Composition still matters
683345
+
683346
+ Algorithmic ≠ chaotic. Apply real design judgment:
683347
+ - **Constrain the palette** (3–5 colors from a coherent scheme — pair with \`rayu-theme-factory\`). Random rainbow output reads as noise.
683348
+ - **Density and negative space** — let the piece breathe; a clear focal area beats uniform busyness.
683349
+ - **Layering** — background field + mid-detail + sparse foreground accents.
683350
+ - **Curate.** Generate many seeds, keep the best. The selection is part of the artistry.
683351
+
683352
+ ## Minimal flow-field sketch (Canvas)
683353
+
683354
+ \`\`\`js
683355
+ const rand = mulberry32(seed)
683356
+ const angle = (x, y) => noise(x * 0.002, y * 0.002) * Math.PI * 2
683357
+ ctx.fillStyle = '#0b0b0e'; ctx.fillRect(0, 0, W, H)
683358
+ ctx.globalAlpha = 0.06; ctx.strokeStyle = palette[0]
683359
+ for (let i = 0; i < 1500; i++) {
683360
+ let x = rand() * W, y = rand() * H
683361
+ ctx.beginPath(); ctx.moveTo(x, y)
683362
+ for (let s = 0; s < 60; s++) { const a = angle(x, y); x += Math.cos(a) * 2; y += Math.sin(a) * 2; ctx.lineTo(x, y) }
683363
+ ctx.stroke()
683364
+ }
683365
+ \`\`\`
683366
+
683367
+ ## Animation & export
683368
+
683369
+ - Animate with \`requestAnimationFrame\`; advance a time/\`z\`-noise dimension for smooth evolution. Honor \`prefers-reduced-motion\` if it ships in a UI.
683370
+ - Export stills via canvas \`toBuffer\`/\`toDataURL\` (PNG); for loops, capture frames and assemble (gif/webm) or ship the live sketch as a \`rayu-web-artifacts-builder\` artifact.
683371
+ - Render at 2×+ for crisp stills.
683372
+
683373
+ ## Working in the rayu swarm
683374
+
683375
+ The \`asset-generation\` subagent uses this for generative backgrounds/visuals; pair with \`rayu-theme-factory\` for the palette and \`rayu-canvas-design\` for finishing static compositions. Save outputs to the project asset path and report seeds so results are reproducible.
683376
+ `;
683377
+ var init_SKILL11 = () => {};
683378
+
683379
+ // src/skills/bundled/rayuSkills.ts
683380
+ function getRayuSkillDefinitions() {
683381
+ const out = [];
683382
+ for (const { md: md3 } of RAYU_SKILLS) {
683383
+ const { frontmatter, content } = parseFrontmatter(md3);
683384
+ const name = typeof frontmatter.name === "string" ? frontmatter.name : "";
683385
+ const description = typeof frontmatter.description === "string" ? frontmatter.description : "";
683386
+ if (!name)
683387
+ continue;
683388
+ out.push({ name, description, body: content.trimStart() });
683389
+ }
683390
+ return out;
683391
+ }
683392
+ function registerRayuSkills() {
683393
+ for (const { name, description, body } of getRayuSkillDefinitions()) {
683394
+ registerBundledSkill({
683395
+ name,
683396
+ description,
683397
+ userInvocable: true,
683398
+ async getPromptForCommand(args) {
683399
+ const parts = [body];
683400
+ if (args) {
683401
+ parts.push(`## User Request
683402
+
683403
+ ${args}`);
683404
+ }
683405
+ return [{ type: "text", text: parts.join(`
683406
+
683407
+ `) }];
683408
+ }
683409
+ });
683410
+ }
683411
+ }
683412
+ var RAYU_SKILLS;
683413
+ var init_rayuSkills = __esm(() => {
683414
+ init_frontmatterParser();
683415
+ init_bundledSkills();
683416
+ init_SKILL();
683417
+ init_SKILL2();
683418
+ init_SKILL3();
683419
+ init_SKILL4();
683420
+ init_SKILL5();
683421
+ init_SKILL6();
683422
+ init_SKILL7();
683423
+ init_SKILL8();
683424
+ init_SKILL9();
683425
+ init_SKILL10();
683426
+ init_SKILL11();
683427
+ RAYU_SKILLS = [
683428
+ { md: SKILL_default },
683429
+ { md: SKILL_default2 },
683430
+ { md: SKILL_default3 },
683431
+ { md: SKILL_default4 },
683432
+ { md: SKILL_default5 },
683433
+ { md: SKILL_default6 },
683434
+ { md: SKILL_default7 },
683435
+ { md: SKILL_default8 },
683436
+ { md: SKILL_default9 },
683437
+ { md: SKILL_default10 },
683438
+ { md: SKILL_default11 }
683439
+ ];
683440
+ });
683441
+
682725
683442
  // src/skills/bundled/simplify.ts
682726
683443
  function registerSimplifySkill() {
682727
683444
  registerBundledSkill({
@@ -683552,18 +684269,18 @@ Documentation content for this bundled skill was not part of the imported source
683552
684269
  var init_server2 = () => {};
683553
684270
 
683554
684271
  // src/skills/bundled/verify/SKILL.md
683555
- var SKILL_default = `# SKILL (placeholder)
684272
+ var SKILL_default12 = `# SKILL (placeholder)
683556
684273
  Documentation content for this bundled skill was not part of the imported source tree.
683557
684274
  `;
683558
- var init_SKILL = () => {};
684275
+ var init_SKILL12 = () => {};
683559
684276
 
683560
684277
  // src/skills/bundled/verifyContent.ts
683561
684278
  var SKILL_MD, SKILL_FILES;
683562
684279
  var init_verifyContent = __esm(() => {
683563
684280
  init_cli();
683564
684281
  init_server2();
683565
- init_SKILL();
683566
- SKILL_MD = SKILL_default;
684282
+ init_SKILL12();
684283
+ SKILL_MD = SKILL_default12;
683567
684284
  SKILL_FILES = {
683568
684285
  "examples/cli.md": cli_default,
683569
684286
  "examples/server.md": server_default
@@ -683614,6 +684331,7 @@ function initBundledSkills() {
683614
684331
  registerSimplifySkill();
683615
684332
  registerBatchSkill();
683616
684333
  registerStuckSkill();
684334
+ registerRayuSkills();
683617
684335
  if (false) {}
683618
684336
  if (false) {}
683619
684337
  if (false) {}
@@ -683627,6 +684345,7 @@ var init_bundled = __esm(() => {
683627
684345
  init_keybindings3();
683628
684346
  init_loremIpsum();
683629
684347
  init_remember();
684348
+ init_rayuSkills();
683630
684349
  init_simplify();
683631
684350
  init_skillify();
683632
684351
  init_stuck();
@@ -684260,7 +684979,7 @@ function appendToLog(path30, message) {
684260
684979
  cwd: getFsImplementation().cwd(),
684261
684980
  userType: "external",
684262
684981
  sessionId: getSessionId(),
684263
- version: "1.3.434"
684982
+ version: "1.3.435"
684264
684983
  };
684265
684984
  getLogWriter(path30).write(messageWithTimestamp);
684266
684985
  }
@@ -684551,7 +685270,7 @@ var init_sessionMemory = __esm(() => {
684551
685270
 
684552
685271
  // src/utils/iTermBackup.ts
684553
685272
  import { copyFile as copyFile12, stat as stat48 } from "fs/promises";
684554
- import { homedir as homedir39 } from "os";
685273
+ import { homedir as homedir40 } from "os";
684555
685274
  import { join as join168 } from "path";
684556
685275
  function markITerm2SetupComplete() {
684557
685276
  saveGlobalConfig((current) => ({
@@ -684567,7 +685286,7 @@ function getIterm2RecoveryInfo() {
684567
685286
  };
684568
685287
  }
684569
685288
  function getITerm2PlistPath() {
684570
- return join168(homedir39(), "Library", "Preferences", "com.googlecode.iterm2.plist");
685289
+ return join168(homedir40(), "Library", "Preferences", "com.googlecode.iterm2.plist");
684571
685290
  }
684572
685291
  async function checkAndRestoreITerm2Backup() {
684573
685292
  const { inProgress, backupPath } = getIterm2RecoveryInfo();
@@ -688368,8 +689087,8 @@ async function getEnvLessBridgeConfig() {
688368
689087
  }
688369
689088
  async function checkEnvLessBridgeMinVersion() {
688370
689089
  const cfg = await getEnvLessBridgeConfig();
688371
- if (cfg.min_version && lt("1.3.434", cfg.min_version)) {
688372
- return `Your version of RAYU (${"1.3.434"}) is too old for Remote Control.
689090
+ if (cfg.min_version && lt("1.3.435", cfg.min_version)) {
689091
+ return `Your version of RAYU (${"1.3.435"}) is too old for Remote Control.
688373
689092
  Version ${cfg.min_version} or higher is required. Run \`claude update\` to update.`;
688374
689093
  }
688375
689094
  return null;
@@ -688843,7 +689562,7 @@ async function initBridgeCore(params) {
688843
689562
  const rawApi = createBridgeApiClient({
688844
689563
  baseUrl,
688845
689564
  getAccessToken,
688846
- runnerVersion: "1.3.434",
689565
+ runnerVersion: "1.3.435",
688847
689566
  onDebug: logForDebugging,
688848
689567
  onAuth401,
688849
689568
  getTrustedDeviceToken
@@ -694205,7 +694924,7 @@ async function startMCPServer(cwd3, debug4, verbose) {
694205
694924
  setCwd(cwd3);
694206
694925
  const server = new Server({
694207
694926
  name: "claude/tengu",
694208
- version: "1.3.434"
694927
+ version: "1.3.435"
694209
694928
  }, {
694210
694929
  capabilities: {
694211
694930
  tools: {}
@@ -695186,11 +695905,11 @@ var exports_install = {};
695186
695905
  __export(exports_install, {
695187
695906
  install: () => install
695188
695907
  });
695189
- import { homedir as homedir40 } from "node:os";
695908
+ import { homedir as homedir41 } from "node:os";
695190
695909
  import { join as join172 } from "node:path";
695191
695910
  function getInstallationPath2() {
695192
695911
  const isWindows2 = env4.platform === "win32";
695193
- const homeDir = homedir40();
695912
+ const homeDir = homedir41();
695194
695913
  if (isWindows2) {
695195
695914
  const windowsPath = join172(homeDir, ".local", "bin", "claude.exe");
695196
695915
  return windowsPath.replace(/\//g, "\\");
@@ -696731,7 +697450,7 @@ ${customInstructions}` : customInstructions;
696731
697450
  }
696732
697451
  }
696733
697452
  logForDiagnosticsNoPII("info", "started", {
696734
- version: "1.3.434",
697453
+ version: "1.3.435",
696735
697454
  is_native_binary: isInBundledMode()
696736
697455
  });
696737
697456
  registerCleanup(async () => {
@@ -697450,7 +698169,7 @@ Usage: rayu --remote "your task description"`, () => gracefulShutdown(1));
697450
698169
  pendingHookMessages
697451
698170
  }, renderAndRun);
697452
698171
  }
697453
- }).version("1.3.434 (Rayu-CLI)", "-v, --version", "Output the version number");
698172
+ }).version("1.3.435 (Rayu-CLI)", "-v, --version", "Output the version number");
697454
698173
  program.option("-w, --worktree [name]", "Create a new git worktree for this session (optionally specify a name)");
697455
698174
  program.option("--tmux", "Create a tmux session for the worktree (requires --worktree). Uses iTerm2 native panes when available; use --tmux=classic for traditional tmux.");
697456
698175
  if (canUserConfigureAdvisor()) {
@@ -697916,7 +698635,7 @@ if (false) {}
697916
698635
  async function main2() {
697917
698636
  const args = process.argv.slice(2);
697918
698637
  if (args.length === 1 && (args[0] === "--version" || args[0] === "-v" || args[0] === "-V")) {
697919
- console.log(`${"1.3.434"} (Rayu-CLI)`);
698638
+ console.log(`${"1.3.435"} (Rayu-CLI)`);
697920
698639
  return;
697921
698640
  }
697922
698641
  const {