micro-models-agent 0.21.1 → 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/main.js +175 -47
  2. package/package.json +1 -1
package/dist/main.js CHANGED
@@ -1888,6 +1888,7 @@ var require_commander = __commonJS((exports) => {
1888
1888
  // src/config/security.ts
1889
1889
  function mergeSecurityConfig(userConfig) {
1890
1890
  return {
1891
+ enabled: userConfig?.enabled ?? DEFAULT_SECURITY_CONFIG.enabled,
1891
1892
  bash: {
1892
1893
  ...DEFAULT_SECURITY_CONFIG.bash,
1893
1894
  ...userConfig?.bash
@@ -1923,7 +1924,9 @@ function mergeSecurityConfig(userConfig) {
1923
1924
  var DEFAULT_SECURITY_CONFIG;
1924
1925
  var init_security = __esm(() => {
1925
1926
  DEFAULT_SECURITY_CONFIG = {
1927
+ enabled: false,
1926
1928
  bash: {
1929
+ enabled: false,
1927
1930
  blacklist: [
1928
1931
  "rm",
1929
1932
  "dd",
@@ -1985,6 +1988,7 @@ var init_security = __esm(() => {
1985
1988
  dangerousOperators: [">", ">>", "2>", "2>>", "`"]
1986
1989
  },
1987
1990
  paths: {
1991
+ enabled: false,
1988
1992
  denied: [
1989
1993
  ".git/",
1990
1994
  "node_modules/",
@@ -2004,6 +2008,7 @@ var init_security = __esm(() => {
2004
2008
  allowed: []
2005
2009
  },
2006
2010
  network: {
2011
+ enabled: false,
2007
2012
  deniedDomains: ["localhost", "127.0.0.1", "::1"],
2008
2013
  allowedDomains: [],
2009
2014
  requestTimeout: 15000,
@@ -2548,16 +2553,15 @@ Available commands:`,
2548
2553
  {content}
2549
2554
 
2550
2555
  Use this knowledge to answer the user's question.`,
2551
- "exec.stuck": "Stuck on step {stepId}. Current: {description}. No progress for {iterations} iterations.",
2552
- "exec.stuck_recovery": '[STUCK: {iterations} iterations on step {stepId} — "{description}". You MUST change approach NOW. Concrete actions: (1) Check what this step needs are dependencies installed? (2) Use plan show to see the plan. (3) If commands fail — create files directly via write_file. (4) After completing the step, call plan update step={stepId} status=done. Do NOT work on other steps until this one is finished.]',
2553
- "exec.tool_errors": "Tool {tool} failed {count} times. Suggest alternative approach.",
2554
- "exec.tool_errors_recovery": "[Tool {tool} failed {count} consecutive times. DO NOT use it again. Try a different approach: (1) create files directly via write_file, (2) use a different tool for the same task, (3) if nothing works — explain the problem and skip this step via plan update step=N status=skipped with a note why.]",
2555
- "exec.repetitive_tool": "[REPETITION: you called {tool} {count} times with identical arguments and result. This is pointless. IMMEDIATELY change approach: create files directly, change arguments, or if it's a process — check its status via process_log.]",
2556
- "exec.consecutive_failures_recovery": "[{count} CONSECUTIVE TOOLS FAILED. Stop running commands. Here is what to do: (1) Create files directly via write_file instead of terminal commands. (2) Check if dependencies are installed (npm install). (3) Use list_dir to see what's in the project. (4) Do not attempt build/tests until all files are created.]",
2557
- "exec.task_reminder": "[ORIGINAL TASK: {task}. You MUST work on this task only. Do not create files for other tasks. If you cannot complete it explain why and request help.]",
2558
- "exec.plan_warning": '[⚠ PLAN: you are on step {step} — "{description}", but calling {tool} with files outside this step. This is FORBIDDEN — work STRICTLY on the current step. First complete it and call plan update step={step} status=done, only then move to the next.]',
2559
- "exec.plan_blocked": "[⛔ BLOCKED: {max} consecutive calls outside the current step. You are violating the plan. Return to step {step} and complete it. Other steps are blocked until this one is done.]",
2560
- "exec.off_track": `[⚠ OFF PLAN: step {stepId} is "{description}", but you're using {tool} on a different path. Return to the current step immediately.]`,
2556
+ "exec.stuck": "No progress on step {stepId} ({description}) for {iterations} iterations.",
2557
+ "exec.stuck_recovery": 'Step {stepId} — "{description}" has had no progress for {iterations} iterations. Try a different approach: review what this step needs, check if dependencies are installed, or create files directly via write_file instead of shell commands. After completing the step call plan update step={stepId} status=done.',
2558
+ "exec.tool_errors": "Tool {tool} failed {count} times. Consider using a different tool.",
2559
+ "exec.tool_errors_recovery": "Tool {tool} has failed {count} times in a row. Try an alternative: create files directly via write_file, use a different command, or if nothing works — skip this step via plan update step=N status=skipped with a note explaining why.",
2560
+ "exec.repetitive_tool": "Called {tool} {count} times with identical arguments and result. Try a different approach create files directly, change arguments, or check process status via process_log.",
2561
+ "exec.consecutive_failures_recovery": "{count} consecutive tool failures. Create files directly via write_file instead of terminal commands. Check that dependencies are installed (npm install). Do not run build/tests until all files are created.",
2562
+ "exec.plan_warning": 'Current plan step {step} is "{description}", but {tool} is being called for files outside this step. Complete the current step first, then call plan update step={step} status=done before moving to the next step.',
2563
+ "exec.plan_blocked": "{max} consecutive calls outside the current step. Finish step {step} before proceeding other steps should wait until this one is complete.",
2564
+ "exec.off_track": 'Step {stepId} "{description}" but you are using {tool} on a different path. Return to the current step.',
2561
2565
  "exec.step_gate_deps": '[⚠ Step {step} "{description}": dependencies are not installed. First run the install command (npm install, pip install, etc.). Verify the lock file or dependency directory exists.]',
2562
2566
  "exec.step_gate_empty": "[⚠ Step {step}: files exist but appear empty: {files}. Add real code to these files before advancing to the next step.]",
2563
2567
  "exec.step_gate_ok": '[✓] Step {step} completed and verified. MOVING to step {nextStep}: "{nextDesc}". Work ONLY on this step.',
@@ -3046,16 +3050,15 @@ var init_ru = __esm(() => {
3046
3050
  {content}
3047
3051
 
3048
3052
  Используйте эти знания для ответа на вопрос пользователя.`,
3049
- "exec.stuck": "Застряли на шаге {stepId}. Текущий: {description}. Нет прогресса {iterations} итераций.",
3050
- "exec.stuck_recovery": '[ЗАСТРЕВАНИЕ: {iterations} итераций на шаге {stepId} — "{description}". ВЫ ДОЛЖНЫ сменить подход прямо сейчас. Конкретные действия: (1) Проверьте что нужно для этого шага установлены ли зависимости? (2) Используйте plan show чтобы увидеть план. (3) Если команды не работают — создайте файлы напрямую через write_file. (4) После завершения шага вызовите plan update step={stepId} status=done. НЕ переходите к другим шагам пока этот не завершён.]',
3051
- "exec.tool_errors": "Инструмент {tool} сбоил {count} раз. Предложите другой подход.",
3052
- "exec.tool_errors_recovery": "[Инструмент {tool} сбоил {count} раз подряд. НЕ ИСПОЛЬЗУЙТЕ его снова. Используйте другой подход: (1) создайте нужные файлы напрямую через write_file, (2) используйте другой инструмент для той же задачи, (3) если ничего не работает — объясните проблему и переходите к следующему шагу плана через plan update step=N status=skipped с пометкой почему.]",
3053
- "exec.repetitive_tool": "[ПОВТОРЕНИЕ: вы вызвали {tool} {count} раз с одинаковыми аргументами и результатом. Это бессмысленно. НЕМЕДЛЕННО смените подход: создайте файлы напрямую, измените аргументы или, если это процесс — проверьте его статус через process_log.]",
3054
- "exec.consecutive_failures_recovery": "[{count} ИНСТРУМЕНТОВ ПОДРЯД УПАЛИ. Хватит пытаться запускать команды. Вот что делать: (1) Создавайте файлы напрямую через write_file вместо команд терминала. (2) Проверьте, установлены ли зависимости (npm install). (3) Используйте list_dir чтобы увидеть что есть в проекте. (4) Не пытайтесь запустить сборку/тесты пока не созданы все файлы.]",
3055
- "exec.task_reminder": "[ИСХОДНАЯ ЗАДАЧА: {task}. ВЫ ДОЛЖНЫ работать только над этой задачей. Не создавайте файлы для других задач. Если не можете выполнить объясните почему и запросите помощь.]",
3056
- "exec.plan_warning": '[⚠ ПЛАН: вы на шаге {step} — "{description}", но вызываете {tool} для файлов вне этого шага. Это ЗАПРЕЩЕНОработайте СТРОГО над текущим шагом. Сначала завершите его и вызовите plan update step={step} status=done, только потом переходите к следующему.]',
3057
- "exec.plan_blocked": "[⛔ ЗАБЛОКИРОВАНО: {max} вызова подряд вне текущего шага. Вы нарушаете план. Вернитесь к шагу {step} и завершите его. Другие шаги будут заблокированы пока текущий не выполнен.]",
3058
- "exec.off_track": '[⚠ ВНЕ ПЛАНА: шаг {stepId} — "{description}", но вы используете {tool} для другого пути. Вернитесь к текущему шагу немедленно.]',
3053
+ "exec.stuck": "Нет прогресса на шаге {stepId} ({description}) {iterations} итераций.",
3054
+ "exec.stuck_recovery": 'Шаг {stepId} — "{description}" без прогресса уже {iterations} итераций. Попробуйте другой подход: проверьте что нужно для этого шага, установлены ли зависимости, или создайте файлы напрямую через write_file вместо команд терминала. После завершения шага вызовите plan update step={stepId} status=done.',
3055
+ "exec.tool_errors": "Инструмент {tool} упал {count} раз. Попробуйте другой инструмент.",
3056
+ "exec.tool_errors_recovery": "Инструмент {tool} упал {count} раз подряд. Попробуйте альтернативу: создайте файлы напрямую через write_file, используйте другую команду, или пропустите этот шаг через plan update step=N status=skipped с пометкой почему.",
3057
+ "exec.repetitive_tool": "Инструмент {tool} вызван {count} раз с одинаковыми аргументами и результатом. Попробуйте другой подход создайте файлы напрямую, измените аргументы или проверьте статус процесса через process_log.",
3058
+ "exec.consecutive_failures_recovery": "{count} инструментов подряд упали. Создавайте файлы напрямую через write_file вместо команд терминала. Проверьте что зависимости установлены (npm install). Не запускайте сборку/тесты пока не созданы все файлы.",
3059
+ "exec.plan_warning": 'Текущий шаг плана {step} "{description}", но вызывается {tool} для файлов вне этого шага. Завершите текущий шаг, вызовите plan update step={step} status=done, затем переходите к следующему.',
3060
+ "exec.plan_blocked": "{max} вызовов подряд вне текущего шага. Завершите шаг {step} остальные шаги ждут пока этот не будет выполнен.",
3061
+ "exec.off_track": 'Шаг {stepId} "{description}", но используется {tool} для другого пути. Вернитесь к текущему шагу.',
3059
3062
  "exec.step_gate_deps": '[⚠ Шаг {step} "{description}": зависимости не установлены. Сначала выполните команду установки (npm install, pip install и т.д.). Проверьте что lock-файл или директория зависимостей существует.]',
3060
3063
  "exec.step_gate_empty": "[⚠ Шаг {step}: файлы существуют, но выглядят пустыми: {files}. Добавьте реальный код в эти файлы перед тем как переходить к следующему шагу.]",
3061
3064
  "exec.step_gate_ok": '[✓] Шаг {step} завершён и проверен. ПЕРЕХОДИМ к шагу {nextStep}: "{nextDesc}". Работайте ТОЛЬКО над этим шагом.',
@@ -4936,12 +4939,33 @@ function isPathInScope(baseDir, targetPath, scope, securityConfig) {
4936
4939
  const baseResolved = resolve(baseDir);
4937
4940
  const targetResolved = resolve(baseDir, normalize(targetPath));
4938
4941
  if (!targetResolved.startsWith(baseResolved)) {
4939
- return { allowed: false, reason: "Path is outside the base working directory" };
4942
+ return {
4943
+ allowed: false,
4944
+ reason: "Path is outside the base working directory"
4945
+ };
4946
+ }
4947
+ if (!securityConfig?.enabled) {
4948
+ if (scope) {
4949
+ const isReadScope = scope.read_only_files.some((f) => targetResolved.startsWith(resolve(baseDir, f)));
4950
+ const isWriteScope = scope.allowed_files.some((f) => targetResolved.startsWith(resolve(baseDir, f)));
4951
+ if (isWriteScope)
4952
+ return { allowed: true };
4953
+ if (isReadScope)
4954
+ return { allowed: true, reason: "Read-only file" };
4955
+ return {
4956
+ allowed: false,
4957
+ reason: "Path is not within the allowed scope for this sub-agent"
4958
+ };
4959
+ }
4960
+ return { allowed: true };
4940
4961
  }
4941
4962
  if (securityConfig?.denied?.length) {
4942
4963
  for (const pattern of securityConfig.denied) {
4943
4964
  if (matchesGlobPattern(targetResolved, baseDir, pattern)) {
4944
- return { allowed: false, reason: `Path matches denied pattern: ${pattern}` };
4965
+ return {
4966
+ allowed: false,
4967
+ reason: `Path matches denied pattern: ${pattern}`
4968
+ };
4945
4969
  }
4946
4970
  }
4947
4971
  }
@@ -4954,7 +4978,10 @@ function isPathInScope(baseDir, targetPath, scope, securityConfig) {
4954
4978
  }
4955
4979
  }
4956
4980
  if (!isAllowed) {
4957
- return { allowed: false, reason: "Path does not match any allowed pattern" };
4981
+ return {
4982
+ allowed: false,
4983
+ reason: "Path does not match any allowed pattern"
4984
+ };
4958
4985
  }
4959
4986
  }
4960
4987
  if (!scope) {
@@ -4975,12 +5002,30 @@ function isPathWritable(baseDir, targetPath, scope, securityConfig) {
4975
5002
  const baseResolved = resolve(baseDir);
4976
5003
  const targetResolved = resolve(baseDir, normalize(targetPath));
4977
5004
  if (!targetResolved.startsWith(baseResolved)) {
4978
- return { allowed: false, reason: "Path is outside the base working directory" };
5005
+ return {
5006
+ allowed: false,
5007
+ reason: "Path is outside the base working directory"
5008
+ };
5009
+ }
5010
+ if (!securityConfig?.enabled) {
5011
+ if (scope) {
5012
+ const isWriteScope = scope.allowed_files.some((f) => targetResolved.startsWith(resolve(baseDir, f)));
5013
+ if (isWriteScope)
5014
+ return { allowed: true };
5015
+ return {
5016
+ allowed: false,
5017
+ reason: "Path is not within the allowed scope for this sub-agent"
5018
+ };
5019
+ }
5020
+ return { allowed: true };
4979
5021
  }
4980
5022
  if (securityConfig?.denied?.length) {
4981
5023
  for (const pattern of securityConfig.denied) {
4982
5024
  if (matchesGlobPattern(targetResolved, baseDir, pattern)) {
4983
- return { allowed: false, reason: `Path matches denied pattern: ${pattern}` };
5025
+ return {
5026
+ allowed: false,
5027
+ reason: `Path matches denied pattern: ${pattern}`
5028
+ };
4984
5029
  }
4985
5030
  }
4986
5031
  }
@@ -4993,7 +5038,10 @@ function isPathWritable(baseDir, targetPath, scope, securityConfig) {
4993
5038
  }
4994
5039
  }
4995
5040
  if (!isAllowed) {
4996
- return { allowed: false, reason: "Path does not match any allowed pattern" };
5041
+ return {
5042
+ allowed: false,
5043
+ reason: "Path does not match any allowed pattern"
5044
+ };
4997
5045
  }
4998
5046
  }
4999
5047
  if (!scope) {
@@ -6417,9 +6465,15 @@ function containsOperator(command, op) {
6417
6465
  return new RegExp(escaped).test(command);
6418
6466
  }
6419
6467
  function isCommandAllowed(command, securityConfig) {
6420
- let config = securityConfig || DEFAULT_BASH_CONFIG;
6468
+ if (!securityConfig?.enabled) {
6469
+ return { allowed: true, sanitizedCommand: command };
6470
+ }
6471
+ let config = securityConfig;
6421
6472
  if (!config.blacklist || !Array.isArray(config.blacklist)) {
6422
- config = FALLBACK_BASH_CONFIG;
6473
+ config = {
6474
+ ...FALLBACK_BASH_CONFIG,
6475
+ enabled: config.enabled ?? FALLBACK_BASH_CONFIG.enabled
6476
+ };
6423
6477
  }
6424
6478
  const trimmedCommand = command.trim();
6425
6479
  if (!trimmedCommand) {
@@ -6508,7 +6562,21 @@ var FALLBACK_BASH_CONFIG, DEFAULT_BASH_CONFIG;
6508
6562
  var init_command_validator = __esm(() => {
6509
6563
  init_security();
6510
6564
  FALLBACK_BASH_CONFIG = {
6511
- blacklist: ["rm", "dd", "chmod", "wget", "curl", "scp", "ssh", "nc", "netcat", "powershell", "pwsh", "cmd"],
6565
+ enabled: false,
6566
+ blacklist: [
6567
+ "rm",
6568
+ "dd",
6569
+ "chmod",
6570
+ "wget",
6571
+ "curl",
6572
+ "scp",
6573
+ "ssh",
6574
+ "nc",
6575
+ "netcat",
6576
+ "powershell",
6577
+ "pwsh",
6578
+ "cmd"
6579
+ ],
6512
6580
  whitelist: [],
6513
6581
  blockDangerousFlags: false,
6514
6582
  dangerousFlags: ["--force", "-rf", "--no-preserve-root"],
@@ -9868,7 +9936,7 @@ Partial output: ${result.text}`
9868
9936
 
9869
9937
  // src/modules/security/network-validator.ts
9870
9938
  function isUrlAllowed(url, securityConfig) {
9871
- if (!securityConfig) {
9939
+ if (!securityConfig?.enabled) {
9872
9940
  return { allowed: true };
9873
9941
  }
9874
9942
  try {
@@ -12850,13 +12918,13 @@ class ExecutionModule {
12850
12918
  name: "plan",
12851
12919
  description: `Create, update, show, or abort a multi-step plan. Use "create" at the start of complex tasks. Use "update" after completing each step to track progress. Use "show" to re-print the current plan checklist.
12852
12920
 
12853
- IMPORTANT each step MUST be detailed and concrete (≥50 chars):
12921
+ Write CONCRETE steps with exact file paths and commands:
12854
12922
  - Specify WHICH files to create with exact paths (e.g. "create src/components/Header.tsx with navigation and logo")
12855
- - Specify WHICH packages to install with exact versions (e.g. "run npm install react@18.3 react-dom@18.3")
12923
+ - Specify WHICH packages to install (e.g. "run npm install react react-dom")
12856
12924
  - Specify WHICH CLI commands to run with exact arguments
12857
- - Must contain at least one file extension (.ts, .tsx, .json, etc.) OR a command verb (install, create, build, run, add, init)
12858
- - BAD: "Настройка проекта и установка зависимостей" (too vague, no files, no versions)
12859
- - GOOD: "Создать package.json с зависимостями react@18.3 и vite@5.4, затем выполнить npm install в корне проекта"`,
12925
+ - Each step should include at least one file extension (.ts, .tsx, .json, etc.) or a command verb (install, create, build, run, add, init)
12926
+ - Good: "Создать src/components/Header.tsx с навигацией и логотипом"
12927
+ - Bad: "Настройка проекта" (too vague what exactly needs to be configured?)`,
12860
12928
  parameters: {
12861
12929
  type: "object",
12862
12930
  properties: {
@@ -14611,21 +14679,20 @@ function buildSystemInfo(config, baseDir, profileCompressed) {
14611
14679
  `Date: ${now}`,
14612
14680
  `Workspace: ${baseDir}`,
14613
14681
  `${profileCompressed}`,
14614
- `Reply in the user's language. Use tools for filesystem, bash, web access.`,
14615
- `Use tools when needed. Explain briefly what you're doing if it's not obvious.`,
14616
- `Answer the user's question directly. Only take action when the user explicitly asks you to change, create, or fix something.`,
14617
- `If a tool call fails, report the error and ask the user how to proceed.`,
14682
+ `Reply in the user's language. Use tools for: read/write/edit/delete files, search (glob/grep), shell commands (bash), web access (web_search, web_fetch), subagents, browser, MCP.`,
14683
+ `Use tools when needed explain briefly what you're doing if it's not obvious.`,
14684
+ `If a tool call fails, analyze the error and correct the call try up to 2 times with different approaches before asking the user for help.`,
14618
14685
  ``,
14619
- `Design principles — apply them automatically without naming them:`,
14620
- `- Do not add code, files, or abstractions that are not needed right now (YAGNI — You Ain't Gonna Need It). If something is not required by the current task, omit it.`,
14621
- `- Prefer simple, straightforward solutions over clever or complex ones (KISS — Keep It Simple, Stupid). Flat code beats nested, minimal config beats flexible, explicit beats generic.`,
14622
- `- Do not duplicate code, logic, or configuration (DRY Don't Repeat Yourself). Extract shared logic into a single place, reuse existing utilities and patterns before writing new ones.`
14686
+ `Design principles:`,
14687
+ `- YAGNI: Do not add code, files, or abstractions not needed right now.`,
14688
+ `- KISS: Prefer simple, straightforward solutions over clever or complex ones.`,
14689
+ `- DRY: Do not duplicate code, logic, or configuration — reuse existing utilities and patterns.`
14623
14690
  ];
14624
14691
  if (isWin) {
14625
14692
  lines.push(``, `Windows environment — use Windows-compatible commands:`, `- Use "dir" instead of "ls". Use "dir /b" for bare listing.`, `- Use "type" or "Get-Content" instead of "cat".`, `- Use "cd" instead of "pwd". Use "echo %cd%" to print working directory.`, `- Use "copy" instead of "cp", "move" instead of "mv", "del" instead of "rm".`, `- Do not use "mkdir -p" — Windows mkdir creates intermediate dirs by default. Use the create_dir tool instead.`, `- Use forward slashes (/) or escaped backslashes (\\\\) in file paths.`, `- Your working directory is: ${baseDir}`);
14626
14693
  }
14627
- lines.push(``, `Bash tool rules:`, `- Use the "workdir" parameter to run commands in a specific directory. Do NOT chain "cd dir && cmd" — the security module blocks the "&&" operator.`, `- Run one command per tool call. Split multi-step shell operations into separate bash calls.`, `- Background processes (dev servers, watchers, long-running npm install): use the "background: true" parameter or the tool will auto-detect and background them. Check output with process_log.`);
14628
- lines.push(``, `=== DEVELOPMENT RULES — follow these strictly ===`, ``, `1. DEPENDENCIES FIRST: Before writing any source code, ALWAYS install project dependencies (e.g., "npm install", "pip install -r requirements.txt", "cargo build", "go mod tidy"). Verify the package manager's lock file or dependency directory exists. Never write code that imports/uses packages that aren't installed yet.`, `2. TOOLKIT/FWK FIRST: If the task specifies a framework or UI library, initialize and configure it BEFORE writing application code. Run its project init command first, then add components/modules. Never write your own version of what the framework already provides.`, `3. ONE STEP AT A TIME: Follow the plan sequentially. Complete step N before starting step N+1. When a step is done: verify the deliverables exist and have real content (not empty), then call "plan update step=N status=done". Do not redo completed work.`, `4. VERIFY YOUR WORK: After creating/modifying files, verify they exist on disk. After installing dependencies, verify the package manager completed successfully. After any command, check its output for errors. Don't assume operations succeeded.`, `5. NO PREMATURE WORK: Do not create files for future steps. Do not add imports/references to packages or modules that haven't been installed yet. Do not reference files or components that don't exist yet. Build incrementally — one layer at a time.`, `6. WHEN STUCK: If a command fails 2+ times, STOP and try a different approach. Write files directly instead of using commands. Ask the user for help. Never repeat the same failing command more than twice.`, ``, `=== PLAN QUALITY RULES — your plan MUST follow these ===`, ``, `- Each step must describe CONCRETE deliverables: exact filenames with paths, exact packages to install, exact CLI commands to run. Steps shorter than 50 characters or without file paths/commands are REJECTED.`, `- A step like "Настройка проекта" or "Setup the project" is USELESS and will be REJECTED.`, `- A step like "Создать src/components/Header.tsx с навигацией и логотипом, добавить в src/App.tsx импорт <Header />" is GOOD.`, `- Include file extensions (.tsx, .css, .json) and directory paths. Every step must mention at least one file or command.`, `- The plan must cover EVERYTHING needed: init → deps → framework setup → code → verification.`, `- Number of steps: 5-8 for a typical task. Too few means you're being vague. Too many means you're over-splitting.`);
14694
+ lines.push(``, `Bash tool rules:`, `- Use the "workdir" parameter to run commands in a specific directory. Prefer workdir over "cd dir && cmd" chaining.`, `- Run one command per tool call. Split multi-step shell operations into separate bash calls.`, `- Background processes (dev servers, watchers, long-running npm install): use the "background: true" parameter or the tool will auto-detect and background them. Check output with process_log.`);
14695
+ lines.push(``, `=== DEVELOPMENT RULES — follow these strictly ===`, ``, `1. DEPENDENCIES FIRST: Before writing any source code, ALWAYS install project dependencies (e.g., "npm install", "pip install -r requirements.txt", "cargo build", "go mod tidy"). Verify the package manager's lock file or dependency directory exists. Never write code that imports/uses packages that aren't installed yet.`, `2. TOOLKIT/FWK FIRST: If the task specifies a framework or UI library, initialize and configure it BEFORE writing application code. Run its project init command first, then add components/modules. Never write your own version of what the framework already provides.`, `3. ONE STEP AT A TIME: Follow the plan sequentially. Complete step N before starting step N+1. When a step is done: verify the deliverables exist and have real content (not empty), then call "plan update step=N status=done". Do not redo completed work.`, `4. VERIFY YOUR WORK: After creating/modifying files, verify they exist on disk. After installing dependencies, verify the package manager completed successfully. After any command, check its output for errors. Don't assume operations succeeded.`, `5. NO PREMATURE WORK: Do not create files for future steps. Do not add imports/references to packages or modules that haven't been installed yet. Do not reference files or components that don't exist yet. Build incrementally — one layer at a time.`, `6. WHEN STUCK: If a command fails 2+ times, STOP and try a different approach. Write files directly instead of using commands. Ask the user for help. Never repeat the same failing command more than twice.`, ``, `=== PLAN QUALITY RULES — your plan MUST follow these ===`, ``, `- Each step must describe CONCRETE deliverables: exact filenames with paths, exact packages to install, exact CLI commands to run. Avoid vague steps be specific.`, `- A step like "Настройка проекта" or "Setup the project" is too vague describe what exactly needs to be configured or set up.`, `- A step like "Создать src/components/Header.tsx с навигацией и логотипом, добавить в src/App.tsx импорт <Header />" is GOOD.`, `- Include file extensions (.tsx, .css, .json) and directory paths. Every step must mention at least one file or command.`, `- The plan must cover EVERYTHING needed: init → deps → framework setup → code → verification.`, `- Number of steps: 5-8 for a typical task. Too few means you're being vague. Too many means you're over-splitting.`);
14629
14696
  if (config.autoPlan) {
14630
14697
  lines.push(``, `Plan rule (MANDATORY): For ANY task that requires creating files, installing packages, or multiple actions — you MUST create a plan using the "plan" tool BEFORE starting work. Each step must describe a concrete deliverable (specific files to create, packages to install, commands to run). Do not combine unrelated work into one step.`);
14631
14698
  }
@@ -15686,7 +15753,9 @@ var STRICT_POLICY = {
15686
15753
  preset: "strict",
15687
15754
  recommendedFor: ["production", "sensitive-data", "multi-user", "enterprise"],
15688
15755
  config: {
15756
+ enabled: true,
15689
15757
  bash: {
15758
+ enabled: true,
15690
15759
  blacklist: [
15691
15760
  "rm",
15692
15761
  "dd",
@@ -15745,10 +15814,22 @@ var STRICT_POLICY = {
15745
15814
  "-R",
15746
15815
  "--no-clobber"
15747
15816
  ],
15748
- dangerousOperators: [">", ">>", "2>", "2>>", "|", "&&", "||", ";", "&", "`"],
15817
+ dangerousOperators: [
15818
+ ">",
15819
+ ">>",
15820
+ "2>",
15821
+ "2>>",
15822
+ "|",
15823
+ "&&",
15824
+ "||",
15825
+ ";",
15826
+ "&",
15827
+ "`"
15828
+ ],
15749
15829
  logCommands: true
15750
15830
  },
15751
15831
  paths: {
15832
+ enabled: true,
15752
15833
  denied: [
15753
15834
  ".git/",
15754
15835
  "node_modules/",
@@ -15781,6 +15862,7 @@ var STRICT_POLICY = {
15781
15862
  allowed: []
15782
15863
  },
15783
15864
  network: {
15865
+ enabled: true,
15784
15866
  deniedDomains: [
15785
15867
  "localhost",
15786
15868
  "127.0.0.1",
@@ -15852,7 +15934,9 @@ var BALANCED_POLICY = {
15852
15934
  preset: "balanced",
15853
15935
  recommendedFor: ["development", "single-user", "general-use", "testing"],
15854
15936
  config: {
15937
+ enabled: true,
15855
15938
  bash: {
15939
+ enabled: true,
15856
15940
  blacklist: [
15857
15941
  "rm",
15858
15942
  "dd",
@@ -15898,6 +15982,7 @@ var BALANCED_POLICY = {
15898
15982
  logCommands: true
15899
15983
  },
15900
15984
  paths: {
15985
+ enabled: true,
15901
15986
  denied: [
15902
15987
  ".git/",
15903
15988
  "node_modules/",
@@ -15918,6 +16003,7 @@ var BALANCED_POLICY = {
15918
16003
  allowed: []
15919
16004
  },
15920
16005
  network: {
16006
+ enabled: true,
15921
16007
  deniedDomains: [],
15922
16008
  allowedDomains: [],
15923
16009
  requestTimeout: 15000,
@@ -15953,7 +16039,12 @@ var BALANCED_POLICY = {
15953
16039
  auditNotifier: {
15954
16040
  enabled: false,
15955
16041
  minSeverity: "medium",
15956
- eventTypes: ["security_block", "bash_command", "file_operation", "network_request"],
16042
+ eventTypes: [
16043
+ "security_block",
16044
+ "bash_command",
16045
+ "file_operation",
16046
+ "network_request"
16047
+ ],
15957
16048
  maxRetries: 3
15958
16049
  }
15959
16050
  }
@@ -15964,7 +16055,9 @@ var PERMISSIVE_POLICY = {
15964
16055
  preset: "permissive",
15965
16056
  recommendedFor: ["trusted-environment", "local-dev", "testing", "sandbox"],
15966
16057
  config: {
16058
+ enabled: true,
15967
16059
  bash: {
16060
+ enabled: true,
15968
16061
  blacklist: [
15969
16062
  "rm",
15970
16063
  "dd",
@@ -15984,10 +16077,12 @@ var PERMISSIVE_POLICY = {
15984
16077
  logCommands: true
15985
16078
  },
15986
16079
  paths: {
16080
+ enabled: true,
15987
16081
  denied: [".env", "*.key", "*.pem", "*.crt", "*.p12", "*.pfx"],
15988
16082
  allowed: []
15989
16083
  },
15990
16084
  network: {
16085
+ enabled: true,
15991
16086
  deniedDomains: [],
15992
16087
  allowedDomains: [],
15993
16088
  requestTimeout: 30000,
@@ -16292,6 +16387,37 @@ function createProgram() {
16292
16387
  config.contextWindow = answers.contextWindow;
16293
16388
  config.maxToolIterations = answers.maxToolIterations;
16294
16389
  config.locale = answers.locale;
16390
+ if (config.security) {
16391
+ config.security.enabled = answers.securityBashBlock || answers.securityFlagsBlock || !answers.securityPathsDeny;
16392
+ config.security.bash.enabled = config.security.enabled;
16393
+ config.security.bash.blockDangerousFlags = answers.securityFlagsBlock;
16394
+ if (answers.securityBashBlock) {
16395
+ config.security.bash.blacklist = [
16396
+ ...new Set([
16397
+ ...config.security.bash.blacklist,
16398
+ "rm",
16399
+ "dd",
16400
+ "chmod",
16401
+ "wget",
16402
+ "curl",
16403
+ "scp",
16404
+ "ssh",
16405
+ "nc",
16406
+ "netcat",
16407
+ "sudo",
16408
+ "su",
16409
+ "kill",
16410
+ "pkill",
16411
+ "killall",
16412
+ "shutdown",
16413
+ "reboot"
16414
+ ])
16415
+ ];
16416
+ }
16417
+ if (!answers.securityPathsDeny) {
16418
+ config.security.paths.denied = [];
16419
+ }
16420
+ }
16295
16421
  saveConfig(config, configPath);
16296
16422
  console.log(t("cli.config_saved"));
16297
16423
  });
@@ -17923,6 +18049,8 @@ async function main() {
17923
18049
  config2.maxToolIterations = answers.maxToolIterations;
17924
18050
  config2.locale = answers.locale;
17925
18051
  if (config2.security) {
18052
+ config2.security.enabled = answers.securityBashBlock || answers.securityFlagsBlock || !answers.securityPathsDeny;
18053
+ config2.security.bash.enabled = config2.security.enabled;
17926
18054
  config2.security.bash.blockDangerousFlags = answers.securityFlagsBlock;
17927
18055
  if (answers.securityBashBlock) {
17928
18056
  config2.security.bash.blacklist = [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "micro-models-agent",
3
- "version": "0.21.1",
3
+ "version": "0.22.0",
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": {