reasonix 0.35.0 → 0.36.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 (80) hide show
  1. package/dashboard/dist/app.js +42 -3
  2. package/dashboard/dist/app.js.map +1 -1
  3. package/dist/cli/{chat-AB5D7I3V.js → chat-RGMYAOY2.js} +16 -15
  4. package/dist/cli/{chunk-RJ5GUVS2.js → chunk-2MCYGFLK.js} +10 -10
  5. package/dist/cli/chunk-2MCYGFLK.js.map +1 -0
  6. package/dist/cli/{chunk-SW3CCXEV.js → chunk-4Q3GRJIU.js} +2 -2
  7. package/dist/cli/{chunk-5JXXEPDM.js → chunk-BHLHOS5Y.js} +8 -2
  8. package/dist/cli/chunk-BHLHOS5Y.js.map +1 -0
  9. package/dist/cli/{chunk-IDP65VCC.js → chunk-BJ376EN3.js} +9 -8
  10. package/dist/cli/chunk-BJ376EN3.js.map +1 -0
  11. package/dist/cli/{chunk-2AWTGJ2C.js → chunk-CRPQUBP6.js} +26 -9
  12. package/dist/cli/{chunk-2AWTGJ2C.js.map → chunk-CRPQUBP6.js.map} +1 -1
  13. package/dist/cli/{chunk-GPHBJWCV.js → chunk-EN4LAZW5.js} +297 -171
  14. package/dist/cli/chunk-EN4LAZW5.js.map +1 -0
  15. package/dist/cli/{chunk-JJTOZPM3.js → chunk-IPCPEZWQ.js} +2 -2
  16. package/dist/cli/{chunk-SN7YH6FC.js → chunk-MLXUGPJE.js} +168 -35
  17. package/dist/cli/chunk-MLXUGPJE.js.map +1 -0
  18. package/dist/cli/{chunk-SX6L4HZZ.js → chunk-QPNZWUZF.js} +53 -6
  19. package/dist/cli/chunk-QPNZWUZF.js.map +1 -0
  20. package/dist/cli/{chunk-N2IC4XDL.js → chunk-QRUQ2BFT.js} +13 -8
  21. package/dist/cli/{chunk-N2IC4XDL.js.map → chunk-QRUQ2BFT.js.map} +1 -1
  22. package/dist/cli/{chunk-KZHMKOJH.js → chunk-T52GAWPP.js} +25 -3
  23. package/dist/cli/chunk-T52GAWPP.js.map +1 -0
  24. package/dist/cli/{chunk-I6YIAK6C.js → chunk-UNMYFZPZ.js} +2 -2
  25. package/dist/cli/{update-4TJWRUIN.js → chunk-WJ3YX4PZ.js} +51 -12
  26. package/dist/cli/chunk-WJ3YX4PZ.js.map +1 -0
  27. package/dist/cli/{chunk-RXGEGA7K.js → chunk-XQIFIB3U.js} +18 -7
  28. package/dist/cli/{chunk-RXGEGA7K.js.map → chunk-XQIFIB3U.js.map} +1 -1
  29. package/dist/cli/{chunk-2EBODRRO.js → chunk-ZJR4QLXB.js} +5 -1
  30. package/dist/cli/{chunk-2EBODRRO.js.map → chunk-ZJR4QLXB.js.map} +1 -1
  31. package/dist/cli/{code-XBEFHXVM.js → code-KJB3WDU6.js} +19 -17
  32. package/dist/cli/code-KJB3WDU6.js.map +1 -0
  33. package/dist/cli/{commands-MEZPSEHV.js → commands-FE2UDFBC.js} +3 -3
  34. package/dist/cli/{commit-CE4EFTUQ.js → commit-3IAGB22T.js} +5 -4
  35. package/dist/cli/commit-3IAGB22T.js.map +1 -0
  36. package/dist/cli/{doctor-A565GMWD.js → doctor-DKD34EFD.js} +7 -7
  37. package/dist/cli/index.js +33 -31
  38. package/dist/cli/index.js.map +1 -1
  39. package/dist/cli/{mcp-LDFK5QJI.js → mcp-2RDEQST6.js} +2 -2
  40. package/dist/cli/{mcp-browse-FYHEITCM.js → mcp-browse-VM5GLRBQ.js} +2 -2
  41. package/dist/cli/{mcp-inspect-T2HBR22P.js → mcp-inspect-CWSVCZUQ.js} +3 -3
  42. package/dist/cli/{replay-P2WC5N5X.js → replay-D7RT2DR7.js} +2 -2
  43. package/dist/cli/{run-QBWJETS3.js → run-FK5UBIIM.js} +11 -10
  44. package/dist/cli/run-FK5UBIIM.js.map +1 -0
  45. package/dist/cli/{server-SMLVXIW4.js → server-W4XJK4GX.js} +16 -16
  46. package/dist/cli/{server-SMLVXIW4.js.map → server-W4XJK4GX.js.map} +1 -1
  47. package/dist/cli/{sessions-55RIZVWG.js → sessions-YZXWMIWW.js} +8 -8
  48. package/dist/cli/{setup-QXMONZ4P.js → setup-IIAJXHP4.js} +196 -130
  49. package/dist/cli/setup-IIAJXHP4.js.map +1 -0
  50. package/dist/cli/update-GUCWB4UN.js +13 -0
  51. package/dist/cli/update-GUCWB4UN.js.map +1 -0
  52. package/dist/cli/{version-Q2HA3AAC.js → version-DWD6RLIU.js} +10 -10
  53. package/dist/index.d.ts +14 -2
  54. package/dist/index.js +270 -47
  55. package/dist/index.js.map +1 -1
  56. package/package.json +1 -1
  57. package/dist/cli/chunk-5JXXEPDM.js.map +0 -1
  58. package/dist/cli/chunk-GPHBJWCV.js.map +0 -1
  59. package/dist/cli/chunk-IDP65VCC.js.map +0 -1
  60. package/dist/cli/chunk-KZHMKOJH.js.map +0 -1
  61. package/dist/cli/chunk-RJ5GUVS2.js.map +0 -1
  62. package/dist/cli/chunk-SN7YH6FC.js.map +0 -1
  63. package/dist/cli/chunk-SX6L4HZZ.js.map +0 -1
  64. package/dist/cli/code-XBEFHXVM.js.map +0 -1
  65. package/dist/cli/commit-CE4EFTUQ.js.map +0 -1
  66. package/dist/cli/run-QBWJETS3.js.map +0 -1
  67. package/dist/cli/setup-QXMONZ4P.js.map +0 -1
  68. package/dist/cli/update-4TJWRUIN.js.map +0 -1
  69. /package/dist/cli/{chat-AB5D7I3V.js.map → chat-RGMYAOY2.js.map} +0 -0
  70. /package/dist/cli/{chunk-SW3CCXEV.js.map → chunk-4Q3GRJIU.js.map} +0 -0
  71. /package/dist/cli/{chunk-JJTOZPM3.js.map → chunk-IPCPEZWQ.js.map} +0 -0
  72. /package/dist/cli/{chunk-I6YIAK6C.js.map → chunk-UNMYFZPZ.js.map} +0 -0
  73. /package/dist/cli/{commands-MEZPSEHV.js.map → commands-FE2UDFBC.js.map} +0 -0
  74. /package/dist/cli/{doctor-A565GMWD.js.map → doctor-DKD34EFD.js.map} +0 -0
  75. /package/dist/cli/{mcp-LDFK5QJI.js.map → mcp-2RDEQST6.js.map} +0 -0
  76. /package/dist/cli/{mcp-browse-FYHEITCM.js.map → mcp-browse-VM5GLRBQ.js.map} +0 -0
  77. /package/dist/cli/{mcp-inspect-T2HBR22P.js.map → mcp-inspect-CWSVCZUQ.js.map} +0 -0
  78. /package/dist/cli/{replay-P2WC5N5X.js.map → replay-D7RT2DR7.js.map} +0 -0
  79. /package/dist/cli/{sessions-55RIZVWG.js.map → sessions-YZXWMIWW.js.map} +0 -0
  80. /package/dist/cli/{version-Q2HA3AAC.js.map → version-DWD6RLIU.js.map} +0 -0
package/dist/index.js CHANGED
@@ -766,6 +766,20 @@ function loadApiKey(path2 = defaultConfigPath()) {
766
766
  if (process.env.DEEPSEEK_API_KEY) return process.env.DEEPSEEK_API_KEY;
767
767
  return readConfig(path2).apiKey;
768
768
  }
769
+ function loadBaseUrl(path2 = defaultConfigPath()) {
770
+ if (process.env.DEEPSEEK_BASE_URL) return process.env.DEEPSEEK_BASE_URL;
771
+ return readConfig(path2).baseUrl;
772
+ }
773
+ function saveBaseUrl(url, path2 = defaultConfigPath()) {
774
+ const cfg = readConfig(path2);
775
+ const trimmed = url.trim();
776
+ if (trimmed) {
777
+ cfg.baseUrl = trimmed;
778
+ } else {
779
+ cfg.baseUrl = void 0;
780
+ }
781
+ writeConfig(cfg, path2);
782
+ }
769
783
  function webSearchEngine(path2 = defaultConfigPath()) {
770
784
  const cfg = readConfig(path2).webSearchEngine;
771
785
  if (cfg === "searxng") return "searxng";
@@ -806,7 +820,8 @@ function addProjectShellAllowed(rootDir, prefix, path2 = defaultConfigPath()) {
806
820
  }
807
821
  function isPlausibleKey(key) {
808
822
  const trimmed = key.trim();
809
- return /^sk-[A-Za-z0-9_-]{16,}$/.test(trimmed);
823
+ if (trimmed.length < 16) return false;
824
+ return !/\s/.test(trimmed);
810
825
  }
811
826
  function redactKey(key) {
812
827
  if (!key) return "";
@@ -889,14 +904,15 @@ var EN = {
889
904
  sections: [
890
905
  {
891
906
  rows: [
892
- { key: "wheel", text: "scrolls the chat history above" },
907
+ { key: "drag", text: "select text \u2014 terminal-native, no modifier needed" },
893
908
  {
894
909
  key: "right-click",
895
- text: "captured by the app \u2014 use Ctrl+V (Win/Linux) or Cmd+V (macOS) to paste"
910
+ text: "your terminal's native menu (paste / copy on Windows Terminal etc.)"
896
911
  },
912
+ { key: "wheel", text: "scrolls chat history (works on web/cloud/SSH terminals too)" },
897
913
  {
898
- key: "Shift + drag",
899
- text: "selects text natively (Option on iTerm2, Shift on Win Term / Alacritty / WezTerm)"
914
+ key: "\u2191 / \u2193",
915
+ text: "scroll chat \xB7 use Ctrl+P / Ctrl+N for prompt history + multi-line cursor"
900
916
  }
901
917
  ]
902
918
  }
@@ -911,7 +927,11 @@ var EN = {
911
927
  rows: [
912
928
  { key: "Enter", text: "submit the prompt" },
913
929
  { key: "Shift+Enter", text: "insert a newline in the prompt" },
914
- { key: "Ctrl+P / Ctrl+N", text: "recall previous / next prompt from history" },
930
+ { key: "\u2191 / \u2193", text: "scroll chat history (mouse wheel routes here too)" },
931
+ {
932
+ key: "Ctrl+P / Ctrl+N",
933
+ text: "previous / next prompt history \xB7 cursor up / down in a multi-line draft"
934
+ },
915
935
  { key: "Ctrl+A / Ctrl+E", text: "jump to start / end of the current line" },
916
936
  { key: "Ctrl+W", text: "delete the word before the cursor" },
917
937
  { key: "Ctrl+U", text: "clear the entire prompt buffer" },
@@ -919,10 +939,6 @@ var EN = {
919
939
  { key: "Shift+Tab", text: "edit-gate: toggle review \u2194 AUTO mode" },
920
940
  { key: "Esc", text: "dismiss picker \xB7 abort the running model turn" },
921
941
  { key: "Ctrl+C", text: "abort the running model turn (NOT copy \u2014 see clipboard)" },
922
- {
923
- key: "\u2191 / \u2193",
924
- text: "scroll chat history (PromptInput cursor when buffer non-empty)"
925
- },
926
942
  { key: "PgUp / PgDn", text: "scroll chat history a page at a time" },
927
943
  { key: "End", text: "jump chat to the most recent line" }
928
944
  ]
@@ -930,18 +946,18 @@ var EN = {
930
946
  {
931
947
  title: "mouse",
932
948
  rows: [
933
- { key: "wheel", text: "scrolls the chat history" },
934
- { key: "right-click", text: "captured by the app \u2014 use Ctrl+V / Cmd+V to paste" },
935
- { key: "left-click", text: "captured (no action yet \u2014 reserved for future use)" }
949
+ { key: "wheel", text: "scrolls chat history (works on web/cloud/SSH terminals too)" },
950
+ { key: "drag", text: "selects text natively \u2014 direct copy works, no modifier" },
951
+ { key: "right-click", text: "terminal-native (paste menu on Windows Terminal etc.)" }
936
952
  ]
937
953
  },
938
954
  {
939
955
  title: "copy / paste",
940
956
  rows: [
941
- { key: "select text", text: "hold Shift while dragging (Option on iTerm2)" },
957
+ { key: "select text", text: "drag to select \u2014 terminal-native (no modifier needed)" },
942
958
  {
943
959
  key: "copy",
944
- text: "Ctrl+Shift+C (Win/Linux) \xB7 Cmd+C (macOS) \u2014 terminal-native after selection"
960
+ text: "Ctrl+Shift+C (Win/Linux) \xB7 Cmd+C (macOS) \u2014 or auto-copy-on-select if your terminal does it"
945
961
  },
946
962
  { key: "paste", text: "Ctrl+V or Ctrl+Shift+V (Win/Linux) \xB7 Cmd+V (macOS)" },
947
963
  {
@@ -959,7 +975,7 @@ var EN = {
959
975
  ]
960
976
  }
961
977
  ],
962
- footer: "Mouse tracking is on so the wheel scrolls chat instead of moving the cursor \u2014 that's why right-click no longer does the terminal's native paste."
978
+ 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."
963
979
  },
964
980
  tipShownOnce: "shown once",
965
981
  modelOverride: "override the default model",
@@ -1160,8 +1176,22 @@ var EN = {
1160
1176
  apiKeyGetOne: "Get one at: https://platform.deepseek.com/api_keys",
1161
1177
  apiKeySavedLocally: "Saved locally to {path}",
1162
1178
  apiKeyInputLabel: "key \u203A ",
1163
- apiKeyInvalid: "Doesn't look like a DeepSeek key. They start with 'sk-' and are 30+ chars.",
1179
+ apiKeyInvalid: "Key looks too short \u2014 paste the full token (16+ chars, no spaces).",
1164
1180
  apiKeyPreview: "preview: {redacted}",
1181
+ themeTitle: "Choose a theme",
1182
+ themeSubtitle: "Preview updates live as you navigate. Change later with /theme.",
1183
+ themeSampleHeading: "Sample",
1184
+ themeFooter: "[\u2191\u2193] navigate \xB7 [Enter] confirm \xB7 [Esc] cancel",
1185
+ themeCaption: {
1186
+ default: "GitHub dark (default)",
1187
+ dark: "Cool dark tones",
1188
+ light: "Clean light mode",
1189
+ "tokyo-night": "Tokyo Night palette",
1190
+ "github-dark": "GitHub dark",
1191
+ "github-light": "GitHub light",
1192
+ "high-contrast": "Accessibility"
1193
+ },
1194
+ reviewLabelTheme: "Theme",
1165
1195
  presetTitle: "Pick a preset",
1166
1196
  mcpTitle: "Which MCP servers should Reasonix wire up for you?",
1167
1197
  mcpUserArgsHint: "(you'll provide {arg})",
@@ -1405,8 +1435,8 @@ var EN = {
1405
1435
  updateNpxForce: "to force a refresh sooner: `npm cache clean --force`.",
1406
1436
  updateUpgradeHint: "to upgrade, exit this session and run:",
1407
1437
  updateUpgradeCmd1: " reasonix update (interactive, dry-run supported via --dry-run)",
1408
- updateUpgradeCmd2: " npm install -g reasonix@latest (direct)",
1409
- updateInSessionDisabled: "in-session install is deliberately disabled \u2014 the npm spawn would",
1438
+ updateUpgradeCmd2: " {command} (direct)",
1439
+ updateInSessionDisabled: "in-session install is deliberately disabled \u2014 the install spawn would",
1410
1440
  updateInSessionDisabled2: "corrupt this TUI's rendering and Windows can lock the running binary.",
1411
1441
  statsNoData: "no usage data yet.",
1412
1442
  statsEveryTurn: "every turn you run here appends one record \u2014 this session's turns",
@@ -1660,6 +1690,56 @@ var EN = {
1660
1690
  newCreated: "\u25B8 created skill: {name}\n {path}\n edit it, then `/skill {name}` to invoke",
1661
1691
  newError: "\u25B2 /skill new failed: {reason}"
1662
1692
  }
1693
+ },
1694
+ cardTitles: {
1695
+ usage: "usage",
1696
+ context: "context",
1697
+ search: "search",
1698
+ subagent: "subagent",
1699
+ reply: "reply",
1700
+ reasoning: "reasoning",
1701
+ reasoningAborted: "reasoning (aborted)",
1702
+ reasoningEllipsis: "reasoning\u2026",
1703
+ error: "error"
1704
+ },
1705
+ cardLabels: {
1706
+ prompt: "prompt",
1707
+ reason: "reason",
1708
+ output: "output",
1709
+ cache: "cache",
1710
+ session: "session",
1711
+ balance: "balance",
1712
+ turn: "turn",
1713
+ system: "system",
1714
+ tools: "tools",
1715
+ log: "log",
1716
+ input: "input",
1717
+ topTools: "top tools",
1718
+ logMsgs: "log msgs",
1719
+ hitSingular: "{count} hit \xB7 {files} file",
1720
+ hitsPlural: "{count} hits \xB7 {files} files",
1721
+ moreHitSingular: "\u22EE +{count} more hit",
1722
+ moreHitsPlural: "\u22EE +{count} more hits",
1723
+ earlierLine: "\u22EE {count} earlier line (use /tool to read full)",
1724
+ earlierLines: "\u22EE {count} earlier lines (use /tool to read full)",
1725
+ earlierStackLine: "\u22EE {count} earlier stack line hidden",
1726
+ earlierStackLines: "\u22EE {count} earlier stack lines hidden",
1727
+ agent: "agent \xB7 {name}",
1728
+ response: "response",
1729
+ writing: "writing \u2026",
1730
+ tok: "tok",
1731
+ pilcrow: "\xB6",
1732
+ aborted: "aborted",
1733
+ truncatedByEsc: "[truncated by esc]",
1734
+ rejected: "rejected",
1735
+ exit: "exit {code}",
1736
+ bytesIn: "{bytes} in",
1737
+ elapsedSec: "{secs}s",
1738
+ stackTrace: "stack trace",
1739
+ retries: "retries",
1740
+ reasoningLabel: "reasoning \xB7 {count} \xB6",
1741
+ runningLabel: "running",
1742
+ workingLabel: "working"
1663
1743
  }
1664
1744
  };
1665
1745
 
@@ -1735,14 +1815,15 @@ var zhCN = {
1735
1815
  sections: [
1736
1816
  {
1737
1817
  rows: [
1738
- { key: "\u6EDA\u8F6E", text: "\u6EDA\u52A8\u4E0A\u65B9\u7684\u804A\u5929\u8BB0\u5F55" },
1818
+ { key: "\u62D6\u52A8", text: "\u76F4\u63A5\u9009\u4E2D\u6587\u672C \u2014 \u7EC8\u7AEF\u539F\u751F\uFF0C\u4E0D\u9700\u8981\u6309 Shift" },
1739
1819
  {
1740
1820
  key: "\u53F3\u952E",
1741
- text: "\u5DF2\u88AB\u5E94\u7528\u63A5\u7BA1 \u2014 \u7528 Ctrl+V\uFF08Win/Linux\uFF09\u6216 Cmd+V\uFF08macOS\uFF09\u7C98\u8D34"
1821
+ text: "\u7EC8\u7AEF\u539F\u751F\u83DC\u5355\uFF08Windows Terminal \u7B49\u7684\u590D\u5236 / \u7C98\u8D34\uFF09"
1742
1822
  },
1823
+ { key: "\u6EDA\u8F6E", text: "\u6EDA\u52A8\u804A\u5929\u8BB0\u5F55\uFF08Web / \u4E91\u7AEF / SSH \u7EC8\u7AEF\u4E5F\u80FD\u7528\uFF09" },
1743
1824
  {
1744
- key: "Shift + \u62D6\u52A8",
1745
- text: "\u539F\u751F\u9009\u4E2D\u6587\u672C\uFF08iTerm2 \u7528 Option\uFF0CWin Term / Alacritty / WezTerm \u7528 Shift\uFF09"
1825
+ key: "\u2191 / \u2193",
1826
+ text: "\u6EDA\u52A8\u804A\u5929 \xB7 \u8F93\u5165\u6846\u5386\u53F2 + \u591A\u884C\u5149\u6807\u7528 Ctrl+P / Ctrl+N"
1746
1827
  }
1747
1828
  ]
1748
1829
  }
@@ -1757,7 +1838,11 @@ var zhCN = {
1757
1838
  rows: [
1758
1839
  { key: "Enter", text: "\u63D0\u4EA4\u8F93\u5165" },
1759
1840
  { key: "Shift+Enter", text: "\u5728\u8F93\u5165\u6846\u4E2D\u63D2\u5165\u6362\u884C" },
1760
- { key: "Ctrl+P / Ctrl+N", text: "\u8C03\u51FA\u4E0A\u4E00\u6761 / \u4E0B\u4E00\u6761\u5386\u53F2\u63D0\u793A" },
1841
+ { key: "\u2191 / \u2193", text: "\u6EDA\u52A8\u804A\u5929\u8BB0\u5F55\uFF08\u9F20\u6807\u6EDA\u8F6E\u4E5F\u8D70\u8FD9\u6761\u8DEF\u5F84\uFF09" },
1842
+ {
1843
+ key: "Ctrl+P / Ctrl+N",
1844
+ text: "\u4E0A\u4E00\u6761 / \u4E0B\u4E00\u6761\u8F93\u5165\u5386\u53F2 \xB7 \u591A\u884C\u8349\u7A3F\u4E2D\u6309\u884C\u79FB\u52A8\u5149\u6807"
1845
+ },
1761
1846
  { key: "Ctrl+A / Ctrl+E", text: "\u8DF3\u5230\u5F53\u524D\u884C\u7684\u5F00\u5934 / \u7ED3\u5C3E" },
1762
1847
  { key: "Ctrl+W", text: "\u5220\u9664\u5149\u6807\u524D\u7684\u4E00\u4E2A\u8BCD" },
1763
1848
  { key: "Ctrl+U", text: "\u6E05\u7A7A\u6574\u4E2A\u8F93\u5165\u7F13\u51B2\u533A" },
@@ -1765,7 +1850,6 @@ var zhCN = {
1765
1850
  { key: "Shift+Tab", text: "\u7F16\u8F91\u95E8\u63A7\uFF1A\u5207\u6362 \u9884\u89C8 \u2194 \u81EA\u52A8 \u6A21\u5F0F" },
1766
1851
  { key: "Esc", text: "\u5173\u95ED\u5F39\u51FA\u9009\u62E9\u5668 \xB7 \u4E2D\u6B62\u5F53\u524D\u6A21\u578B\u56DE\u5408" },
1767
1852
  { key: "Ctrl+C", text: "\u4E2D\u6B62\u5F53\u524D\u6A21\u578B\u56DE\u5408\uFF08\u4E0D\u662F\u590D\u5236 \u2014 \u89C1\u526A\u8D34\u677F\u6BB5\uFF09" },
1768
- { key: "\u2191 / \u2193", text: "\u6EDA\u52A8\u804A\u5929\u8BB0\u5F55\uFF08\u7F13\u51B2\u533A\u975E\u7A7A\u65F6\u4E3A\u5149\u6807\u79FB\u52A8\uFF09" },
1769
1853
  { key: "PgUp / PgDn", text: "\u6574\u9875\u6EDA\u52A8\u804A\u5929\u8BB0\u5F55" },
1770
1854
  { key: "End", text: "\u8DF3\u5230\u804A\u5929\u7684\u6700\u65B0\u4E00\u884C" }
1771
1855
  ]
@@ -1773,18 +1857,18 @@ var zhCN = {
1773
1857
  {
1774
1858
  title: "\u9F20\u6807",
1775
1859
  rows: [
1776
- { key: "\u6EDA\u8F6E", text: "\u6EDA\u52A8\u804A\u5929\u8BB0\u5F55" },
1777
- { key: "\u53F3\u952E", text: "\u88AB\u5E94\u7528\u63A5\u7BA1 \u2014 \u7528 Ctrl+V / Cmd+V \u7C98\u8D34" },
1778
- { key: "\u5DE6\u952E", text: "\u88AB\u63A5\u7BA1\uFF08\u6682\u65E0\u52A8\u4F5C \u2014 \u9884\u7559\u7ED9\u540E\u7EED\u529F\u80FD\uFF09" }
1860
+ { key: "\u6EDA\u8F6E", text: "\u6EDA\u52A8\u804A\u5929\u8BB0\u5F55\uFF08Web / \u4E91\u7AEF / SSH \u7EC8\u7AEF\u4E5F\u80FD\u7528\uFF09" },
1861
+ { key: "\u62D6\u52A8", text: "\u539F\u751F\u9009\u4E2D\u6587\u672C \u2014 \u76F4\u63A5\u590D\u5236\uFF0C\u4E0D\u9700\u8981\u4FEE\u9970\u952E" },
1862
+ { key: "\u53F3\u952E", text: "\u7EC8\u7AEF\u539F\u751F\uFF08Windows Terminal \u7B49\u7684\u7C98\u8D34\u83DC\u5355\uFF09" }
1779
1863
  ]
1780
1864
  },
1781
1865
  {
1782
1866
  title: "\u590D\u5236 / \u7C98\u8D34",
1783
1867
  rows: [
1784
- { key: "\u9009\u4E2D\u6587\u5B57", text: "\u62D6\u52A8\u65F6\u6309\u4F4F Shift\uFF08iTerm2 \u7528 Option\uFF09" },
1868
+ { key: "\u9009\u4E2D\u6587\u5B57", text: "\u76F4\u63A5\u62D6\u52A8 \u2014 \u7EC8\u7AEF\u539F\u751F\uFF08\u4E0D\u9700\u8981\u4EFB\u4F55\u4FEE\u9970\u952E\uFF09" },
1785
1869
  {
1786
1870
  key: "\u590D\u5236",
1787
- text: "Ctrl+Shift+C\uFF08Win/Linux\uFF09\xB7 Cmd+C\uFF08macOS\uFF09\u2014 \u9009\u4E2D\u540E\u7531\u7EC8\u7AEF\u539F\u751F\u5904\u7406"
1871
+ text: "Ctrl+Shift+C\uFF08Win/Linux\uFF09\xB7 Cmd+C\uFF08macOS\uFF09\u2014 \u6216\u9009\u4E2D\u5373\u590D\u5236\uFF08\u770B\u7EC8\u7AEF\u8BBE\u7F6E\uFF09"
1788
1872
  },
1789
1873
  { key: "\u7C98\u8D34", text: "Ctrl+V \u6216 Ctrl+Shift+V\uFF08Win/Linux\uFF09\xB7 Cmd+V\uFF08macOS\uFF09" },
1790
1874
  {
@@ -1802,7 +1886,7 @@ var zhCN = {
1802
1886
  ]
1803
1887
  }
1804
1888
  ],
1805
- footer: "\u9F20\u6807\u8FFD\u8E2A\u5DF2\u5F00\u542F\uFF0C\u6EDA\u8F6E\u7528\u6765\u6EDA\u52A8\u804A\u5929\u800C\u4E0D\u662F\u79FB\u52A8\u5149\u6807 \u2014 \u8FD9\u4E5F\u662F\u53F3\u952E\u4E0D\u518D\u89E6\u53D1\u7EC8\u7AEF\u539F\u751F\u7C98\u8D34\u7684\u539F\u56E0\u3002"
1889
+ 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"
1806
1890
  },
1807
1891
  tipShownOnce: "\u4EC5\u663E\u793A\u4E00\u6B21",
1808
1892
  modelOverride: "\u8986\u76D6\u9ED8\u8BA4\u6A21\u578B",
@@ -2007,8 +2091,22 @@ var zhCN = {
2007
2091
  apiKeyGetOne: "\u5728\u6B64\u83B7\u53D6\uFF1Ahttps://platform.deepseek.com/api_keys",
2008
2092
  apiKeySavedLocally: "\u4FDD\u5B58\u5728\u672C\u5730\uFF1A{path}",
2009
2093
  apiKeyInputLabel: "key \u203A ",
2010
- apiKeyInvalid: "\u8FD9\u770B\u8D77\u6765\u4E0D\u50CF DeepSeek \u7684 key\u3002\u5B83\u4EEC\u4EE5 'sk-' \u5F00\u5934\uFF0C30 \u5B57\u7B26\u4EE5\u4E0A\u3002",
2094
+ apiKeyInvalid: "key \u957F\u5EA6\u4E0D\u8DB3\u2014\u2014\u8BF7\u7C98\u8D34\u5B8C\u6574 token\uFF0816+ \u5B57\u7B26\uFF0C\u4E0D\u542B\u7A7A\u683C\uFF09\u3002",
2011
2095
  apiKeyPreview: "\u9884\u89C8\uFF1A{redacted}",
2096
+ themeTitle: "\u9009\u62E9\u4E3B\u9898",
2097
+ themeSubtitle: "\u65B9\u5411\u952E\u5207\u6362\u65F6\u5373\u65F6\u9884\u89C8\u6548\u679C\uFF0C\u4E4B\u540E\u53EF\u7528 /theme \u66F4\u6539\u3002",
2098
+ themeSampleHeading: "\u793A\u4F8B",
2099
+ themeFooter: "[\u2191\u2193] \u79FB\u52A8 \xB7 [Enter] \u786E\u8BA4 \xB7 [Esc] \u53D6\u6D88",
2100
+ themeCaption: {
2101
+ default: "GitHub \u6DF1\u8272\uFF08\u9ED8\u8BA4\uFF09",
2102
+ dark: "\u6DF1\u8272\u8C03",
2103
+ light: "\u6E05\u723D\u6D45\u8272",
2104
+ "tokyo-night": "\u4E1C\u4EAC\u591C\u8272",
2105
+ "github-dark": "GitHub \u6DF1\u8272",
2106
+ "github-light": "GitHub \u6D45\u8272",
2107
+ "high-contrast": "\u9AD8\u5BF9\u6BD4\u5EA6\uFF08\u65E0\u969C\u788D\uFF09"
2108
+ },
2109
+ reviewLabelTheme: "\u4E3B\u9898",
2012
2110
  presetTitle: "\u9009\u62E9\u9884\u8BBE",
2013
2111
  mcpTitle: "Reasonix \u8981\u4E3A\u4F60\u63A5\u5165\u54EA\u4E9B MCP \u670D\u52A1\u5668\uFF1F",
2014
2112
  mcpUserArgsHint: "\uFF08\u9700\u8981\u4F60\u63D0\u4F9B {arg}\uFF09",
@@ -2252,8 +2350,8 @@ var zhCN = {
2252
2350
  updateNpxForce: "\u8981\u5F3A\u5236\u5237\u65B0\uFF1A`npm cache clean --force`\u3002",
2253
2351
  updateUpgradeHint: "\u8981\u5347\u7EA7\uFF0C\u8BF7\u9000\u51FA\u6B64\u4F1A\u8BDD\u5E76\u8FD0\u884C\uFF1A",
2254
2352
  updateUpgradeCmd1: " reasonix update \uFF08\u4EA4\u4E92\u5F0F\uFF0C\u652F\u6301 --dry-run \u9884\u89C8\uFF09",
2255
- updateUpgradeCmd2: " npm install -g reasonix@latest \uFF08\u76F4\u63A5\u5B89\u88C5\uFF09",
2256
- updateInSessionDisabled: "\u4F1A\u8BDD\u5185\u5B89\u88C5\u88AB\u523B\u610F\u7981\u7528 \u2014 npm spawn \u4F1A",
2353
+ updateUpgradeCmd2: " {command} \uFF08\u76F4\u63A5\u5B89\u88C5\uFF09",
2354
+ updateInSessionDisabled: "\u4F1A\u8BDD\u5185\u5B89\u88C5\u88AB\u523B\u610F\u7981\u7528 \u2014 \u5B89\u88C5\u547D\u4EE4\u4F1A",
2257
2355
  updateInSessionDisabled2: "\u7834\u574F\u6B64 TUI \u7684\u6E32\u67D3\uFF0C\u4E14 Windows \u53EF\u80FD\u9501\u5B9A\u8FD0\u884C\u4E2D\u7684\u4E8C\u8FDB\u5236\u6587\u4EF6\u3002",
2258
2356
  statsNoData: "\u5C1A\u65E0\u4F7F\u7528\u6570\u636E\u3002",
2259
2357
  statsEveryTurn: "\u60A8\u5728\u6B64\u8FD0\u884C\u7684\u6BCF\u4E00\u8F6E\u90FD\u4F1A\u8FFD\u52A0\u4E00\u6761\u8BB0\u5F55 \u2014 \u6B64\u4F1A\u8BDD\u7684\u8F6E\u6B21",
@@ -2507,6 +2605,56 @@ var zhCN = {
2507
2605
  newCreated: "\u25B8 \u5DF2\u521B\u5EFA\u6280\u80FD\uFF1A{name}\n {path}\n \u7F16\u8F91\u540E\u7528 `/skill {name}` \u8C03\u7528",
2508
2606
  newError: "\u25B2 /skill new \u5931\u8D25\uFF1A{reason}"
2509
2607
  }
2608
+ },
2609
+ cardTitles: {
2610
+ usage: "\u7528\u91CF",
2611
+ context: "\u4E0A\u4E0B\u6587",
2612
+ search: "\u641C\u7D22",
2613
+ subagent: "\u5B50\u4EE3\u7406",
2614
+ reply: "\u56DE\u590D",
2615
+ reasoning: "\u63A8\u7406\u4E2D",
2616
+ reasoningAborted: "\u63A8\u7406\uFF08\u5DF2\u4E2D\u6B62\uFF09",
2617
+ reasoningEllipsis: "\u63A8\u7406\u4E2D\u2026",
2618
+ error: "\u9519\u8BEF"
2619
+ },
2620
+ cardLabels: {
2621
+ prompt: "\u63D0\u793A",
2622
+ reason: "\u63A8\u7406",
2623
+ output: "\u8F93\u51FA",
2624
+ cache: "\u7F13\u5B58",
2625
+ session: "\u4F1A\u8BDD",
2626
+ balance: "\u4F59\u989D",
2627
+ turn: "\u8F6E",
2628
+ system: "\u7CFB\u7EDF",
2629
+ tools: "\u5DE5\u5177",
2630
+ log: "\u65E5\u5FD7",
2631
+ input: "\u8F93\u5165",
2632
+ topTools: "Top \u5DE5\u5177",
2633
+ logMsgs: "\u65E5\u5FD7\u6D88\u606F",
2634
+ hitSingular: "{count} \u6761\u7ED3\u679C \xB7 {files} \u4E2A\u6587\u4EF6",
2635
+ hitsPlural: "{count} \u6761\u7ED3\u679C \xB7 {files} \u4E2A\u6587\u4EF6",
2636
+ moreHitSingular: "\u22EE +{count} \u6761\u7ED3\u679C",
2637
+ moreHitsPlural: "\u22EE +{count} \u6761\u7ED3\u679C",
2638
+ earlierLine: "\u22EE \u524D {count} \u884C\uFF08\u4F7F\u7528 /tool \u9605\u8BFB\u5168\u6587\uFF09",
2639
+ earlierLines: "\u22EE \u524D {count} \u884C\uFF08\u4F7F\u7528 /tool \u9605\u8BFB\u5168\u6587\uFF09",
2640
+ earlierStackLine: "\u22EE \u524D {count} \u884C\u5806\u6808\u5DF2\u9690\u85CF",
2641
+ earlierStackLines: "\u22EE \u524D {count} \u884C\u5806\u6808\u5DF2\u9690\u85CF",
2642
+ agent: "\u4EE3\u7406 \xB7 {name}",
2643
+ response: "\u56DE\u590D",
2644
+ writing: "\u8F93\u51FA\u4E2D \u2026",
2645
+ tok: "tok",
2646
+ pilcrow: "\xB6",
2647
+ aborted: "\u5DF2\u4E2D\u6B62",
2648
+ truncatedByEsc: "[\u5DF2\u88AB Esc \u622A\u65AD]",
2649
+ rejected: "\u5DF2\u62D2\u7EDD",
2650
+ exit: "\u9000\u51FA\u7801 {code}",
2651
+ bytesIn: "{bytes} \u8F93\u5165",
2652
+ elapsedSec: "{secs}\u79D2",
2653
+ stackTrace: "\u5806\u6808\u8DDF\u8E2A",
2654
+ retries: "\u6B21\u91CD\u8BD5",
2655
+ reasoningLabel: "\u63A8\u7406 \xB7 {count} \xB6",
2656
+ runningLabel: "\u8FD0\u884C\u4E2D",
2657
+ workingLabel: "\u5DE5\u4F5C\u4E2D"
2510
2658
  }
2511
2659
  };
2512
2660
 
@@ -7813,9 +7961,14 @@ function registerSubmitPlan(registry, opts) {
7813
7961
  kind: "plan_proposed",
7814
7962
  payload: { plan, steps, summary }
7815
7963
  });
7816
- if (verdict.type === "approve") return "plan approved";
7817
- if (verdict.type === "refine") throw new Error("user requested refinement");
7818
- throw new Error("plan cancelled");
7964
+ const fb = verdict.feedback?.trim();
7965
+ if (verdict.type === "approve") {
7966
+ return fb ? `plan approved. user's additional instructions: ${fb}` : "plan approved";
7967
+ }
7968
+ if (verdict.type === "refine") {
7969
+ throw new Error(fb ? `user requested refinement: ${fb}` : "user requested refinement");
7970
+ }
7971
+ throw new Error(fb ? `plan cancelled: ${fb}` : "plan cancelled");
7819
7972
  }
7820
7973
  });
7821
7974
  }
@@ -9450,6 +9603,7 @@ async function runCommand(cmd, opts) {
9450
9603
  });
9451
9604
  }
9452
9605
  const timeoutMs = timeoutSec * 1e3;
9606
+ const normalizedEnv = normalizeWindowsEnvVars(process.env);
9453
9607
  const spawnOpts = {
9454
9608
  cwd: opts.cwd,
9455
9609
  shell: false,
@@ -9463,9 +9617,9 @@ async function runCommand(cmd, opts) {
9463
9617
  // sees a Python traceback instead of the script's real output
9464
9618
  // and goes around in circles trying to fix the wrong problem.
9465
9619
  // Harmless on non-Python processes (env vars they don't read).
9466
- env: { ...process.env, PYTHONIOENCODING: "utf-8", PYTHONUTF8: "1" }
9620
+ env: { ...normalizedEnv, PYTHONIOENCODING: "utf-8", PYTHONUTF8: "1" }
9467
9621
  };
9468
- const { bin, args, spawnOverrides } = prepareSpawn(argv);
9622
+ const { bin, args, spawnOverrides } = prepareSpawn(argv, { env: normalizedEnv });
9469
9623
  const effectiveSpawnOpts = { ...spawnOpts, ...spawnOverrides };
9470
9624
  return await new Promise((resolve10, reject) => {
9471
9625
  let child;
@@ -9546,9 +9700,9 @@ function resolveExecutable(cmd, opts = {}) {
9546
9700
  if (cmd.includes("/") || cmd.includes("\\") || pathMod7.isAbsolute(cmd)) return cmd;
9547
9701
  if (pathMod7.extname(cmd)) return cmd;
9548
9702
  const env = opts.env ?? process.env;
9549
- const pathExt = (env.PATHEXT ?? ".COM;.EXE;.BAT;.CMD").split(";").map((e) => e.trim()).filter(Boolean);
9703
+ const pathExt = (getEnvCaseInsensitive(env, "PATHEXT") ?? ".COM;.EXE;.BAT;.CMD").split(";").map((e) => e.trim()).filter(Boolean);
9550
9704
  const delimiter2 = opts.pathDelimiter ?? (platform === "win32" ? ";" : pathMod7.delimiter);
9551
- const pathDirs = (env.PATH ?? "").split(delimiter2).filter(Boolean);
9705
+ const pathDirs = (getEnvCaseInsensitive(env, "PATH") ?? "").split(delimiter2).filter(Boolean);
9552
9706
  const isFile = opts.isFile ?? defaultIsFile;
9553
9707
  for (const dir of pathDirs) {
9554
9708
  for (const ext of pathExt) {
@@ -9558,6 +9712,52 @@ function resolveExecutable(cmd, opts = {}) {
9558
9712
  }
9559
9713
  return cmd;
9560
9714
  }
9715
+ function normalizeWindowsEnvVars(env, opts = {}) {
9716
+ const platform = opts.platform ?? process.platform;
9717
+ if (platform !== "win32") return { ...env };
9718
+ const out = {};
9719
+ const pathValues = [];
9720
+ const pathExtValues = [];
9721
+ for (const [key, value] of Object.entries(env)) {
9722
+ const lower = key.toLowerCase();
9723
+ if (lower === "path") {
9724
+ if (typeof value === "string") pathValues.push(value);
9725
+ continue;
9726
+ }
9727
+ if (lower === "pathext") {
9728
+ if (typeof value === "string") pathExtValues.push(value);
9729
+ continue;
9730
+ }
9731
+ out[key] = value;
9732
+ }
9733
+ if (pathValues.length > 0) out.Path = mergeWindowsPathLike(pathValues, ";");
9734
+ if (pathExtValues.length > 0) out.PATHEXT = mergeWindowsPathLike(pathExtValues, ";");
9735
+ return out;
9736
+ }
9737
+ function getEnvCaseInsensitive(env, key) {
9738
+ const exact = env[key];
9739
+ if (exact !== void 0) return exact;
9740
+ const target = key.toLowerCase();
9741
+ for (const [candidate, value] of Object.entries(env)) {
9742
+ if (candidate.toLowerCase() === target) return value;
9743
+ }
9744
+ return void 0;
9745
+ }
9746
+ function mergeWindowsPathLike(values, delimiter2) {
9747
+ const seen = /* @__PURE__ */ new Set();
9748
+ const merged = [];
9749
+ for (const value of values) {
9750
+ for (const part of value.split(delimiter2)) {
9751
+ const entry = part.trim();
9752
+ if (!entry) continue;
9753
+ const normalized = entry.toLowerCase();
9754
+ if (seen.has(normalized)) continue;
9755
+ seen.add(normalized);
9756
+ merged.push(entry);
9757
+ }
9758
+ }
9759
+ return merged.join(delimiter2);
9760
+ }
9561
9761
  function defaultIsFile(full) {
9562
9762
  try {
9563
9763
  return existsSync8(full) && statSync4(full).isFile();
@@ -10778,13 +10978,32 @@ function compareVersions(a, b) {
10778
10978
  if (!bPre) return -1;
10779
10979
  return aPre < bPre ? -1 : aPre > bPre ? 1 : 0;
10780
10980
  }
10981
+ function detectInstallSource(bin) {
10982
+ const raw = bin ?? process.argv[1] ?? "";
10983
+ if (!raw) return "unknown";
10984
+ const norm = raw.replace(/\\/g, "/").toLowerCase();
10985
+ if (/\/_npx\//.test(norm)) return "npx";
10986
+ if (/\/\.pnpm\//.test(norm) && /dlx/i.test(norm)) return "npx";
10987
+ const ua = (process.env.npm_config_user_agent ?? "").toLowerCase();
10988
+ if (ua.includes("npx/")) return "npx";
10989
+ if (/\/\.bun\//.test(norm) || /\/bun\/install\//.test(norm)) return "bun";
10990
+ if (/\/pnpm\/global\//.test(norm) || /\/pnpm\/[^/]+\/node_modules\//.test(norm)) return "pnpm";
10991
+ if (/\/yarn\/global\//.test(norm) || /\/\.yarn\/global\//.test(norm)) return "yarn";
10992
+ if (/\/node_modules\/reasonix(\b|\/)/.test(norm)) return "npm";
10993
+ return "unknown";
10994
+ }
10781
10995
  function isNpxInstall() {
10782
- const bin = process.argv[1] ?? "";
10783
- if (/[/\\]_npx[/\\]/.test(bin)) return true;
10784
- if (/[/\\]\.pnpm[/\\]/.test(bin) && /dlx/i.test(bin)) return true;
10785
- const ua = process.env.npm_config_user_agent ?? "";
10786
- if (ua.includes("npx/")) return true;
10787
- return false;
10996
+ return detectInstallSource() === "npx";
10997
+ }
10998
+ function detectNpmInstallPrefix(bin) {
10999
+ const raw = bin ?? process.argv[1] ?? "";
11000
+ if (!raw) return null;
11001
+ const norm = raw.replace(/\\/g, "/");
11002
+ const posix = norm.match(/^(.+?)\/lib\/node_modules\/reasonix(?:\/|$)/i);
11003
+ if (posix) return posix[1] ?? null;
11004
+ const win = norm.match(/^(.+?)\/node_modules\/reasonix(?:\/|$)/i);
11005
+ if (win) return win[1] ?? null;
11006
+ return null;
10788
11007
  }
10789
11008
 
10790
11009
  // src/mcp/types.ts
@@ -12236,6 +12455,8 @@ export {
12236
12455
  defaultUsageLogPath,
12237
12456
  deleteSession,
12238
12457
  detectAtPicker,
12458
+ detectInstallSource,
12459
+ detectNpmInstallPrefix,
12239
12460
  detectShellOperator,
12240
12461
  diffTranscripts,
12241
12462
  expandAtMentions,
@@ -12267,6 +12488,7 @@ export {
12267
12488
  listFilesWithStatsSync,
12268
12489
  listSessions,
12269
12490
  loadApiKey,
12491
+ loadBaseUrl,
12270
12492
  loadDotenv,
12271
12493
  loadHooks,
12272
12494
  loadSessionMessages,
@@ -12311,6 +12533,7 @@ export {
12311
12533
  sanitizeMemoryName,
12312
12534
  sanitizeName as sanitizeSessionName,
12313
12535
  saveApiKey,
12536
+ saveBaseUrl,
12314
12537
  scavengeToolCalls,
12315
12538
  sessionPath,
12316
12539
  sessionsDir,