micro-models-agent 0.59.0 → 0.60.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (233) hide show
  1. package/CHANGELOG.md +584 -564
  2. package/README.md +358 -358
  3. package/dist/certification/certifications.json +493 -493
  4. package/dist/i18n/en.json +746 -718
  5. package/dist/i18n/ru.json +746 -718
  6. package/dist/main.js +566 -70
  7. package/dist/modules/browser/bridge-server.mjs +219 -219
  8. package/dist/skills/builtin/git.md +36 -36
  9. package/dist/skills/builtin/typescript.md +35 -35
  10. package/package.json +51 -51
  11. package/dist/cli/commands.js +0 -447
  12. package/dist/cli/completer.js +0 -167
  13. package/dist/cli/index.js +0 -2
  14. package/dist/cli/main.js +0 -153
  15. package/dist/cli/plugin-commands.js +0 -36
  16. package/dist/cli/repl-commands.js +0 -761
  17. package/dist/cli/repl.js +0 -702
  18. package/dist/cli/run-result.js +0 -33
  19. package/dist/cli/security-commands.js +0 -164
  20. package/dist/cli/setup.js +0 -237
  21. package/dist/config/config.js +0 -276
  22. package/dist/config/defaults.js +0 -141
  23. package/dist/config/domains.js +0 -179
  24. package/dist/config/experts.js +0 -15
  25. package/dist/config/index.js +0 -4
  26. package/dist/config/security.js +0 -213
  27. package/dist/config/types.js +0 -1
  28. package/dist/core/agent-moe.js +0 -102
  29. package/dist/core/agent.js +0 -1018
  30. package/dist/core/bootstrap.js +0 -481
  31. package/dist/core/crash-handler.js +0 -51
  32. package/dist/core/environment.js +0 -199
  33. package/dist/core/index.js +0 -2
  34. package/dist/core/prompt-builder.js +0 -76
  35. package/dist/core/session-logger.js +0 -251
  36. package/dist/core/types.js +0 -1
  37. package/dist/core/version.js +0 -26
  38. package/dist/core/workspace.js +0 -76
  39. package/dist/i18n/index.js +0 -46
  40. package/dist/index.js +0 -22
  41. package/dist/llm/image-utils.js +0 -143
  42. package/dist/llm/index.js +0 -4
  43. package/dist/llm/model-loader.js +0 -78
  44. package/dist/llm/openai-compat.js +0 -497
  45. package/dist/llm/orchestrator.js +0 -200
  46. package/dist/llm/provider.js +0 -10
  47. package/dist/llm/response.js +0 -39
  48. package/dist/llm/token-counter.js +0 -39
  49. package/dist/llm/types.js +0 -1
  50. package/dist/logger/app-logger.js +0 -189
  51. package/dist/logger/file-log.js +0 -151
  52. package/dist/logger/index.js +0 -1
  53. package/dist/migration/backup.js +0 -45
  54. package/dist/migration/detect.js +0 -50
  55. package/dist/migration/index.js +0 -2
  56. package/dist/modules/artifacts/store.js +0 -61
  57. package/dist/modules/browser/actions.js +0 -76
  58. package/dist/modules/browser/bridge-client.js +0 -199
  59. package/dist/modules/browser/bridge-path.js +0 -10
  60. package/dist/modules/browser/cookie-store.js +0 -24
  61. package/dist/modules/browser/driver.js +0 -136
  62. package/dist/modules/browser/index.js +0 -7
  63. package/dist/modules/browser/module.js +0 -29
  64. package/dist/modules/browser/session.js +0 -342
  65. package/dist/modules/browser/snapshot.js +0 -148
  66. package/dist/modules/browser/types.js +0 -12
  67. package/dist/modules/certification/cli.js +0 -213
  68. package/dist/modules/certification/fact-checker.js +0 -82
  69. package/dist/modules/certification/loader.js +0 -106
  70. package/dist/modules/certification/manifest.js +0 -58
  71. package/dist/modules/certification/runner.js +0 -245
  72. package/dist/modules/certification/scenarios.js +0 -407
  73. package/dist/modules/certification/types.js +0 -1
  74. package/dist/modules/context/chunk-query.js +0 -100
  75. package/dist/modules/context/fact-extractor.js +0 -168
  76. package/dist/modules/context/history.js +0 -15
  77. package/dist/modules/context/index.js +0 -1
  78. package/dist/modules/context/manager.js +0 -440
  79. package/dist/modules/execution/audit-runners.js +0 -206
  80. package/dist/modules/execution/auditor.js +0 -218
  81. package/dist/modules/execution/execution-plugin.js +0 -431
  82. package/dist/modules/execution/index.js +0 -8
  83. package/dist/modules/execution/module.js +0 -625
  84. package/dist/modules/execution/moe-executor.js +0 -304
  85. package/dist/modules/execution/plan-coverage.js +0 -68
  86. package/dist/modules/execution/plan-persister.js +0 -46
  87. package/dist/modules/execution/plan-store.js +0 -196
  88. package/dist/modules/execution/plan-tool.js +0 -677
  89. package/dist/modules/execution/plan-validator.js +0 -153
  90. package/dist/modules/execution/planner.js +0 -94
  91. package/dist/modules/execution/stuck-detector.js +0 -746
  92. package/dist/modules/execution/tracker.js +0 -69
  93. package/dist/modules/execution/types.js +0 -1
  94. package/dist/modules/execution/verifier.js +0 -235
  95. package/dist/modules/execution/windows-commands.js +0 -41
  96. package/dist/modules/hallucination/confidence.js +0 -66
  97. package/dist/modules/hallucination/consistency.js +0 -26
  98. package/dist/modules/hallucination/detector.js +0 -47
  99. package/dist/modules/hallucination/factual.js +0 -169
  100. package/dist/modules/hallucination/index.js +0 -5
  101. package/dist/modules/hallucination/js-identifiers.js +0 -262
  102. package/dist/modules/hallucination/llm-judge.js +0 -101
  103. package/dist/modules/index.js +0 -5
  104. package/dist/modules/indexer/cache.js +0 -40
  105. package/dist/modules/indexer/index.js +0 -3
  106. package/dist/modules/indexer/module.js +0 -246
  107. package/dist/modules/indexer/project-profile.js +0 -183
  108. package/dist/modules/indexer/walker.js +0 -101
  109. package/dist/modules/lsp/check-tool.js +0 -58
  110. package/dist/modules/lsp/client.js +0 -389
  111. package/dist/modules/lsp/command.js +0 -60
  112. package/dist/modules/lsp/config.js +0 -135
  113. package/dist/modules/lsp/index.js +0 -3
  114. package/dist/modules/lsp/module.js +0 -260
  115. package/dist/modules/lsp/probe.js +0 -86
  116. package/dist/modules/lsp/project-root.js +0 -32
  117. package/dist/modules/lsp/startup-check.js +0 -144
  118. package/dist/modules/lsp/types.js +0 -1
  119. package/dist/modules/mcp/client.js +0 -399
  120. package/dist/modules/mcp/index.js +0 -3
  121. package/dist/modules/mcp/module.js +0 -142
  122. package/dist/modules/mcp/registry.js +0 -15
  123. package/dist/modules/memory/index.js +0 -1
  124. package/dist/modules/memory/module.js +0 -96
  125. package/dist/modules/memory/search.js +0 -42
  126. package/dist/modules/memory/store.js +0 -69
  127. package/dist/modules/pipelines/engine.js +0 -60
  128. package/dist/modules/pipelines/index.js +0 -3
  129. package/dist/modules/pipelines/parser.js +0 -56
  130. package/dist/modules/pipelines/template.js +0 -14
  131. package/dist/modules/plugins/builtin/lint-on-write.js +0 -334
  132. package/dist/modules/plugins/builtin/notify.js +0 -9
  133. package/dist/modules/plugins/index.js +0 -1
  134. package/dist/modules/plugins/loader.js +0 -70
  135. package/dist/modules/plugins/manager.js +0 -261
  136. package/dist/modules/plugins/types.js +0 -1
  137. package/dist/modules/pricing/index.js +0 -61
  138. package/dist/modules/pricing/prices.js +0 -129
  139. package/dist/modules/processes/detect.js +0 -34
  140. package/dist/modules/processes/index.js +0 -2
  141. package/dist/modules/processes/registry.js +0 -327
  142. package/dist/modules/processes/runner.js +0 -23
  143. package/dist/modules/providers/create.js +0 -22
  144. package/dist/modules/providers/fallback.js +0 -79
  145. package/dist/modules/providers/health.js +0 -46
  146. package/dist/modules/providers/index.js +0 -5
  147. package/dist/modules/providers/manager.js +0 -161
  148. package/dist/modules/providers/presets.js +0 -128
  149. package/dist/modules/providers/registry.js +0 -22
  150. package/dist/modules/providers/types.js +0 -1
  151. package/dist/modules/registry.js +0 -48
  152. package/dist/modules/security/audit-log.js +0 -136
  153. package/dist/modules/security/audit-notifier.js +0 -292
  154. package/dist/modules/security/command-validator.js +0 -219
  155. package/dist/modules/security/content-scanner.js +0 -53
  156. package/dist/modules/security/data-sanitizer.js +0 -89
  157. package/dist/modules/security/encryption.js +0 -242
  158. package/dist/modules/security/index.js +0 -14
  159. package/dist/modules/security/network-validator.js +0 -88
  160. package/dist/modules/security/path-validator.js +0 -203
  161. package/dist/modules/security/rate-limiter.js +0 -119
  162. package/dist/modules/security/security-policies.js +0 -531
  163. package/dist/modules/security/session-encryption.js +0 -210
  164. package/dist/modules/security/session-isolation.js +0 -95
  165. package/dist/modules/session/index.js +0 -3
  166. package/dist/modules/session/manager.js +0 -172
  167. package/dist/modules/session/module.js +0 -24
  168. package/dist/modules/session/store.js +0 -222
  169. package/dist/modules/session/types.js +0 -1
  170. package/dist/modules/skills/index.js +0 -2
  171. package/dist/modules/skills/loader.js +0 -72
  172. package/dist/modules/skills/matcher.js +0 -27
  173. package/dist/modules/skills/module.js +0 -129
  174. package/dist/modules/types.js +0 -1
  175. package/dist/modules/updater/checker.js +0 -96
  176. package/dist/modules/updater/index.js +0 -2
  177. package/dist/modules/updater/module.js +0 -116
  178. package/dist/modules/user-profile/compressor.js +0 -16
  179. package/dist/modules/user-profile/index.js +0 -1
  180. package/dist/modules/user-profile/profile.js +0 -68
  181. package/dist/tools/approve.js +0 -33
  182. package/dist/tools/attach-image.js +0 -101
  183. package/dist/tools/bash.js +0 -519
  184. package/dist/tools/browser.js +0 -115
  185. package/dist/tools/chunk-query.js +0 -100
  186. package/dist/tools/create-dir.js +0 -56
  187. package/dist/tools/delete-file.js +0 -63
  188. package/dist/tools/download-file.js +0 -117
  189. package/dist/tools/edit-file.js +0 -80
  190. package/dist/tools/enable-tools.js +0 -59
  191. package/dist/tools/executor.js +0 -154
  192. package/dist/tools/file-info.js +0 -47
  193. package/dist/tools/filter-tools.js +0 -17
  194. package/dist/tools/glob-tool.js +0 -27
  195. package/dist/tools/grep-tool.js +0 -125
  196. package/dist/tools/hidden-tools-block.js +0 -37
  197. package/dist/tools/index.js +0 -78
  198. package/dist/tools/list-dir.js +0 -49
  199. package/dist/tools/load-skill.js +0 -43
  200. package/dist/tools/mcp-call.js +0 -69
  201. package/dist/tools/move-file.js +0 -86
  202. package/dist/tools/path-utils.js +0 -101
  203. package/dist/tools/pipeline-run.js +0 -145
  204. package/dist/tools/preview.js +0 -2
  205. package/dist/tools/process-kill.js +0 -40
  206. package/dist/tools/process-list.js +0 -37
  207. package/dist/tools/process-log.js +0 -54
  208. package/dist/tools/question.js +0 -141
  209. package/dist/tools/read-file.js +0 -179
  210. package/dist/tools/recall.js +0 -118
  211. package/dist/tools/registry.js +0 -47
  212. package/dist/tools/remember.js +0 -68
  213. package/dist/tools/scope-check.js +0 -32
  214. package/dist/tools/search-history.js +0 -85
  215. package/dist/tools/subagent.js +0 -196
  216. package/dist/tools/types.js +0 -1
  217. package/dist/tools/user-input.js +0 -123
  218. package/dist/tools/web-browse.js +0 -87
  219. package/dist/tools/web-fetch.js +0 -119
  220. package/dist/tools/web-search.js +0 -105
  221. package/dist/tools/write-file.js +0 -82
  222. package/dist/ui/box.js +0 -77
  223. package/dist/ui/colors.js +0 -4
  224. package/dist/ui/diff.js +0 -178
  225. package/dist/ui/index.js +0 -6
  226. package/dist/ui/line-editor.js +0 -822
  227. package/dist/ui/line-math.js +0 -73
  228. package/dist/ui/md-formatter.js +0 -212
  229. package/dist/ui/output.js +0 -13
  230. package/dist/ui/plan-view.js +0 -103
  231. package/dist/ui/renderer.js +0 -259
  232. package/dist/ui/spinner.js +0 -70
  233. package/dist/ui/table.js +0 -144
@@ -1,761 +0,0 @@
1
- import { pc } from "../ui/colors";
2
- import { readMmaVersion } from "../core/version";
3
- import { renderTable } from "../ui/table";
4
- import { t } from "../i18n/index";
5
- import { runSetup } from "./setup";
6
- import { saveConfig } from "../config/config";
7
- import { getMessageText } from "../llm/provider";
8
- import { join, dirname } from "path";
9
- import { homedir } from "os";
10
- import { existsSync } from "fs";
11
- const version = readMmaVersion();
12
- export const COMMAND_GROUPS = {
13
- help: "general",
14
- exit: "general",
15
- clear: "general",
16
- run: "general",
17
- image: "general",
18
- config: "agent",
19
- status: "agent",
20
- reasoning: "agent",
21
- provider: "agent",
22
- model: "agent",
23
- context: "agent",
24
- reload: "agent",
25
- wizard: "agent",
26
- sysprompt: "agent",
27
- lsp: "agent",
28
- sessions: "session",
29
- new: "session",
30
- resume: "session",
31
- rename: "session",
32
- delete: "session",
33
- skill: "skill",
34
- plugins: "agent",
35
- };
36
- export function registerAllCommands(ctx) {
37
- registerBuiltinCommands(ctx);
38
- registerMmaCommands(ctx);
39
- registerSessionCommands(ctx);
40
- registerSkillCommands(ctx);
41
- }
42
- function registerBuiltinCommands(ctx) {
43
- ctx.registerCommand({
44
- name: "help",
45
- description: t("repl.help"),
46
- usage: t("repl.help_usage"),
47
- action: () => ctx.showHelp(),
48
- });
49
- ctx.registerCommand({
50
- name: "exit",
51
- description: t("repl.exit"),
52
- aliases: ["quit", "q"],
53
- usage: t("repl.exit_usage"),
54
- action: () => ctx.stop(),
55
- });
56
- ctx.registerCommand({
57
- name: "clear",
58
- description: t("repl.clear"),
59
- usage: t("repl.clear_usage"),
60
- action: () => {
61
- console.clear();
62
- },
63
- });
64
- }
65
- function registerMmaCommands(ctx) {
66
- ctx.registerCommand({
67
- name: "run",
68
- description: t("repl.run"),
69
- usage: t("repl.run_usage"),
70
- action: async (args) => {
71
- if (args.length === 0) {
72
- console.log(t("repl.run_usage"));
73
- return;
74
- }
75
- const prompt = args.join(" ");
76
- await ctx.runAgent(prompt);
77
- },
78
- });
79
- ctx.registerCommand({
80
- name: "image",
81
- description: t("repl.image"),
82
- aliases: ["img"],
83
- usage: t("repl.image_usage"),
84
- action: async (args) => {
85
- const source = args.join(" ");
86
- if (!source) {
87
- console.log(t("repl.image_usage"));
88
- return;
89
- }
90
- try {
91
- const { loadFileAsDataUrl, loadUrlAsDataUrl, readClipboardImage } = await import("../llm/image-utils");
92
- const { existsSync } = await import("fs");
93
- const { resolve } = await import("path");
94
- let dataUrl;
95
- let label;
96
- if (source.toLowerCase() === "clipboard") {
97
- const clipBuf = await readClipboardImage();
98
- if (!clipBuf) {
99
- console.log(pc.yellow(t("image.clipboard_empty")));
100
- return;
101
- }
102
- const { bufferToDataUrl } = await import("../llm/image-utils");
103
- const result = await bufferToDataUrl(clipBuf);
104
- dataUrl = result.dataUrl;
105
- label = "clipboard";
106
- }
107
- else if (source.startsWith("http://") || source.startsWith("https://")) {
108
- const result = await loadUrlAsDataUrl(source);
109
- dataUrl = result.dataUrl;
110
- label = source;
111
- }
112
- else {
113
- const absPath = resolve(process.cwd(), source);
114
- if (!existsSync(absPath)) {
115
- console.log(pc.red(t("image.not_found", { path: source })));
116
- return;
117
- }
118
- const result = await loadFileAsDataUrl(absPath);
119
- dataUrl = result.dataUrl;
120
- label = source;
121
- }
122
- const contextManager = ctx.agent.contextManager;
123
- if (!contextManager) {
124
- console.log(pc.red(t("image.no_context")));
125
- return;
126
- }
127
- contextManager.addPendingImage({
128
- type: "image_url",
129
- image_url: { url: dataUrl },
130
- });
131
- const sizeKb = Math.round((dataUrl.length * 3) / 4 / 1024);
132
- console.log(pc.green(t("image.attached", { source: label, size: `${sizeKb} KB` })));
133
- }
134
- catch (err) {
135
- console.log(pc.red(t("image.error", { message: err.message })));
136
- }
137
- },
138
- });
139
- ctx.registerCommand({
140
- name: "config",
141
- description: t("repl.config"),
142
- usage: t("repl.config_usage"),
143
- action: () => {
144
- const cfg = ctx.config;
145
- const ctxW = cfg.contextWindow;
146
- const sys = Math.floor(ctxW * cfg.contextBudget.systemPrompt);
147
- const res = Math.floor(ctxW * cfg.contextBudget.responseReserve);
148
- console.log(`${t("repl.model")} ${cfg.model}`);
149
- const providers = ctx.agent.listProviders();
150
- const active = providers.find((p) => p.active);
151
- if (active) {
152
- console.log(`${t("repl.provider")} ${active.label} (${pc.dim(active.type)}) → ${pc.dim(active.baseUrl)}`);
153
- }
154
- else {
155
- console.log(`${t("repl.provider")} ${cfg.provider.type} → ${cfg.provider.baseUrl}`);
156
- }
157
- console.log(`${t("repl.context")} ${ctxW} (sys:${sys} res:${res} hist:${ctxW - sys - res})`);
158
- console.log(`${t("repl.max_iters")} ${cfg.maxToolIterations}`);
159
- console.log(`${t("repl.stuck_thresh")} ${cfg.stuckThreshold}`);
160
- console.log(`${t("repl.reasoning_label")} ${cfg.showReasoning ? pc.green(t("repl.show")) : pc.dim(t("repl.hide"))}`);
161
- console.log(`${t("repl.log_level")} ${cfg.logLevel}`);
162
- console.log(`${t("repl.locale")} ${cfg.locale}`);
163
- const meta = ctx.sessionManager?.getActiveMeta();
164
- if (meta) {
165
- console.log(`${t("repl.session_label")} ${meta.name} (${meta.id}) — ${meta.messageCount} msgs`);
166
- }
167
- },
168
- });
169
- ctx.registerCommand({
170
- name: "config migrate",
171
- description: t("cli.migrate_config"),
172
- action: async () => {
173
- const { hasDomainFiles } = await import("../config/domains");
174
- const { loadConfig: loadCfg } = await import("../config/config");
175
- const configDir = ctx.configDir;
176
- const configPath = join(configDir, "config.json");
177
- if (hasDomainFiles(configDir)) {
178
- console.log(pc.yellow(t("config.migrate_no_legacy")));
179
- return;
180
- }
181
- if (!existsSync(configPath)) {
182
- console.log(pc.yellow(t("config.migrate_no_legacy")));
183
- return;
184
- }
185
- console.log(t("config.migrate_start"));
186
- const { config } = loadCfg({ configDir, projectConfigPath: join(configDir, ".mmrc") });
187
- saveConfig(config, configPath, configDir);
188
- const { renameSync, readdirSync } = await import("fs");
189
- renameSync(configPath, configPath + ".bak");
190
- const domainFiles = readdirSync(join(configDir, "config")).filter((f) => f.endsWith(".json"));
191
- console.log(pc.green(t("config.migrate_done", { count: String(domainFiles.length) })));
192
- },
193
- });
194
- ctx.registerCommand({
195
- name: "reasoning",
196
- description: t("repl.reasoning"),
197
- usage: t("repl.reasoning_usage"),
198
- action: () => {
199
- ctx.config.showReasoning = !ctx.config.showReasoning;
200
- const status = ctx.config.showReasoning ? pc.green(t("repl.show")) : pc.dim(t("repl.hide"));
201
- console.log(t("repl.reasoning_status", { status }));
202
- },
203
- });
204
- ctx.registerCommand({
205
- name: "status",
206
- description: t("repl.status"),
207
- usage: t("repl.status_usage"),
208
- action: () => {
209
- const providers = ctx.agent.listProviders();
210
- const active = providers.find((p) => p.active);
211
- console.log(`${t("repl.model")} ${ctx.config.model}`);
212
- if (active) {
213
- console.log(`${t("repl.provider")} ${active.label} (${pc.dim(active.type)}) @ ${pc.dim(active.baseUrl)}`);
214
- }
215
- else {
216
- console.log(`${t("repl.provider")} ${ctx.config.provider.type} @ ${ctx.config.provider.baseUrl}`);
217
- }
218
- const meta = ctx.sessionManager?.getActiveMeta();
219
- if (meta) {
220
- console.log(`${t("repl.session_label")} ${meta.name} (${meta.id}) — ${meta.messageCount} messages`);
221
- }
222
- },
223
- });
224
- ctx.registerCommand({
225
- name: "wizard",
226
- description: t("repl.wizard"),
227
- aliases: ["setup"],
228
- usage: t("repl.wizard_usage"),
229
- action: async () => {
230
- console.log(pc.yellow(t("repl.wizard_running")));
231
- await ctx.withExclusiveInput(async () => {
232
- const answers = await runSetup(ctx.rl);
233
- const configPath = join(homedir(), ".mma", "config.json");
234
- ctx.config.provider.type = answers.provider;
235
- ctx.config.provider.baseUrl = answers.apiBase;
236
- ctx.config.provider.apiKey = answers.apiKey;
237
- ctx.config.model = answers.model;
238
- ctx.config.contextWindow = answers.contextWindow;
239
- ctx.config.maxToolIterations = answers.maxToolIterations;
240
- ctx.config.locale = answers.locale;
241
- saveConfig(ctx.config, configPath, dirname(configPath));
242
- await ctx.agent.reconfigure(ctx.config);
243
- console.log(pc.green(t("cli.config_saved")));
244
- });
245
- },
246
- });
247
- ctx.registerCommand({
248
- name: "sysprompt",
249
- description: t("repl.sysprompt_desc"),
250
- usage: t("repl.sysprompt_desc"),
251
- action: () => {
252
- const info = ctx.agent.getSystemPromptInfo();
253
- console.log(pc.bold(`System prompt (${info.tokenCount} tokens):`));
254
- console.log(pc.dim("─".repeat(60)));
255
- for (const line of info.text.split("\n")) {
256
- console.log(line);
257
- }
258
- console.log(pc.dim("─".repeat(60)));
259
- if (info.excluded.length > 0) {
260
- console.log(pc.yellow(`\nExcluded blocks: ${info.excluded.length}`));
261
- for (const e of info.excluded) {
262
- console.log(pc.dim(` - ${e.slice(0, 80)}${e.length > 80 ? "..." : ""}`));
263
- }
264
- }
265
- },
266
- });
267
- ctx.registerCommand({
268
- name: "provider",
269
- description: t("repl.provider_list"),
270
- usage: t("repl.provider_usage"),
271
- action: async (args) => {
272
- const subcmd = args[0];
273
- if (!subcmd || subcmd === "list") {
274
- const providers = ctx.agent.listProviders();
275
- if (providers.length === 0) {
276
- console.log(`${t("repl.provider_current")} ${ctx.config.provider.type}`);
277
- console.log(` ${ctx.config.provider.baseUrl}`);
278
- }
279
- else {
280
- console.log(t("repl.provider_current"));
281
- for (const p of providers) {
282
- const marker = p.active ? pc.green("* ") : " ";
283
- console.log(` ${marker}${p.label} (${pc.dim(p.type)}) ${pc.dim(p.baseUrl)}`);
284
- }
285
- }
286
- return;
287
- }
288
- if (subcmd === "use") {
289
- const name = args[1];
290
- if (!name) {
291
- console.log(t("repl.provider_usage"));
292
- return;
293
- }
294
- try {
295
- await ctx.agent.setProvider(name);
296
- ctx.refreshModelCache();
297
- console.log(pc.green(t("repl.provider_set", { name })));
298
- }
299
- catch (e) {
300
- console.log(pc.red(e.message));
301
- }
302
- return;
303
- }
304
- console.log(t("repl.provider_usage"));
305
- },
306
- });
307
- ctx.registerCommand({
308
- name: "model",
309
- description: t("repl.model_list"),
310
- usage: t("repl.model_usage"),
311
- action: async (args) => {
312
- const subcmd = args[0];
313
- if (!subcmd || subcmd === "list") {
314
- console.log(`${t("repl.model_current")} ${ctx.config.model}`);
315
- const { OpenAICompatProvider } = await import("../llm/openai-compat");
316
- const provider = new OpenAICompatProvider({
317
- model: ctx.config.model,
318
- baseUrl: ctx.config.provider.baseUrl,
319
- apiKey: ctx.config.provider.apiKey,
320
- contextWindow: ctx.config.contextWindow,
321
- });
322
- const { Spinner } = await import("../ui/spinner");
323
- const s = new Spinner();
324
- s.start(t("cli.fetching_models"));
325
- try {
326
- const models = await provider.listModels();
327
- s.stop();
328
- if (models.length > 0) {
329
- ctx.refreshModelCache();
330
- console.log(t("cli.available_models"));
331
- const { getCertMark } = await import("../modules/certification/manifest");
332
- for (const m of models) {
333
- const marker = m === ctx.config.model ? pc.green("* ") : " ";
334
- const mark = getCertMark(m, ctx.config.provider.baseUrl, version, process.cwd());
335
- const cert = mark === "certified"
336
- ? pc.green("✔")
337
- : mark === "stale"
338
- ? pc.yellow("○")
339
- : pc.dim("·");
340
- console.log(` ${marker}${cert} ${m}`);
341
- }
342
- }
343
- else {
344
- console.log(t("cli.no_models_found"));
345
- }
346
- }
347
- catch (err) {
348
- s.stop();
349
- console.log(t("cli.model_fetch_failed", { error: String(err) }));
350
- }
351
- console.log(t("cli.model_hint"));
352
- return;
353
- }
354
- if (subcmd === "use") {
355
- const name = args[1];
356
- if (!name) {
357
- console.log(t("repl.model_usage"));
358
- return;
359
- }
360
- ctx.config.model = name;
361
- const configPath = join(homedir(), ".mma", "config.json");
362
- saveConfig(ctx.config, configPath, dirname(configPath));
363
- await ctx.agent.reconfigure(ctx.config);
364
- console.log(pc.green(t("repl.model_set", { name })));
365
- return;
366
- }
367
- console.log(t("repl.model_usage"));
368
- },
369
- });
370
- ctx.registerCommand({
371
- name: "context",
372
- description: t("cli.manage_context"),
373
- usage: "/context <size>",
374
- action: async (args) => {
375
- if (args.length === 0) {
376
- console.log(`/context ${t("repl.context")} ${ctx.config.contextWindow}`);
377
- console.log(`Usage: /context <size> (min 1024)`);
378
- return;
379
- }
380
- const size = parseInt(args[0], 10);
381
- if (isNaN(size) || size < 1024) {
382
- console.log(t("cli.invalid_context_size"));
383
- return;
384
- }
385
- ctx.config.contextWindow = size;
386
- const configPath = join(homedir(), ".mma", "config.json");
387
- saveConfig(ctx.config, configPath, dirname(configPath));
388
- await ctx.agent.reconfigure(ctx.config);
389
- console.log(pc.green(t("cli.context_set", { size })));
390
- },
391
- });
392
- ctx.registerCommand({
393
- name: "reload",
394
- description: t("repl.reload"),
395
- usage: t("repl.reload_usage"),
396
- action: async () => {
397
- console.log(pc.yellow(t("repl.reloading")));
398
- if (ctx.sessionManager && ctx.config.session.autoSave) {
399
- }
400
- ctx.agent.shutdown();
401
- const { loadConfig } = await import("../config/config");
402
- const { homedir } = await import("os");
403
- const { join } = await import("path");
404
- const configDir = ctx.configDir;
405
- const baseDir = ctx.baseDir;
406
- const projectConfigPath = join(baseDir, ".mmrc");
407
- const { config: freshConfig } = loadConfig({ configDir, projectConfigPath });
408
- Object.assign(ctx.config, freshConfig);
409
- const { bootstrap } = await import("../core/bootstrap");
410
- const result = await bootstrap(configDir, baseDir, false, false);
411
- ctx.agent = result.agent;
412
- ctx.sessionManager = result.sessionManager;
413
- ctx.skillsModule = result.skillsModule;
414
- ctx.pluginManager = result.pluginManager;
415
- ctx.setupCompleter();
416
- console.log(pc.green(t("repl.reloaded")));
417
- console.log(`${t("repl.model")} ${ctx.config.model}`);
418
- console.log(`${t("repl.context")} ${ctx.config.contextWindow}`);
419
- console.log(`${t("repl.provider")} ${ctx.config.provider.type} @ ${ctx.config.provider.baseUrl}`);
420
- },
421
- });
422
- ctx.registerCommand({
423
- name: "plugins",
424
- description: t("repl.plugins"),
425
- usage: t("repl.plugins_usage"),
426
- action: (args) => {
427
- if (!ctx.pluginManager) {
428
- console.log(t("cli.plugins.none"));
429
- return;
430
- }
431
- const showAll = args.includes("--all");
432
- const infos = ctx.pluginManager.getPluginInfos();
433
- const filtered = showAll ? infos : infos.filter(({ plugin }) => !plugin.isBuiltin);
434
- if (filtered.length === 0) {
435
- console.log(t("cli.plugins.none"));
436
- return;
437
- }
438
- const mmaVersion = version;
439
- console.log(t("cli.plugins.header", {
440
- count: String(filtered.length),
441
- mma: mmaVersion,
442
- }));
443
- for (const { plugin, source } of filtered) {
444
- const v = plugin.version || "-";
445
- const origin = source || "builtin";
446
- const mark = plugin.isBuiltin ? t("cli.plugins.builtin_mark") : " ";
447
- console.log(` ${mark} ${plugin.name} v${v} [${origin}]`);
448
- }
449
- if (!showAll) {
450
- const builtinCount = infos.filter(({ plugin }) => plugin.isBuiltin).length;
451
- if (builtinCount > 0) {
452
- console.log(pc.dim(` (${builtinCount} builtin hidden — /plugins --all to show)`));
453
- }
454
- }
455
- },
456
- });
457
- ctx.registerCommand({
458
- name: "lsp",
459
- description: t("repl.lsp"),
460
- usage: t("repl.lsp_usage"),
461
- action: async (args) => {
462
- const subcommand = args[0] || "status";
463
- // Access LSP module via the agent's module registry
464
- const lspModule = ctx.agent.getModule("lsp");
465
- if (!lspModule) {
466
- console.log(pc.yellow(t("repl.lsp_not_available")));
467
- return;
468
- }
469
- switch (subcommand) {
470
- case "status": {
471
- const disabled = lspModule.getDisabledServers();
472
- const failures = lspModule.getFailureCounts();
473
- const config = ctx.config.lsp;
474
- console.log(pc.bold(t("repl.lsp_status_header")));
475
- console.log(`${t("repl.lsp_enabled")} ${config?.enabled ? pc.green("yes") : pc.red("no")}`);
476
- if (disabled.length > 0) {
477
- console.log(pc.yellow(`${t("repl.lsp_disabled_servers")} ${disabled.join(", ")}`));
478
- }
479
- if (failures.size > 0) {
480
- console.log(pc.dim(t("repl.lsp_failure_counts")));
481
- for (const [server, count] of failures) {
482
- console.log(pc.dim(` ${server}: ${count}`));
483
- }
484
- }
485
- if (disabled.length === 0 && failures.size === 0) {
486
- console.log(pc.green(t("repl.lsp_all_ok")));
487
- }
488
- break;
489
- }
490
- case "restart": {
491
- console.log(pc.yellow(t("repl.lsp_restarting")));
492
- lspModule.resetDisabledServers();
493
- console.log(pc.green(t("repl.lsp_restarted")));
494
- break;
495
- }
496
- case "check": {
497
- const path = args[1];
498
- if (!path) {
499
- console.log(pc.yellow(t("repl.lsp_check_usage")));
500
- return;
501
- }
502
- console.log(pc.dim(t("repl.lsp_checking", { path })));
503
- // Run lsp_check tool via the agent's tool executor
504
- try {
505
- const result = await ctx.agent.deps?.toolExecutor?.execute("lsp_check", { path }, ctx.agent.deps?.toolCtx);
506
- if (result?.output) {
507
- console.log(result.output);
508
- }
509
- }
510
- catch (e) {
511
- console.log(pc.red(t("repl.lsp_check_error", {
512
- error: e instanceof Error ? e.message : String(e),
513
- })));
514
- }
515
- break;
516
- }
517
- default: {
518
- console.log(pc.dim(t("repl.lsp_usage")));
519
- break;
520
- }
521
- }
522
- },
523
- });
524
- }
525
- function registerSessionCommands(ctx) {
526
- if (!ctx.sessionManager)
527
- return;
528
- ctx.registerCommand({
529
- name: "sessions",
530
- description: t("repl.sessions"),
531
- aliases: ["ls"],
532
- usage: t("repl.sessions_usage"),
533
- action: () => {
534
- const sessions = ctx.sessionManager.list();
535
- const active = ctx.sessionManager.getActive();
536
- if (sessions.length === 0) {
537
- console.log(t("session.no_sessions_hint"));
538
- return;
539
- }
540
- const rows = sessions.map((s) => [
541
- s.id === active ? pc.green("●") : "",
542
- s.id.slice(0, 12),
543
- s.name,
544
- s.updatedAt.slice(0, 19).replace("T", " "),
545
- String(s.messageCount),
546
- ]);
547
- for (const line of renderTable([
548
- t("session.col_active"),
549
- t("session.col_id"),
550
- t("session.col_name"),
551
- t("session.col_updated"),
552
- t("session.col_msgs"),
553
- ], rows)) {
554
- console.log(line);
555
- }
556
- console.log(pc.dim(`\n ${t("repl.resume_hint")}`));
557
- },
558
- });
559
- ctx.registerCommand({
560
- name: "new",
561
- description: t("repl.new"),
562
- aliases: ["create"],
563
- usage: t("repl.new_usage"),
564
- action: (args) => {
565
- const name = args.join(" ") || undefined;
566
- const meta = ctx.sessionManager.create(name);
567
- ctx.agent.clearContext();
568
- console.clear();
569
- console.log(`${t("session.created", { name: meta.name })} (${pc.dim(meta.id.slice(0, 12))})`);
570
- console.log(pc.dim(` ${t("session.chat_cleared")}\n`));
571
- },
572
- });
573
- ctx.registerCommand({
574
- name: "resume",
575
- description: t("repl.resume"),
576
- aliases: ["switch", "use"],
577
- usage: t("repl.resume_usage"),
578
- action: (args) => {
579
- const query = args.join(" ");
580
- const sessions = ctx.sessionManager.list();
581
- if (!query) {
582
- console.log(pc.dim(t("session.available")));
583
- const active = ctx.sessionManager.getActive();
584
- for (const s of sessions) {
585
- const marker = s.id === active ? pc.green(" *") : " ";
586
- console.log(pc.dim(` ${marker} ${s.id.slice(0, 12)} ${s.name}`));
587
- }
588
- console.log(pc.dim(`\n ${t("repl.resume_usage")}`));
589
- return;
590
- }
591
- const match = sessions.find((s) => s.id === query ||
592
- s.id.startsWith(query) ||
593
- s.name.toLowerCase().includes(query.toLowerCase()));
594
- if (!match) {
595
- console.log(t("session.no_match", { query }));
596
- return;
597
- }
598
- ctx.sessionManager.setActive(match.id);
599
- const history = ctx.sessionManager.loadHistory();
600
- ctx.agent.setContext(history);
601
- console.clear();
602
- console.log(pc.bold(pc.green(t("session.resumed", { name: match.name }))) +
603
- " " +
604
- pc.dim(`(${match.id.slice(0, 12)})`) +
605
- " — " +
606
- match.messageCount +
607
- " msgs");
608
- console.log(pc.dim("─".repeat(50)));
609
- if (history.length === 0) {
610
- console.log(pc.dim(t("session.no_history")));
611
- }
612
- else {
613
- console.log(pc.dim(t("session.chat_history")));
614
- console.log();
615
- for (const msg of history) {
616
- if (msg.role === "user") {
617
- console.log(pc.cyan(t("session.user_label") + ":"));
618
- console.log(getMessageText(msg.content));
619
- console.log();
620
- }
621
- else if (msg.role === "assistant") {
622
- console.log(pc.green(t("session.assistant_label") + ":"));
623
- console.log(getMessageText(msg.content));
624
- console.log();
625
- }
626
- }
627
- }
628
- console.log(pc.dim("─".repeat(50)));
629
- console.log(pc.dim(` ${t("session.chat_loaded")}`));
630
- },
631
- });
632
- ctx.registerCommand({
633
- name: "rename",
634
- description: t("repl.rename"),
635
- usage: t("repl.rename_usage"),
636
- action: (args) => {
637
- const name = args.join(" ");
638
- if (!name) {
639
- console.log(t("repl.rename_usage"));
640
- return;
641
- }
642
- const active = ctx.sessionManager.getActive();
643
- if (!active) {
644
- console.log(t("session.no_active"));
645
- return;
646
- }
647
- ctx.sessionManager.rename(active, name);
648
- console.log(t("session.renamed", { name }));
649
- },
650
- });
651
- ctx.registerCommand({
652
- name: "delete",
653
- description: t("repl.delete"),
654
- aliases: ["rm"],
655
- usage: t("repl.delete_usage"),
656
- action: (args) => {
657
- const query = args[0];
658
- if (!query) {
659
- console.log(t("repl.delete_usage"));
660
- return;
661
- }
662
- const sessions = ctx.sessionManager.list();
663
- const match = sessions.find((s) => s.id === query || s.id.startsWith(query));
664
- if (!match) {
665
- console.log(t("session.no_match", { query }));
666
- return;
667
- }
668
- ctx.sessionManager.delete(match.id);
669
- console.log(`${t("session.deleted", { id: match.id })}: ${match.name}`);
670
- },
671
- });
672
- }
673
- function registerSkillCommands(ctx) {
674
- if (!ctx.skillsModule)
675
- return;
676
- ctx.registerCommand({
677
- name: "skill",
678
- description: t("repl.skill"),
679
- usage: t("repl.skill_usage"),
680
- action: (args) => {
681
- const subcmd = args[0];
682
- const arg = args.slice(1).join(" ");
683
- if (!subcmd || subcmd === "list") {
684
- const available = ctx.skillsModule.getAvailable();
685
- if (available.length === 0) {
686
- console.log(t("repl.no_skills"));
687
- return;
688
- }
689
- console.log(pc.bold(t("repl.available_skills")));
690
- for (const skill of available) {
691
- const tokens = Math.ceil(skill.content.length / 4);
692
- const loaded = ctx.skillsModule.getLoaded().some((s) => s.name === skill.name);
693
- const marker = loaded ? pc.green(" [loaded]") : "";
694
- console.log(` ${pc.cyan(skill.name)}${marker} ${pc.dim(`(${tokens} tokens)`)} ${skill.description.slice(0, 60)}`);
695
- }
696
- return;
697
- }
698
- if (subcmd === "loaded") {
699
- const loaded = ctx.skillsModule.getLoaded();
700
- const budget = ctx.skillsModule.getBudget();
701
- if (loaded.length === 0) {
702
- console.log(t("repl.no_loaded"));
703
- return;
704
- }
705
- console.log(pc.bold(t("repl.loaded_skills")));
706
- for (const skill of loaded) {
707
- const tokens = Math.ceil(skill.content.length / 4);
708
- console.log(` ${pc.cyan(skill.name)} ${pc.dim(`(${tokens} tokens)`)} ${skill.description.slice(0, 60)}`);
709
- }
710
- console.log(pc.dim(`\n ${t("repl.budget", { used: budget.used, total: budget.total, remaining: budget.remaining })}`));
711
- return;
712
- }
713
- if (subcmd === "load") {
714
- if (!arg) {
715
- console.log(t("repl.skill_load_usage"));
716
- return;
717
- }
718
- const result = ctx.skillsModule.loadByName(arg);
719
- if (result.success) {
720
- console.log(pc.green(result.message));
721
- }
722
- else {
723
- console.log(pc.red(result.message));
724
- }
725
- return;
726
- }
727
- if (subcmd === "unload") {
728
- if (!arg) {
729
- console.log(t("repl.skill_unload_usage"));
730
- return;
731
- }
732
- if (ctx.skillsModule.unload(arg)) {
733
- console.log(pc.green(t("repl.skill_unloaded", { name: arg })));
734
- }
735
- else {
736
- console.log(pc.red(t("repl.skill_not_loaded", { name: arg })));
737
- }
738
- return;
739
- }
740
- if (subcmd === "search") {
741
- if (!arg) {
742
- console.log(t("repl.skill_search_usage"));
743
- return;
744
- }
745
- const results = ctx.skillsModule.search(arg);
746
- if (results.length === 0) {
747
- console.log(t("repl.no_skill_match", { query: arg }));
748
- return;
749
- }
750
- console.log(pc.bold(t("repl.skills_matching", { query: arg })));
751
- for (const skill of results) {
752
- const tokens = Math.ceil(skill.content.length / 4);
753
- console.log(` ${pc.cyan(skill.name)} ${pc.dim(`(${tokens} tokens)`)} ${skill.description.slice(0, 60)}`);
754
- }
755
- return;
756
- }
757
- console.log(pc.red(t("repl.skill_unknown_sub", { subcmd })));
758
- console.log(t("repl.skill_usage"));
759
- },
760
- });
761
- }