micro-models-agent 0.56.0 → 0.56.2
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/CHANGELOG.md +452 -0
- package/dist/main.js +225 -100
- package/package.json +3 -2
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,452 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to Micro Models Agent (MMA) will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/), and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
6
|
+
|
|
7
|
+
## [0.56.1] - 2026-08-27
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
- **CLI**: `mma changelog` command — show latest changelog entry or diff between versions (`--from <version>`)
|
|
11
|
+
- **Updater**: show changelog after auto-update install (`updater.installed` message includes new version's changelog)
|
|
12
|
+
- **Docs**: `CHANGELOG.md` included in npm package (visible via `npm info micro-models-agent`)
|
|
13
|
+
- **Docs**: rule to maintain changelog in `AGENTS.md`
|
|
14
|
+
|
|
15
|
+
## [0.56.0] - 2026-08-27
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
- **MoE**: live re-plan loop in `runWithMoE` — orchestrator re-plans on structural failures
|
|
19
|
+
- **MoE**: scope expansion protocol (`scope_request`) for cross-expert file access
|
|
20
|
+
- **MoE**: Esc/interrupt support in the MoE execution path
|
|
21
|
+
- **MoE**: `input_from` cross-expert data flow for subtask dependencies
|
|
22
|
+
- **LSP**: Angular language server support (`@angular/language-server` for `.html` in Angular workspaces)
|
|
23
|
+
- **Tools**: syntax pre-validation and auto-fix for `write_file`/`edit_file`
|
|
24
|
+
|
|
25
|
+
### Fixed
|
|
26
|
+
- **Security**: SSRF via IPv6-mapped IPv4 and raw numeric hostnames
|
|
27
|
+
- **Security**: command-validator blacklist bypasses (shell expansions, encoded chars)
|
|
28
|
+
- **Security**: audit webhook retry queue drained forever (infinite loop + duplicate notifications)
|
|
29
|
+
- **Core**: dangling `tool_calls` on interrupt — synthesized tool messages keep assistant/tool pairing
|
|
30
|
+
- **Core**: live reasoning policy + `set_thinking` override integration
|
|
31
|
+
- **Core**: deep-clone config defaults to prevent cross-session mutation
|
|
32
|
+
- **Config**: preserve `provider.fallback` on hot-swap
|
|
33
|
+
- **Tools**: path/scope escape holes in filesystem and read tools closed
|
|
34
|
+
- **Tools**: clear timeout timer & abort listener after race settles; log discarded losers
|
|
35
|
+
- **MCP**: stdio timer leaks + null deref after disconnect; added initialize handshake
|
|
36
|
+
- **LSP**: spawn servers detached on POSIX so `killTree` reaches the whole chain
|
|
37
|
+
- **Browser**: bridge leaked Chromium on SIGTERM and parent death
|
|
38
|
+
- **UI**: diff LCS memory cap; one bad encrypted line no longer kills session history
|
|
39
|
+
- **CLI**: `/config migrate` was unreachable
|
|
40
|
+
- **MoE**: locale-independent artifact path + no retry on user abort
|
|
41
|
+
|
|
42
|
+
## [0.55.1] - 2026-08-25
|
|
43
|
+
|
|
44
|
+
### Fixed
|
|
45
|
+
- **LLM**: NDJSON-tolerant stream parser for Ollama backends
|
|
46
|
+
- **LLM**: mid-stream provider errors surfaced (Ollama generation failures)
|
|
47
|
+
- **LLM**: `delta.reasoning` alias for thinking models
|
|
48
|
+
- **LLM**: wire-level debug logging for diagnostics
|
|
49
|
+
|
|
50
|
+
## [0.55.0] - 2026-08-25
|
|
51
|
+
|
|
52
|
+
### Added
|
|
53
|
+
- **Certification**: targeted re-run (`--scenarios <ids>`) with result merging
|
|
54
|
+
- **Certification**: per-rep timeout (`--timeout <ms>` + per-scenario `timeoutMs`)
|
|
55
|
+
- **Certification**: audit-gate bypass fix for `--exit-on-complete`
|
|
56
|
+
|
|
57
|
+
### Fixed
|
|
58
|
+
- **Certification**: stale-label wording (removed impossible user instruction)
|
|
59
|
+
- **Dependencies**: typescript pinned to ^5.9 (TS7 preview breaks `@types/node`)
|
|
60
|
+
|
|
61
|
+
## [0.54.0] - 2026-08-24
|
|
62
|
+
|
|
63
|
+
### Added
|
|
64
|
+
- **Certification**: global manifest shipped with package updates (`~/.mma/certifications.json`)
|
|
65
|
+
- **Certification**: bundled manifest + startup sync from package
|
|
66
|
+
|
|
67
|
+
### Fixed
|
|
68
|
+
- **Certification**: marks only showed when running from repo root
|
|
69
|
+
|
|
70
|
+
## [0.53.0] - 2026-08-24
|
|
71
|
+
|
|
72
|
+
### Added
|
|
73
|
+
- **Certification**: qwen3.5-9b certified 20/20
|
|
74
|
+
- **Config**: `provider.maxCompletionTokens` option
|
|
75
|
+
- **Certification**: label text in `mma model list` and REPL `/model`
|
|
76
|
+
|
|
77
|
+
### Fixed
|
|
78
|
+
- **Certification**: reasoning-heavy models truncated tool_call arguments at default 4096 cap
|
|
79
|
+
- **Certification**: scenario 3.5 prompt disambiguation
|
|
80
|
+
|
|
81
|
+
## [0.52.0] - 2026-08-23
|
|
82
|
+
|
|
83
|
+
### Added
|
|
84
|
+
- **Execution**: `FS_MUTATING_TOOLS` — plan auto-advance after bash/download/subagent/mcp/pipeline/browser tools
|
|
85
|
+
- **Config**: `provider.maxCompletionTokens` plumbing through ProviderManager → agent
|
|
86
|
+
|
|
87
|
+
### Fixed
|
|
88
|
+
- **Execution**: small models create files via bash instead of `write_file`, stalling plans
|
|
89
|
+
- **Execution**: `maxCompletionTokens` was never read from config
|
|
90
|
+
|
|
91
|
+
## [0.51.0] - 2026-08-23
|
|
92
|
+
|
|
93
|
+
### Added
|
|
94
|
+
- **Plugin**: `HostBridge` interface for bidirectional agent communication
|
|
95
|
+
- **Plugin**: `onTurnEnd(ctx, TurnSummary)` hook — dispatched once per completed run
|
|
96
|
+
- **Plugin**: `web-ui` example plugin — browser-based chat with SSE streaming
|
|
97
|
+
- **CLI**: REPL bridge wiring for web-ui submit/interrupt
|
|
98
|
+
|
|
99
|
+
### Fixed
|
|
100
|
+
- **REPL**: `/config migrate` unreachable
|
|
101
|
+
|
|
102
|
+
## [0.50.3] - 2026-08-22
|
|
103
|
+
|
|
104
|
+
### Fixed
|
|
105
|
+
- **UI**: REPL line editor scroll-proof rendering (absolute anchoring via DSR query)
|
|
106
|
+
|
|
107
|
+
## [0.50.2] - 2026-08-22
|
|
108
|
+
|
|
109
|
+
### Fixed
|
|
110
|
+
- **LLM**: idle stream timeout increased 60s → 180s (LM Studio buffering)
|
|
111
|
+
- **LLM**: stall diagnosis with dedicated message for SSE buffering
|
|
112
|
+
- **LLM**: truncation no longer masquerades as empty response
|
|
113
|
+
- **LLM**: recoverable LLM errors fed back into context instead of dying
|
|
114
|
+
- **Execution**: bash flailing detector (≥4 failed bash attempts in last 6)
|
|
115
|
+
|
|
116
|
+
## [0.50.1] - 2026-08-21
|
|
117
|
+
|
|
118
|
+
### Fixed
|
|
119
|
+
- **Security**: no longer silently overrides explicit user opt-out
|
|
120
|
+
- **Lint**: skips missing lint binary (was appending error to every write)
|
|
121
|
+
- **Stuck**: anti-spam for stuck-warnings (dedup via key, decay per-tool counters)
|
|
122
|
+
- **Plan**: unified progress counting (done+skipped as settled)
|
|
123
|
+
- **Plan**: bulk `steps[]` rewrite guarded on progressed plans
|
|
124
|
+
- **Plan**: archived plans answer read-only
|
|
125
|
+
- **Process**: usage hints for `process_kill`/`process_log` without id
|
|
126
|
+
|
|
127
|
+
## [0.50.0] - 2026-08-21
|
|
128
|
+
|
|
129
|
+
### Added
|
|
130
|
+
- **Provider**: health probe (`probeProviders()` + `mma provider check`)
|
|
131
|
+
- **Provider**: code-only capability routing (`ProviderManager.pickFor()`)
|
|
132
|
+
- **Provider**: per-entry isolation + priority fallback order
|
|
133
|
+
- **Pricing**: per-provider cost attribution + breakdown
|
|
134
|
+
|
|
135
|
+
### Fixed
|
|
136
|
+
- **Provider**: transparent failover on 429/5xx/network errors
|
|
137
|
+
|
|
138
|
+
## [0.49.0] - 2026-08-20
|
|
139
|
+
|
|
140
|
+
### Fixed
|
|
141
|
+
- **REPL**: stale-plan leaks — plan state no longer persists across sessions
|
|
142
|
+
- **REPL**: plan checklist prints only on plan/todo tool-end events
|
|
143
|
+
- **Plan**: `PlanStore` is single source of truth for UI consumers
|
|
144
|
+
|
|
145
|
+
## [0.48.3] - 2026-08-20
|
|
146
|
+
|
|
147
|
+
### Fixed
|
|
148
|
+
- **Hallucination**: dotfile false-positive (`.prettierrc.json` extracted as `prettierrc.json`)
|
|
149
|
+
|
|
150
|
+
## [0.48.2] - 2026-08-20
|
|
151
|
+
|
|
152
|
+
### Fixed
|
|
153
|
+
- **REPL**: stale plan printed on first agent run of a session
|
|
154
|
+
|
|
155
|
+
## [0.47.0] - 2026-08-19
|
|
156
|
+
|
|
157
|
+
### Added
|
|
158
|
+
- **Session**: startup diagnostics logging (environment, LSP probe, baseline typecheck)
|
|
159
|
+
- **Session**: `logBaselineTypecheck()` for post-mortem visibility
|
|
160
|
+
|
|
161
|
+
## [0.46.1] - 2026-08-19
|
|
162
|
+
|
|
163
|
+
### Fixed
|
|
164
|
+
- **LLM**: connection-break hardening (stream-level retry, no-data timeout, `[DONE]` tracking)
|
|
165
|
+
- **LLM**: non-streaming timeout (was missing, could hang forever)
|
|
166
|
+
- **Config**: `retry.maxStreamRetries`, `retry.noDataTimeoutMs` options
|
|
167
|
+
|
|
168
|
+
## [0.46.0] - 2026-08-19
|
|
169
|
+
|
|
170
|
+
### Added
|
|
171
|
+
- **Provider**: multi-provider + hot-swap + per-message provenance
|
|
172
|
+
- **Provider**: `ProviderManager` with entry-based config
|
|
173
|
+
- **CLI**: `mma provider add/list/use`
|
|
174
|
+
- **REPL**: `/provider list/use`
|
|
175
|
+
|
|
176
|
+
### Fixed
|
|
177
|
+
- **Path**: `safeResolvePath` POSIX bug (absolute paths re-resolved against baseDir)
|
|
178
|
+
|
|
179
|
+
## [0.45.0] - 2026-08-18
|
|
180
|
+
|
|
181
|
+
### Added
|
|
182
|
+
- **Provider**: provider module Phase 1 (registry, presets, `createProvider()`)
|
|
183
|
+
- **Provider**: `openrouter` preset
|
|
184
|
+
- **Setup**: wizard menu built from `BUILTIN_PROVIDERS`
|
|
185
|
+
|
|
186
|
+
## [0.44.0] - 2026-08-18
|
|
187
|
+
|
|
188
|
+
### Added
|
|
189
|
+
- **Plugins**: folder plugins (subdirectory with entry file)
|
|
190
|
+
- **Plugin**: `trace-server` split into folder plugin
|
|
191
|
+
|
|
192
|
+
### Fixed
|
|
193
|
+
- **Plugin**: template-literal page inlining broke `\n` in JS strings
|
|
194
|
+
|
|
195
|
+
## [0.43.2] - 2026-08-17
|
|
196
|
+
|
|
197
|
+
### Fixed
|
|
198
|
+
- **Execution**: plan done-gate on known compile failures (typecheck gate)
|
|
199
|
+
- **Bootstrap**: live getters for `sessionId`/`sessionContext` after session switch
|
|
200
|
+
- **Edit**: `edit_file` "String not found" hint to `read_file` first
|
|
201
|
+
|
|
202
|
+
## [0.43.1] - 2026-08-17
|
|
203
|
+
|
|
204
|
+
### Fixed
|
|
205
|
+
- **Agent**: session-interrupt no longer renders tool results after "Session ended"
|
|
206
|
+
- **Executor**: `onAfterTool` plugins skipped when signal is aborted
|
|
207
|
+
- **Lint**: abortable syntax checks on Esc
|
|
208
|
+
|
|
209
|
+
## [0.43.0] - 2026-08-17
|
|
210
|
+
|
|
211
|
+
### Added
|
|
212
|
+
- **Plan**: `plan delete <id>` + `plan purge` actions
|
|
213
|
+
- **Plan**: `abort` honors `id` parameter
|
|
214
|
+
- **Plan**: `replan` renumbers ids for kept steps
|
|
215
|
+
- **Audit**: `resolveTestCommand` picks the project's real test runner
|
|
216
|
+
|
|
217
|
+
### Fixed
|
|
218
|
+
- **Plan**: `switch` to already-active plan is a no-op
|
|
219
|
+
- **Plan**: final audit runs for a completed plan
|
|
220
|
+
- **Plan**: evidence-based plan nudge (replaces iteration counter)
|
|
221
|
+
- **Plan**: `checkPlanAlignment` scans path arguments only
|
|
222
|
+
- **Plan**: `isDepsStep` requires a package-manager verb
|
|
223
|
+
- **Plan**: auto-advance resolves nested files
|
|
224
|
+
|
|
225
|
+
## [0.42.0] - 2026-08-16
|
|
226
|
+
|
|
227
|
+
### Added
|
|
228
|
+
- **Execution**: automatic error web search (≥5 same-error repeats → web search → inject results)
|
|
229
|
+
- **Config**: `errorWebSearch` section
|
|
230
|
+
|
|
231
|
+
### Fixed
|
|
232
|
+
- **Execution**: `onAfterTool` double-counted typecheck + failure errors
|
|
233
|
+
|
|
234
|
+
## [0.41.1] - 2026-08-16
|
|
235
|
+
|
|
236
|
+
### Fixed
|
|
237
|
+
- **LSP**: `typescript@5` pin + `--yes` for npx
|
|
238
|
+
- **LSP**: sequential probing (waves) to avoid npx cache lock contention
|
|
239
|
+
- **LSP**: stale config normalization
|
|
240
|
+
- **LSP**: Windows process leak in `shutdown()`
|
|
241
|
+
- **REPL**: non-blocking LSP banner
|
|
242
|
+
- **Bootstrap**: lazy startup health check
|
|
243
|
+
|
|
244
|
+
## [0.41.0] - 2026-08-15
|
|
245
|
+
|
|
246
|
+
### Added
|
|
247
|
+
- **REPL**: live plan checklist with progress bar
|
|
248
|
+
- **UI**: tool-to-step binding (`← step N` suffix in tool headers)
|
|
249
|
+
- **UI**: background command output preview
|
|
250
|
+
|
|
251
|
+
## [0.40.1] - 2026-08-15
|
|
252
|
+
|
|
253
|
+
### Fixed
|
|
254
|
+
- **LSP**: broken package names (`vscode-html-languageserver` → `vscode-langservers-extracted`)
|
|
255
|
+
|
|
256
|
+
## [0.40.0] - 2026-08-15
|
|
257
|
+
|
|
258
|
+
### Added
|
|
259
|
+
- **Tools**: tool-set narrowing (on-demand enable via `enable_tools`)
|
|
260
|
+
- **Config**: `tools.defaultTags` + `tools.enableOnDemand`
|
|
261
|
+
- **Tools**: `alwaysOn` flag for structural tools
|
|
262
|
+
|
|
263
|
+
## [0.39.1] - 2026-08-14
|
|
264
|
+
|
|
265
|
+
### Fixed
|
|
266
|
+
- **Plugins**: dedup by version, compatibility gate, source tracking
|
|
267
|
+
- **CLI**: `mma plugins list` command
|
|
268
|
+
|
|
269
|
+
## [0.38.0] - 2026-08-14
|
|
270
|
+
|
|
271
|
+
### Added
|
|
272
|
+
- **LSP**: `lsp_check` tool for on-demand diagnostics
|
|
273
|
+
- **Plan**: `plan create` guard (blocks when active plan has progress)
|
|
274
|
+
|
|
275
|
+
### Fixed
|
|
276
|
+
- **Context**: compaction summary carries plan + read state
|
|
277
|
+
- **Browser**: bridge path resolution in bundled dist
|
|
278
|
+
|
|
279
|
+
## [0.37.0] - 2026-08-13
|
|
280
|
+
|
|
281
|
+
### Added
|
|
282
|
+
- **Plugins**: folder plugin support in `PluginLoader`
|
|
283
|
+
|
|
284
|
+
### Fixed
|
|
285
|
+
- **Plugin**: template-literal page inlining broke `\n` in JS
|
|
286
|
+
|
|
287
|
+
## [0.36.3] - 2026-08-13
|
|
288
|
+
|
|
289
|
+
### Fixed
|
|
290
|
+
- **UI**: REPL paste fix (batch single-render, CRLF collapse)
|
|
291
|
+
|
|
292
|
+
## [0.36.2] - 2026-08-13
|
|
293
|
+
|
|
294
|
+
### Fixed
|
|
295
|
+
- **Updater**: silent logger, one-shot `process.exit()` killed background install, semver-aware check
|
|
296
|
+
|
|
297
|
+
## [0.36.1] - 2026-08-13
|
|
298
|
+
|
|
299
|
+
### Fixed
|
|
300
|
+
- **Audit**: nested-file resolution, non-zero test run blocks
|
|
301
|
+
- **Browser**: bridge diagnostics + one-shot restart
|
|
302
|
+
- **LSP**: per-server disable + initialize retry + CSS timeout
|
|
303
|
+
- **Bash**: npm exec hint
|
|
304
|
+
|
|
305
|
+
## [0.36.0] - 2026-08-12
|
|
306
|
+
|
|
307
|
+
### Added
|
|
308
|
+
- **Plan**: model-declared `kind: "create"|"delete"` for steps
|
|
309
|
+
- **Execution**: `FS_MUTATING_TOOLS` for plan auto-advance
|
|
310
|
+
- **Config**: `provider.maxCompletionTokens` option
|
|
311
|
+
|
|
312
|
+
### Fixed
|
|
313
|
+
- **Context**: compaction preserves session `mission`
|
|
314
|
+
- **Context**: deleted files leave compaction `[Files:]` list
|
|
315
|
+
- **Audit**: final audit runs real `tsc --noEmit --skipLibCheck`
|
|
316
|
+
- **Bash**: repeated forbidden Windows commands hard-stopped after 2 failures
|
|
317
|
+
|
|
318
|
+
## [0.35.5] - 2026-08-12
|
|
319
|
+
|
|
320
|
+
### Fixed
|
|
321
|
+
- **Execution**: plan-alignment phantom paths (domains/extensions treated as files)
|
|
322
|
+
- **Execution**: hint/recovery dedup in `StuckDetector`
|
|
323
|
+
|
|
324
|
+
## [0.35.3] - 2026-08-11
|
|
325
|
+
|
|
326
|
+
### Fixed
|
|
327
|
+
- **LSP**: workspace root resolved from edited file's project
|
|
328
|
+
- **Audit**: skipped steps treated as terminal
|
|
329
|
+
- **Bash**: Windows hint keys on original command word
|
|
330
|
+
- **Tools**: boundedOutput tools never budget-truncated
|
|
331
|
+
|
|
332
|
+
## [0.35.0] - 2026-08-11
|
|
333
|
+
|
|
334
|
+
### Added
|
|
335
|
+
- **Tools**: `download_file` tool for binary file downloads
|
|
336
|
+
|
|
337
|
+
## [0.34.0] - 2026-08-10
|
|
338
|
+
|
|
339
|
+
### Added
|
|
340
|
+
- **Indexer**: project profile (`[Stack: ...]` summary from manifest)
|
|
341
|
+
- **Indexer**: dynamic map refresh inside sessions
|
|
342
|
+
|
|
343
|
+
## [0.33.3] - 2026-08-10
|
|
344
|
+
|
|
345
|
+
### Fixed
|
|
346
|
+
- **Audit**: nested-file resolution (basename + path-suffix match)
|
|
347
|
+
- **Plan**: `plan show` honors `id` parameter
|
|
348
|
+
- **Context**: compaction interval reset per user turn
|
|
349
|
+
- **Context**: `extractFacts` captures `edit_file` paths + Windows drive-letter paths
|
|
350
|
+
- **Execution**: stuck detector read-only loop detection
|
|
351
|
+
- **Read**: default limit 15 → 300 lines
|
|
352
|
+
- **LSP**: `spawn` on Windows (`.cmd` shim resolution)
|
|
353
|
+
- **Todo**: `todo add` tracks subtasks, `todo done` marks individual sub-task
|
|
354
|
+
- **Memory**: learns repeated per-tool failures (≥3×)
|
|
355
|
+
- **Context**: compaction preserves user's task
|
|
356
|
+
|
|
357
|
+
## [0.33.2] - 2026-08-09
|
|
358
|
+
|
|
359
|
+
### Fixed
|
|
360
|
+
- **UI**: REPL conversation layout (user/agent message dividers)
|
|
361
|
+
- **Tools**: `isFilePathLike` uses allow-list of file extensions
|
|
362
|
+
|
|
363
|
+
## [0.33.1] - 2026-08-09
|
|
364
|
+
|
|
365
|
+
### Fixed
|
|
366
|
+
- **UI**: REPL line editor redraw fix (no duplicated multi-line input)
|
|
367
|
+
- **Tools**: `web_fetch`/`web_browse` description clarifications
|
|
368
|
+
|
|
369
|
+
## [0.33.0] - 2026-08-09
|
|
370
|
+
|
|
371
|
+
### Added
|
|
372
|
+
- **RLM**: pass-by-reference sub-agent results (`ArtifactStore`)
|
|
373
|
+
- **RLM**: chunked parallel queries (`chunk_query` tool)
|
|
374
|
+
- **Config**: `subagent.resultMode`, `maxSummaryChars`, `artifactsDir`, `stableSystemPrompt`
|
|
375
|
+
|
|
376
|
+
## [0.32.0] - 2026-08-08
|
|
377
|
+
|
|
378
|
+
### Added
|
|
379
|
+
- **Browser**: driver abstraction (`PlaywrightDriver` + `BridgeDriver`)
|
|
380
|
+
- **Browser**: Node bridge for Bun compatibility
|
|
381
|
+
- **Config**: `browser.maxConsoleLineChars`
|
|
382
|
+
|
|
383
|
+
## [0.31.0] - 2026-08-08
|
|
384
|
+
|
|
385
|
+
### Added
|
|
386
|
+
- **Security**: session file encryption (AES-256-GCM)
|
|
387
|
+
- **Security**: audit notifications (file + webhook)
|
|
388
|
+
- **Security**: security policies (strict/balanced/permissive)
|
|
389
|
+
- **CLI**: `mma security` commands
|
|
390
|
+
|
|
391
|
+
## [0.30.0] - 2026-08-07
|
|
392
|
+
|
|
393
|
+
### Added
|
|
394
|
+
- **Execution**: final audit gate (runs `bun test` for verification steps)
|
|
395
|
+
- **Execution**: `detectTestResults()` auto-verification in bash
|
|
396
|
+
|
|
397
|
+
### Fixed
|
|
398
|
+
- **Execution**: empty-CLI entry-point hint
|
|
399
|
+
- **Bash**: Windows anti-patterns documentation
|
|
400
|
+
|
|
401
|
+
## [0.29.0] - 2026-08-07
|
|
402
|
+
|
|
403
|
+
### Added
|
|
404
|
+
- **Bash**: smart UTF-8/OEM line decoding (fixes Cyrillic on Windows)
|
|
405
|
+
- **Bash**: behavior-based background detection
|
|
406
|
+
- **Bash**: stuck-detector bash awareness
|
|
407
|
+
|
|
408
|
+
## [0.28.0] - 2026-08-06
|
|
409
|
+
|
|
410
|
+
### Fixed
|
|
411
|
+
- **Agent**: double-Esc interrupt fix (Bun readline keypress collapsing)
|
|
412
|
+
- **Agent**: abortable in-flight LLM requests on interrupt
|
|
413
|
+
- **UI**: clipboard paste hint
|
|
414
|
+
|
|
415
|
+
## [0.27.0] - 2026-08-06
|
|
416
|
+
|
|
417
|
+
### Fixed
|
|
418
|
+
- **Security**: Windows hardening
|
|
419
|
+
- **Hallucination**: fixes
|
|
420
|
+
|
|
421
|
+
## [0.26.0] - 2026-08-05
|
|
422
|
+
|
|
423
|
+
### Added
|
|
424
|
+
- **UI**: opencode-style inline tool headers (`ui.toolStyle`)
|
|
425
|
+
- **UI**: model commentary next to tool calls (`ui.toolComments`)
|
|
426
|
+
- **UI**: diffs without background color
|
|
427
|
+
|
|
428
|
+
## [0.25.0] - 2026-08-05
|
|
429
|
+
|
|
430
|
+
### Added
|
|
431
|
+
- **LSP**: LSP module (typescript, CSS, HTML, JSON, Python, Rust, Go)
|
|
432
|
+
- **Execution**: audit gate language-agnostic
|
|
433
|
+
- **Bash**: Windows command hints
|
|
434
|
+
|
|
435
|
+
## [0.24.0] - 2026-08-04
|
|
436
|
+
|
|
437
|
+
### Added
|
|
438
|
+
- **Context**: quality formula upgrade (token load + compaction loss + error density + freshness)
|
|
439
|
+
- **Read**: display mode (show only header in REPL, full content to LLM)
|
|
440
|
+
|
|
441
|
+
## [0.23.0] - 2026-08-04
|
|
442
|
+
|
|
443
|
+
### Added
|
|
444
|
+
- **Certification**: model certification module (`mma model certify`)
|
|
445
|
+
- **CLI**: cert checkmarks in model lists
|
|
446
|
+
|
|
447
|
+
## [0.22.0] - 2026-08-03
|
|
448
|
+
|
|
449
|
+
### Added
|
|
450
|
+
- **Security**: `enabled` flag (disabled by default)
|
|
451
|
+
- **CLI**: init/first-run apply wizard security answers
|
|
452
|
+
- **Prompt**: system prompt & recovery messages cleanup
|
package/dist/main.js
CHANGED
|
@@ -3126,8 +3126,12 @@ Apply a matching solution from these results. If none is relevant — do NOT rep
|
|
|
3126
3126
|
"updater.check_error": "[updater] update check failed: {error}",
|
|
3127
3127
|
"updater.available": "[updater] Update available: {current} → {latest}. Run `npm install -g micro-models-agent` to upgrade.",
|
|
3128
3128
|
"updater.installing": "[updater] Installing {latest} globally (current: {current})…",
|
|
3129
|
-
"updater.installed":
|
|
3129
|
+
"updater.installed": `[updater] Installed {latest}. Restart MMA to use it (was {current}).
|
|
3130
|
+
{changelog}`,
|
|
3130
3131
|
"updater.install_failed": "[updater] Failed to install {latest}: {error}. Update manually with `npm install -g micro-models-agent`.",
|
|
3132
|
+
"cli.changelog_title": "Changelog (micro-models-agent@{version}):",
|
|
3133
|
+
"cli.changelog_not_found": "Changelog not found for this installation.",
|
|
3134
|
+
"cli.changelog_range": "Changes since {from}:",
|
|
3131
3135
|
"tools.enable_no_tags": 'enable_tools requires at least one tag in the "tags" array.',
|
|
3132
3136
|
"tools.enable_no_executor": "Tool executor is not available — cannot enumerate enabled tools.",
|
|
3133
3137
|
"tools.enable_already_active": "Tool tags already active: {tags}.",
|
|
@@ -3889,8 +3893,12 @@ var init_ru = __esm(() => {
|
|
|
3889
3893
|
"updater.check_error": "[updater] Ошибка проверки обновления: {error}",
|
|
3890
3894
|
"updater.available": "[updater] Доступно обновление: {current} → {latest}. Выполните `npm install -g micro-models-agent` для обновления.",
|
|
3891
3895
|
"updater.installing": "[updater] Установка {latest} глобально (текущая: {current})…",
|
|
3892
|
-
"updater.installed":
|
|
3896
|
+
"updater.installed": `[updater] Установлена {latest}. Перезапустите MMA для применения (была {current}).
|
|
3897
|
+
{changelog}`,
|
|
3893
3898
|
"updater.install_failed": "[updater] Не удалось установить {latest}: {error}. Обновите вручную: `npm install -g micro-models-agent`.",
|
|
3899
|
+
"cli.changelog_title": "Список изменений (micro-models-agent@{version}):",
|
|
3900
|
+
"cli.changelog_not_found": "Changelog не найден для этой установки.",
|
|
3901
|
+
"cli.changelog_range": "Изменения с версии {from}:",
|
|
3894
3902
|
"tools.enable_no_tags": 'enable_tools требует хотя бы один тег в массиве "tags".',
|
|
3895
3903
|
"tools.enable_no_executor": "Исполнитель тулов недоступен — невозможно перечислить включённые тулы.",
|
|
3896
3904
|
"tools.enable_already_active": "Теги тулов уже активны: {tags}.",
|
|
@@ -33408,8 +33416,8 @@ var init_scenarios = __esm(() => {
|
|
|
33408
33416
|
});
|
|
33409
33417
|
|
|
33410
33418
|
// src/modules/certification/loader.ts
|
|
33411
|
-
import { existsSync as
|
|
33412
|
-
import { join as
|
|
33419
|
+
import { existsSync as existsSync52, readdirSync as readdirSync17, readFileSync as readFileSync33 } from "fs";
|
|
33420
|
+
import { join as join45 } from "path";
|
|
33413
33421
|
function validateScenario(s) {
|
|
33414
33422
|
const errors2 = [];
|
|
33415
33423
|
const isSkip = s.mode === "skip";
|
|
@@ -33461,12 +33469,12 @@ function loadScenarios(userDir) {
|
|
|
33461
33469
|
else
|
|
33462
33470
|
scenarios.push(s);
|
|
33463
33471
|
}
|
|
33464
|
-
if (userDir &&
|
|
33472
|
+
if (userDir && existsSync52(userDir)) {
|
|
33465
33473
|
for (const file of readdirSync17(userDir)) {
|
|
33466
33474
|
if (!file.endsWith(".yaml") && !file.endsWith(".yml"))
|
|
33467
33475
|
continue;
|
|
33468
33476
|
try {
|
|
33469
|
-
const raw =
|
|
33477
|
+
const raw = readFileSync33(join45(userDir, file), "utf-8");
|
|
33470
33478
|
const data = $parse(raw);
|
|
33471
33479
|
const parsed = normalizeScenario(data, file);
|
|
33472
33480
|
const errs = validateScenario(parsed);
|
|
@@ -33529,8 +33537,8 @@ var init_loader3 = __esm(() => {
|
|
|
33529
33537
|
});
|
|
33530
33538
|
|
|
33531
33539
|
// src/modules/certification/fact-checker.ts
|
|
33532
|
-
import { existsSync as
|
|
33533
|
-
import { join as
|
|
33540
|
+
import { existsSync as existsSync53, readFileSync as readFileSync34, statSync as statSync9 } from "fs";
|
|
33541
|
+
import { join as join46 } from "path";
|
|
33534
33542
|
function checkSandbox(sandboxDir, checks, exitCode, output) {
|
|
33535
33543
|
const failures = [];
|
|
33536
33544
|
for (const check of checks) {
|
|
@@ -33547,16 +33555,16 @@ function runCheck2(sandboxDir, check, exitCode, output) {
|
|
|
33547
33555
|
case "outputContains":
|
|
33548
33556
|
return output.includes(check.text);
|
|
33549
33557
|
case "fileExists":
|
|
33550
|
-
return isFile(
|
|
33558
|
+
return isFile(join46(sandboxDir, check.path));
|
|
33551
33559
|
case "fileNotExists":
|
|
33552
|
-
return !
|
|
33560
|
+
return !existsSync53(join46(sandboxDir, check.path));
|
|
33553
33561
|
case "dirExists":
|
|
33554
|
-
return isDir(
|
|
33562
|
+
return isDir(join46(sandboxDir, check.path));
|
|
33555
33563
|
case "fileContent": {
|
|
33556
|
-
const abs =
|
|
33564
|
+
const abs = join46(sandboxDir, check.path);
|
|
33557
33565
|
if (!isFile(abs))
|
|
33558
33566
|
return false;
|
|
33559
|
-
const content =
|
|
33567
|
+
const content = readFileSync34(abs, "utf-8");
|
|
33560
33568
|
if (check.contains !== undefined)
|
|
33561
33569
|
return content.includes(check.contains);
|
|
33562
33570
|
if (check.equals !== undefined)
|
|
@@ -33564,10 +33572,10 @@ function runCheck2(sandboxDir, check, exitCode, output) {
|
|
|
33564
33572
|
return false;
|
|
33565
33573
|
}
|
|
33566
33574
|
case "fileRegex": {
|
|
33567
|
-
const abs =
|
|
33575
|
+
const abs = join46(sandboxDir, check.path);
|
|
33568
33576
|
if (!isFile(abs))
|
|
33569
33577
|
return false;
|
|
33570
|
-
return new RegExp(check.pattern).test(
|
|
33578
|
+
return new RegExp(check.pattern).test(readFileSync34(abs, "utf-8"));
|
|
33571
33579
|
}
|
|
33572
33580
|
default:
|
|
33573
33581
|
return false;
|
|
@@ -33575,14 +33583,14 @@ function runCheck2(sandboxDir, check, exitCode, output) {
|
|
|
33575
33583
|
}
|
|
33576
33584
|
function isFile(p) {
|
|
33577
33585
|
try {
|
|
33578
|
-
return
|
|
33586
|
+
return existsSync53(p) && statSync9(p).isFile();
|
|
33579
33587
|
} catch {
|
|
33580
33588
|
return false;
|
|
33581
33589
|
}
|
|
33582
33590
|
}
|
|
33583
33591
|
function isDir(p) {
|
|
33584
33592
|
try {
|
|
33585
|
-
return
|
|
33593
|
+
return existsSync53(p) && statSync9(p).isDirectory();
|
|
33586
33594
|
} catch {
|
|
33587
33595
|
return false;
|
|
33588
33596
|
}
|
|
@@ -33613,8 +33621,8 @@ var init_fact_checker = () => {};
|
|
|
33613
33621
|
|
|
33614
33622
|
// src/modules/certification/runner.ts
|
|
33615
33623
|
import { spawn as spawn10 } from "child_process";
|
|
33616
|
-
import { existsSync as
|
|
33617
|
-
import { join as
|
|
33624
|
+
import { existsSync as existsSync54, mkdirSync as mkdirSync20, rmSync as rmSync4, cpSync as cpSync2, writeFileSync as writeFileSync20, readdirSync as readdirSync18, readFileSync as readFileSync35 } from "fs";
|
|
33625
|
+
import { join as join47, resolve as resolve23, dirname as dirname20, relative as relative7 } from "path";
|
|
33618
33626
|
async function runScenario(scenario, opts) {
|
|
33619
33627
|
if (scenario.mode === "skip") {
|
|
33620
33628
|
return {
|
|
@@ -33634,7 +33642,7 @@ async function runScenario(scenario, opts) {
|
|
|
33634
33642
|
let firstError;
|
|
33635
33643
|
let lastFailedSandbox;
|
|
33636
33644
|
for (let i = 1;i <= reps; i++) {
|
|
33637
|
-
const sandbox =
|
|
33645
|
+
const sandbox = join47(opts.sandboxBase, `run-${scenario.id}-${i}`);
|
|
33638
33646
|
let failures = [];
|
|
33639
33647
|
let exitCode = -1;
|
|
33640
33648
|
let output = "";
|
|
@@ -33658,9 +33666,9 @@ async function runScenario(scenario, opts) {
|
|
|
33658
33666
|
env3.MMA_PROVIDER_APIKEY = opts.providerKey;
|
|
33659
33667
|
if (scenario.config && opts.baseConfig) {
|
|
33660
33668
|
const merged = deepMergeAny(opts.baseConfig, scenario.config);
|
|
33661
|
-
const certConfigDir =
|
|
33669
|
+
const certConfigDir = join47(sandbox, ".mma");
|
|
33662
33670
|
mkdirSync20(certConfigDir, { recursive: true });
|
|
33663
|
-
writeFileSync20(
|
|
33671
|
+
writeFileSync20(join47(certConfigDir, "config.json"), JSON.stringify(merged, null, 2), "utf-8");
|
|
33664
33672
|
env3.MMA_CONFIG_DIR = certConfigDir;
|
|
33665
33673
|
}
|
|
33666
33674
|
const res = await runner(env3, opts.mmaRoot, args, timeoutMs);
|
|
@@ -33707,12 +33715,12 @@ function prepareSandbox(sandbox, scenario, mmaRoot) {
|
|
|
33707
33715
|
rmSync4(sandbox, { recursive: true, force: true });
|
|
33708
33716
|
mkdirSync20(sandbox, { recursive: true });
|
|
33709
33717
|
for (const f of scenario.fixtures ?? []) {
|
|
33710
|
-
const src =
|
|
33711
|
-
if (!
|
|
33718
|
+
const src = join47(mmaRoot, f.source);
|
|
33719
|
+
if (!existsSync54(src)) {
|
|
33712
33720
|
throw new Error(`fixture missing: ${f.source}`);
|
|
33713
33721
|
}
|
|
33714
|
-
const dest =
|
|
33715
|
-
mkdirSync20(
|
|
33722
|
+
const dest = join47(sandbox, f.dest);
|
|
33723
|
+
mkdirSync20(dirname20(dest), { recursive: true });
|
|
33716
33724
|
cpSync2(src, dest);
|
|
33717
33725
|
}
|
|
33718
33726
|
}
|
|
@@ -33724,10 +33732,10 @@ function collectDiagnostics(sandbox) {
|
|
|
33724
33732
|
} else {
|
|
33725
33733
|
lines.push(" Files created: (none)");
|
|
33726
33734
|
}
|
|
33727
|
-
const planPath =
|
|
33728
|
-
if (
|
|
33735
|
+
const planPath = join47(sandbox, ".mma", "plans", "active.json");
|
|
33736
|
+
if (existsSync54(planPath)) {
|
|
33729
33737
|
try {
|
|
33730
|
-
const plan = JSON.parse(
|
|
33738
|
+
const plan = JSON.parse(readFileSync35(planPath, "utf-8"));
|
|
33731
33739
|
const steps = plan.steps ?? [];
|
|
33732
33740
|
const done = steps.filter((s) => s.status === "done").length;
|
|
33733
33741
|
const pending = steps.filter((s) => s.status === "pending" || s.status === "in_progress");
|
|
@@ -33746,7 +33754,7 @@ function listFiles(dir, root) {
|
|
|
33746
33754
|
for (const entry of readdirSync18(dir, { withFileTypes: true })) {
|
|
33747
33755
|
if (entry.name === ".mma")
|
|
33748
33756
|
continue;
|
|
33749
|
-
const abs =
|
|
33757
|
+
const abs = join47(dir, entry.name);
|
|
33750
33758
|
const rel = toForwardSlash(relative7(root, abs));
|
|
33751
33759
|
if (entry.isDirectory()) {
|
|
33752
33760
|
result.push(...listFiles(abs, root));
|
|
@@ -33758,15 +33766,15 @@ function listFiles(dir, root) {
|
|
|
33758
33766
|
return result;
|
|
33759
33767
|
}
|
|
33760
33768
|
function resolveMmaEntry(mmaRoot) {
|
|
33761
|
-
const dev =
|
|
33762
|
-
if (
|
|
33769
|
+
const dev = join47(mmaRoot, "src", "cli", "main.ts");
|
|
33770
|
+
if (existsSync54(dev))
|
|
33763
33771
|
return dev;
|
|
33764
|
-
return
|
|
33772
|
+
return join47(mmaRoot, "dist", "main.js");
|
|
33765
33773
|
}
|
|
33766
33774
|
function findMmaRoot(fromDir) {
|
|
33767
33775
|
const candidates = [resolve23(fromDir, "..", "..", ".."), resolve23(fromDir, "..")];
|
|
33768
33776
|
for (const c of candidates) {
|
|
33769
|
-
if (
|
|
33777
|
+
if (existsSync54(join47(c, "package.json")))
|
|
33770
33778
|
return c;
|
|
33771
33779
|
}
|
|
33772
33780
|
return process.cwd();
|
|
@@ -33834,15 +33842,15 @@ __export(exports_cli, {
|
|
|
33834
33842
|
certList: () => certList
|
|
33835
33843
|
});
|
|
33836
33844
|
import { rmSync as rmSync5, writeFileSync as writeFileSync21 } from "fs";
|
|
33837
|
-
import { join as
|
|
33845
|
+
import { join as join48, dirname as dirname21 } from "path";
|
|
33838
33846
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
33839
|
-
import { existsSync as
|
|
33847
|
+
import { existsSync as existsSync55, readFileSync as readFileSync36 } from "fs";
|
|
33840
33848
|
function readVersion() {
|
|
33841
|
-
const candidates = [
|
|
33849
|
+
const candidates = [join48(MMA_ROOT, "package.json")];
|
|
33842
33850
|
for (const p of candidates) {
|
|
33843
|
-
if (
|
|
33851
|
+
if (existsSync55(p)) {
|
|
33844
33852
|
try {
|
|
33845
|
-
const raw = JSON.parse(
|
|
33853
|
+
const raw = JSON.parse(readFileSync36(p, "utf-8"));
|
|
33846
33854
|
if (raw.version)
|
|
33847
33855
|
return raw.version;
|
|
33848
33856
|
} catch {}
|
|
@@ -33855,7 +33863,7 @@ function parseTags(s) {
|
|
|
33855
33863
|
}
|
|
33856
33864
|
async function certify(opts) {
|
|
33857
33865
|
const providerUrl = opts.providerUrl || opts.config.provider.baseUrl;
|
|
33858
|
-
const { scenarios, errors: errors2 } = loadScenarios(
|
|
33866
|
+
const { scenarios, errors: errors2 } = loadScenarios(join48(opts.projectDir, ".mma", "certification", "scenarios"));
|
|
33859
33867
|
for (const e of errors2)
|
|
33860
33868
|
console.error(pc2.yellow(` ${e}`));
|
|
33861
33869
|
let selected = filterByTags(scenarios, opts.tags);
|
|
@@ -33886,7 +33894,7 @@ async function certify(opts) {
|
|
|
33886
33894
|
return;
|
|
33887
33895
|
}
|
|
33888
33896
|
console.log(t("cli.cert_started", { model: opts.name, provider: providerUrl }));
|
|
33889
|
-
const sandboxBase =
|
|
33897
|
+
const sandboxBase = join48(process.cwd(), ".mma", "certification");
|
|
33890
33898
|
const results = [];
|
|
33891
33899
|
const total = selected.length;
|
|
33892
33900
|
let idx = 0;
|
|
@@ -34019,10 +34027,10 @@ function printResults(results) {
|
|
|
34019
34027
|
}
|
|
34020
34028
|
}
|
|
34021
34029
|
function writeReport(entry, projectDir) {
|
|
34022
|
-
const reportDir =
|
|
34030
|
+
const reportDir = join48(projectDir, "certification");
|
|
34023
34031
|
const ts = entry.certifiedAt.replace(/[:.]/g, "-").slice(0, 19);
|
|
34024
34032
|
const filename = `report-${entry.model.replace(/[/\\:]/g, "_")}-${ts}.json`;
|
|
34025
|
-
const reportPath =
|
|
34033
|
+
const reportPath = join48(reportDir, filename);
|
|
34026
34034
|
const report = {
|
|
34027
34035
|
model: entry.model,
|
|
34028
34036
|
providerUrl: entry.providerUrl,
|
|
@@ -34055,7 +34063,7 @@ var init_cli = __esm(() => {
|
|
|
34055
34063
|
init_loader3();
|
|
34056
34064
|
init_runner2();
|
|
34057
34065
|
init_manifest();
|
|
34058
|
-
HERE =
|
|
34066
|
+
HERE = dirname21(fileURLToPath5(import.meta.url));
|
|
34059
34067
|
MMA_ROOT = findMmaRoot(HERE);
|
|
34060
34068
|
});
|
|
34061
34069
|
|
|
@@ -34065,8 +34073,8 @@ __export(exports_repl_commands, {
|
|
|
34065
34073
|
registerAllCommands: () => registerAllCommands,
|
|
34066
34074
|
COMMAND_GROUPS: () => COMMAND_GROUPS
|
|
34067
34075
|
});
|
|
34068
|
-
import { join as
|
|
34069
|
-
import { existsSync as
|
|
34076
|
+
import { join as join50, dirname as dirname23 } from "path";
|
|
34077
|
+
import { existsSync as existsSync57 } from "fs";
|
|
34070
34078
|
function registerAllCommands(ctx) {
|
|
34071
34079
|
registerBuiltinCommands(ctx);
|
|
34072
34080
|
registerMmaCommands(ctx);
|
|
@@ -34123,7 +34131,7 @@ function registerMmaCommands(ctx) {
|
|
|
34123
34131
|
}
|
|
34124
34132
|
try {
|
|
34125
34133
|
const { loadFileAsDataUrl: loadFileAsDataUrl2, loadUrlAsDataUrl: loadUrlAsDataUrl2, readClipboardImage: readClipboardImage2 } = await Promise.resolve().then(() => (init_image_utils(), exports_image_utils));
|
|
34126
|
-
const { existsSync:
|
|
34134
|
+
const { existsSync: existsSync58 } = await import("fs");
|
|
34127
34135
|
const { resolve: resolve24 } = await import("path");
|
|
34128
34136
|
let dataUrl;
|
|
34129
34137
|
let label;
|
|
@@ -34143,7 +34151,7 @@ function registerMmaCommands(ctx) {
|
|
|
34143
34151
|
label = source;
|
|
34144
34152
|
} else {
|
|
34145
34153
|
const absPath = resolve24(process.cwd(), source);
|
|
34146
|
-
if (!
|
|
34154
|
+
if (!existsSync58(absPath)) {
|
|
34147
34155
|
console.log(pc2.red(t("image.not_found", { path: source })));
|
|
34148
34156
|
return;
|
|
34149
34157
|
}
|
|
@@ -34246,7 +34254,7 @@ function registerMmaCommands(ctx) {
|
|
|
34246
34254
|
console.log(pc2.yellow(t("repl.wizard_running")));
|
|
34247
34255
|
await ctx.withExclusiveInput(async () => {
|
|
34248
34256
|
const answers = await runSetup(ctx.rl);
|
|
34249
|
-
const configPath =
|
|
34257
|
+
const configPath = join50(ctx.configDir, "config.json");
|
|
34250
34258
|
ctx.config.provider.type = answers.provider;
|
|
34251
34259
|
ctx.config.provider.baseUrl = answers.apiBase;
|
|
34252
34260
|
ctx.config.provider.apiKey = answers.apiKey;
|
|
@@ -34254,7 +34262,7 @@ function registerMmaCommands(ctx) {
|
|
|
34254
34262
|
ctx.config.contextWindow = answers.contextWindow;
|
|
34255
34263
|
ctx.config.maxToolIterations = answers.maxToolIterations;
|
|
34256
34264
|
ctx.config.locale = answers.locale;
|
|
34257
|
-
saveConfig(ctx.config, configPath,
|
|
34265
|
+
saveConfig(ctx.config, configPath, dirname23(configPath));
|
|
34258
34266
|
await ctx.agent.reconfigure(ctx.config);
|
|
34259
34267
|
console.log(pc2.green(t("cli.config_saved")));
|
|
34260
34268
|
});
|
|
@@ -34368,8 +34376,8 @@ function registerMmaCommands(ctx) {
|
|
|
34368
34376
|
return;
|
|
34369
34377
|
}
|
|
34370
34378
|
ctx.config.model = name;
|
|
34371
|
-
const configPath =
|
|
34372
|
-
saveConfig(ctx.config, configPath,
|
|
34379
|
+
const configPath = join50(ctx.configDir, "config.json");
|
|
34380
|
+
saveConfig(ctx.config, configPath, dirname23(configPath));
|
|
34373
34381
|
await ctx.agent.reconfigure(ctx.config);
|
|
34374
34382
|
console.log(pc2.green(t("repl.model_set", { name })));
|
|
34375
34383
|
return;
|
|
@@ -34393,8 +34401,8 @@ function registerMmaCommands(ctx) {
|
|
|
34393
34401
|
return;
|
|
34394
34402
|
}
|
|
34395
34403
|
ctx.config.contextWindow = size;
|
|
34396
|
-
const configPath =
|
|
34397
|
-
saveConfig(ctx.config, configPath,
|
|
34404
|
+
const configPath = join50(ctx.configDir, "config.json");
|
|
34405
|
+
saveConfig(ctx.config, configPath, dirname23(configPath));
|
|
34398
34406
|
await ctx.agent.reconfigure(ctx.config);
|
|
34399
34407
|
console.log(pc2.green(t("cli.context_set", { size })));
|
|
34400
34408
|
}
|
|
@@ -34408,10 +34416,10 @@ function registerMmaCommands(ctx) {
|
|
|
34408
34416
|
if (ctx.sessionManager && ctx.config.session.autoSave) {}
|
|
34409
34417
|
ctx.agent.shutdown();
|
|
34410
34418
|
const { loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_config2(), exports_config));
|
|
34411
|
-
const { join:
|
|
34419
|
+
const { join: join51 } = await import("path");
|
|
34412
34420
|
const configDir = ctx.configDir;
|
|
34413
34421
|
const baseDir = ctx.baseDir;
|
|
34414
|
-
const projectConfigPath =
|
|
34422
|
+
const projectConfigPath = join51(baseDir, ".mmrc");
|
|
34415
34423
|
const { config: freshConfig } = loadConfig2({ configDir, projectConfigPath });
|
|
34416
34424
|
Object.assign(ctx.config, freshConfig);
|
|
34417
34425
|
const { bootstrap: bootstrap2 } = await Promise.resolve().then(() => (init_bootstrap(), exports_bootstrap));
|
|
@@ -34765,21 +34773,21 @@ async function runConfigMigrate(ctx) {
|
|
|
34765
34773
|
const { hasDomainFiles: hasDomainFiles3 } = await Promise.resolve().then(() => (init_domains(), exports_domains));
|
|
34766
34774
|
const { loadConfig: loadCfg } = await Promise.resolve().then(() => (init_config2(), exports_config));
|
|
34767
34775
|
const configDir = ctx.configDir;
|
|
34768
|
-
const configPath =
|
|
34776
|
+
const configPath = join50(configDir, "config.json");
|
|
34769
34777
|
if (hasDomainFiles3(configDir)) {
|
|
34770
34778
|
console.log(pc2.yellow(t("config.migrate_no_legacy")));
|
|
34771
34779
|
return;
|
|
34772
34780
|
}
|
|
34773
|
-
if (!
|
|
34781
|
+
if (!existsSync57(configPath)) {
|
|
34774
34782
|
console.log(pc2.yellow(t("config.migrate_no_legacy")));
|
|
34775
34783
|
return;
|
|
34776
34784
|
}
|
|
34777
34785
|
console.log(t("config.migrate_start"));
|
|
34778
|
-
const { config } = loadCfg({ configDir, projectConfigPath:
|
|
34786
|
+
const { config } = loadCfg({ configDir, projectConfigPath: join50(configDir, ".mmrc") });
|
|
34779
34787
|
saveConfig(config, configPath, configDir);
|
|
34780
34788
|
const { renameSync: renameSync4, readdirSync: readdirSync19 } = await import("fs");
|
|
34781
34789
|
renameSync4(configPath, configPath + ".bak");
|
|
34782
|
-
const domainFiles = readdirSync19(
|
|
34790
|
+
const domainFiles = readdirSync19(join50(configDir, "config")).filter((f) => f.endsWith(".json"));
|
|
34783
34791
|
console.log(pc2.green(t("config.migrate_done", { count: String(domainFiles.length) })));
|
|
34784
34792
|
}
|
|
34785
34793
|
var version2, COMMAND_GROUPS;
|
|
@@ -34839,9 +34847,9 @@ init_config2();
|
|
|
34839
34847
|
init_setup();
|
|
34840
34848
|
init_i18n();
|
|
34841
34849
|
init_colors();
|
|
34842
|
-
import { join as
|
|
34850
|
+
import { join as join49, dirname as dirname22 } from "path";
|
|
34843
34851
|
import { homedir as homedir16 } from "os";
|
|
34844
|
-
import { existsSync as
|
|
34852
|
+
import { existsSync as existsSync56 } from "fs";
|
|
34845
34853
|
|
|
34846
34854
|
// src/cli/security-commands.ts
|
|
34847
34855
|
init_bootstrap();
|
|
@@ -35472,12 +35480,92 @@ function createPluginCommand(program2) {
|
|
|
35472
35480
|
// src/cli/commands.ts
|
|
35473
35481
|
init_presets();
|
|
35474
35482
|
init_version();
|
|
35483
|
+
|
|
35484
|
+
// src/modules/updater/changelog-reader.ts
|
|
35485
|
+
import { readFileSync as readFileSync32, existsSync as existsSync51 } from "fs";
|
|
35486
|
+
import { dirname as dirname19, join as join44 } from "path";
|
|
35487
|
+
function readChangelog(packageName) {
|
|
35488
|
+
try {
|
|
35489
|
+
let dir = dirname19(import.meta.url);
|
|
35490
|
+
if (dir.startsWith("file://")) {
|
|
35491
|
+
dir = decodeURIComponent(dir.slice(7));
|
|
35492
|
+
}
|
|
35493
|
+
for (let i = 0;i < 10; i++) {
|
|
35494
|
+
const pkgPath = join44(dir, "package.json");
|
|
35495
|
+
if (existsSync51(pkgPath)) {
|
|
35496
|
+
const pkg = JSON.parse(readFileSync32(pkgPath, "utf-8"));
|
|
35497
|
+
if (pkg.name === packageName) {
|
|
35498
|
+
const changelogPath = join44(dir, "CHANGELOG.md");
|
|
35499
|
+
if (existsSync51(changelogPath)) {
|
|
35500
|
+
return readFileSync32(changelogPath, "utf-8");
|
|
35501
|
+
}
|
|
35502
|
+
return null;
|
|
35503
|
+
}
|
|
35504
|
+
}
|
|
35505
|
+
dir = dirname19(dir);
|
|
35506
|
+
}
|
|
35507
|
+
return null;
|
|
35508
|
+
} catch {
|
|
35509
|
+
return null;
|
|
35510
|
+
}
|
|
35511
|
+
}
|
|
35512
|
+
function extractChangelogRange(changelog, fromVersion, toVersion) {
|
|
35513
|
+
const lines = changelog.split(`
|
|
35514
|
+
`);
|
|
35515
|
+
const sections = [];
|
|
35516
|
+
let capturing = false;
|
|
35517
|
+
let foundFrom = false;
|
|
35518
|
+
for (const line of lines) {
|
|
35519
|
+
const match = line.match(/^## \[(\d+\.\d+\.\d+)\]/);
|
|
35520
|
+
if (match) {
|
|
35521
|
+
const ver = match[1];
|
|
35522
|
+
if (ver === fromVersion) {
|
|
35523
|
+
foundFrom = true;
|
|
35524
|
+
break;
|
|
35525
|
+
}
|
|
35526
|
+
if (capturing) {
|
|
35527
|
+
sections.push("");
|
|
35528
|
+
}
|
|
35529
|
+
capturing = true;
|
|
35530
|
+
}
|
|
35531
|
+
if (capturing) {
|
|
35532
|
+
sections.push(line);
|
|
35533
|
+
}
|
|
35534
|
+
}
|
|
35535
|
+
if (!foundFrom)
|
|
35536
|
+
return null;
|
|
35537
|
+
return sections.length > 0 ? sections.join(`
|
|
35538
|
+
`).trim() : null;
|
|
35539
|
+
}
|
|
35540
|
+
function extractLatestChangelog(changelog) {
|
|
35541
|
+
const lines = changelog.split(`
|
|
35542
|
+
`);
|
|
35543
|
+
const sections = [];
|
|
35544
|
+
let capturing = false;
|
|
35545
|
+
let found = false;
|
|
35546
|
+
for (const line of lines) {
|
|
35547
|
+
const match = line.match(/^## \[(\d+\.\d+\.\d+)\]/);
|
|
35548
|
+
if (match) {
|
|
35549
|
+
if (found)
|
|
35550
|
+
break;
|
|
35551
|
+
capturing = true;
|
|
35552
|
+
found = true;
|
|
35553
|
+
}
|
|
35554
|
+
if (capturing) {
|
|
35555
|
+
sections.push(line);
|
|
35556
|
+
}
|
|
35557
|
+
}
|
|
35558
|
+
return sections.length > 0 ? sections.join(`
|
|
35559
|
+
`).trim() : null;
|
|
35560
|
+
}
|
|
35561
|
+
|
|
35562
|
+
// src/cli/commands.ts
|
|
35475
35563
|
var version = readMmaVersion();
|
|
35476
35564
|
function createProgram() {
|
|
35477
35565
|
const program2 = new Command().name("mma").description(t("cli.description")).version(version).option("--no-agents-md", t("cli.no_agents_md")).option("-d, --dir <path>", t("cli.dir")).option("-e, --exit-on-complete", t("cli.exit_on_complete")).option("-j, --json", t("cli.json")).option("--reasoning <level>", t("cli.reasoning_level"), "auto");
|
|
35478
35566
|
program2.command("init").description(t("cli.init")).action(async () => {
|
|
35479
35567
|
const answers = await runSetup();
|
|
35480
|
-
const configPath =
|
|
35568
|
+
const configPath = join49(homedir16(), ".mma", "config.json");
|
|
35481
35569
|
const { config } = await bootstrap();
|
|
35482
35570
|
config.provider.type = answers.provider;
|
|
35483
35571
|
config.provider.baseUrl = answers.apiBase;
|
|
@@ -35517,12 +35605,12 @@ function createProgram() {
|
|
|
35517
35605
|
config.security.paths.denied = [];
|
|
35518
35606
|
}
|
|
35519
35607
|
}
|
|
35520
|
-
saveConfig(config, configPath,
|
|
35608
|
+
saveConfig(config, configPath, dirname22(configPath));
|
|
35521
35609
|
console.log(t("cli.config_saved"));
|
|
35522
35610
|
});
|
|
35523
35611
|
const configCmd = program2.command("config").description(t("cli.manage_config"));
|
|
35524
35612
|
configCmd.command("set").argument("<key>", t("cli.config_key")).argument("<value>", "Config value").description(t("cli.set_value")).action(async (key, value) => {
|
|
35525
|
-
const configPath =
|
|
35613
|
+
const configPath = join49(homedir16(), ".mma", "config.json");
|
|
35526
35614
|
const { config } = await bootstrap();
|
|
35527
35615
|
const keys = key.split(".");
|
|
35528
35616
|
let obj = config;
|
|
@@ -35542,7 +35630,7 @@ function createProgram() {
|
|
|
35542
35630
|
obj[lastKey] = parseFloat(value);
|
|
35543
35631
|
else
|
|
35544
35632
|
obj[lastKey] = value;
|
|
35545
|
-
saveConfig(config, configPath,
|
|
35633
|
+
saveConfig(config, configPath, dirname22(configPath));
|
|
35546
35634
|
console.log(t("cli.set_done", { key, value }));
|
|
35547
35635
|
});
|
|
35548
35636
|
configCmd.command("show").description(t("cli.show_config")).action(async () => {
|
|
@@ -35552,24 +35640,24 @@ function createProgram() {
|
|
|
35552
35640
|
configCmd.command("migrate").description(t("cli.migrate_config")).action(async () => {
|
|
35553
35641
|
const { loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_config2(), exports_config));
|
|
35554
35642
|
const { hasDomainFiles: hasDomainFiles3 } = await Promise.resolve().then(() => (init_domains(), exports_domains));
|
|
35555
|
-
const configDir =
|
|
35556
|
-
const configPath =
|
|
35643
|
+
const configDir = join49(homedir16(), ".mma");
|
|
35644
|
+
const configPath = join49(configDir, "config.json");
|
|
35557
35645
|
if (hasDomainFiles3(configDir)) {
|
|
35558
35646
|
console.log(pc2.yellow(t("config.migrate_no_legacy")));
|
|
35559
35647
|
return;
|
|
35560
35648
|
}
|
|
35561
|
-
if (!
|
|
35649
|
+
if (!existsSync56(configPath)) {
|
|
35562
35650
|
console.log(pc2.yellow(t("config.migrate_no_legacy")));
|
|
35563
35651
|
return;
|
|
35564
35652
|
}
|
|
35565
35653
|
console.log(t("config.migrate_start"));
|
|
35566
|
-
const { config } = loadConfig2({ configDir, projectConfigPath:
|
|
35654
|
+
const { config } = loadConfig2({ configDir, projectConfigPath: join49(configDir, ".mmrc") });
|
|
35567
35655
|
saveConfig(config, configPath, configDir);
|
|
35568
35656
|
const bakPath = configPath + ".bak";
|
|
35569
35657
|
const { renameSync: renameSync4 } = await import("fs");
|
|
35570
35658
|
renameSync4(configPath, bakPath);
|
|
35571
35659
|
const { readdirSync: readdirSync19 } = await import("fs");
|
|
35572
|
-
const domainFiles = readdirSync19(
|
|
35660
|
+
const domainFiles = readdirSync19(join49(configDir, "config")).filter((f) => f.endsWith(".json"));
|
|
35573
35661
|
console.log(pc2.green(t("config.migrate_done", { count: String(domainFiles.length) })));
|
|
35574
35662
|
});
|
|
35575
35663
|
const model = program2.command("model").description(t("cli.manage_models"));
|
|
@@ -35609,10 +35697,10 @@ function createProgram() {
|
|
|
35609
35697
|
console.log(t("cli.model_hint"));
|
|
35610
35698
|
});
|
|
35611
35699
|
model.command("use").argument("<name>", "Model name").description(t("cli.set_model")).action(async (name) => {
|
|
35612
|
-
const configPath =
|
|
35700
|
+
const configPath = join49(homedir16(), ".mma", "config.json");
|
|
35613
35701
|
const { config } = await bootstrap();
|
|
35614
35702
|
config.model = name;
|
|
35615
|
-
saveConfig(config, configPath,
|
|
35703
|
+
saveConfig(config, configPath, dirname22(configPath));
|
|
35616
35704
|
console.log(t("cli.model_set", { name }));
|
|
35617
35705
|
});
|
|
35618
35706
|
model.command("certify").argument("<name>", "Model name").option("--provider-url <url>", t("cli.cert_provider_url")).option("--provider-key <key>", t("cli.cert_provider_key")).option("--context-window <n>", t("cli.cert_context_window")).option("--tags <tags>", t("cli.cert_tags"), "core").option("--scenarios <ids>", t("cli.cert_scenarios")).option("--timeout <ms>", t("cli.cert_timeout")).option("--reps <n>", t("cli.cert_reps")).option("--force", t("cli.cert_force")).option("--clean", t("cli.cert_clean")).description(t("cli.certify")).action(async (name, cmdOpts) => {
|
|
@@ -35648,7 +35736,7 @@ function createProgram() {
|
|
|
35648
35736
|
await uncertify2(name, config, process.cwd());
|
|
35649
35737
|
});
|
|
35650
35738
|
program2.command("context").description(t("cli.manage_context")).argument("<size>", "Context window size in tokens").action(async (size) => {
|
|
35651
|
-
const configPath =
|
|
35739
|
+
const configPath = join49(homedir16(), ".mma", "config.json");
|
|
35652
35740
|
const { config } = await bootstrap();
|
|
35653
35741
|
const contextWindow = parseInt(size, 10);
|
|
35654
35742
|
if (isNaN(contextWindow) || contextWindow < 1024) {
|
|
@@ -35656,7 +35744,7 @@ function createProgram() {
|
|
|
35656
35744
|
return;
|
|
35657
35745
|
}
|
|
35658
35746
|
config.contextWindow = contextWindow;
|
|
35659
|
-
saveConfig(config, configPath,
|
|
35747
|
+
saveConfig(config, configPath, dirname22(configPath));
|
|
35660
35748
|
console.log(t("cli.context_set", { size: contextWindow }));
|
|
35661
35749
|
});
|
|
35662
35750
|
const provider = program2.command("provider").description(t("cli.manage_providers"));
|
|
@@ -35694,7 +35782,7 @@ function createProgram() {
|
|
|
35694
35782
|
console.log(t("cli.base_url"), config.provider.baseUrl);
|
|
35695
35783
|
});
|
|
35696
35784
|
provider.command("use").argument("<name>", "Provider name").description(t("cli.set_provider")).action(async (name) => {
|
|
35697
|
-
const configPath =
|
|
35785
|
+
const configPath = join49(homedir16(), ".mma", "config.json");
|
|
35698
35786
|
const { config, agent } = await bootstrap();
|
|
35699
35787
|
if (config.provider.entries && config.provider.entries.length > 0) {
|
|
35700
35788
|
try {
|
|
@@ -35710,14 +35798,14 @@ function createProgram() {
|
|
|
35710
35798
|
if (baseUrl) {
|
|
35711
35799
|
config.provider.baseUrl = baseUrl;
|
|
35712
35800
|
}
|
|
35713
|
-
saveConfig(config, configPath,
|
|
35801
|
+
saveConfig(config, configPath, dirname22(configPath));
|
|
35714
35802
|
console.log(t("cli.provider_set", { name }));
|
|
35715
35803
|
if (baseUrl) {
|
|
35716
35804
|
console.log(t("cli.provider_base_hint", { baseUrl }));
|
|
35717
35805
|
}
|
|
35718
35806
|
});
|
|
35719
35807
|
provider.command("add").argument("<name>", "Provider type or label").option("--url <url>", "Base URL").option("--key <key>", "API key").option("--priority <n>", "Fallback priority (lower = tried first)").option("--context-window <n>", "Context window override for this entry").option("--rpm <n>", "Max requests per minute for this entry").option("--parallel <n>", "Max parallel tasks for this entry").description(t("cli.add_provider")).action(async (name, opts) => {
|
|
35720
|
-
const configPath =
|
|
35808
|
+
const configPath = join49(homedir16(), ".mma", "config.json");
|
|
35721
35809
|
const { config } = await bootstrap();
|
|
35722
35810
|
const entries = Array.isArray(config.provider.entries) ? config.provider.entries : [];
|
|
35723
35811
|
if (entries.length === 0) {
|
|
@@ -35749,7 +35837,7 @@ function createProgram() {
|
|
|
35749
35837
|
});
|
|
35750
35838
|
config.provider.entries = entries;
|
|
35751
35839
|
config.provider.active = config.provider.active || config.provider.type;
|
|
35752
|
-
saveConfig(config, configPath,
|
|
35840
|
+
saveConfig(config, configPath, dirname22(configPath));
|
|
35753
35841
|
console.log(pc2.green(t("cli.provider_added", { name })));
|
|
35754
35842
|
console.log(t("cli.provider_switch_hint"));
|
|
35755
35843
|
});
|
|
@@ -35790,6 +35878,31 @@ function createProgram() {
|
|
|
35790
35878
|
});
|
|
35791
35879
|
createSecurityCommand(program2);
|
|
35792
35880
|
createPluginCommand(program2);
|
|
35881
|
+
program2.command("changelog").description(t("cli.changelog_title", { version })).option("--from <version>", t("cli.changelog_range", { from: "..." })).action((opts) => {
|
|
35882
|
+
console.error("[DEBUG] changelog action called");
|
|
35883
|
+
const changelog = readChangelog("micro-models-agent");
|
|
35884
|
+
if (!changelog) {
|
|
35885
|
+
console.log(pc2.yellow(t("cli.changelog_not_found")));
|
|
35886
|
+
return;
|
|
35887
|
+
}
|
|
35888
|
+
if (opts.from) {
|
|
35889
|
+
const range = extractChangelogRange(changelog, opts.from, version);
|
|
35890
|
+
if (!range) {
|
|
35891
|
+
console.log(pc2.yellow(t("cli.changelog_not_found")));
|
|
35892
|
+
return;
|
|
35893
|
+
}
|
|
35894
|
+
console.log(pc2.cyan(t("cli.changelog_range", { from: opts.from })));
|
|
35895
|
+
console.log(range);
|
|
35896
|
+
} else {
|
|
35897
|
+
const latest = extractLatestChangelog(changelog);
|
|
35898
|
+
if (!latest) {
|
|
35899
|
+
console.log(pc2.yellow(t("cli.changelog_not_found")));
|
|
35900
|
+
return;
|
|
35901
|
+
}
|
|
35902
|
+
console.log(pc2.cyan(t("cli.changelog_title", { version })));
|
|
35903
|
+
console.log(latest);
|
|
35904
|
+
}
|
|
35905
|
+
});
|
|
35793
35906
|
program2.argument("[prompt...]", "Prompt to execute").description("Run a single prompt").action((prompt) => {});
|
|
35794
35907
|
return program2;
|
|
35795
35908
|
}
|
|
@@ -36667,8 +36780,8 @@ class LineEditor {
|
|
|
36667
36780
|
}
|
|
36668
36781
|
|
|
36669
36782
|
// src/cli/repl.ts
|
|
36670
|
-
import { existsSync as
|
|
36671
|
-
import { join as
|
|
36783
|
+
import { existsSync as existsSync58, readFileSync as readFileSync39, writeFileSync as writeFileSync22 } from "fs";
|
|
36784
|
+
import { join as join51 } from "path";
|
|
36672
36785
|
import { homedir as homedir17 } from "os";
|
|
36673
36786
|
|
|
36674
36787
|
// src/cli/completer.ts
|
|
@@ -37495,10 +37608,10 @@ class Repl {
|
|
|
37495
37608
|
this.envReport = envReport;
|
|
37496
37609
|
this.execModule = execModule;
|
|
37497
37610
|
this.slog = new SessionLogger(sessionManager, logger4);
|
|
37498
|
-
this.configDir = configDir ||
|
|
37611
|
+
this.configDir = configDir || join51(homedir17(), ".mma");
|
|
37499
37612
|
this.baseDir = baseDir || process.cwd();
|
|
37500
37613
|
this.noAgentsMd = noAgentsMd === true;
|
|
37501
|
-
this.historyPath = historyPath ??
|
|
37614
|
+
this.historyPath = historyPath ?? join51(homedir17(), ".mma", "repl-history");
|
|
37502
37615
|
this.loadHistory();
|
|
37503
37616
|
this.rl = process.stdin.isTTY ? new LineEditor({
|
|
37504
37617
|
input: process.stdin,
|
|
@@ -37550,9 +37663,9 @@ class Repl {
|
|
|
37550
37663
|
}));
|
|
37551
37664
|
}
|
|
37552
37665
|
loadHistory() {
|
|
37553
|
-
if (
|
|
37666
|
+
if (existsSync58(this.historyPath)) {
|
|
37554
37667
|
try {
|
|
37555
|
-
const raw =
|
|
37668
|
+
const raw = readFileSync39(this.historyPath, "utf-8");
|
|
37556
37669
|
this.history = raw.split(`
|
|
37557
37670
|
`).filter(Boolean).slice(-this.maxHistory);
|
|
37558
37671
|
} catch {
|
|
@@ -37950,11 +38063,11 @@ ${t("image.clipboard_empty")}`));
|
|
|
37950
38063
|
row(t("repl.agents_label"), pc2.red(t("repl.disabled")));
|
|
37951
38064
|
} else {
|
|
37952
38065
|
const agentsMdCandidates = [
|
|
37953
|
-
|
|
37954
|
-
|
|
37955
|
-
|
|
38066
|
+
join51(this.baseDir, "AGENTS.md"),
|
|
38067
|
+
join51(this.baseDir, ".mma", "AGENTS.md"),
|
|
38068
|
+
join51(this.configDir, "AGENTS.md")
|
|
37956
38069
|
];
|
|
37957
|
-
const foundAgents = agentsMdCandidates.filter((p) =>
|
|
38070
|
+
const foundAgents = agentsMdCandidates.filter((p) => existsSync58(p));
|
|
37958
38071
|
if (foundAgents.length > 0) {
|
|
37959
38072
|
for (const p of foundAgents) {
|
|
37960
38073
|
row(t("repl.agents_label"), pc2.dim(p));
|
|
@@ -37965,7 +38078,7 @@ ${t("image.clipboard_empty")}`));
|
|
|
37965
38078
|
}
|
|
37966
38079
|
const meta = this.sessionManager?.getActiveMeta();
|
|
37967
38080
|
if (meta) {
|
|
37968
|
-
const sessionPath =
|
|
38081
|
+
const sessionPath = join51(this.configDir, "sessions", meta.id);
|
|
37969
38082
|
row(t("repl.session_label"), `${pc2.cyan(meta.name)} ${pc2.dim(`(${meta.id.slice(0, 12)})`)} — ${meta.messageCount} msgs ${pc2.dim(sessionPath)}`);
|
|
37970
38083
|
}
|
|
37971
38084
|
const isTty2 = process.stdout.isTTY === true;
|
|
@@ -38080,8 +38193,8 @@ init_setup();
|
|
|
38080
38193
|
init_config2();
|
|
38081
38194
|
init_i18n();
|
|
38082
38195
|
init_colors();
|
|
38083
|
-
import { existsSync as
|
|
38084
|
-
import { join as
|
|
38196
|
+
import { existsSync as existsSync59 } from "fs";
|
|
38197
|
+
import { join as join53, dirname as dirname24 } from "path";
|
|
38085
38198
|
import { homedir as homedir19 } from "os";
|
|
38086
38199
|
|
|
38087
38200
|
// src/modules/updater/index.ts
|
|
@@ -38165,7 +38278,16 @@ class UpdaterModule {
|
|
|
38165
38278
|
}));
|
|
38166
38279
|
const install = await this.updater.install(result.latest);
|
|
38167
38280
|
if (install.success) {
|
|
38168
|
-
|
|
38281
|
+
const changelog = readChangelog("micro-models-agent");
|
|
38282
|
+
const latestEntry = changelog ? extractLatestChangelog(changelog) : null;
|
|
38283
|
+
const changelogBlock = latestEntry ? pc2.cyan(`
|
|
38284
|
+
${t("cli.changelog_title", { version: result.latest })}
|
|
38285
|
+
`) + latestEntry : "";
|
|
38286
|
+
this.logger.info(t("updater.installed", {
|
|
38287
|
+
current: result.current,
|
|
38288
|
+
latest: result.latest,
|
|
38289
|
+
changelog: changelogBlock
|
|
38290
|
+
}));
|
|
38169
38291
|
} else {
|
|
38170
38292
|
this.logger.warn(t("updater.install_failed", {
|
|
38171
38293
|
current: result.current,
|
|
@@ -38186,9 +38308,9 @@ init_environment();
|
|
|
38186
38308
|
init_data_sanitizer();
|
|
38187
38309
|
init_i18n();
|
|
38188
38310
|
import { appendFileSync as appendFileSync7, mkdirSync as mkdirSync21 } from "fs";
|
|
38189
|
-
import { join as
|
|
38311
|
+
import { join as join52 } from "path";
|
|
38190
38312
|
import { homedir as homedir18 } from "os";
|
|
38191
|
-
var CRASH_LOG_DIR =
|
|
38313
|
+
var CRASH_LOG_DIR = join52(homedir18(), ".mma", "logs");
|
|
38192
38314
|
var CRASH_LOG_FILE = "crash.jsonl";
|
|
38193
38315
|
function formatCrashEntry(type2, err) {
|
|
38194
38316
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -38204,7 +38326,7 @@ function formatCrashEntry(type2, err) {
|
|
|
38204
38326
|
function writeCrashEntry(dir, entry) {
|
|
38205
38327
|
try {
|
|
38206
38328
|
mkdirSync21(dir, { recursive: true });
|
|
38207
|
-
appendFileSync7(
|
|
38329
|
+
appendFileSync7(join52(dir, CRASH_LOG_FILE), JSON.stringify(entry) + `
|
|
38208
38330
|
`, "utf-8");
|
|
38209
38331
|
} catch {}
|
|
38210
38332
|
}
|
|
@@ -38258,6 +38380,9 @@ async function main() {
|
|
|
38258
38380
|
const jsonMode = opts.json === true;
|
|
38259
38381
|
const reasoningLevel = opts.reasoning;
|
|
38260
38382
|
const isSubcommand = program2.args.length > 0 && cmdNames.has(program2.args[0]);
|
|
38383
|
+
console.error("[DEBUG] program.args:", program2.args);
|
|
38384
|
+
console.error("[DEBUG] cmdNames:", [...cmdNames]);
|
|
38385
|
+
console.error("[DEBUG] isSubcommand:", isSubcommand);
|
|
38261
38386
|
if (isSubcommand) {
|
|
38262
38387
|
return;
|
|
38263
38388
|
}
|
|
@@ -38313,9 +38438,9 @@ async function main() {
|
|
|
38313
38438
|
await updater?.waitForIdle();
|
|
38314
38439
|
process.exit(exitCode);
|
|
38315
38440
|
} else {
|
|
38316
|
-
const mmaDir =
|
|
38317
|
-
const legacyConfigPath =
|
|
38318
|
-
let hasAnyConfig =
|
|
38441
|
+
const mmaDir = join53(homedir19(), ".mma");
|
|
38442
|
+
const legacyConfigPath = join53(mmaDir, "config.json");
|
|
38443
|
+
let hasAnyConfig = existsSync59(legacyConfigPath);
|
|
38319
38444
|
if (!hasAnyConfig) {
|
|
38320
38445
|
try {
|
|
38321
38446
|
const { hasDomainFiles: hasDomainFiles3 } = await Promise.resolve().then(() => (init_domains(), exports_domains));
|
|
@@ -38378,7 +38503,7 @@ async function main() {
|
|
|
38378
38503
|
config.security.paths.denied = [];
|
|
38379
38504
|
}
|
|
38380
38505
|
}
|
|
38381
|
-
saveConfig(config, legacyConfigPath,
|
|
38506
|
+
saveConfig(config, legacyConfigPath, dirname24(legacyConfigPath));
|
|
38382
38507
|
await agent.reconfigure(config);
|
|
38383
38508
|
}
|
|
38384
38509
|
startAutoUpdate(config);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "micro-models-agent",
|
|
3
|
-
"version": "0.56.
|
|
3
|
+
"version": "0.56.2",
|
|
4
4
|
"description": "Micro Models Agent (MMA) — LLM agent harness for small models (Qwen3.5-9B, 32K-64K context)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
},
|
|
9
9
|
"files": [
|
|
10
10
|
"dist/",
|
|
11
|
-
"bin/"
|
|
11
|
+
"bin/",
|
|
12
|
+
"CHANGELOG.md"
|
|
12
13
|
],
|
|
13
14
|
"engines": {
|
|
14
15
|
"node": ">=20"
|