reasonix 0.33.2 → 0.34.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/dashboard/dist/app.js +1 -21
  2. package/dashboard/dist/app.js.map +1 -1
  3. package/dist/cli/{chat-ZMSAXE77.js → chat-TD6GR3QK.js} +14 -13
  4. package/dist/cli/chunk-2EBODRRO.js +149 -0
  5. package/dist/cli/chunk-2EBODRRO.js.map +1 -0
  6. package/dist/cli/{chunk-DULSP7JH.js → chunk-5JXXEPDM.js} +34 -1
  7. package/dist/cli/chunk-5JXXEPDM.js.map +1 -0
  8. package/dist/cli/{chunk-OW7IHE6M.js → chunk-EINEIIIW.js} +693 -364
  9. package/dist/cli/chunk-EINEIIIW.js.map +1 -0
  10. package/dist/cli/{chunk-WVJL7ZO2.js → chunk-F3ILWP2L.js} +4 -4
  11. package/dist/cli/{chunk-SDE5U32Z.js → chunk-KZHMKOJH.js} +13 -8
  12. package/dist/cli/{chunk-SDE5U32Z.js.map → chunk-KZHMKOJH.js.map} +1 -1
  13. package/dist/cli/{chunk-G7M3QWEN.js → chunk-LNTORE5K.js} +225 -132
  14. package/dist/cli/chunk-LNTORE5K.js.map +1 -0
  15. package/dist/cli/chunk-MRLXEMZ7.js +26 -0
  16. package/dist/cli/chunk-MRLXEMZ7.js.map +1 -0
  17. package/dist/cli/{chunk-WBDE4IRI.js → chunk-OERAGRJX.js} +2 -2
  18. package/dist/cli/{chunk-QGE6AF76.js → chunk-Q36KBLSU.js} +207 -8
  19. package/dist/cli/chunk-Q36KBLSU.js.map +1 -0
  20. package/dist/cli/{chunk-RZILUXUC.js → chunk-RXGEGA7K.js} +2 -2
  21. package/dist/cli/{chunk-FXGQ5NHE.js → chunk-SA4UGZPG.js} +21 -1
  22. package/dist/cli/chunk-SA4UGZPG.js.map +1 -0
  23. package/dist/cli/{chunk-J5VLP23S.js → chunk-SW3CCXEV.js} +2 -2
  24. package/dist/cli/{chunk-W4LDFAZ6.js → chunk-SX6L4HZZ.js} +2 -2
  25. package/dist/cli/chunk-WUI3P4RA.js +319 -0
  26. package/dist/cli/chunk-WUI3P4RA.js.map +1 -0
  27. package/dist/cli/{code-R4TXQQEE.js → code-TGUOQBRJ.js} +15 -14
  28. package/dist/cli/{code-R4TXQQEE.js.map → code-TGUOQBRJ.js.map} +1 -1
  29. package/dist/cli/{commands-JWT2MWVH.js → commands-MEZPSEHV.js} +4 -3
  30. package/dist/cli/{commands-JWT2MWVH.js.map → commands-MEZPSEHV.js.map} +1 -1
  31. package/dist/cli/{commit-RPZBOZS2.js → commit-CE4EFTUQ.js} +3 -2
  32. package/dist/cli/{commit-RPZBOZS2.js.map → commit-CE4EFTUQ.js.map} +1 -1
  33. package/dist/cli/{doctor-V5HLCMSQ.js → doctor-YASM64X6.js} +7 -6
  34. package/dist/cli/index.js +22 -21
  35. package/dist/cli/index.js.map +1 -1
  36. package/dist/cli/{mcp-ARTNQ24O.js → mcp-LDFK5QJI.js} +3 -2
  37. package/dist/cli/{mcp-ARTNQ24O.js.map → mcp-LDFK5QJI.js.map} +1 -1
  38. package/dist/cli/{mcp-browse-HLO2ENDL.js → mcp-browse-FYHEITCM.js} +3 -2
  39. package/dist/cli/{mcp-browse-HLO2ENDL.js.map → mcp-browse-FYHEITCM.js.map} +1 -1
  40. package/dist/cli/{replay-Q43DSMG6.js → replay-JEDLU7F2.js} +8 -6
  41. package/dist/cli/{replay-Q43DSMG6.js.map → replay-JEDLU7F2.js.map} +1 -1
  42. package/dist/cli/{run-HK3FP266.js → run-NHD2RSTD.js} +7 -6
  43. package/dist/cli/{run-HK3FP266.js.map → run-NHD2RSTD.js.map} +1 -1
  44. package/dist/cli/{server-SYC3OVOP.js → server-MC4A4WAJ.js} +9 -8
  45. package/dist/cli/{server-SYC3OVOP.js.map → server-MC4A4WAJ.js.map} +1 -1
  46. package/dist/cli/{sessions-3XU2GGHX.js → sessions-ZHWJEW4L.js} +7 -6
  47. package/dist/cli/{sessions-3XU2GGHX.js.map → sessions-ZHWJEW4L.js.map} +1 -1
  48. package/dist/cli/{setup-CCJZAWTY.js → setup-DK43MT47.js} +6 -5
  49. package/dist/cli/{setup-CCJZAWTY.js.map → setup-DK43MT47.js.map} +1 -1
  50. package/dist/cli/{version-5SGI2SEE.js → version-O362UKPM.js} +7 -6
  51. package/dist/cli/{version-5SGI2SEE.js.map → version-O362UKPM.js.map} +1 -1
  52. package/dist/index.d.ts +45 -1
  53. package/dist/index.js +569 -27
  54. package/dist/index.js.map +1 -1
  55. package/package.json +1 -1
  56. package/dist/cli/chunk-63KAV5DX.js +0 -106
  57. package/dist/cli/chunk-63KAV5DX.js.map +0 -1
  58. package/dist/cli/chunk-DULSP7JH.js.map +0 -1
  59. package/dist/cli/chunk-FXGQ5NHE.js.map +0 -1
  60. package/dist/cli/chunk-G7M3QWEN.js.map +0 -1
  61. package/dist/cli/chunk-OW7IHE6M.js.map +0 -1
  62. package/dist/cli/chunk-QGE6AF76.js.map +0 -1
  63. package/dist/cli/chunk-ZPTSJGX5.js +0 -88
  64. package/dist/cli/chunk-ZPTSJGX5.js.map +0 -1
  65. /package/dist/cli/{chat-ZMSAXE77.js.map → chat-TD6GR3QK.js.map} +0 -0
  66. /package/dist/cli/{chunk-WVJL7ZO2.js.map → chunk-F3ILWP2L.js.map} +0 -0
  67. /package/dist/cli/{chunk-WBDE4IRI.js.map → chunk-OERAGRJX.js.map} +0 -0
  68. /package/dist/cli/{chunk-RZILUXUC.js.map → chunk-RXGEGA7K.js.map} +0 -0
  69. /package/dist/cli/{chunk-J5VLP23S.js.map → chunk-SW3CCXEV.js.map} +0 -0
  70. /package/dist/cli/{chunk-W4LDFAZ6.js.map → chunk-SX6L4HZZ.js.map} +0 -0
  71. /package/dist/cli/{doctor-V5HLCMSQ.js.map → doctor-YASM64X6.js.map} +0 -0
@@ -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 \"▸ TIP: edit-gate keybindings\\n y / n accept or drop pending edits\\n Shift+Tab switch review ↔ AUTO (persisted; AUTO applies instantly)\\n u undo the last auto-applied batch (within the 5s banner)\\n Current mode is shown in the bottom status bar. Run /keys anytime for the full list.\\n (This tip shows once — suppressed after.)\",\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: \"show all keyboard shortcuts and prompt prefixes\" },\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: \"Doesn't look like a DeepSeek key. They start with 'sk-' and are 30+ chars.\",\n apiKeyPreview: \"preview: {redacted}\",\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 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 },\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: \" npm install -g reasonix@latest (direct)\",\n updateInSessionDisabled: \"in-session install is deliberately disabled — the npm 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};\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 \"▸ 提示:编辑门控快捷键\\n y / n 接受或放弃待处理的编辑\\n Shift+Tab 切换 预览 ↔ 自动 (持久化;自动模式立即应用)\\n u 撤消上次自动应用的批处理 (在 5 秒横幅内)\\n 当前模式显示在底部状态栏。随时运行 /keys 查看完整列表。\\n (此提示仅显示一次 — 之后将隐藏。)\",\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: \"这看起来不像 DeepSeek 的 key。它们以 'sk-' 开头,30 字符以上。\",\n apiKeyPreview: \"预览:{redacted}\",\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 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 },\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: \" npm install -g reasonix@latest (直接安装)\",\n updateInSessionDisabled: \"会话内安装被刻意禁用 — npm spawn 会\",\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};\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/** 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":[]}
@@ -1,88 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- // src/cli/ui/theme.ts
4
- var GRADIENT = [
5
- "#5eead4",
6
- // teal
7
- "#67e8f9",
8
- // cyan
9
- "#7dd3fc",
10
- // sky
11
- "#93c5fd",
12
- // blue
13
- "#a5b4fc",
14
- // indigo
15
- "#c4b5fd",
16
- // violet
17
- "#d8b4fe",
18
- // purple
19
- "#f0abfc"
20
- // fuchsia
21
- ];
22
- var COLOR = {
23
- primary: "#67e8f9",
24
- // cyan-300
25
- accent: "#c4b5fd",
26
- // violet-300
27
- brand: "#5eead4",
28
- // teal-300
29
- user: "#67e8f9",
30
- // user message glyph + bar
31
- assistant: "#86efac",
32
- // green-300, assistant glyph + bar
33
- tool: "#fcd34d",
34
- // amber-300, tool ok pill bg
35
- toolErr: "#fda4af",
36
- // rose-300, tool err pill bg
37
- info: "#94a3b8",
38
- // slate-400, info / dim
39
- warn: "#fbbf24",
40
- // amber-400
41
- err: "#f87171",
42
- // red-400
43
- ok: "#4ade80"
44
- // green-400
45
- };
46
- var GLYPH = {
47
- brand: "\u25C8",
48
- user: "\u25C7",
49
- assistant: "\u25C6",
50
- toolOk: "\u25A3",
51
- toolErr: "\u25A5",
52
- warn: "\u25B2",
53
- err: "\u2726",
54
- arrow: "\u203A",
55
- bullet: "\xB7",
56
- bar: "\u258E",
57
- thinBar: "\u258F",
58
- block: "\u2588",
59
- shade1: "\u2591",
60
- shade2: "\u2592",
61
- shade3: "\u2593",
62
- // Status icons — checkbox-style states used across plan steps,
63
- // job rows, history entries. Pair with the COLOR semantics:
64
- // done→ok, cur→primary, pending→info-faint, fail→err.
65
- done: "\u2713",
66
- cur: "\u25B8",
67
- pending: "\u25CB",
68
- fail: "\u2717",
69
- running: "\u25CF",
70
- // Tree-drawing chars for hierarchical lists (plan steps, sub-loops,
71
- // hook attachments). 1 cell each; render fine in every monospace
72
- // font we've tested.
73
- branch: "\u2523",
74
- branchEnd: "\u2517",
75
- branchStub: "\u2503",
76
- rule: "\u2500",
77
- // Spinner frames — 4-step rotation. Cycle every 200ms via setInterval
78
- // (Ink's useEffect setState pattern). Equivalent to ink-spinner but
79
- // with our own cadence + character set.
80
- spinFrames: ["\u25D0", "\u25D3", "\u25D1", "\u25D2"]
81
- };
82
-
83
- export {
84
- GRADIENT,
85
- COLOR,
86
- GLYPH
87
- };
88
- //# sourceMappingURL=chunk-ZPTSJGX5.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/cli/ui/theme.ts"],"sourcesContent":["/** Brand gradient — REASONIX wordmark sweep, reused for accents / progress / dividers. */\nexport const GRADIENT: ReadonlyArray<string> = [\n \"#5eead4\", // teal\n \"#67e8f9\", // cyan\n \"#7dd3fc\", // sky\n \"#93c5fd\", // blue\n \"#a5b4fc\", // indigo\n \"#c4b5fd\", // violet\n \"#d8b4fe\", // purple\n \"#f0abfc\", // fuchsia\n];\n\n/** Tailwind 400/500 row — keeps tone consistent with GRADIENT. */\nexport const COLOR = {\n primary: \"#67e8f9\", // cyan-300\n accent: \"#c4b5fd\", // violet-300\n brand: \"#5eead4\", // teal-300\n\n user: \"#67e8f9\", // user message glyph + bar\n assistant: \"#86efac\", // green-300, assistant glyph + bar\n tool: \"#fcd34d\", // amber-300, tool ok pill bg\n toolErr: \"#fda4af\", // rose-300, tool err pill bg\n info: \"#94a3b8\", // slate-400, info / dim\n warn: \"#fbbf24\", // amber-400\n err: \"#f87171\", // red-400\n ok: \"#4ade80\", // green-400\n} as const;\n\nexport const GLYPH = {\n brand: \"◈\",\n user: \"◇\",\n assistant: \"◆\",\n toolOk: \"▣\",\n toolErr: \"▥\",\n warn: \"▲\",\n err: \"✦\",\n arrow: \"›\",\n bullet: \"·\",\n bar: \"▎\",\n thinBar: \"▏\",\n block: \"█\",\n shade1: \"░\",\n shade2: \"▒\",\n shade3: \"▓\",\n\n // Status icons — checkbox-style states used across plan steps,\n // job rows, history entries. Pair with the COLOR semantics:\n // done→ok, cur→primary, pending→info-faint, fail→err.\n done: \"✓\",\n cur: \"▸\",\n pending: \"○\",\n fail: \"✗\",\n running: \"●\",\n\n // Tree-drawing chars for hierarchical lists (plan steps, sub-loops,\n // hook attachments). 1 cell each; render fine in every monospace\n // font we've tested.\n branch: \"┣\",\n branchEnd: \"┗\",\n branchStub: \"┃\",\n rule: \"─\",\n\n // Spinner frames — 4-step rotation. Cycle every 200ms via setInterval\n // (Ink's useEffect setState pattern). Equivalent to ink-spinner but\n // with our own cadence + character set.\n spinFrames: [\"◐\", \"◓\", \"◑\", \"◒\"] as readonly string[],\n} as const;\n\n/** Ordering survives 256-/16-color quantization — canvas always darker than sel. */\nexport const SURFACE = {\n canvas: \"#070a10\",\n shell: \"#0b1019\",\n card: \"#101721\",\n elev: \"#161f2c\",\n sel: \"#1a2433\",\n line: \"#1c2433\",\n lineSoft: \"#141b27\",\n} as const;\n\nexport const FG = {\n strong: \"#e6edf6\",\n default: \"#cbd5e1\",\n dim: \"#94a3b8\",\n faint: \"#64748b\",\n ghost: \"#475569\",\n} as const;\n\nexport function gradientCells(\n width: number,\n glyph: string = GLYPH.block,\n): Array<{ ch: string; color: string }> {\n const cells: Array<{ ch: string; color: string }> = [];\n if (width <= 0) return cells;\n const last = GRADIENT.length - 1;\n for (let i = 0; i < width; i++) {\n const t = width === 1 ? 0 : (i * last) / (width - 1);\n const lo = Math.floor(t);\n const hi = Math.min(last, lo + 1);\n // Pick the closer of the two anchor colors for this cell. Linear\n // hex blending could be fancier but the discrete steps already\n // read as a smooth fade at any reasonable width.\n const color = t - lo < 0.5 ? GRADIENT[lo]! : GRADIENT[hi]!;\n cells.push({ ch: glyph, color });\n }\n return cells;\n}\n"],"mappings":";;;AACO,IAAM,WAAkC;AAAA,EAC7C;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AACF;AAGO,IAAM,QAAQ;AAAA,EACnB,SAAS;AAAA;AAAA,EACT,QAAQ;AAAA;AAAA,EACR,OAAO;AAAA;AAAA,EAEP,MAAM;AAAA;AAAA,EACN,WAAW;AAAA;AAAA,EACX,MAAM;AAAA;AAAA,EACN,SAAS;AAAA;AAAA,EACT,MAAM;AAAA;AAAA,EACN,MAAM;AAAA;AAAA,EACN,KAAK;AAAA;AAAA,EACL,IAAI;AAAA;AACN;AAEO,IAAM,QAAQ;AAAA,EACnB,OAAO;AAAA,EACP,MAAM;AAAA,EACN,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,MAAM;AAAA,EACN,KAAK;AAAA,EACL,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,SAAS;AAAA,EACT,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA;AAAA;AAAA;AAAA,EAKR,MAAM;AAAA,EACN,KAAK;AAAA,EACL,SAAS;AAAA,EACT,MAAM;AAAA,EACN,SAAS;AAAA;AAAA;AAAA;AAAA,EAKT,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,MAAM;AAAA;AAAA;AAAA;AAAA,EAKN,YAAY,CAAC,UAAK,UAAK,UAAK,QAAG;AACjC;","names":[]}