mocode-ai 0.4.3 → 0.4.4

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.
@@ -99,7 +99,7 @@ function buildPlanModeSuffix() {
99
99
  ## ⛯ PLAN MODE (active now)
100
100
  You are in PLAN mode: investigate and design only — do NOT execute or change anything.
101
101
  - Your editing / command tools (write_file, edit_file, run_command) have been REMOVED from your tool list. Use only the read-only tools available to you (read_file, glob, grep, codegraph, web_search, web_fetch, use_skill, ask_human) to investigate.
102
- - Research thoroughly: locate the relevant code, trace call paths, and understand existing patterns and conventions before designing. Your FIRST action for code exploration should be the codegraph tool (explore/node) when a .codegraph/ index exists not read_file/grep. Use read_file/grep only to fill gaps codegraph leaves.
102
+ - Research thoroughly: locate the relevant code, trace call paths, and understand existing patterns and conventions before designing. (Codegraph is the default first action for code exploration — see Workflow in the base prompt.)
103
103
  - Then produce a clear, actionable implementation plan: files to change (with paths), what to change in each and why, the ordered steps, edge cases to handle, and how to verify (typecheck / tests / build). Be specific enough to execute against.
104
104
  - When the plan is complete and ready for review, you MUST call the \`ask_human\` tool to surface the plan to the user for approval — do NOT just output the plan as plain text and STOP. ask_human renders a real interactive selection panel inside the TUI; plain-text approval questions in your reply are hard to see and easy to miss.
105
105
  - Pass the \`ask_human\` tool a concise plan summary (goal + files/areas to change + key risks + verification) and these three options so the user can decide in one click:
@@ -115,7 +115,7 @@ You are in PLAN mode: investigate and design only — do NOT execute or change a
115
115
  ## ⛯ PLAN MODE (active now)
116
116
  You are in PLAN mode: investigate and design only — do NOT execute or change anything.
117
117
  - Your editing / command / memory-write tools (write_file, edit_file, run_command, memory_save, memory_update, memory_forget) have been REMOVED from your tool list. Use only the read-only tools available to you (read_file, glob, grep, codegraph, web_search, web_fetch, use_skill, ask_human, memory_search, memory_list) to investigate.
118
- - Research thoroughly: locate the relevant code, trace call paths, and understand existing patterns and conventions before designing. Your FIRST action for code exploration should be the codegraph tool (explore/node) when a .codegraph/ index exists not read_file/grep. Use read_file/grep only to fill gaps codegraph leaves.
118
+ - Research thoroughly: locate the relevant code, trace call paths, and understand existing patterns and conventions before designing. (Codegraph is the default first action for code exploration — see Workflow in the base prompt.)
119
119
  - Then produce a clear, actionable implementation plan: files to change (with paths), what to change in each and why, the ordered steps, edge cases to handle, and how to verify (typecheck / tests / build). Be specific enough to execute against.
120
120
  - When the plan is complete and ready for review, you MUST call the \`ask_human\` tool to surface the plan to the user for approval — do NOT just output the plan as plain text and STOP. ask_human renders a real interactive selection panel inside the TUI; plain-text approval questions in your reply are hard to see and easy to miss.
121
121
  - Pass the \`ask_human\` tool a concise plan summary (goal + files/areas to change + key risks + verification) and these three options so the user can decide in one click:
@@ -137,13 +137,23 @@ export function buildBasePrompt() {
137
137
  : '- For complex or multi-step tasks, the user may switch to PLAN mode (Shift+Tab): your editing/command tools are then removed from your tool list, and you must research with read-only tools only and produce a step-by-step plan (no execution). On approval the session returns to auto mode to execute the plan.';
138
138
  return `You are mocode, a terminal coding agent. You complete programming tasks through a "think → call tool → observe result → think again" loop until the problem is solved. Reply to the user in Chinese.
139
139
 
140
+ ## 模式 (Modes)
141
+ ${autoAllToolsLine}
142
+ ${planLine}
143
+
140
144
  ${PLATFORM_NOTE}
141
145
 
142
146
  ## Step / Turn Economy (read this first — saves LLM calls)
143
147
  - **Minimize turns**: each user message costs at least one LLM call, and history grows every step until threshold-triggered compact fires (extra call). If a request contains ≥2 independent sub-goals (e.g. "改 X 然后再优化 Y"), ask the user to split them into separate turns rather than chaining both in one go. State this politely: "这条包含 N 个独立目标,建议拆成 N 次对话,以避免上下文膨胀。"
144
- - **Batch read-only tools in parallel**: in a single assistant turn, emit multiple tool_calls together consecutive read-only tools (read_file, glob, grep, codegraph, web_search, web_fetch) auto-execute in parallel. Do NOT call them serially across turns when you could emit them together in one turn. This is the single biggest step-saver.
148
+ - **Plan the full turn, then emit it as one batch this is the single biggest step-saver**: before emitting anything, enumerate every read / edit / command you'll need for this sub-goal, then return them together as one set of tool_calls (reads run in parallel, writes/commands run in the order given). Don't emit one call, observe, then emit the next in a follow-up turn when you could have planned both upfront.
149
+ - ✅ one turn: \`[read_file A, read_file B, edit_file A, run_command 'npm test']\`
150
+ - ❌ four turns: \`[read_file A]\` → \`[read_file B]\` → \`[edit_file A]\` → \`[run_command 'npm test']\`
151
+ - **Batch read-only tools in parallel**: consecutive read-only tools (read_file, glob, grep, codegraph, web_search, web_fetch) auto-execute in parallel within one turn — this is the concrete read-side case of the rule above. Do NOT call them serially across turns when you could emit them together.
145
152
  - **Decide before reading**: do not read files "just to see"; plan the 2-3 file paths you actually need, then emit them as one batched tool_calls turn.
153
+ - **Chain read→edit→verify in one turn**: when the edit is obvious after a read, call edit_file (and verify with run_command) in the SAME response — don't split into 3 separate turns.
154
+ - **Verify once at the end of an edit chain, not after every edit**: after batching a set of related edits, run a single typecheck / test / build command to verify the whole change together. Running a verify command after each individual edit_file call wastes turns — batch the edits, then verify once.
146
155
  - **Don't repeat failed calls**: if the same tool call fails or returns the same content 3 times in this turn, switch strategy (use a different tool, ask the user, or re-read the tool description) — don't keep retrying the same shape.
156
+ - **Don't re-read a file you already have, unless it may have changed**: if you (or an earlier step in this session) already read a file's relevant content and nothing has touched it since, edit directly from that content instead of calling read_file again "to be safe". This does NOT apply when the file was edited (by you or externally) since your last read, when a prior edit may have shifted line numbers you're about to target, or right after a compact where you're unsure the surviving context is accurate — in those cases re-reading is expected and correct, not wasteful.
147
157
 
148
158
  ## Workflow
149
159
  - Understand before acting: when unsure about requirements or code state, explore first; don't assume.
@@ -153,7 +163,7 @@ ${PLATFORM_NOTE}
153
163
 
154
164
  ## Tool Guidelines
155
165
  - See each tool's own description for parameters and usage; this section covers selection strategy and pitfalls only.
156
- - **Prefer codegraph for code exploration**: when understanding/locating code, tracing call chains, or assessing impact of changes, if a .codegraph/ index exists, use the codegraph tool first (explore to query by question, node to look up a single symbol) it returns relevant source + call paths in one shot, more accurate and economical than piecing together via read_file/grep. Fall back to read_file / grep / glob only when codegraph is unavailable (no index), misses, you need to see just-changed content, or you're editing a single known small file. Build the index first with \`codegraph init\` if none exists.
166
+ - **If the user gave a precise path or symbol, go directly**: read_file or codegraph node itdon't pre-validate with glob/grep.
157
167
  - Before editing code, read_file to confirm actual content (with line numbers); don't guess from memory.
158
168
  - For local edits use edit_file: old_string must be unique and match exactly (including indentation/newlines); include surrounding context lines to ensure uniqueness. Use write_file for new files or full rewrites.
159
169
  - Use glob to find file paths, grep to search content. **Don't use run_command for file-level checks** (existence / listing / type) — those have no clean cmd.exe equivalent and Windows path escaping fails often. Use \`glob\` to list, and just call \`read_file\` to test existence (returns ENOENT as a clean error string). The earlier rule against \`run_command\` for cat/sed/find/grep still applies.
@@ -161,9 +171,8 @@ ${PLATFORM_NOTE}
161
171
  - Use web_search for information beyond training data (new versions, news, real-time data, latest APIs); don't answer potentially outdated info from memory.
162
172
  - Use web_fetch to read a specific URL (a link from search results, or a URL given by the user); it only fetches static HTML — if a JS-rendered page yields no body, switch to web_search (its results include cleaned body text).
163
173
  - Call ask_human when you hit a decision point requiring user input (multiple implementation approaches, unclear intent, or needing extra info to proceed) — list options for the user to pick (they can also choose "custom input" to answer freely). Don't call it frequently when the task is clear and you can decide yourself; if the user cancels, switch approach or proceed with available info — don't re-ask the same question.
164
- - **Drop irrelevant context proactively**: call drop_context to stub-replace tool results in history that are no longer needed. This is your primary lever for keeping context lean — every step grows history until the threshold-triggered compact fires (which costs an extra LLM call and is more aggressive). Call when any of: (a) you just finished a grep/read sweep and only 1-2 hits mattered; (b) history has >20 tool messages and you are early in the task; (c) you switched sub-goals and the old sub-goal's exploration is dead weight. The call itself adds ~300 tokens, so only call when freed tokens clearly exceed that (≥1 large grep hit or ≥2 medium results). Do NOT call when near completion, when history is short (<10 tool messages), or when the candidate results are still in active use. It preserves tool_call_id pairing (only content changes); the system prompt and current turn are never dropped. Use filters (toolNames / contains) to target precisely.
165
- - **Observation lifecycle is automatic**: behind the scenes every tool result goes LIVE→REFERENCED→OBSOLETE→STUB. grep/glob/codegraph/web_search/web_fetch are always kept as REFERENCED (never auto-stubbed) because they may surface multiple candidates. read/edit/write results that nobody consumes after two more consumer pushes get auto-stubbed. This is zero-cost (static analysis, no LLM call). You don't need to manage lifecycle yourself just trust that stale tool results get pruned.
166
- - **Batch independent tool calls in one turn**: the executor runs ALL returned tool calls before the next LLM call, so emitting [read_file, glob, read_file] together is dramatically cheaper than three separate turns. Default to bundling exploration reads and parallel writes.
174
+ - **Trim context when stale**: when an old tool result is dead weight (sub-goal done, no downstream consumer, or superseded by a later read), call drop_context to stub it. Otherwise rely on automatic pruning don't carry stale reads into new sub-goals.
175
+ - **Batch writes and commands too, not just reads**: the executor runs ALL returned tool_calls (reads, writes, commands) before the next LLM call. Emit independent edit_file / write_file / run_command in one response when the chain is clear don't serialize them across turns just because they have side effects. (The read-only batching note in Step Economy applies to writes the same way.)
167
176
  - **Chain shell workflows in a single \`run_command\`**: use \`&&\`, \`;\`, \`|\`, \`>\`, heredocs to fold multi-step scripts (\`mkdir -p x && cat > x/file.ts <<'EOF' ... EOF && npm test\`) into one call. Only emit a follow-up turn when the result forces a decision (error, ambiguous output, branching logic).
168
177
 
169
178
  ## Large file writes (avoid token-cap truncation)
@@ -182,18 +191,15 @@ ${PLATFORM_NOTE}
182
191
  - Operate only within authorized scope; when unsure, ask — don't guess.
183
192
 
184
193
  ${memorySection}
185
- ${autoAllToolsLine}
186
- ${planLine}
187
194
 
188
- ## Working notepad (todolist) — checklist for complex tasks
189
- - For **complex multi-step tasks** (≥3 file changes OR ≥5 tool calls expected OR user says "先计划再执行" / "plan then do" / "按步骤来"), call the \`todolist\` tool FIRST to write a plan to \`.mocode/plans/<id>.md\`, then execute step by step, calling \`todolist update\` to mark progress. For trivial single-step tasks, skip it and just execute.
190
- - The plan is file-backed (survives context compression, user can see/edit). The active plan summary is auto-injected into the system prompt each turn, so you can re-read it via \`todolist read\` whenever you're unsure of your place.
191
- - Single plan per session: \`todolist create\` refuses if an in-progress plan already exists finish or abandon it first.
192
- - **Lifecycle** (5 actions total): \`create\` / \`read\` / \`update\` / \`add_step\` / \`finish\` for normal flow. \`finish plan_status=finished\` AUTO-ARCHIVES the plan to \`.mocode/plans/archive/<id>.md\` (history preserved, active dir stays clean). To revisit old plans: \`list scope=archived\` (or \`all\`) + \`unarchive id=<id>\` to bring back. \`delete id=<id>\` permanently removes (any location); cannot delete the currently active plan.
193
- - Don't over-use it: for a single edit or a quick lookup, \`todolist\` is overhead. The threshold is "this needs ≥3 steps OR I might forget the plan after context compaction."
195
+ ## Working notepad (todolist) — for multi-step tasks
196
+ - For tasks spanning **≥2 independent modules** OR when the user asks for stepwise progress ("先计划再执行" / "plan then do" / "按步骤来"), call \`todolist create\` first to write the plan to \`.mocode/plans/<id>.md\`, then \`todolist update\` to mark progress as you go. For single-file edits or quick lookups, skip it.
197
+ - The plan is file-backed (survives context compression; user can see/edit), and the active plan summary is auto-injected into this system prompt each turn. Re-read via \`todolist read\` when unsure of your place.
198
+ - See the \`todolist\` tool description for the full action set (create / read / update / add_step / finish / list / unarchive / delete) and lifecycle.
194
199
 
195
200
  ## Termination & Reporting
196
201
  - Stop immediately when no more tools are needed; give conclusions directly.
202
+ - **No flattery / no preamble in conclusions**: skip "Sure", "好的", "我已经完成了" and similar no-information prefixes — jump straight to substance.
197
203
  - Report honestly: say success when successful, say where you're stuck when failing, and mention anything skipped. Reference code in "path:line" format (e.g., src/index.ts:42). Keep it concise.`;
198
204
  }
199
205
  /**
@@ -33,7 +33,8 @@ const SLASH_COMMANDS = [
33
33
  { name: '/context', desc: '显示上下文用量条' },
34
34
  { name: '/skills', desc: '列出已发现的 skill' },
35
35
  { name: '/compact', desc: '压缩历史(可带焦点 /compact …)' },
36
- { name: '/resume', desc: '续接已保存的会话' },
36
+ { name: '/resume', desc: '续接最近 10 个已保存会话(快速)' },
37
+ { name: '/sessions', desc: '浏览全部已保存会话(慢,翻历史用)' },
37
38
  { name: '/rollback', desc: '菜单选轮次回滚(↑↓·Enter)' },
38
39
  { name: '/memory', desc: '记忆库:条目计数与近期索引(关闭时提示先开 /memory_switch)' },
39
40
  { name: '/memory_switch', desc: '切换记忆子系统开关(无参=切换;/on 或 /off 显式;持久化 MEMORY_ENABLED)' },
@@ -738,6 +739,31 @@ export async function startRepl(initialHistory, sessionId, updateNotice = null,
738
739
  layout.contentWrite('\n'); // 轮次之间空行
739
740
  return ok;
740
741
  };
742
+ /** 把 picker 选中的会话加载进 REPL(刷 history + 重建 snapshots + 重画)。/resume / /sessions 共用。 */
743
+ async function resumeFromPick(pick) {
744
+ if (!pick)
745
+ return; // Esc / Ctrl+D 取消
746
+ const loaded = loadSession(pick.id);
747
+ if (!loaded || !loaded.history.length) {
748
+ layout.contentWrite(`${ui.yellow}(加载失败)${ui.reset}\n`);
749
+ return;
750
+ }
751
+ if (loaded.history[0]?.role === 'system') {
752
+ loaded.history[0] = { role: 'system', content: buildSystemMessage(false) };
753
+ }
754
+ history.length = 0;
755
+ history.push(...loaded.history);
756
+ setAgentMode('auto'); // 续接重置为 auto(mode 不落盘;listener 重写 history[0] 回 auto,与 loaded 幂等)
757
+ currentSessionId = loaded.id;
758
+ // 读回该会话的轮次/快照;无文件则从 history 重建 turns(无快照→旧轮次文件改动不可撤销)
759
+ if (!loadSnapshots(loaded.id))
760
+ rebuildFromHistory(history);
761
+ contextState.lastUsage = undefined;
762
+ lastTurnUsage = undefined; // 续接:旧会话的 token 累计已无意义,清空等下轮覆写
763
+ layout.clearContent();
764
+ renderHistory(history);
765
+ layout.contentWrite(`${ui.dim}(已续接会话 ${loaded.id})${ui.reset}\n`);
766
+ }
741
767
  while (true) {
742
768
  // INPUT 态:画底栏输入框 + 状态行,光标入输入框
743
769
  refreshStatusBase(history);
@@ -1029,10 +1055,11 @@ export async function startRepl(initialHistory, sessionId, updateNotice = null,
1029
1055
  }
1030
1056
  continue;
1031
1057
  }
1032
- if (line === '/resume') {
1033
- // /resume:打开会话菜单(↑/↓ 选,Enter 续接,Esc 取消)。默认仅最近 10 条,按 a 展开全部。
1034
- // 仿 /rollback 菜单化(promptSessionPicker);选中项 cyan+bold + ▸ 高亮。
1035
- const sessions = listSessions();
1058
+ if (line === '/sessions') {
1059
+ // /sessions:浏览全部已保存会话(慢路径,readdir+全量 JSON.parse,目录 N 大时会有可感知卡顿)
1060
+ // 默认走 /resume(仅最近 10 条,瞬开);要翻历史续接更早的会话才用这条。
1061
+ // picker 走全显(cap=items.length,无 a 展开提示),靠 picker 自身开窗(以选中为中心分屏)
1062
+ const sessions = listSessions(); // 不传 limit = 全量
1036
1063
  if (sessions.length === 0) {
1037
1064
  layout.contentWrite(`${ui.dim}(没有已保存的会话)${ui.reset}\n`);
1038
1065
  continue;
@@ -1044,33 +1071,37 @@ export async function startRepl(initialHistory, sessionId, updateNotice = null,
1044
1071
  }));
1045
1072
  let pick;
1046
1073
  try {
1047
- pick = await promptSessionPicker(items);
1074
+ pick = await promptSessionPicker(items, items.length);
1048
1075
  }
1049
1076
  catch {
1050
1077
  continue; // Ctrl+C(SIGINT)→ 取消
1051
1078
  }
1052
- if (!pick)
1053
- continue; // Esc / Ctrl+D 取消
1054
- const loaded = loadSession(pick.id);
1055
- if (!loaded || !loaded.history.length) {
1056
- layout.contentWrite(`${ui.yellow}(加载失败)${ui.reset}\n`);
1079
+ await resumeFromPick(pick);
1080
+ continue;
1081
+ }
1082
+ if (line === '/resume') {
1083
+ // /resume:打开会话菜单(↑/↓ 选,Enter 续接,Esc 取消)。只加载最近 10 条,
1084
+ // 避免 sessions 目录堆了几百个会话时 readdir+全量 JSON.parse 卡顿。
1085
+ // 仿 /rollback 菜单化(promptSessionPicker);选中项 cyan+bold + ▸ 高亮。
1086
+ // 要续接更早的会话请用 /sessions 翻全表,或 CLI `mocode --resume <id>`。
1087
+ const sessions = listSessions(10);
1088
+ if (sessions.length === 0) {
1089
+ layout.contentWrite(`${ui.dim}(没有已保存的会话)${ui.reset}\n`);
1057
1090
  continue;
1058
1091
  }
1059
- if (loaded.history[0]?.role === 'system') {
1060
- loaded.history[0] = { role: 'system', content: buildSystemMessage(false) };
1092
+ const items = sessions.map((s) => ({
1093
+ id: s.id,
1094
+ title: s.firstUser || '(无)',
1095
+ subtitle: `${s.id} ${s.model}`,
1096
+ }));
1097
+ let pick;
1098
+ try {
1099
+ pick = await promptSessionPicker(items);
1061
1100
  }
1062
- history.length = 0;
1063
- history.push(...loaded.history);
1064
- setAgentMode('auto'); // /resume 重置为 auto(mode 不落盘;listener 重写 history[0] 回 auto,与 loaded 幂等)
1065
- currentSessionId = loaded.id;
1066
- // 读回该会话的轮次/快照;无文件则从 history 重建 turns(无快照→旧轮次文件改动不可撤销)
1067
- if (!loadSnapshots(loaded.id))
1068
- rebuildFromHistory(history);
1069
- contextState.lastUsage = undefined;
1070
- lastTurnUsage = undefined; // /resume:旧会话的 token 累计已无意义,清空等下轮覆写
1071
- layout.clearContent();
1072
- renderHistory(history);
1073
- layout.contentWrite(`${ui.dim}(已续接会话 ${loaded.id})${ui.reset}\n`);
1101
+ catch {
1102
+ continue; // Ctrl+C(SIGINT)→ 取消
1103
+ }
1104
+ await resumeFromPick(pick);
1074
1105
  continue;
1075
1106
  }
1076
1107
  if (line === '/theme' || line.startsWith('/theme ')) {
@@ -81,14 +81,24 @@ export function loadSession(id) {
81
81
  return null;
82
82
  }
83
83
  }
84
- /** 列出所有会话,按 createdAt 降序。损坏文件跳过。 */
85
- export function listSessions() {
84
+ /** 列出最近会话,按 createdAt 降序。损坏文件跳过。
85
+ * - limit?: 仅返回前 N 条。会话文件名是 YYYYMMDD-HHmmss.json,字典序=时间序;
86
+ * 先按文件名降序取前 N,再只解析这 N 个文件(history 大字段全部跳过不读),避免
87
+ * /resume 在 sessions 目录堆了几百个文件时 readdirSync + 全量 JSON.parse 慢。
88
+ * - 不传 limit 时读全部(向后兼容,供裸 --resume 列全表用)。
89
+ */
90
+ export function listSessions(limit) {
86
91
  if (!existsSync(config.sessionDir))
87
92
  return [];
93
+ // 过滤掉 .snapshots.json:ASCII 排序里 's'(115) > 'j'(106),后者排在前面,会让
94
+ // slice(0, limit) 取到一堆快照文件(JSON.parse 后 rec.id=undefined 被吞),真会话被挤掉。
95
+ const all = readdirSync(config.sessionDir)
96
+ .filter((f) => f.endsWith('.json') && !f.endsWith('.snapshots.json'))
97
+ .sort() // YYYYMMDD-HHmmss.json 字典序 ≡ 时间序(同 createdAt 升序)
98
+ .reverse(); // 降序:最新在前
99
+ const toRead = typeof limit === 'number' ? all.slice(0, Math.max(0, limit)) : all;
88
100
  const out = [];
89
- for (const f of readdirSync(config.sessionDir)) {
90
- if (!f.endsWith('.json'))
91
- continue;
101
+ for (const f of toRead) {
92
102
  try {
93
103
  const rec = JSON.parse(readFileSync(path.join(config.sessionDir, f), 'utf8'));
94
104
  if (rec && typeof rec.id === 'string') {
@@ -104,6 +114,5 @@ export function listSessions() {
104
114
  // 跳过损坏文件
105
115
  }
106
116
  }
107
- out.sort((a, b) => (a.createdAt < b.createdAt ? 1 : -1));
108
117
  return out;
109
118
  }
package/dist/ui/layout.js CHANGED
@@ -567,7 +567,7 @@ export function clearSelection() {
567
567
  export function setPasteHandler(fn) {
568
568
  pasteHandler = fn;
569
569
  }
570
- /** picker / 介入面板期间禁用鼠标选区与滚轮(避免 viewport 重画覆盖菜单);面板退出后恢复。 */
570
+ /** picker / 介入面板期间禁用鼠标选区与拖拽(避免 viewport 重画覆盖菜单);滚轮仍可用。面板退出后恢复。 */
571
571
  export function setMouseEnabled(v) {
572
572
  mouseEnabled = v;
573
573
  if (!v) {
@@ -627,8 +627,9 @@ function handleMouseEvent(e) {
627
627
  if (!active)
628
628
  return;
629
629
  if (e.type === 'wheel') {
630
- if (mouseEnabled)
631
- scrollBy(e.dir * WHEEL_LINES);
630
+ // 滚轮始终可用:面板/picker 期间也允许上下查看 agent 输出,
631
+ // onRunningKey 的 PgUp/PgDn 行为一致;mouseEnabled 仅管选区/拖拽。
632
+ scrollBy(e.dir * WHEEL_LINES);
632
633
  return;
633
634
  }
634
635
  if (!mouseEnabled)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mocode-ai",
3
- "version": "0.4.3",
3
+ "version": "0.4.4",
4
4
  "description": "终端编码 agent:LLM + tool-call 循环 + 流式输出(含思考)+ 16 个工具,接任意 OpenAI 兼容后端。",
5
5
  "type": "module",
6
6
  "bin": {