micro-models-agent 0.48.3 → 0.49.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 (2) hide show
  1. package/dist/main.js +60 -68
  2. package/package.json +1 -1
package/dist/main.js CHANGED
@@ -19139,6 +19139,9 @@ class ExecutionModule {
19139
19139
  getTracker() {
19140
19140
  return this.tracker;
19141
19141
  }
19142
+ getActivePlan() {
19143
+ return this.tracker?.getPlan() ?? null;
19144
+ }
19142
19145
  getStore() {
19143
19146
  return this.store;
19144
19147
  }
@@ -22202,6 +22205,31 @@ function buildSystemInfo(config, baseDir, profileCompressed) {
22202
22205
  lines.push(`Plan rule (MANDATORY): any task creating files, installing packages, or requiring multiple actions MUST create a plan with the "plan" tool BEFORE starting. Each step = a concrete deliverable.`);
22203
22206
  }
22204
22207
  lines.push(`Runtime verification: when a bug is described in terms of runtime behavior (what happens when the app runs), reproduce it — run the app / build / browser tool — and confirm the fix against actual runtime output before calling "plan update step=N status=done". Check existing servers first with process_list/process_log: a stale dev server started BEFORE your change still runs the old pipeline and keeps failing even after the files on disk are fixed. Restart or kill it (process_kill) and verify the exact endpoint/port the user reported — a fresh server on a new port does NOT prove the user's error is gone.`);
22208
+ const sec = config.security;
22209
+ if (sec?.enabled) {
22210
+ const secLines = [`SECURITY RESTRICTIONS (enforced — blocked calls return "[SECURITY BLOCKED]", do not retry them):`];
22211
+ if (sec.bash?.enabled && sec.bash.blacklist.length > 0) {
22212
+ const cmds = sec.bash.blacklist.slice(0, 15).join(", ");
22213
+ secLines.push(`Forbidden bash commands: ${cmds}${sec.bash.blacklist.length > 15 ? ", …" : ""}.`);
22214
+ if (sec.bash.whitelist.length > 0) {
22215
+ secLines.push(`Only whitelisted bash commands are allowed: ${sec.bash.whitelist.slice(0, 15).join(", ")}.`);
22216
+ }
22217
+ if (sec.bash.blockDangerousFlags) {
22218
+ secLines.push(`Pipes/redirects/chaining (| > >> ; &&) in bash are blocked — one plain command per call.`);
22219
+ }
22220
+ }
22221
+ if (sec.paths?.enabled && sec.paths.denied.length > 0) {
22222
+ const paths = sec.paths.denied.slice(0, 10).join(", ");
22223
+ secLines.push(`Denied paths (read/write): ${paths}${sec.paths.denied.length > 10 ? ", …" : ""}.`);
22224
+ }
22225
+ if (sec.network?.enabled && sec.network.deniedDomains.length > 0) {
22226
+ const domains = sec.network.deniedDomains.slice(0, 10).join(", ");
22227
+ secLines.push(`Denied network domains: ${domains}${sec.network.deniedDomains.length > 10 ? ", …" : ""}.`);
22228
+ }
22229
+ if (secLines.length > 1) {
22230
+ lines.push(...secLines);
22231
+ }
22232
+ }
22205
22233
  const hasMCP = config.mcpServers && Object.values(config.mcpServers).some((s) => s.enabled !== false);
22206
22234
  if (hasMCP) {
22207
22235
  lines.push(`MCP servers are available — use the named MCP tools (prefixed mcp__) to query external services.`);
@@ -22533,6 +22561,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
22533
22561
  sessionManager,
22534
22562
  skillsModule,
22535
22563
  pluginManager,
22564
+ execModule,
22536
22565
  toolCtx,
22537
22566
  configDir: dir,
22538
22567
  baseDir,
@@ -33368,8 +33397,8 @@ class LineEditor {
33368
33397
  }
33369
33398
 
33370
33399
  // src/cli/repl.ts
33371
- import { existsSync as existsSync53, readFileSync as readFileSync35, writeFileSync as writeFileSync17 } from "fs";
33372
- import { join as join49 } from "path";
33400
+ import { existsSync as existsSync52, readFileSync as readFileSync34, writeFileSync as writeFileSync17 } from "fs";
33401
+ import { join as join48 } from "path";
33373
33402
  import { homedir as homedir18 } from "os";
33374
33403
 
33375
33404
  // src/cli/completer.ts
@@ -33981,31 +34010,6 @@ init_session_logger();
33981
34010
  init_colors();
33982
34011
  init_js_identifiers();
33983
34012
  init_i18n();
33984
- import { existsSync as existsSync52, readFileSync as readFileSync34 } from "fs";
33985
- import { join as join48 } from "path";
33986
- function readActivePlan(baseDir) {
33987
- const p = join48(baseDir, ".mma", "plans", "active.json");
33988
- if (!existsSync52(p))
33989
- return null;
33990
- try {
33991
- const raw = readFileSync34(p, "utf-8");
33992
- if (!raw.trim())
33993
- return null;
33994
- const parsed = JSON.parse(raw);
33995
- if (!parsed || !Array.isArray(parsed.steps))
33996
- return null;
33997
- return {
33998
- id: parsed.id || "plan",
33999
- title: parsed.title || "Plan",
34000
- steps: parsed.steps,
34001
- createdAt: parsed.createdAt || new Date().toISOString(),
34002
- baseDir: parsed.baseDir || baseDir,
34003
- name: parsed.name
34004
- };
34005
- } catch {
34006
- return null;
34007
- }
34008
- }
34009
34013
  function currentStepIndex(plan) {
34010
34014
  const idx = plan.steps.findIndex((s) => s.status !== "done" && s.status !== "skipped");
34011
34015
  return idx === -1 ? 0 : idx;
@@ -34114,8 +34118,7 @@ class Repl {
34114
34118
  noAgentsMd;
34115
34119
  pendingClipboardImage = null;
34116
34120
  exitOnClose = false;
34117
- activePlan = null;
34118
- lastPlanSig = null;
34121
+ execModule;
34119
34122
  rl;
34120
34123
  agent;
34121
34124
  config;
@@ -34125,7 +34128,7 @@ class Repl {
34125
34128
  logger;
34126
34129
  slog;
34127
34130
  envReport;
34128
- constructor(agent, config, sessionManager, skillsModule, pluginManager, configDir, baseDir, noAgentsMd, logger, exitOnClose, envReport, historyPath) {
34131
+ constructor(agent, config, sessionManager, skillsModule, pluginManager, configDir, baseDir, noAgentsMd, logger, exitOnClose, envReport, historyPath, execModule) {
34129
34132
  this.agent = agent;
34130
34133
  this.config = config;
34131
34134
  this.exitOnClose = exitOnClose === true;
@@ -34134,11 +34137,12 @@ class Repl {
34134
34137
  this.pluginManager = pluginManager;
34135
34138
  this.logger = logger;
34136
34139
  this.envReport = envReport;
34140
+ this.execModule = execModule;
34137
34141
  this.slog = new SessionLogger(sessionManager, logger);
34138
- this.configDir = configDir || join49(homedir18(), ".mma");
34142
+ this.configDir = configDir || join48(homedir18(), ".mma");
34139
34143
  this.baseDir = baseDir || process.cwd();
34140
34144
  this.noAgentsMd = noAgentsMd === true;
34141
- this.historyPath = historyPath ?? join49(homedir18(), ".mma", "repl-history");
34145
+ this.historyPath = historyPath ?? join48(homedir18(), ".mma", "repl-history");
34142
34146
  this.loadHistory();
34143
34147
  this.rl = process.stdin.isTTY ? new LineEditor({
34144
34148
  input: process.stdin,
@@ -34171,9 +34175,9 @@ class Repl {
34171
34175
  this.setupListeners();
34172
34176
  }
34173
34177
  loadHistory() {
34174
- if (existsSync53(this.historyPath)) {
34178
+ if (existsSync52(this.historyPath)) {
34175
34179
  try {
34176
- const raw = readFileSync35(this.historyPath, "utf-8");
34180
+ const raw = readFileSync34(this.historyPath, "utf-8");
34177
34181
  this.history = raw.split(`
34178
34182
  `).filter(Boolean).slice(-this.maxHistory);
34179
34183
  } catch {
@@ -34375,14 +34379,13 @@ ${t("image.clipboard_empty")}`));
34375
34379
  spinner: this.config.ui?.spinner ?? true,
34376
34380
  toolStyle: this.config.ui?.toolStyle ?? "inline"
34377
34381
  });
34378
- this.refreshActivePlan(renderer);
34379
34382
  const result = await this.agent.run(input, (c) => renderer.text(c), (m) => renderer.meta(m), (ev) => {
34380
34383
  if (ev.type === "start") {
34381
- renderer.toolStart(ev.tool, ev.args, stepContextForTool(this.activePlan, ev.tool, ev.args), ev.icon);
34384
+ renderer.toolStart(ev.tool, ev.args, stepContextForTool(this.execModule?.getActivePlan() ?? null, ev.tool, ev.args), ev.icon);
34382
34385
  } else {
34383
34386
  renderer.toolEnd(ev.tool, ev.duration ?? 0, ev.error, ev.ctxDelta, ev.costUsd);
34384
34387
  if (ev.tool === "plan" || ev.tool === "todo") {
34385
- this.refreshActivePlan(renderer);
34388
+ this.renderPlan(renderer);
34386
34389
  }
34387
34390
  }
34388
34391
  }, (phase) => {
@@ -34407,23 +34410,11 @@ ${t("image.clipboard_empty")}`));
34407
34410
  this.agentRunning = false;
34408
34411
  }
34409
34412
  }
34410
- refreshActivePlan(renderer) {
34411
- const plan = readActivePlan(this.baseDir);
34412
- const sig = plan ? JSON.stringify(plan.steps.map((s) => `${s.id}:${s.status}`)) : "";
34413
- if (!plan) {
34414
- this.activePlan = null;
34415
- this.lastPlanSig = "";
34416
- return;
34417
- }
34418
- this.activePlan = plan;
34419
- if (this.lastPlanSig === null) {
34420
- this.lastPlanSig = sig;
34413
+ renderPlan(renderer) {
34414
+ const plan = this.execModule?.getActivePlan();
34415
+ if (!plan)
34421
34416
  return;
34422
- }
34423
- if (sig !== this.lastPlanSig) {
34424
- this.lastPlanSig = sig;
34425
- renderer.planBlock(formatPlanChecklist(plan));
34426
- }
34417
+ renderer.planBlock(formatPlanChecklist(plan));
34427
34418
  }
34428
34419
  commands = new Map;
34429
34420
  registerCommand(cmd) {
@@ -34556,11 +34547,11 @@ ${t("image.clipboard_empty")}`));
34556
34547
  row(t("repl.agents_label"), pc2.red(t("repl.disabled")));
34557
34548
  } else {
34558
34549
  const agentsMdCandidates = [
34559
- join49(this.baseDir, "AGENTS.md"),
34560
- join49(this.baseDir, ".mma", "AGENTS.md"),
34561
- join49(this.configDir, "AGENTS.md")
34550
+ join48(this.baseDir, "AGENTS.md"),
34551
+ join48(this.baseDir, ".mma", "AGENTS.md"),
34552
+ join48(this.configDir, "AGENTS.md")
34562
34553
  ];
34563
- const foundAgents = agentsMdCandidates.filter((p) => existsSync53(p));
34554
+ const foundAgents = agentsMdCandidates.filter((p) => existsSync52(p));
34564
34555
  if (foundAgents.length > 0) {
34565
34556
  for (const p of foundAgents) {
34566
34557
  row(t("repl.agents_label"), pc2.dim(p));
@@ -34571,7 +34562,7 @@ ${t("image.clipboard_empty")}`));
34571
34562
  }
34572
34563
  const meta = this.sessionManager?.getActiveMeta();
34573
34564
  if (meta) {
34574
- const sessionPath = join49(this.configDir, "sessions", meta.id);
34565
+ const sessionPath = join48(this.configDir, "sessions", meta.id);
34575
34566
  row(t("repl.session_label"), `${pc2.cyan(meta.name)} ${pc2.dim(`(${meta.id.slice(0, 12)})`)} — ${meta.messageCount} msgs ${pc2.dim(sessionPath)}`);
34576
34567
  }
34577
34568
  const headerWidth = Math.max(50, Math.min(96, process.stdout.columns || 96));
@@ -34670,8 +34661,8 @@ init_setup();
34670
34661
  init_config2();
34671
34662
  init_i18n();
34672
34663
  init_colors();
34673
- import { existsSync as existsSync54 } from "fs";
34674
- import { join as join51 } from "path";
34664
+ import { existsSync as existsSync53 } from "fs";
34665
+ import { join as join50 } from "path";
34675
34666
  import { homedir as homedir20 } from "os";
34676
34667
 
34677
34668
  // src/modules/updater/index.ts
@@ -34776,9 +34767,9 @@ init_environment();
34776
34767
  init_data_sanitizer();
34777
34768
  init_i18n();
34778
34769
  import { appendFileSync as appendFileSync7, mkdirSync as mkdirSync20 } from "fs";
34779
- import { join as join50 } from "path";
34770
+ import { join as join49 } from "path";
34780
34771
  import { homedir as homedir19 } from "os";
34781
- var CRASH_LOG_DIR = join50(homedir19(), ".mma", "logs");
34772
+ var CRASH_LOG_DIR = join49(homedir19(), ".mma", "logs");
34782
34773
  var CRASH_LOG_FILE = "crash.jsonl";
34783
34774
  function formatCrashEntry(type2, err) {
34784
34775
  const message = err instanceof Error ? err.message : String(err);
@@ -34794,7 +34785,7 @@ function formatCrashEntry(type2, err) {
34794
34785
  function writeCrashEntry(dir, entry) {
34795
34786
  try {
34796
34787
  mkdirSync20(dir, { recursive: true });
34797
- appendFileSync7(join50(dir, CRASH_LOG_FILE), JSON.stringify(entry) + `
34788
+ appendFileSync7(join49(dir, CRASH_LOG_FILE), JSON.stringify(entry) + `
34798
34789
  `, "utf-8");
34799
34790
  } catch {}
34800
34791
  }
@@ -34897,15 +34888,15 @@ async function main() {
34897
34888
  await updater?.waitForIdle();
34898
34889
  process.exit(exitCode);
34899
34890
  } else {
34900
- const configPath = join51(homedir20(), ".mma", "config.json");
34901
- if (!existsSync54(configPath)) {
34891
+ const configPath = join50(homedir20(), ".mma", "config.json");
34892
+ if (!existsSync53(configPath)) {
34902
34893
  console.log(pc2.yellow(`
34903
34894
  ` + t("cli.first_run") + `
34904
34895
  `));
34905
34896
  const answers = await runSetup();
34906
34897
  const config2 = loadConfig({
34907
- configDir: join51(homedir20(), ".mma"),
34908
- projectConfigPath: projectDir ? join51(projectDir, ".mmrc") : join51(process.cwd(), ".mmrc")
34898
+ configDir: join50(homedir20(), ".mma"),
34899
+ projectConfigPath: projectDir ? join50(projectDir, ".mmrc") : join50(process.cwd(), ".mmrc")
34909
34900
  });
34910
34901
  config2.provider.type = answers.provider;
34911
34902
  config2.provider.baseUrl = answers.apiBase;
@@ -34953,13 +34944,14 @@ async function main() {
34953
34944
  sessionManager,
34954
34945
  skillsModule,
34955
34946
  pluginManager,
34947
+ execModule,
34956
34948
  configDir,
34957
34949
  baseDir,
34958
34950
  logger,
34959
34951
  envReport
34960
34952
  } = await bootstrap(undefined, projectDir, noAgentsMd, exitOnComplete);
34961
34953
  startAutoUpdate(config);
34962
- const repl = new Repl(agent, config, sessionManager, skillsModule, pluginManager, configDir, baseDir, noAgentsMd, logger, true, envReport);
34954
+ const repl = new Repl(agent, config, sessionManager, skillsModule, pluginManager, configDir, baseDir, noAgentsMd, logger, true, envReport, undefined, execModule);
34963
34955
  await repl.start();
34964
34956
  }
34965
34957
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "micro-models-agent",
3
- "version": "0.48.3",
3
+ "version": "0.49.1",
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": {