micro-models-agent 0.21.0 → 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.
- package/dist/main.js +176 -70
- 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,
|
|
@@ -2304,7 +2309,6 @@ Command: {command}`,
|
|
|
2304
2309
|
"tool.friendly.process_log": "Process output",
|
|
2305
2310
|
"tool.friendly.process_kill": "Stopping process",
|
|
2306
2311
|
"plan.no_steps": "No plan steps specified. Provide concrete steps with files and commands.",
|
|
2307
|
-
"plan.bad_steps": "Plan step quality unacceptable. Each step must describe concrete deliverables (files, packages, commands). Minimum 20 chars per step. Errors: {errors}",
|
|
2308
2312
|
"plan.created": "Plan created: {title} ({steps} steps)",
|
|
2309
2313
|
"plan.step_done": "Step {n}/{total}: {description} ✓",
|
|
2310
2314
|
"plan.complete": "Task complete: {summary}",
|
|
@@ -2549,16 +2553,15 @@ Available commands:`,
|
|
|
2549
2553
|
{content}
|
|
2550
2554
|
|
|
2551
2555
|
Use this knowledge to answer the user's question.`,
|
|
2552
|
-
"exec.stuck": "
|
|
2553
|
-
"exec.stuck_recovery": '
|
|
2554
|
-
"exec.tool_errors": "Tool {tool} failed {count} times.
|
|
2555
|
-
"exec.tool_errors_recovery": "
|
|
2556
|
-
"exec.repetitive_tool": "
|
|
2557
|
-
"exec.consecutive_failures_recovery": "
|
|
2558
|
-
"exec.
|
|
2559
|
-
"exec.
|
|
2560
|
-
"exec.
|
|
2561
|
-
"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.',
|
|
2562
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.]',
|
|
2563
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.]",
|
|
2564
2567
|
"exec.step_gate_ok": '[✓] Step {step} completed and verified. MOVING to step {nextStep}: "{nextDesc}". Work ONLY on this step.',
|
|
@@ -2803,7 +2806,6 @@ var init_ru = __esm(() => {
|
|
|
2803
2806
|
"tool.friendly.process_log": "Вывод процесса",
|
|
2804
2807
|
"tool.friendly.process_kill": "Остановка процесса",
|
|
2805
2808
|
"plan.no_steps": "Не указаны шаги плана. Укажите конкретные шаги с файлами и командами.",
|
|
2806
|
-
"plan.bad_steps": "Качество шагов плана неприемлемо. Каждый шаг должен описывать конкретные deliverables (файлы, пакеты, команды). Минимум 20 символов на шаг. Ошибки: {errors}",
|
|
2807
2809
|
"plan.created": "План создан: {title} ({steps} шагов)",
|
|
2808
2810
|
"plan.step_done": "Шаг {n}/{total}: {description} ✓",
|
|
2809
2811
|
"plan.complete": "Задача выполнена: {summary}",
|
|
@@ -3048,16 +3050,15 @@ var init_ru = __esm(() => {
|
|
|
3048
3050
|
{content}
|
|
3049
3051
|
|
|
3050
3052
|
Используйте эти знания для ответа на вопрос пользователя.`,
|
|
3051
|
-
"exec.stuck": "
|
|
3052
|
-
"exec.stuck_recovery": '
|
|
3053
|
-
"exec.tool_errors": "Инструмент {tool}
|
|
3054
|
-
"exec.tool_errors_recovery": "
|
|
3055
|
-
"exec.repetitive_tool": "
|
|
3056
|
-
"exec.consecutive_failures_recovery": "
|
|
3057
|
-
"exec.
|
|
3058
|
-
"exec.
|
|
3059
|
-
"exec.
|
|
3060
|
-
"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} для другого пути. Вернитесь к текущему шагу.',
|
|
3061
3062
|
"exec.step_gate_deps": '[⚠ Шаг {step} "{description}": зависимости не установлены. Сначала выполните команду установки (npm install, pip install и т.д.). Проверьте что lock-файл или директория зависимостей существует.]',
|
|
3062
3063
|
"exec.step_gate_empty": "[⚠ Шаг {step}: файлы существуют, но выглядят пустыми: {files}. Добавьте реальный код в эти файлы перед тем как переходить к следующему шагу.]",
|
|
3063
3064
|
"exec.step_gate_ok": '[✓] Шаг {step} завершён и проверен. ПЕРЕХОДИМ к шагу {nextStep}: "{nextDesc}". Работайте ТОЛЬКО над этим шагом.',
|
|
@@ -4938,12 +4939,33 @@ function isPathInScope(baseDir, targetPath, scope, securityConfig) {
|
|
|
4938
4939
|
const baseResolved = resolve(baseDir);
|
|
4939
4940
|
const targetResolved = resolve(baseDir, normalize(targetPath));
|
|
4940
4941
|
if (!targetResolved.startsWith(baseResolved)) {
|
|
4941
|
-
return {
|
|
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 };
|
|
4942
4961
|
}
|
|
4943
4962
|
if (securityConfig?.denied?.length) {
|
|
4944
4963
|
for (const pattern of securityConfig.denied) {
|
|
4945
4964
|
if (matchesGlobPattern(targetResolved, baseDir, pattern)) {
|
|
4946
|
-
return {
|
|
4965
|
+
return {
|
|
4966
|
+
allowed: false,
|
|
4967
|
+
reason: `Path matches denied pattern: ${pattern}`
|
|
4968
|
+
};
|
|
4947
4969
|
}
|
|
4948
4970
|
}
|
|
4949
4971
|
}
|
|
@@ -4956,7 +4978,10 @@ function isPathInScope(baseDir, targetPath, scope, securityConfig) {
|
|
|
4956
4978
|
}
|
|
4957
4979
|
}
|
|
4958
4980
|
if (!isAllowed) {
|
|
4959
|
-
return {
|
|
4981
|
+
return {
|
|
4982
|
+
allowed: false,
|
|
4983
|
+
reason: "Path does not match any allowed pattern"
|
|
4984
|
+
};
|
|
4960
4985
|
}
|
|
4961
4986
|
}
|
|
4962
4987
|
if (!scope) {
|
|
@@ -4977,12 +5002,30 @@ function isPathWritable(baseDir, targetPath, scope, securityConfig) {
|
|
|
4977
5002
|
const baseResolved = resolve(baseDir);
|
|
4978
5003
|
const targetResolved = resolve(baseDir, normalize(targetPath));
|
|
4979
5004
|
if (!targetResolved.startsWith(baseResolved)) {
|
|
4980
|
-
return {
|
|
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 };
|
|
4981
5021
|
}
|
|
4982
5022
|
if (securityConfig?.denied?.length) {
|
|
4983
5023
|
for (const pattern of securityConfig.denied) {
|
|
4984
5024
|
if (matchesGlobPattern(targetResolved, baseDir, pattern)) {
|
|
4985
|
-
return {
|
|
5025
|
+
return {
|
|
5026
|
+
allowed: false,
|
|
5027
|
+
reason: `Path matches denied pattern: ${pattern}`
|
|
5028
|
+
};
|
|
4986
5029
|
}
|
|
4987
5030
|
}
|
|
4988
5031
|
}
|
|
@@ -4995,7 +5038,10 @@ function isPathWritable(baseDir, targetPath, scope, securityConfig) {
|
|
|
4995
5038
|
}
|
|
4996
5039
|
}
|
|
4997
5040
|
if (!isAllowed) {
|
|
4998
|
-
return {
|
|
5041
|
+
return {
|
|
5042
|
+
allowed: false,
|
|
5043
|
+
reason: "Path does not match any allowed pattern"
|
|
5044
|
+
};
|
|
4999
5045
|
}
|
|
5000
5046
|
}
|
|
5001
5047
|
if (!scope) {
|
|
@@ -6419,9 +6465,15 @@ function containsOperator(command, op) {
|
|
|
6419
6465
|
return new RegExp(escaped).test(command);
|
|
6420
6466
|
}
|
|
6421
6467
|
function isCommandAllowed(command, securityConfig) {
|
|
6422
|
-
|
|
6468
|
+
if (!securityConfig?.enabled) {
|
|
6469
|
+
return { allowed: true, sanitizedCommand: command };
|
|
6470
|
+
}
|
|
6471
|
+
let config = securityConfig;
|
|
6423
6472
|
if (!config.blacklist || !Array.isArray(config.blacklist)) {
|
|
6424
|
-
config =
|
|
6473
|
+
config = {
|
|
6474
|
+
...FALLBACK_BASH_CONFIG,
|
|
6475
|
+
enabled: config.enabled ?? FALLBACK_BASH_CONFIG.enabled
|
|
6476
|
+
};
|
|
6425
6477
|
}
|
|
6426
6478
|
const trimmedCommand = command.trim();
|
|
6427
6479
|
if (!trimmedCommand) {
|
|
@@ -6510,7 +6562,21 @@ var FALLBACK_BASH_CONFIG, DEFAULT_BASH_CONFIG;
|
|
|
6510
6562
|
var init_command_validator = __esm(() => {
|
|
6511
6563
|
init_security();
|
|
6512
6564
|
FALLBACK_BASH_CONFIG = {
|
|
6513
|
-
|
|
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
|
+
],
|
|
6514
6580
|
whitelist: [],
|
|
6515
6581
|
blockDangerousFlags: false,
|
|
6516
6582
|
dangerousFlags: ["--force", "-rf", "--no-preserve-root"],
|
|
@@ -9870,7 +9936,7 @@ Partial output: ${result.text}`
|
|
|
9870
9936
|
|
|
9871
9937
|
// src/modules/security/network-validator.ts
|
|
9872
9938
|
function isUrlAllowed(url, securityConfig) {
|
|
9873
|
-
if (!securityConfig) {
|
|
9939
|
+
if (!securityConfig?.enabled) {
|
|
9874
9940
|
return { allowed: true };
|
|
9875
9941
|
}
|
|
9876
9942
|
try {
|
|
@@ -12428,16 +12494,6 @@ class PlanCreator {
|
|
|
12428
12494
|
baseDir
|
|
12429
12495
|
};
|
|
12430
12496
|
}
|
|
12431
|
-
static validateSteps(steps) {
|
|
12432
|
-
const errors = [];
|
|
12433
|
-
for (let i = 0;i < steps.length; i++) {
|
|
12434
|
-
const s = steps[i].trim();
|
|
12435
|
-
if (s.length < MIN_STEP_DESC_LENGTH) {
|
|
12436
|
-
errors.push(`Step ${i + 1} too short (${s.length} chars). Describe WHAT files to create, WHICH packages to install, WHICH commands to run. Minimum ${MIN_STEP_DESC_LENGTH} chars.`);
|
|
12437
|
-
}
|
|
12438
|
-
}
|
|
12439
|
-
return { valid: errors.length === 0, errors };
|
|
12440
|
-
}
|
|
12441
12497
|
static toPromptBlock(plan, currentStepIndex) {
|
|
12442
12498
|
const date = plan.createdAt.slice(0, 10);
|
|
12443
12499
|
const lines = [
|
|
@@ -12455,7 +12511,6 @@ class PlanCreator {
|
|
|
12455
12511
|
`);
|
|
12456
12512
|
}
|
|
12457
12513
|
}
|
|
12458
|
-
var MIN_STEP_DESC_LENGTH = 20;
|
|
12459
12514
|
|
|
12460
12515
|
// src/modules/execution/tracker.ts
|
|
12461
12516
|
class PlanTracker {
|
|
@@ -12863,13 +12918,13 @@ class ExecutionModule {
|
|
|
12863
12918
|
name: "plan",
|
|
12864
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.
|
|
12865
12920
|
|
|
12866
|
-
|
|
12867
|
-
- Specify WHICH files to create
|
|
12921
|
+
Write CONCRETE steps with exact file paths and commands:
|
|
12922
|
+
- Specify WHICH files to create with exact paths (e.g. "create src/components/Header.tsx with navigation and logo")
|
|
12868
12923
|
- Specify WHICH packages to install (e.g. "run npm install react react-dom")
|
|
12869
|
-
- Specify WHICH commands to run with exact arguments
|
|
12870
|
-
-
|
|
12871
|
-
-
|
|
12872
|
-
-
|
|
12924
|
+
- Specify WHICH CLI commands to run with exact arguments
|
|
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?)`,
|
|
12873
12928
|
parameters: {
|
|
12874
12929
|
type: "object",
|
|
12875
12930
|
properties: {
|
|
@@ -12893,15 +12948,6 @@ IMPORTANT — each step MUST be detailed and concrete:
|
|
|
12893
12948
|
if (steps.length === 0) {
|
|
12894
12949
|
return { success: false, output: t("plan.no_steps") };
|
|
12895
12950
|
}
|
|
12896
|
-
const validation = PlanCreator.validateSteps(steps);
|
|
12897
|
-
if (!validation.valid) {
|
|
12898
|
-
return {
|
|
12899
|
-
success: false,
|
|
12900
|
-
output: t("plan.bad_steps", {
|
|
12901
|
-
errors: validation.errors.join("; ")
|
|
12902
|
-
})
|
|
12903
|
-
};
|
|
12904
|
-
}
|
|
12905
12951
|
const plan = PlanCreator.createPlan(title, steps, this.baseDir);
|
|
12906
12952
|
this.setPlan(plan);
|
|
12907
12953
|
const display = PlanCreator.toPromptBlock(plan, 0);
|
|
@@ -14633,21 +14679,20 @@ function buildSystemInfo(config, baseDir, profileCompressed) {
|
|
|
14633
14679
|
`Date: ${now}`,
|
|
14634
14680
|
`Workspace: ${baseDir}`,
|
|
14635
14681
|
`${profileCompressed}`,
|
|
14636
|
-
`Reply in the user's language. Use tools for
|
|
14637
|
-
`Use tools when needed
|
|
14638
|
-
`
|
|
14639
|
-
`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.`,
|
|
14640
14685
|
``,
|
|
14641
|
-
`Design principles
|
|
14642
|
-
`- Do not add code, files, or abstractions
|
|
14643
|
-
`- Prefer simple, straightforward solutions over clever or complex ones
|
|
14644
|
-
`- Do not duplicate code, logic, or configuration
|
|
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.`
|
|
14645
14690
|
];
|
|
14646
14691
|
if (isWin) {
|
|
14647
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}`);
|
|
14648
14693
|
}
|
|
14649
|
-
lines.push(``, `Bash tool rules:`, `- Use the "workdir" parameter to run commands in a specific directory.
|
|
14650
|
-
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.`, `- A step like "Настройка проекта" or "Setup the project" is
|
|
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.`);
|
|
14651
14696
|
if (config.autoPlan) {
|
|
14652
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.`);
|
|
14653
14698
|
}
|
|
@@ -15708,7 +15753,9 @@ var STRICT_POLICY = {
|
|
|
15708
15753
|
preset: "strict",
|
|
15709
15754
|
recommendedFor: ["production", "sensitive-data", "multi-user", "enterprise"],
|
|
15710
15755
|
config: {
|
|
15756
|
+
enabled: true,
|
|
15711
15757
|
bash: {
|
|
15758
|
+
enabled: true,
|
|
15712
15759
|
blacklist: [
|
|
15713
15760
|
"rm",
|
|
15714
15761
|
"dd",
|
|
@@ -15767,10 +15814,22 @@ var STRICT_POLICY = {
|
|
|
15767
15814
|
"-R",
|
|
15768
15815
|
"--no-clobber"
|
|
15769
15816
|
],
|
|
15770
|
-
dangerousOperators: [
|
|
15817
|
+
dangerousOperators: [
|
|
15818
|
+
">",
|
|
15819
|
+
">>",
|
|
15820
|
+
"2>",
|
|
15821
|
+
"2>>",
|
|
15822
|
+
"|",
|
|
15823
|
+
"&&",
|
|
15824
|
+
"||",
|
|
15825
|
+
";",
|
|
15826
|
+
"&",
|
|
15827
|
+
"`"
|
|
15828
|
+
],
|
|
15771
15829
|
logCommands: true
|
|
15772
15830
|
},
|
|
15773
15831
|
paths: {
|
|
15832
|
+
enabled: true,
|
|
15774
15833
|
denied: [
|
|
15775
15834
|
".git/",
|
|
15776
15835
|
"node_modules/",
|
|
@@ -15803,6 +15862,7 @@ var STRICT_POLICY = {
|
|
|
15803
15862
|
allowed: []
|
|
15804
15863
|
},
|
|
15805
15864
|
network: {
|
|
15865
|
+
enabled: true,
|
|
15806
15866
|
deniedDomains: [
|
|
15807
15867
|
"localhost",
|
|
15808
15868
|
"127.0.0.1",
|
|
@@ -15874,7 +15934,9 @@ var BALANCED_POLICY = {
|
|
|
15874
15934
|
preset: "balanced",
|
|
15875
15935
|
recommendedFor: ["development", "single-user", "general-use", "testing"],
|
|
15876
15936
|
config: {
|
|
15937
|
+
enabled: true,
|
|
15877
15938
|
bash: {
|
|
15939
|
+
enabled: true,
|
|
15878
15940
|
blacklist: [
|
|
15879
15941
|
"rm",
|
|
15880
15942
|
"dd",
|
|
@@ -15920,6 +15982,7 @@ var BALANCED_POLICY = {
|
|
|
15920
15982
|
logCommands: true
|
|
15921
15983
|
},
|
|
15922
15984
|
paths: {
|
|
15985
|
+
enabled: true,
|
|
15923
15986
|
denied: [
|
|
15924
15987
|
".git/",
|
|
15925
15988
|
"node_modules/",
|
|
@@ -15940,6 +16003,7 @@ var BALANCED_POLICY = {
|
|
|
15940
16003
|
allowed: []
|
|
15941
16004
|
},
|
|
15942
16005
|
network: {
|
|
16006
|
+
enabled: true,
|
|
15943
16007
|
deniedDomains: [],
|
|
15944
16008
|
allowedDomains: [],
|
|
15945
16009
|
requestTimeout: 15000,
|
|
@@ -15975,7 +16039,12 @@ var BALANCED_POLICY = {
|
|
|
15975
16039
|
auditNotifier: {
|
|
15976
16040
|
enabled: false,
|
|
15977
16041
|
minSeverity: "medium",
|
|
15978
|
-
eventTypes: [
|
|
16042
|
+
eventTypes: [
|
|
16043
|
+
"security_block",
|
|
16044
|
+
"bash_command",
|
|
16045
|
+
"file_operation",
|
|
16046
|
+
"network_request"
|
|
16047
|
+
],
|
|
15979
16048
|
maxRetries: 3
|
|
15980
16049
|
}
|
|
15981
16050
|
}
|
|
@@ -15986,7 +16055,9 @@ var PERMISSIVE_POLICY = {
|
|
|
15986
16055
|
preset: "permissive",
|
|
15987
16056
|
recommendedFor: ["trusted-environment", "local-dev", "testing", "sandbox"],
|
|
15988
16057
|
config: {
|
|
16058
|
+
enabled: true,
|
|
15989
16059
|
bash: {
|
|
16060
|
+
enabled: true,
|
|
15990
16061
|
blacklist: [
|
|
15991
16062
|
"rm",
|
|
15992
16063
|
"dd",
|
|
@@ -16006,10 +16077,12 @@ var PERMISSIVE_POLICY = {
|
|
|
16006
16077
|
logCommands: true
|
|
16007
16078
|
},
|
|
16008
16079
|
paths: {
|
|
16080
|
+
enabled: true,
|
|
16009
16081
|
denied: [".env", "*.key", "*.pem", "*.crt", "*.p12", "*.pfx"],
|
|
16010
16082
|
allowed: []
|
|
16011
16083
|
},
|
|
16012
16084
|
network: {
|
|
16085
|
+
enabled: true,
|
|
16013
16086
|
deniedDomains: [],
|
|
16014
16087
|
allowedDomains: [],
|
|
16015
16088
|
requestTimeout: 30000,
|
|
@@ -16314,6 +16387,37 @@ function createProgram() {
|
|
|
16314
16387
|
config.contextWindow = answers.contextWindow;
|
|
16315
16388
|
config.maxToolIterations = answers.maxToolIterations;
|
|
16316
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
|
+
}
|
|
16317
16421
|
saveConfig(config, configPath);
|
|
16318
16422
|
console.log(t("cli.config_saved"));
|
|
16319
16423
|
});
|
|
@@ -17945,6 +18049,8 @@ async function main() {
|
|
|
17945
18049
|
config2.maxToolIterations = answers.maxToolIterations;
|
|
17946
18050
|
config2.locale = answers.locale;
|
|
17947
18051
|
if (config2.security) {
|
|
18052
|
+
config2.security.enabled = answers.securityBashBlock || answers.securityFlagsBlock || !answers.securityPathsDeny;
|
|
18053
|
+
config2.security.bash.enabled = config2.security.enabled;
|
|
17948
18054
|
config2.security.bash.blockDangerousFlags = answers.securityFlagsBlock;
|
|
17949
18055
|
if (answers.securityBashBlock) {
|
|
17950
18056
|
config2.security.bash.blacklist = [
|