reasonix 0.37.0 → 0.38.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/README.zh-CN.md +1 -0
- package/dist/cli/{chat-7257YAPG.js → chat-FPEYKTMI.js} +13 -14
- package/dist/cli/{chunk-T52GAWPP.js → chunk-3VTV4WAH.js} +2 -2
- package/dist/cli/{chunk-MSKUP6PD.js → chunk-4PNXH2MH.js} +910 -659
- package/dist/cli/chunk-4PNXH2MH.js.map +1 -0
- package/dist/cli/{chunk-YER7WCHF.js → chunk-A63QT566.js} +24 -10
- package/dist/cli/chunk-A63QT566.js.map +1 -0
- package/dist/cli/{chunk-4Q3GRJIU.js → chunk-AATCLE5N.js} +2 -2
- package/dist/cli/{chunk-BHLHOS5Y.js → chunk-BW2HWSYH.js} +315 -5
- package/dist/cli/chunk-BW2HWSYH.js.map +1 -0
- package/dist/cli/{chunk-ZJR4QLXB.js → chunk-FB46F6H4.js} +2 -2
- package/dist/cli/{chunk-GKZJXYMY.js → chunk-FYKZB6TX.js} +415 -11
- package/dist/cli/chunk-FYKZB6TX.js.map +1 -0
- package/dist/cli/{chunk-XQIFIB3U.js → chunk-JOFZ6AW5.js} +2 -2
- package/dist/cli/{chunk-JGZKTAOH.js → chunk-LMNAMITH.js} +2 -2
- package/dist/cli/{chunk-S4GF3HPO.js → chunk-LY352GTC.js} +6 -4
- package/dist/cli/chunk-LY352GTC.js.map +1 -0
- package/dist/cli/{chunk-VF57YX2M.js → chunk-NYP2DDDV.js} +40 -1
- package/dist/cli/chunk-NYP2DDDV.js.map +1 -0
- package/dist/cli/{chunk-JULZ7JTO.js → chunk-T5U5JO7Q.js} +11 -8
- package/dist/cli/chunk-T5U5JO7Q.js.map +1 -0
- package/dist/cli/{chunk-SEFXUF24.js → chunk-YJKLNYCP.js} +113 -24
- package/dist/cli/chunk-YJKLNYCP.js.map +1 -0
- package/dist/cli/{code-64EG5IU2.js → code-GTE65OUT.js} +23 -17
- package/dist/cli/{code-64EG5IU2.js.map → code-GTE65OUT.js.map} +1 -1
- package/dist/cli/{commands-FE2UDFBC.js → commands-R4JWISND.js} +3 -4
- package/dist/cli/{commands-FE2UDFBC.js.map → commands-R4JWISND.js.map} +1 -1
- package/dist/cli/{commit-3IAGB22T.js → commit-TQ4DMUNS.js} +2 -3
- package/dist/cli/{commit-3IAGB22T.js.map → commit-TQ4DMUNS.js.map} +1 -1
- package/dist/cli/{doctor-BW5HSQDW.js → doctor-GGK2JKTA.js} +6 -7
- package/dist/cli/index.js +24 -25
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/{mcp-2RDEQST6.js → mcp-M7I23TQ7.js} +2 -3
- package/dist/cli/{mcp-2RDEQST6.js.map → mcp-M7I23TQ7.js.map} +1 -1
- package/dist/cli/{mcp-browse-VM5GLRBQ.js → mcp-browse-TWO7RYT4.js} +2 -3
- package/dist/cli/{mcp-browse-VM5GLRBQ.js.map → mcp-browse-TWO7RYT4.js.map} +1 -1
- package/dist/cli/{prompt-KGIUONO3.js → prompt-ODPFOKSH.js} +2 -2
- package/dist/cli/{replay-D7RT2DR7.js → replay-R3QRXPI2.js} +13 -9
- package/dist/cli/replay-R3QRXPI2.js.map +1 -0
- package/dist/cli/{run-RWCOA32G.js → run-WGSPYYOJ.js} +7 -8
- package/dist/cli/{run-RWCOA32G.js.map → run-WGSPYYOJ.js.map} +1 -1
- package/dist/cli/{server-6ZW4TQUP.js → server-IZPWQYG3.js} +8 -9
- package/dist/cli/{server-6ZW4TQUP.js.map → server-IZPWQYG3.js.map} +1 -1
- package/dist/cli/{sessions-5ISNWFMU.js → sessions-E4UH5JYL.js} +7 -8
- package/dist/cli/{sessions-5ISNWFMU.js.map → sessions-E4UH5JYL.js.map} +1 -1
- package/dist/cli/{setup-HJG23NKJ.js → setup-FTZNN3TZ.js} +60 -15
- package/dist/cli/setup-FTZNN3TZ.js.map +1 -0
- package/dist/cli/{version-BXAN7Q4V.js → version-MDVCFTKA.js} +7 -8
- package/dist/cli/{version-BXAN7Q4V.js.map → version-MDVCFTKA.js.map} +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.js +568 -40
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/cli/chunk-BHLHOS5Y.js.map +0 -1
- package/dist/cli/chunk-GKZJXYMY.js.map +0 -1
- package/dist/cli/chunk-JULZ7JTO.js.map +0 -1
- package/dist/cli/chunk-MSKUP6PD.js.map +0 -1
- package/dist/cli/chunk-S4GF3HPO.js.map +0 -1
- package/dist/cli/chunk-SEFXUF24.js.map +0 -1
- package/dist/cli/chunk-VF57YX2M.js.map +0 -1
- package/dist/cli/chunk-WUI3P4RA.js +0 -319
- package/dist/cli/chunk-WUI3P4RA.js.map +0 -1
- package/dist/cli/chunk-YER7WCHF.js.map +0 -1
- package/dist/cli/replay-D7RT2DR7.js.map +0 -1
- package/dist/cli/setup-HJG23NKJ.js.map +0 -1
- /package/dist/cli/{chat-7257YAPG.js.map → chat-FPEYKTMI.js.map} +0 -0
- /package/dist/cli/{chunk-T52GAWPP.js.map → chunk-3VTV4WAH.js.map} +0 -0
- /package/dist/cli/{chunk-4Q3GRJIU.js.map → chunk-AATCLE5N.js.map} +0 -0
- /package/dist/cli/{chunk-ZJR4QLXB.js.map → chunk-FB46F6H4.js.map} +0 -0
- /package/dist/cli/{chunk-XQIFIB3U.js.map → chunk-JOFZ6AW5.js.map} +0 -0
- /package/dist/cli/{chunk-JGZKTAOH.js.map → chunk-LMNAMITH.js.map} +0 -0
- /package/dist/cli/{doctor-BW5HSQDW.js.map → doctor-GGK2JKTA.js.map} +0 -0
- /package/dist/cli/{prompt-KGIUONO3.js.map → prompt-ODPFOKSH.js.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -980,6 +980,10 @@ var EN = {
|
|
|
980
980
|
title: "copy / paste",
|
|
981
981
|
rows: [
|
|
982
982
|
{ key: "select text", text: "drag to select \u2014 terminal-native (no modifier needed)" },
|
|
983
|
+
{
|
|
984
|
+
key: "/copy",
|
|
985
|
+
text: "vim/tmux-style copy mode \u2014 works in SSH/mosh/tmux where drag-select can't extend past the viewport"
|
|
986
|
+
},
|
|
983
987
|
{
|
|
984
988
|
key: "copy",
|
|
985
989
|
text: "Ctrl+Shift+C (Win/Linux) \xB7 Cmd+C (macOS) \u2014 or auto-copy-on-select if your terminal does it"
|
|
@@ -1062,6 +1066,9 @@ var EN = {
|
|
|
1062
1066
|
},
|
|
1063
1067
|
slash: {
|
|
1064
1068
|
help: { description: "show the full command reference" },
|
|
1069
|
+
copy: {
|
|
1070
|
+
description: "open vim/tmux-style copy mode \u2014 j/k navigate, v select, y yank to clipboard"
|
|
1071
|
+
},
|
|
1065
1072
|
status: { description: "current model, flags, context, session" },
|
|
1066
1073
|
preset: {
|
|
1067
1074
|
description: "model bundle \u2014 auto escalates flash \u2192 pro, flash/pro lock",
|
|
@@ -1069,6 +1076,10 @@ var EN = {
|
|
|
1069
1076
|
},
|
|
1070
1077
|
model: { description: "switch DeepSeek model id", argsHint: "<id>" },
|
|
1071
1078
|
models: { description: "list available models fetched from DeepSeek /models" },
|
|
1079
|
+
theme: {
|
|
1080
|
+
description: "show or persist the terminal theme preference. Bare opens picker.",
|
|
1081
|
+
argsHint: "[auto|default|dark|light|tokyo-night|github-dark|github-light|high-contrast]"
|
|
1082
|
+
},
|
|
1072
1083
|
language: {
|
|
1073
1084
|
description: "switch the runtime language",
|
|
1074
1085
|
argsHint: "<EN|zh-CN>",
|
|
@@ -1124,9 +1135,15 @@ var EN = {
|
|
|
1124
1135
|
context: { description: "show context-window breakdown (system / tools / log / input)" },
|
|
1125
1136
|
retry: { description: "truncate & resend your last message (fresh sample)" },
|
|
1126
1137
|
compact: {
|
|
1127
|
-
description: "
|
|
1138
|
+
description: "narrow oversized tool results + tool-call args in the log; cap at tokens, default 4000",
|
|
1128
1139
|
argsHint: "[tokens]"
|
|
1129
1140
|
},
|
|
1141
|
+
cwd: {
|
|
1142
|
+
description: "switch the workspace root mid-session \u2014 re-points fs / shell / memory tools, reloads project hooks, refreshes the at-mention walker",
|
|
1143
|
+
argsHint: "<path>"
|
|
1144
|
+
},
|
|
1145
|
+
stop: { description: "abort the current model turn (typed alternative to Esc)" },
|
|
1146
|
+
feedback: { description: "open a GitHub issue with diagnostic info copied to clipboard" },
|
|
1130
1147
|
keys: { description: "keyboard + mouse + copy/paste reference" },
|
|
1131
1148
|
plans: { description: "list this session's active + archived plans, newest first" },
|
|
1132
1149
|
replay: {
|
|
@@ -1202,6 +1219,9 @@ var EN = {
|
|
|
1202
1219
|
apiKeySavedLocally: "Saved locally to {path}",
|
|
1203
1220
|
apiKeyInputLabel: "key \u203A ",
|
|
1204
1221
|
apiKeyInvalid: "Key looks too short \u2014 paste the full token (16+ chars, no spaces).",
|
|
1222
|
+
apiKeyChecking: "Checking API key\u2026",
|
|
1223
|
+
apiKeyRejected: "DeepSeek rejected this API key. Paste a valid key, or press Esc to cancel setup.",
|
|
1224
|
+
apiKeyCheckFailed: "Could not verify this API key right now ({message}). Check your network or try again.",
|
|
1205
1225
|
apiKeyPreview: "preview: {redacted}",
|
|
1206
1226
|
themeTitle: "Choose a theme",
|
|
1207
1227
|
themeSubtitle: "Preview updates live as you navigate. Change later with /theme.",
|
|
@@ -1749,12 +1769,157 @@ var EN = {
|
|
|
1749
1769
|
waitingForResponse: "\u2026waiting for response\u2026",
|
|
1750
1770
|
hintSend: "send",
|
|
1751
1771
|
hintNewline: "newline",
|
|
1772
|
+
hintClear: "clear",
|
|
1752
1773
|
hintScroll: "scroll",
|
|
1753
1774
|
hintHistory: "history",
|
|
1754
1775
|
hintAbort: "abort",
|
|
1755
1776
|
hintQuit: "quit",
|
|
1756
1777
|
abortedHint: "turn aborted by user \xB7 esc again to clear \xB7 \u23CE to ask a follow-up"
|
|
1757
1778
|
},
|
|
1779
|
+
shellConfirm: {
|
|
1780
|
+
title: "Shell command",
|
|
1781
|
+
bgTitle: "Background process",
|
|
1782
|
+
subtitle: "model wants to run a shell command",
|
|
1783
|
+
bgSubtitle: "long-running process \u2014 keeps running after approval, /kill to stop",
|
|
1784
|
+
denyTitle: "Deny \u2014 provide context",
|
|
1785
|
+
optional: "optional",
|
|
1786
|
+
denyFooter: "type context \xB7 \u23CE submit with reason \xB7 esc skip (deny without reason)",
|
|
1787
|
+
awaiting: "awaiting",
|
|
1788
|
+
pickFooter: "\u2191\u2193 pick \xB7 \u23CE confirm \xB7 Tab add context \xB7 esc cancel",
|
|
1789
|
+
allowOnce: "allow once",
|
|
1790
|
+
allowOnceDesc: "run this command, ask again next time",
|
|
1791
|
+
allowAlways: "allow always",
|
|
1792
|
+
allowAlwaysDesc: "remember `{prefix}` for this project",
|
|
1793
|
+
deny: "deny",
|
|
1794
|
+
denyDesc: "press Tab to add context telling the model why"
|
|
1795
|
+
},
|
|
1796
|
+
editConfirm: {
|
|
1797
|
+
footer: "[y/Enter] apply \xB7 [n] reject with reason \xB7 [a] apply rest \xB7 [A] flip AUTO \xB7 [\u2191\u2193/Space] scroll \xB7 [Esc] abort",
|
|
1798
|
+
newTag: "NEW",
|
|
1799
|
+
editTag: "EDIT",
|
|
1800
|
+
linesCount: "-{removed} +{added} lines",
|
|
1801
|
+
viewingRange: "viewing {start}-{end}/{total}",
|
|
1802
|
+
denyFooter: "\u23CE submit \xB7 esc skip (deny without reason)",
|
|
1803
|
+
oldLabel: " - old",
|
|
1804
|
+
newLabel: " + new",
|
|
1805
|
+
sideBySide: " side-by-side \xB7 removed lines on the left, added on the right \xB7 paired by offset",
|
|
1806
|
+
linesAbove: " \u2191 {count} line above (\u2191/k or PgUp)",
|
|
1807
|
+
linesAbovePlural: " \u2191 {count} lines above (\u2191/k or PgUp)",
|
|
1808
|
+
linesBelow: " \u2193 {count} line below (\u2193/j or Space/PgDn)",
|
|
1809
|
+
linesBelowPlural: " \u2193 {count} lines below (\u2193/j or Space/PgDn)"
|
|
1810
|
+
},
|
|
1811
|
+
sessionPicker: {
|
|
1812
|
+
header: " \u25C8 REASONIX \xB7 pick a session ",
|
|
1813
|
+
title: "pick a session \u2014 {workspace}",
|
|
1814
|
+
messages: "{count} message",
|
|
1815
|
+
messagesPlural: "{count} messages",
|
|
1816
|
+
turns: "{count} turns",
|
|
1817
|
+
pickerHint: "\u2191\u2193 pick \xB7 \u23CE open \xB7 [n] new \xB7 [d] delete \xB7 [r] rename \xB7 esc quit",
|
|
1818
|
+
empty: " no saved sessions in this workspace yet \u2014 press ",
|
|
1819
|
+
emptyNew: " to start a new one",
|
|
1820
|
+
renamePrompt: ' rename "{from}" \u2192 ',
|
|
1821
|
+
renameHint: " \u23CE confirm rename \xB7 esc cancel",
|
|
1822
|
+
emptyHint: " \u23CE new session \xB7 esc quit",
|
|
1823
|
+
justNow: "just now",
|
|
1824
|
+
minAgo: "{count} min ago",
|
|
1825
|
+
yesterday: "yesterday",
|
|
1826
|
+
hoursAgo: "{count}h ago",
|
|
1827
|
+
daysAgo: "{count} days ago"
|
|
1828
|
+
},
|
|
1829
|
+
modelPicker: {
|
|
1830
|
+
header: " \u25C8 REASONIX \xB7 pick a setup ",
|
|
1831
|
+
loading: " \xB7 loading catalog\u2026",
|
|
1832
|
+
catalogEmpty: " \xB7 catalog empty \u2014 using known fallbacks",
|
|
1833
|
+
modelsAvailable: " \xB7 {count} models available",
|
|
1834
|
+
presetsHeader: " PRESETS \xB7 recommended \u2014 model + effort + auto-escalate",
|
|
1835
|
+
modelsHeader: " MODELS \xB7 raw pick \u2014 auto-escalate stays as-is",
|
|
1836
|
+
pickerFooter: " \u2191\u2193 pick \xB7 \u23CE confirm \xB7 [r] refresh \xB7 esc cancel",
|
|
1837
|
+
currentLabel: " \xB7 current"
|
|
1838
|
+
},
|
|
1839
|
+
slashSuggestions: {
|
|
1840
|
+
noMatch: "no slash command matches that prefix",
|
|
1841
|
+
backspaceHint: " \u2014 Backspace to edit, or /help for the full list",
|
|
1842
|
+
commandCount: "{count} command",
|
|
1843
|
+
commandCountPlural: "{count} commands",
|
|
1844
|
+
aboveLabel: " \u2191 {count} above",
|
|
1845
|
+
belowLabel: " \u2193 {count} below",
|
|
1846
|
+
advancedHint: " + {count} advanced \xB7 type a letter to search",
|
|
1847
|
+
footerHint: " \u2191\u2193 navigate \xB7 Tab / \u23CE pick \xB7 esc cancel",
|
|
1848
|
+
groupChat: "CHAT",
|
|
1849
|
+
groupSetup: "SETUP",
|
|
1850
|
+
groupInfo: "INFO",
|
|
1851
|
+
groupSession: "SESSION",
|
|
1852
|
+
groupExtend: "EXTEND",
|
|
1853
|
+
groupCode: "CODE",
|
|
1854
|
+
groupJobs: "JOBS",
|
|
1855
|
+
groupAdvanced: "ADVANCED"
|
|
1856
|
+
},
|
|
1857
|
+
atMentions: {
|
|
1858
|
+
loading: "loading\u2026",
|
|
1859
|
+
entrySingular: "{count} entry",
|
|
1860
|
+
entryPlural: "{count} entries",
|
|
1861
|
+
searching: "searching\u2026",
|
|
1862
|
+
scanned: "scanned",
|
|
1863
|
+
match: "match",
|
|
1864
|
+
matches: "matches",
|
|
1865
|
+
forFilter: 'for "{filter}"',
|
|
1866
|
+
noMatch: 'no files match "{filter}"',
|
|
1867
|
+
emptyDir: "empty directory",
|
|
1868
|
+
scanning: "scanning the tree\u2026",
|
|
1869
|
+
footerBrowse: "\u2191\u2193 navigate \xB7 Tab drill into folder \xB7 \u23CE insert \xB7 esc cancel",
|
|
1870
|
+
footerBrowseSearch: "\u2191\u2193 navigate \xB7 Tab / \u23CE insert as @path \xB7 esc cancel",
|
|
1871
|
+
footerInsert: "\u2191\u2193 navigate \xB7 Tab / \u23CE insert as @path \xB7 esc cancel"
|
|
1872
|
+
},
|
|
1873
|
+
statsPanel: {
|
|
1874
|
+
modePlan: "PLAN",
|
|
1875
|
+
modeYolo: "yolo",
|
|
1876
|
+
modeAuto: "auto",
|
|
1877
|
+
modeReview: "review",
|
|
1878
|
+
pro: "\u21E7 pro",
|
|
1879
|
+
budget: " budget "
|
|
1880
|
+
},
|
|
1881
|
+
welcomeBanner: {
|
|
1882
|
+
workspace: "\u25B8 workspace",
|
|
1883
|
+
relaunchHint: " (relaunch with --dir <path> to switch)",
|
|
1884
|
+
dashboard: "\u25B8 web"
|
|
1885
|
+
},
|
|
1886
|
+
ctxBreakdown: {
|
|
1887
|
+
title: "\u25A3 context",
|
|
1888
|
+
compactHint: " /compact folds (auto at 50%) \xB7 /new wipes log",
|
|
1889
|
+
topTools: " top tool results by cost ({count}):",
|
|
1890
|
+
msg: "msg",
|
|
1891
|
+
turnLabel: "turn"
|
|
1892
|
+
},
|
|
1893
|
+
startup: {
|
|
1894
|
+
codeRooted: '\u25B8 reasonix code: rooted at {rootDir}, session "{session}" \xB7 {tools} native tool(s){semantic}',
|
|
1895
|
+
ephemeral: "(ephemeral)",
|
|
1896
|
+
semanticOn: " \xB7 semantic_search on"
|
|
1897
|
+
},
|
|
1898
|
+
doctorErrors: {
|
|
1899
|
+
unreadable: "{path} unreadable \u2014 {message}",
|
|
1900
|
+
cannotList: "cannot list \u2014 {message}",
|
|
1901
|
+
parseFailed: "couldn't parse settings.json \u2014 {message}",
|
|
1902
|
+
probeFailed: "probe failed \u2014 {message}"
|
|
1903
|
+
},
|
|
1904
|
+
webErrors: {
|
|
1905
|
+
status: "web_search {status}",
|
|
1906
|
+
mojeekBlocked: "web_search: Mojeek anti-bot page \u2014 rate-limited or blocked",
|
|
1907
|
+
mojeekNoResults: "web_search: 0 results but response doesn't look like a real empty page ({chars} chars, first 120: {preview})",
|
|
1908
|
+
invalidEndpoint: 'web_search: invalid SearXNG endpoint "{endpoint}"',
|
|
1909
|
+
endpointMustBeHttp: "web_search: SearXNG endpoint must be http(s), got {protocol}",
|
|
1910
|
+
cannotReach: "web_search: Cannot reach SearXNG server at {endpoint}. Please install SearXNG (https://github.com/searxng/searxng) and start it (e.g. `docker run -d -p 8080:8080 searxng/searxng`), or switch to the default engine with /search-engine mojeek.",
|
|
1911
|
+
searxngNoResults: "web_search: 0 results but SearXNG response doesn't look like an empty results page ({chars} chars)",
|
|
1912
|
+
fetchStatus: "web_fetch {status} for {url}",
|
|
1913
|
+
fetchTooLarge: "web_fetch refused: content-length {len} bytes exceeds {cap}-byte cap ({url})",
|
|
1914
|
+
fetchBodyTooLarge: "web_fetch refused: response body exceeded {cap}-byte cap ({seen} bytes seen)",
|
|
1915
|
+
fetchInvalidUrl: "web_fetch: url must start with http:// or https://"
|
|
1916
|
+
},
|
|
1917
|
+
choiceConfirm: {
|
|
1918
|
+
customLabel: "Let me type my own answer",
|
|
1919
|
+
customDesc: "None of the above fits \u2014 type a free-form reply. The model reads it verbatim.",
|
|
1920
|
+
cancelLabel: "Cancel \u2014 drop the question",
|
|
1921
|
+
cancelDesc: "Model stops and asks what you want instead."
|
|
1922
|
+
},
|
|
1758
1923
|
cardTitles: {
|
|
1759
1924
|
usage: "usage",
|
|
1760
1925
|
context: "context",
|
|
@@ -1764,7 +1929,9 @@ var EN = {
|
|
|
1764
1929
|
reasoning: "reasoning",
|
|
1765
1930
|
reasoningAborted: "reasoning (aborted)",
|
|
1766
1931
|
reasoningEllipsis: "reasoning\u2026",
|
|
1767
|
-
error: "error"
|
|
1932
|
+
error: "error",
|
|
1933
|
+
doctor: "doctor",
|
|
1934
|
+
you: "you"
|
|
1768
1935
|
},
|
|
1769
1936
|
cardLabels: {
|
|
1770
1937
|
prompt: "prompt",
|
|
@@ -1803,7 +1970,42 @@ var EN = {
|
|
|
1803
1970
|
retries: "retries",
|
|
1804
1971
|
reasoningLabel: "reasoning \xB7 {count} \xB6",
|
|
1805
1972
|
runningLabel: "running",
|
|
1806
|
-
workingLabel: "working"
|
|
1973
|
+
workingLabel: "working",
|
|
1974
|
+
defaultFooter: "\u2191\u2193 pick \xB7 \u23CE confirm \xB7 esc cancel",
|
|
1975
|
+
applyAction: "[a] apply",
|
|
1976
|
+
skipAction: "[s] skip",
|
|
1977
|
+
rejectAction: "[r] reject",
|
|
1978
|
+
levelOk: "OK",
|
|
1979
|
+
levelWarn: "warn",
|
|
1980
|
+
levelFail: "FAIL",
|
|
1981
|
+
checksLabel: "checks",
|
|
1982
|
+
passed: "passed",
|
|
1983
|
+
warnTag: "warn",
|
|
1984
|
+
failTag: "fail",
|
|
1985
|
+
stepLabel: "step",
|
|
1986
|
+
done: "done",
|
|
1987
|
+
inProgress: "\u2190 in progress",
|
|
1988
|
+
upcoming: "upcoming",
|
|
1989
|
+
resumed: "resumed \xB7 ",
|
|
1990
|
+
archive: "\u23EA archive \xB7 ",
|
|
1991
|
+
more: "\u22EE +{count} more",
|
|
1992
|
+
categoryUser: "user",
|
|
1993
|
+
categoryFeedback: "feedback",
|
|
1994
|
+
categoryProject: "project",
|
|
1995
|
+
categoryReference: "reference"
|
|
1996
|
+
},
|
|
1997
|
+
copyMode: {
|
|
1998
|
+
title: "\u2500\u2500 COPY MODE \u2500\u2500",
|
|
1999
|
+
help: "j/k or \u2191/\u2193 move \xB7 v select \xB7 y yank \xB7 g/G top/bottom \xB7 q quit",
|
|
2000
|
+
statusBar: "line {cur}/{total} \xB7 selection: {sel}",
|
|
2001
|
+
statusYanked: "yanked {size} chars (osc52={osc52})",
|
|
2002
|
+
statusEmpty: "nothing selected",
|
|
2003
|
+
empty: "(no chat content yet \u2014 say something to the model first)",
|
|
2004
|
+
labelUser: "you",
|
|
2005
|
+
labelAssistant: "assistant",
|
|
2006
|
+
labelReasoning: "reasoning",
|
|
2007
|
+
yankedToast: "\u25B8 copied {size} chars to clipboard (osc52)",
|
|
2008
|
+
yankedToastFile: "\u25B8 copied {size} chars \xB7 file: {path}"
|
|
1807
2009
|
}
|
|
1808
2010
|
};
|
|
1809
2011
|
|
|
@@ -1930,6 +2132,10 @@ var zhCN = {
|
|
|
1930
2132
|
title: "\u590D\u5236 / \u7C98\u8D34",
|
|
1931
2133
|
rows: [
|
|
1932
2134
|
{ 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" },
|
|
2135
|
+
{
|
|
2136
|
+
key: "/copy",
|
|
2137
|
+
text: "vim/tmux \u98CE\u683C\u590D\u5236\u6A21\u5F0F \u2014 SSH / mosh / tmux \u4E0B\u62D6\u9009\u8D8A\u8FC7\u53EF\u89C6\u533A\u65E0\u6548\u65F6\u7528\u8FD9\u4E2A"
|
|
2138
|
+
},
|
|
1933
2139
|
{
|
|
1934
2140
|
key: "\u590D\u5236",
|
|
1935
2141
|
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"
|
|
@@ -2012,6 +2218,9 @@ var zhCN = {
|
|
|
2012
2218
|
},
|
|
2013
2219
|
slash: {
|
|
2014
2220
|
help: { description: "\u663E\u793A\u5B8C\u6574\u547D\u4EE4\u53C2\u8003" },
|
|
2221
|
+
copy: {
|
|
2222
|
+
description: "\u8FDB\u5165 vim/tmux \u98CE\u683C\u590D\u5236\u6A21\u5F0F \u2014 j/k \u79FB\u52A8\u3001v \u8D77\u9009\u533A\u3001y \u590D\u5236\u5230\u526A\u8D34\u677F"
|
|
2223
|
+
},
|
|
2015
2224
|
status: { description: "\u5F53\u524D\u6A21\u578B\u3001\u6807\u5FD7\u3001\u4E0A\u4E0B\u6587\u3001\u4F1A\u8BDD" },
|
|
2016
2225
|
preset: {
|
|
2017
2226
|
description: "\u6A21\u578B\u7EC4\u5408 \u2014 \u81EA\u52A8\u5728 flash \u2192 pro \u4E4B\u95F4\u5207\u6362\uFF0C\u6216\u9501\u5B9A flash/pro",
|
|
@@ -2019,6 +2228,10 @@ var zhCN = {
|
|
|
2019
2228
|
},
|
|
2020
2229
|
model: { description: "\u5207\u6362 DeepSeek \u6A21\u578B ID", argsHint: "<id>" },
|
|
2021
2230
|
models: { description: "\u5217\u51FA\u4ECE DeepSeek /models \u83B7\u53D6\u7684\u53EF\u7528\u6A21\u578B" },
|
|
2231
|
+
theme: {
|
|
2232
|
+
description: "\u663E\u793A\u6216\u6301\u4E45\u5316\u7EC8\u7AEF\u4E3B\u9898\u504F\u597D\u3002\u65E0\u53C2\u6570\u65F6\u6253\u5F00\u9009\u62E9\u5668\u3002",
|
|
2233
|
+
argsHint: "[auto|default|dark|light|tokyo-night|github-dark|github-light|high-contrast]"
|
|
2234
|
+
},
|
|
2022
2235
|
language: {
|
|
2023
2236
|
description: "\u5207\u6362\u8FD0\u884C\u65F6\u8BED\u8A00",
|
|
2024
2237
|
argsHint: "<en|zh-CN>",
|
|
@@ -2080,6 +2293,12 @@ var zhCN = {
|
|
|
2080
2293
|
argsHint: "[tokens]"
|
|
2081
2294
|
},
|
|
2082
2295
|
keys: { description: "\u952E\u76D8 + \u9F20\u6807 + \u590D\u5236\u7C98\u8D34\u53C2\u8003" },
|
|
2296
|
+
cwd: {
|
|
2297
|
+
description: "\u5207\u6362\u5DE5\u4F5C\u533A\u6839\u76EE\u5F55 \u2014 \u91CD\u65B0\u6307\u5411\u6587\u4EF6/Shell/\u8BB0\u5FC6\u5DE5\u5177\uFF0C\u91CD\u8F7D\u9879\u76EE hooks\uFF0C\u5237\u65B0 @ \u5F15\u7528\u904D\u5386\u5668",
|
|
2298
|
+
argsHint: "<path>"
|
|
2299
|
+
},
|
|
2300
|
+
stop: { description: "\u4E2D\u6B62\u5F53\u524D\u6A21\u578B\u56DE\u5408\uFF08\u6309 Esc \u7684\u66FF\u4EE3\u65B9\u5F0F\uFF09" },
|
|
2301
|
+
feedback: { description: "\u6253\u5F00 GitHub Issue\uFF0C\u8BCA\u65AD\u4FE1\u606F\u5DF2\u590D\u5236\u5230\u526A\u8D34\u677F" },
|
|
2083
2302
|
plans: { description: "\u5217\u51FA\u6B64\u4F1A\u8BDD\u7684\u6D3B\u8DC3 + \u5F52\u6863\u8BA1\u5212\uFF08\u6700\u65B0\u5728\u524D\uFF09" },
|
|
2084
2303
|
replay: {
|
|
2085
2304
|
description: "\u52A0\u8F7D\u5F52\u6863\u8BA1\u5212\u4E3A\u53EA\u8BFB\u7684\u65F6\u95F4\u65C5\u884C\u5FEB\u7167\uFF08\u9ED8\u8BA4\uFF1A\u6700\u65B0\uFF09",
|
|
@@ -2156,6 +2375,9 @@ var zhCN = {
|
|
|
2156
2375
|
apiKeySavedLocally: "\u4FDD\u5B58\u5728\u672C\u5730\uFF1A{path}",
|
|
2157
2376
|
apiKeyInputLabel: "key \u203A ",
|
|
2158
2377
|
apiKeyInvalid: "key \u957F\u5EA6\u4E0D\u8DB3\u2014\u2014\u8BF7\u7C98\u8D34\u5B8C\u6574 token\uFF0816+ \u5B57\u7B26\uFF0C\u4E0D\u542B\u7A7A\u683C\uFF09\u3002",
|
|
2378
|
+
apiKeyChecking: "\u6B63\u5728\u68C0\u67E5 API key\u2026",
|
|
2379
|
+
apiKeyRejected: "DeepSeek \u62D2\u7EDD\u4E86\u8FD9\u4E2A API key\u3002\u8BF7\u7C98\u8D34\u6709\u6548 key\uFF0C\u6216\u6309 Esc \u53D6\u6D88\u8BBE\u7F6E\u3002",
|
|
2380
|
+
apiKeyCheckFailed: "\u6682\u65F6\u65E0\u6CD5\u9A8C\u8BC1 API key\uFF08{message}\uFF09\u3002\u8BF7\u68C0\u67E5\u7F51\u7EDC\u540E\u91CD\u8BD5\u3002",
|
|
2159
2381
|
apiKeyPreview: "\u9884\u89C8\uFF1A{redacted}",
|
|
2160
2382
|
themeTitle: "\u9009\u62E9\u4E3B\u9898",
|
|
2161
2383
|
themeSubtitle: "\u65B9\u5411\u952E\u5207\u6362\u65F6\u5373\u65F6\u9884\u89C8\u6548\u679C\uFF0C\u4E4B\u540E\u53EF\u7528 /theme \u66F4\u6539\u3002",
|
|
@@ -2689,10 +2911,10 @@ var zhCN = {
|
|
|
2689
2911
|
plan: "\u8BA1\u5212",
|
|
2690
2912
|
yolo: "\u81EA\u7531",
|
|
2691
2913
|
auto: "\u81EA\u52A8",
|
|
2692
|
-
review: "\u5BA1\
|
|
2693
|
-
writesGated: " \u5199\u5165
|
|
2914
|
+
review: "\u5BA1\u67E5",
|
|
2915
|
+
writesGated: " \u5DF2\u9650\u5236\u5199\u5165 \xB7 /plan off \u89E3\u9664",
|
|
2694
2916
|
editsShellAuto: "\u7F16\u8F91 + Shell \u81EA\u52A8 \xB7 /undo \u53EF\u56DE\u6EDA",
|
|
2695
|
-
editsLandNow: "\u7F16\u8F91\
|
|
2917
|
+
editsLandNow: "\u7F16\u8F91\u5DF2\u751F\u6548 \xB7 \u6309 u \u64A4\u6D88",
|
|
2696
2918
|
queuedApplyDiscard: "{count} \u4E2A\u5F85\u5904\u7406 \xB7 y \u5E94\u7528 \xB7 n \u4E22\u5F03",
|
|
2697
2919
|
editsQueued: "\u7F16\u8F91\u5DF2\u6392\u961F \xB7 y \u5E94\u7528 \xB7 n \u4E22\u5F03",
|
|
2698
2920
|
shiftTabFlip: " {mid} \xB7 Shift+Tab \u5207\u6362",
|
|
@@ -2703,12 +2925,157 @@ var zhCN = {
|
|
|
2703
2925
|
waitingForResponse: "\u2026\u7B49\u5F85\u54CD\u5E94\u2026",
|
|
2704
2926
|
hintSend: "\u53D1\u9001",
|
|
2705
2927
|
hintNewline: "\u6362\u884C",
|
|
2928
|
+
hintClear: "\u6E05\u7A7A",
|
|
2706
2929
|
hintScroll: "\u6EDA\u52A8",
|
|
2707
2930
|
hintHistory: "\u5386\u53F2",
|
|
2708
2931
|
hintAbort: "\u4E2D\u6B62",
|
|
2709
2932
|
hintQuit: "\u9000\u51FA",
|
|
2710
2933
|
abortedHint: "\u7528\u6237\u5DF2\u4E2D\u6B62\u672C\u8F6E \xB7 \u518D\u6309 Esc \u6E05\u9664 \xB7 \u23CE \u7EE7\u7EED\u63D0\u95EE"
|
|
2711
2934
|
},
|
|
2935
|
+
shellConfirm: {
|
|
2936
|
+
title: "Shell \u547D\u4EE4",
|
|
2937
|
+
bgTitle: "\u540E\u53F0\u8FDB\u7A0B",
|
|
2938
|
+
subtitle: "\u6A21\u578B\u8BF7\u6C42\u6267\u884C Shell \u547D\u4EE4",
|
|
2939
|
+
bgSubtitle: "\u957F\u65F6\u95F4\u8FD0\u884C \u2014 \u6279\u51C6\u540E\u6301\u7EED\u8FD0\u884C\uFF0C/kill \u53EF\u505C\u6B62",
|
|
2940
|
+
denyTitle: "\u62D2\u7EDD \u2014 \u63D0\u4F9B\u539F\u56E0",
|
|
2941
|
+
optional: "\u53EF\u9009",
|
|
2942
|
+
denyFooter: "\u8F93\u5165\u539F\u56E0 \xB7 \u23CE \u63D0\u4EA4 \xB7 Esc \u8DF3\u8FC7\uFF08\u76F4\u63A5\u62D2\u7EDD\uFF09",
|
|
2943
|
+
awaiting: "\u7B49\u5F85\u4E2D",
|
|
2944
|
+
pickFooter: "\u2191\u2193 \u9009\u62E9 \xB7 \u23CE \u786E\u8BA4 \xB7 Tab \u6DFB\u52A0\u8BF4\u660E \xB7 Esc \u53D6\u6D88",
|
|
2945
|
+
allowOnce: "\u5141\u8BB8\u4E00\u6B21",
|
|
2946
|
+
allowOnceDesc: "\u6267\u884C\u6B64\u547D\u4EE4\uFF0C\u4E0B\u6B21\u518D\u95EE",
|
|
2947
|
+
allowAlways: "\u59CB\u7EC8\u5141\u8BB8",
|
|
2948
|
+
allowAlwaysDesc: "\u8BB0\u4F4F `{prefix}`\uFF0C\u672C\u9879\u76EE\u5185\u4E0D\u518D\u8BE2\u95EE",
|
|
2949
|
+
deny: "\u62D2\u7EDD",
|
|
2950
|
+
denyDesc: "\u6309 Tab \u6DFB\u52A0\u8BF4\u660E\uFF0C\u544A\u8BC9\u6A21\u578B\u539F\u56E0"
|
|
2951
|
+
},
|
|
2952
|
+
editConfirm: {
|
|
2953
|
+
footer: "[y/Enter] \u5E94\u7528 \xB7 [n] \u62D2\u7EDD\u5E76\u8BF4\u660E \xB7 [a] \u5E94\u7528\u5269\u4F59 \xB7 [A] \u5207\u6362 AUTO \xB7 [\u2191\u2193/Space] \u6EDA\u52A8 \xB7 [Esc] \u4E2D\u6B62",
|
|
2954
|
+
newTag: "\u65B0\u589E",
|
|
2955
|
+
editTag: "\u7F16\u8F91",
|
|
2956
|
+
linesCount: "-{removed} +{added} \u884C",
|
|
2957
|
+
viewingRange: "\u6B63\u5728\u67E5\u770B {start}-{end}/{total}",
|
|
2958
|
+
denyFooter: "\u23CE \u63D0\u4EA4 \xB7 Esc \u8DF3\u8FC7\uFF08\u76F4\u63A5\u62D2\u7EDD\uFF09",
|
|
2959
|
+
oldLabel: " \u65E7\u5185\u5BB9",
|
|
2960
|
+
newLabel: " \u65B0\u5185\u5BB9",
|
|
2961
|
+
sideBySide: " \u5DE6\u53F3\u5BF9\u6BD4 \xB7 \u5DE6\u4FA7\u5220\u9664\uFF0C\u53F3\u4FA7\u65B0\u589E \xB7 \u6309\u504F\u79FB\u914D\u5BF9",
|
|
2962
|
+
linesAbove: " \u2191 \u4E0A\u65B9 {count} \u884C\uFF08\u2191/k \u6216 PgUp\uFF09",
|
|
2963
|
+
linesAbovePlural: " \u2191 \u4E0A\u65B9 {count} \u884C\uFF08\u2191/k \u6216 PgUp\uFF09",
|
|
2964
|
+
linesBelow: " \u2193 \u4E0B\u65B9 {count} \u884C\uFF08\u2193/j \u6216 Space/PgDn\uFF09",
|
|
2965
|
+
linesBelowPlural: " \u2193 \u4E0B\u65B9 {count} \u884C\uFF08\u2193/j \u6216 Space/PgDn\uFF09"
|
|
2966
|
+
},
|
|
2967
|
+
sessionPicker: {
|
|
2968
|
+
header: " \u25C8 REASONIX \xB7 \u9009\u62E9\u4F1A\u8BDD ",
|
|
2969
|
+
title: "\u9009\u62E9\u4F1A\u8BDD \u2014 {workspace}",
|
|
2970
|
+
messages: "{count} \u6761\u6D88\u606F",
|
|
2971
|
+
messagesPlural: "{count} \u6761\u6D88\u606F",
|
|
2972
|
+
turns: "{count} \u8F6E",
|
|
2973
|
+
pickerHint: "\u2191\u2193 \u9009\u62E9 \xB7 \u23CE \u6253\u5F00 \xB7 [n] \u65B0\u5EFA \xB7 [d] \u5220\u9664 \xB7 [r] \u91CD\u547D\u540D \xB7 Esc \u9000\u51FA",
|
|
2974
|
+
empty: " \u6B64\u5DE5\u4F5C\u533A\u6682\u65E0\u5DF2\u4FDD\u5B58\u7684\u4F1A\u8BDD \u2014 \u6309 ",
|
|
2975
|
+
emptyNew: " \u5F00\u59CB\u65B0\u4F1A\u8BDD",
|
|
2976
|
+
renamePrompt: ' \u91CD\u547D\u540D "{from}" \u2192 ',
|
|
2977
|
+
renameHint: " \u23CE \u786E\u8BA4\u91CD\u547D\u540D \xB7 Esc \u53D6\u6D88",
|
|
2978
|
+
emptyHint: " \u23CE \u65B0\u5EFA\u4F1A\u8BDD \xB7 Esc \u9000\u51FA",
|
|
2979
|
+
justNow: "\u521A\u521A",
|
|
2980
|
+
minAgo: "{count} \u5206\u949F\u524D",
|
|
2981
|
+
yesterday: "\u6628\u5929",
|
|
2982
|
+
hoursAgo: "{count} \u5C0F\u65F6\u524D",
|
|
2983
|
+
daysAgo: "{count} \u5929\u524D"
|
|
2984
|
+
},
|
|
2985
|
+
modelPicker: {
|
|
2986
|
+
header: " \u25C8 REASONIX \xB7 \u9009\u62E9\u914D\u7F6E ",
|
|
2987
|
+
loading: " \xB7 \u52A0\u8F7D\u76EE\u5F55\u2026",
|
|
2988
|
+
catalogEmpty: " \xB7 \u76EE\u5F55\u4E3A\u7A7A \u2014 \u4F7F\u7528\u5DF2\u77E5\u5907\u9009",
|
|
2989
|
+
modelsAvailable: " \xB7 {count} \u4E2A\u6A21\u578B\u53EF\u7528",
|
|
2990
|
+
presetsHeader: " \u9884\u8BBE \xB7 \u63A8\u8350 \u2014 \u6A21\u578B + \u5F3A\u5EA6 + \u81EA\u52A8\u5347\u7EA7",
|
|
2991
|
+
modelsHeader: " \u6A21\u578B \xB7 \u76F4\u63A5\u9009\u62E9 \u2014 \u81EA\u52A8\u5347\u7EA7\u4FDD\u6301\u4E0D\u53D8",
|
|
2992
|
+
pickerFooter: " \u2191\u2193 \u9009\u62E9 \xB7 \u23CE \u786E\u8BA4 \xB7 [r] \u5237\u65B0 \xB7 Esc \u53D6\u6D88",
|
|
2993
|
+
currentLabel: " \xB7 \u5F53\u524D"
|
|
2994
|
+
},
|
|
2995
|
+
slashSuggestions: {
|
|
2996
|
+
noMatch: "\u6CA1\u6709\u5339\u914D\u6B64\u524D\u7F00\u7684\u659C\u6760\u547D\u4EE4",
|
|
2997
|
+
backspaceHint: " \u2014 \u6309 Backspace \u4FEE\u6539\uFF0C\u6216 /help \u67E5\u770B\u5B8C\u6574\u5217\u8868",
|
|
2998
|
+
commandCount: "{count} \u4E2A\u547D\u4EE4",
|
|
2999
|
+
commandCountPlural: "{count} \u4E2A\u547D\u4EE4",
|
|
3000
|
+
aboveLabel: " \u2191 {count} \u4E2A\u4EE5\u4E0A",
|
|
3001
|
+
belowLabel: " \u2193 {count} \u4E2A\u4EE5\u4E0B",
|
|
3002
|
+
advancedHint: " + {count} \u4E2A\u9AD8\u7EA7\u547D\u4EE4 \xB7 \u8F93\u5165\u5B57\u6BCD\u641C\u7D22",
|
|
3003
|
+
footerHint: " \u2191\u2193 \u5BFC\u822A \xB7 Tab / \u23CE \u9009\u62E9 \xB7 Esc \u53D6\u6D88",
|
|
3004
|
+
groupChat: "\u804A\u5929",
|
|
3005
|
+
groupSetup: "\u8BBE\u7F6E",
|
|
3006
|
+
groupInfo: "\u4FE1\u606F",
|
|
3007
|
+
groupSession: "\u4F1A\u8BDD",
|
|
3008
|
+
groupExtend: "\u6269\u5C55",
|
|
3009
|
+
groupCode: "\u4EE3\u7801",
|
|
3010
|
+
groupJobs: "\u4EFB\u52A1",
|
|
3011
|
+
groupAdvanced: "\u9AD8\u7EA7"
|
|
3012
|
+
},
|
|
3013
|
+
atMentions: {
|
|
3014
|
+
loading: "\u52A0\u8F7D\u4E2D\u2026",
|
|
3015
|
+
entrySingular: "{count} \u6761",
|
|
3016
|
+
entryPlural: "{count} \u6761",
|
|
3017
|
+
searching: "\u641C\u7D22\u4E2D\u2026",
|
|
3018
|
+
scanned: "\u5DF2\u626B\u63CF",
|
|
3019
|
+
match: "\u4E2A\u5339\u914D",
|
|
3020
|
+
matches: "\u4E2A\u5339\u914D",
|
|
3021
|
+
forFilter: '\u5339\u914D "{filter}"',
|
|
3022
|
+
noMatch: '\u6CA1\u6709\u5339\u914D "{filter}" \u7684\u6587\u4EF6',
|
|
3023
|
+
emptyDir: "\u7A7A\u76EE\u5F55",
|
|
3024
|
+
scanning: "\u6B63\u5728\u626B\u63CF\u76EE\u5F55\u6811\u2026",
|
|
3025
|
+
footerBrowse: "\u2191\u2193 \u5BFC\u822A \xB7 Tab \u8FDB\u5165\u6587\u4EF6\u5939 \xB7 \u23CE \u63D2\u5165 \xB7 Esc \u53D6\u6D88",
|
|
3026
|
+
footerBrowseSearch: "\u2191\u2193 \u5BFC\u822A \xB7 Tab / \u23CE \u4EE5 @path \u63D2\u5165 \xB7 Esc \u53D6\u6D88",
|
|
3027
|
+
footerInsert: "\u2191\u2193 \u5BFC\u822A \xB7 Tab / \u23CE \u4EE5 @path \u63D2\u5165 \xB7 Esc \u53D6\u6D88"
|
|
3028
|
+
},
|
|
3029
|
+
statsPanel: {
|
|
3030
|
+
modePlan: "\u8BA1\u5212",
|
|
3031
|
+
modeYolo: "\u81EA\u7531",
|
|
3032
|
+
modeAuto: "\u81EA\u52A8",
|
|
3033
|
+
modeReview: "\u5BA1\u67E5",
|
|
3034
|
+
pro: "\u21E7 \u4E13\u4E1A",
|
|
3035
|
+
budget: " \u9884\u7B97 "
|
|
3036
|
+
},
|
|
3037
|
+
welcomeBanner: {
|
|
3038
|
+
workspace: "\u25B8 \u5DE5\u4F5C\u533A",
|
|
3039
|
+
relaunchHint: "\uFF08\u91CD\u542F\u65F6\u7528 --dir <path> \u5207\u6362\uFF09",
|
|
3040
|
+
dashboard: "\u25B8 \u7F51\u9875"
|
|
3041
|
+
},
|
|
3042
|
+
ctxBreakdown: {
|
|
3043
|
+
title: "\u25A3 \u4E0A\u4E0B\u6587",
|
|
3044
|
+
compactHint: " /compact \u6298\u53E0\uFF08\u8D85\u8FC7 50% \u81EA\u52A8\u89E6\u53D1\uFF09\xB7 /new \u6E05\u7A7A\u65E5\u5FD7",
|
|
3045
|
+
topTools: " \u5E38\u7528\u5DE5\u5177\uFF08\u6309\u6210\u672C\u6392\u5E8F\uFF0C{count} \u4E2A\uFF09\uFF1A",
|
|
3046
|
+
msg: "\u6761",
|
|
3047
|
+
turnLabel: "\u8F6E"
|
|
3048
|
+
},
|
|
3049
|
+
startup: {
|
|
3050
|
+
codeRooted: '\u25B8 reasonix code\uFF1A\u6839\u76EE\u5F55 {rootDir}\uFF0C\u4F1A\u8BDD "{session}" \xB7 {tools} \u4E2A\u539F\u751F\u5DE5\u5177{semantic}',
|
|
3051
|
+
ephemeral: "\uFF08\u4E34\u65F6\uFF09",
|
|
3052
|
+
semanticOn: " \xB7 \u8BED\u4E49\u641C\u7D22\u5DF2\u5F00\u542F"
|
|
3053
|
+
},
|
|
3054
|
+
doctorErrors: {
|
|
3055
|
+
unreadable: "{path} \u65E0\u6CD5\u8BFB\u53D6 \u2014 {message}",
|
|
3056
|
+
cannotList: "\u65E0\u6CD5\u5217\u51FA \u2014 {message}",
|
|
3057
|
+
parseFailed: "\u65E0\u6CD5\u89E3\u6790 settings.json \u2014 {message}",
|
|
3058
|
+
probeFailed: "\u63A2\u6D4B\u5931\u8D25 \u2014 {message}"
|
|
3059
|
+
},
|
|
3060
|
+
webErrors: {
|
|
3061
|
+
status: "web_search \u72B6\u6001\u7801 {status}",
|
|
3062
|
+
mojeekBlocked: "web_search: Mojeek \u53CD\u722C\u9875\u9762 \u2014 \u9891\u7387\u9650\u5236\u6216\u88AB\u5C4F\u853D",
|
|
3063
|
+
mojeekNoResults: "web_search: \u8FD4\u56DE 0 \u6761\u7ED3\u679C\u4F46\u54CD\u5E94\u770B\u8D77\u6765\u4E0D\u662F\u6B63\u5E38\u7A7A\u7ED3\u679C\u9875\uFF08{chars} \u5B57\u7B26\uFF0C\u524D 120 \u5B57\u7B26\uFF1A{preview}\uFF09",
|
|
3064
|
+
invalidEndpoint: 'web_search: \u65E0\u6548\u7684 SearXNG \u7AEF\u70B9 "{endpoint}"',
|
|
3065
|
+
endpointMustBeHttp: "web_search: SearXNG \u7AEF\u70B9\u5FC5\u987B\u662F http(s) \u534F\u8BAE\uFF0C\u5F53\u524D\u4E3A {protocol}",
|
|
3066
|
+
cannotReach: "web_search: \u65E0\u6CD5\u8BBF\u95EE SearXNG \u670D\u52A1\u5668 {endpoint}\u3002\u8BF7\u5B89\u88C5 SearXNG\uFF08https://github.com/searxng/searxng\uFF09\u5E76\u542F\u52A8\uFF08\u4F8B\u5982 `docker run -d -p 8080:8080 searxng/searxng`\uFF09\uFF0C\u6216\u4F7F\u7528 /search-engine mojeek \u5207\u6362\u5230\u9ED8\u8BA4\u5F15\u64CE\u3002",
|
|
3067
|
+
searxngNoResults: "web_search: \u8FD4\u56DE 0 \u6761\u7ED3\u679C\u4F46 SearXNG \u54CD\u5E94\u770B\u8D77\u6765\u4E0D\u662F\u6B63\u5E38\u7A7A\u7ED3\u679C\u9875\uFF08{chars} \u5B57\u7B26\uFF09",
|
|
3068
|
+
fetchStatus: "web_fetch \u72B6\u6001\u7801 {status}\uFF08{url}\uFF09",
|
|
3069
|
+
fetchTooLarge: "web_fetch \u62D2\u7EDD\uFF1Acontent-length {len} \u5B57\u8282\u8D85\u8FC7\u4E0A\u9650 {cap} \u5B57\u8282\uFF08{url}\uFF09",
|
|
3070
|
+
fetchBodyTooLarge: "web_fetch \u62D2\u7EDD\uFF1A\u54CD\u5E94\u4F53\u8D85\u8FC7 {cap} \u5B57\u8282\u4E0A\u9650\uFF08\u5DF2\u63A5\u6536 {seen} \u5B57\u8282\uFF09",
|
|
3071
|
+
fetchInvalidUrl: "web_fetch: URL \u5FC5\u987B\u4EE5 http:// \u6216 https:// \u5F00\u5934"
|
|
3072
|
+
},
|
|
3073
|
+
choiceConfirm: {
|
|
3074
|
+
customLabel: "\u81EA\u5B9A\u4E49\u56DE\u7B54",
|
|
3075
|
+
customDesc: "\u4EE5\u4E0A\u9009\u9879\u90FD\u4E0D\u5408\u9002 \u2014 \u8F93\u5165\u81EA\u7531\u683C\u5F0F\u56DE\u590D\uFF0C\u6A21\u578B\u4F1A\u539F\u6837\u8BFB\u53D6",
|
|
3076
|
+
cancelLabel: "\u53D6\u6D88 \u2014 \u653E\u5F03\u95EE\u9898",
|
|
3077
|
+
cancelDesc: "\u6A21\u578B\u505C\u6B62\u5E76\u8BE2\u95EE\u4F60\u771F\u6B63\u7684\u9700\u6C42"
|
|
3078
|
+
},
|
|
2712
3079
|
cardTitles: {
|
|
2713
3080
|
usage: "\u7528\u91CF",
|
|
2714
3081
|
context: "\u4E0A\u4E0B\u6587",
|
|
@@ -2718,7 +3085,9 @@ var zhCN = {
|
|
|
2718
3085
|
reasoning: "\u63A8\u7406\u4E2D",
|
|
2719
3086
|
reasoningAborted: "\u63A8\u7406\uFF08\u5DF2\u4E2D\u6B62\uFF09",
|
|
2720
3087
|
reasoningEllipsis: "\u63A8\u7406\u4E2D\u2026",
|
|
2721
|
-
error: "\u9519\u8BEF"
|
|
3088
|
+
error: "\u9519\u8BEF",
|
|
3089
|
+
doctor: "\u73AF\u5883\u8BCA\u65AD",
|
|
3090
|
+
you: "\u4F60"
|
|
2722
3091
|
},
|
|
2723
3092
|
cardLabels: {
|
|
2724
3093
|
prompt: "\u63D0\u793A",
|
|
@@ -2732,7 +3101,7 @@ var zhCN = {
|
|
|
2732
3101
|
tools: "\u5DE5\u5177",
|
|
2733
3102
|
log: "\u65E5\u5FD7",
|
|
2734
3103
|
input: "\u8F93\u5165",
|
|
2735
|
-
topTools: "
|
|
3104
|
+
topTools: "\u5E38\u7528\u5DE5\u5177",
|
|
2736
3105
|
logMsgs: "\u65E5\u5FD7\u6D88\u606F",
|
|
2737
3106
|
hitSingular: "{count} \u6761\u7ED3\u679C \xB7 {files} \u4E2A\u6587\u4EF6",
|
|
2738
3107
|
hitsPlural: "{count} \u6761\u7ED3\u679C \xB7 {files} \u4E2A\u6587\u4EF6",
|
|
@@ -2757,7 +3126,42 @@ var zhCN = {
|
|
|
2757
3126
|
retries: "\u6B21\u91CD\u8BD5",
|
|
2758
3127
|
reasoningLabel: "\u63A8\u7406 \xB7 {count} \xB6",
|
|
2759
3128
|
runningLabel: "\u8FD0\u884C\u4E2D",
|
|
2760
|
-
workingLabel: "\
|
|
3129
|
+
workingLabel: "\u5904\u7406\u4E2D",
|
|
3130
|
+
defaultFooter: "\u2191\u2193 \u9009\u62E9 \xB7 \u23CE \u786E\u8BA4 \xB7 Esc \u53D6\u6D88",
|
|
3131
|
+
applyAction: "[a] \u5E94\u7528",
|
|
3132
|
+
skipAction: "[s] \u8DF3\u8FC7",
|
|
3133
|
+
rejectAction: "[r] \u62D2\u7EDD",
|
|
3134
|
+
levelOk: "\u6B63\u5E38",
|
|
3135
|
+
levelWarn: "\u8B66\u544A",
|
|
3136
|
+
levelFail: "\u5931\u8D25",
|
|
3137
|
+
checksLabel: "\u68C0\u67E5\u9879",
|
|
3138
|
+
passed: "\u901A\u8FC7",
|
|
3139
|
+
warnTag: "\u8B66\u544A",
|
|
3140
|
+
failTag: "\u5931\u8D25",
|
|
3141
|
+
stepLabel: "\u6B65\u9AA4",
|
|
3142
|
+
done: "\u5DF2\u5B8C\u6210",
|
|
3143
|
+
inProgress: "\u2190 \u8FDB\u884C\u4E2D",
|
|
3144
|
+
upcoming: "\u5F85\u5904\u7406",
|
|
3145
|
+
resumed: "\u5DF2\u6062\u590D \xB7 ",
|
|
3146
|
+
archive: "\u23EA \u5F52\u6863 \xB7 ",
|
|
3147
|
+
more: "\u22EE +{count} \u66F4\u591A",
|
|
3148
|
+
categoryUser: "\u7528\u6237",
|
|
3149
|
+
categoryFeedback: "\u53CD\u9988",
|
|
3150
|
+
categoryProject: "\u9879\u76EE",
|
|
3151
|
+
categoryReference: "\u53C2\u8003"
|
|
3152
|
+
},
|
|
3153
|
+
copyMode: {
|
|
3154
|
+
title: "\u2500\u2500 \u590D\u5236\u6A21\u5F0F \u2500\u2500",
|
|
3155
|
+
help: "j/k \u6216 \u2191/\u2193 \u79FB\u52A8 \xB7 v \u8D77\u9009\u533A \xB7 y \u590D\u5236 \xB7 g/G \u9876/\u5E95 \xB7 q \u9000\u51FA",
|
|
3156
|
+
statusBar: "\u7B2C {cur}/{total} \u884C \xB7 \u9009\u533A\uFF1A{sel}",
|
|
3157
|
+
statusYanked: "\u5DF2\u590D\u5236 {size} \u5B57\u7B26\uFF08osc52={osc52}\uFF09",
|
|
3158
|
+
statusEmpty: "\u672A\u9009\u4E2D\u5185\u5BB9",
|
|
3159
|
+
empty: "\uFF08\u8FD8\u6CA1\u6709\u804A\u5929\u5185\u5BB9 \u2014 \u5148\u548C\u6A21\u578B\u8BF4\u70B9\u4EC0\u4E48\uFF09",
|
|
3160
|
+
labelUser: "\u4F60",
|
|
3161
|
+
labelAssistant: "\u52A9\u624B",
|
|
3162
|
+
labelReasoning: "\u63A8\u7406",
|
|
3163
|
+
yankedToast: "\u25B8 \u5DF2\u590D\u5236 {size} \u5B57\u7B26\u5230\u526A\u8D34\u677F (osc52)",
|
|
3164
|
+
yankedToastFile: "\u25B8 \u5DF2\u590D\u5236 {size} \u5B57\u7B26 \xB7 \u6587\u4EF6\uFF1A{path}"
|
|
2761
3165
|
}
|
|
2762
3166
|
};
|
|
2763
3167
|
|
|
@@ -3277,6 +3681,10 @@ var ToolRegistry = class {
|
|
|
3277
3681
|
setResultAugmenter(fn) {
|
|
3278
3682
|
this._resultAugmenter = fn;
|
|
3279
3683
|
}
|
|
3684
|
+
/** True when an augmenter is already wired — lets late-installing callers skip clobbering an earlier one. */
|
|
3685
|
+
get hasResultAugmenter() {
|
|
3686
|
+
return this._resultAugmenter !== null;
|
|
3687
|
+
}
|
|
3280
3688
|
register(def) {
|
|
3281
3689
|
if (!def.name) throw new Error("tool requires a name");
|
|
3282
3690
|
const internal = { ...def };
|
|
@@ -4799,6 +5207,7 @@ function signature(call) {
|
|
|
4799
5207
|
|
|
4800
5208
|
// src/loop.ts
|
|
4801
5209
|
var ESCALATION_MODEL = "deepseek-v4-pro";
|
|
5210
|
+
var PARENT_BUDGET_WARN_THRESHOLD = 5;
|
|
4802
5211
|
var CacheFirstLoop = class {
|
|
4803
5212
|
client;
|
|
4804
5213
|
prefix;
|
|
@@ -4835,6 +5244,7 @@ var CacheFirstLoop = class {
|
|
|
4835
5244
|
_turnFailures = new TurnFailureTracker();
|
|
4836
5245
|
_turnSelfCorrected = false;
|
|
4837
5246
|
_foldedThisTurn = false;
|
|
5247
|
+
_toolDispatchesThisStep = 0;
|
|
4838
5248
|
context;
|
|
4839
5249
|
/** Subscribe API so UI hooks can derive `running` from finally-guaranteed insertions. */
|
|
4840
5250
|
get inflight() {
|
|
@@ -4889,6 +5299,23 @@ var CacheFirstLoop = class {
|
|
|
4889
5299
|
stormThreshold: parsePositiveIntEnv(process.env.REASONIX_STORM_THRESHOLD),
|
|
4890
5300
|
stormWindow: parsePositiveIntEnv(process.env.REASONIX_STORM_WINDOW)
|
|
4891
5301
|
});
|
|
5302
|
+
if (!this.tools.hasResultAugmenter) {
|
|
5303
|
+
this.tools.setResultAugmenter((_name, _args, result) => {
|
|
5304
|
+
this._toolDispatchesThisStep++;
|
|
5305
|
+
const remaining = this.maxToolIters - this._toolDispatchesThisStep;
|
|
5306
|
+
if (remaining <= 0) {
|
|
5307
|
+
return `${result}
|
|
5308
|
+
|
|
5309
|
+
[budget: 0 of ${this.maxToolIters} tool calls left this turn \u2014 finalize NOW; the next iter forces a summary]`;
|
|
5310
|
+
}
|
|
5311
|
+
if (remaining <= PARENT_BUDGET_WARN_THRESHOLD) {
|
|
5312
|
+
return `${result}
|
|
5313
|
+
|
|
5314
|
+
[budget: ${remaining} of ${this.maxToolIters} tool calls left this turn \u2014 wrap up soon]`;
|
|
5315
|
+
}
|
|
5316
|
+
return result;
|
|
5317
|
+
});
|
|
5318
|
+
}
|
|
4892
5319
|
this.sessionName = opts.session ?? null;
|
|
4893
5320
|
if (this.sessionName) {
|
|
4894
5321
|
const prior = loadSessionMessages(this.sessionName);
|
|
@@ -5142,6 +5569,7 @@ ${reason}`
|
|
|
5142
5569
|
this._turnSelfCorrected = false;
|
|
5143
5570
|
this._escalateThisTurn = false;
|
|
5144
5571
|
this._foldedThisTurn = false;
|
|
5572
|
+
this._toolDispatchesThisStep = 0;
|
|
5145
5573
|
let armedConsumed = false;
|
|
5146
5574
|
if (this._proArmedForNextTurn) {
|
|
5147
5575
|
this._escalateThisTurn = true;
|
|
@@ -7823,6 +8251,74 @@ Prefer \`list_directory\` for a single-level view, \`search_files\` to find spec
|
|
|
7823
8251
|
return `moved ${displayRel4(rootDir, src)} \u2192 ${displayRel4(rootDir, dst)}`;
|
|
7824
8252
|
}
|
|
7825
8253
|
});
|
|
8254
|
+
registry.register({
|
|
8255
|
+
name: "delete_file",
|
|
8256
|
+
description: "Delete one file under the sandbox root. Refuses directories \u2014 use delete_directory for those. Errors if the path doesn't exist.",
|
|
8257
|
+
parameters: {
|
|
8258
|
+
type: "object",
|
|
8259
|
+
properties: { path: { type: "string" } },
|
|
8260
|
+
required: ["path"]
|
|
8261
|
+
},
|
|
8262
|
+
fn: async (args) => {
|
|
8263
|
+
const abs = safePath(args.path);
|
|
8264
|
+
const st = await fs4.lstat(abs);
|
|
8265
|
+
if (st.isDirectory()) {
|
|
8266
|
+
throw new Error(
|
|
8267
|
+
`delete_file: ${args.path} is a directory \u2014 use delete_directory to remove it`
|
|
8268
|
+
);
|
|
8269
|
+
}
|
|
8270
|
+
await fs4.unlink(abs);
|
|
8271
|
+
return `deleted ${displayRel4(rootDir, abs)}`;
|
|
8272
|
+
}
|
|
8273
|
+
});
|
|
8274
|
+
registry.register({
|
|
8275
|
+
name: "delete_directory",
|
|
8276
|
+
description: "Recursively delete a directory under the sandbox root. Pass `recursive:false` to refuse non-empty directories. Errors if the path doesn't exist.",
|
|
8277
|
+
parameters: {
|
|
8278
|
+
type: "object",
|
|
8279
|
+
properties: {
|
|
8280
|
+
path: { type: "string" },
|
|
8281
|
+
recursive: {
|
|
8282
|
+
type: "boolean",
|
|
8283
|
+
description: "When true (default) deletes the directory and all its contents. When false, only removes empty directories \u2014 non-empty refuses with an error."
|
|
8284
|
+
}
|
|
8285
|
+
},
|
|
8286
|
+
required: ["path"]
|
|
8287
|
+
},
|
|
8288
|
+
fn: async (args) => {
|
|
8289
|
+
const abs = safePath(args.path);
|
|
8290
|
+
const st = await fs4.lstat(abs);
|
|
8291
|
+
if (!st.isDirectory()) {
|
|
8292
|
+
throw new Error(`delete_directory: ${args.path} is a file \u2014 use delete_file to remove it`);
|
|
8293
|
+
}
|
|
8294
|
+
const recursive = args.recursive !== false;
|
|
8295
|
+
if (recursive) {
|
|
8296
|
+
await fs4.rm(abs, { recursive: true, force: false });
|
|
8297
|
+
} else {
|
|
8298
|
+
await fs4.rmdir(abs);
|
|
8299
|
+
}
|
|
8300
|
+
return `deleted ${displayRel4(rootDir, abs)}/${recursive ? " (recursive)" : ""}`;
|
|
8301
|
+
}
|
|
8302
|
+
});
|
|
8303
|
+
registry.register({
|
|
8304
|
+
name: "copy_file",
|
|
8305
|
+
description: "Copy a file or directory under the sandbox root. Both source and destination resolve under the sandbox. Parent directories of the destination are created as needed. Refuses to overwrite an existing destination \u2014 delete it first if you want to replace it.",
|
|
8306
|
+
parameters: {
|
|
8307
|
+
type: "object",
|
|
8308
|
+
properties: {
|
|
8309
|
+
source: { type: "string" },
|
|
8310
|
+
destination: { type: "string" }
|
|
8311
|
+
},
|
|
8312
|
+
required: ["source", "destination"]
|
|
8313
|
+
},
|
|
8314
|
+
fn: async (args) => {
|
|
8315
|
+
const src = safePath(args.source);
|
|
8316
|
+
const dst = safePath(args.destination);
|
|
8317
|
+
await fs4.mkdir(pathMod4.dirname(dst), { recursive: true });
|
|
8318
|
+
await fs4.cp(src, dst, { recursive: true, force: false, errorOnExist: true });
|
|
8319
|
+
return `copied ${displayRel4(rootDir, src)} \u2192 ${displayRel4(rootDir, dst)}`;
|
|
8320
|
+
}
|
|
8321
|
+
});
|
|
7826
8322
|
return registry;
|
|
7827
8323
|
}
|
|
7828
8324
|
|
|
@@ -8479,6 +8975,18 @@ var DEFAULT_SUBAGENT_MODEL = "deepseek-v4-flash";
|
|
|
8479
8975
|
var DEFAULT_SUBAGENT_EFFORT = "high";
|
|
8480
8976
|
var SUBAGENT_TOOL_NAME = "spawn_subagent";
|
|
8481
8977
|
var NEVER_INHERITED_TOOLS = /* @__PURE__ */ new Set([SUBAGENT_TOOL_NAME, "submit_plan"]);
|
|
8978
|
+
var SOFT_HINT_AFTER_SPAWNS = 1;
|
|
8979
|
+
var STRONG_HINT_AFTER_SPAWNS = 4;
|
|
8980
|
+
var STRONG_HINT_TOKEN_THRESHOLD = 5e4;
|
|
8981
|
+
function subagentBudgetHint(spawnCount, totalTokens) {
|
|
8982
|
+
if (spawnCount > STRONG_HINT_AFTER_SPAWNS || totalTokens >= STRONG_HINT_TOKEN_THRESHOLD) {
|
|
8983
|
+
return `[budget: this session has now spawned ${spawnCount} subagents totalling ${totalTokens} tokens. Each spawn pays a fresh prefix-cache miss plus a full child loop \u2014 confirm the next spawn is genuinely needed (parallel fan-out or >10-read context blow-up) before calling spawn_subagent again. If you can answer with direct tools, do that instead.]`;
|
|
8984
|
+
}
|
|
8985
|
+
if (spawnCount > SOFT_HINT_AFTER_SPAWNS) {
|
|
8986
|
+
return `[note: this session has spawned ${spawnCount} subagents totalling ${totalTokens} tokens; confirm this one is worth it.]`;
|
|
8987
|
+
}
|
|
8988
|
+
return null;
|
|
8989
|
+
}
|
|
8482
8990
|
async function spawnSubagent(opts) {
|
|
8483
8991
|
const model = opts.model ?? DEFAULT_SUBAGENT_MODEL;
|
|
8484
8992
|
const maxToolIters = opts.maxToolIters ?? DEFAULT_MAX_ITERS;
|
|
@@ -8700,10 +9208,12 @@ function registerSubagentTool(parentRegistry, opts) {
|
|
|
8700
9208
|
const maxToolIters = opts.maxToolIters ?? DEFAULT_MAX_ITERS;
|
|
8701
9209
|
const maxResultChars = opts.maxResultChars ?? DEFAULT_MAX_RESULT_CHARS2;
|
|
8702
9210
|
const sink = opts.sink;
|
|
9211
|
+
let sessionSpawnCount = 0;
|
|
9212
|
+
let sessionSpawnTokens = 0;
|
|
8703
9213
|
parentRegistry.register({
|
|
8704
9214
|
name: SUBAGENT_TOOL_NAME,
|
|
8705
9215
|
parallelSafe: true,
|
|
8706
|
-
description: "Spawn an isolated subagent to handle a self-contained subtask in a fresh context, returning only its final answer.
|
|
9216
|
+
description: "Spawn an isolated subagent to handle a self-contained subtask in a fresh context, returning only its final answer. **Prefer direct tools.** Spawn primarily for parallel fan-out (2+ independent investigations issued in one tool batch) or when the work would otherwise need >10 file reads/searches whose trail you don't need to keep. Single greps, 1-3 file cross-references, and 'keep my context clean for one question' are NOT good reasons to spawn \u2014 direct tools are cheaper and let you reference the evidence later. Each spawn pays a fresh prefix-cache miss plus a full child loop. The subagent inherits your tools but runs in its own isolated message log; only the final assistant message comes back. Keep tasks focused; the subagent has a stricter iter budget than you do.",
|
|
8707
9217
|
parameters: {
|
|
8708
9218
|
type: "object",
|
|
8709
9219
|
properties: {
|
|
@@ -8758,7 +9268,12 @@ ${escalationContract(model)}`;
|
|
|
8758
9268
|
sink,
|
|
8759
9269
|
parentSignal: ctx?.signal
|
|
8760
9270
|
});
|
|
8761
|
-
|
|
9271
|
+
sessionSpawnCount++;
|
|
9272
|
+
sessionSpawnTokens += result.usage.totalTokens;
|
|
9273
|
+
const formatted = formatSubagentResult(result);
|
|
9274
|
+
const hint = subagentBudgetHint(sessionSpawnCount, sessionSpawnTokens);
|
|
9275
|
+
return hint ? `${formatted}
|
|
9276
|
+
${hint}` : formatted;
|
|
8762
9277
|
}
|
|
8763
9278
|
});
|
|
8764
9279
|
return parentRegistry;
|
|
@@ -10074,7 +10589,7 @@ function registerShellTools(registry, opts) {
|
|
|
10074
10589
|
const isAllowAll = typeof opts.allowAll === "function" ? opts.allowAll : () => opts.allowAll === true;
|
|
10075
10590
|
registry.register({
|
|
10076
10591
|
name: "run_command",
|
|
10077
|
-
description: "Run a shell command in the project root
|
|
10592
|
+
description: "Run a shell command in the project root; returns combined stdout+stderr. Allowlisted read-only / test / lint / typecheck commands run immediately; anything that could mutate state, install deps, or touch the network is gated by user confirmation. Prefer this over asking the user to run a command manually \u2014 after edits, run the project's tests to verify.\n\nConstraints (no real shell \u2014 argv is parsed natively for cross-platform parity):\n\u2022 Supported: chain ops `|` / `||` / `&&` / `;` (each segment allowlist-checked individually), file redirects `>` / `>>` / `<` / `2>` / `2>>` / `2>&1` / `&>` (target paths resolve relative to project root, max one redirect per fd per segment).\n\u2022 NOT supported: background `&`, heredoc `<<`, command substitution `$(\u2026)`, subshells `(\u2026)`, process substitution `<(\u2026)`, `$VAR` env expansion, glob expansion. To pass an operator char as literal arg, quote it (`grep \"a|b\" file`).\n\u2022 `cd` does NOT persist \u2014 between calls OR within a chain like `cd dir && cmd`. Use the binary's own cwd flag: `npm --prefix <dir>`, `git -C <dir>`, `cargo -C <dir>`, `pytest <dir>/tests`.\n\u2022 Filter at source \u2014 unbounded output (`netstat -ano`, `find /`) wastes tokens. Use `grep -c`, `wc -l`, narrower paths, etc.",
|
|
10078
10593
|
// Plan-mode gate: allow allowlisted commands through (git status,
|
|
10079
10594
|
// cargo check, ls, grep …) so the model can actually investigate
|
|
10080
10595
|
// during planning. Anything that would otherwise trigger a
|
|
@@ -10126,7 +10641,7 @@ function registerShellTools(registry, opts) {
|
|
|
10126
10641
|
});
|
|
10127
10642
|
registry.register({
|
|
10128
10643
|
name: "run_background",
|
|
10129
|
-
description: "Spawn a long-running process (dev server, watcher
|
|
10644
|
+
description: "Spawn a long-running process (dev server, watcher) and detach. Waits up to `waitSec` for startup or a readiness signal ('Local:', 'listening on', 'compiled successfully'), then returns the job id + startup preview. Tail logs with `job_output`, kill with `stop_job`, list with `list_jobs`.\n\nSingle process only \u2014 chains / redirects / `cd` work as in run_command, but a typical dev-server invocation is one binary. Use the binary's own --cwd / --prefix flag for subdirectories. Vite gotcha: npm's `--prefix` only finds package.json; vite's server root still uses process cwd \u2014 pass `vite <project-dir>` instead.\n\nUSE THIS \u2014 not run_command \u2014 for: npm/yarn/pnpm dev, uvicorn / flask run, cargo watch, tsc --watch, webpack serve, anything with dev/serve/watch in the name.",
|
|
10130
10645
|
parameters: {
|
|
10131
10646
|
type: "object",
|
|
10132
10647
|
properties: {
|
|
@@ -10198,6 +10713,8 @@ function registerShellTools(registry, opts) {
|
|
|
10198
10713
|
name: "wait_for_job",
|
|
10199
10714
|
description: "Block until a background job exits or produces new output, bounded by `timeoutMs`. Use this instead of polling `job_output` with identical args when you're intentionally waiting for state to change. Returns JSON with `exited`, `exitCode`, and `latestOutput`.",
|
|
10200
10715
|
readOnly: true,
|
|
10716
|
+
parallelSafe: true,
|
|
10717
|
+
stormExempt: true,
|
|
10201
10718
|
parameters: {
|
|
10202
10719
|
type: "object",
|
|
10203
10720
|
properties: {
|
|
@@ -10316,16 +10833,19 @@ async function searchMojeek(query, opts = {}) {
|
|
|
10316
10833
|
signal: opts.signal,
|
|
10317
10834
|
redirect: "follow"
|
|
10318
10835
|
});
|
|
10319
|
-
if (!resp.ok) throw new Error(
|
|
10836
|
+
if (!resp.ok) throw new Error(t("webErrors.status", { status: resp.status }));
|
|
10320
10837
|
const html = await resp.text();
|
|
10321
10838
|
const results = parseMojeekResults(html).slice(0, topK);
|
|
10322
10839
|
if (results.length === 0) {
|
|
10323
10840
|
if (/no results found|did not match any documents/i.test(html)) return [];
|
|
10324
10841
|
if (/captcha|verify you are human|access denied|forbidden/i.test(html)) {
|
|
10325
|
-
throw new Error("
|
|
10842
|
+
throw new Error(t("webErrors.mojeekBlocked"));
|
|
10326
10843
|
}
|
|
10327
10844
|
throw new Error(
|
|
10328
|
-
|
|
10845
|
+
t("webErrors.mojeekNoResults", {
|
|
10846
|
+
chars: html.length,
|
|
10847
|
+
preview: html.slice(0, 120).replace(/\s+/g, " ")
|
|
10848
|
+
})
|
|
10329
10849
|
);
|
|
10330
10850
|
}
|
|
10331
10851
|
return results;
|
|
@@ -10335,10 +10855,10 @@ function normalizeSearxngEndpoint(raw) {
|
|
|
10335
10855
|
try {
|
|
10336
10856
|
url = new URL(raw.includes("://") ? raw : `http://${raw}`);
|
|
10337
10857
|
} catch {
|
|
10338
|
-
throw new Error(
|
|
10858
|
+
throw new Error(t("webErrors.invalidEndpoint", { endpoint: raw }));
|
|
10339
10859
|
}
|
|
10340
10860
|
if (url.protocol !== "http:" && url.protocol !== "https:") {
|
|
10341
|
-
throw new Error(
|
|
10861
|
+
throw new Error(t("webErrors.endpointMustBeHttp", { protocol: url.protocol }));
|
|
10342
10862
|
}
|
|
10343
10863
|
return url.origin;
|
|
10344
10864
|
}
|
|
@@ -10358,19 +10878,17 @@ async function searchSearxng(query, opts = {}) {
|
|
|
10358
10878
|
} catch (err) {
|
|
10359
10879
|
if (err instanceof TypeError && err.message.includes("fetch")) {
|
|
10360
10880
|
throw new Error(
|
|
10361
|
-
|
|
10881
|
+
t("webErrors.cannotReach", { endpoint: opts.endpoint ?? "http://localhost:8080" })
|
|
10362
10882
|
);
|
|
10363
10883
|
}
|
|
10364
10884
|
throw err;
|
|
10365
10885
|
}
|
|
10366
|
-
if (!resp.ok) throw new Error(
|
|
10886
|
+
if (!resp.ok) throw new Error(t("webErrors.status", { status: resp.status }));
|
|
10367
10887
|
const html = await resp.text();
|
|
10368
10888
|
const results = parseSearxngHtmlResults(html).slice(0, topK);
|
|
10369
10889
|
if (results.length === 0) {
|
|
10370
10890
|
if (/no results found|did not match any documents/i.test(html)) return [];
|
|
10371
|
-
throw new Error(
|
|
10372
|
-
`web_search: 0 results but SearXNG response doesn't look like an empty results page (${html.length} chars)`
|
|
10373
|
-
);
|
|
10891
|
+
throw new Error(t("webErrors.searxngNoResults", { chars: html.length }));
|
|
10374
10892
|
}
|
|
10375
10893
|
return results;
|
|
10376
10894
|
}
|
|
@@ -10464,13 +10982,11 @@ async function webFetch(url, opts = {}) {
|
|
|
10464
10982
|
clearTimeout(timer);
|
|
10465
10983
|
opts.signal?.removeEventListener("abort", cancel);
|
|
10466
10984
|
}
|
|
10467
|
-
if (!resp.ok) throw new Error(
|
|
10985
|
+
if (!resp.ok) throw new Error(t("webErrors.fetchStatus", { status: resp.status, url }));
|
|
10468
10986
|
const contentType = resp.headers.get("content-type") ?? "";
|
|
10469
10987
|
const declaredLen = Number(resp.headers.get("content-length") ?? "");
|
|
10470
10988
|
if (Number.isFinite(declaredLen) && declaredLen > FETCH_MAX_BYTES) {
|
|
10471
|
-
throw new Error(
|
|
10472
|
-
`web_fetch refused: content-length ${declaredLen} bytes exceeds ${FETCH_MAX_BYTES}-byte cap (${url})`
|
|
10473
|
-
);
|
|
10989
|
+
throw new Error(t("webErrors.fetchTooLarge", { len: declaredLen, cap: FETCH_MAX_BYTES, url }));
|
|
10474
10990
|
}
|
|
10475
10991
|
const raw = await readBodyCapped(resp, FETCH_MAX_BYTES);
|
|
10476
10992
|
const title = extractTitle(raw);
|
|
@@ -10497,9 +11013,7 @@ async function readBodyCapped(resp, maxBytes) {
|
|
|
10497
11013
|
await reader.cancel();
|
|
10498
11014
|
} catch {
|
|
10499
11015
|
}
|
|
10500
|
-
throw new Error(
|
|
10501
|
-
`web_fetch refused: response body exceeded ${maxBytes}-byte cap (${total} bytes seen)`
|
|
10502
|
-
);
|
|
11016
|
+
throw new Error(t("webErrors.fetchBodyTooLarge", { cap: maxBytes, seen: total }));
|
|
10503
11017
|
}
|
|
10504
11018
|
out += decoder.decode(value, { stream: true });
|
|
10505
11019
|
}
|
|
@@ -10627,7 +11141,7 @@ function registerWebTools(registry, opts = {}) {
|
|
|
10627
11141
|
},
|
|
10628
11142
|
fn: async (args, ctx) => {
|
|
10629
11143
|
if (!/^https?:\/\//i.test(args.url)) {
|
|
10630
|
-
throw new Error("
|
|
11144
|
+
throw new Error(t("webErrors.fetchInvalidUrl"));
|
|
10631
11145
|
}
|
|
10632
11146
|
const page = await webFetch(args.url, { maxChars: maxFetchChars, signal: ctx?.signal });
|
|
10633
11147
|
const header = page.title ? `${page.title}
|
|
@@ -12180,6 +12694,17 @@ If you are about to write "X is missing" or "Y is not implemented" \u2014 **STOP
|
|
|
12180
12694
|
|
|
12181
12695
|
Asserting absence without a search is the #1 way evaluative answers go wrong. Treat the urge to write "missing" as a red flag in your own reasoning.
|
|
12182
12696
|
|
|
12697
|
+
# When auditing or reviewing this codebase
|
|
12698
|
+
|
|
12699
|
+
When you're asked to audit / review / critique Reasonix itself ("what tools are missing?", "review the prompt system", "anything wrong with how X works?"), the failure mode isn't hallucinating absences \u2014 it's building confident, well-structured proposals on factually wrong premises. Six rails:
|
|
12700
|
+
|
|
12701
|
+
- **Auto-preview is for locating, not auditing.** Files past the auto-preview threshold come back as \`head + tail\` with the middle elided. Don't conclude what's in the elided section \u2014 runtime behavior, current architectural state, whether a plan doc is still accurate \u2014 off the preview. Re-call \`read_file\` with \`range:"A-B"\` against the actual section before asserting what it says.
|
|
12702
|
+
- **Flag \u2192 consumer trace.** Reading a type field (\`parallelSafe?: boolean\`, \`stormExempt?: boolean\`) is not understanding behavior. Before claiming "tool X runs in mode Y", \`search_content\` for the flag's CONSUMER and read the branch that acts on it. **For inventory claims** ("which tools have flag F?"), grep the flag \u2014 don't enumerate from memory; the field is set per-tool and easily mis-recalled.
|
|
12703
|
+
- **No fabricated percentages.** "Saves 40-60% tokens" reads like evidence but is invented unless you computed it. Ground numbers in a cited transcript / token count, or use hedged language ("small but non-zero", "may compound") \u2014 never present an unmeasured number as a measured one.
|
|
12704
|
+
- **Schema cost is real.** Every tool's description ships in every request. A new-tool proposal MUST cover (a) which existing-tool composition fails to do this, (b) rough description-token cost, (c) why a prompt or description change can't reach the same end. Default to "tighten prompt / existing tool" before "add tool".
|
|
12705
|
+
- **MEMORY.md is part of the design space.** The pinned memory blocks above are loaded user feedback \u2014 recommendations contradicting them ("auto-commit checkpoints", "free-credit messaging", anything the user has explicitly ruled out) are wrong by construction. Cross-check before proposing.
|
|
12706
|
+
- **User-facing \u2260 model-facing \u2260 library-facing.** Reasonix has four action surfaces: slash commands (user), tools (model), UI (user), and library exports (\`src/index.ts\`). Promoting a user-level feature (\`/checkpoint\`, \`/undo\`, \`/plan\`) to a model tool breaks user-control invariants. Treating a library export as "dead code" because the CLI doesn't register it to the model misreads the design \u2014 embedders consume \`src/index.ts\` directly.
|
|
12707
|
+
|
|
12183
12708
|
# When to propose a plan (submit_plan)
|
|
12184
12709
|
|
|
12185
12710
|
You have a \`submit_plan\` tool that shows the user a markdown plan and lets them Approve / Refine / Cancel before you execute. Use it proactively when the task is large enough to deserve a review gate:
|
|
@@ -12224,7 +12749,7 @@ Call shape: \`{ todos: [{ content, activeForm, status }, ...] }\` \u2014 \`conte
|
|
|
12224
12749
|
# Plan mode (/plan)
|
|
12225
12750
|
|
|
12226
12751
|
The user can ALSO enter "plan mode" via /plan, which is a stronger, explicit constraint:
|
|
12227
|
-
- Write tools (edit_file, multi_edit, write_file, create_directory, move_file) and non-allowlisted run_command calls are BOUNCED at dispatch \u2014 you'll get a tool result like "unavailable in plan mode". Don't retry them.
|
|
12752
|
+
- Write tools (edit_file, multi_edit, write_file, create_directory, move_file, copy_file, delete_file, delete_directory) and non-allowlisted run_command calls are BOUNCED at dispatch \u2014 you'll get a tool result like "unavailable in plan mode". Don't retry them.
|
|
12228
12753
|
- Read tools (read_file, list_directory, search_files, directory_tree, get_file_info) and allowlisted read-only / test shell commands still work \u2014 use them to investigate.
|
|
12229
12754
|
- You MUST call submit_plan before anything will execute. Approve exits plan mode; Refine stays in; Cancel exits without implementing.
|
|
12230
12755
|
|
|
@@ -12239,15 +12764,18 @@ Two built-ins ship by default:
|
|
|
12239
12764
|
- **explore** \`[\u{1F9EC} subagent]\` \u2014 read-only investigation across the codebase. Use when the user says things like "find all places that...", "how does X work across the project", "survey the code for Y". Pass \`arguments\` describing the concrete question.
|
|
12240
12765
|
- **research** \`[\u{1F9EC} subagent]\` \u2014 combines web search + code reading. Use for "is X supported by lib Y", "what's the canonical way to Z", "compare our impl to the spec".
|
|
12241
12766
|
|
|
12242
|
-
|
|
12243
|
-
|
|
12244
|
-
|
|
12245
|
-
|
|
12767
|
+
**Default: don't delegate.** Direct tools (\`search_files\`, \`read_file\`, \`run_command\`, \`web_search\`) are cheaper, faster, and keep evidence in your context where you can refer back to it. A subagent spawn pays a fresh prefix-cache miss and a full child loop \u2014 hundreds of ms of overhead and full input pricing for the child's first turn. For most questions the spawn costs more than it saves.
|
|
12768
|
+
|
|
12769
|
+
Spawn ONLY in these two cases:
|
|
12770
|
+
1. **True parallelism** \u2014 you have 2+ independent investigations that can run concurrently in the same tool batch. The wall-time win is real and only achievable via fan-out.
|
|
12771
|
+
2. **Context blow-up** \u2014 the work would otherwise need >10 file reads/searches and you only need the conclusion. Keeping the trail out of your context is the actual saving.
|
|
12246
12772
|
|
|
12247
|
-
|
|
12248
|
-
-
|
|
12249
|
-
-
|
|
12250
|
-
-
|
|
12773
|
+
Anti-patterns \u2014 do NOT spawn for any of these:
|
|
12774
|
+
- single grep / single file read \u2192 call the tool directly
|
|
12775
|
+
- 1-3 file cross-reference \u2192 read them directly
|
|
12776
|
+
- "to keep my context clean for one question" \u2192 not enough saving to justify the spawn
|
|
12777
|
+
- anything that needs user interaction (subagents can't submit plans or ask for clarification)
|
|
12778
|
+
- anything where you need to track intermediate results yourself (planning, multi-step edits)
|
|
12251
12779
|
|
|
12252
12780
|
Always pass a clear, self-contained \`arguments\` \u2014 that text is the **only** context the subagent gets.
|
|
12253
12781
|
|