reasonix 0.46.1 → 0.47.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/README.md +62 -13
  2. package/README.zh-CN.md +52 -10
  3. package/dashboard/dist/app.js +217 -60
  4. package/dashboard/dist/app.js.map +1 -1
  5. package/dist/cli/{acp-LKJU5DZX.js → acp-QK3DMC53.js} +22 -22
  6. package/dist/cli/chat-VV5UWY4V.js +51 -0
  7. package/dist/cli/{chunk-DGA5QYFM.js → chunk-24A7FHGJ.js} +42 -13
  8. package/dist/cli/chunk-24A7FHGJ.js.map +1 -0
  9. package/dist/cli/{chunk-K3AIFMI6.js → chunk-6J6BSUCR.js} +2 -2
  10. package/dist/cli/{chunk-C72TNHDE.js → chunk-BWYVFFKR.js} +2 -2
  11. package/dist/cli/{chunk-EAOL43HB.js → chunk-BYYVYJDX.js} +3 -3
  12. package/dist/cli/{chunk-HNXDZGC6.js → chunk-CI2PF5QX.js} +2 -2
  13. package/dist/cli/{chunk-JVQT5IYP.js → chunk-COWPEX54.js} +19 -9
  14. package/dist/cli/chunk-COWPEX54.js.map +1 -0
  15. package/dist/cli/{chunk-IYQ325V7.js → chunk-E5WCLUIU.js} +2 -2
  16. package/dist/cli/{chunk-YRLC2EDF.js → chunk-EQATK2L2.js} +2 -2
  17. package/dist/cli/{chunk-R2ASNSEO.js → chunk-FDKOUJKZ.js} +8 -8
  18. package/dist/cli/{chunk-TEUDEGX2.js → chunk-FY4S7TJZ.js} +19 -5
  19. package/dist/cli/chunk-FY4S7TJZ.js.map +1 -0
  20. package/dist/cli/{chunk-JVFEJAJX.js → chunk-GDKB2PPK.js} +2 -2
  21. package/dist/cli/{chunk-WQ6ZRDQM.js → chunk-HIYTRCSW.js} +16 -12
  22. package/dist/cli/chunk-HIYTRCSW.js.map +1 -0
  23. package/dist/cli/{chunk-ZOQHVQON.js → chunk-ICAFSZHS.js} +307 -30
  24. package/dist/cli/chunk-ICAFSZHS.js.map +1 -0
  25. package/dist/cli/{chunk-SPXN5JIT.js → chunk-ICSYGIPN.js} +1386 -1021
  26. package/dist/cli/chunk-ICSYGIPN.js.map +1 -0
  27. package/dist/cli/{chunk-XPAUNFOL.js → chunk-K6GUKSXH.js} +3 -2
  28. package/dist/cli/chunk-K6GUKSXH.js.map +1 -0
  29. package/dist/cli/{chunk-6VANO7KB.js → chunk-KDRUEXII.js} +147 -20
  30. package/dist/cli/chunk-KDRUEXII.js.map +1 -0
  31. package/dist/cli/{chunk-NCBP5D6E.js → chunk-LBLR4CUZ.js} +2 -2
  32. package/dist/cli/{chunk-2425HK6U.js → chunk-LGEKVMMV.js} +7 -2
  33. package/dist/cli/{chunk-2425HK6U.js.map → chunk-LGEKVMMV.js.map} +1 -1
  34. package/dist/cli/{chunk-7SGGXNB2.js → chunk-OJVITDGB.js} +2 -2
  35. package/dist/cli/{chunk-SE7C5ZSI.js → chunk-QVDWH2A2.js} +3 -3
  36. package/dist/cli/{chunk-WRONKNIH.js → chunk-QVUFWDD2.js} +2 -2
  37. package/dist/cli/{chunk-3AAG2CUT.js → chunk-R6GQKKBW.js} +2 -2
  38. package/dist/cli/{chunk-E7TAHQ4A.js → chunk-RRXUIPWG.js} +19 -18
  39. package/dist/cli/chunk-RRXUIPWG.js.map +1 -0
  40. package/dist/cli/{chunk-CXVWUPA3.js → chunk-TKVXTQ3T.js} +26 -26
  41. package/dist/cli/chunk-TKVXTQ3T.js.map +1 -0
  42. package/dist/cli/{chunk-DHRVZJ2D.js → chunk-UDVFBEXC.js} +3 -3
  43. package/dist/cli/{chunk-7YW6TPXK.js → chunk-VC2CQA5D.js} +9 -9
  44. package/dist/cli/{chunk-M4E5JK6S.js → chunk-VJMBISEI.js} +2 -2
  45. package/dist/cli/{chunk-TDSBASOF.js → chunk-VKYSZKH2.js} +2 -2
  46. package/dist/cli/{chunk-7LOJS3LV.js → chunk-VMUUFWFF.js} +2 -2
  47. package/dist/cli/{chunk-MIIZJD5O.js → chunk-VNQGCA3Q.js} +2 -2
  48. package/dist/cli/{chunk-2AASOSD5.js → chunk-WF7TPVZM.js} +2 -2
  49. package/dist/cli/{chunk-JLQDNLZF.js → chunk-YDPLF7XR.js} +26 -14
  50. package/dist/cli/chunk-YDPLF7XR.js.map +1 -0
  51. package/dist/cli/{code-2JIHL5M2.js → code-C24TUAE5.js} +39 -34
  52. package/dist/cli/code-C24TUAE5.js.map +1 -0
  53. package/dist/cli/{commands-OPT5AJNH.js → commands-RR3GIYOK.js} +4 -4
  54. package/dist/cli/{commit-KA37H6GM.js → commit-FSHPIINM.js} +3 -3
  55. package/dist/cli/{desktop-5ONTRU3C.js → desktop-7NCHPEFB.js} +263 -36
  56. package/dist/cli/desktop-7NCHPEFB.js.map +1 -0
  57. package/dist/cli/{diff-SOIA7AKH.js → diff-RAAHHLHV.js} +8 -8
  58. package/dist/cli/{doctor-RCUP4XRV.js → doctor-PKVQIXRT.js} +9 -9
  59. package/dist/cli/{events-6KHITNX4.js → events-VRYXOSKI.js} +3 -3
  60. package/dist/cli/index.js +81 -40
  61. package/dist/cli/index.js.map +1 -1
  62. package/dist/cli/{mcp-JP5OWD6R.js → mcp-CRJ26PP4.js} +2 -2
  63. package/dist/cli/{mcp-browse-ONCJJPJN.js → mcp-browse-QPAOWZOP.js} +2 -2
  64. package/dist/cli/{mcp-inspect-TPLHW5JA.js → mcp-inspect-CVCLABRS.js} +4 -4
  65. package/dist/cli/{prompt-RJDNCQAP.js → prompt-SKYXERSI.js} +4 -4
  66. package/dist/cli/{prune-sessions-MKEATRVL.js → prune-sessions-SEWX7GP6.js} +2 -2
  67. package/dist/cli/{replay-4NILJG4U.js → replay-KPDW2ZMJ.js} +9 -9
  68. package/dist/cli/{run-WFGXB4SB.js → run-WIKDIXTG.js} +17 -17
  69. package/dist/cli/{server-5VFQP3PV.js → server-P6V2G3P6.js} +82 -34
  70. package/dist/cli/server-P6V2G3P6.js.map +1 -0
  71. package/dist/cli/{sessions-5XDJDALO.js → sessions-2NULRMSA.js} +15 -15
  72. package/dist/cli/{setup-F6XSWLRA.js → setup-Y5WDBQFL.js} +6 -6
  73. package/dist/cli/{stats-ALHBZICE.js → stats-T7BL2YOR.js} +6 -6
  74. package/dist/cli/{version-JVRAHBMM.js → version-3KWDNWLN.js} +15 -15
  75. package/dist/index.d.ts +31 -10
  76. package/dist/index.js +505 -66
  77. package/dist/index.js.map +1 -1
  78. package/package.json +1 -1
  79. package/dist/cli/chat-W7LAWEN6.js +0 -51
  80. package/dist/cli/chunk-6VANO7KB.js.map +0 -1
  81. package/dist/cli/chunk-CXVWUPA3.js.map +0 -1
  82. package/dist/cli/chunk-DGA5QYFM.js.map +0 -1
  83. package/dist/cli/chunk-E7TAHQ4A.js.map +0 -1
  84. package/dist/cli/chunk-JLQDNLZF.js.map +0 -1
  85. package/dist/cli/chunk-JVQT5IYP.js.map +0 -1
  86. package/dist/cli/chunk-SPXN5JIT.js.map +0 -1
  87. package/dist/cli/chunk-TEUDEGX2.js.map +0 -1
  88. package/dist/cli/chunk-WQ6ZRDQM.js.map +0 -1
  89. package/dist/cli/chunk-XPAUNFOL.js.map +0 -1
  90. package/dist/cli/chunk-ZOQHVQON.js.map +0 -1
  91. package/dist/cli/code-2JIHL5M2.js.map +0 -1
  92. package/dist/cli/desktop-5ONTRU3C.js.map +0 -1
  93. package/dist/cli/server-5VFQP3PV.js.map +0 -1
  94. /package/dist/cli/{acp-LKJU5DZX.js.map → acp-QK3DMC53.js.map} +0 -0
  95. /package/dist/cli/{chat-W7LAWEN6.js.map → chat-VV5UWY4V.js.map} +0 -0
  96. /package/dist/cli/{chunk-K3AIFMI6.js.map → chunk-6J6BSUCR.js.map} +0 -0
  97. /package/dist/cli/{chunk-C72TNHDE.js.map → chunk-BWYVFFKR.js.map} +0 -0
  98. /package/dist/cli/{chunk-EAOL43HB.js.map → chunk-BYYVYJDX.js.map} +0 -0
  99. /package/dist/cli/{chunk-HNXDZGC6.js.map → chunk-CI2PF5QX.js.map} +0 -0
  100. /package/dist/cli/{chunk-IYQ325V7.js.map → chunk-E5WCLUIU.js.map} +0 -0
  101. /package/dist/cli/{chunk-YRLC2EDF.js.map → chunk-EQATK2L2.js.map} +0 -0
  102. /package/dist/cli/{chunk-R2ASNSEO.js.map → chunk-FDKOUJKZ.js.map} +0 -0
  103. /package/dist/cli/{chunk-JVFEJAJX.js.map → chunk-GDKB2PPK.js.map} +0 -0
  104. /package/dist/cli/{chunk-NCBP5D6E.js.map → chunk-LBLR4CUZ.js.map} +0 -0
  105. /package/dist/cli/{chunk-7SGGXNB2.js.map → chunk-OJVITDGB.js.map} +0 -0
  106. /package/dist/cli/{chunk-SE7C5ZSI.js.map → chunk-QVDWH2A2.js.map} +0 -0
  107. /package/dist/cli/{chunk-WRONKNIH.js.map → chunk-QVUFWDD2.js.map} +0 -0
  108. /package/dist/cli/{chunk-3AAG2CUT.js.map → chunk-R6GQKKBW.js.map} +0 -0
  109. /package/dist/cli/{chunk-DHRVZJ2D.js.map → chunk-UDVFBEXC.js.map} +0 -0
  110. /package/dist/cli/{chunk-7YW6TPXK.js.map → chunk-VC2CQA5D.js.map} +0 -0
  111. /package/dist/cli/{chunk-M4E5JK6S.js.map → chunk-VJMBISEI.js.map} +0 -0
  112. /package/dist/cli/{chunk-TDSBASOF.js.map → chunk-VKYSZKH2.js.map} +0 -0
  113. /package/dist/cli/{chunk-7LOJS3LV.js.map → chunk-VMUUFWFF.js.map} +0 -0
  114. /package/dist/cli/{chunk-MIIZJD5O.js.map → chunk-VNQGCA3Q.js.map} +0 -0
  115. /package/dist/cli/{chunk-2AASOSD5.js.map → chunk-WF7TPVZM.js.map} +0 -0
  116. /package/dist/cli/{commands-OPT5AJNH.js.map → commands-RR3GIYOK.js.map} +0 -0
  117. /package/dist/cli/{commit-KA37H6GM.js.map → commit-FSHPIINM.js.map} +0 -0
  118. /package/dist/cli/{diff-SOIA7AKH.js.map → diff-RAAHHLHV.js.map} +0 -0
  119. /package/dist/cli/{doctor-RCUP4XRV.js.map → doctor-PKVQIXRT.js.map} +0 -0
  120. /package/dist/cli/{events-6KHITNX4.js.map → events-VRYXOSKI.js.map} +0 -0
  121. /package/dist/cli/{mcp-JP5OWD6R.js.map → mcp-CRJ26PP4.js.map} +0 -0
  122. /package/dist/cli/{mcp-browse-ONCJJPJN.js.map → mcp-browse-QPAOWZOP.js.map} +0 -0
  123. /package/dist/cli/{mcp-inspect-TPLHW5JA.js.map → mcp-inspect-CVCLABRS.js.map} +0 -0
  124. /package/dist/cli/{prompt-RJDNCQAP.js.map → prompt-SKYXERSI.js.map} +0 -0
  125. /package/dist/cli/{prune-sessions-MKEATRVL.js.map → prune-sessions-SEWX7GP6.js.map} +0 -0
  126. /package/dist/cli/{replay-4NILJG4U.js.map → replay-KPDW2ZMJ.js.map} +0 -0
  127. /package/dist/cli/{run-WFGXB4SB.js.map → run-WIKDIXTG.js.map} +0 -0
  128. /package/dist/cli/{sessions-5XDJDALO.js.map → sessions-2NULRMSA.js.map} +0 -0
  129. /package/dist/cli/{setup-F6XSWLRA.js.map → setup-Y5WDBQFL.js.map} +0 -0
  130. /package/dist/cli/{stats-ALHBZICE.js.map → stats-T7BL2YOR.js.map} +0 -0
  131. /package/dist/cli/{version-JVRAHBMM.js.map → version-3KWDNWLN.js.map} +0 -0
@@ -3,7 +3,7 @@ import { createRequire as __cr } from 'node:module'; if (typeof globalThis.requi
3
3
  import {
4
4
  indexCompatible,
5
5
  querySemantic
6
- } from "./chunk-JLQDNLZF.js";
6
+ } from "./chunk-YDPLF7XR.js";
7
7
 
8
8
  // src/index/semantic/tool.ts
9
9
  async function registerSemanticSearchTool(registry, opts) {
@@ -43,6 +43,7 @@ async function registerSemanticSearchTool(registry, opts) {
43
43
  apiKey: opts.apiKey,
44
44
  model: opts.model,
45
45
  extraBody: opts.extraBody,
46
+ batchSize: opts.batchSize,
46
47
  signal: ctx?.signal
47
48
  });
48
49
  if (hits === null) {
@@ -92,4 +93,4 @@ export {
92
93
  registerSemanticSearchTool,
93
94
  bootstrapSemanticSearchInCodeMode
94
95
  };
95
- //# sourceMappingURL=chunk-XPAUNFOL.js.map
96
+ //# sourceMappingURL=chunk-K6GUKSXH.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/index/semantic/tool.ts"],"sourcesContent":["import type { ToolRegistry } from \"../../tools.js\";\nimport { indexCompatible, indexExists, querySemantic } from \"./builder.js\";\nimport type { SearchHit } from \"./store.js\";\n\ntype SemanticToolOptions = {\n provider?: \"ollama\" | \"openai-compat\";\n baseUrl?: string;\n apiKey?: string;\n model?: string;\n extraBody?: Record<string, unknown>;\n timeoutMs?: number;\n batchSize?: number;\n root: string;\n defaultTopK?: number;\n defaultMinScore?: number;\n};\n\nexport async function registerSemanticSearchTool(\n registry: ToolRegistry,\n opts: SemanticToolOptions,\n): Promise<boolean> {\n if (!(await indexCompatible(opts.root, { provider: opts.provider, model: opts.model })))\n return false;\n const defaultTopK = opts.defaultTopK ?? 8;\n const defaultMinScore = opts.defaultMinScore ?? 0.3;\n\n registry.register({\n name: \"semantic_search\",\n description:\n \"FIRST CHOICE for descriptive queries. Use this BEFORE search_content (grep) when the user describes WHAT code does ('where do we handle X', 'which file owns Y', 'how does Z work', 'find the logic that …'). Returns ranked snippets ordered by semantic relevance — finds the right file even when your description shares no words with the code. Falls back to search_content / search_files only for: exact identifiers, regex patterns, or counting occurrences of a known token. If your first instinct is grep on a paraphrased question, you are wrong — try semantic_search first.\",\n readOnly: true,\n parallelSafe: true,\n parameters: {\n type: \"object\",\n properties: {\n query: {\n type: \"string\",\n description:\n \"Natural-language description, phrased as a question or noun phrase: 'where do we validate the session cookie?' / 'retry backoff logic' / 'code that prevents user changes from immediately landing on disk'. Do NOT pass exact identifiers — those are search_content's job.\",\n },\n topK: {\n type: \"integer\",\n description: `Number of snippets to return (1..16). Default ${defaultTopK}.`,\n },\n minScore: {\n type: \"number\",\n description: `Drop snippets with cosine score below this (0..1). Default ${defaultMinScore}. Raise for stricter matches; lower if the index is small.`,\n },\n },\n required: [\"query\"],\n },\n fn: async (args: { query: string; topK?: number; minScore?: number }, ctx) => {\n const hits = await querySemantic(opts.root, args.query, {\n topK: args.topK ?? defaultTopK,\n minScore: args.minScore ?? defaultMinScore,\n provider: opts.provider,\n baseUrl: opts.baseUrl,\n apiKey: opts.apiKey,\n model: opts.model,\n extraBody: opts.extraBody,\n batchSize: opts.batchSize,\n signal: ctx?.signal,\n });\n if (hits === null) {\n return \"No semantic index found for this project. Run `reasonix index` to build one.\";\n }\n if (hits.length === 0) {\n return `query: ${args.query}\\n\\nno matches above the score threshold (${args.minScore ?? defaultMinScore}).`;\n }\n return formatHits(args.query, hits);\n },\n });\n return true;\n}\n\nexport function formatHits(query: string, hits: readonly SearchHit[]): string {\n const lines: string[] = [`query: ${query}`, `\\nresults (${hits.length}):`];\n hits.forEach((h, i) => {\n const { entry, score } = h;\n lines.push(\n `\\n${i + 1}. ${entry.path}:${entry.startLine}-${entry.endLine} (score ${score.toFixed(3)})`,\n );\n // Cap each snippet so a 60-line chunk doesn't dominate the\n // model's context. The full chunk is still discoverable via\n // read_file once the model picks the most relevant hit.\n const preview = entry.text.split(\"\\n\").slice(0, 8).join(\"\\n\");\n lines.push(indentBlock(preview, \" \"));\n if (entry.text.split(\"\\n\").length > 8) {\n lines.push(\n ` …(${entry.text.split(\"\\n\").length - 8} more lines — read_file ${entry.path}:${entry.startLine} for the full chunk)`,\n );\n }\n });\n return lines.join(\"\\n\");\n}\n\nfunction indentBlock(text: string, prefix: string): string {\n return text\n .split(\"\\n\")\n .map((l) => prefix + l)\n .join(\"\\n\");\n}\n\n/** Silent: register if index exists, else skip — no Ollama probe, no setup prompt. */\nexport async function bootstrapSemanticSearchInCodeMode(\n registry: ToolRegistry,\n rootDir: string,\n opts: Omit<SemanticToolOptions, \"root\" | \"defaultTopK\" | \"defaultMinScore\"> = {},\n): Promise<{ enabled: boolean }> {\n if (await indexCompatible(rootDir, { provider: opts.provider, model: opts.model })) {\n await registerSemanticSearchTool(registry, { ...opts, root: rootDir });\n return { enabled: true };\n }\n return { enabled: false };\n}\n"],"mappings":";;;;;;;;AAiBA,eAAsB,2BACpB,UACA,MACkB;AAClB,MAAI,CAAE,MAAM,gBAAgB,KAAK,MAAM,EAAE,UAAU,KAAK,UAAU,OAAO,KAAK,MAAM,CAAC;AACnF,WAAO;AACT,QAAM,cAAc,KAAK,eAAe;AACxC,QAAM,kBAAkB,KAAK,mBAAmB;AAEhD,WAAS,SAAS;AAAA,IAChB,MAAM;AAAA,IACN,aACE;AAAA,IACF,UAAU;AAAA,IACV,cAAc;AAAA,IACd,YAAY;AAAA,MACV,MAAM;AAAA,MACN,YAAY;AAAA,QACV,OAAO;AAAA,UACL,MAAM;AAAA,UACN,aACE;AAAA,QACJ;AAAA,QACA,MAAM;AAAA,UACJ,MAAM;AAAA,UACN,aAAa,iDAAiD,WAAW;AAAA,QAC3E;AAAA,QACA,UAAU;AAAA,UACR,MAAM;AAAA,UACN,aAAa,8DAA8D,eAAe;AAAA,QAC5F;AAAA,MACF;AAAA,MACA,UAAU,CAAC,OAAO;AAAA,IACpB;AAAA,IACA,IAAI,OAAO,MAA2D,QAAQ;AAC5E,YAAM,OAAO,MAAM,cAAc,KAAK,MAAM,KAAK,OAAO;AAAA,QACtD,MAAM,KAAK,QAAQ;AAAA,QACnB,UAAU,KAAK,YAAY;AAAA,QAC3B,UAAU,KAAK;AAAA,QACf,SAAS,KAAK;AAAA,QACd,QAAQ,KAAK;AAAA,QACb,OAAO,KAAK;AAAA,QACZ,WAAW,KAAK;AAAA,QAChB,WAAW,KAAK;AAAA,QAChB,QAAQ,KAAK;AAAA,MACf,CAAC;AACD,UAAI,SAAS,MAAM;AACjB,eAAO;AAAA,MACT;AACA,UAAI,KAAK,WAAW,GAAG;AACrB,eAAO,UAAU,KAAK,KAAK;AAAA;AAAA,wCAA6C,KAAK,YAAY,eAAe;AAAA,MAC1G;AACA,aAAO,WAAW,KAAK,OAAO,IAAI;AAAA,IACpC;AAAA,EACF,CAAC;AACD,SAAO;AACT;AAEO,SAAS,WAAW,OAAe,MAAoC;AAC5E,QAAM,QAAkB,CAAC,UAAU,KAAK,IAAI;AAAA,WAAc,KAAK,MAAM,IAAI;AACzE,OAAK,QAAQ,CAAC,GAAG,MAAM;AACrB,UAAM,EAAE,OAAO,MAAM,IAAI;AACzB,UAAM;AAAA,MACJ;AAAA,EAAK,IAAI,CAAC,KAAK,MAAM,IAAI,IAAI,MAAM,SAAS,IAAI,MAAM,OAAO,YAAY,MAAM,QAAQ,CAAC,CAAC;AAAA,IAC3F;AAIA,UAAM,UAAU,MAAM,KAAK,MAAM,IAAI,EAAE,MAAM,GAAG,CAAC,EAAE,KAAK,IAAI;AAC5D,UAAM,KAAK,YAAY,SAAS,KAAK,CAAC;AACtC,QAAI,MAAM,KAAK,MAAM,IAAI,EAAE,SAAS,GAAG;AACrC,YAAM;AAAA,QACJ,aAAQ,MAAM,KAAK,MAAM,IAAI,EAAE,SAAS,CAAC,gCAA2B,MAAM,IAAI,IAAI,MAAM,SAAS;AAAA,MACnG;AAAA,IACF;AAAA,EACF,CAAC;AACD,SAAO,MAAM,KAAK,IAAI;AACxB;AAEA,SAAS,YAAY,MAAc,QAAwB;AACzD,SAAO,KACJ,MAAM,IAAI,EACV,IAAI,CAAC,MAAM,SAAS,CAAC,EACrB,KAAK,IAAI;AACd;AAGA,eAAsB,kCACpB,UACA,SACA,OAA8E,CAAC,GAChD;AAC/B,MAAI,MAAM,gBAAgB,SAAS,EAAE,UAAU,KAAK,UAAU,OAAO,KAAK,MAAM,CAAC,GAAG;AAClF,UAAM,2BAA2B,UAAU,EAAE,GAAG,MAAM,MAAM,QAAQ,CAAC;AACrE,WAAO,EAAE,SAAS,KAAK;AAAA,EACzB;AACA,SAAO,EAAE,SAAS,MAAM;AAC1B;","names":[]}
@@ -3,7 +3,7 @@ import { createRequire as __cr } from 'node:module'; if (typeof globalThis.requi
3
3
  import {
4
4
  loadLanguage,
5
5
  saveLanguage
6
- } from "./chunk-DGA5QYFM.js";
6
+ } from "./chunk-24A7FHGJ.js";
7
7
 
8
8
  // src/i18n/EN.ts
9
9
  var EN = {
@@ -104,8 +104,9 @@ var EN = {
104
104
  { key: "wheel", text: "scrolls chat history (works on web/cloud/SSH terminals too)" },
105
105
  {
106
106
  key: "\u2191 / \u2193",
107
- text: "scroll chat \xB7 use Ctrl+P / Ctrl+N for prompt history + multi-line cursor"
108
- }
107
+ text: "prompt history (or per-line cursor in a multi-line draft) \u2014 Ctrl+P / Ctrl+N alias"
108
+ },
109
+ { key: "PgUp / PgDn", text: "scroll chat history (mouse wheel routes here too)" }
109
110
  ]
110
111
  }
111
112
  ],
@@ -119,11 +120,11 @@ var EN = {
119
120
  rows: [
120
121
  { key: "Enter", text: "submit the prompt" },
121
122
  { key: "Shift+Enter", text: "insert a newline in the prompt" },
122
- { key: "\u2191 / \u2193", text: "scroll chat history (mouse wheel routes here too)" },
123
123
  {
124
- key: "Ctrl+P / Ctrl+N",
124
+ key: "\u2191 / \u2193",
125
125
  text: "previous / next prompt history \xB7 cursor up / down in a multi-line draft"
126
126
  },
127
+ { key: "Ctrl+P / Ctrl+N", text: "readline alias for \u2191 / \u2193" },
127
128
  { key: "Ctrl+A / Ctrl+E", text: "jump to start / end of the current line" },
128
129
  { key: "Ctrl+W", text: "delete the word before the cursor" },
129
130
  { key: "Ctrl+U", text: "clear the entire prompt buffer" },
@@ -132,7 +133,11 @@ var EN = {
132
133
  { key: "Esc", text: "dismiss picker \xB7 abort the running model turn" },
133
134
  { key: "Ctrl+C", text: "abort the running model turn (NOT copy \u2014 see clipboard)" },
134
135
  { key: "PgUp / PgDn", text: "scroll chat history a page at a time" },
135
- { key: "End", text: "jump chat to the most recent line" }
136
+ { key: "End", text: "jump chat to the most recent line" },
137
+ {
138
+ key: "Ctrl+R",
139
+ text: "toggle verbose mode \u2014 full reasoning + tool output, no head/tail elision"
140
+ }
136
141
  ]
137
142
  },
138
143
  {
@@ -171,7 +176,7 @@ var EN = {
171
176
  ]
172
177
  }
173
178
  ],
174
- footer: "Wheel\u2192\u2191/\u2193 via DECSET 1007 (alternate-scroll) \u2014 wheel scrolls chat on most terminals (web/cloud/SSH included) without disturbing native selection. Drag to select stays modifier-free. Pass --no-mouse to opt out."
179
+ footer: "Wheel scrolls chat on most terminals (web/cloud/SSH included) \u2014 SGR mouse tracking is on by default and stays out of the way of native drag-select and right-click. Pass --no-mouse to opt out."
175
180
  },
176
181
  tipShownOnce: "shown once",
177
182
  modelOverride: "override the default model",
@@ -326,7 +331,7 @@ var EN = {
326
331
  sessions: { description: "list saved sessions (current marked with \u25B8)" },
327
332
  title: { description: "ask the model to rename this session from the conversation" },
328
333
  qq: {
329
- description: "connect, inspect, or disconnect the QQ channel for this session",
334
+ description: "connect, inspect, or disconnect the QQ channel for this session (first connect guides App ID / App Secret setup)",
330
335
  argsHint: "[connect [appId appSecret [sandbox]]|status|disconnect]"
331
336
  },
332
337
  setup: { description: "reminds you to exit and run `reasonix setup`" },
@@ -550,6 +555,8 @@ var EN = {
550
555
  notedVerbCreated: "created",
551
556
  notedVerbAppended: "appended to",
552
557
  memoryWriteFailed: "# memory write failed",
558
+ verboseOn: "\u25B8 verbose mode on \u2014 full reasoning + tool output",
559
+ verboseOff: "\u25B8 verbose mode off \u2014 head/tail elision restored",
553
560
  commandFailed: "! command failed",
554
561
  btwUsage: "\u25B8 /btw <question> \u2014 ask a side question without polluting the conversation context.",
555
562
  btwHeader: "\u226B btw",
@@ -684,6 +691,48 @@ var EN = {
684
691
  titleStarted: "\u25B8 naming session\u2026",
685
692
  titleFailed: "\u25B8 session title failed: {reason}"
686
693
  },
694
+ qq: {
695
+ unavailable: "/qq is not available in this session.",
696
+ connecting: "QQ: connecting\u2026",
697
+ connectFailed: "QQ connect failed: {reason}",
698
+ disconnecting: "QQ: disconnecting\u2026",
699
+ disconnectFailed: "QQ disconnect failed: {reason}",
700
+ usage: "Usage: /qq connect [appId appSecret [sandbox]] | /qq status | /qq disconnect",
701
+ promptAppId: "QQ setup: enter your QQ Open Platform App ID, then press Enter. Type /cancel to abort.",
702
+ promptAppSecret: "QQ setup: enter your QQ Open Platform App Secret, then press Enter. Type /cancel to abort.",
703
+ setupWaitingAppId: "waiting for App ID",
704
+ setupWaitingAppSecret: "waiting for App Secret",
705
+ setupCancelled: "QQ setup cancelled.",
706
+ credentialsRequired: "QQ App ID and App Secret are required.",
707
+ connected: "QQ connected in {mode} mode. It will auto-start on future launches.",
708
+ alreadyConnected: "QQ is already connected in {mode} mode. Auto-start is enabled.",
709
+ disconnected: "QQ disconnected. Auto-start is disabled.",
710
+ status: "QQ: {connected}, auto-start {enabled}, credentials {configured}, appId {appId}, {sandbox}, access {access}, current mode {mode}.",
711
+ statusSetup: "QQ: setup in progress \u2014 {step}",
712
+ stateConnected: "connected",
713
+ stateDisconnected: "disconnected",
714
+ stateEnabled: "enabled",
715
+ stateDisabled: "disabled",
716
+ stateConfigured: "configured",
717
+ stateNotConfigured: "not configured",
718
+ sandbox: "sandbox",
719
+ production: "production",
720
+ none: "none",
721
+ modeChat: "chat",
722
+ modeCode: "code",
723
+ accessOwner: "owner {owner}",
724
+ accessOwnerWithAllowlist: "owner {owner}, allowlist {count}",
725
+ accessAllowlist: "allowlist {count}",
726
+ accessRuntime: "first-sender (runtime only, {owner})",
727
+ accessOpen: "open (unbound)",
728
+ lockAlreadyRunning: "QQ channel is already running in process {pid}. Stop that process before starting another QQ channel.",
729
+ unauthorizedMessage: "QQ ignored message from unauthorized openid {openid}. Current access: {access}.",
730
+ runtimeBound: "QQ temporarily bound this run to first sender {openid}. Set `qq.ownerOpenId` in config to persist access.",
731
+ missingAppId: "QQ App ID is required. Run `/qq connect` to configure.",
732
+ missingAppSecret: "QQ App Secret is required. Run `/qq connect` to configure.",
733
+ authFailed: "QQ bot authentication failed \u2014 check your App ID and App Secret.",
734
+ readyTimeout: "QQ bot did not receive READY within 15s \u2014 check your App ID and App Secret."
735
+ },
687
736
  admin: {
688
737
  doctorNeedsTui: "/doctor needs a TUI context (postDoctor wired).",
689
738
  doctorRunning: "\u2695 Doctor \u2014 running health checks\u2026",
@@ -950,12 +999,14 @@ var EN = {
950
999
  usageSearxng: " /search-engine searxng use SearXNG at default endpoint",
951
1000
  usageSearxngUrl: " /search-engine searxng <url> use SearXNG at custom endpoint",
952
1001
  usageMetaso: " /search-engine metaso use Metaso API (100/d free, configure your own API key for more)",
1002
+ usageTavily: " /search-engine tavily use Tavily API (LLM-friendly, free 1000/mo \u2014 set TAVILY_API_KEY or tavilyApiKey in config; get one at https://tavily.com)",
953
1003
  alias: "Alias: /se",
954
1004
  searxngInfo: "SearXNG is a self-hosted metasearch engine (https://github.com/searxng/searxng).",
955
1005
  searxngInstall: "Install it with: docker run -d -p 8080:8080 searxng/searxng",
956
1006
  switched: 'Switched web search engine to "{engine}".{note}',
957
1007
  switchedSearxngNote: " Make sure SearXNG is running at {endpoint}.",
958
1008
  switchedMetasoNote: " There is a daily quota of 100 (configure your own API key for higher limits).",
1009
+ switchedTavilyNote: " Set TAVILY_API_KEY or `tavilyApiKey` in config; free 1000/mo at https://tavily.com.",
959
1010
  confirmed: '\u2713 Web search engine set to "{engine}"{detail}. Next assistant turn will pick up the change.',
960
1011
  confirmedDetail: " ({endpoint})"
961
1012
  },
@@ -1091,6 +1142,13 @@ var EN = {
1091
1142
  linesBelow: " \u2193 {count} line below (\u2193/j or Space/PgDn)",
1092
1143
  linesBelowPlural: " \u2193 {count} lines below (\u2193/j or Space/PgDn)"
1093
1144
  },
1145
+ editPicker: {
1146
+ title: "edit a previous message",
1147
+ hint: "\u2191\u2193 pick \xB7 Enter to load into composer \xB7 Esc to cancel",
1148
+ empty: "no user turns yet \u2014 nothing to edit",
1149
+ dismiss: "Esc to dismiss",
1150
+ forked: "\u25B8 forked at turn #{turn} \u2014 buffer holds the original text"
1151
+ },
1094
1152
  sessionPicker: {
1095
1153
  header: " \u25C8 REASONIX \xB7 pick a session ",
1096
1154
  title: "pick a session \u2014 {workspace}",
@@ -1224,6 +1282,11 @@ var EN = {
1224
1282
  metasoServerError: "web_search: Metaso server error ({status}) \u2014 try again later, or switch engine with /search-engine mojeek",
1225
1283
  metasoParseError: "web_search: Metaso returned unparseable response (HTTP {status}) \u2014 try again later",
1226
1284
  metasoApiError: "web_search: Metaso API error (code {code}: {message}) \u2014 try again later",
1285
+ tavilyMissingKey: "web_search: Tavily backend requires an API key \u2014 set TAVILY_API_KEY env var or `tavilyApiKey` in ~/.reasonix/config.json; free 1000/mo signup at https://tavily.com",
1286
+ tavilyUnauthorized: "web_search: Tavily API key rejected \u2014 check TAVILY_API_KEY or get one at https://tavily.com",
1287
+ tavilyRateLimit: "web_search: Tavily rate-limited or monthly quota exceeded \u2014 wait, switch engine with /search-engine mojeek, or upgrade your Tavily plan",
1288
+ tavilyServerError: "web_search: Tavily server error ({status}) \u2014 try again later, or switch engine with /search-engine mojeek",
1289
+ tavilyParseError: "web_search: Tavily returned unparseable response (HTTP {status}) \u2014 try again later",
1227
1290
  fetchStatus: "web_fetch {status} for {url} \u2014 try: confirm the URL resolves in a browser; status suggests the host returned an error page",
1228
1291
  fetchRateLimit429: "web_fetch 429 for {url} \u2014 try: wait 10s before retrying; the host is rate-limiting this client",
1229
1292
  fetchForbidden403: "web_fetch 403 for {url} \u2014 try: the host is blocking this client; the page may require login or block bots \u2014 use web_search snippets instead",
@@ -1342,7 +1405,8 @@ var EN = {
1342
1405
  scrollAbove: " \u2191 {scroll} / {max} row above",
1343
1406
  scrollAbovePlural: " \u2191 {scroll} / {max} rows above",
1344
1407
  scrollMore: " \u2014 {remaining} more",
1345
- scrollPgUp: " \xB7 PgUp / wheel / \u2191"
1408
+ scrollPgUp: " \xB7 PgUp / wheel",
1409
+ scrollCopy: " \xB7 /copy enters copy mode"
1346
1410
  },
1347
1411
  slashArgPicker: {
1348
1412
  noMatch: 'no match for "{partial}"',
@@ -1400,7 +1464,8 @@ var EN = {
1400
1464
  reconnectDetail: "tearing down \xB7 re-handshake \xB7 listing tools",
1401
1465
  disabledDetail: "via /mcp disable {name}",
1402
1466
  failedSetupHint: "\u2192 run `reasonix setup` to remove this entry, or fix the underlying issue (missing npm package, network, etc.).",
1403
- failedSetupConfigHint: "\u2192 run `reasonix setup` to remove broken entries from your saved config."
1467
+ failedSetupConfigHint: "\u2192 run `reasonix setup` to remove broken entries from your saved config.",
1468
+ abortedHint: "MCP startup aborted \u2014 {count} server(s) skipped. Run /mcp to retry once you've fixed the underlying issue."
1404
1469
  },
1405
1470
  checkpointPicker: {
1406
1471
  title: "restore a checkpoint \u2014 {workspace}",
@@ -1545,8 +1610,9 @@ var zhCN = {
1545
1610
  { key: "\u6EDA\u8F6E", text: "\u6EDA\u52A8\u804A\u5929\u8BB0\u5F55\uFF08Web / \u4E91\u7AEF / SSH \u7EC8\u7AEF\u4E5F\u80FD\u7528\uFF09" },
1546
1611
  {
1547
1612
  key: "\u2191 / \u2193",
1548
- text: "\u6EDA\u52A8\u804A\u5929 \xB7 \u8F93\u5165\u6846\u5386\u53F2 + \u591A\u884C\u5149\u6807\u7528 Ctrl+P / Ctrl+N"
1549
- }
1613
+ text: "\u8F93\u5165\u5386\u53F2\uFF08\u591A\u884C\u8349\u7A3F\u65F6\u6309\u884C\u79FB\u52A8\u5149\u6807\uFF09\u2014 Ctrl+P / Ctrl+N \u540C\u4E49"
1614
+ },
1615
+ { key: "PgUp / PgDn", text: "\u6EDA\u52A8\u804A\u5929\u8BB0\u5F55\uFF08\u9F20\u6807\u6EDA\u8F6E\u4E5F\u8D70\u8FD9\u6761\u8DEF\u5F84\uFF09" }
1550
1616
  ]
1551
1617
  }
1552
1618
  ],
@@ -1560,11 +1626,11 @@ var zhCN = {
1560
1626
  rows: [
1561
1627
  { key: "Enter", text: "\u63D0\u4EA4\u8F93\u5165" },
1562
1628
  { key: "Shift+Enter", text: "\u5728\u8F93\u5165\u6846\u4E2D\u63D2\u5165\u6362\u884C" },
1563
- { key: "\u2191 / \u2193", text: "\u6EDA\u52A8\u804A\u5929\u8BB0\u5F55\uFF08\u9F20\u6807\u6EDA\u8F6E\u4E5F\u8D70\u8FD9\u6761\u8DEF\u5F84\uFF09" },
1564
1629
  {
1565
- key: "Ctrl+P / Ctrl+N",
1630
+ key: "\u2191 / \u2193",
1566
1631
  text: "\u4E0A\u4E00\u6761 / \u4E0B\u4E00\u6761\u8F93\u5165\u5386\u53F2 \xB7 \u591A\u884C\u8349\u7A3F\u4E2D\u6309\u884C\u79FB\u52A8\u5149\u6807"
1567
1632
  },
1633
+ { key: "Ctrl+P / Ctrl+N", text: "\u2191 / \u2193 \u7684 readline \u540C\u4E49\u952E" },
1568
1634
  { key: "Ctrl+A / Ctrl+E", text: "\u8DF3\u5230\u5F53\u524D\u884C\u7684\u5F00\u5934 / \u7ED3\u5C3E" },
1569
1635
  { key: "Ctrl+W", text: "\u5220\u9664\u5149\u6807\u524D\u7684\u4E00\u4E2A\u8BCD" },
1570
1636
  { key: "Ctrl+U", text: "\u6E05\u7A7A\u6574\u4E2A\u8F93\u5165\u7F13\u51B2\u533A" },
@@ -1573,7 +1639,8 @@ var zhCN = {
1573
1639
  { key: "Esc", text: "\u5173\u95ED\u5F39\u51FA\u9009\u62E9\u5668 \xB7 \u4E2D\u6B62\u5F53\u524D\u6A21\u578B\u56DE\u5408" },
1574
1640
  { key: "Ctrl+C", text: "\u4E2D\u6B62\u5F53\u524D\u6A21\u578B\u56DE\u5408\uFF08\u4E0D\u662F\u590D\u5236 \u2014 \u89C1\u526A\u8D34\u677F\u6BB5\uFF09" },
1575
1641
  { key: "PgUp / PgDn", text: "\u6574\u9875\u6EDA\u52A8\u804A\u5929\u8BB0\u5F55" },
1576
- { key: "End", text: "\u8DF3\u5230\u804A\u5929\u7684\u6700\u65B0\u4E00\u884C" }
1642
+ { key: "End", text: "\u8DF3\u5230\u804A\u5929\u7684\u6700\u65B0\u4E00\u884C" },
1643
+ { key: "Ctrl+R", text: "\u5207\u6362\u8BE6\u7EC6\u6A21\u5F0F \u2014 \u663E\u793A\u5B8C\u6574\u63A8\u7406 + \u5DE5\u5177\u8F93\u51FA\uFF0C\u4E0D\u7701\u7565" }
1577
1644
  ]
1578
1645
  },
1579
1646
  {
@@ -1612,7 +1679,7 @@ var zhCN = {
1612
1679
  ]
1613
1680
  }
1614
1681
  ],
1615
- footer: "\u901A\u8FC7 DECSET 1007\uFF08alternate-scroll\uFF09\uFF0C\u7EC8\u7AEF\u628A\u6EDA\u8F6E\u7FFB\u8BD1\u6210 \u2191/\u2193 \u53D1\u7ED9\u5E94\u7528 \u2014 \u5927\u591A\u6570\u7EC8\u7AEF\uFF08\u542B Web / \u4E91\u7AEF / SSH\uFF09\u90FD\u80FD\u6EDA\uFF0C\u4E14\u4E0D\u5F71\u54CD\u7EC8\u7AEF\u539F\u751F\u9009\u533A\u3002\u76F4\u63A5\u62D6\u52A8\u9009\u4E2D\u6587\u672C\u65E0\u9700 Shift\u3002\u4F20\u5165 --no-mouse \u53EF\u5173\u95ED\u3002"
1682
+ footer: "\u6EDA\u8F6E\u5728\u5927\u591A\u6570\u7EC8\u7AEF\uFF08\u542B Web / \u4E91\u7AEF / SSH\uFF09\u90FD\u80FD\u6EDA\u804A\u5929 \u2014 \u9ED8\u8BA4\u5F00\u542F SGR \u9F20\u6807\u8DDF\u8E2A\uFF0C\u4F46\u4E0D\u4F1A\u5F71\u54CD\u7EC8\u7AEF\u539F\u751F\u62D6\u9009\u548C\u53F3\u952E\u83DC\u5355\u3002\u76F4\u63A5\u62D6\u52A8\u9009\u4E2D\u6587\u672C\u65E0\u9700 Shift\u3002\u4F20\u5165 --no-mouse \u53EF\u5173\u95ED\u3002"
1616
1683
  },
1617
1684
  tipShownOnce: "\u4EC5\u663E\u793A\u4E00\u6B21",
1618
1685
  modelOverride: "\u8986\u76D6\u9ED8\u8BA4\u6A21\u578B",
@@ -1769,7 +1836,7 @@ var zhCN = {
1769
1836
  sessions: { description: "\u5217\u51FA\u5DF2\u4FDD\u5B58\u7684\u4F1A\u8BDD\uFF08\u5F53\u524D\u6807\u8BB0\u4E3A \u25B8\uFF09" },
1770
1837
  title: { description: "\u8BA9\u6A21\u578B\u6839\u636E\u5F53\u524D\u5BF9\u8BDD\u91CD\u547D\u540D\u6B64\u4F1A\u8BDD" },
1771
1838
  qq: {
1772
- description: "\u8FDE\u63A5\u3001\u67E5\u770B\u6216\u65AD\u5F00\u5F53\u524D\u4F1A\u8BDD\u7684 QQ \u901A\u9053",
1839
+ description: "\u8FDE\u63A5\u3001\u67E5\u770B\u6216\u65AD\u5F00\u5F53\u524D\u4F1A\u8BDD\u7684 QQ \u901A\u9053\uFF08\u9996\u6B21\u8FDE\u63A5\u4F1A\u5F15\u5BFC\u5F55\u5165 App ID / App Secret\uFF09",
1773
1840
  argsHint: "[connect [appId appSecret [sandbox]]|status|disconnect]"
1774
1841
  },
1775
1842
  setup: { description: "\u63D0\u9192\u60A8\u9000\u51FA\u5E76\u8FD0\u884C `reasonix setup`" },
@@ -1995,6 +2062,8 @@ var zhCN = {
1995
2062
  notedVerbCreated: "\u521B\u5EFA",
1996
2063
  notedVerbAppended: "\u8FFD\u52A0\u5230",
1997
2064
  memoryWriteFailed: "# \u8BB0\u5FC6\u5199\u5165\u5931\u8D25",
2065
+ verboseOn: "\u25B8 \u8BE6\u7EC6\u6A21\u5F0F\u5DF2\u5F00 \u2014 \u663E\u793A\u5B8C\u6574\u63A8\u7406 + \u5DE5\u5177\u8F93\u51FA",
2066
+ verboseOff: "\u25B8 \u8BE6\u7EC6\u6A21\u5F0F\u5DF2\u5173 \u2014 \u6062\u590D\u5934\u5C3E\u7701\u7565",
1998
2067
  commandFailed: "! \u547D\u4EE4\u5931\u8D25",
1999
2068
  btwUsage: "\u25B8 /btw <\u95EE\u9898> \u2014 \u987A\u4FBF\u95EE\u4E2A\u9898\u5916\u8BDD\uFF0C\u4E0D\u4F1A\u5199\u5165\u5F53\u524D\u4F1A\u8BDD\u4E0A\u4E0B\u6587\u3002",
2000
2069
  btwHeader: "\u226B btw",
@@ -2129,6 +2198,48 @@ var zhCN = {
2129
2198
  titleStarted: "\u25B8 \u6B63\u5728\u547D\u540D\u4F1A\u8BDD\u2026",
2130
2199
  titleFailed: "\u25B8 \u4F1A\u8BDD\u547D\u540D\u5931\u8D25\uFF1A{reason}"
2131
2200
  },
2201
+ qq: {
2202
+ unavailable: "/qq \u5728\u5F53\u524D\u4F1A\u8BDD\u4E2D\u4E0D\u53EF\u7528\u3002",
2203
+ connecting: "QQ\uFF1A\u6B63\u5728\u8FDE\u63A5\u2026",
2204
+ connectFailed: "QQ \u8FDE\u63A5\u5931\u8D25\uFF1A{reason}",
2205
+ disconnecting: "QQ\uFF1A\u6B63\u5728\u65AD\u5F00\u2026",
2206
+ disconnectFailed: "QQ \u65AD\u5F00\u5931\u8D25\uFF1A{reason}",
2207
+ usage: "\u7528\u6CD5\uFF1A/qq connect [appId appSecret [sandbox]] | /qq status | /qq disconnect",
2208
+ promptAppId: "QQ \u9996\u6B21\u914D\u7F6E\uFF1A\u8BF7\u8F93\u5165 QQ \u5F00\u653E\u5E73\u53F0 App ID \u540E\u56DE\u8F66\u3002\u8F93\u5165 /cancel \u53EF\u53D6\u6D88\u3002",
2209
+ promptAppSecret: "QQ \u9996\u6B21\u914D\u7F6E\uFF1A\u8BF7\u8F93\u5165 QQ \u5F00\u653E\u5E73\u53F0 App Secret \u540E\u56DE\u8F66\u3002\u8F93\u5165 /cancel \u53EF\u53D6\u6D88\u3002",
2210
+ setupWaitingAppId: "\u7B49\u5F85\u8F93\u5165 App ID",
2211
+ setupWaitingAppSecret: "\u7B49\u5F85\u8F93\u5165 App Secret",
2212
+ setupCancelled: "QQ \u9996\u6B21\u914D\u7F6E\u5DF2\u53D6\u6D88\u3002",
2213
+ credentialsRequired: "QQ App ID \u548C App Secret \u4E0D\u80FD\u4E3A\u7A7A\u3002",
2214
+ connected: "QQ \u5DF2\u5728{mode}\u6A21\u5F0F\u4E0B\u8FDE\u63A5\u6210\u529F\uFF0C\u540E\u7EED\u542F\u52A8\u4F1A\u81EA\u52A8\u542F\u7528\u3002",
2215
+ alreadyConnected: "QQ \u5DF2\u5728{mode}\u6A21\u5F0F\u4E0B\u8FDE\u63A5\uFF0C\u81EA\u52A8\u542F\u52A8\u5DF2\u542F\u7528\u3002",
2216
+ disconnected: "QQ \u5DF2\u65AD\u5F00\u8FDE\u63A5\uFF0C\u81EA\u52A8\u542F\u52A8\u5DF2\u5173\u95ED\u3002",
2217
+ status: "QQ\uFF1A{connected}\uFF0C\u81EA\u52A8\u542F\u52A8{enabled}\uFF0C\u51ED\u636E{configured}\uFF0CappId {appId}\uFF0C{sandbox}\uFF0C\u8BBF\u95EE\u63A7\u5236 {access}\uFF0C\u5F53\u524D\u6A21\u5F0F {mode}\u3002",
2218
+ statusSetup: "QQ\uFF1A\u9996\u6B21\u914D\u7F6E\u8FDB\u884C\u4E2D \u2014\u2014 {step}",
2219
+ stateConnected: "\u5DF2\u8FDE\u63A5",
2220
+ stateDisconnected: "\u672A\u8FDE\u63A5",
2221
+ stateEnabled: "\u5DF2\u542F\u7528",
2222
+ stateDisabled: "\u672A\u542F\u7528",
2223
+ stateConfigured: "\u5DF2\u914D\u7F6E",
2224
+ stateNotConfigured: "\u672A\u914D\u7F6E",
2225
+ sandbox: "\u6C99\u7BB1\u73AF\u5883",
2226
+ production: "\u6B63\u5F0F\u73AF\u5883",
2227
+ none: "\u65E0",
2228
+ modeChat: "\u804A\u5929",
2229
+ modeCode: "\u4EE3\u7801",
2230
+ accessOwner: "\u6240\u6709\u8005 {owner}",
2231
+ accessOwnerWithAllowlist: "\u6240\u6709\u8005 {owner}\uFF0C\u767D\u540D\u5355 {count}",
2232
+ accessAllowlist: "\u767D\u540D\u5355 {count}",
2233
+ accessRuntime: "\u9996\u4E2A\u79C1\u804A\u7528\u6237\uFF08\u4EC5\u672C\u6B21\u8FD0\u884C\uFF0C{owner}\uFF09",
2234
+ accessOpen: "\u5F00\u653E\uFF08\u672A\u7ED1\u5B9A\uFF09",
2235
+ lockAlreadyRunning: "QQ \u901A\u9053\u5DF2\u5728\u8FDB\u7A0B {pid} \u4E2D\u8FD0\u884C\u3002\u8BF7\u5148\u505C\u6B62\u8BE5\u8FDB\u7A0B\uFF0C\u518D\u542F\u52A8\u65B0\u7684 QQ \u901A\u9053\u3002",
2236
+ unauthorizedMessage: "QQ \u5FFD\u7565\u4E86\u672A\u6388\u6743 openid {openid} \u7684\u6D88\u606F\u3002\u5F53\u524D\u8BBF\u95EE\u63A7\u5236\uFF1A{access}\u3002",
2237
+ runtimeBound: "QQ \u5DF2\u5728\u672C\u6B21\u8FD0\u884C\u4E2D\u4E34\u65F6\u7ED1\u5B9A\u5230\u9996\u4E2A\u53D1\u9001\u8005 {openid}\u3002\u5982\u9700\u6301\u4E45\u5316\uFF0C\u8BF7\u5728\u914D\u7F6E\u4E2D\u8BBE\u7F6E `qq.ownerOpenId`\u3002",
2238
+ missingAppId: "\u7F3A\u5C11 QQ App ID\u3002\u8BF7\u5148\u8FD0\u884C `/qq connect` \u5B8C\u6210\u914D\u7F6E\u3002",
2239
+ missingAppSecret: "\u7F3A\u5C11 QQ App Secret\u3002\u8BF7\u5148\u8FD0\u884C `/qq connect` \u5B8C\u6210\u914D\u7F6E\u3002",
2240
+ authFailed: "QQ \u673A\u5668\u4EBA\u9274\u6743\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5 App ID \u548C App Secret\u3002",
2241
+ readyTimeout: "QQ \u673A\u5668\u4EBA 15 \u79D2\u5185\u672A\u6536\u5230 READY\uFF0C\u8BF7\u68C0\u67E5 App ID \u548C App Secret\u3002"
2242
+ },
2132
2243
  admin: {
2133
2244
  doctorNeedsTui: "/doctor \u9700\u8981 TUI \u4E0A\u4E0B\u6587\uFF08postDoctor \u5DF2\u8FDE\u63A5\uFF09\u3002",
2134
2245
  doctorRunning: "\u2695 \u5065\u5EB7\u68C0\u67E5 \u2014 \u6B63\u5728\u8FD0\u884C\u2026",
@@ -2395,12 +2506,14 @@ var zhCN = {
2395
2506
  usageSearxng: " /search-engine searxng \u4F7F\u7528 SearXNG \u9ED8\u8BA4\u7AEF\u70B9",
2396
2507
  usageSearxngUrl: " /search-engine searxng <url> \u4F7F\u7528 SearXNG \u81EA\u5B9A\u4E49\u7AEF\u70B9",
2397
2508
  usageMetaso: " /search-engine metaso \u4F7F\u7528 Metaso API\uFF08\u6BCF\u5929 100 \u6B21\u514D\u8D39\uFF0C\u914D\u7F6E\u4F60\u81EA\u5DF1\u7684 API \u5BC6\u94A5\u53EF\u63D0\u5347\u9650\u989D\uFF09",
2509
+ usageTavily: " /search-engine tavily \u4F7F\u7528 Tavily API\uFF08LLM \u53CB\u597D\uFF0C\u6BCF\u6708 1000 \u6B21\u514D\u8D39 \u2014 \u8BBE\u7F6E TAVILY_API_KEY \u6216 config \u7684 tavilyApiKey\uFF1B\u6CE8\u518C https://tavily.com\uFF09",
2398
2510
  alias: "\u522B\u540D\uFF1A/se",
2399
2511
  searxngInfo: "SearXNG \u662F\u4E00\u4E2A\u81EA\u6258\u7BA1\u7684\u5143\u641C\u7D22\u5F15\u64CE\uFF08https://github.com/searxng/searxng\uFF09\u3002",
2400
2512
  searxngInstall: "\u5B89\u88C5\u547D\u4EE4\uFF1A docker run -d -p 8080:8080 searxng/searxng",
2401
2513
  switched: '\u5DF2\u5207\u6362\u7F51\u9875\u641C\u7D22\u5F15\u64CE\u4E3A "{engine}"\u3002{note}',
2402
2514
  switchedSearxngNote: " \u8BF7\u786E\u4FDD SearXNG \u5728 {endpoint} \u8FD0\u884C\u3002",
2403
2515
  switchedMetasoNote: " \u6BCF\u65E5\u9650\u989D 100 \u6B21\uFF08\u914D\u7F6E\u4F60\u81EA\u5DF1\u7684 API \u5BC6\u94A5\u53EF\u63D0\u5347\u9650\u989D\uFF09\u3002",
2516
+ switchedTavilyNote: " \u8BF7\u8BBE\u7F6E\u73AF\u5883\u53D8\u91CF TAVILY_API_KEY \u6216 config \u4E2D\u7684 `tavilyApiKey`\uFF1Bhttps://tavily.com \u6BCF\u6708 1000 \u6B21\u514D\u8D39\u3002",
2404
2517
  confirmed: '\u2713 \u7F51\u9875\u641C\u7D22\u5F15\u64CE\u5DF2\u8BBE\u4E3A "{engine}"{detail}\u3002\u4E0B\u4E00\u8F6E\u6A21\u578B\u8C03\u7528\u5C06\u751F\u6548\u3002',
2405
2518
  confirmedDetail: "\uFF08{endpoint}\uFF09"
2406
2519
  },
@@ -2536,6 +2649,13 @@ var zhCN = {
2536
2649
  linesBelow: " \u2193 \u4E0B\u65B9 {count} \u884C\uFF08\u2193/j \u6216 Space/PgDn\uFF09",
2537
2650
  linesBelowPlural: " \u2193 \u4E0B\u65B9 {count} \u884C\uFF08\u2193/j \u6216 Space/PgDn\uFF09"
2538
2651
  },
2652
+ editPicker: {
2653
+ title: "\u7F16\u8F91\u4E4B\u524D\u7684\u6D88\u606F",
2654
+ hint: "\u2191\u2193 \u9009\u62E9 \xB7 Enter \u52A0\u8F7D\u5230\u8F93\u5165\u6846 \xB7 Esc \u53D6\u6D88",
2655
+ empty: "\u8FD8\u6CA1\u6709\u7528\u6237\u53D1\u8A00 \u2014 \u6CA1\u4EC0\u4E48\u53EF\u4EE5\u7F16\u8F91\u7684",
2656
+ dismiss: "Esc \u5173\u95ED",
2657
+ forked: "\u25B8 \u4ECE\u7B2C #{turn} \u8F6E\u5206\u53C9 \u2014 \u539F\u6587\u5DF2\u586B\u56DE\u8F93\u5165\u6846"
2658
+ },
2539
2659
  sessionPicker: {
2540
2660
  header: " \u25C8 REASONIX \xB7 \u9009\u62E9\u4F1A\u8BDD ",
2541
2661
  title: "\u9009\u62E9\u4F1A\u8BDD \u2014 {workspace}",
@@ -2669,6 +2789,11 @@ var zhCN = {
2669
2789
  metasoServerError: "web_search: Metaso \u670D\u52A1\u5668\u9519\u8BEF\uFF08{status}\uFF09\u2014 \u7A0D\u540E\u91CD\u8BD5\uFF0C\u6216\u4F7F\u7528 /search-engine mojeek \u5207\u6362\u5F15\u64CE",
2670
2790
  metasoParseError: "web_search: Metaso \u8FD4\u56DE\u65E0\u6CD5\u89E3\u6790\u7684\u54CD\u5E94\uFF08HTTP {status}\uFF09\u2014 \u7A0D\u540E\u91CD\u8BD5",
2671
2791
  metasoApiError: "web_search: Metaso API \u9519\u8BEF\uFF08code {code}: {message}\uFF09\u2014 \u7A0D\u540E\u91CD\u8BD5",
2792
+ tavilyMissingKey: "web_search: Tavily \u540E\u7AEF\u9700\u8981 API \u5BC6\u94A5 \u2014 \u8BBE\u7F6E TAVILY_API_KEY \u73AF\u5883\u53D8\u91CF\uFF0C\u6216\u5728 ~/.reasonix/config.json \u4E2D\u914D\u7F6E `tavilyApiKey`\uFF1Bhttps://tavily.com \u6BCF\u6708 1000 \u6B21\u514D\u8D39",
2793
+ tavilyUnauthorized: "web_search: Tavily API \u5BC6\u94A5\u88AB\u62D2\u7EDD \u2014 \u68C0\u67E5 TAVILY_API_KEY\uFF0C\u6216\u5728 https://tavily.com \u83B7\u53D6\u5BC6\u94A5",
2794
+ tavilyRateLimit: "web_search: Tavily \u8BF7\u6C42\u9891\u7387\u9650\u5236\u6216\u6708\u5EA6\u914D\u989D\u7528\u5C3D \u2014 \u7B49\u5F85\u3001\u7528 /search-engine mojeek \u5207\u6362\u5F15\u64CE\uFF0C\u6216\u5347\u7EA7 Tavily \u8BA1\u5212",
2795
+ tavilyServerError: "web_search: Tavily \u670D\u52A1\u5668\u9519\u8BEF\uFF08{status}\uFF09\u2014 \u7A0D\u540E\u91CD\u8BD5\uFF0C\u6216\u4F7F\u7528 /search-engine mojeek \u5207\u6362\u5F15\u64CE",
2796
+ tavilyParseError: "web_search: Tavily \u8FD4\u56DE\u65E0\u6CD5\u89E3\u6790\u7684\u54CD\u5E94\uFF08HTTP {status}\uFF09\u2014 \u7A0D\u540E\u91CD\u8BD5",
2672
2797
  fetchStatus: "web_fetch {status} for {url} \u2014 try: \u5728\u6D4F\u89C8\u5668\u4E2D\u786E\u8BA4\u8BE5 URL \u80FD\u5426\u8BBF\u95EE\uFF1B\u8BE5\u72B6\u6001\u7801\u8868\u660E\u76EE\u6807\u4E3B\u673A\u8FD4\u56DE\u4E86\u9519\u8BEF\u9875\u9762",
2673
2798
  fetchRateLimit429: "web_fetch 429 for {url} \u2014 try: \u7B49\u5F85 10 \u79D2\u540E\u91CD\u8BD5\uFF1B\u76EE\u6807\u4E3B\u673A\u6B63\u5728\u5BF9\u8BE5\u5BA2\u6237\u7AEF\u8FDB\u884C\u9650\u6D41",
2674
2799
  fetchForbidden403: "web_fetch 403 for {url} \u2014 try: \u76EE\u6807\u4E3B\u673A\u62D2\u7EDD\u8BE5\u5BA2\u6237\u7AEF\u8BBF\u95EE\uFF1B\u8BE5\u9875\u9762\u53EF\u80FD\u9700\u8981\u767B\u5F55\u6216\u5C4F\u853D\u722C\u866B \u2014 \u6539\u7528 web_search \u6458\u8981",
@@ -2787,7 +2912,8 @@ var zhCN = {
2787
2912
  scrollAbove: " \u2191 {scroll}/{max} \u884C",
2788
2913
  scrollAbovePlural: " \u2191 {scroll}/{max} \u884C",
2789
2914
  scrollMore: " \u2014 \u8FD8\u6709 {remaining} \u884C",
2790
- scrollPgUp: " \xB7 PgUp/\u6EDA\u8F6E/\u2191"
2915
+ scrollPgUp: " \xB7 PgUp/\u6EDA\u8F6E",
2916
+ scrollCopy: " \xB7 /copy \u8FDB\u5165\u590D\u5236\u6A21\u5F0F"
2791
2917
  },
2792
2918
  slashArgPicker: {
2793
2919
  noMatch: '\u6CA1\u6709\u5339\u914D "{partial}"',
@@ -2845,7 +2971,8 @@ var zhCN = {
2845
2971
  reconnectDetail: "\u65AD\u5F00\u65E7\u8FDE\u63A5 \xB7 \u91CD\u65B0\u63E1\u624B \xB7 \u5217\u51FA\u5DE5\u5177",
2846
2972
  disabledDetail: "\u901A\u8FC7 /mcp disable {name}",
2847
2973
  failedSetupHint: "\u2192 \u8FD0\u884C `reasonix setup` \u79FB\u9664\u6B64\u6761\u76EE\uFF0C\u6216\u4FEE\u590D\u5E95\u5C42\u95EE\u9898\uFF08\u7F3A\u5C11 npm \u5305\u3001\u7F51\u7EDC\u7B49\uFF09\u3002",
2848
- failedSetupConfigHint: "\u2192 \u8FD0\u884C `reasonix setup` \u4ECE\u5DF2\u4FDD\u5B58\u914D\u7F6E\u4E2D\u79FB\u9664\u635F\u574F\u7684\u6761\u76EE\u3002"
2974
+ failedSetupConfigHint: "\u2192 \u8FD0\u884C `reasonix setup` \u4ECE\u5DF2\u4FDD\u5B58\u914D\u7F6E\u4E2D\u79FB\u9664\u635F\u574F\u7684\u6761\u76EE\u3002",
2975
+ abortedHint: "\u5DF2\u4E2D\u65AD MCP \u542F\u52A8 \u2014 \u8DF3\u8FC7 {count} \u4E2A\u670D\u52A1\u5668\u3002\u95EE\u9898\u4FEE\u590D\u540E\u7528 /mcp \u91CD\u65B0\u8FDE\u63A5\u3002"
2849
2976
  },
2850
2977
  checkpointPicker: {
2851
2978
  title: "\u6062\u590D\u68C0\u67E5\u70B9 \u2014 {workspace}",
@@ -2981,4 +3108,4 @@ export {
2981
3108
  tObj,
2982
3109
  t
2983
3110
  };
2984
- //# sourceMappingURL=chunk-6VANO7KB.js.map
3111
+ //# sourceMappingURL=chunk-KDRUEXII.js.map