micro-models-agent 2.11.0 → 2.12.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/CHANGELOG.md +10 -0
- package/dist/assets/js/tabs.js +22 -3
- package/dist/cli/cache-line.js +1 -0
- package/dist/cli/command-suggest.js +5 -4
- package/dist/cli/commands.js +231 -122
- package/dist/cli/completer.js +132 -31
- package/dist/cli/index.js +1 -0
- package/dist/cli/json-payload.js +4 -4
- package/dist/cli/main.js +166 -61
- package/dist/cli/onboarding-commands.js +126 -0
- package/dist/cli/plugin-commands.js +2 -1
- package/dist/cli/relaunch.js +16 -13
- package/dist/cli/repl-commands-lsp.js +75 -0
- package/dist/cli/repl-commands-skills.js +105 -0
- package/dist/cli/repl-commands.js +589 -266
- package/dist/cli/repl.js +436 -177
- package/dist/cli/run-result.js +5 -6
- package/dist/cli/security-commands.js +37 -28
- package/dist/cli/setup-order.js +4 -55
- package/dist/cli/setup-prompt.js +3 -2
- package/dist/cli/setup.js +27 -107
- package/dist/cli/web-command.js +98 -0
- package/dist/config/budget.js +5 -5
- package/dist/config/config.js +103 -96
- package/dist/config/defaults.js +38 -8
- package/dist/config/domains.js +24 -27
- package/dist/config/env.js +46 -0
- package/dist/config/experts.js +2 -0
- package/dist/config/index.js +1 -0
- package/dist/config/paths.js +56 -0
- package/dist/config/redact.js +44 -0
- package/dist/config/registry-extra.js +334 -0
- package/dist/config/registry.js +584 -0
- package/dist/config/security.js +35 -36
- package/dist/config/timeouts.js +74 -0
- package/dist/config/utils.js +16 -15
- package/dist/core/agent/artifact-progress.js +59 -0
- package/dist/core/agent/artifact-resolve.js +79 -0
- package/dist/core/agent/audit-gate.js +7 -3
- package/dist/core/agent/compaction.js +2 -2
- package/dist/core/agent/constants.js +33 -4
- package/dist/core/agent/context-log.js +454 -0
- package/dist/core/agent/context-renderer.js +5 -0
- package/dist/core/agent/critic-gate.js +132 -0
- package/dist/core/agent/hallucination-gate.js +148 -38
- package/dist/core/agent/loop-state.js +15 -0
- package/dist/core/agent/prefix-monitor.js +1 -1
- package/dist/core/agent/reasoning-resolver.js +10 -1
- package/dist/core/agent/token-tracker.js +7 -4
- package/dist/core/agent/tool-batch.js +93 -18
- package/dist/core/agent/tool-images.js +18 -0
- package/dist/core/agent/tool-output.js +65 -11
- package/dist/core/agent/tool-pairing.js +60 -0
- package/dist/core/agent-moe.js +25 -24
- package/dist/core/agent.js +429 -108
- package/dist/core/bootstrap/agent-phase.js +66 -0
- package/dist/core/bootstrap/config-phase.js +86 -0
- package/dist/core/bootstrap/modules-phase.js +269 -0
- package/dist/core/bootstrap/provider-phase.js +183 -0
- package/dist/core/bootstrap/session-phase.js +204 -0
- package/dist/core/bootstrap/state.js +94 -0
- package/dist/core/bootstrap/workspace-phase.js +115 -0
- package/dist/core/bootstrap.js +92 -660
- package/dist/core/crash-handler.js +17 -7
- package/dist/core/environment.js +37 -12
- package/dist/core/host-plan.js +43 -0
- package/dist/core/host.js +23 -0
- package/dist/core/index.js +1 -0
- package/dist/core/prompt-builder.js +17 -1
- package/dist/core/prompt-overflow.js +42 -43
- package/dist/core/session-logger.js +122 -30
- package/dist/core/system-prompt.js +117 -0
- package/dist/core/version.js +6 -4
- package/dist/core/web-host.js +34 -0
- package/dist/core/workspace.js +19 -15
- package/dist/i18n/index.js +37 -3
- package/dist/index.js +7 -3
- package/dist/llm/image-utils.js +55 -64
- package/dist/llm/llm-errors.js +9 -0
- package/dist/llm/model-loader.js +10 -32
- package/dist/llm/models-dev.js +121 -0
- package/dist/llm/openai-compat.js +146 -73
- package/dist/llm/orchestrator.js +33 -11
- package/dist/llm/provider-budget.js +2 -2
- package/dist/llm/provider-context.js +233 -0
- package/dist/llm/provider.js +1 -1
- package/dist/llm/response.js +5 -0
- package/dist/llm/token-counter.js +27 -11
- package/dist/logger/app-logger.js +48 -22
- package/dist/logger/file-log.js +28 -19
- package/dist/logger/index.js +1 -0
- package/dist/main.js +273 -47
- package/dist/migration/backup.js +14 -3
- package/dist/migration/detect.js +12 -3
- package/dist/migration/index.js +1 -0
- package/dist/modules/artifacts/store.js +9 -8
- package/dist/modules/browser/actions.js +6 -0
- package/dist/modules/browser/bridge-client.js +14 -12
- package/dist/modules/browser/bridge-path.js +4 -4
- package/dist/modules/browser/console-buffer.js +37 -0
- package/dist/modules/browser/cookie-store.js +5 -0
- package/dist/modules/browser/driver-types.js +1 -0
- package/dist/modules/browser/driver.js +19 -11
- package/dist/modules/browser/index.js +3 -1
- package/dist/modules/browser/module.js +2 -1
- package/dist/modules/browser/session.js +10 -30
- package/dist/modules/browser/snapshot.js +19 -13
- package/dist/modules/browser/types.js +1 -0
- package/dist/modules/certification/cli.js +28 -20
- package/dist/modules/certification/fact-checker.js +9 -1
- package/dist/modules/certification/loader.js +9 -2
- package/dist/modules/certification/manifest.js +83 -21
- package/dist/modules/certification/runner.js +23 -13
- package/dist/modules/certification/scenarios.js +20 -20
- package/dist/modules/certification/syntax-scenarios.js +1 -2
- package/dist/modules/context/chunk-query.js +11 -9
- package/dist/modules/context/fact-extractor.js +37 -39
- package/dist/modules/context/index.js +1 -0
- package/dist/modules/context/manager.js +106 -80
- package/dist/modules/critic/client.js +176 -0
- package/dist/modules/critic/evidence.js +81 -0
- package/dist/modules/critic/provider.js +45 -0
- package/dist/modules/critic/tools.js +78 -0
- package/dist/modules/critic/types.js +1 -0
- package/dist/modules/execution/audit-runners.js +28 -34
- package/dist/modules/execution/auditor.js +53 -49
- package/dist/modules/execution/execution-plugin.js +142 -102
- package/dist/modules/execution/index.js +1 -1
- package/dist/modules/execution/input-from.js +37 -13
- package/dist/modules/execution/module.js +368 -191
- package/dist/modules/execution/moe-executor.js +53 -26
- package/dist/modules/execution/plan-actions.js +320 -202
- package/dist/modules/execution/plan-checks.js +35 -0
- package/dist/modules/execution/plan-coverage.js +36 -33
- package/dist/modules/execution/plan-steps.js +11 -3
- package/dist/modules/execution/plan-store.js +83 -17
- package/dist/modules/execution/plan-tool.js +89 -35
- package/dist/modules/execution/plan-validator.js +30 -10
- package/dist/modules/execution/planner.js +22 -13
- package/dist/modules/execution/stuck-detector.js +196 -93
- package/dist/modules/execution/tracker.js +22 -8
- package/dist/modules/execution/verifier.js +69 -48
- package/dist/modules/execution/windows-commands.js +12 -12
- package/dist/modules/hallucination/artifact-claim.js +93 -0
- package/dist/modules/hallucination/confidence.js +13 -11
- package/dist/modules/hallucination/consistency.js +10 -2
- package/dist/modules/hallucination/detector.js +10 -5
- package/dist/modules/hallucination/factual.js +43 -26
- package/dist/modules/hallucination/index.js +1 -0
- package/dist/modules/hallucination/js-identifiers.js +44 -45
- package/dist/modules/hallucination/llm-judge.js +17 -12
- package/dist/modules/hallucination/success-claim.js +59 -0
- package/dist/modules/indexer/cache.js +52 -4
- package/dist/modules/indexer/index.js +1 -0
- package/dist/modules/indexer/map-command.js +2 -4
- package/dist/modules/indexer/map-select.js +16 -16
- package/dist/modules/indexer/module.js +47 -12
- package/dist/modules/indexer/project-profile.js +8 -7
- package/dist/modules/indexer/symbols.js +15 -15
- package/dist/modules/indexer/walker.js +159 -29
- package/dist/modules/lsp/check-tool.js +7 -5
- package/dist/modules/lsp/client.js +39 -39
- package/dist/modules/lsp/command.js +17 -24
- package/dist/modules/lsp/config.js +12 -11
- package/dist/modules/lsp/index.js +1 -0
- package/dist/modules/lsp/module.js +48 -46
- package/dist/modules/lsp/probe.js +13 -14
- package/dist/modules/lsp/project-root.js +14 -17
- package/dist/modules/lsp/startup-check.js +18 -16
- package/dist/modules/mcp/client.js +59 -62
- package/dist/modules/mcp/index.js +1 -0
- package/dist/modules/mcp/module.js +66 -37
- package/dist/modules/mcp/registry.js +5 -0
- package/dist/modules/memory/index.js +1 -0
- package/dist/modules/memory/module.js +12 -8
- package/dist/modules/memory/search.js +4 -1
- package/dist/modules/memory/store.js +40 -2
- package/dist/modules/onboarding/init.js +47 -0
- package/dist/modules/onboarding/meet.js +30 -0
- package/dist/modules/onboarding/mode.js +30 -0
- package/dist/modules/onboarding/prompts.js +43 -0
- package/dist/modules/pipelines/engine.js +10 -0
- package/dist/modules/pipelines/index.js +1 -0
- package/dist/modules/pipelines/parser.js +4 -1
- package/dist/modules/pipelines/template.js +4 -0
- package/dist/modules/plugins/builtin/lint-on-write.js +80 -67
- package/dist/modules/plugins/builtin/notify.js +2 -0
- package/dist/modules/plugins/index.js +1 -0
- package/dist/modules/plugins/loader.js +18 -3
- package/dist/modules/plugins/manager.js +37 -17
- package/dist/modules/pricing/index.js +10 -11
- package/dist/modules/pricing/prices.js +12 -12
- package/dist/modules/processes/index.js +1 -0
- package/dist/modules/processes/kill-tree.js +27 -31
- package/dist/modules/processes/registry.js +44 -25
- package/dist/modules/processes/runner.js +4 -4
- package/dist/modules/providers/capabilities.js +28 -0
- package/dist/modules/providers/create.js +3 -4
- package/dist/modules/providers/factory.js +7 -7
- package/dist/modules/providers/fallback.js +12 -12
- package/dist/modules/providers/health.js +4 -4
- package/dist/modules/providers/manager.js +50 -19
- package/dist/modules/providers/naming.js +15 -0
- package/dist/modules/providers/preflight.js +71 -0
- package/dist/modules/providers/presets.js +39 -8
- package/dist/modules/providers/registry.js +7 -2
- package/dist/modules/reasoning/policy.js +8 -6
- package/dist/modules/reasoning/probe.js +30 -25
- package/dist/modules/security/audit-log.js +19 -36
- package/dist/modules/security/audit-notifier.js +35 -75
- package/dist/modules/security/command-validator.js +99 -51
- package/dist/modules/security/content-scanner.js +8 -8
- package/dist/modules/security/data-sanitizer.js +9 -16
- package/dist/modules/security/encryption.js +32 -52
- package/dist/modules/security/index.js +2 -1
- package/dist/modules/security/network-validator.js +120 -43
- package/dist/modules/security/path-validator.js +61 -46
- package/dist/modules/security/protected-paths.js +73 -0
- package/dist/modules/security/rate-limiter.js +17 -49
- package/dist/modules/security/security-policies.js +25 -57
- package/dist/modules/security/session-encryption.js +32 -71
- package/dist/modules/security/session-isolation.js +15 -28
- package/dist/modules/session/auto-name.js +63 -0
- package/dist/modules/session/export.js +98 -0
- package/dist/modules/session/index.js +1 -0
- package/dist/modules/session/manager.js +79 -28
- package/dist/modules/session/module.js +4 -3
- package/dist/modules/session/store.js +57 -20
- package/dist/modules/setup/answers.js +35 -0
- package/dist/modules/setup/apply.js +79 -0
- package/dist/modules/setup/discovery.js +72 -0
- package/dist/modules/skills/index.js +1 -0
- package/dist/modules/skills/loader.js +9 -1
- package/dist/modules/skills/module.js +11 -0
- package/dist/modules/updater/changelog-reader.js +15 -16
- package/dist/modules/updater/checker.js +9 -4
- package/dist/modules/updater/dev-detect.js +7 -6
- package/dist/modules/updater/index.js +1 -0
- package/dist/modules/updater/module.js +17 -15
- package/dist/modules/user-profile/compressor.js +2 -0
- package/dist/modules/user-profile/index.js +1 -0
- package/dist/modules/user-profile/profile.js +10 -1
- package/dist/modules/webui/answer-api.js +29 -0
- package/dist/modules/webui/assets.js +50 -0
- package/dist/modules/webui/body.js +21 -0
- package/dist/modules/webui/commands-settings.js +209 -0
- package/dist/modules/webui/commands-shared.js +60 -0
- package/dist/modules/webui/commands.js +174 -0
- package/dist/modules/webui/config-api.js +134 -0
- package/dist/modules/webui/file-api.js +202 -0
- package/dist/modules/webui/forward.js +159 -0
- package/dist/modules/webui/history-api.js +112 -0
- package/dist/modules/webui/host-state.js +60 -0
- package/dist/modules/webui/i18n-api.js +9 -0
- package/dist/modules/webui/limits.js +6 -0
- package/dist/modules/webui/log-forward.js +20 -0
- package/dist/modules/webui/memory-commands.js +64 -0
- package/dist/modules/webui/model-cache.js +18 -0
- package/dist/modules/webui/module.js +148 -0
- package/dist/modules/webui/persist.js +24 -0
- package/dist/modules/webui/prompt-io.js +97 -0
- package/dist/modules/webui/providers-api.js +337 -0
- package/dist/modules/webui/providers-view.js +56 -0
- package/dist/modules/webui/reasoning-view.js +15 -0
- package/dist/modules/webui/run-agent.js +81 -0
- package/dist/modules/webui/server.js +284 -0
- package/dist/modules/webui/sessions-api.js +178 -0
- package/dist/modules/webui/settings-api.js +561 -0
- package/dist/modules/webui/setup-api.js +201 -0
- package/dist/modules/webui/state.js +74 -0
- package/dist/modules/webui/util.js +261 -0
- package/dist/output/bus.js +7 -2
- package/dist/output/channel.js +80 -28
- package/dist/output/format.js +2 -1
- package/dist/output/index.js +1 -0
- package/dist/output/json-sink.js +5 -3
- package/dist/output/machine.js +4 -3
- package/dist/output/session-sink.js +4 -4
- package/dist/tools/approve.js +4 -0
- package/dist/tools/attach-image.js +5 -4
- package/dist/tools/auto-fixer.js +26 -44
- package/dist/tools/auto-tags.js +83 -0
- package/dist/tools/bash.js +193 -116
- package/dist/tools/browser.js +76 -31
- package/dist/tools/chunk-query.js +14 -6
- package/dist/tools/create-dir.js +9 -5
- package/dist/tools/delete-file.js +9 -5
- package/dist/tools/download-file.js +32 -7
- package/dist/tools/edit-file.js +52 -14
- package/dist/tools/enable-tools.js +6 -6
- package/dist/tools/executor.js +132 -27
- package/dist/tools/file-info.js +3 -1
- package/dist/tools/filter-tools.js +3 -3
- package/dist/tools/glob-tool.js +4 -1
- package/dist/tools/grep-tool.js +13 -10
- package/dist/tools/hidden-tools-block.js +6 -6
- package/dist/tools/index.js +16 -8
- package/dist/tools/list-dir.js +4 -2
- package/dist/tools/load-skill.js +7 -0
- package/dist/tools/mcp-call.js +15 -4
- package/dist/tools/meet-done.js +14 -0
- package/dist/tools/move-file.js +14 -7
- package/dist/tools/path-utils.js +29 -29
- package/dist/tools/pipeline-run.js +29 -7
- package/dist/tools/preview.js +1 -1
- package/dist/tools/process-ids.js +31 -0
- package/dist/tools/process-kill.js +9 -16
- package/dist/tools/process-list.js +1 -0
- package/dist/tools/process-log.js +11 -16
- package/dist/tools/process-wait.js +63 -0
- package/dist/tools/prompt-io.js +4 -3
- package/dist/tools/question.js +172 -25
- package/dist/tools/read-file.js +55 -34
- package/dist/tools/recall.js +14 -8
- package/dist/tools/registry.js +6 -5
- package/dist/tools/remember.js +8 -4
- package/dist/tools/scope-request.js +11 -6
- package/dist/tools/search-history.js +5 -2
- package/dist/tools/session-info.js +2 -0
- package/dist/tools/set-thinking.js +8 -4
- package/dist/tools/subagent.js +59 -39
- package/dist/tools/syntax-validator.js +292 -90
- package/dist/tools/user-input.js +22 -18
- package/dist/tools/web-browse.js +9 -3
- package/dist/tools/web-fetch.js +12 -23
- package/dist/tools/web-search.js +7 -5
- package/dist/tools/write-file.js +45 -15
- package/dist/ui/action-log.js +13 -0
- package/dist/ui/box.js +4 -3
- package/dist/ui/colors.js +2 -0
- package/dist/ui/diff.js +6 -5
- package/dist/ui/index.js +1 -0
- package/dist/ui/line-editor.js +230 -122
- package/dist/ui/line-math.js +10 -2
- package/dist/ui/md-formatter.js +57 -37
- package/dist/ui/output.js +8 -3
- package/dist/ui/plan-view.js +21 -10
- package/dist/ui/renderer.js +393 -67
- package/dist/ui/spinner.js +16 -5
- package/dist/ui/table.js +15 -17
- package/dist/ui/theme.js +143 -0
- package/dist/utils/child-run.js +20 -0
- package/dist/utils/error.js +1 -1
- package/dist/utils/index.js +2 -0
- package/dist/utils/retry.js +2 -2
- package/dist/utils/truncate.js +1 -1
- package/package.json +1 -1
|
@@ -1,14 +1,8 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Rate limiter for LLM requests
|
|
3
|
-
* Prevents DoS attacks by limiting the number of requests per time window
|
|
4
|
-
*/
|
|
5
1
|
const DEFAULT_CONFIG = {
|
|
6
2
|
maxRequestsPerMinute: 60,
|
|
7
3
|
maxParallelTasks: 5,
|
|
8
4
|
};
|
|
9
|
-
/**
|
|
10
|
-
* Rate limiter class for tracking LLM requests
|
|
11
|
-
*/
|
|
5
|
+
/** Лимитер запросов к LLM (окно + параллелизм). */
|
|
12
6
|
export class RateLimiter {
|
|
13
7
|
config;
|
|
14
8
|
state;
|
|
@@ -20,10 +14,7 @@ export class RateLimiter {
|
|
|
20
14
|
parallelTasks: 0,
|
|
21
15
|
};
|
|
22
16
|
}
|
|
23
|
-
/**
|
|
24
|
-
* Check if a new request is allowed
|
|
25
|
-
* Returns true if the request is allowed, false if rate limited
|
|
26
|
-
*/
|
|
17
|
+
/** Разрешён ли новый запрос (true) или сработал лимит (false). */
|
|
27
18
|
canMakeRequest() {
|
|
28
19
|
this.cleanupOldRequests();
|
|
29
20
|
if (this.state.requests.length >= this.config.maxRequestsPerMinute) {
|
|
@@ -31,50 +22,38 @@ export class RateLimiter {
|
|
|
31
22
|
}
|
|
32
23
|
return true;
|
|
33
24
|
}
|
|
34
|
-
/**
|
|
35
|
-
* Record a request
|
|
36
|
-
*/
|
|
25
|
+
/** Записать запрос в окно. */
|
|
37
26
|
recordRequest() {
|
|
38
27
|
this.cleanupOldRequests();
|
|
39
28
|
this.state.requests.push(Date.now());
|
|
40
29
|
}
|
|
41
|
-
/**
|
|
42
|
-
* Check if a new parallel task is allowed
|
|
43
|
-
*/
|
|
30
|
+
/** Можно ли стартовать параллельную задачу. */
|
|
44
31
|
canStartParallelTask() {
|
|
45
32
|
if (this.state.parallelTasks >= this.config.maxParallelTasks) {
|
|
46
33
|
return false;
|
|
47
34
|
}
|
|
48
35
|
return true;
|
|
49
36
|
}
|
|
50
|
-
/**
|
|
51
|
-
* Start a parallel task
|
|
52
|
-
*/
|
|
37
|
+
/** Старт параллельной задачи. */
|
|
53
38
|
startParallelTask() {
|
|
54
39
|
this.state.parallelTasks++;
|
|
55
40
|
}
|
|
56
|
-
/**
|
|
57
|
-
* End a parallel task
|
|
58
|
-
*/
|
|
41
|
+
/** Финиш параллельной задачи. */
|
|
59
42
|
endParallelTask() {
|
|
60
43
|
this.state.parallelTasks = Math.max(0, this.state.parallelTasks - 1);
|
|
61
44
|
}
|
|
62
|
-
/**
|
|
63
|
-
* Get current parallel task count
|
|
64
|
-
*/
|
|
45
|
+
/** Текущее число параллельных задач. */
|
|
65
46
|
getParallelTaskCount() {
|
|
66
47
|
return this.state.parallelTasks;
|
|
67
48
|
}
|
|
68
|
-
/**
|
|
69
|
-
* Get remaining requests in current window
|
|
70
|
-
*/
|
|
49
|
+
/** Остаток запросов в текущем окне. */
|
|
71
50
|
getRemainingRequests() {
|
|
72
51
|
this.cleanupOldRequests();
|
|
73
52
|
return Math.max(0, this.config.maxRequestsPerMinute - this.state.requests.length);
|
|
74
53
|
}
|
|
75
54
|
/**
|
|
76
|
-
*
|
|
77
|
-
*
|
|
55
|
+
* Миллисекунд до освобождения слота (старейший запрос вывалится из минутного
|
|
56
|
+
* окна). 0 — запрос можно слать сразу.
|
|
78
57
|
*/
|
|
79
58
|
msUntilRequest() {
|
|
80
59
|
this.cleanupOldRequests();
|
|
@@ -83,48 +62,37 @@ export class RateLimiter {
|
|
|
83
62
|
const oldest = this.state.requests[0];
|
|
84
63
|
return Math.max(0, 60_000 - (Date.now() - oldest));
|
|
85
64
|
}
|
|
86
|
-
/**
|
|
87
|
-
* Clean up old requests (older than 1 minute)
|
|
88
|
-
*/
|
|
65
|
+
/** Выкинуть запросы старше минуты. */
|
|
89
66
|
cleanupOldRequests() {
|
|
90
67
|
const now = Date.now();
|
|
91
68
|
const oneMinuteAgo = now - 60_000;
|
|
92
|
-
//
|
|
69
|
+
// Чистка не чаще раза в 5 секунд — без оверхеда
|
|
93
70
|
if (now - this.lastCleanup < 5000) {
|
|
94
71
|
return;
|
|
95
72
|
}
|
|
96
73
|
this.state.requests = this.state.requests.filter((timestamp) => timestamp > oneMinuteAgo);
|
|
97
74
|
this.lastCleanup = now;
|
|
98
75
|
}
|
|
99
|
-
/**
|
|
100
|
-
* Reset the rate limiter
|
|
101
|
-
*/
|
|
76
|
+
/** Сбросить лимитер. */
|
|
102
77
|
reset() {
|
|
103
78
|
this.state.requests = [];
|
|
104
79
|
this.state.parallelTasks = 0;
|
|
105
80
|
this.lastCleanup = 0;
|
|
106
81
|
}
|
|
107
|
-
/**
|
|
108
|
-
* Get rate limit configuration
|
|
109
|
-
*/
|
|
82
|
+
/** Текущий конфиг лимитов. */
|
|
110
83
|
getConfig() {
|
|
111
84
|
return this.config;
|
|
112
85
|
}
|
|
113
|
-
/**
|
|
114
|
-
* Update rate limit configuration
|
|
115
|
-
*/
|
|
86
|
+
/** Обновить конфиг лимитов. */
|
|
116
87
|
updateConfig(config) {
|
|
117
88
|
this.config = { ...this.config, ...config };
|
|
118
89
|
}
|
|
119
90
|
}
|
|
120
91
|
/**
|
|
121
|
-
*
|
|
122
|
-
* Can be used by LLM provider to enforce rate limits
|
|
92
|
+
* Глобальный лимитер для LLM-провайдера.
|
|
123
93
|
*/
|
|
124
94
|
export const globalRateLimiter = new RateLimiter();
|
|
125
|
-
/**
|
|
126
|
-
* Create a rate limiter with custom configuration
|
|
127
|
-
*/
|
|
95
|
+
/** Создать лимитер с кастомным конфигом. */
|
|
128
96
|
export function createRateLimiter(config) {
|
|
129
97
|
return new RateLimiter(config);
|
|
130
98
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { mergeSecurityConfig } from "../../config/security";
|
|
2
2
|
/**
|
|
3
|
-
* Strict
|
|
4
|
-
*
|
|
3
|
+
* Strict: максимум безопасности, минимум гибкости.
|
|
4
|
+
* Для: продакшн, чувствительные данные, многопользовательские системы.
|
|
5
5
|
*/
|
|
6
6
|
export const STRICT_POLICY = {
|
|
7
7
|
name: "Strict",
|
|
@@ -141,7 +141,7 @@ export const STRICT_POLICY = {
|
|
|
141
141
|
/require\('net'\)\.createServer/,
|
|
142
142
|
/process\.exit\(/,
|
|
143
143
|
/while\(true\)/,
|
|
144
|
-
/for\(
|
|
144
|
+
/for\(;;\)/,
|
|
145
145
|
/rm -rf/,
|
|
146
146
|
/dd if=/,
|
|
147
147
|
/chmod 777/,
|
|
@@ -174,8 +174,8 @@ export const STRICT_POLICY = {
|
|
|
174
174
|
},
|
|
175
175
|
};
|
|
176
176
|
/**
|
|
177
|
-
* Balanced
|
|
178
|
-
*
|
|
177
|
+
* Balanced: вменяемая безопасность с разумной гибкостью.
|
|
178
|
+
* Для: разработка, однопользовательские системы, общее использование.
|
|
179
179
|
*/
|
|
180
180
|
export const BALANCED_POLICY = {
|
|
181
181
|
name: "Balanced",
|
|
@@ -274,7 +274,7 @@ export const BALANCED_POLICY = {
|
|
|
274
274
|
/require\('child_process'\)/,
|
|
275
275
|
/process\.exit\(/,
|
|
276
276
|
/while\(true\)/,
|
|
277
|
-
/for\(
|
|
277
|
+
/for\(;;\)/,
|
|
278
278
|
/rm -rf/,
|
|
279
279
|
/dd if=/,
|
|
280
280
|
/chmod 777/,
|
|
@@ -294,8 +294,8 @@ export const BALANCED_POLICY = {
|
|
|
294
294
|
},
|
|
295
295
|
};
|
|
296
296
|
/**
|
|
297
|
-
* Permissive
|
|
298
|
-
*
|
|
297
|
+
* Permissive: минимум безопасности, максимум гибкости.
|
|
298
|
+
* Для: доверенные окружения, локальная разработка, тесты.
|
|
299
299
|
*/
|
|
300
300
|
export const PERMISSIVE_POLICY = {
|
|
301
301
|
name: "Permissive",
|
|
@@ -348,7 +348,7 @@ export const PERMISSIVE_POLICY = {
|
|
|
348
348
|
/eval\(/,
|
|
349
349
|
/new Function\(/,
|
|
350
350
|
/while\(true\)/,
|
|
351
|
-
/for\(
|
|
351
|
+
/for\(;;\)/,
|
|
352
352
|
/rm -rf/,
|
|
353
353
|
/dd if=/,
|
|
354
354
|
],
|
|
@@ -366,9 +366,7 @@ export const PERMISSIVE_POLICY = {
|
|
|
366
366
|
},
|
|
367
367
|
},
|
|
368
368
|
};
|
|
369
|
-
/**
|
|
370
|
-
* All available security policies
|
|
371
|
-
*/
|
|
369
|
+
/** Все доступные политики безопасности. */
|
|
372
370
|
export const SECURITY_POLICIES = {
|
|
373
371
|
strict: STRICT_POLICY,
|
|
374
372
|
balanced: BALANCED_POLICY,
|
|
@@ -381,27 +379,19 @@ export const SECURITY_POLICIES = {
|
|
|
381
379
|
config: {},
|
|
382
380
|
},
|
|
383
381
|
};
|
|
384
|
-
/**
|
|
385
|
-
* Security policy manager
|
|
386
|
-
*/
|
|
382
|
+
/** Менеджер политик безопасности (текущая + кастом). */
|
|
387
383
|
export class SecurityPolicyManager {
|
|
388
384
|
currentPolicy = "balanced";
|
|
389
385
|
customConfig = {};
|
|
390
|
-
/**
|
|
391
|
-
* Get all available policies
|
|
392
|
-
*/
|
|
386
|
+
/** Все доступные политики. */
|
|
393
387
|
getPolicies() {
|
|
394
388
|
return Object.values(SECURITY_POLICIES);
|
|
395
389
|
}
|
|
396
|
-
/**
|
|
397
|
-
* Get a specific policy by name
|
|
398
|
-
*/
|
|
390
|
+
/** Политика по имени (неизвестная — balanced). */
|
|
399
391
|
getPolicy(preset) {
|
|
400
392
|
return SECURITY_POLICIES[preset] || SECURITY_POLICIES.balanced;
|
|
401
393
|
}
|
|
402
|
-
/**
|
|
403
|
-
* Get the current policy
|
|
404
|
-
*/
|
|
394
|
+
/** Текущая политика (custom — с кастомным конфигом). */
|
|
405
395
|
getCurrentPolicy() {
|
|
406
396
|
if (this.currentPolicy === "custom") {
|
|
407
397
|
return {
|
|
@@ -411,22 +401,16 @@ export class SecurityPolicyManager {
|
|
|
411
401
|
}
|
|
412
402
|
return this.getPolicy(this.currentPolicy);
|
|
413
403
|
}
|
|
414
|
-
/**
|
|
415
|
-
* Set the current policy
|
|
416
|
-
*/
|
|
404
|
+
/** Назначить текущую политику. */
|
|
417
405
|
setPolicy(preset) {
|
|
418
406
|
this.currentPolicy = preset;
|
|
419
407
|
}
|
|
420
|
-
/**
|
|
421
|
-
* Set custom configuration (for 'custom' preset)
|
|
422
|
-
*/
|
|
408
|
+
/** Задать кастомный конфиг (переключает на 'custom'). */
|
|
423
409
|
setCustomConfig(config) {
|
|
424
410
|
this.customConfig = config;
|
|
425
411
|
this.currentPolicy = "custom";
|
|
426
412
|
}
|
|
427
|
-
/**
|
|
428
|
-
* Get the current security configuration
|
|
429
|
-
*/
|
|
413
|
+
/** Текущий security-конфиг (политика + мерж дефолтов). */
|
|
430
414
|
getConfig() {
|
|
431
415
|
const policy = this.getCurrentPolicy();
|
|
432
416
|
return mergeSecurityConfig({
|
|
@@ -434,9 +418,7 @@ export class SecurityPolicyManager {
|
|
|
434
418
|
...(this.currentPolicy === "custom" ? this.customConfig : {}),
|
|
435
419
|
});
|
|
436
420
|
}
|
|
437
|
-
/**
|
|
438
|
-
* Apply a policy and return the merged configuration
|
|
439
|
-
*/
|
|
421
|
+
/** Применить политику с опциональными оверрайдами; вернуть смерженный конфиг. */
|
|
440
422
|
applyPolicy(preset, customOverrides) {
|
|
441
423
|
this.setPolicy(preset);
|
|
442
424
|
if (customOverrides) {
|
|
@@ -445,9 +427,7 @@ export class SecurityPolicyManager {
|
|
|
445
427
|
}
|
|
446
428
|
return this.getConfig();
|
|
447
429
|
}
|
|
448
|
-
/**
|
|
449
|
-
* Get policy recommendation for a use case
|
|
450
|
-
*/
|
|
430
|
+
/** Рекомендованная политика для кейса (иначе — balanced). */
|
|
451
431
|
getRecommendation(useCase) {
|
|
452
432
|
for (const policy of this.getPolicies()) {
|
|
453
433
|
if (policy.recommendedFor.includes(useCase)) {
|
|
@@ -456,9 +436,7 @@ export class SecurityPolicyManager {
|
|
|
456
436
|
}
|
|
457
437
|
return BALANCED_POLICY;
|
|
458
438
|
}
|
|
459
|
-
/**
|
|
460
|
-
* Check if current policy allows a specific action
|
|
461
|
-
*/
|
|
439
|
+
/** Разрешает ли текущая политика действие (bash/file_access/network). */
|
|
462
440
|
allowsAction(action, context) {
|
|
463
441
|
const config = this.getConfig();
|
|
464
442
|
switch (action) {
|
|
@@ -490,9 +468,7 @@ export class SecurityPolicyManager {
|
|
|
490
468
|
return true;
|
|
491
469
|
}
|
|
492
470
|
}
|
|
493
|
-
/**
|
|
494
|
-
* Get policy comparison
|
|
495
|
-
*/
|
|
471
|
+
/** Посравнить две политики по ключам конфига. */
|
|
496
472
|
comparePolicies(policy1, policy2) {
|
|
497
473
|
const config1 = this.getPolicy(policy1).config;
|
|
498
474
|
const config2 = this.getPolicy(policy2).config;
|
|
@@ -507,25 +483,17 @@ export class SecurityPolicyManager {
|
|
|
507
483
|
return comparison;
|
|
508
484
|
}
|
|
509
485
|
}
|
|
510
|
-
/**
|
|
511
|
-
* Global security policy manager instance
|
|
512
|
-
*/
|
|
486
|
+
/** Глобальный менеджер политик. */
|
|
513
487
|
export const globalSecurityPolicyManager = new SecurityPolicyManager();
|
|
514
|
-
/**
|
|
515
|
-
* Create a security policy manager with custom configuration
|
|
516
|
-
*/
|
|
488
|
+
/** Создать менеджер политик. */
|
|
517
489
|
export function createSecurityPolicyManager() {
|
|
518
490
|
return new SecurityPolicyManager();
|
|
519
491
|
}
|
|
520
|
-
/**
|
|
521
|
-
* Get a policy by name
|
|
522
|
-
*/
|
|
492
|
+
/** Политика по имени через глобальный менеджер. */
|
|
523
493
|
export function getSecurityPolicy(preset) {
|
|
524
494
|
return globalSecurityPolicyManager.getPolicy(preset);
|
|
525
495
|
}
|
|
526
|
-
/**
|
|
527
|
-
* Apply a security policy
|
|
528
|
-
*/
|
|
496
|
+
/** Применить политику через глобальный менеджер. */
|
|
529
497
|
export function applySecurityPolicy(preset, customOverrides) {
|
|
530
498
|
return globalSecurityPolicyManager.applyPolicy(preset, customOverrides);
|
|
531
499
|
}
|
|
@@ -1,45 +1,36 @@
|
|
|
1
|
+
// Шифрование файлов сессий (history.jsonl, session.jsonl): чтение/запись/append.
|
|
1
2
|
import { readFileSync, writeFileSync, existsSync, readdirSync, unlinkSync } from "fs";
|
|
2
3
|
import { join } from "path";
|
|
3
|
-
import { homedir } from "os";
|
|
4
4
|
import { encryptString, decryptString, isEncryptedString, ConfigEncryptor, } from "./encryption";
|
|
5
5
|
import { defaultOutputBus } from "../../output";
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
*/
|
|
6
|
+
import { globalMmaDir } from "../../config/paths";
|
|
7
|
+
/** Дефолтный конфиг шифрования сессии (выключено). */
|
|
9
8
|
export const DEFAULT_SESSION_ENCRYPTION = {
|
|
10
9
|
enabled: false,
|
|
11
10
|
encryptHistory: true,
|
|
12
11
|
encryptSessionLog: true,
|
|
13
12
|
};
|
|
14
|
-
/**
|
|
15
|
-
* Session file encryptor/decryptor
|
|
16
|
-
*/
|
|
13
|
+
/** Шифровальщик/расшифровщик файлов сессии. */
|
|
17
14
|
export class SessionFileEncryptor {
|
|
18
15
|
config;
|
|
19
16
|
encryptor;
|
|
20
17
|
constructor(config) {
|
|
21
18
|
this.config = { ...DEFAULT_SESSION_ENCRYPTION, ...config };
|
|
22
19
|
this.encryptor = new ConfigEncryptor({
|
|
23
|
-
keyPath: config?.keyPath || join(
|
|
20
|
+
keyPath: config?.keyPath || join(globalMmaDir(), ".session-encryption-key"),
|
|
24
21
|
});
|
|
25
22
|
}
|
|
26
|
-
/**
|
|
27
|
-
* Check if session file encryption is enabled
|
|
28
|
-
*/
|
|
23
|
+
/** Включено ли шифрование файлов сессии. */
|
|
29
24
|
isEnabled() {
|
|
30
25
|
return this.config.enabled;
|
|
31
26
|
}
|
|
32
|
-
/**
|
|
33
|
-
* Encrypt a session file content
|
|
34
|
-
*/
|
|
27
|
+
/** Зашифровать содержимое файла сессии. */
|
|
35
28
|
encryptFileContent(content) {
|
|
36
29
|
if (!this.config.enabled)
|
|
37
30
|
return content;
|
|
38
31
|
return encryptString(content, this.encryptor.getKey());
|
|
39
32
|
}
|
|
40
|
-
/**
|
|
41
|
-
* Decrypt a session file content
|
|
42
|
-
*/
|
|
33
|
+
/** Расшифровать содержимое файла сессии (plain text — как есть). */
|
|
43
34
|
decryptFileContent(content) {
|
|
44
35
|
if (!this.config.enabled)
|
|
45
36
|
return content;
|
|
@@ -47,17 +38,13 @@ export class SessionFileEncryptor {
|
|
|
47
38
|
return content;
|
|
48
39
|
return decryptString(content, this.encryptor.getKey());
|
|
49
40
|
}
|
|
50
|
-
/**
|
|
51
|
-
* Encrypt a JSON object (for structured files)
|
|
52
|
-
*/
|
|
41
|
+
/** Зашифровать JSON-объект (для структурных файлов). */
|
|
53
42
|
encryptJSON(obj) {
|
|
54
43
|
if (!this.config.enabled)
|
|
55
44
|
return JSON.stringify(obj);
|
|
56
45
|
return this.encryptFileContent(JSON.stringify(obj));
|
|
57
46
|
}
|
|
58
|
-
/**
|
|
59
|
-
* Decrypt a JSON string
|
|
60
|
-
*/
|
|
47
|
+
/** Расшифровать JSON-строку; мусор — ошибка. */
|
|
61
48
|
decryptJSON(content) {
|
|
62
49
|
let plain = content;
|
|
63
50
|
if (this.config.enabled) {
|
|
@@ -70,18 +57,16 @@ export class SessionFileEncryptor {
|
|
|
70
57
|
throw new Error("Invalid JSON content in session file — file may be corrupted or encrypted with a different key");
|
|
71
58
|
}
|
|
72
59
|
}
|
|
73
|
-
/**
|
|
74
|
-
* Encrypt a JSONL file (one JSON object per line)
|
|
75
|
-
*/
|
|
60
|
+
/** Зашифровать JSONL-файл (по строке на объект). */
|
|
76
61
|
encryptJSONL(lines) {
|
|
77
62
|
if (!this.config.enabled)
|
|
78
63
|
return lines;
|
|
79
64
|
return lines.map((line) => this.encryptFileContent(line));
|
|
80
65
|
}
|
|
81
66
|
/**
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
67
|
+
* Расшифровать JSONL. Строка с ошибкой (битая, оборванная крашем, чужой
|
|
68
|
+
* plaintext) логируется и ПРОПУСКАЕТСЯ — одна плохая строка не должна
|
|
69
|
+
* убивать всю историю сессии.
|
|
85
70
|
*/
|
|
86
71
|
decryptJSONL(lines) {
|
|
87
72
|
if (!this.config.enabled)
|
|
@@ -96,42 +81,32 @@ export class SessionFileEncryptor {
|
|
|
96
81
|
}
|
|
97
82
|
});
|
|
98
83
|
}
|
|
99
|
-
/**
|
|
100
|
-
* Read and decrypt a session file
|
|
101
|
-
*/
|
|
84
|
+
/** Прочитать и расшифровать файл сессии. */
|
|
102
85
|
readSessionFile(filePath) {
|
|
103
86
|
const content = readFileSync(filePath, "utf8");
|
|
104
87
|
return this.decryptFileContent(content);
|
|
105
88
|
}
|
|
106
|
-
/**
|
|
107
|
-
* Write and encrypt a session file
|
|
108
|
-
*/
|
|
89
|
+
/** Зашифровать и записать файл сессии. */
|
|
109
90
|
writeSessionFile(filePath, content) {
|
|
110
91
|
const encrypted = this.encryptFileContent(content);
|
|
111
92
|
writeFileSync(filePath, encrypted, "utf8");
|
|
112
93
|
}
|
|
113
|
-
/**
|
|
114
|
-
* Read and decrypt a JSON session file
|
|
115
|
-
*/
|
|
94
|
+
/** Прочитать и расшифровать JSON-файл сессии. */
|
|
116
95
|
readSessionJSON(filePath) {
|
|
117
96
|
const content = readFileSync(filePath, "utf8");
|
|
118
97
|
return this.decryptJSON(content);
|
|
119
98
|
}
|
|
120
|
-
/**
|
|
121
|
-
* Write and encrypt a JSON session file
|
|
122
|
-
*/
|
|
99
|
+
/** Зашифровать и записать JSON-файл сессии. */
|
|
123
100
|
writeSessionJSON(filePath, obj) {
|
|
124
101
|
const content = this.encryptJSON(obj);
|
|
125
102
|
writeFileSync(filePath, content, "utf8");
|
|
126
103
|
}
|
|
127
|
-
/**
|
|
128
|
-
* Read and decrypt a JSONL session file
|
|
129
|
-
*/
|
|
104
|
+
/** Прочитать и расшифровать JSONL-файл сессии (битые строки пропускаются). */
|
|
130
105
|
readSessionJSONL(filePath) {
|
|
131
106
|
const content = readFileSync(filePath, "utf8");
|
|
132
107
|
const lines = content.split("\n").filter((line) => line.trim());
|
|
133
108
|
const decryptedLines = this.decryptJSONL(lines);
|
|
134
|
-
//
|
|
109
|
+
// Кривые строки пропускаем, а не роняем весь лог сессии
|
|
135
110
|
return decryptedLines.flatMap((line) => {
|
|
136
111
|
try {
|
|
137
112
|
return [JSON.parse(line)];
|
|
@@ -141,19 +116,15 @@ export class SessionFileEncryptor {
|
|
|
141
116
|
}
|
|
142
117
|
});
|
|
143
118
|
}
|
|
144
|
-
/**
|
|
145
|
-
* Append an encrypted entry to a JSONL file
|
|
146
|
-
*/
|
|
119
|
+
/** Добавить зашифрованную запись в JSONL-файл. */
|
|
147
120
|
appendToSessionJSONL(filePath, obj) {
|
|
148
121
|
const encryptedLine = this.encryptFileContent(JSON.stringify(obj));
|
|
149
|
-
writeFileSync(filePath, encryptedLine
|
|
122
|
+
writeFileSync(filePath, `${encryptedLine}\n`, {
|
|
150
123
|
flag: "a",
|
|
151
124
|
encoding: "utf8",
|
|
152
125
|
});
|
|
153
126
|
}
|
|
154
|
-
/**
|
|
155
|
-
* Encrypt all session files in a directory
|
|
156
|
-
*/
|
|
127
|
+
/** Зашифровать все файлы каталога сессии (*.enc, оригиналы удаляются). */
|
|
157
128
|
encryptSessionDirectory(sessionDir) {
|
|
158
129
|
if (!this.config.enabled)
|
|
159
130
|
return;
|
|
@@ -164,18 +135,16 @@ export class SessionFileEncryptor {
|
|
|
164
135
|
try {
|
|
165
136
|
const content = readFileSync(filePath, "utf8");
|
|
166
137
|
const encrypted = this.encryptFileContent(content);
|
|
167
|
-
writeFileSync(filePath
|
|
138
|
+
writeFileSync(`${filePath}.enc`, encrypted, "utf8");
|
|
168
139
|
unlinkSync(filePath);
|
|
169
140
|
}
|
|
170
141
|
catch {
|
|
171
|
-
//
|
|
142
|
+
// Бинарники и нечитаемое пропускаем
|
|
172
143
|
}
|
|
173
144
|
}
|
|
174
145
|
}
|
|
175
146
|
}
|
|
176
|
-
/**
|
|
177
|
-
* Decrypt all session files in a directory
|
|
178
|
-
*/
|
|
147
|
+
/** Расшифровать все *.enc в каталоге сессии (оригиналы восстанавливаются). */
|
|
179
148
|
decryptSessionDirectory(sessionDir) {
|
|
180
149
|
if (!this.config.enabled)
|
|
181
150
|
return;
|
|
@@ -183,7 +152,7 @@ export class SessionFileEncryptor {
|
|
|
183
152
|
for (const file of files) {
|
|
184
153
|
if (file.endsWith(".enc")) {
|
|
185
154
|
const encFilePath = join(sessionDir, file);
|
|
186
|
-
const decFilePath = encFilePath.slice(0, -4); //
|
|
155
|
+
const decFilePath = encFilePath.slice(0, -4); // снять .enc
|
|
187
156
|
try {
|
|
188
157
|
const content = readFileSync(encFilePath, "utf8");
|
|
189
158
|
const decrypted = this.decryptFileContent(content);
|
|
@@ -191,31 +160,23 @@ export class SessionFileEncryptor {
|
|
|
191
160
|
unlinkSync(encFilePath);
|
|
192
161
|
}
|
|
193
162
|
catch {
|
|
194
|
-
//
|
|
163
|
+
// Нерасшифровываемое пропускаем
|
|
195
164
|
}
|
|
196
165
|
}
|
|
197
166
|
}
|
|
198
167
|
}
|
|
199
168
|
}
|
|
200
|
-
/**
|
|
201
|
-
* Global session file encryptor instance
|
|
202
|
-
*/
|
|
169
|
+
/** Глобальный шифровальщик файлов сессии. */
|
|
203
170
|
export const globalSessionEncryptor = new SessionFileEncryptor();
|
|
204
|
-
/**
|
|
205
|
-
* Create a session file encryptor with custom configuration
|
|
206
|
-
*/
|
|
171
|
+
/** Создать шифровальщик файлов сессии с кастомным конфигом. */
|
|
207
172
|
export function createSessionFileEncryptor(config) {
|
|
208
173
|
return new SessionFileEncryptor(config);
|
|
209
174
|
}
|
|
210
|
-
/**
|
|
211
|
-
* Helper to encrypt a message object (for SessionMessage)
|
|
212
|
-
*/
|
|
175
|
+
/** Хелпер: зашифровать объект сообщения (для SessionMessage). */
|
|
213
176
|
export function encryptSessionMessage(msg) {
|
|
214
177
|
return globalSessionEncryptor.encryptJSON(msg);
|
|
215
178
|
}
|
|
216
|
-
/**
|
|
217
|
-
* Helper to decrypt a session message
|
|
218
|
-
*/
|
|
179
|
+
/** Хелпер: расшифровать сообщение сессии. */
|
|
219
180
|
export function decryptSessionMessage(encrypted) {
|
|
220
181
|
return globalSessionEncryptor.decryptJSON(encrypted);
|
|
221
182
|
}
|
|
@@ -1,30 +1,27 @@
|
|
|
1
|
+
// Изоляция сессий: свой temp-каталог, свои security-оверрайды, скоуп путей.
|
|
1
2
|
import { join, resolve } from "path";
|
|
2
|
-
import { homedir } from "os";
|
|
3
3
|
import { mkdirSync, existsSync } from "fs";
|
|
4
4
|
import { DEFAULT_SECURITY_CONFIG } from "../../config/security";
|
|
5
5
|
import { isInsideDir } from "../../tools/path-utils";
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
*/
|
|
6
|
+
import { globalSessionsDir } from "../../config/paths";
|
|
7
|
+
/** Дефолтный конфиг изоляции сессий (выключена). */
|
|
9
8
|
export const DEFAULT_SESSION_ISOLATION = {
|
|
10
9
|
enabled: false,
|
|
11
10
|
isolatePlugins: true,
|
|
12
11
|
isolateTempFiles: true,
|
|
13
12
|
};
|
|
14
|
-
/**
|
|
15
|
-
* Create a session context with isolation
|
|
16
|
-
*/
|
|
13
|
+
/** Создать контекст сессии с изоляцией (temp-каталог 0700). */
|
|
17
14
|
export function createSessionContext(sessionId, projectDir, isolationConfig, securityOverrides) {
|
|
18
15
|
const config = { ...DEFAULT_SESSION_ISOLATION, ...isolationConfig };
|
|
19
|
-
//
|
|
20
|
-
const baseDir = config.baseDir || join(
|
|
16
|
+
// Временный каталог сессии
|
|
17
|
+
const baseDir = config.baseDir || join(globalSessionsDir(), sessionId);
|
|
21
18
|
const tempDir = join(baseDir, "temp");
|
|
22
19
|
if (config.isolateTempFiles && !existsSync(tempDir)) {
|
|
23
20
|
try {
|
|
24
21
|
mkdirSync(tempDir, { recursive: true, mode: 0o700 });
|
|
25
22
|
}
|
|
26
23
|
catch {
|
|
27
|
-
//
|
|
24
|
+
// Каталог не создался — работаем без изоляции
|
|
28
25
|
}
|
|
29
26
|
}
|
|
30
27
|
return {
|
|
@@ -35,8 +32,7 @@ export function createSessionContext(sessionId, projectDir, isolationConfig, sec
|
|
|
35
32
|
};
|
|
36
33
|
}
|
|
37
34
|
/**
|
|
38
|
-
*
|
|
39
|
-
* Merges global security config with session overrides
|
|
35
|
+
* Security-конфиг сессии: глобальный + оверрайды (вложенные объекты мержатся).
|
|
40
36
|
*/
|
|
41
37
|
export function getSessionSecurityConfig(globalConfig, sessionContext) {
|
|
42
38
|
const globalSecurity = globalConfig.security || DEFAULT_SECURITY_CONFIG;
|
|
@@ -47,7 +43,7 @@ export function getSessionSecurityConfig(globalConfig, sessionContext) {
|
|
|
47
43
|
return {
|
|
48
44
|
...globalSecurity,
|
|
49
45
|
...sessionOverrides,
|
|
50
|
-
//
|
|
46
|
+
// Вложенные объекты — мерж, не замена
|
|
51
47
|
bash: { ...globalSecurity.bash, ...sessionOverrides.bash },
|
|
52
48
|
paths: { ...globalSecurity.paths, ...sessionOverrides.paths },
|
|
53
49
|
network: { ...globalSecurity.network, ...sessionOverrides.network },
|
|
@@ -55,31 +51,22 @@ export function getSessionSecurityConfig(globalConfig, sessionContext) {
|
|
|
55
51
|
contentScan: { ...globalSecurity.contentScan, ...sessionOverrides.contentScan },
|
|
56
52
|
};
|
|
57
53
|
}
|
|
58
|
-
/**
|
|
59
|
-
* Get session-specific temporary directory
|
|
60
|
-
*/
|
|
54
|
+
/** Временный каталог сессии. */
|
|
61
55
|
export function getSessionTempDir(sessionContext) {
|
|
62
56
|
return sessionContext.tempDir;
|
|
63
57
|
}
|
|
64
|
-
/**
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
export function cleanupSessionTempDir(sessionContext) {
|
|
68
|
-
// Note: In a real implementation, we would recursively delete the temp dir
|
|
69
|
-
// For now, we just leave it as the OS will clean up eventually
|
|
70
|
-
// In production, you might want to implement proper cleanup
|
|
58
|
+
/** Убрать временные данные сессии (пока no-op — чистит ОС). */
|
|
59
|
+
export function cleanupSessionTempDir(_sessionContext) {
|
|
60
|
+
// Заглушка: рекурсивное удаление не реализовано, чистит ОС.
|
|
71
61
|
}
|
|
72
62
|
/**
|
|
73
|
-
*
|
|
74
|
-
* Ensures the path is within the session's working directory or temp directory
|
|
63
|
+
* Путь к файлу сессии: обязан лежать в рабочем или temp-каталоге сессии.
|
|
75
64
|
*/
|
|
76
65
|
export function createSessionFilePath(sessionContext, relativePath, useTempDir = false) {
|
|
77
66
|
const baseDir = useTempDir ? sessionContext.tempDir : sessionContext.workingDir;
|
|
78
67
|
return resolve(baseDir, relativePath);
|
|
79
68
|
}
|
|
80
|
-
/**
|
|
81
|
-
* Check if a path is within the session's allowed directories
|
|
82
|
-
*/
|
|
69
|
+
/** Путь в разрешённых каталогах сессии (рабочий или temp) или нет. */
|
|
83
70
|
export function isPathInSessionScope(sessionContext, path) {
|
|
84
71
|
const resolvedPath = resolve(path);
|
|
85
72
|
const workingDir = resolve(sessionContext.workingDir);
|