reasonix 0.36.1 → 0.37.0
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.
- package/README.md +47 -75
- package/README.zh-CN.md +47 -32
- package/dashboard/dist/app.js +405 -196
- package/dashboard/dist/app.js.map +1 -1
- package/dist/cli/{chat-7AF5SPAJ.js → chat-7257YAPG.js} +12 -12
- package/dist/cli/{chunk-DFP4YSVM.js → chunk-6CXT5JRM.js} +17 -2
- package/dist/cli/{chunk-DFP4YSVM.js.map → chunk-6CXT5JRM.js.map} +1 -1
- package/dist/cli/{chunk-G3XNWSFN.js → chunk-6NMWJSES.js} +2 -2
- package/dist/cli/{chunk-MLXUGPJE.js → chunk-GKZJXYMY.js} +79 -1
- package/dist/cli/chunk-GKZJXYMY.js.map +1 -0
- package/dist/cli/{chunk-IPCPEZWQ.js → chunk-JGZKTAOH.js} +2 -2
- package/dist/cli/{chunk-BJ376EN3.js → chunk-JULZ7JTO.js} +3 -3
- package/dist/cli/{chunk-3OBWN2NH.js → chunk-MSKUP6PD.js} +1481 -1033
- package/dist/cli/chunk-MSKUP6PD.js.map +1 -0
- package/dist/cli/{chunk-QPNZWUZF.js → chunk-S4GF3HPO.js} +26 -1
- package/dist/cli/chunk-S4GF3HPO.js.map +1 -0
- package/dist/cli/{chunk-QRUQ2BFT.js → chunk-SEFXUF24.js} +119 -51
- package/dist/cli/chunk-SEFXUF24.js.map +1 -0
- package/dist/cli/{chunk-2MCYGFLK.js → chunk-VF57YX2M.js} +18 -17
- package/dist/cli/chunk-VF57YX2M.js.map +1 -0
- package/dist/cli/{chunk-KJQIA4US.js → chunk-XOIDSPMQ.js} +71 -32
- package/dist/cli/chunk-XOIDSPMQ.js.map +1 -0
- package/dist/cli/{chunk-ZU45XW3P.js → chunk-YER7WCHF.js} +21 -6
- package/dist/cli/chunk-YER7WCHF.js.map +1 -0
- package/dist/cli/{code-SWI4EBME.js → code-64EG5IU2.js} +24 -15
- package/dist/cli/code-64EG5IU2.js.map +1 -0
- package/dist/cli/{doctor-DKD34EFD.js → doctor-BW5HSQDW.js} +5 -5
- package/dist/cli/{events-P27CX7LN.js → events-SQXPVV7B.js} +3 -3
- package/dist/cli/index.js +28 -26
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/prompt-KGIUONO3.js +13 -0
- package/dist/cli/{prune-sessions-ERL6B4G5.js → prune-sessions-FCFOYCBP.js} +2 -2
- package/dist/cli/{run-FK5UBIIM.js → run-RWCOA32G.js} +8 -8
- package/dist/cli/{server-W4XJK4GX.js → server-6ZW4TQUP.js} +95 -49
- package/dist/cli/{server-W4XJK4GX.js.map → server-6ZW4TQUP.js.map} +1 -1
- package/dist/cli/{sessions-YZXWMIWW.js → sessions-5ISNWFMU.js} +8 -8
- package/dist/cli/{setup-IIAJXHP4.js → setup-HJG23NKJ.js} +2 -2
- package/dist/cli/{version-DWD6RLIU.js → version-BXAN7Q4V.js} +8 -8
- package/dist/index.d.ts +34 -2
- package/dist/index.js +295 -62
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/cli/chunk-2MCYGFLK.js.map +0 -1
- package/dist/cli/chunk-3OBWN2NH.js.map +0 -1
- package/dist/cli/chunk-KJQIA4US.js.map +0 -1
- package/dist/cli/chunk-MLXUGPJE.js.map +0 -1
- package/dist/cli/chunk-QPNZWUZF.js.map +0 -1
- package/dist/cli/chunk-QRUQ2BFT.js.map +0 -1
- package/dist/cli/chunk-ZU45XW3P.js.map +0 -1
- package/dist/cli/code-SWI4EBME.js.map +0 -1
- package/dist/cli/prompt-YEKXMNNV.js +0 -11
- /package/dist/cli/{chat-7AF5SPAJ.js.map → chat-7257YAPG.js.map} +0 -0
- /package/dist/cli/{chunk-G3XNWSFN.js.map → chunk-6NMWJSES.js.map} +0 -0
- /package/dist/cli/{chunk-IPCPEZWQ.js.map → chunk-JGZKTAOH.js.map} +0 -0
- /package/dist/cli/{chunk-BJ376EN3.js.map → chunk-JULZ7JTO.js.map} +0 -0
- /package/dist/cli/{doctor-DKD34EFD.js.map → doctor-BW5HSQDW.js.map} +0 -0
- /package/dist/cli/{events-P27CX7LN.js.map → events-SQXPVV7B.js.map} +0 -0
- /package/dist/cli/{prompt-YEKXMNNV.js.map → prompt-KGIUONO3.js.map} +0 -0
- /package/dist/cli/{prune-sessions-ERL6B4G5.js.map → prune-sessions-FCFOYCBP.js.map} +0 -0
- /package/dist/cli/{run-FK5UBIIM.js.map → run-RWCOA32G.js.map} +0 -0
- /package/dist/cli/{sessions-YZXWMIWW.js.map → sessions-5ISNWFMU.js.map} +0 -0
- /package/dist/cli/{setup-IIAJXHP4.js.map → setup-HJG23NKJ.js.map} +0 -0
- /package/dist/cli/{version-DWD6RLIU.js.map → version-BXAN7Q4V.js.map} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/prompt-fragments.ts","../../src/memory/project.ts","../../src/skills.ts"],"sourcesContent":["/** Shared prompt fragments — single source so house-style rules can't drift across agent/subagent/skill prompts. */\n\n/** Embedded literally — no interpolation, so prefix-cache hash stays stable across sessions. */\nexport const TUI_FORMATTING_RULES = `Formatting (rendered in a TUI with a real markdown renderer):\n- Tabular data → GitHub-Flavored Markdown tables with ASCII pipes (\\`| col | col |\\` header + \\`| --- | --- |\\` separator). Never use Unicode box-drawing characters (│ ─ ┼ ┌ ┐ └ ┘ ├ ┤) — they look intentional but break terminal word-wrap and render as garbled columns at narrow widths.\n- Keep table cells short (one phrase each). If a cell needs a paragraph, use bullets below the table instead.\n- Code, file paths with line ranges, and shell commands → fenced code blocks (\\`\\`\\`).\n- Do NOT draw decorative frames around content with \\`┌──┐ │ └──┘\\` characters. The renderer adds its own borders; extra ASCII art adds noise and shatters at narrow widths.\n- For flow charts and diagrams: a plain bullet list with \\`→\\` or \\`↓\\` between steps. Don't try to draw boxes-and-arrows in ASCII; it never survives word-wrap.`;\n\nexport const ESCALATION_CONTRACT = `Cost-aware escalation (when you're running on deepseek-v4-flash):\n\nIf a task CLEARLY exceeds what flash can do well — complex cross-file architecture refactors, subtle concurrency / security / correctness invariants you can't resolve with confidence, or a design trade-off you'd be guessing at — output the marker as the FIRST line of your response (nothing before it, not even whitespace on a separate line). This aborts the current call and retries this turn on deepseek-v4-pro, one shot.\n\nTwo accepted forms:\n- \\`<<<NEEDS_PRO>>>\\` — bare marker, no rationale.\n- \\`<<<NEEDS_PRO: <one-sentence reason>>>>\\` — preferred. The reason text appears in the user-visible warning (\"⇧ flash requested escalation — <your reason>\"), so they understand WHY a more expensive call is happening. Keep it under ~150 chars, no newlines, no nested \\`>\\` characters. Examples: \\`<<<NEEDS_PRO: cross-file refactor across 6 modules with circular imports>>>\\` or \\`<<<NEEDS_PRO: subtle session-token race; flash would likely miss the locking invariant>>>\\`.\n\nDo NOT emit any other content in the same response when you request escalation. Use this sparingly: normal tasks — reading files, small edits, clear bug fixes, straightforward feature additions — stay on flash. Request escalation ONLY when you would otherwise produce a guess or a visibly-mediocre answer. If in doubt, attempt the task on flash first; the system also escalates automatically if you hit 3+ repair / SEARCH-mismatch errors in a single turn (the user sees a typed breakdown).`;\n\nexport const NEGATIVE_CLAIM_RULE = `Negative claims (\"X is missing\", \"Y isn't implemented\", \"there's no Z\") are the #1 hallucination shape. They feel safe to write because no citation seems possible — but that's exactly why you must NOT write them on instinct.\n\nIf you have a search tool (\\`search_content\\`, \\`grep\\`, web search), call it FIRST before asserting absence:\n- Returns matches → you were wrong; correct yourself and cite the matches.\n- Returns nothing → state the absence WITH the search query as evidence: \\`No callers of \\\\\\`foo()\\\\\\` found (search_content \"foo\").\\`\n\nIf you have no search tool, qualify hard: \"I haven't verified — this is a guess.\" Never assert absence with fake authority.`;\n","/** REASONIX.md pinned into ImmutablePrefix.system; edits invalidate the prefix-cache fingerprint. */\n\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nexport const PROJECT_MEMORY_FILE = \"REASONIX.md\";\nexport const PROJECT_MEMORY_MAX_CHARS = 8000;\n\nexport interface ProjectMemory {\n /** Absolute path the memory was read from. */\n path: string;\n /** Post-truncation content (may include a \"… (truncated N chars)\" marker). */\n content: string;\n /** Original byte length before truncation. */\n originalChars: number;\n /** True iff `originalChars > PROJECT_MEMORY_MAX_CHARS`. */\n truncated: boolean;\n}\n\n/** Empty / whitespace-only files return null so they don't perturb the cache prefix. */\nexport function readProjectMemory(rootDir: string): ProjectMemory | null {\n const path = join(rootDir, PROJECT_MEMORY_FILE);\n if (!existsSync(path)) return null;\n let raw: string;\n try {\n raw = readFileSync(path, \"utf8\");\n } catch {\n return null;\n }\n const trimmed = raw.trim();\n if (!trimmed) return null;\n const originalChars = trimmed.length;\n const truncated = originalChars > PROJECT_MEMORY_MAX_CHARS;\n const content = truncated\n ? `${trimmed.slice(0, PROJECT_MEMORY_MAX_CHARS)}\\n… (truncated ${\n originalChars - PROJECT_MEMORY_MAX_CHARS\n } chars)`\n : trimmed;\n return { path, content, originalChars, truncated };\n}\n\nexport function memoryEnabled(): boolean {\n const env = process.env.REASONIX_MEMORY;\n if (env === \"off\" || env === \"false\" || env === \"0\") return false;\n return true;\n}\n\n/** Deterministic — same memory file always yields the same prefix hash. */\nexport function applyProjectMemory(basePrompt: string, rootDir: string): string {\n if (!memoryEnabled()) return basePrompt;\n const mem = readProjectMemory(rootDir);\n if (!mem) return basePrompt;\n return `${basePrompt}\n\n# Project memory (REASONIX.md)\n\nThe user pinned these notes about this project — treat them as authoritative context for every turn:\n\n\\`\\`\\`\n${mem.content}\n\\`\\`\\`\n`;\n}\n","/** Project scope wins over global. Only names+descriptions enter the prefix; bodies load lazily into the append-only log. */\n\nimport { existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { NEGATIVE_CLAIM_RULE, TUI_FORMATTING_RULES } from \"./prompt-fragments.js\";\n\nexport const SKILLS_DIRNAME = \"skills\";\nexport const SKILL_FILE = \"SKILL.md\";\n/** Cap on the pinned skills-index block, mirrors memory-index cap. */\nexport const SKILLS_INDEX_MAX_CHARS = 4000;\n/** Skill identifier shape — alnum + `_` + `-` + interior `.`, 1-64 chars. */\nconst VALID_SKILL_NAME = /^[a-zA-Z0-9][a-zA-Z0-9._-]{0,63}$/;\n\nexport type SkillScope = \"project\" | \"global\" | \"builtin\";\n\n/** inline = body enters parent log; subagent = isolated child loop, only final answer returns. */\nexport type SkillRunAs = \"inline\" | \"subagent\";\n\nexport interface Skill {\n /** Canonical name — sanitized, matches the directory / filename stem. */\n name: string;\n /** One-line description shown in the pinned index. */\n description: string;\n /** Full markdown body (post-frontmatter). Loaded on demand. */\n body: string;\n /** Which scope this skill was loaded from. */\n scope: SkillScope;\n /** Absolute path to the SKILL.md (or {name}.md) file, or \"(builtin)\" for shipped defaults. */\n path: string;\n /** Parsed `allowed-tools` frontmatter — when present, the spawned subagent's registry is scoped to these literal tool names. */\n allowedTools?: readonly string[];\n runAs: SkillRunAs;\n /** Subagent model override; only meaningful when `runAs === \"subagent\"`. */\n model?: string;\n}\n\nexport interface SkillStoreOptions {\n /** Override `$HOME` — tests point this at a tmpdir. */\n homeDir?: string;\n /** Required for project-scope skills; omit to read only the global scope. */\n projectRoot?: string;\n /** Suppress bundled built-ins — for tests asserting exact list contents. */\n disableBuiltins?: boolean;\n}\n\nfunction parseFrontmatter(raw: string): { data: Record<string, string>; body: string } {\n const lines = raw.split(/\\r?\\n/);\n if (lines[0] !== \"---\") return { data: {}, body: raw };\n const end = lines.indexOf(\"---\", 1);\n if (end < 0) return { data: {}, body: raw };\n const data: Record<string, string> = {};\n for (let i = 1; i < end; i++) {\n const line = lines[i];\n if (!line) continue;\n const m = line.match(/^([a-zA-Z_][a-zA-Z0-9_-]*):\\s*(.*)$/);\n if (m?.[1]) data[m[1]] = (m[2] ?? \"\").trim();\n }\n return {\n data,\n body: lines\n .slice(end + 1)\n .join(\"\\n\")\n .replace(/^\\n+/, \"\"),\n };\n}\n\nfunction isValidSkillName(name: string): boolean {\n return VALID_SKILL_NAME.test(name);\n}\n\nfunction parseAllowedTools(raw: string | undefined): readonly string[] | undefined {\n if (raw === undefined) return undefined;\n const names = raw\n .split(\",\")\n .map((s) => s.trim())\n .filter(Boolean);\n return names.length > 0 ? Object.freeze(names) : undefined;\n}\n\nexport class SkillStore {\n private readonly homeDir: string;\n private readonly projectRoot: string | undefined;\n private readonly disableBuiltins: boolean;\n\n constructor(opts: SkillStoreOptions = {}) {\n this.homeDir = opts.homeDir ?? homedir();\n this.projectRoot = opts.projectRoot ? resolve(opts.projectRoot) : undefined;\n this.disableBuiltins = opts.disableBuiltins === true;\n }\n\n /** True iff this store was configured with a project root. */\n hasProjectScope(): boolean {\n return this.projectRoot !== undefined;\n }\n\n /** Project scope first so per-repo skill overrides a global with the same name. */\n roots(): Array<{ dir: string; scope: SkillScope }> {\n const out: Array<{ dir: string; scope: SkillScope }> = [];\n if (this.projectRoot) {\n out.push({\n dir: join(this.projectRoot, \".reasonix\", SKILLS_DIRNAME),\n scope: \"project\",\n });\n }\n out.push({ dir: join(this.homeDir, \".reasonix\", SKILLS_DIRNAME), scope: \"global\" });\n return out;\n }\n\n /** Higher-priority root wins on collision (project > global > builtin); sorted for stable prefix hash. */\n list(): Skill[] {\n const byName = new Map<string, Skill>();\n for (const { dir, scope } of this.roots()) {\n if (!existsSync(dir)) continue;\n let entries: import(\"node:fs\").Dirent[];\n try {\n entries = readdirSync(dir, { withFileTypes: true });\n } catch {\n continue;\n }\n for (const entry of entries) {\n const skill = this.readEntry(dir, scope, entry);\n if (!skill) continue;\n if (!byName.has(skill.name)) byName.set(skill.name, skill);\n }\n }\n // Builtins last so user/project files override on name collision.\n if (!this.disableBuiltins) {\n for (const skill of BUILTIN_SKILLS) {\n if (!byName.has(skill.name)) byName.set(skill.name, skill);\n }\n }\n return [...byName.values()].sort((a, b) => a.name.localeCompare(b.name));\n }\n\n /** Scaffold a new skill stub at the chosen scope. Refuses to overwrite. */\n create(name: string, scope: \"project\" | \"global\"): { path: string } | { error: string } {\n return this.createWithContent(name, scope, skillStubBody(name));\n }\n\n /** Like `create` but writes caller-supplied file contents instead of the stub — used by the scaffold tool. */\n createWithContent(\n name: string,\n scope: \"project\" | \"global\",\n content: string,\n ): { path: string } | { error: string } {\n if (!isValidSkillName(name)) {\n return { error: `invalid skill name: \"${name}\" — use letters, digits, _, -, .` };\n }\n if (scope === \"project\" && !this.projectRoot) {\n return { error: \"project scope requires a workspace — run from `reasonix code`\" };\n }\n const root =\n scope === \"project\"\n ? join(this.projectRoot ?? \"\", \".reasonix\", SKILLS_DIRNAME)\n : join(this.homeDir, \".reasonix\", SKILLS_DIRNAME);\n const flat = join(root, `${name}.md`);\n const folder = join(root, name, SKILL_FILE);\n if (existsSync(folder)) {\n return { error: `skill \"${name}\" already exists at ${folder}` };\n }\n mkdirSync(dirname(flat), { recursive: true });\n try {\n writeFileSync(flat, content, { encoding: \"utf8\", flag: \"wx\" });\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"EEXIST\") {\n return { error: `skill \"${name}\" already exists at ${flat}` };\n }\n throw err;\n }\n return { path: flat };\n }\n\n /** Resolve one skill by name. Returns `null` if not found or malformed. */\n read(name: string): Skill | null {\n if (!isValidSkillName(name)) return null;\n for (const { dir, scope } of this.roots()) {\n if (!existsSync(dir)) continue;\n const dirCandidate = join(dir, name, SKILL_FILE);\n if (existsSync(dirCandidate) && statSync(dirCandidate).isFile()) {\n return this.parse(dirCandidate, name, scope);\n }\n const flatCandidate = join(dir, `${name}.md`);\n if (existsSync(flatCandidate) && statSync(flatCandidate).isFile()) {\n return this.parse(flatCandidate, name, scope);\n }\n }\n if (!this.disableBuiltins) {\n for (const skill of BUILTIN_SKILLS) {\n if (skill.name === name) return skill;\n }\n }\n return null;\n }\n\n private readEntry(dir: string, scope: SkillScope, entry: import(\"node:fs\").Dirent): Skill | null {\n if (entry.isDirectory()) {\n if (!isValidSkillName(entry.name)) return null;\n const file = join(dir, entry.name, SKILL_FILE);\n if (!existsSync(file)) return null;\n return this.parse(file, entry.name, scope);\n }\n if (entry.isFile() && entry.name.endsWith(\".md\")) {\n const stem = entry.name.slice(0, -3);\n if (!isValidSkillName(stem)) return null;\n return this.parse(join(dir, entry.name), stem, scope);\n }\n return null;\n }\n\n private parse(path: string, stem: string, scope: SkillScope): Skill | null {\n let raw: string;\n try {\n raw = readFileSync(path, \"utf8\");\n } catch {\n return null;\n }\n const { data, body } = parseFrontmatter(raw);\n const name = data.name && isValidSkillName(data.name) ? data.name : stem;\n return {\n name,\n description: (data.description ?? \"\").trim(),\n body: body.trim(),\n scope,\n path,\n allowedTools: parseAllowedTools(data[\"allowed-tools\"]),\n runAs: parseRunAs(data.runAs),\n model: data.model?.startsWith(\"deepseek-\") ? data.model : undefined,\n };\n }\n}\n\n/** Unknown values default to the safe (non-spawning) `inline` mode. */\nfunction parseRunAs(raw: string | undefined): SkillRunAs {\n return raw?.trim() === \"subagent\" ? \"subagent\" : \"inline\";\n}\n\n/** Stub markdown for `/skill new` — minimal frontmatter + scaffolding the user fills in. */\nfunction skillStubBody(name: string): string {\n return `---\nname: ${name}\ndescription: One-liner — what does this skill do?\n---\n\n# ${name}\n\nReplace this body with the playbook the model should follow when this skill is invoked.\n\nTips:\n- Reference tools by name (run_command, edit_file, search_content, ...)\n- Add \\`runAs: subagent\\` to frontmatter to spawn an isolated subagent loop\n- Add \\`allowed-tools: read_file, search_content\\` to scope a subagent's tools\n`;\n}\n\n/** Subagent tag goes AFTER the name in brackets — leading-marker tags get copied into `name` arg verbatim. */\nfunction skillIndexLine(s: Pick<Skill, \"name\" | \"description\" | \"runAs\">): string {\n const safeDesc = s.description.replace(/\\n/g, \" \").trim();\n const tag = s.runAs === \"subagent\" ? \" [🧬 subagent]\" : \"\";\n const max = 130 - s.name.length - tag.length;\n const clipped = safeDesc.length > max ? `${safeDesc.slice(0, Math.max(1, max - 1))}…` : safeDesc;\n return clipped ? `- ${s.name}${tag} — ${clipped}` : `- ${s.name}${tag}`;\n}\n\n/** Bodies stay out — prefix must stay short + cacheable; bodies load on demand. */\nexport function applySkillsIndex(basePrompt: string, opts: SkillStoreOptions = {}): string {\n const store = new SkillStore(opts);\n const skills = store.list().filter((s) => s.description);\n if (skills.length === 0) return basePrompt;\n const lines = skills.map(skillIndexLine);\n const joined = lines.join(\"\\n\");\n const truncated =\n joined.length > SKILLS_INDEX_MAX_CHARS\n ? `${joined.slice(0, SKILLS_INDEX_MAX_CHARS)}\\n… (truncated ${\n joined.length - SKILLS_INDEX_MAX_CHARS\n } chars)`\n : joined;\n return [\n basePrompt,\n \"\",\n \"# Skills — playbooks you can invoke\",\n \"\",\n 'One-liner index. Each entry is either a built-in or a user-authored playbook. Call `run_skill({ name: \"<skill-name>\", arguments: \"<task>\" })` — the `name` is JUST the skill identifier (e.g. `\"explore\"`), NOT the `[🧬 subagent]` tag that appears after it. Entries tagged `[🧬 subagent]` spawn an **isolated subagent** — its tool calls and reasoning never enter your context, only its final answer does. Use subagent skills for tasks that would otherwise flood your context (deep exploration, multi-step research, anything where you only need the conclusion). Plain skills are inlined: their body becomes a tool result you read and act on directly. The user can also invoke a skill via `/skill <name>`.',\n \"\",\n \"```\",\n truncated,\n \"```\",\n ].join(\"\\n\");\n}\n\nconst BUILTIN_EXPLORE_BODY = `You are running as an exploration subagent. Your job is to investigate the codebase the parent agent pointed you at, then return one focused, distilled answer.\n\nHow to operate:\n- Use read_file, search_files, search_content, directory_tree, list_directory, get_file_info as your primary tools. Stay read-only.\n- For \"find all places that call / reference / use X\" questions, use \\`search_content\\` (content grep) — NOT \\`search_files\\` (which only matches file names). This is the most common subagent mistake; using the wrong tool gives empty results and you waste your iter budget chasing a phantom.\n- Cast a wide net first (search_content for symbol references, directory_tree for structure) to map the territory; then read the 3-10 most relevant files in full.\n- Don't read every file — be selective. Aim for breadth on the first pass, depth only where the question demands it.\n- Stop exploring as soon as you can answer the question. The parent doesn't see your tool calls, so over-exploration is pure waste.\n\nYour final answer:\n- One paragraph (or a few short bullets). Lead with the conclusion.\n- Cite specific file paths + line ranges when they support the answer.\n- If the question can't be answered from what you found, say so plainly and suggest where to look next.\n- No follow-up offers, no \"let me know if you need more.\" The parent will ask again if they need more.\n\n${NEGATIVE_CLAIM_RULE}\n\n${TUI_FORMATTING_RULES}\n\nThe 'task' the parent gave you is the question you must answer. Treat any other reading of it as scope creep.`;\n\nconst BUILTIN_RESEARCH_BODY = `You are running as a research subagent. Your job is to gather information from code AND the web, synthesize it, and return one focused conclusion.\n\nHow to operate:\n- Combine code reading (read_file, search_files) with web tools (web_search, web_fetch) as appropriate to the question.\n- For \"how does X work\" / \"is Y supported\" questions: web first to find the canonical reference, then verify against the local code.\n- For \"what's our policy on Z\" / \"where do we use Q\": local code first, web only if you need to compare against external standards.\n- Cap yourself at ~10 tool calls. If you can't converge in 10, return what you have plus a note about what's missing.\n\nYour final answer:\n- One paragraph (or short bullets). Lead with the conclusion.\n- Cite both code (file:line) AND web sources (URL) when they back the answer.\n- Distinguish \"I verified this in code\" from \"I read this on a docs page\" — the parent will trust the former more.\n- If the answer is uncertain, say so. Don't invent confidence.\n\n${NEGATIVE_CLAIM_RULE}\n\n${TUI_FORMATTING_RULES}\n\nThe 'task' the parent gave you is the research question. Stay on it.`;\n\nconst BUILTIN_REVIEW_BODY = `You are running as a code-review subagent. Your job is to inspect the changes the user is about to ship — usually the current git branch vs its upstream — and produce a focused review the parent can hand back to the user.\n\nHow to operate:\n- Default scope: the current branch's diff vs the default branch. If the user's task names a specific commit range or files, honor that instead.\n- Discover scope first: \\`run_command git status\\`, \\`git diff --stat\\`, \\`git log --oneline\\` to see what changed. Then \\`git diff\\` (or \\`git diff <base>...HEAD\\`) for the actual hunks.\n- Read the touched files (\\`read_file\\`) when the diff alone doesn't carry enough context — function signatures, surrounding invariants, callers.\n- For \"any callers depending on this?\" questions: \\`search_content\\` against the symbol BEFORE asserting impact.\n- Stay read-only. Never \\`run_command git commit\\`, never write files, never propose SEARCH/REPLACE blocks. The parent decides whether to act on your findings.\n- Cap yourself at ~12 tool calls. If the diff is too big to review in one pass, pick the riskiest 2-3 files and say so explicitly.\n\nWhat to look for, in priority order:\n1. **Correctness bugs** — off-by-one, null/undefined handling, race conditions, wrong sign / wrong operator, edge cases the code doesn't handle.\n2. **Security** — injection (SQL, shell, path traversal), secrets in code, missing authz checks, unsafe deserialization.\n3. **Behavior changes the diff hides** — renames that miss callers, removed branches that were load-bearing, error-handling that now swallows what used to surface.\n4. **Tests** — does the change have tests for the new behavior? Are existing tests still meaningful, or did the change make them tautological?\n5. **Style + consistency** — only flag deviations that matter (unsafe \\`any\\`, missing types in TypeScript, inconsistent error shape). Don't pile on cosmetic nits if the substance is clean.\n\nYour final answer:\n- Lead with a one-sentence verdict: \"ship as-is\" / \"minor nits, OK to ship after\" / \"blocking issues, do not ship\".\n- Then a short bulleted list of issues, each with: file:line citation + the problem in one sentence + what to change.\n- Group by severity if you have more than 4 items: **Blocking**, **Should-fix**, **Nits**.\n- If everything looks clean, say so plainly. Don't manufacture concerns.\n\n${NEGATIVE_CLAIM_RULE}\n\n${TUI_FORMATTING_RULES}\n\nThe 'task' the parent gave you describes WHAT to review (a branch, a file set, or \"the pending changes\"). Stay on it; don't redesign the feature.`;\n\nconst BUILTIN_SECURITY_REVIEW_BODY = `You are running as a security-review subagent. Your job is to inspect the changes the user is about to ship — usually the current git branch vs its upstream — through a security lens specifically, and report exploitable issues.\n\nHow to operate:\n- Default scope: the current branch's diff vs the default branch. If the user names a different range or a directory, honor that.\n- Discover scope first: \\`git status\\`, \\`git diff --stat\\`, \\`git diff <base>...HEAD\\`. Read touched files (\\`read_file\\`) when the diff alone doesn't carry security context — auth checks, input validation, the actual handler that calls into the changed function.\n- Use \\`search_content\\` to verify \"is this user-controlled input ever sanitized later?\" / \"are there other call sites that depend on this validation?\" before asserting impact.\n- Stay read-only. Never write, never run destructive commands, never propose SEARCH/REPLACE blocks. The parent decides what to act on.\n- Cap yourself at ~12 tool calls. If the diff is too big, focus on the riskiest 2-3 files and say so explicitly.\n\nThreat model — flag with severity:\n\n**CRITICAL** (do-not-ship):\n- SQL / NoSQL / shell / template injection — user input concatenated into a query, command, or template without parameterization.\n- Path traversal — user-controlled filenames touching the filesystem without canonicalization + sandbox check.\n- Authentication / authorization missing — endpoints / actions that should require a session check but don't.\n- Hardcoded secrets — API keys, passwords, signing tokens visible in the diff.\n- Deserialization of untrusted input — \\`pickle.loads\\`, \\`yaml.load\\` (non-safe), \\`eval\\`, \\`Function()\\`, \\`unserialize()\\`.\n- Cryptographic mistakes — homemade crypto, weak hashes (MD5/SHA-1) for passwords, missing IVs, ECB mode, predictable nonces.\n\n**HIGH**:\n- XSS — user input rendered into HTML without escaping (or wrong escaping context).\n- SSRF — fetching URLs from user input without an allowlist.\n- Race conditions in security-relevant code — TOCTOU on auth/file checks.\n- Open redirects — user-controlled URL passed to a redirect helper.\n- Insufficient logging on security events (login failure, permission denial) — only flag if the codebase clearly DOES log elsewhere.\n\n**MEDIUM**:\n- Verbose error messages leaking internal paths / stack traces / SQL.\n- Missing rate limiting on a credential / token endpoint.\n- Cross-origin / cookie-flag issues (missing \\`Secure\\` / \\`HttpOnly\\` / \\`SameSite\\`).\n\nThings to NOT pile on (out of scope here — the regular /review covers them):\n- Style, formatting, naming.\n- Performance, refactor opportunities, test coverage gaps that aren't security-relevant.\n- \"Should be a constant\" / \"extract this helper\" — irrelevant to ship-blocking.\n\nYour final answer:\n- Lead with a one-sentence verdict: \"no security issues found\", \"minor concerns\", or \"blocking issues\".\n- Then a list grouped by severity. Each item: file:line + 1-sentence threat + 1-sentence fix direction (no full SEARCH/REPLACE — the user / parent agent will write that).\n- If clean, say so plainly. Don't manufacture findings.\n\n${NEGATIVE_CLAIM_RULE}\n\n${TUI_FORMATTING_RULES}\n\nThe 'task' the parent gave you names what to review. Stay on it; don't redesign the feature.`;\n\nconst BUILTIN_TEST_BODY = `You are running as the parent agent — this skill is INLINED, not a subagent. The user invoked /test (or asked you to \"run the tests and fix failures\"). Your job: run the project's test suite, diagnose any failure, propose fixes as SEARCH/REPLACE edit blocks, then re-run. Repeat until green or you hit a wall you should escalate.\n\nHow to operate:\n\n1. **Detect the test command**.\n - Look for \\`package.json\\` → \\`scripts.test\\` first (most common: \\`npm test\\`, \\`pnpm test\\`, \\`yarn test\\`).\n - If no package.json or no test script: try \\`pytest\\`, \\`go test ./...\\`, \\`cargo test\\` based on what files exist (pyproject.toml/requirements.txt → pytest; go.mod → go test; Cargo.toml → cargo test).\n - If you can't tell, ASK the user for the command — don't guess. One question, one tool call to confirm.\n\n2. **Run it via run_command** (typical timeout 120s, bigger if the suite is large). Capture stdout + stderr.\n\n3. **Read the failures**. Pull out: which test names failed, the actual error/traceback, the file + line that threw. Don't just paraphrase — locate the exact assertion or stack frame.\n\n4. **Propose fixes**. For each distinct failure:\n - If the failure is in PRODUCTION code (test catches a real bug) → propose a SEARCH/REPLACE that fixes the production code.\n - If the failure is in TEST code (test is wrong, codebase is right) → propose a SEARCH/REPLACE that updates the test, AND say so explicitly: \"This is a test bug, not a production bug — updating the assertion.\"\n - If the failure is environmental (missing dep, wrong node version, missing fixture file) → say so and stop. Don't try to install packages or change config without checking with the user.\n\n5. **Apply + re-run**. After the user accepts the edit blocks, run the test command again. Iterate.\n\n6. **Stop conditions**:\n - All tests pass → report green, summarize what changed.\n - Same test still failing after 2 fix attempts on the same line → STOP. Tell the user \"I've tried twice, it's still failing — here's what I think is happening, want me to try a different angle?\". Don't loop indefinitely.\n - 3+ unrelated failures → fix one at a time, smallest first, so each pass narrows the surface.\n\nDon't:\n- Run \\`npm install\\` / \\`pip install\\` / \\`cargo update\\` without asking — those mutate lockfiles and have global effects.\n- Disable, skip, or delete failing tests to \"make it green\". If a test seems wrong, update its assertion with a one-sentence explanation, but never add \\`.skip\\` / \\`it.skip\\` / \\`@pytest.mark.skip\\`.\n- Modify the test runner config (vitest.config, jest.config, etc.) to silence failures.\n\nLead each turn with a one-line status: \"▸ running \\`npm test\\` ...\" → \"▸ 2 failures in tests/foo.test.ts — first is …\" → so the user always knows where you are without scrolling tool output.`;\n\nconst BUILTIN_SKILLS: readonly Skill[] = Object.freeze([\n Object.freeze<Skill>({\n name: \"explore\",\n description:\n \"Explore the codebase in an isolated subagent — wide-net read-only investigation that returns one distilled answer. Best for: 'find all places that...', 'how does X work across the project', 'survey the code for Y'.\",\n body: BUILTIN_EXPLORE_BODY,\n scope: \"builtin\",\n path: \"(builtin)\",\n runAs: \"subagent\",\n }),\n Object.freeze<Skill>({\n name: \"research\",\n description:\n \"Research a question by combining web search + code reading in an isolated subagent. Best for: 'is X feature supported by lib Y', 'what's the canonical way to do Z', 'compare our impl against the spec'.\",\n body: BUILTIN_RESEARCH_BODY,\n scope: \"builtin\",\n path: \"(builtin)\",\n runAs: \"subagent\",\n }),\n Object.freeze<Skill>({\n name: \"review\",\n description:\n \"Review the pending changes (current branch diff by default) in an isolated subagent — flags correctness, security, missing tests, hidden behavior changes; reports verdict + per-issue file:line. Read-only; the parent decides what to act on.\",\n body: BUILTIN_REVIEW_BODY,\n scope: \"builtin\",\n path: \"(builtin)\",\n runAs: \"subagent\",\n }),\n Object.freeze<Skill>({\n name: \"security-review\",\n description:\n \"Security-focused review of the current branch diff in an isolated subagent — flags injection/authz/secrets/deserialization/path-traversal/crypto issues, severity-tagged. Read-only. Use when shipping changes that touch auth, input parsing, file IO, or external requests.\",\n body: BUILTIN_SECURITY_REVIEW_BODY,\n scope: \"builtin\",\n path: \"(builtin)\",\n runAs: \"subagent\",\n }),\n Object.freeze<Skill>({\n name: \"test\",\n description:\n \"Run the project's test suite, diagnose failures, propose SEARCH/REPLACE fixes, re-run until green (or stop after 2 fix attempts on the same failure). Inlined — runs in the parent loop so you see the edit blocks and can /apply them. Detects npm/pnpm/yarn/pytest/go/cargo.\",\n body: BUILTIN_TEST_BODY,\n scope: \"builtin\",\n path: \"(builtin)\",\n runAs: \"inline\",\n }),\n]);\n"],"mappings":"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","names":["existsSync","readFileSync","join","join","existsSync","readFileSync"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/i18n/EN.ts","../../src/i18n/zh-CN.ts","../../src/i18n/index.ts"],"sourcesContent":["import type { TranslationSchema } from \"./types.js\";\n\nexport const EN: TranslationSchema = {\n common: {\n error: \"Error\",\n warning: \"Warning\",\n loading: \"Loading...\",\n done: \"Done\",\n cancel: \"Cancel\",\n confirm: \"Confirm\",\n back: \"Back\",\n next: \"Next\",\n },\n cli: {\n description: \"DeepSeek-native agent framework — built for cache hits and cheap tokens.\",\n continue: \"Resume the most recently used chat session without showing the picker.\",\n setup: \"Interactive wizard — API key, preset, MCP servers. Re-run any time to reconfigure.\",\n code: \"Code-editing chat — filesystem tools rooted at <dir> (default: cwd), coding system prompt, v4-flash baseline.\",\n chat: \"Interactive Ink TUI with live cache/cost panel.\",\n run: \"Run a single task non-interactively, streaming output.\",\n stats: \"Show usage dashboard.\",\n doctor: \"One-command health check.\",\n commit: \"Draft a commit message from the staged diff.\",\n sessions: \"List saved chat sessions, or inspect one by name.\",\n pruneSessions: \"Delete saved sessions idle ≥N days (default 90). Use --dry-run to preview.\",\n events: \"Pretty-print the kernel event-log sidecar.\",\n replay: \"Interactive Ink TUI to scrub through a transcript.\",\n diff: \"Compare two transcripts in a split-pane Ink TUI.\",\n mcp: \"Model Context Protocol helpers — discover servers, test your setup.\",\n version: \"Print Reasonix version.\",\n update: \"Check for a newer Reasonix and install it.\",\n index: \"Build (or incrementally refresh) a local semantic search index.\",\n },\n ui: {\n welcome: \"Run `reasonix` any time to start chatting — your settings are remembered.\",\n taglineChat: \"DeepSeek-native agent\",\n taglineCode: \"DeepSeek-native coding agent\",\n taglineSub: \"cache-first · flash-first\",\n startSessionHint: \"type a message to start your session\",\n inputPlaceholder: \"Ask anything... (type / for commands, @ for files)\",\n busy: \"Thinking...\",\n thinking: \"▸ thinking...\",\n undo: \"Undo\",\n undoHint: \"press u within 5s to undo\",\n applied: \"applied\",\n rejected: \"rejected\",\n noDashboard: \"Suppress the auto-launched embedded web dashboard.\",\n dashboardAutoStartFailed:\n \"▲ dashboard auto-start failed ({reason}) — try /dashboard, or pass --no-dashboard to silence\",\n systemAppendHint:\n \"Append instructions to the code system prompt. Does NOT replace the default prompt — adds after it.\",\n systemAppendFileHint:\n \"Append file contents to the code system prompt. Does NOT replace the default prompt. UTF-8, relative to cwd or absolute.\",\n resumedSession:\n '▸ resumed session \"{name}\" with {count} prior messages · /forget to start over · /sessions to list',\n newSession:\n '▸ session \"{name}\" (new) — auto-saved as you chat · /forget to delete · /sessions to list',\n ephemeralSession: \"▸ ephemeral chat (no session persistence) — drop --no-session to enable\",\n restoredEdits:\n \"▸ restored {count} pending edit block(s) from an interrupted prior run — /apply to commit or /discard to drop.\",\n resumedPlan: \"Resumed plan · {when}{summary}\",\n tipEditBindings: {\n topic: \"edit-gate keybindings\",\n sections: [\n {\n rows: [\n { key: \"y / n\", text: \"accept or drop pending edits\" },\n {\n key: \"Shift+Tab\",\n text: \"switch review ↔ AUTO (persisted; AUTO applies instantly)\",\n },\n { key: \"u\", text: \"undo the last auto-applied batch (within the 5s banner)\" },\n ],\n },\n ],\n footer: \"Current mode shown in the bottom status bar · /keys for the full reference\",\n },\n tipMouseClipboard: {\n topic: \"mouse + clipboard\",\n sections: [\n {\n rows: [\n { key: \"drag\", text: \"select text — terminal-native, no modifier needed\" },\n {\n key: \"right-click\",\n text: \"your terminal's native menu (paste / copy on Windows Terminal etc.)\",\n },\n { key: \"wheel\", text: \"scrolls chat history (works on web/cloud/SSH terminals too)\" },\n {\n key: \"↑ / ↓\",\n text: \"scroll chat · use Ctrl+P / Ctrl+N for prompt history + multi-line cursor\",\n },\n ],\n },\n ],\n footer: \"Run /keys for the full keyboard + mouse reference\",\n },\n keysReference: {\n topic: \"Reasonix keys + mouse reference\",\n sections: [\n {\n title: \"keyboard\",\n rows: [\n { key: \"Enter\", text: \"submit the prompt\" },\n { key: \"Shift+Enter\", text: \"insert a newline in the prompt\" },\n { key: \"↑ / ↓\", text: \"scroll chat history (mouse wheel routes here too)\" },\n {\n key: \"Ctrl+P / Ctrl+N\",\n text: \"previous / next prompt history · cursor up / down in a multi-line draft\",\n },\n { key: \"Ctrl+A / Ctrl+E\", text: \"jump to start / end of the current line\" },\n { key: \"Ctrl+W\", text: \"delete the word before the cursor\" },\n { key: \"Ctrl+U\", text: \"clear the entire prompt buffer\" },\n { key: \"Tab\", text: \"complete @-mention · drill folder · accept slash command\" },\n { key: \"Shift+Tab\", text: \"edit-gate: toggle review ↔ AUTO mode\" },\n { key: \"Esc\", text: \"dismiss picker · abort the running model turn\" },\n { key: \"Ctrl+C\", text: \"abort the running model turn (NOT copy — see clipboard)\" },\n { key: \"PgUp / PgDn\", text: \"scroll chat history a page at a time\" },\n { key: \"End\", text: \"jump chat to the most recent line\" },\n ],\n },\n {\n title: \"mouse\",\n rows: [\n { key: \"wheel\", text: \"scrolls chat history (works on web/cloud/SSH terminals too)\" },\n { key: \"drag\", text: \"selects text natively — direct copy works, no modifier\" },\n { key: \"right-click\", text: \"terminal-native (paste menu on Windows Terminal etc.)\" },\n ],\n },\n {\n title: \"copy / paste\",\n rows: [\n { key: \"select text\", text: \"drag to select — terminal-native (no modifier needed)\" },\n {\n key: \"copy\",\n text: \"Ctrl+Shift+C (Win/Linux) · Cmd+C (macOS) — or auto-copy-on-select if your terminal does it\",\n },\n { key: \"paste\", text: \"Ctrl+V or Ctrl+Shift+V (Win/Linux) · Cmd+V (macOS)\" },\n {\n key: \"bracketed paste\",\n text: \"multi-line pastes stay one block — no auto-submit on intermediate newlines\",\n },\n ],\n },\n {\n title: \"edit-gate (code mode)\",\n rows: [\n { key: \"y / n\", text: \"accept or drop pending edits in the review modal\" },\n { key: \"Shift+Tab\", text: \"toggle review ↔ AUTO (persisted across sessions)\" },\n { key: \"u\", text: \"undo the last auto-applied batch (within the 5s banner)\" },\n ],\n },\n ],\n footer:\n \"Wheel→↑/↓ via DECSET 1007 (alternate-scroll) — wheel scrolls chat on most terminals (web/cloud/SSH included) without disturbing native selection. Drag to select stays modifier-free. Pass --no-mouse to opt out.\",\n },\n tipShownOnce: \"shown once\",\n modelOverride: \"override the default model\",\n noSession: \"disable session persistence for this run\",\n resumeHint: \"force-resume the named session (even if idle)\",\n newHint: \"force a fresh session (ignore --session / --continue)\",\n transcriptHint: \"path to write the JSONL transcript\",\n budgetHint: \"session USD cap — warns at 80%, refuses next turn at 100%\",\n modelIdHint: \"DeepSeek model id (e.g. deepseek-v4-flash)\",\n systemPromptHint: \"override the default system prompt\",\n presetHint: \"model bundle — auto|flash|pro\",\n sessionNameHint: \"session name (default: 'default')\",\n ephemeralHint: \"disable session persistence for this run\",\n mcpSpecHint: \"MCP server spec (repeatable)\",\n mcpPrefixHint: \"prefix MCP tool names with this string\",\n noConfigHint: \"ignore ~/.reasonix/config.json for this run\",\n presetHintShort: \"model bundle — auto|flash|pro\",\n budgetHintShort: \"session USD cap\",\n transcriptHintShort: \"JSONL transcript path\",\n mcpSpecHintShort: \"MCP server spec (repeatable)\",\n mcpPrefixHintShort: \"MCP tool name prefix\",\n dryRunHint: \"show what would be installed without actually installing\",\n rebuildHint: \"rebuild the index from scratch\",\n embedModelHint: \"embedding model name\",\n projectDirHint: \"project root directory\",\n ollamaUrlHint: \"Ollama server URL\",\n skipPromptsHint: \"skip confirmation prompts\",\n verboseHint: \"show full session metadata\",\n pruneDaysHint: \"delete sessions idle this many days or more (default 90)\",\n pruneDryRunHint: \"list what would be deleted without removing anything\",\n eventTypeHint: \"filter by event type\",\n eventSinceHint: \"start from this event id\",\n eventTailHint: \"show only the last N events\",\n jsonHint: \"output as JSON\",\n projectionHint: \"show projected state at each event\",\n printHint: \"print to stdout instead of TUI\",\n headHint: \"show only the first N events\",\n tailHint: \"show only the last N events\",\n mdReportHint: \"write a markdown diff report to this path\",\n printHintTable: \"print a table to stdout\",\n tuiHint: \"open the interactive TUI\",\n labelAHint: \"label for the left pane\",\n labelBHint: \"label for the right pane\",\n mcpListDescription: \"browse the MCP registry (official → smithery → local fallback)\",\n mcpInspectDescription: \"inspect an MCP server spec (tools, resources, prompts)\",\n mcpSearchDescription: \"search the MCP registry for servers matching a query\",\n mcpInstallDescription: \"install an MCP server by name (writes its spec to your config)\",\n mcpBrowseDescription: \"interactive marketplace browser — type to filter, enter to install\",\n mcpLocalHint: \"show only the bundled offline catalog\",\n mcpRefreshHint: \"bypass the 24h cache and refetch\",\n mcpLimitHint: \"max entries to show\",\n mcpPagesHint: \"eagerly load this many pages (default 1)\",\n mcpAllHint: \"load every page (slow on first run)\",\n mcpMaxPagesHint: \"cap how many pages to walk while searching (default 20)\",\n jsonHintCatalog: \"output as JSON\",\n jsonHintReport: \"output the inspection report as JSON\",\n modelOverrideFlash: \"override the model (default: deepseek-v4-flash)\",\n skipConfirmHint: \"skip the confirmation prompt\",\n },\n slash: {\n help: { description: \"show the full command reference\" },\n status: { description: \"current model, flags, context, session\" },\n preset: {\n description: \"model bundle — auto escalates flash → pro, flash/pro lock\",\n argsHint: \"<auto|flash|pro>\",\n },\n model: { description: \"switch DeepSeek model id\", argsHint: \"<id>\" },\n models: { description: \"list available models fetched from DeepSeek /models\" },\n language: {\n description: \"switch the runtime language\",\n argsHint: \"<EN|zh-CN>\",\n success: \"Language switched to English.\",\n unsupported: \"Unsupported language code: {code}. Supported: {supported}.\",\n },\n pro: {\n description: \"arm v4-pro for the NEXT turn only (one-shot · auto-disarms after turn)\",\n argsHint: \"[off]\",\n },\n budget: {\n description:\n \"session USD cap — warns at 80%, refuses next turn at 100%. Off by default. /budget alone shows status\",\n argsHint: \"[usd|off]\",\n },\n mcp: { description: \"list MCP servers + tools attached to this session\" },\n resource: {\n description: \"browse + read MCP resources (no arg → list URIs; <uri> → fetch contents)\",\n argsHint: \"[uri]\",\n },\n prompt: {\n description: \"browse + fetch MCP prompts (no arg → list names; <name> → render prompt)\",\n argsHint: \"[name]\",\n },\n memory: {\n description: \"show / manage pinned memory (REASONIX.md + ~/.reasonix/memory)\",\n argsHint: \"[list|show <name>|forget <name>|clear <scope> confirm]\",\n },\n skill: {\n description: \"list / run user skills (<project>/.reasonix/skills + ~/.reasonix/skills)\",\n argsHint: \"[list|show <name>|<name> [args]]\",\n },\n hooks: {\n description: \"list active hooks (settings.json under .reasonix/) · reload re-reads from disk\",\n argsHint: \"[reload]\",\n },\n permissions: {\n description:\n \"show / edit shell allowlist (builtin read-only · per-project: ~/.reasonix/config.json)\",\n argsHint: \"[list|add <prefix>|remove <prefix|N>|clear confirm]\",\n },\n dashboard: {\n description: \"launch the embedded web dashboard (127.0.0.1, token-gated)\",\n argsHint: \"[stop]\",\n },\n update: { description: \"show current vs latest version + the shell command to upgrade\" },\n stats: {\n description:\n \"cross-session cost dashboard (today / week / month / all-time · cache hit · vs Claude)\",\n },\n cost: {\n description:\n \"bare → last turn's spend (Usage card); with text → estimate cost of sending it next (worst-case + likely-cache)\",\n argsHint: \"[text]\",\n },\n doctor: { description: \"health check (api / config / api-reach / index / hooks / project)\" },\n context: { description: \"show context-window breakdown (system / tools / log / input)\" },\n retry: { description: \"truncate & resend your last message (fresh sample)\" },\n compact: {\n description:\n \"shrink oversized tool results AND tool-call args (edit_file search/replace) in the log; cap in tokens, default 4000\",\n argsHint: \"[tokens]\",\n },\n keys: { description: \"keyboard + mouse + copy/paste reference\" },\n plans: { description: \"list this session's active + archived plans, newest first\" },\n replay: {\n description: \"load an archived plan as a read-only Time Travel snapshot (default: newest)\",\n argsHint: \"[N]\",\n },\n sessions: { description: \"list saved sessions (current marked with ▸)\" },\n setup: { description: \"reminds you to exit and run `reasonix setup`\" },\n semantic: {\n description: \"show semantic_search status — built? Ollama installed? how to enable\",\n },\n clear: { description: \"clear visible scrollback only (log/context kept)\" },\n new: { description: \"start a fresh conversation (clear context + scrollback)\" },\n loop: {\n description:\n \"auto-resubmit <prompt> every <interval> until you type something / Esc / /loop stop\",\n argsHint: \"<5s..6h> <prompt> · stop · (no args = status)\",\n },\n exit: { description: \"quit the TUI\" },\n init: {\n description:\n \"scan the project and synthesize a baseline REASONIX.md (model writes; review with /apply). `force` overwrites an existing file.\",\n argsHint: \"[force]\",\n },\n apply: {\n description:\n \"commit pending edit blocks to disk (no arg → all; `1`, `1,3`, or `1-4` → that subset, rest stay pending)\",\n argsHint: \"[N|N,M|N-M]\",\n },\n discard: {\n description: \"drop pending edit blocks without writing (no arg → all; indices → that subset)\",\n argsHint: \"[N|N,M|N-M]\",\n },\n walk: {\n description:\n \"step through pending edits one block at a time (git-add-p style: y/n per block, a apply rest, A flip AUTO)\",\n },\n undo: { description: \"roll back the last applied edit batch\" },\n history: { description: \"list every edit batch this session (ids for /show, undone markers)\" },\n show: {\n description: \"dump a stored edit diff (omit id for newest non-undone)\",\n argsHint: \"[id]\",\n },\n commit: { description: \"git add -A && git commit -m ...\", argsHint: '\"msg\"' },\n checkpoint: {\n description:\n \"snapshot every file the session has touched (Cursor-style internal store, not git). /checkpoint alone lists.\",\n argsHint: \"[name|list|forget <id>]\",\n },\n restore: {\n description: \"roll back files to a named checkpoint (see /checkpoint list)\",\n argsHint: \"<name|id>\",\n },\n plan: {\n description: \"toggle read-only plan mode (writes bounced until submit_plan + approval)\",\n argsHint: \"[on|off]\",\n },\n mode: {\n description:\n \"edit-gate: review (queue) · auto (apply+undo) · yolo (apply+auto-shell). Shift+Tab cycles.\",\n argsHint: \"[review|auto|yolo]\",\n },\n jobs: { description: \"list background jobs started by run_background\" },\n kill: {\n description: \"stop a background job by id (SIGTERM → SIGKILL after grace)\",\n argsHint: \"<id>\",\n },\n logs: {\n description: \"tail a background job's output (default last 80 lines)\",\n argsHint: \"<id> [lines]\",\n },\n },\n wizard: {\n languageTitle: \"Choose your language\",\n languageSubtitle: \"Detected from your system locale. Switch later via /language.\",\n welcomeTitle: \"Welcome to Reasonix.\",\n apiKeyPrompt: \"Paste your DeepSeek API key to get started.\",\n apiKeyGetOne: \"Get one at: https://platform.deepseek.com/api_keys\",\n apiKeySavedLocally: \"Saved locally to {path}\",\n apiKeyInputLabel: \"key › \",\n apiKeyInvalid: \"Key looks too short — paste the full token (16+ chars, no spaces).\",\n apiKeyPreview: \"preview: {redacted}\",\n themeTitle: \"Choose a theme\",\n themeSubtitle: \"Preview updates live as you navigate. Change later with /theme.\",\n themeSampleHeading: \"Sample\",\n themeFooter: \"[↑↓] navigate · [Enter] confirm · [Esc] cancel\",\n themeCaption: {\n default: \"GitHub dark (default)\",\n dark: \"Cool dark tones\",\n light: \"Clean light mode\",\n \"tokyo-night\": \"Tokyo Night palette\",\n \"github-dark\": \"GitHub dark\",\n \"github-light\": \"GitHub light\",\n \"high-contrast\": \"Accessibility\",\n },\n reviewLabelTheme: \"Theme\",\n presetTitle: \"Pick a preset\",\n mcpTitle: \"Which MCP servers should Reasonix wire up for you?\",\n mcpUserArgsHint: \"(you'll provide {arg})\",\n mcpFooterMulti:\n \"[↑↓] navigate · [Space] toggle · [Enter] confirm · [Esc] cancel · empty = skip\",\n mcpArgsTitle: \"Configure {name}\",\n mcpArgsDirMissing: \"Directory {path} doesn't exist.\",\n mcpArgsDirCreateHint: \"[Y/Enter] create it (mkdir -p) · [N/Esc] enter a different path\",\n mcpArgsDirCreateFailed: \"Couldn't create {path}: {message}\",\n mcpArgsRequiredParam: \"Required parameter: \",\n mcpArgsEmpty: \"{name} needs a value — got an empty string.\",\n mcpArgsNotADir: \"{path} exists but is not a directory.\",\n reviewTitle: \"Ready to save\",\n reviewLabelApiKey: \"API key\",\n reviewLabelLanguage: \"Language\",\n reviewLabelPreset: \"Preset\",\n reviewLabelMcp: \"MCP\",\n reviewMcpNone: \"(none)\",\n reviewMcpServers: \"{count} server(s)\",\n reviewSavesTo: \"Saves to {path}\",\n reviewSaveError: \"Could not save config: {message}\",\n reviewFooter: \"[Enter] save · [Esc] cancel\",\n savedTitle: \"▸ Saved.\",\n savedFooter: \"[Enter] to exit\",\n selectFooter: \"[↑↓] navigate · [Enter] confirm · [Esc] cancel\",\n stepCounter: \"Step {step}/{total} · \",\n },\n planFlow: {\n approveCardTitle: \"Approve plan\",\n approveCardMetaRight: \"awaiting\",\n openQuestionsBanner:\n \"▲ the plan flags open questions or risks — pick {refine} to write concrete answers before the model moves on.\",\n openQuestionsHeader: \"Open questions / risks\",\n truncatedBodyMore: \"… {n} more line above in scrollback\",\n truncatedBodyMorePlural: \"… {n} more lines above in scrollback\",\n picker: {\n accept: \"accept\",\n acceptHint: \"run it now, in order\",\n refine: \"refine\",\n refineHint: \"give the agent more guidance, draft a new plan\",\n revise: \"revise\",\n reviseHint: \"edit the plan inline before running (skip / reorder steps)\",\n reject: \"reject\",\n rejectHint: \"discard, agent will retry from scratch\",\n },\n refineFooter: \"⏎ send · esc return to picker\",\n refineQuestionsHeading: \"Answer these or describe the change you want:\",\n modes: {\n approve: {\n title: \"approving — any last instructions?\",\n hint: \"Answer questions the plan raised, add constraints, or just press Enter to approve as-is.\",\n blankHint: \" (Enter with blank = approve without extra instructions.)\",\n },\n refine: {\n title: \"refining — what should the model change?\",\n hint: \"Describe what's wrong or missing, or answer questions the plan raised.\",\n blankHint: \" (Enter with blank = let the model pick safe defaults for any open questions.)\",\n },\n reject: {\n title: \"rejecting — tell the model why (optional)\",\n hint: \"Say what the model got wrong about your goal, or what you actually want instead.\",\n blankHint:\n \" (Enter with blank = cancel without explanation; the model will ask what you want.)\",\n },\n \"checkpoint-revise\": {\n title: \"revising — what should change before the next step?\",\n hint: \"Scope change, skip steps, alternative approach — the model adjusts the remaining plan.\",\n blankHint: \" (Enter with blank = continue with the current plan.)\",\n },\n \"choice-custom\": {\n title: \"custom answer — type whatever fits\",\n hint: \"Free-form reply. The model reads it verbatim and proceeds — no need to match the listed options.\",\n blankHint: \" (Enter with blank = ask the model what you actually want.)\",\n },\n },\n checkpoint: {\n title: \"Checkpoint — step done\",\n continue: \"Continue — run the next step\",\n continueHint: \"Model resumes with the next step.\",\n revise: \"Revise — give feedback before the next step\",\n reviseHint: \"Stay paused, type guidance; model adjusts the remaining plan.\",\n stop: \"Stop — end the plan here\",\n stopHint: \"Model summarizes what was done and ends.\",\n },\n stepList: {\n counter: \"{total} steps\",\n counterSingular: \"{total} step\",\n counterDone: \"{done}/{total} done ({pct}%) · {total} steps\",\n counterDoneSingular: \"{done}/{total} done ({pct}%) · {total} step\",\n },\n },\n app: {\n walkCancelledRemaining: \"▸ walk cancelled — {count} block(s) still pending.\",\n walkCancelled: \"▸ walk cancelled.\",\n editModeYolo:\n \"▸ edit mode: YOLO — edits AND shell commands auto-run. /undo still rolls back edits. Use carefully.\",\n editModeAuto:\n \"▸ edit mode: AUTO — edits apply immediately; press u within 5s to undo (space pauses the timer). Shell commands still ask.\",\n editModeReview: \"▸ edit mode: review — edits queue for /apply (or y) / /discard (or n)\",\n rejectedEdit: \"▸ rejected edit to {path}{context}\",\n autoApprovingRest: \"▸ auto-approving remaining edits for this turn\",\n flippedAutoSession: \"▸ flipped to AUTO mode for the rest of the session (persisted)\",\n flippedAutoWalk: \"▸ flipped to AUTO mode — future edits will apply immediately. Walk exited.\",\n dashboardStopped: \"▸ dashboard stopped.\",\n notedMemory: \"▸ noted ({scope}) — {verb} {path}\",\n notedScopeProject: \"project\",\n notedScopeGlobal: \"global\",\n notedVerbCreated: \"created\",\n notedVerbAppended: \"appended to\",\n memoryWriteFailed: \"# memory write failed\",\n commandFailed: \"! command failed\",\n restoreCodeOnly: \"▸ /restore is code-mode only\",\n hookUserPromptSubmit: \"UserPromptSubmit hook\",\n hookStop: \"Stop hook\",\n atMentions: \"▸ @mentions: {parts}\",\n atUrl: \"▸ @url: {parts}\",\n atUrlFailed: \"@url expansion failed\",\n denied: \"▸ denied: {cmd}{context}\",\n alwaysAllowed: '▸ always allowed \"{prefix}\" for {dir}',\n runningCommand: \"▸ running: {cmd}\",\n startingBackground: \"▸ starting (background): {cmd}\",\n checkpointSaved:\n \"⛁ checkpoint saved · {id} · {count} file{s} · /restore {id} to roll back this step\",\n continuingAfter: \"▸ continuing after {label}{counter}\",\n planStoppedAt: \"▸ plan stopped at {label}{counter}\",\n revisingAfter: \"▸ revising after {label} — {feedback}\",\n },\n hooks: {\n head: \"hook {tag} `{cmd}` {decision}{truncTag}\",\n headWithDetail: \"hook {tag} `{cmd}` {decision}{truncTag}: {detail}\",\n truncated: \" (output truncated at 256KB)\",\n decisionBlock: \"block\",\n decisionWarn: \"warn\",\n decisionTimeout: \"timeout\",\n decisionError: \"error\",\n },\n summary: {\n status: \"summarizing what was gathered…\",\n hallucinatedFallback:\n \"(model emitted fake tool-call markup instead of a prose summary — try /retry with a narrower question, or /think to inspect R1's reasoning)\",\n failedAfterReason:\n \"{label} and the fallback summary call failed: {message}. Run /clear and retry with a narrower question, or raise --max-tool-iters.\",\n },\n loop: {\n budgetExhausted:\n \"session budget exhausted — spent ${spent} ≥ cap ${cap}. Bump the cap with /budget <usd>, clear it with /budget off, or end the session.\",\n budget80Pct: \"▲ budget 80% used — ${spent} of ${cap}. Next turn or two likely trips the cap.\",\n proArmed: \"⇧ /pro armed — this turn runs on deepseek-v4-pro (one-shot · disarms after turn)\",\n abortedAtIter:\n \"aborted at iter {iter}/{cap} — stopped without producing a summary (press ↑ + Enter or /retry to resume)\",\n toolUploadStatus: \"tool result uploaded · model thinking before next response…\",\n toolBudgetWarning:\n \"{iter}/{cap} tool calls used — approaching budget. Press Esc to force a summary now.\",\n preflightFoldStatus: \"preflight: context near full, attempting fold…\",\n preflightFolded:\n \"preflight: request ~{estimate}/{ctxMax} tokens ({pct}%) — folded {beforeMessages} messages → {afterMessages} (summary {summaryChars} chars). Sending.\",\n preflightNoFold:\n \"preflight: request ~{estimate}/{ctxMax} tokens ({pct}%) and nothing left to fold — DeepSeek will likely 400. Run /clear or /new to start fresh.\",\n flashEscalation: \"⇧ flash requested escalation — retrying this turn on {model}{reasonSuffix}\",\n harvestStatus: \"extracting plan state from reasoning…\",\n autoEscalation:\n \"⇧ auto-escalating to {model} for the rest of this turn — flash hit {breakdown}. Next turn falls back to {fallback} unless /pro is armed.\",\n repeatToolCallWarning:\n \"Caught a repeated tool call — let the model see the issue and retry with a different approach.\",\n stormStuck:\n \"Stopped a stuck retry loop — the model kept calling the same tool with identical args after a self-correction nudge. Try /retry, rephrase, or rule out the underlying blocker.\",\n stormSuppressed: \"Suppressed {count} repeated tool call(s) — same name + args fired 3+ times.\",\n compactingHistoryStatus: \"compacting history{aggressiveTag}…\",\n aggressiveTag: \" (aggressive)\",\n foldedHistory:\n \"context {before}/{ctxMax} ({pct}%) — folded {beforeMessages} messages → {afterMessages} (summary {summaryChars} chars). Continuing.\",\n aggressivelyFoldedHistory:\n \"context {before}/{ctxMax} ({pct}%) — aggressively folded {beforeMessages} messages → {afterMessages} (summary {summaryChars} chars). Continuing.\",\n forcingSummary:\n \"context {before}/{ctxMax} ({pct}%) — forcing summary from what was gathered. Run /compact, /clear, or /new to reset.\",\n },\n errors: {\n contextOverflow:\n \"Context overflow (DeepSeek 400): session history is {requested}, past the model's prompt limit (V4: 1M tokens; legacy chat/reasoner: 131k). Usually a single tool result grew too big. Reasonix caps new tool results at 8k tokens and auto-heals oversized history on session load — a restart often clears it. If it still overflows, run /forget (delete the session) or /clear (drop the displayed history) to start fresh.\",\n contextOverflowTooMany: \"too many tokens\",\n auth401:\n \"Authentication failed (DeepSeek 401): {inner}. Your API key is rejected. Fix with `reasonix setup` or `export DEEPSEEK_API_KEY=sk-...`. Get one at https://platform.deepseek.com/api_keys.\",\n balance402:\n \"Out of balance (DeepSeek 402): {inner}. Top up at https://platform.deepseek.com/top_up — the panel header shows your balance once it's non-zero.\",\n badparam422: \"Invalid parameter (DeepSeek 422): {inner}\",\n badrequest400: \"Bad request (DeepSeek 400): {inner}\",\n deepseek5xxHead:\n \"DeepSeek service unavailable ({status}) — this is a DeepSeek-side problem, not Reasonix. Already retried 4× with backoff.\",\n deepseek5xxReachable:\n \" DeepSeek's main API answered our health check, but /chat/completions is failing — partial outage on their side.\",\n deepseek5xxUnreachable:\n \" DeepSeek API is unreachable from your network — could be a wider DS outage or a local network issue.\",\n deepseek5xxActionNetwork:\n \" Try: (1) check your network, (2) wait 30s and retry, (3) status page: https://status.deepseek.com.\",\n deepseek5xxActionRetry:\n \" Try: (1) wait 30s and retry, (2) /preset to switch model, (3) status page: https://status.deepseek.com.\",\n innerNoMessage: \"(no message)\",\n reasonAborted: \"[aborted by user (Esc) — summarizing what I found so far]\",\n reasonContextGuard:\n \"[context budget running low — summarizing before the next call would overflow]\",\n reasonStuck:\n \"[stuck on a repeated tool call — explaining what was tried and what's blocking progress]\",\n reasonBudget: \"[tool-call budget ({iterCap}) reached — forcing summary from what I found]\",\n labelAborted: \"aborted by user\",\n labelContextGuard: \"context-guard triggered (prompt > 80% of window)\",\n labelStuck: \"stuck (repeated tool call suppressed by storm-breaker)\",\n labelBudget: \"tool-call budget ({iterCap}) reached\",\n },\n handlers: {\n basic: {\n newInfo:\n \"▸ new conversation — dropped {count} message(s) from context. Same session, fresh slate.\",\n helpTitle: \"Commands:\",\n helpShellTitle: \"Shell shortcut:\",\n helpShell: \" !<cmd> run <cmd> in the sandbox root; output goes into\",\n helpShellDetail:\n \" the conversation so the model sees it next turn.\",\n helpShellConsent:\n \" No allowlist gate — user-typed = explicit consent.\",\n helpShellExample: \" Example: !git status !ls src/ !npm test\",\n helpMemoryTitle: \"Quick memory:\",\n helpMemoryPin:\n \" #<note> append <note> to <project>/REASONIX.md (committable).\",\n helpMemoryPinEx:\n \" Example: #findByEmail must be case-insensitive\",\n helpMemoryGlobal:\n \" #g <note> append <note> to ~/.reasonix/REASONIX.md (global, never committed).\",\n helpMemoryGlobalEx: \" Example: #g always run pnpm not npm\",\n helpMemoryPinBoth:\n \" Both pin into every future session's prefix. Faster than /memory.\",\n helpMemoryEscape:\n \" Use `\\\\#text` to send a literal `#text` to the model.\",\n helpFileTitle: \"File references (code mode):\",\n helpFile: \" @path/to/file inline file content under [Referenced files] on send.\",\n helpFilePicker:\n \" Type `@` to open the picker (↑↓ navigate, Tab/Enter pick).\",\n helpUrlTitle: \"URL references:\",\n helpUrl:\n \" @https://example.com fetch the URL, strip HTML, inline under [Referenced URLs].\",\n helpUrlCache:\n \" Same URL twice in one session fetches once (in-mem cache).\",\n helpUrlPunct:\n \" Trailing sentence punctuation (./,/)) is stripped automatically.\",\n helpPresetsTitle: \"Presets (branch + harvest are NEVER auto-enabled — opt-in only):\",\n helpPresetAuto:\n \" auto v4-flash → v4-pro on hard turns ← default · cheap when easy, smart when hard\",\n helpPresetFlash:\n \" flash v4-flash always cheapest · predictable per-turn cost\",\n helpPresetPro:\n \" pro v4-pro always ~3× flash (5/31) · hard multi-turn work\",\n helpSessionsTitle: \"Sessions (auto-enabled by default, named 'default'):\",\n helpSessionCustom: \" reasonix chat --session <name> use a different named session\",\n helpSessionNone: \" reasonix chat --no-session disable persistence for this run\",\n retryNone: \"nothing to retry — no prior user message in this session's log.\",\n retryInfo: '▸ retrying: \"{preview}\"',\n loopTuiOnly: \"/loop is only available in the interactive TUI (not in run/replay).\",\n loopStopped: \"▸ loop stopped.\",\n loopNoActive: \"no active loop to stop.\",\n loopNoActiveHint:\n \"no active loop. Start one with `/loop <interval> <prompt>` (e.g. /loop 30s npm test).\\nCancels on: /loop stop · Esc · /clear /new · any user-typed prompt.\",\n loopStarted:\n '▸ loop started — re-submitting \"{prompt}\" every {duration}. Type anything (or /loop stop) to cancel.',\n keysNeedsTui: \"/keys needs a TUI context (postKeys wired).\",\n },\n admin: {\n doctorNeedsTui: \"/doctor needs a TUI context (postDoctor wired).\",\n doctorRunning: \"⚕ Doctor — running health checks…\",\n hooksReloadUnavailable:\n \"/hooks reload is not available in this context (no reload callback wired).\",\n hooksReloaded: \"▸ reloaded hooks · {count} active\",\n hooksUsage:\n \"usage: /hooks list active hooks\\n /hooks reload re-read settings.json files\",\n hooksNone: \"no hooks configured.\",\n hooksDropHint: \"drop a settings.json with a `hooks` key into either of:\",\n hooksProject: \" · {path} (project)\",\n hooksProjectFallback: \" · <project>/.reasonix/settings.json (project)\",\n hooksGlobal: \" · {path} (global)\",\n hooksEvents: \"events: PreToolUse, PostToolUse, UserPromptSubmit, Stop\",\n hooksExitCodes: \"exit 0 = pass · exit 2 = block (Pre*) · other = warn\",\n hooksLoaded: \"▸ {count} hook(s) loaded\",\n hooksSources: \"sources: project={project} · global={global}\",\n updateCurrent: \"current: reasonix {version}\",\n updateLatestPending: \"latest: (not yet resolved — background check in flight or offline)\",\n updateRetryHint: \"triggered a fresh registry fetch — retry `/update` in a few seconds,\",\n updateRetryHint2: \"or run `reasonix update` in another terminal to force it synchronously.\",\n updateLatest: \"latest: reasonix {version}\",\n updateUpToDate: \"you're on the latest. nothing to do.\",\n updateNpxHint: \"you're running via npx — the next `npx reasonix ...` launch will auto-fetch.\",\n updateNpxForce: \"to force a refresh sooner: `npm cache clean --force`.\",\n updateUpgradeHint: \"to upgrade, exit this session and run:\",\n updateUpgradeCmd1:\n \" reasonix update (interactive, dry-run supported via --dry-run)\",\n updateUpgradeCmd2: \" {command} (direct)\",\n updateInSessionDisabled:\n \"in-session install is deliberately disabled — the install spawn would\",\n updateInSessionDisabled2:\n \"corrupt this TUI's rendering and Windows can lock the running binary.\",\n statsNoData: \"no usage data yet.\",\n statsEveryTurn: \"every turn you run here appends one record — this session's turns\",\n statsWillAppear: \"will show up in the dashboard once you send a message.\",\n },\n edits: {\n undoCodeOnly:\n \"/undo is only available inside `reasonix code` — chat mode doesn't apply edits.\",\n historyCodeOnly: \"/history is only available inside `reasonix code`.\",\n showCodeOnly: \"/show is only available inside `reasonix code`.\",\n applyCodeOnly: \"/apply is only available inside `reasonix code` (nothing to apply here).\",\n discardCodeOnly: \"/discard is only available inside `reasonix code`.\",\n planCodeOnly:\n \"/plan is only available inside `reasonix code` — chat mode doesn't gate tool writes.\",\n planOn:\n \"▸ plan mode ON — write tools are gated; the model MUST call `submit_plan` before anything executes. (The model can also call submit_plan on its own for big tasks even when plan mode is off — this toggle is the stronger, explicit constraint.) Type /plan off to leave.\",\n planOff:\n \"▸ plan mode OFF — write tools are live again. Model can still propose plans autonomously for large tasks.\",\n modeCodeOnly: \"/mode is only available inside `reasonix code`.\",\n modeUsage: \"usage: /mode <review|auto|yolo> (Shift+Tab also cycles)\",\n modeYolo:\n \"▸ edit mode: YOLO — edits AND shell commands auto-run with no prompt. /undo still rolls back edits. Use carefully.\",\n modeAuto:\n \"▸ edit mode: AUTO — edits apply immediately; press u within 5s to undo, or /undo later. Shell commands still ask.\",\n modeReview: \"▸ edit mode: review — edits queue for /apply (or y) / /discard (or n)\",\n commitCodeOnly: \"/commit is only available inside `reasonix code` (needs a rooted git repo).\",\n commitUsage:\n 'usage: /commit \"your commit message\" — runs `git add -A && git commit -m \"…\"` in {root}',\n walkCodeOnly: \"/walk is only available inside `reasonix code`.\",\n checkpointCodeOnly:\n \"/checkpoint is only available inside `reasonix code` — chat mode doesn't apply edits.\",\n checkpointNone:\n \"no checkpoints yet — `/checkpoint <name>` snapshots every file the session has touched. Restore later with `/restore <name>`.\",\n checkpointHeader: \"◈ checkpoints · {count} stored\",\n checkpointRestoreHint:\n \" /restore <name|id> · /checkpoint forget <id> · /checkpoint <name> to add\",\n checkpointForgetUsage: \"usage: /checkpoint forget <id|name>\",\n checkpointNoMatch: '▸ no checkpoint matching \"{name}\" — see /checkpoint list',\n checkpointDeleted: \"▸ deleted checkpoint {id} ({name})\",\n checkpointDeleteFailed: \"▸ failed to delete {id} (already gone?)\",\n checkpointSaveUsage: \"usage: /checkpoint <name> (or /checkpoint list to see existing)\",\n checkpointSavedEmpty:\n '▸ checkpoint \"{name}\" saved ({id}) — but no files have been touched yet, so it\\'s an empty baseline. Edits made after this point will be revertable.',\n checkpointSaved:\n '▸ checkpoint \"{name}\" saved ({id}) — {files} file{s}, {size} KB. Restore: /restore {name}',\n restoreCodeOnly: \"/restore is only available inside `reasonix code`.\",\n restoreUsage: \"usage: /restore <name|id> (see /checkpoint list for ids)\",\n restoreNoMatch: '▸ no checkpoint matching \"{target}\" — try /checkpoint list',\n restoreInfo: '▸ restored \"{name}\" ({id}) from {when}',\n restoreWrote: \" · wrote back {count} file{s}\",\n restoreRemoved: \" · removed {count} file{s} (didn't exist at checkpoint time)\",\n restoreSkipped: \" ✗ {count} file{s} skipped:\",\n cwdCodeOnly: \"/cwd is only available inside `reasonix code`.\",\n cwdUsage:\n \"usage: /cwd <path> (current root: {current}). Re-points filesystem / shell / memory tools to <path>.\",\n cwdUsageNoCurrent: \"usage: /cwd <path> re-points the workspace root to <path>.\",\n },\n model: {\n modelHint: \"try deepseek-v4-flash or deepseek-v4-pro — run /models to fetch the live list\",\n modelUsage: \"usage: /model <id> ({hint})\",\n modelNotInCatalog:\n \"model → {id} (⚠ not in the fetched catalog: {list}. If this is wrong the next call will 400 — run /models to refresh.)\",\n modelSet: \"model → {id}\",\n presetAuto: \"preset → auto (v4-flash → v4-pro on hard turns · default)\",\n presetFlash: \"preset → flash (v4-flash always · cheapest · /pro still bumps one turn)\",\n presetPro: \"preset → pro (v4-pro always · ~3× flash · for hard multi-turn work)\",\n presetUsage: \"usage: /preset <auto|flash|pro>\",\n proNothingArmed: \"nothing armed — /pro with no args will arm pro for your next turn\",\n proDisarmed: \"▸ /pro disarmed — next turn falls back to the current preset\",\n proUsage:\n \"usage: /pro arm pro for the next turn (one-shot, auto-disarms after)\\n /pro off cancel armed state before the next turn\",\n proArmed:\n \"▸ /pro armed — your NEXT message runs on {model} regardless of preset. Auto-disarms after one turn. Use /preset max for a persistent switch.\",\n budgetNoCap:\n \"no session budget set — Reasonix will keep going until you stop it. Set one with: /budget <usd> (e.g. /budget 5)\",\n budgetStatus:\n \"budget: ${spent} of ${cap} ({pct}%) · /budget off to clear, /budget <usd> to change\",\n budgetOff: \"budget → off (no cap)\",\n budgetUsage:\n 'usage: /budget <usd> (got \"{arg}\" — must be a positive number, e.g. /budget 5 or /budget 12.50)',\n budgetExhausted:\n \"▲ budget → ${cap} but already spent ${spent}. Next turn will be refused — bump the cap higher to keep going, or end the session.\",\n budgetSet:\n \"budget → ${cap} (so far: ${spent} · warns at 80%, refuses next turn at 100% · /budget off to clear)\",\n },\n permissions: {\n mutateCodeOnly:\n \"/permissions add / remove / clear are only available inside `reasonix code` — they edit the project-scoped allowlist (`~/.reasonix/config.json` projects[<root>].shellAllowed).\",\n addUsage:\n 'usage: /permissions add <prefix> (multi-token OK: /permissions add \"git push origin\")',\n addAlready: \"▸ already allowed: {prefix}\",\n addBuiltin:\n \"▸ `{prefix}` is already in the builtin allowlist — no per-project entry needed. (Builtin entries are always on.)\",\n addInfo:\n \"▸ added: {prefix}\\n → next `{prefix}` invocation runs without prompting in this project.\",\n removeUsage:\n \"usage: /permissions remove <prefix-or-index> (e.g. /permissions remove 3, or /permissions remove npm)\",\n removeEmpty: \"▸ no project allowlist entries to remove.\",\n removeIndexOob: \"▸ index out of range: {idx} (project list has {count} entries)\",\n removeNothing: \"▸ nothing to remove.\",\n removeBuiltin:\n \"▸ `{prefix}` is in the builtin allowlist (read-only). Builtin entries can't be removed at runtime — they're baked into the binary.\",\n removeInfo: \"▸ removed: {prefix}\",\n removeNotFound:\n \"▸ no such project entry: {prefix} (try /permissions list to see what's stored)\",\n clearAlready: \"▸ project allowlist is already empty.\",\n clearConfirm:\n \"about to drop {count} project allowlist entr{plural} for {root}. Re-run with the word 'confirm' to proceed: /permissions clear confirm\",\n clearedNone: \"▸ project allowlist was already empty — nothing changed.\",\n cleared: \"▸ cleared {count} project allowlist entr{plural}.\",\n usage:\n 'usage: /permissions [list] show current state\\n /permissions add <prefix> persist (e.g. \"npm run build\")\\n /permissions remove <prefix-or-N> drop one entry\\n /permissions clear confirm wipe every project entry',\n modeYolo:\n \"▸ edit mode: YOLO — every shell command auto-runs, allowlist is bypassed. /mode review to re-enable prompts.\",\n modeAuto:\n \"▸ edit mode: auto — edits auto-apply, shell still gated by allowlist (or ShellConfirm prompt for non-allowlisted).\",\n modeReview:\n \"▸ edit mode: review — both edits and non-allowlisted shell commands ask before running.\",\n projectHeader: \"Project allowlist ({count}) — {root}\",\n projectNone1: ' (none — pick \"always allow\" on a ShellConfirm prompt to add one,',\n projectNone2: \" or `/permissions add <prefix>` directly.)\",\n projectNoRoot: \"Project allowlist — (no project root; chat mode shows builtin entries only)\",\n builtinHeader: \"Builtin allowlist ({count}) — read-only, baked in\",\n subcommands:\n \"Subcommands: /permissions add <prefix> · /permissions remove <prefix-or-N> · /permissions clear confirm\",\n },\n dashboard: {\n notAvailable:\n \"/dashboard is not available in this context (no startDashboard callback wired).\",\n stopNoCallback: \"/dashboard stop: no stop callback wired.\",\n notRunning: \"▸ dashboard is not running.\",\n stopping: \"▸ dashboard stopping…\",\n alreadyRunning: \"▸ dashboard is already running:\",\n alreadyRunningHint: \"Open it in any browser. Type `/dashboard stop` to tear it down.\",\n ready: \"▸ dashboard ready:\",\n readyHint: \"127.0.0.1 only · token-gated. Type `/dashboard stop` to shut down.\",\n failed: \"▸ dashboard failed to start: {reason}\",\n starting: \"▸ starting dashboard server…\",\n },\n observability: {\n contextInfo: \"context: ~{total} of {max} ({pct}%) · system {sys} · tools {tools} · log {log}\",\n compactStarting: \"▸ folding older turns into a summary…\",\n compactNoop: \"▸ nothing to fold — log already small or recent turns alone exceed the budget.\",\n compactDone: \"▸ folded {before} messages → {after} (summary {chars} chars). Continuing.\",\n compactFailed: \"▸ fold failed: {reason}\",\n costNoTurn: \"no turn yet — `/cost` shows the most recent turn's token + spend breakdown.\",\n costNeedsTui: \"/cost needs a TUI context (postUsage wired).\",\n costNoPricing:\n '▸ /cost: no pricing table for model \"{model}\". Add one to telemetry/stats.ts.',\n costEstimate:\n \"▸ /cost estimate · {model} · {prompt} prompt tokens (sys {sys} + tools {tools} + log {log} + msg {msg})\",\n costWorstCase:\n \" worst case (full miss): {input} input + ~{output} output ({avg} avg) ≈ {total}\",\n costLikely: \" likely ({pct}% session cache hit): {input} input + ~{output} output ≈ {total}\",\n costLikelyCold: \" likely: matches worst case until cache fills (no completed turns yet)\",\n statusModel: \" model {model}\",\n statusFlags: \" flags stream={stream} · effort={effort}\",\n statusCtx: \" ctx {bar} {used}/{max} ({pct}%)\",\n statusCtxNone: \" ctx no turns yet\",\n statusCost: \" cost ${cost} · cache {bar} {pct}% · turns {turns}\",\n statusCostCold: \" cost ${cost} · turns {turns} (cache warming up)\",\n statusBudget: \" budget ${spent} / ${cap} ({pct}%){tag}\",\n statusSession: ' session \"{name}\" · {count} messages in log (resumed {resumed})',\n statusSessionEphemeral: \" session (ephemeral — no persistence)\",\n statusWorkspace:\n \" workspace {path} · pinned at launch (relaunch with --dir <path> to switch)\",\n statusMcp: \" mcp {servers} server(s), {tools} tool(s) in registry\",\n statusEdits: \" edits {count} pending (/apply to commit, /discard to drop)\",\n statusPlan: \" plan ON — writes gated (submit_plan + approval)\",\n statusModeYolo:\n \" mode YOLO — edits + shell auto-run with no prompt (/undo still rolls back · Shift+Tab to flip)\",\n statusModeAuto:\n \" mode AUTO — edits apply immediately (u to undo within 5s · Shift+Tab to flip)\",\n statusModeReview: \" mode review — edits queue for /apply or y (Shift+Tab to flip)\",\n statusDash: \" dash {url} (open in browser · /dashboard stop)\",\n },\n plans: {\n noSession:\n \"no session attached — `/plans` is per-session. Run `reasonix code` in a project to get a session.\",\n activePlan: \"▸ active plan{label} — {done}/{total} step{s} done · last touched {when}\",\n activeNone: \"▸ active plan: (none)\",\n noArchives:\n \"no archived plans yet for this session — they auto-archive when every step is done\",\n archivedHeader: \"Archived ({count}):\",\n replayNoSession:\n \"no session attached — `/replay` is per-session. Run `reasonix code` in a project to get a session.\",\n replayNoArchives:\n \"no archived plans yet for this session — `/replay` lights up once a plan completes (auto-archives when every step is done).\",\n replayInvalidIndex:\n \"invalid index — `/replay` takes 1..{max} (newest = 1). Use `/plans` to see the list.\",\n archivedRow: \" ✓ {when} {total} step{s} · {completion} {label}\",\n completionComplete: \"complete\",\n stopAborted:\n \"▸ plan stopped — model aborted; type a follow-up to continue or start a new task.\",\n },\n jobs: {\n codeOnly: \"/jobs is only available inside `reasonix code`.\",\n killCodeOnly: \"/kill is only available inside `reasonix code`.\",\n logsCodeOnly: \"/logs is only available inside `reasonix code`.\",\n empty:\n \"◈ jobs · 0 running · 0 total\\n (run_background spawns one — dev servers, watchers, long-running scripts)\",\n header: \"◈ jobs · {running} running · {total} total\",\n footer: \" /logs <id> tail · /kill <id> SIGTERM → SIGKILL\",\n killUsage: \"usage: /kill <id> (see /jobs for ids)\",\n killNotFound: \"job {id}: not found\",\n killAlreadyExited: \"job {id} already exited ({code})\",\n killStopping:\n \"▸ stopping job {id} (tree kill: SIGTERM → SIGKILL after 2s grace; Windows: taskkill /T /F)\",\n killStatus: \"▸ job {id} {status}\",\n killStillAlive: \"still alive after SIGKILL (!) — report this as a bug\",\n logsUsage: \"usage: /logs <id> [lines] (default last 80 lines)\",\n logsNotFound: \"job {id}: not found\",\n logsStatus: \"[job {id} · {status}]\\n$ {command}\",\n logsRunning: \"running · pid {pid}\",\n logsExited: \"exited {code}\",\n logsFailed: \"failed ({reason})\",\n logsStopped: \"stopped\",\n },\n memory: {\n disabled:\n \"memory is disabled (REASONIX_MEMORY=off in env). Unset the var to re-enable — no REASONIX.md or ~/.reasonix/memory content will be pinned in the meantime.\",\n noRoot:\n \"no working directory on this session — `/memory` needs a root to resolve REASONIX.md from. (Running in a test harness?)\",\n listEmpty:\n \"no user memories yet. The model can call `remember` to save one, or you can create files by hand in ~/.reasonix/memory/global/ or the per-project subdir.\",\n listHeader: \"User memories ({count}):\",\n listFooter: \"View body: /memory show <name> Delete: /memory forget <name>\",\n showUsage: \"usage: /memory show <name> or /memory show <scope>/<name>\",\n showNotFound: \"no memory found: {target}\",\n showFailed: \"show failed: {reason}\",\n forgetUsage: \"usage: /memory forget <name> or /memory forget <scope>/<name>\",\n forgetNotFound: \"no memory found: {target}\",\n forgetInfo: \"▸ forgot {scope}/{name}. Next /new or launch won't see it.\",\n forgetFailed: \"could not forget {scope}/{name} (already gone?)\",\n forgetError: \"forget failed: {reason}\",\n clearUsage: \"usage: /memory clear <global|project> confirm\",\n clearConfirm:\n \"about to delete every memory in scope={scope}. Re-run with the word 'confirm' to proceed: /memory clear {scope} confirm\",\n cleared: \"▸ cleared scope={scope} — deleted {count} memory file(s).\",\n noMemory: \"no memory pinned in {root}.\",\n layers: \"Three layers are available:\",\n layerProject: \" 1. {file} — committable team memory (in the repo).\",\n layerGlobal: \" 2. ~/.reasonix/memory/global/ — your cross-project private memory.\",\n layerProjectHash: \" 3. ~/.reasonix/memory/<project-hash>/ — this project's private memory.\",\n askModel: \"Ask the model to `remember` something, or hand-edit files directly.\",\n changesNote:\n \"Changes take effect on next /new or launch — the system prompt is hashed once per session to keep the prefix cache warm.\",\n subcommands:\n \"Subcommands: /memory list | /memory show <name> | /memory forget <name> | /memory clear <scope> confirm\",\n changesNoteShort:\n \"Changes take effect on next /new or launch. Subcommands: /memory list | show | forget | clear\",\n },\n mcp: {\n noServers:\n 'no MCP servers attached. Run `reasonix setup` to pick some, or launch with --mcp \"<spec>\". `reasonix mcp list` shows the catalog.',\n toolsLabel: \" tools {count}\",\n resourcesHint: \"`/resource` to browse+read\",\n promptsHint: \"`/prompt` to browse+fetch\",\n awarenessOnly:\n \"Chat mode consumes tools today; resources+prompts are surfaced here for awareness.\",\n catalogHint:\n \"Full catalog: `reasonix mcp list` · deeper diagnosis: `reasonix mcp inspect <spec>`.\",\n fallbackServers: \"MCP servers ({count}):\",\n fallbackTools: \"Tools in registry ({count}):\",\n fallbackChange: \"To change this set, exit and run `reasonix setup`.\",\n usageDisableEnable:\n \"usage: /mcp {action} <name> · pick a name shown in /mcp (anonymous servers can't be named-toggled).\",\n usageReconnect: \"usage: /mcp reconnect <name> · pick a name shown in /mcp.\",\n unknownServer: 'unknown MCP server \"{name}\". Known: {list}.',\n noneList: \"(none)\",\n reconnectNoTui: \"/mcp reconnect requires the interactive TUI (postInfo not wired).\",\n },\n init: {\n codeOnly:\n \"/init only works in code mode (it needs filesystem tools).\\nRun `reasonix code [path]` to start a session rooted at the\\nproject you want to initialize, then run /init.\",\n exists: \"▸ REASONIX.md already exists at {path}\",\n existsForce: \" /init force regenerate from scratch (overwrites)\",\n existsEdit: \" Or edit it by hand — it's just markdown. The current file is\",\n existsPinned: \" pinned into the system prompt every launch as-is.\",\n info: \"▸ /init — model will scan the project and synthesize REASONIX.md.\\n The result lands as a pending edit; review with /apply or /walk.\",\n },\n webSearchEngine: {\n currentEngine: \"Current web search engine: {engine}\",\n endpoint: \"SearXNG endpoint: {url}\",\n usageHeader: \"Usage:\",\n usageMojeek: \" /search-engine mojeek use Mojeek (default, no external deps)\",\n usageSearxng: \" /search-engine searxng use SearXNG at default endpoint\",\n usageSearxngUrl: \" /search-engine searxng <url> use SearXNG at custom endpoint\",\n alias: \"Alias: /se\",\n searxngInfo:\n \"SearXNG is a self-hosted metasearch engine (https://github.com/searxng/searxng).\",\n searxngInstall: \"Install it with: docker run -d -p 8080:8080 searxng/searxng\",\n switched: 'Switched web search engine to \"{engine}\".{note}',\n switchedSearxngNote: \" Make sure SearXNG is running at {endpoint}.\",\n confirmed:\n '✓ Web search engine set to \"{engine}\"{detail}. Next assistant turn will pick up the change.',\n confirmedDetail: \" ({endpoint})\",\n },\n skill: {\n listEmpty: \"no skills found. Reasonix reads skills from:\",\n listProjectScope:\n \" · <project>/.reasonix/skills/<name>/SKILL.md (or <name>.md) — project scope\",\n listGlobalScope: \" · ~/.reasonix/skills/<name>/SKILL.md (or <name>.md) — global scope\",\n listProjectOnly: \" (project scope is only active in `reasonix code`)\",\n listFrontmatter: \"Each file's frontmatter needs at least `name` and `description`.\",\n listInvoke:\n \"Invoke a skill with `/skill <name> [args]` or by asking the model to call `run_skill`.\",\n listHeader: \"User skills ({count}):\",\n listFooter: \"View: /skill show <name> Run: /skill <name> [args] New: /skill new <name>\",\n listEmptyNewHint:\n \"Scaffold one with: /skill new <name> (project scope) — there's no remote registry yet; you author skills directly.\",\n showUsage: \"usage: /skill show <name>\",\n showNotFound: \"no skill found: {name}\",\n runNotFound: \"no skill found: {name} (try /skill list)\",\n runInfo: \"▸ running skill: {name}{args}\",\n newUsage: \"usage: /skill new <name> [--global]\",\n newCreated: \"▸ created skill: {name}\\n {path}\\n edit it, then `/skill {name}` to invoke\",\n newError: \"▲ /skill new failed: {reason}\",\n },\n },\n cardTitles: {\n usage: \"usage\",\n context: \"context\",\n search: \"search\",\n subagent: \"subagent\",\n reply: \"reply\",\n reasoning: \"reasoning\",\n reasoningAborted: \"reasoning (aborted)\",\n reasoningEllipsis: \"reasoning\\u2026\",\n error: \"error\",\n },\n cardLabels: {\n prompt: \"prompt\",\n reason: \"reason\",\n output: \"output\",\n cache: \"cache\",\n session: \"session\",\n balance: \"balance\",\n turn: \"turn\",\n system: \"system\",\n tools: \"tools\",\n log: \"log\",\n input: \"input\",\n topTools: \"top tools\",\n logMsgs: \"log msgs\",\n hitSingular: \"{count} hit \\u00b7 {files} file\",\n hitsPlural: \"{count} hits \\u00b7 {files} files\",\n moreHitSingular: \"\\u22ee +{count} more hit\",\n moreHitsPlural: \"\\u22ee +{count} more hits\",\n earlierLine: \"\\u22ee {count} earlier line (use /tool to read full)\",\n earlierLines: \"\\u22ee {count} earlier lines (use /tool to read full)\",\n earlierStackLine: \"\\u22ee {count} earlier stack line hidden\",\n earlierStackLines: \"\\u22ee {count} earlier stack lines hidden\",\n agent: \"agent \\u00b7 {name}\",\n response: \"response\",\n writing: \"writing \\u2026\",\n tok: \"tok\",\n pilcrow: \"\\u00b6\",\n aborted: \"aborted\",\n truncatedByEsc: \"[truncated by esc]\",\n rejected: \"rejected\",\n exit: \"exit {code}\",\n bytesIn: \"{bytes} in\",\n elapsedSec: \"{secs}s\",\n stackTrace: \"stack trace\",\n retries: \"retries\",\n reasoningLabel: \"reasoning \\u00b7 {count} \\u00b6\",\n runningLabel: \"running\",\n workingLabel: \"working\",\n },\n};\n","import type { TranslationSchema } from \"./types.js\";\n\nexport const zhCN: TranslationSchema = {\n common: {\n error: \"错误\",\n warning: \"警告\",\n loading: \"加载中...\",\n done: \"完成\",\n cancel: \"取消\",\n confirm: \"确认\",\n back: \"返回\",\n next: \"下一步\",\n },\n cli: {\n description: \"DeepSeek 原生智能体框架 — 专为缓存命中和低成本令牌构建。\",\n continue: \"恢复最近使用的聊天会话,不显示选择器。\",\n setup: \"交互式向导 — API 密钥、预设、MCP 服务器。随时重新运行以重新配置。\",\n code: \"代码编辑聊天 — 以 <dir>(默认:cwd)为根的文件系统工具,编码系统提示词,v4-flash 基线。\",\n chat: \"具有实时缓存/成本面板的交互式 Ink TUI。\",\n run: \"以非交互方式运行单个任务,流式输出。\",\n stats: \"显示使用情况仪表板。\",\n doctor: \"一键健康检查。\",\n commit: \"从暂存的差异中起草提交消息。\",\n sessions: \"列出保存的聊天会话,或按名称检查。\",\n pruneSessions: \"删除空闲 ≥N 天的已保存会话(默认 90)。使用 --dry-run 预览。\",\n events: \"美化打印内核事件日志侧边文件。\",\n replay: \"交互式 Ink TUI,用于浏览转录稿。\",\n diff: \"在分栏 Ink TUI 中比较两个转录稿。\",\n mcp: \"模型上下文协议 (MCP) 助手 — 发现服务器,测试您的设置。\",\n version: \"打印 Reasonix 版本。\",\n update: \"检查较新版本的 Reasonix 并安装。\",\n index: \"构建(或增量刷新)本地语义搜索索引。\",\n },\n ui: {\n welcome: \"随时运行 `reasonix` 开始聊天 — 您的设置将被记住。\",\n taglineChat: \"DeepSeek 原生智能体\",\n taglineCode: \"DeepSeek 原生代码智能体\",\n taglineSub: \"缓存优先 · Flash 优先\",\n startSessionHint: \"输入消息以开始您的会话\",\n inputPlaceholder: \"输入任何内容... (输入 / 使用命令, @ 引用文件)\",\n busy: \"思考中...\",\n thinking: \"▸ 思考中...\",\n undo: \"撤消\",\n undoHint: \"在 5 秒内按 u 撤消\",\n applied: \"已应用\",\n rejected: \"已拒绝\",\n noDashboard: \"禁止自动启动嵌入式 Web 仪表板。\",\n dashboardAutoStartFailed:\n \"▲ 仪表板自动启动失败 ({reason}) — 尝试 /dashboard,或传递 --no-dashboard 以静默\",\n systemAppendHint: \"追加指令到代码系统提示词。不替换默认提示词 — 在其后添加。\",\n systemAppendFileHint:\n \"追加文件内容到代码系统提示词。不替换默认提示词。UTF-8,相对于 cwd 或绝对路径。\",\n resumedSession:\n '▸ 已恢复会话 \"{name}\",包含 {count} 条历史消息 · /forget 重新开始 · /sessions 列出',\n newSession: '▸ 会话 \"{name}\" (新) — 随聊随存 · /forget 删除 · /sessions 列出',\n ephemeralSession: \"▸ 临时聊天 (不保存会话) — 去掉 --no-session 以启用保存\",\n restoredEdits:\n \"▸ 从中断的运行中恢复了 {count} 个待处理的编辑块 — /apply 提交或 /discard 放弃。\",\n resumedPlan: \"已恢复计划 · {when}{summary}\",\n tipEditBindings: {\n topic: \"编辑门控快捷键\",\n sections: [\n {\n rows: [\n { key: \"y / n\", text: \"接受或放弃待处理的编辑\" },\n { key: \"Shift+Tab\", text: \"切换 预览 ↔ 自动(持久化;自动模式立即应用)\" },\n { key: \"u\", text: \"撤销上次自动应用的批处理(5 秒横幅内)\" },\n ],\n },\n ],\n footer: \"当前模式显示在底部状态栏 · /keys 查看完整快捷键参考\",\n },\n tipMouseClipboard: {\n topic: \"鼠标 + 剪贴板\",\n sections: [\n {\n rows: [\n { key: \"拖动\", text: \"直接选中文本 — 终端原生,不需要按 Shift\" },\n {\n key: \"右键\",\n text: \"终端原生菜单(Windows Terminal 等的复制 / 粘贴)\",\n },\n { key: \"滚轮\", text: \"滚动聊天记录(Web / 云端 / SSH 终端也能用)\" },\n {\n key: \"↑ / ↓\",\n text: \"滚动聊天 · 输入框历史 + 多行光标用 Ctrl+P / Ctrl+N\",\n },\n ],\n },\n ],\n footer: \"运行 /keys 查看完整键盘 + 鼠标参考\",\n },\n keysReference: {\n topic: \"Reasonix 键盘 + 鼠标参考\",\n sections: [\n {\n title: \"键盘\",\n rows: [\n { key: \"Enter\", text: \"提交输入\" },\n { key: \"Shift+Enter\", text: \"在输入框中插入换行\" },\n { key: \"↑ / ↓\", text: \"滚动聊天记录(鼠标滚轮也走这条路径)\" },\n {\n key: \"Ctrl+P / Ctrl+N\",\n text: \"上一条 / 下一条输入历史 · 多行草稿中按行移动光标\",\n },\n { key: \"Ctrl+A / Ctrl+E\", text: \"跳到当前行的开头 / 结尾\" },\n { key: \"Ctrl+W\", text: \"删除光标前的一个词\" },\n { key: \"Ctrl+U\", text: \"清空整个输入缓冲区\" },\n { key: \"Tab\", text: \"补全 @-mention · 进入文件夹 · 接受 slash 命令\" },\n { key: \"Shift+Tab\", text: \"编辑门控:切换 预览 ↔ 自动 模式\" },\n { key: \"Esc\", text: \"关闭弹出选择器 · 中止当前模型回合\" },\n { key: \"Ctrl+C\", text: \"中止当前模型回合(不是复制 — 见剪贴板段)\" },\n { key: \"PgUp / PgDn\", text: \"整页滚动聊天记录\" },\n { key: \"End\", text: \"跳到聊天的最新一行\" },\n ],\n },\n {\n title: \"鼠标\",\n rows: [\n { key: \"滚轮\", text: \"滚动聊天记录(Web / 云端 / SSH 终端也能用)\" },\n { key: \"拖动\", text: \"原生选中文本 — 直接复制,不需要修饰键\" },\n { key: \"右键\", text: \"终端原生(Windows Terminal 等的粘贴菜单)\" },\n ],\n },\n {\n title: \"复制 / 粘贴\",\n rows: [\n { key: \"选中文字\", text: \"直接拖动 — 终端原生(不需要任何修饰键)\" },\n {\n key: \"复制\",\n text: \"Ctrl+Shift+C(Win/Linux)· Cmd+C(macOS)— 或选中即复制(看终端设置)\",\n },\n { key: \"粘贴\", text: \"Ctrl+V 或 Ctrl+Shift+V(Win/Linux)· Cmd+V(macOS)\" },\n {\n key: \"bracketed paste\",\n text: \"多行粘贴整体进入 — 中间换行不会触发提交\",\n },\n ],\n },\n {\n title: \"编辑门控(仅 code 模式)\",\n rows: [\n { key: \"y / n\", text: \"在预览模态中接受或放弃待处理的编辑\" },\n { key: \"Shift+Tab\", text: \"切换 预览 ↔ 自动(持久化)\" },\n { key: \"u\", text: \"撤销上次自动应用的批处理(5 秒横幅内)\" },\n ],\n },\n ],\n footer:\n \"通过 DECSET 1007(alternate-scroll),终端把滚轮翻译成 ↑/↓ 发给应用 — 大多数终端(含 Web / 云端 / SSH)都能滚,且不影响终端原生选区。直接拖动选中文本无需 Shift。传入 --no-mouse 可关闭。\",\n },\n tipShownOnce: \"仅显示一次\",\n modelOverride: \"覆盖默认模型\",\n noSession: \"禁用本次运行的会话持久化\",\n resumeHint: \"强制恢复指定会话(即使空闲)\",\n newHint: \"强制创建新会话(忽略 --session / --continue)\",\n transcriptHint: \"JSONL 转录稿的写入路径\",\n budgetHint: \"会话美元上限 — 80% 时警告,100% 时拒绝下一轮\",\n modelIdHint: \"DeepSeek 模型 ID(例如 deepseek-v4-flash)\",\n systemPromptHint: \"覆盖默认系统提示词\",\n presetHint: \"模型组合 — auto|flash|pro\",\n sessionNameHint: \"会话名称(默认:'default')\",\n ephemeralHint: \"禁用本次运行的会话持久化\",\n mcpSpecHint: \"MCP 服务器规格(可重复)\",\n mcpPrefixHint: \"用此字符串为 MCP 工具名添加前缀\",\n noConfigHint: \"本次运行忽略 ~/.reasonix/config.json\",\n presetHintShort: \"模型组合 — auto|flash|pro\",\n budgetHintShort: \"会话美元上限\",\n transcriptHintShort: \"JSONL 转录稿路径\",\n mcpSpecHintShort: \"MCP 服务器规格(可重复)\",\n mcpPrefixHintShort: \"MCP 工具名前缀\",\n dryRunHint: \"显示将要安装的内容但不实际安装\",\n rebuildHint: \"从头重建索引\",\n embedModelHint: \"嵌入模型名称\",\n projectDirHint: \"项目根目录\",\n ollamaUrlHint: \"Ollama 服务器 URL\",\n skipPromptsHint: \"跳过确认提示\",\n verboseHint: \"显示完整的会话元数据\",\n pruneDaysHint: \"删除空闲此天数或更多的会话(默认 90)\",\n pruneDryRunHint: \"列出将要删除的内容但不实际删除\",\n eventTypeHint: \"按事件类型过滤\",\n eventSinceHint: \"从此事件 ID 开始\",\n eventTailHint: \"仅显示最后 N 个事件\",\n jsonHint: \"以 JSON 格式输出\",\n projectionHint: \"显示每个事件的投影状态\",\n printHint: \"打印到标准输出而非 TUI\",\n headHint: \"仅显示前 N 个事件\",\n tailHint: \"仅显示最后 N 个事件\",\n mdReportHint: \"将 markdown 差异报告写入此路径\",\n printHintTable: \"打印表格到标准输出\",\n tuiHint: \"打开交互式 TUI\",\n labelAHint: \"左侧面板的标签\",\n labelBHint: \"右侧面板的标签\",\n mcpListDescription: \"浏览 MCP 注册表(官方 → smithery → 本地 fallback)\",\n mcpInspectDescription: \"检查 MCP 服务器规格(工具、资源、提示)\",\n mcpSearchDescription: \"在 MCP 注册表中搜索匹配的服务器\",\n mcpInstallDescription: \"按名称安装 MCP 服务器(将其规格写入配置)\",\n mcpBrowseDescription: \"交互式市场浏览器 — 输入过滤、回车安装\",\n mcpLocalHint: \"只显示内置的离线目录\",\n mcpRefreshHint: \"忽略 24 小时缓存,强制刷新\",\n mcpLimitHint: \"最多显示多少条\",\n mcpPagesHint: \"一次性预加载多少页(默认 1)\",\n mcpAllHint: \"加载全部页(首次较慢)\",\n mcpMaxPagesHint: \"搜索时最多走多少页(默认 20)\",\n jsonHintCatalog: \"以 JSON 格式输出\",\n jsonHintReport: \"以 JSON 格式输出检查报告\",\n modelOverrideFlash: \"覆盖模型(默认:deepseek-v4-flash)\",\n skipConfirmHint: \"跳过确认提示\",\n },\n slash: {\n help: { description: \"显示完整命令参考\" },\n status: { description: \"当前模型、标志、上下文、会话\" },\n preset: {\n description: \"模型组合 — 自动在 flash → pro 之间切换,或锁定 flash/pro\",\n argsHint: \"<auto|flash|pro>\",\n },\n model: { description: \"切换 DeepSeek 模型 ID\", argsHint: \"<id>\" },\n models: { description: \"列出从 DeepSeek /models 获取的可用模型\" },\n language: {\n description: \"切换运行时语言\",\n argsHint: \"<en|zh-CN>\",\n success: \"语言已切换为简体中文。\",\n unsupported: \"不支持的语言代码:{code}。支持的语言:{supported}。\",\n },\n pro: {\n description: \"仅为下一轮启用 v4-pro(一次性 · 自动解除)\",\n argsHint: \"[off]\",\n },\n budget: {\n description: \"会话美元上限 — 80% 时警告,100% 时拒绝下一轮。默认关闭。单独 /budget 显示状态\",\n argsHint: \"[usd|off]\",\n },\n mcp: { description: \"列出附加到此会话的 MCP 服务器 + 工具\" },\n resource: {\n description: \"浏览 + 读取 MCP 资源(无参数 → 列出 URI;<uri> → 获取内容)\",\n argsHint: \"[uri]\",\n },\n prompt: {\n description: \"浏览 + 获取 MCP 提示(无参数 → 列出名称;<name> → 渲染提示)\",\n argsHint: \"[name]\",\n },\n memory: {\n description: \"显示 / 管理固定记忆(REASONIX.md + ~/.reasonix/memory)\",\n argsHint: \"[list|show <name>|forget <name>|clear <scope> confirm]\",\n },\n skill: {\n description: \"列出 / 运行用户技能(<project>/.reasonix/skills + ~/.reasonix/skills)\",\n argsHint: \"[list|show <name>|<name> [args]]\",\n },\n hooks: {\n description: \"列出活跃的 hooks(.reasonix/ 下的 settings.json)· reload 从磁盘重新读取\",\n argsHint: \"[reload]\",\n },\n permissions: {\n description: \"显示 / 编辑 shell 允许列表(内置只读 · 项目级:~/.reasonix/config.json)\",\n argsHint: \"[list|add <prefix>|remove <prefix|N>|clear confirm]\",\n },\n dashboard: {\n description: \"启动嵌入式 Web 仪表板(127.0.0.1,token 保护)\",\n argsHint: \"[stop]\",\n },\n update: { description: \"显示当前版本与最新版本及升级命令\" },\n stats: {\n description: \"跨会话成本仪表板(今日 / 本周 / 本月 / 全部 · 缓存命中 · 与 Claude 对比)\",\n },\n cost: {\n description: \"空 → 上一轮花费(使用卡片);带文本 → 估算发送成本(最坏情况 + 可能缓存命中)\",\n argsHint: \"[text]\",\n },\n doctor: {\n description: \"健康检查(api / config / api-reach / index / hooks / project)\",\n },\n context: { description: \"显示上下文窗口分解(系统 / 工具 / 日志 / 输入)\" },\n retry: { description: \"截断并重发您的最后一条消息(重新采样)\" },\n compact: {\n description: \"缩小日志中过大的工具结果和工具调用参数;上限为 tokens,默认 4000\",\n argsHint: \"[tokens]\",\n },\n keys: { description: \"键盘 + 鼠标 + 复制粘贴参考\" },\n plans: { description: \"列出此会话的活跃 + 归档计划(最新在前)\" },\n replay: {\n description: \"加载归档计划为只读的时间旅行快照(默认:最新)\",\n argsHint: \"[N]\",\n },\n sessions: { description: \"列出已保存的会话(当前标记为 ▸)\" },\n setup: { description: \"提醒您退出并运行 `reasonix setup`\" },\n semantic: {\n description: \"显示 semantic_search 状态 — 已构建?Ollama 已安装?如何启用\",\n },\n clear: { description: \"仅清除可见的滚动回放(日志/上下文保留)\" },\n new: { description: \"开始全新对话(清除上下文 + 滚动回放)\" },\n loop: {\n description: \"每 <interval> 自动重新提交 <prompt>,直到您输入 / Esc / /loop stop\",\n argsHint: \"<5s..6h> <prompt> · stop · (无参数 = 状态)\",\n },\n exit: { description: \"退出 TUI\" },\n init: {\n description:\n \"扫描项目并合成基线 REASONIX.md(模型写入;使用 /apply 审查)。`force` 覆盖已有文件。\",\n argsHint: \"[force]\",\n },\n apply: {\n description:\n \"将待处理的编辑块提交到磁盘(无参数 → 全部;`1`、`1,3` 或 `1-4` → 该子集,其余保持待处理)\",\n argsHint: \"[N|N,M|N-M]\",\n },\n discard: {\n description: \"丢弃待处理的编辑块而不写入(无参数 → 全部;索引 → 该子集)\",\n argsHint: \"[N|N,M|N-M]\",\n },\n walk: {\n description: \"逐块逐步处理待处理的编辑(git-add-p 风格:每块 y/n,a 应用剩余,A 切换 AUTO)\",\n },\n undo: { description: \"回滚最后应用的编辑批处理\" },\n history: {\n description: \"列出此会话的每个编辑批处理(用于 /show 的 ID,撤消标记)\",\n },\n show: {\n description: \"转储存储的编辑差异(省略 id 时为最新未撤消的)\",\n argsHint: \"[id]\",\n },\n commit: { description: \"git add -A && git commit -m ...\", argsHint: '\"msg\"' },\n checkpoint: {\n description: \"快照会话涉及的每个文件(Cursor 风格内部存储,非 git)。单独 /checkpoint 列出。\",\n argsHint: \"[name|list|forget <id>]\",\n },\n restore: {\n description: \"将文件回滚到命名的检查点(见 /checkpoint list)\",\n argsHint: \"<name|id>\",\n },\n plan: {\n description: \"切换只读计划模式(写入被弹回直到 submit_plan + 审批)\",\n argsHint: \"[on|off]\",\n },\n mode: {\n description:\n \"编辑门控:review(排队)· auto(应用+撤消)· yolo(应用+自动 shell)。Shift+Tab 循环。\",\n argsHint: \"[review|auto|yolo]\",\n },\n jobs: { description: \"列出 run_background 启动的后台作业\" },\n kill: {\n description: \"按 ID 停止后台作业(SIGTERM → 宽限期后 SIGKILL)\",\n argsHint: \"<id>\",\n },\n logs: {\n description: \"跟踪后台作业的输出(默认最后 80 行)\",\n argsHint: \"<id> [lines]\",\n },\n },\n wizard: {\n languageTitle: \"选择语言\",\n languageSubtitle: \"已根据系统语言自动选中。之后可用 /language 切换。\",\n welcomeTitle: \"欢迎使用 Reasonix。\",\n apiKeyPrompt: \"粘贴你的 DeepSeek API key 开始使用。\",\n apiKeyGetOne: \"在此获取:https://platform.deepseek.com/api_keys\",\n apiKeySavedLocally: \"保存在本地:{path}\",\n apiKeyInputLabel: \"key › \",\n apiKeyInvalid: \"key 长度不足——请粘贴完整 token(16+ 字符,不含空格)。\",\n apiKeyPreview: \"预览:{redacted}\",\n themeTitle: \"选择主题\",\n themeSubtitle: \"方向键切换时即时预览效果,之后可用 /theme 更改。\",\n themeSampleHeading: \"示例\",\n themeFooter: \"[↑↓] 移动 · [Enter] 确认 · [Esc] 取消\",\n themeCaption: {\n default: \"GitHub 深色(默认)\",\n dark: \"深色调\",\n light: \"清爽浅色\",\n \"tokyo-night\": \"东京夜色\",\n \"github-dark\": \"GitHub 深色\",\n \"github-light\": \"GitHub 浅色\",\n \"high-contrast\": \"高对比度(无障碍)\",\n },\n reviewLabelTheme: \"主题\",\n presetTitle: \"选择预设\",\n mcpTitle: \"Reasonix 要为你接入哪些 MCP 服务器?\",\n mcpUserArgsHint: \"(需要你提供 {arg})\",\n mcpFooterMulti: \"[↑↓] 移动 · [空格] 选择 · [Enter] 确认 · [Esc] 取消 · 全不选 = 跳过\",\n mcpArgsTitle: \"配置 {name}\",\n mcpArgsDirMissing: \"目录 {path} 不存在。\",\n mcpArgsDirCreateHint: \"[Y/Enter] 创建(mkdir -p)· [N/Esc] 输入其他路径\",\n mcpArgsDirCreateFailed: \"无法创建 {path}:{message}\",\n mcpArgsRequiredParam: \"必填参数:\",\n mcpArgsEmpty: \"{name} 需要一个值 — 不能为空。\",\n mcpArgsNotADir: \"{path} 存在但不是目录。\",\n reviewTitle: \"确认保存\",\n reviewLabelApiKey: \"API key\",\n reviewLabelLanguage: \"语言\",\n reviewLabelPreset: \"预设\",\n reviewLabelMcp: \"MCP\",\n reviewMcpNone: \"(无)\",\n reviewMcpServers: \"{count} 个服务器\",\n reviewSavesTo: \"保存到 {path}\",\n reviewSaveError: \"保存配置失败:{message}\",\n reviewFooter: \"[Enter] 保存 · [Esc] 取消\",\n savedTitle: \"▸ 已保存。\",\n savedFooter: \"[Enter] 退出\",\n selectFooter: \"[↑↓] 移动 · [Enter] 确认 · [Esc] 取消\",\n stepCounter: \"步骤 {step}/{total} · \",\n },\n planFlow: {\n approveCardTitle: \"确认计划\",\n approveCardMetaRight: \"等待中\",\n openQuestionsBanner:\n \"▲ 计划中标记了待确认的问题或风险 —— 请选 {refine} 给出明确答案,再让模型继续。\",\n openQuestionsHeader: \"待确认 / 风险\",\n truncatedBodyMore: \"… 还有 {n} 行在上方滚动历史中\",\n truncatedBodyMorePlural: \"… 还有 {n} 行在上方滚动历史中\",\n picker: {\n accept: \"采纳\",\n acceptHint: \"立即按顺序执行\",\n refine: \"细化\",\n refineHint: \"给模型更多指引,重新出一版计划\",\n revise: \"改写\",\n reviseHint: \"在执行前就地编辑计划(跳过 / 重排步骤)\",\n reject: \"驳回\",\n rejectHint: \"丢弃,让模型从头再来\",\n },\n refineFooter: \"⏎ 发送 · esc 返回选项\",\n refineQuestionsHeading: \"回答以下问题,或直接说明你想要的修改:\",\n modes: {\n approve: {\n title: \"采纳 —— 还有补充指示吗?\",\n hint: \"回答计划中的问题、补充约束,或直接回车按现状采纳。\",\n blankHint: \"(留空回车 = 不附加指示直接采纳。)\",\n },\n refine: {\n title: \"细化 —— 模型应该改什么?\",\n hint: \"说明问题在哪、缺什么,或者回答计划提出的疑问。\",\n blankHint: \"(留空回车 = 让模型对所有待确认问题选用安全默认。)\",\n },\n reject: {\n title: \"驳回 —— 告诉模型原因(可选)\",\n hint: \"说明模型对你的目标理解错在哪里,或你真正想要什么。\",\n blankHint: \"(留空回车 = 不解释直接取消;模型会反过来问你想要什么。)\",\n },\n \"checkpoint-revise\": {\n title: \"改写 —— 下一步前要调整什么?\",\n hint: \"范围调整、跳过步骤、换个思路 —— 模型会据此修改剩余步骤。\",\n blankHint: \"(留空回车 = 按当前计划继续。)\",\n },\n \"choice-custom\": {\n title: \"自定义回答 —— 想说什么都行\",\n hint: \"自由文本。模型会原样读取并继续 —— 不必匹配候选项。\",\n blankHint: \"(留空回车 = 让模型反过来问你想要什么。)\",\n },\n },\n checkpoint: {\n title: \"检查点 —— 当前步骤已完成\",\n continue: \"继续 —— 执行下一步\",\n continueHint: \"模型从下一步继续。\",\n revise: \"调整 —— 在下一步前给反馈\",\n reviseHint: \"先暂停,输入指引;模型会调整剩余计划。\",\n stop: \"停止 —— 在此结束计划\",\n stopHint: \"模型总结已完成的工作并结束。\",\n },\n stepList: {\n counter: \"{total} 个步骤\",\n counterSingular: \"{total} 个步骤\",\n counterDone: \"{done}/{total} 已完成({pct}%) · 共 {total} 步\",\n counterDoneSingular: \"{done}/{total} 已完成({pct}%) · 共 {total} 步\",\n },\n },\n app: {\n walkCancelledRemaining: \"▸ 浏览已取消 — 还有 {count} 个待处理编辑块。\",\n walkCancelled: \"▸ 浏览已取消。\",\n editModeYolo:\n \"▸ 编辑模式:YOLO — 编辑和 shell 命令都自动执行。/undo 仍可撤销编辑。请谨慎使用。\",\n editModeAuto:\n \"▸ 编辑模式:AUTO — 编辑立即应用;5 秒内按 u 撤销(空格暂停计时)。shell 命令仍会询问。\",\n editModeReview: \"▸ 编辑模式:review — 编辑入队待 /apply(或 y)/ /discard(或 n)\",\n rejectedEdit: \"▸ 拒绝了对 {path} 的编辑{context}\",\n autoApprovingRest: \"▸ 本轮剩余编辑自动批准\",\n flippedAutoSession: \"▸ 已切换到 AUTO 模式(本会话剩余生效,已持久化)\",\n flippedAutoWalk: \"▸ 已切换到 AUTO 模式 — 后续编辑立即应用。浏览模式退出。\",\n dashboardStopped: \"▸ 仪表板已停止。\",\n notedMemory: \"▸ 已记录({scope})— {verb} {path}\",\n notedScopeProject: \"项目\",\n notedScopeGlobal: \"全局\",\n notedVerbCreated: \"创建\",\n notedVerbAppended: \"追加到\",\n memoryWriteFailed: \"# 记忆写入失败\",\n commandFailed: \"! 命令失败\",\n restoreCodeOnly: \"▸ /restore 仅在代码模式可用\",\n hookUserPromptSubmit: \"UserPromptSubmit 钩子\",\n hookStop: \"Stop 钩子\",\n atMentions: \"▸ @mentions:{parts}\",\n atUrl: \"▸ @url:{parts}\",\n atUrlFailed: \"@url 展开失败\",\n denied: \"▸ 已拒绝:{cmd}{context}\",\n alwaysAllowed: '▸ 已对 {dir} 永久允许 \"{prefix}\"',\n runningCommand: \"▸ 正在执行:{cmd}\",\n startingBackground: \"▸ 后台启动:{cmd}\",\n checkpointSaved: \"⛁ 已保存检查点 · {id} · {count} 个文件 · /restore {id} 可回滚此步\",\n continuingAfter: \"▸ 在 {label}{counter} 之后继续\",\n planStoppedAt: \"▸ 计划在 {label}{counter} 处停止\",\n revisingAfter: \"▸ 在 {label} 之后修订 — {feedback}\",\n },\n hooks: {\n head: \"钩子 {tag} `{cmd}` {decision}{truncTag}\",\n headWithDetail: \"钩子 {tag} `{cmd}` {decision}{truncTag}:{detail}\",\n truncated: \"(输出在 256KB 处截断)\",\n decisionBlock: \"拦截\",\n decisionWarn: \"告警\",\n decisionTimeout: \"超时\",\n decisionError: \"错误\",\n },\n summary: {\n status: \"正在总结已收集的内容…\",\n hallucinatedFallback:\n \"(模型生成了伪造的工具调用标记而非纯文本总结 — 试试 /retry 换个更窄的问题,或 /think 查看 R1 的推理)\",\n failedAfterReason:\n \"{label},且回退的总结调用也失败:{message}。请运行 /clear 后用更窄的问题重试,或提高 --max-tool-iters。\",\n },\n loop: {\n budgetExhausted:\n \"会话预算已用完 — 已花费 ${spent} ≥ 上限 ${cap}。用 /budget <usd> 提高上限,/budget off 清除上限,或结束会话。\",\n budget80Pct: \"▲ 预算已用 80% — ${spent} / ${cap}。下一两轮可能就触顶。\",\n proArmed: \"⇧ /pro 已装备 — 本轮使用 deepseek-v4-pro(一次性 · 本轮后自动解除)\",\n abortedAtIter:\n \"在第 {iter}/{cap} 次工具调用处中断 — 未生成总结即停止(按 ↑ + Enter 或 /retry 恢复)\",\n toolUploadStatus: \"工具结果已上传 · 模型在生成下一条响应前思考中…\",\n toolBudgetWarning: \"已用 {iter}/{cap} 次工具调用 — 接近上限。按 Esc 立即强制总结。\",\n preflightFoldStatus: \"预检:上下文接近上限,尝试折叠…\",\n preflightFolded:\n \"预检:请求约 {estimate}/{ctxMax} tokens({pct}%)— 已折叠 {beforeMessages} 条消息 → {afterMessages}(总结 {summaryChars} 字)。发送中。\",\n preflightNoFold:\n \"预检:请求约 {estimate}/{ctxMax} tokens({pct}%)且没有可折叠的内容 — DeepSeek 大概率会返回 400。请运行 /clear 或 /new 重新开始。\",\n flashEscalation: \"⇧ flash 请求升级 — 本轮改用 {model}{reasonSuffix}\",\n harvestStatus: \"正在从推理过程提取计划状态…\",\n autoEscalation:\n \"⇧ 本轮剩余调用自动升级到 {model} — flash 命中 {breakdown}。下一轮回退到 {fallback},除非已装备 /pro。\",\n repeatToolCallWarning: \"拦截到重复工具调用 — 让模型察觉问题并换种方式重试。\",\n stormStuck:\n \"已停止卡死的重试循环 — 模型在自纠提示后仍以相同参数重复调用同一工具。请尝试 /retry、换种说法,或排查底层阻塞。\",\n stormSuppressed: \"已抑制 {count} 次重复工具调用 — 同一名称 + 参数触发 3 次以上。\",\n compactingHistoryStatus: \"正在压缩历史{aggressiveTag}…\",\n aggressiveTag: \"(激进)\",\n foldedHistory:\n \"上下文 {before}/{ctxMax}({pct}%)— 已折叠 {beforeMessages} 条消息 → {afterMessages}(总结 {summaryChars} 字)。继续。\",\n aggressivelyFoldedHistory:\n \"上下文 {before}/{ctxMax}({pct}%)— 已激进折叠 {beforeMessages} 条消息 → {afterMessages}(总结 {summaryChars} 字)。继续。\",\n forcingSummary:\n \"上下文 {before}/{ctxMax}({pct}%)— 基于已收集到的内容强制总结。请运行 /compact、/clear 或 /new 重置。\",\n },\n errors: {\n contextOverflow:\n \"上下文溢出(DeepSeek 400):会话历史已达 {requested},超出模型 prompt 上限(V4:1M tokens;旧版 chat/reasoner:131k)。通常是单个工具结果太大。Reasonix 默认将新工具结果限制在 8k tokens,并在会话加载时自动修复超大历史 — 重启常能清掉。如果仍然溢出,运行 /forget(删除会话)或 /clear(丢弃显示中的历史)从头开始。\",\n contextOverflowTooMany: \"tokens 数量过多\",\n auth401:\n \"认证失败(DeepSeek 401):{inner}。你的 API key 被拒绝。运行 `reasonix setup` 或 `export DEEPSEEK_API_KEY=sk-...` 修复。在 https://platform.deepseek.com/api_keys 获取 key。\",\n balance402:\n \"余额不足(DeepSeek 402):{inner}。在 https://platform.deepseek.com/top_up 充值 — 余额非零时面板顶栏会显示。\",\n badparam422: \"参数错误(DeepSeek 422):{inner}\",\n badrequest400: \"请求错误(DeepSeek 400):{inner}\",\n deepseek5xxHead:\n \"DeepSeek 服务不可用({status}) — 这是 DeepSeek 服务端问题,不是 Reasonix 故障。已按指数退避重试 4 次。\",\n deepseek5xxReachable:\n \" DeepSeek 主 API 健康检查通过,但 /chat/completions 在挂 — 他们那边部分服务异常。\",\n deepseek5xxUnreachable:\n \" 无法从你的网络访问 DeepSeek API — 可能是 DS 整体故障,也可能是本地网络问题。\",\n deepseek5xxActionNetwork:\n \" 建议:(1) 检查网络,(2) 等 30 秒后重试,(3) 查看状态页 https://status.deepseek.com。\",\n deepseek5xxActionRetry:\n \" 建议:(1) 等 30 秒后重试,(2) 用 /preset 切换模型,(3) 查看状态页 https://status.deepseek.com。\",\n innerNoMessage: \"(无错误信息)\",\n reasonAborted: \"[用户已中断(Esc) — 正在总结到目前为止的发现]\",\n reasonContextGuard: \"[上下文额度即将耗尽 — 在下一次调用溢出之前先总结]\",\n reasonStuck: \"[卡在重复的工具调用上 — 说明已尝试的方法以及阻塞点]\",\n reasonBudget: \"[工具调用配额({iterCap})已用尽 — 基于已发现的内容强制总结]\",\n labelAborted: \"用户中断\",\n labelContextGuard: \"触发上下文保护(prompt > 80% 窗口)\",\n labelStuck: \"卡死(重复工具调用被反风暴机制抑制)\",\n labelBudget: \"工具调用配额({iterCap})已用尽\",\n },\n handlers: {\n basic: {\n newInfo: \"▸ 新对话 — 已从上下文中丢弃 {count} 条消息。同一会话,全新开始。\",\n helpTitle: \"命令:\",\n helpShellTitle: \"Shell 快捷方式:\",\n helpShell: \" !<cmd> 在沙箱根目录运行 <cmd>;输出进入对话\",\n helpShellDetail: \" 以便模型在下一轮看到。无允许列表限制。\",\n helpShellConsent: \" 用户输入 = 明确同意。\",\n helpShellExample: \" 示例:!git status !ls src/ !npm test\",\n helpMemoryTitle: \"快速记忆:\",\n helpMemoryPin:\n \" #<note> 将 <note> 追加到 <project>/REASONIX.md(可提交)。\",\n helpMemoryPinEx: \" 示例:#findByEmail 必须区分大小写\",\n helpMemoryGlobal:\n \" #g <note> 将 <note> 追加到 ~/.reasonix/REASONIX.md(全局,不提交)。\",\n helpMemoryGlobalEx: \" 示例:#g 始终使用 pnpm 而非 npm\",\n helpMemoryPinBoth:\n \" 两者都固定到每个未来会话的前缀中。比 /memory 更快。\",\n helpMemoryEscape: \" 使用 `\\\\#text` 发送字面量 `#text` 给模型。\",\n helpFileTitle: \"文件引用(代码模式):\",\n helpFile: \" @path/to/file 发送时将文件内容内联到 [Referenced files] 下。\",\n helpFilePicker:\n \" 输入 `@` 打开选择器(↑↓ 导航,Tab/Enter 选择)。\",\n helpUrlTitle: \"URL 引用:\",\n helpUrl: \" @https://example.com 获取 URL,剥离 HTML,内联到 [Referenced URLs] 下。\",\n helpUrlCache: \" 同一会话中相同 URL 只获取一次(内存缓存)。\",\n helpUrlPunct: \" 自动剥离尾部标点符号(./,/))。\",\n helpPresetsTitle: \"预设(branch + harvest 永远不会自动启用 — 仅手动选择):\",\n helpPresetAuto: \" auto v4-flash → v4-pro 在困难轮次切换 ← 默认 · 简单时便宜,困难时智能\",\n helpPresetFlash: \" flash 始终使用 v4-flash 最便宜 · 每轮成本可预测\",\n helpPresetPro:\n \" pro 始终使用 v4-pro 约 3 倍 flash · 用于困难的多轮工作\",\n helpSessionsTitle: \"会话(默认自动启用,命名为 'default'):\",\n helpSessionCustom: \" reasonix chat --session <name> 使用不同的命名会话\",\n helpSessionNone: \" reasonix chat --no-session 禁用本次运行的持久化\",\n retryNone: \"没有可重试的内容 — 此会话日志中没有先前的用户消息。\",\n retryInfo: '▸ 重试中:\"{preview}\"',\n loopTuiOnly: \"/loop 仅在交互式 TUI 中可用(不在 run/replay 中)。\",\n loopStopped: \"▸ 循环已停止。\",\n loopNoActive: \"没有活动的循环可停止。\",\n loopNoActiveHint:\n \"没有活动的循环。使用 `/loop <interval> <prompt>` 启动一个(例如 /loop 30s npm test)。\\n取消方式:/loop stop · Esc · /clear /new · 任何用户输入的提示。\",\n loopStarted:\n '▸ 循环已启动 — 每 {duration} 重新提交 \"{prompt}\"。输入任何内容(或 /loop stop)取消。',\n keysNeedsTui: \"/keys 需要 TUI 上下文(postKeys 已连接)。\",\n },\n admin: {\n doctorNeedsTui: \"/doctor 需要 TUI 上下文(postDoctor 已连接)。\",\n doctorRunning: \"⚕ 健康检查 — 正在运行…\",\n hooksReloadUnavailable: \"/hooks reload 在此上下文中不可用(无重载回调)。\",\n hooksReloaded: \"▸ 已重载 hooks · {count} 个活跃\",\n hooksUsage:\n \"用法:/hooks 列出活跃的 hooks\\n /hooks reload 重新读取 settings.json 文件\",\n hooksNone: \"未配置 hooks。\",\n hooksDropHint: \"将包含 `hooks` 键的 settings.json 放入以下任一位置:\",\n hooksProject: \" · {path}(项目)\",\n hooksProjectFallback: \" · <project>/.reasonix/settings.json(项目)\",\n hooksGlobal: \" · {path}(全局)\",\n hooksEvents: \"事件:PreToolUse, PostToolUse, UserPromptSubmit, Stop\",\n hooksExitCodes: \"exit 0 = 通过 · exit 2 = 阻止(Pre*)· 其他 = 警告\",\n hooksLoaded: \"▸ 已加载 {count} 个 hook\",\n hooksSources: \"来源:project={project} · global={global}\",\n updateCurrent: \"当前:reasonix {version}\",\n updateLatestPending: \"最新:(尚未解析 — 后台检查进行中或离线)\",\n updateRetryHint: \"已触发新的注册表获取 — 几秒后重试 `/update`,\",\n updateRetryHint2: \"或在另一个终端运行 `reasonix update` 强制同步执行。\",\n updateLatest: \"最新:reasonix {version}\",\n updateUpToDate: \"您已是最新版本。无需操作。\",\n updateNpxHint: \"您正在通过 npx 运行 — 下次 `npx reasonix ...` 启动时将自动获取。\",\n updateNpxForce: \"要强制刷新:`npm cache clean --force`。\",\n updateUpgradeHint: \"要升级,请退出此会话并运行:\",\n updateUpgradeCmd1: \" reasonix update (交互式,支持 --dry-run 预览)\",\n updateUpgradeCmd2: \" {command} (直接安装)\",\n updateInSessionDisabled: \"会话内安装被刻意禁用 — 安装命令会\",\n updateInSessionDisabled2: \"破坏此 TUI 的渲染,且 Windows 可能锁定运行中的二进制文件。\",\n statsNoData: \"尚无使用数据。\",\n statsEveryTurn: \"您在此运行的每一轮都会追加一条记录 — 此会话的轮次\",\n statsWillAppear: \"将在您发送消息后显示在仪表板中。\",\n },\n edits: {\n undoCodeOnly: \"/undo 仅在 `reasonix code` 中可用 — 聊天模式不应用编辑。\",\n historyCodeOnly: \"/history 仅在 `reasonix code` 中可用。\",\n showCodeOnly: \"/show 仅在 `reasonix code` 中可用。\",\n applyCodeOnly: \"/apply 仅在 `reasonix code` 中可用(此处无内容可应用)。\",\n discardCodeOnly: \"/discard 仅在 `reasonix code` 中可用。\",\n planCodeOnly: \"/plan 仅在 `reasonix code` 中可用 — 聊天模式不限制工具写入。\",\n planOn:\n \"▸ 计划模式开启 — 写入工具被限制;模型必须先调用 `submit_plan` 才能执行任何操作。(模型也可以在计划模式关闭时自主调用 submit_plan 处理大型任务 — 此开关是更强的显式约束。)输入 /plan off 退出。\",\n planOff: \"▸ 计划模式关闭 — 写入工具再次可用。模型仍可为大型任务自主提出计划。\",\n modeCodeOnly: \"/mode 仅在 `reasonix code` 中可用。\",\n modeUsage: \"用法:/mode <review|auto|yolo> (Shift+Tab 也可循环)\",\n modeYolo:\n \"▸ 编辑模式:YOLO — 编辑和 Shell 命令自动运行,无提示。/undo 仍可回滚编辑。请谨慎使用。\",\n modeAuto:\n \"▸ 编辑模式:AUTO — 编辑立即应用;在 5 秒内按 u 撤消,或稍后使用 /undo。Shell 命令仍会询问。\",\n modeReview: \"▸ 编辑模式:review — 编辑排队等待 /apply(或 y)/ /discard(或 n)\",\n commitCodeOnly: \"/commit 仅在 `reasonix code` 中可用(需要有根的 git 仓库)。\",\n commitUsage: '用法:/commit \"提交消息\" — 在 {root} 中运行 `git add -A && git commit -m \"…\"`',\n walkCodeOnly: \"/walk 仅在 `reasonix code` 中可用。\",\n checkpointCodeOnly: \"/checkpoint 仅在 `reasonix code` 中可用 — 聊天模式不应用编辑。\",\n checkpointNone:\n \"尚无检查点 — `/checkpoint <name>` 快照会话涉及的每个文件。稍后使用 `/restore <name>` 恢复。\",\n checkpointHeader: \"◈ 检查点 · 已存储 {count} 个\",\n checkpointRestoreHint:\n \" /restore <name|id> · /checkpoint forget <id> · /checkpoint <name> 添加\",\n checkpointForgetUsage: \"用法:/checkpoint forget <id|name>\",\n checkpointNoMatch: '▸ 未找到匹配 \"{name}\" 的检查点 — 见 /checkpoint list',\n checkpointDeleted: \"▸ 已删除检查点 {id}({name})\",\n checkpointDeleteFailed: \"▸ 删除 {id} 失败(已消失?)\",\n checkpointSaveUsage: \"用法:/checkpoint <name> (或 /checkpoint list 查看现有)\",\n checkpointSavedEmpty:\n '▸ 检查点 \"{name}\" 已保存({id})— 但尚未涉及任何文件,因此是空基线。此后的编辑将可撤消。',\n checkpointSaved:\n '▸ 检查点 \"{name}\" 已保存({id})— {files} 个文件,{size} KB。恢复:/restore {name}',\n restoreCodeOnly: \"/restore 仅在 `reasonix code` 中可用。\",\n restoreUsage: \"用法:/restore <name|id> (见 /checkpoint list 获取 ID)\",\n restoreNoMatch: '▸ 未找到匹配 \"{target}\" 的检查点 — 尝试 /checkpoint list',\n restoreInfo: '▸ 已恢复 \"{name}\"({id}),来自 {when}',\n restoreWrote: \" · 写回了 {count} 个文件\",\n restoreRemoved: \" · 移除了 {count} 个文件(检查点时不存在)\",\n restoreSkipped: \" ✗ 跳过了 {count} 个文件:\",\n cwdCodeOnly: \"/cwd 仅在 `reasonix code` 中可用。\",\n cwdUsage:\n \"用法:/cwd <path> (当前根目录:{current})。重新指向 filesystem / shell / memory 工具到 <path>。\",\n cwdUsageNoCurrent: \"用法:/cwd <path> 将工作区根目录切换到 <path>。\",\n },\n model: {\n modelHint: \"尝试 deepseek-v4-flash 或 deepseek-v4-pro — 运行 /models 获取实时列表\",\n modelUsage: \"用法:/model <id> ({hint})\",\n modelNotInCatalog:\n \"model → {id} (⚠ 不在获取的目录中:{list}。如果这是错误的,下次调用将返回 400 — 运行 /models 刷新。)\",\n modelSet: \"model → {id}\",\n presetAuto: \"preset → auto (v4-flash → v4-pro 在困难轮次切换 · 默认)\",\n presetFlash: \"preset → flash (始终使用 v4-flash · 最便宜 · /pro 仍可临时提升一轮)\",\n presetPro: \"preset → pro (始终使用 v4-pro · 约 3 倍 flash · 用于困难的多轮工作)\",\n presetUsage: \"用法:/preset <auto|flash|pro>\",\n proNothingArmed: \"未启用 — /pro 不带参数将为下一轮启用 pro\",\n proDisarmed: \"▸ /pro 已解除 — 下一轮回退到当前预设\",\n proUsage:\n \"用法:/pro 为下一轮启用 pro(一次性,自动解除)\\n /pro off 在下一轮前取消启用状态\",\n proArmed:\n \"▸ /pro 已启用 — 您的下一条消息将在 {model} 上运行,无论预设如何。一轮后自动解除。使用 /preset max 进行持久切换。\",\n budgetNoCap:\n \"未设置会话预算 — Reasonix 将持续运行直到您停止。使用以下方式设置:/budget <usd> (例如 /budget 5)\",\n budgetStatus: \"预算:${spent} / ${cap}({pct}%)· /budget off 清除,/budget <usd> 更改\",\n budgetOff: \"budget → 关闭(无上限)\",\n budgetUsage:\n '用法:/budget <usd> (收到 \"{arg}\" — 必须是正数,例如 /budget 5 或 /budget 12.50)',\n budgetExhausted:\n \"▲ budget → ${cap} 但已花费 ${spent}。下一轮将被拒绝 — 提高上限以继续,或结束会话。\",\n budgetSet:\n \"budget → ${cap} (迄今:${spent} · 80% 时警告,100% 时拒绝下一轮 · /budget off 清除)\",\n },\n permissions: {\n mutateCodeOnly:\n \"/permissions add / remove / clear 仅在 `reasonix code` 中可用 — 它们编辑项目范围的允许列表(`~/.reasonix/config.json` projects[<root>].shellAllowed)。\",\n addUsage:\n '用法:/permissions add <prefix> (多 token 可用:/permissions add \"git push origin\")',\n addAlready: \"▸ 已允许:{prefix}\",\n addBuiltin: \"▸ `{prefix}` 已在内置允许列表中 — 无需项目条目。(内置条目始终开启。)\",\n addInfo: \"▸ 已添加:{prefix}\\n → 在此项目中,下次 `{prefix}` 调用将无需提示。\",\n removeUsage:\n \"用法:/permissions remove <prefix-or-index> (例如 /permissions remove 3,或 /permissions remove npm)\",\n removeEmpty: \"▸ 没有项目允许列表条目可移除。\",\n removeIndexOob: \"▸ 索引超出范围:{idx}(项目列表有 {count} 个条目)\",\n removeNothing: \"▸ 无内容可移除。\",\n removeBuiltin:\n \"▸ `{prefix}` 在内置允许列表中(只读)。内置条目无法在运行时移除 — 它们已编译到二进制文件中。\",\n removeInfo: \"▸ 已移除:{prefix}\",\n removeNotFound: \"▸ 无此项目条目:{prefix} (尝试 /permissions list 查看已存储的内容)\",\n clearAlready: \"▸ 项目允许列表已为空。\",\n clearConfirm:\n \"即将丢弃 {root} 的 {count} 个项目允许列表条目。重新运行并附带 'confirm' 一词以继续:/permissions clear confirm\",\n clearedNone: \"▸ 项目允许列表已为空 — 无变化。\",\n cleared: \"▸ 已清除 {count} 个项目允许列表条目。\",\n usage:\n '用法:/permissions [list] 显示当前状态\\n /permissions add <prefix> 持久化(例如 \"npm run build\")\\n /permissions remove <prefix-or-N> 删除一个条目\\n /permissions clear confirm 清除所有项目条目',\n modeYolo:\n \"▸ 编辑模式:YOLO — 每个 shell 命令自动运行,允许列表被绕过。/mode review 重新启用提示。\",\n modeAuto:\n \"▸ 编辑模式:auto — 编辑自动应用,shell 仍受允许列表限制(或非允许列表的 ShellConfirm 提示)。\",\n modeReview: \"▸ 编辑模式:review — 编辑和非允许列表的 shell 命令在运行前都会询问。\",\n projectHeader: \"项目允许列表({count})— {root}\",\n projectNone1: ' (无 — 在 ShellConfirm 提示中选择 \"always allow\" 添加一个,',\n projectNone2: \" 或直接 `/permissions add <prefix>`。)\",\n projectNoRoot: \"项目允许列表 — (无项目根目录;聊天模式仅显示内置条目)\",\n builtinHeader: \"内置允许列表({count})— 只读,已编译\",\n subcommands:\n \"子命令:/permissions add <prefix> · /permissions remove <prefix-or-N> · /permissions clear confirm\",\n },\n dashboard: {\n notAvailable: \"/dashboard 在此上下文中不可用(无 startDashboard 回调)。\",\n stopNoCallback: \"/dashboard stop:无停止回调。\",\n notRunning: \"▸ 仪表板未运行。\",\n stopping: \"▸ 仪表板正在停止…\",\n alreadyRunning: \"▸ 仪表板已在运行:\",\n alreadyRunningHint: \"在任何浏览器中打开它。输入 `/dashboard stop` 关闭。\",\n ready: \"▸ 仪表板就绪:\",\n readyHint: \"仅 127.0.0.1 · token 保护。输入 `/dashboard stop` 关闭。\",\n failed: \"▸ 仪表板启动失败:{reason}\",\n starting: \"▸ 正在启动仪表板服务器…\",\n },\n observability: {\n contextInfo: \"上下文:~{total} / {max}({pct}%)· 系统 {sys} · 工具 {tools} · 日志 {log}\",\n compactStarting: \"▸ 正在折叠旧轮次为摘要…\",\n compactNoop: \"▸ 无需折叠 — 日志已足够小,或最近轮次本身已超过预算。\",\n compactDone: \"▸ 已折叠 {before} 条消息 → {after}(摘要 {chars} 字符)。继续。\",\n compactFailed: \"▸ 折叠失败:{reason}\",\n costNoTurn: \"尚无轮次 — `/cost` 显示最近一轮的 token + 花费明细。\",\n costNeedsTui: \"/cost 需要 TUI 上下文(postUsage 已连接)。\",\n costNoPricing: '▸ /cost:模型 \"{model}\" 无定价表。请在 telemetry/stats.ts 中添加。',\n costEstimate:\n \"▸ /cost 估算 · {model} · {prompt} prompt tokens(系统 {sys} + 工具 {tools} + 日志 {log} + 消息 {msg})\",\n costWorstCase:\n \" 最坏情况(完全未命中):{input} 输入 + ~{output} 输出({avg} 平均)≈ {total}\",\n costLikely: \" 可能({pct}% 会话缓存命中):{input} 输入 + ~{output} 输出 ≈ {total}\",\n costLikelyCold: \" 可能:在缓存填充前与最坏情况相同(无已完成的轮次)\",\n statusModel: \" 模型 {model}\",\n statusFlags: \" 标志 stream={stream} · effort={effort}\",\n statusCtx: \" 上下文 {bar} {used}/{max}({pct}%)\",\n statusCtxNone: \" 上下文 尚无轮次\",\n statusCost: \" 成本 ${cost} · 缓存 {bar} {pct}% · 轮次 {turns}\",\n statusCostCold: \" 成本 ${cost} · 轮次 {turns}(缓存预热中)\",\n statusBudget: \" 预算 ${spent} / ${cap}({pct}%){tag}\",\n statusSession: ' 会话 \"{name}\" · 日志中 {count} 条消息(恢复了 {resumed} 条)',\n statusSessionEphemeral: \" 会话 (临时 — 无持久化)\",\n statusWorkspace: \" 工作区 {path} · 启动时锁定(用 --dir <path> 重新启动以切换)\",\n statusMcp: \" MCP {servers} 个服务器,注册表中 {tools} 个工具\",\n statusEdits: \" 编辑 {count} 个待处理(/apply 提交,/discard 丢弃)\",\n statusPlan: \" 计划 开启 — 写入受限(submit_plan + 审批)\",\n statusModeYolo:\n \" 模式 YOLO — 编辑 + shell 自动运行,无提示(/undo 仍可回滚 · Shift+Tab 切换)\",\n statusModeAuto: \" 模式 AUTO — 编辑立即应用(5 秒内按 u 撤消 · Shift+Tab 切换)\",\n statusModeReview: \" 模式 review — 编辑排队等待 /apply 或 y(Shift+Tab 切换)\",\n statusDash: \" 仪表板 {url}(在浏览器中打开 · /dashboard stop)\",\n },\n plans: {\n noSession: \"未附加会话 — `/plans` 是按会话的。在项目中运行 `reasonix code` 以获取会话。\",\n activePlan: \"▸ 活跃计划{label} — {done}/{total} 步骤已完成 · 最后触及 {when}\",\n activeNone: \"▸ 活跃计划:(无)\",\n noArchives: \"此会话尚无归档计划 — 当每个步骤完成时自动归档\",\n archivedHeader: \"已归档({count}):\",\n replayNoSession:\n \"未附加会话 — `/replay` 是按会话的。在项目中运行 `reasonix code` 以获取会话。\",\n replayNoArchives:\n \"此会话尚无归档计划 — `/replay` 在计划完成后启用(每个步骤完成时自动归档)。\",\n replayInvalidIndex:\n \"无效索引 — `/replay` 接受 1..{max}(最新 = 1)。使用 `/plans` 查看列表。\",\n archivedRow: \" ✓ {when} {total}步 · {completion} {label}\",\n completionComplete: \"已完成\",\n stopAborted: \"▸ 计划已停止 — 模型已中止;输入后续内容继续,或开始新任务。\",\n },\n jobs: {\n codeOnly: \"/jobs 仅在 `reasonix code` 中可用。\",\n killCodeOnly: \"/kill 仅在 `reasonix code` 中可用。\",\n logsCodeOnly: \"/logs 仅在 `reasonix code` 中可用。\",\n empty:\n \"◈ 作业 · 0 运行中 · 共 0 个\\n (run_background 生成一个 — 开发服务器、监视器、长时间运行的脚本)\",\n header: \"◈ 作业 · {running} 运行中 · 共 {total} 个\",\n footer: \" /logs <id> 跟踪 · /kill <id> SIGTERM → SIGKILL\",\n killUsage: \"用法:/kill <id> (见 /jobs 获取 ID)\",\n killNotFound: \"作业 {id}:未找到\",\n killAlreadyExited: \"作业 {id} 已退出({code})\",\n killStopping:\n \"▸ 正在停止作业 {id}(树终止:SIGTERM → 2 秒宽限期后 SIGKILL;Windows:taskkill /T /F)\",\n killStatus: \"▸ 作业 {id} {status}\",\n killStillAlive: \"SIGKILL 后仍存活 (!) — 请将此作为 bug 报告\",\n logsUsage: \"用法:/logs <id> [lines] (默认最后 80 行)\",\n logsNotFound: \"作业 {id}:未找到\",\n logsStatus: \"[作业 {id} · {status}]\\n$ {command}\",\n logsRunning: \"运行中 · pid {pid}\",\n logsExited: \"已退出 {code}\",\n logsFailed: \"失败({reason})\",\n logsStopped: \"已停止\",\n },\n memory: {\n disabled:\n \"记忆已禁用(环境变量 REASONIX_MEMORY=off)。取消设置该变量以重新启用 — 此期间不会固定任何 REASONIX.md 或 ~/.reasonix/memory 内容。\",\n noRoot:\n \"此会话无工作目录 — `/memory` 需要一个根目录来解析 REASONIX.md。(在测试环境中运行?)\",\n listEmpty:\n \"尚无用户记忆。模型可以调用 `remember` 保存一个,或您可以在 ~/.reasonix/memory/global/ 或项目子目录中手动创建文件。\",\n listHeader: \"用户记忆({count}):\",\n listFooter: \"查看正文:/memory show <name> 删除:/memory forget <name>\",\n showUsage: \"用法:/memory show <name> 或 /memory show <scope>/<name>\",\n showNotFound: \"未找到记忆:{target}\",\n showFailed: \"显示失败:{reason}\",\n forgetUsage: \"用法:/memory forget <name> 或 /memory forget <scope>/<name>\",\n forgetNotFound: \"未找到记忆:{target}\",\n forgetInfo: \"▸ 已遗忘 {scope}/{name}。下次 /new 或启动时将不可见。\",\n forgetFailed: \"无法遗忘 {scope}/{name}(已消失?)\",\n forgetError: \"遗忘失败:{reason}\",\n clearUsage: \"用法:/memory clear <global|project> confirm\",\n clearConfirm:\n \"即将删除 scope={scope} 中的每个记忆。重新运行并附带 'confirm' 一词以继续:/memory clear {scope} confirm\",\n cleared: \"▸ 已清除 scope={scope} — 删除了 {count} 个记忆文件。\",\n noMemory: \"在 {root} 中未固定记忆。\",\n layers: \"可用的三个层级:\",\n layerProject: \" 1. {file} — 可提交的团队记忆(在仓库中)。\",\n layerGlobal: \" 2. ~/.reasonix/memory/global/ — 您的跨项目私有记忆。\",\n layerProjectHash: \" 3. ~/.reasonix/memory/<project-hash>/ — 此项目的私有记忆。\",\n askModel: \"让模型 `remember` 某些内容,或直接手编辑文件。\",\n changesNote: \"更改在下次 /new 或启动时生效 — 系统提示词每会话哈希一次以保持前缀缓存热度。\",\n subcommands:\n \"子命令:/memory list | /memory show <name> | /memory forget <name> | /memory clear <scope> confirm\",\n changesNoteShort:\n \"更改在下次 /new 或启动时生效。子命令:/memory list | show | forget | clear\",\n },\n mcp: {\n noServers:\n '未附加 MCP 服务器。运行 `reasonix setup` 选择一些,或使用 --mcp \"<spec>\" 启动。`reasonix mcp list` 显示目录。',\n toolsLabel: \" 工具 {count}\",\n resourcesHint: \"`/resource` 浏览+读取\",\n promptsHint: \"`/prompt` 浏览+获取\",\n awarenessOnly: \"聊天模式目前消耗工具;资源+提示在此展示供了解。\",\n catalogHint: \"完整目录:`reasonix mcp list` · 深度诊断:`reasonix mcp inspect <spec>`。\",\n fallbackServers: \"MCP 服务器({count}):\",\n fallbackTools: \"注册表中的工具({count}):\",\n fallbackChange: \"要更改此设置,请退出并运行 `reasonix setup`。\",\n usageDisableEnable:\n \"用法:/mcp {action} <name> · 从 /mcp 列表中挑一个名字(匿名服务器无法按名切换)。\",\n usageReconnect: \"用法:/mcp reconnect <name> · 从 /mcp 列表中挑一个名字。\",\n unknownServer: '未知 MCP 服务器 \"{name}\"。已知:{list}。',\n noneList: \"(无)\",\n reconnectNoTui: \"/mcp reconnect 需要交互式 TUI(postInfo 未连接)。\",\n },\n init: {\n codeOnly:\n \"/init 仅在代码模式下工作(需要文件系统工具)。\\n运行 `reasonix code [path]` 启动一个以您要初始化的项目为根的会话,\\n然后运行 /init。\",\n exists: \"▸ REASONIX.md 已存在于 {path}\",\n existsForce: \" /init force 从头重新生成(覆盖)\",\n existsEdit: \" 或手动编辑 — 它只是 markdown。当前文件已\",\n existsPinned: \" 固定到每次启动的系统提示词中。\",\n info: \"▸ /init — 模型将扫描项目并合成 REASONIX.md。\\n 结果将作为待处理的编辑;使用 /apply 或 /walk 审查。\",\n },\n webSearchEngine: {\n currentEngine: \"当前网页搜索引擎:{engine}\",\n endpoint: \"SearXNG 端点:{url}\",\n usageHeader: \"用法:\",\n usageMojeek: \" /search-engine mojeek 使用 Mojeek(默认,无外部依赖)\",\n usageSearxng: \" /search-engine searxng 使用 SearXNG 默认端点\",\n usageSearxngUrl: \" /search-engine searxng <url> 使用 SearXNG 自定义端点\",\n alias: \"别名:/se\",\n searxngInfo: \"SearXNG 是一个自托管的元搜索引擎(https://github.com/searxng/searxng)。\",\n searxngInstall: \"安装命令: docker run -d -p 8080:8080 searxng/searxng\",\n switched: '已切换网页搜索引擎为 \"{engine}\"。{note}',\n switchedSearxngNote: \" 请确保 SearXNG 在 {endpoint} 运行。\",\n confirmed: '✓ 网页搜索引擎已设为 \"{engine}\"{detail}。下一轮模型调用将生效。',\n confirmedDetail: \"({endpoint})\",\n },\n skill: {\n listEmpty: \"未找到技能。Reasonix 从以下位置读取技能:\",\n listProjectScope:\n \" · <project>/.reasonix/skills/<name>/SKILL.md (或 <name>.md) — 项目范围\",\n listGlobalScope: \" · ~/.reasonix/skills/<name>/SKILL.md (或 <name>.md) — 全局范围\",\n listProjectOnly: \" (项目范围仅在 `reasonix code` 中活跃)\",\n listFrontmatter: \"每个文件的 frontmatter 至少需要 `name` 和 `description`。\",\n listInvoke: \"使用 `/skill <name> [args]` 调用技能,或让模型调用 `run_skill`。\",\n listHeader: \"用户技能({count}):\",\n listFooter: \"查看:/skill show <name> 运行:/skill <name> [args] 新建:/skill new <name>\",\n listEmptyNewHint:\n \"用 `/skill new <name>` 在项目范围下生成一个空白模板 — 暂无在线市场,技能需要自己写。\",\n showUsage: \"用法:/skill show <name>\",\n showNotFound: \"未找到技能:{name}\",\n runNotFound: \"未找到技能:{name} (尝试 /skill list)\",\n runInfo: \"▸ 正在运行技能:{name}{args}\",\n newUsage: \"用法:/skill new <name> [--global]\",\n newCreated: \"▸ 已创建技能:{name}\\n {path}\\n 编辑后用 `/skill {name}` 调用\",\n newError: \"▲ /skill new 失败:{reason}\",\n },\n },\n cardTitles: {\n usage: \"用量\",\n context: \"上下文\",\n search: \"搜索\",\n subagent: \"子代理\",\n reply: \"回复\",\n reasoning: \"推理中\",\n reasoningAborted: \"推理(已中止)\",\n reasoningEllipsis: \"推理中…\",\n error: \"错误\",\n },\n cardLabels: {\n prompt: \"提示\",\n reason: \"推理\",\n output: \"输出\",\n cache: \"缓存\",\n session: \"会话\",\n balance: \"余额\",\n turn: \"轮\",\n system: \"系统\",\n tools: \"工具\",\n log: \"日志\",\n input: \"输入\",\n topTools: \"Top 工具\",\n logMsgs: \"日志消息\",\n hitSingular: \"{count} 条结果 · {files} 个文件\",\n hitsPlural: \"{count} 条结果 · {files} 个文件\",\n moreHitSingular: \"⋮ +{count} 条结果\",\n moreHitsPlural: \"⋮ +{count} 条结果\",\n earlierLine: \"⋮ 前 {count} 行(使用 /tool 阅读全文)\",\n earlierLines: \"⋮ 前 {count} 行(使用 /tool 阅读全文)\",\n earlierStackLine: \"⋮ 前 {count} 行堆栈已隐藏\",\n earlierStackLines: \"⋮ 前 {count} 行堆栈已隐藏\",\n agent: \"代理 · {name}\",\n response: \"回复\",\n writing: \"输出中 …\",\n tok: \"tok\",\n pilcrow: \"¶\",\n aborted: \"已中止\",\n truncatedByEsc: \"[已被 Esc 截断]\",\n rejected: \"已拒绝\",\n exit: \"退出码 {code}\",\n bytesIn: \"{bytes} 输入\",\n elapsedSec: \"{secs}秒\",\n stackTrace: \"堆栈跟踪\",\n retries: \"次重试\",\n reasoningLabel: \"推理 · {count} ¶\",\n runningLabel: \"运行中\",\n workingLabel: \"工作中\",\n },\n};\n","import { loadLanguage, saveLanguage } from \"../config.js\";\nimport { EN } from \"./EN.js\";\nimport type { LanguageCode, TranslationSchema } from \"./types.js\";\nimport { zhCN } from \"./zh-CN.js\";\n\nconst translations: Record<LanguageCode, TranslationSchema> = {\n EN,\n \"zh-CN\": zhCN,\n};\n\n/** Map a system locale (e.g. \"zh-CN\", \"en-US\") to a supported LanguageCode, or null. */\nexport function detectSystemLanguage(\n locale: string = Intl.DateTimeFormat().resolvedOptions().locale,\n): LanguageCode | null {\n if (locale.startsWith(\"zh\")) return \"zh-CN\";\n if (locale.startsWith(\"en\")) return \"EN\";\n return null;\n}\n\nlet currentLang: LanguageCode = loadLanguage() ?? detectSystemLanguage() ?? \"EN\";\n\ntype Listener = () => void;\nconst listeners: Listener[] = [];\n\nexport function onLanguageChange(cb: Listener): () => void {\n listeners.push(cb);\n return () => {\n const i = listeners.indexOf(cb);\n if (i >= 0) listeners.splice(i, 1);\n };\n}\n\nexport function notifyLanguageChange(): void {\n for (const cb of listeners) cb();\n}\n\nexport function setLanguage(lang: LanguageCode): void {\n if (translations[lang]) {\n currentLang = lang;\n saveLanguage(lang);\n }\n}\n\n/** Set language for the current process only (no disk write). Used by tests. */\nexport function setLanguageRuntime(lang: LanguageCode): void {\n if (translations[lang]) {\n currentLang = lang;\n }\n}\n\nexport function getLanguage(): LanguageCode {\n return currentLang;\n}\n\nexport function getSupportedLanguages(): LanguageCode[] {\n return Object.keys(translations) as LanguageCode[];\n}\n\n/** Returns a structured (non-string) translation entry — for tables / row objects passed to TipCard etc. */\nexport function tObj<T>(path: string): T {\n const parts = path.split(\".\");\n let val: unknown = translations[currentLang] || translations.EN;\n for (const part of parts) {\n val = (val as Record<string, unknown> | undefined)?.[part];\n if (val === undefined) break;\n }\n if (val === undefined && currentLang !== \"EN\") {\n val = translations.EN;\n for (const part of parts) {\n val = (val as Record<string, unknown> | undefined)?.[part];\n if (val === undefined) break;\n }\n }\n return val as T;\n}\n\n/** Simple t() — nested keys (e.g. \"common.error\") + param replacement (e.g. \"{code}\"). */\nexport function t(path: string, params?: Record<string, string | number>): string {\n const parts = path.split(\".\");\n let val: any = translations[currentLang] || translations.EN;\n\n for (const part of parts) {\n val = val?.[part];\n if (val === undefined) break;\n }\n\n // Fallback to English if not found in current language\n if (val === undefined && currentLang !== \"EN\") {\n val = translations.EN;\n for (const part of parts) {\n val = val?.[part];\n if (val === undefined) break;\n }\n }\n\n if (typeof val !== \"string\") {\n return path;\n }\n\n if (params) {\n let result = val;\n for (const [k, v] of Object.entries(params)) {\n result = result.replace(new RegExp(`\\\\{${k}\\\\}`, \"g\"), String(v));\n }\n return result;\n }\n\n return val;\n}\n"],"mappings":"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","names":[]}
|