micro-models-agent 2.10.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 +33 -0
- package/dist/assets/app.js +22 -4
- package/dist/assets/index.html +29 -0
- package/dist/assets/js/dom.js +2 -1
- package/dist/assets/js/feed.js +38 -26
- package/dist/assets/js/format.js +1 -1
- package/dist/assets/js/rail.js +114 -0
- package/dist/assets/js/settings-controls.js +2 -2
- package/dist/assets/js/settings.js +246 -51
- package/dist/assets/js/store.js +3 -0
- package/dist/assets/js/tabs.js +104 -2
- package/dist/assets/styles.css +215 -66
- 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/en.json +106 -21
- package/dist/i18n/index.js +37 -3
- package/dist/i18n/ru.json +109 -21
- 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 +24285 -22447
- 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
package/dist/cli/completer.js
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
import { readdirSync, statSync } from "fs";
|
|
2
2
|
import { join } from "path";
|
|
3
|
+
import { allConfigNames, canonicalKeys, resolveConfigKey } from "../config/registry";
|
|
4
|
+
import { t } from "../i18n/index";
|
|
5
|
+
/**
|
|
6
|
+
* Строит slash-варианты из реестра команд. `commands` ключуется И каноническими
|
|
7
|
+
* именами, И алиасами — каждый алиас становится дополняемым токеном с описанием
|
|
8
|
+
* своей команды.
|
|
9
|
+
*/
|
|
10
|
+
export function buildSlashCompletions(commands) {
|
|
11
|
+
return Array.from(commands.entries()).map(([name, cmd]) => ({
|
|
12
|
+
name,
|
|
13
|
+
description: cmd.description,
|
|
14
|
+
}));
|
|
15
|
+
}
|
|
16
|
+
/** Дополняет slash-команды в позиции 0. */
|
|
3
17
|
export class SlashCommandProvider {
|
|
4
18
|
name = "slash-commands";
|
|
5
19
|
commands;
|
|
@@ -10,24 +24,30 @@ export class SlashCommandProvider {
|
|
|
10
24
|
return ctx.tokenIndex === 0 && ctx.line.startsWith("/");
|
|
11
25
|
}
|
|
12
26
|
complete(ctx) {
|
|
13
|
-
return this.commands
|
|
27
|
+
return this.commands
|
|
28
|
+
.filter((c) => c.name.startsWith(ctx.partial.slice(1)))
|
|
29
|
+
.map((c) => ({ value: `/${c.name}`, description: c.description }));
|
|
14
30
|
}
|
|
15
31
|
}
|
|
32
|
+
/** Дополняет субкоманды (`/model use`, `/skill load`, …) в позиции 1. */
|
|
16
33
|
export class SubcommandProvider {
|
|
17
34
|
name = "subcommands";
|
|
18
35
|
command;
|
|
19
36
|
subcommands;
|
|
20
37
|
constructor(command, subcommands) {
|
|
21
38
|
this.command = command;
|
|
22
|
-
this.subcommands = subcommands;
|
|
39
|
+
this.subcommands = subcommands.map((s) => (typeof s === "string" ? { name: s } : s));
|
|
23
40
|
}
|
|
24
41
|
match(ctx) {
|
|
25
42
|
return ctx.tokenIndex === 1 && ctx.tokens[0] === `/${this.command}`;
|
|
26
43
|
}
|
|
27
44
|
complete(ctx) {
|
|
28
|
-
return this.subcommands
|
|
45
|
+
return this.subcommands
|
|
46
|
+
.filter((s) => s.name.startsWith(ctx.partial))
|
|
47
|
+
.map((s) => ({ value: s.name, description: s.description }));
|
|
29
48
|
}
|
|
30
49
|
}
|
|
50
|
+
/** Дополняет имена моделей для `/model use`. */
|
|
31
51
|
export class ModelArgProvider {
|
|
32
52
|
name = "model-args";
|
|
33
53
|
getModels;
|
|
@@ -38,30 +58,25 @@ export class ModelArgProvider {
|
|
|
38
58
|
return ctx.tokenIndex === 2 && ctx.tokens[0] === "/model" && ctx.tokens[1] === "use";
|
|
39
59
|
}
|
|
40
60
|
complete(ctx) {
|
|
41
|
-
return this.getModels()
|
|
42
|
-
|
|
43
|
-
}
|
|
44
|
-
export class ConfigKeyProvider {
|
|
45
|
-
name = "config-keys";
|
|
46
|
-
keys;
|
|
47
|
-
constructor(keys) {
|
|
48
|
-
this.keys = keys;
|
|
49
|
-
}
|
|
50
|
-
match(ctx) {
|
|
51
|
-
return ctx.tokenIndex >= 1 && ctx.tokens[0] === "/config" && ctx.tokens[1] === "set";
|
|
52
|
-
}
|
|
53
|
-
complete(ctx) {
|
|
54
|
-
return this.keys.filter((k) => k.startsWith(ctx.partial));
|
|
61
|
+
return this.getModels()
|
|
62
|
+
.filter((m) => m.startsWith(ctx.partial))
|
|
63
|
+
.map((m) => ({ value: m }));
|
|
55
64
|
}
|
|
56
65
|
}
|
|
66
|
+
/** Дополняет файловые пути (до 20 вариантов, каталоги со `/`). */
|
|
57
67
|
export class FilePathProvider {
|
|
58
68
|
name = "file-paths";
|
|
69
|
+
root;
|
|
70
|
+
constructor(root) {
|
|
71
|
+
this.root = root;
|
|
72
|
+
}
|
|
59
73
|
match(ctx) {
|
|
60
|
-
return ctx.
|
|
74
|
+
return (ctx.tokenIndex >= 1 &&
|
|
75
|
+
(ctx.partial.includes("/") || ctx.partial.includes("\\")));
|
|
61
76
|
}
|
|
62
77
|
complete(ctx) {
|
|
63
78
|
try {
|
|
64
|
-
const cwd = process.cwd();
|
|
79
|
+
const cwd = this.root ?? process.cwd();
|
|
65
80
|
const partialPath = ctx.partial;
|
|
66
81
|
const lastSlash = Math.max(partialPath.lastIndexOf("/"), partialPath.lastIndexOf("\\"));
|
|
67
82
|
const dirPath = lastSlash > 0 ? partialPath.slice(0, lastSlash) : ".";
|
|
@@ -77,13 +92,14 @@ export class FilePathProvider {
|
|
|
77
92
|
matches.push(completion);
|
|
78
93
|
}
|
|
79
94
|
}
|
|
80
|
-
return matches.slice(0, 20);
|
|
95
|
+
return matches.slice(0, 20).map((m) => ({ value: m }));
|
|
81
96
|
}
|
|
82
97
|
catch {
|
|
83
98
|
return [];
|
|
84
99
|
}
|
|
85
100
|
}
|
|
86
101
|
}
|
|
102
|
+
/** Дополняет имена провайдеров для `/provider use`. */
|
|
87
103
|
export class ProviderArgProvider {
|
|
88
104
|
name = "provider-args";
|
|
89
105
|
providers;
|
|
@@ -94,25 +110,30 @@ export class ProviderArgProvider {
|
|
|
94
110
|
return ctx.tokenIndex === 2 && ctx.tokens[0] === "/provider" && ctx.tokens[1] === "use";
|
|
95
111
|
}
|
|
96
112
|
complete(ctx) {
|
|
97
|
-
return this.providers.filter((p) => p.startsWith(ctx.partial));
|
|
113
|
+
return this.providers.filter((p) => p.startsWith(ctx.partial)).map((p) => ({ value: p }));
|
|
98
114
|
}
|
|
99
115
|
}
|
|
116
|
+
/** Дополняет имена сессий для `/resume` и др. */
|
|
100
117
|
export class SessionNameProvider {
|
|
101
118
|
name = "session-names";
|
|
102
119
|
getNames;
|
|
103
|
-
|
|
120
|
+
commands;
|
|
121
|
+
constructor(getNames, commands = ["/resume"]) {
|
|
104
122
|
this.getNames = getNames;
|
|
123
|
+
this.commands = commands;
|
|
105
124
|
}
|
|
106
125
|
match(ctx) {
|
|
107
|
-
return ctx.tokenIndex >= 1 && ctx.tokens[0]
|
|
126
|
+
return ctx.tokenIndex >= 1 && this.commands.includes(ctx.tokens[0]);
|
|
108
127
|
}
|
|
109
128
|
complete(ctx) {
|
|
110
129
|
const names = this.getNames();
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
130
|
+
const filtered = !ctx.partial
|
|
131
|
+
? names
|
|
132
|
+
: names.filter((n) => n.toLowerCase().includes(ctx.partial.toLowerCase()));
|
|
133
|
+
return filtered.map((n) => ({ value: n }));
|
|
114
134
|
}
|
|
115
135
|
}
|
|
136
|
+
/** Дополняет имена скиллов для `/skill load|unload`. */
|
|
116
137
|
export class SkillNameProvider {
|
|
117
138
|
name = "skill-names";
|
|
118
139
|
skillsModule;
|
|
@@ -133,21 +154,101 @@ export class SkillNameProvider {
|
|
|
133
154
|
if (!source)
|
|
134
155
|
return [];
|
|
135
156
|
const names = source();
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
157
|
+
const filtered = !ctx.partial
|
|
158
|
+
? names
|
|
159
|
+
: names.filter((n) => n.toLowerCase().includes(ctx.partial.toLowerCase()));
|
|
160
|
+
return filtered.map((n) => ({ value: n }));
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Дополняет ключи `/config` (канонические и алиасы). Partial без точки листает
|
|
165
|
+
* верхние группы + подходящие ключи; partial с точкой — следующий сегмент
|
|
166
|
+
* точечного дерева (напр. `contextBudget.` → systemPrompt).
|
|
167
|
+
*/
|
|
168
|
+
export class ConfigKeyProvider {
|
|
169
|
+
name = "config-keys";
|
|
170
|
+
match(ctx) {
|
|
171
|
+
return ctx.tokenIndex === 1 && ctx.tokens[0] === "/config";
|
|
172
|
+
}
|
|
173
|
+
complete(ctx) {
|
|
174
|
+
const partial = ctx.partial;
|
|
175
|
+
const items = allConfigNames().map(({ name, def, alias }) => ({
|
|
176
|
+
value: name,
|
|
177
|
+
description: alias ? `${t("config.alias_label")} ${def.key}` : def.domain,
|
|
178
|
+
}));
|
|
179
|
+
if (!partial.includes(".")) {
|
|
180
|
+
const groups = [...new Set(canonicalKeys().filter((k) => k.includes(".")).map((k) => k.split(".")[0]))];
|
|
181
|
+
const groupItems = groups.map((g) => ({
|
|
182
|
+
value: g,
|
|
183
|
+
description: t("config.group_label"),
|
|
184
|
+
}));
|
|
185
|
+
return [...groupItems, ...items].filter((i) => i.value.startsWith(partial));
|
|
186
|
+
}
|
|
187
|
+
return items.filter((i) => i.value.startsWith(partial));
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
/** Дополняет enum-значения в позиции значения `/config <ключ> <значение>`. */
|
|
191
|
+
export class ConfigValueProvider {
|
|
192
|
+
name = "config-values";
|
|
193
|
+
match(ctx) {
|
|
194
|
+
return ctx.tokenIndex === 2 && ctx.tokens[0] === "/config";
|
|
195
|
+
}
|
|
196
|
+
complete(ctx) {
|
|
197
|
+
const def = resolveConfigKey(ctx.tokens[1]);
|
|
198
|
+
if (!def?.enumValues)
|
|
199
|
+
return [];
|
|
200
|
+
return def.enumValues
|
|
201
|
+
.filter((v) => v.startsWith(ctx.partial))
|
|
202
|
+
.map((v) => ({ value: v }));
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
/** Дополняет флаги `/provider add`. */
|
|
206
|
+
export class FlagProvider {
|
|
207
|
+
name = "provider-add-flags";
|
|
208
|
+
match(ctx) {
|
|
209
|
+
return ctx.tokens[0] === "/provider" && ctx.tokens[1] === "add" && ctx.tokenIndex >= 2;
|
|
210
|
+
}
|
|
211
|
+
complete(ctx) {
|
|
212
|
+
const flags = [
|
|
213
|
+
{ value: "--url", description: t("repl.provider_flag_url") },
|
|
214
|
+
{ value: "--key", description: t("repl.provider_flag_key") },
|
|
215
|
+
{ value: "--priority", description: t("repl.provider_flag_priority") },
|
|
216
|
+
{ value: "--context-window", description: t("repl.provider_flag_context_window") },
|
|
217
|
+
{ value: "--rpm", description: t("repl.provider_flag_rpm") },
|
|
218
|
+
{ value: "--parallel", description: t("repl.provider_flag_parallel") },
|
|
219
|
+
];
|
|
220
|
+
return flags.filter((f) => f.value.startsWith(ctx.partial));
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
/** Дополняет имена команд для `/help <команда>`. */
|
|
224
|
+
export class CommandArgProvider {
|
|
225
|
+
name = "help-command-args";
|
|
226
|
+
getNames;
|
|
227
|
+
constructor(getNames) {
|
|
228
|
+
this.getNames = getNames;
|
|
229
|
+
}
|
|
230
|
+
match(ctx) {
|
|
231
|
+
return ctx.tokenIndex === 1 && ctx.tokens[0] === "/help";
|
|
232
|
+
}
|
|
233
|
+
complete(ctx) {
|
|
234
|
+
return this.getNames()
|
|
235
|
+
.filter((n) => n.startsWith(ctx.partial))
|
|
236
|
+
.map((n) => ({ value: n }));
|
|
139
237
|
}
|
|
140
238
|
}
|
|
239
|
+
/** Комплитер: гоняет ввод через провайдеров, первый с хитами побеждает. */
|
|
141
240
|
export class Completer {
|
|
142
241
|
providers = [];
|
|
242
|
+
/** Регистрирует провайдера. */
|
|
143
243
|
registerProvider(provider) {
|
|
144
244
|
this.providers.push(provider);
|
|
145
245
|
}
|
|
146
|
-
/**
|
|
147
|
-
*
|
|
246
|
+
/** Сброс всех провайдеров — перед пересборкой (напр. /reload), чтобы
|
|
247
|
+
* перерегистрация не копила дубликаты. */
|
|
148
248
|
reset() {
|
|
149
249
|
this.providers = [];
|
|
150
250
|
}
|
|
251
|
+
/** Дополняет строку; возвращает [варианты, partial]. */
|
|
151
252
|
complete(line) {
|
|
152
253
|
const cursor = line.length;
|
|
153
254
|
const tokens = line.split(/\s+/);
|
package/dist/cli/index.js
CHANGED
package/dist/cli/json-payload.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* Машиночитаемый документ завершённого `--json`-прогона. Массив `diagnostics`
|
|
3
|
+
* несёт warn/error-события шины, погашенные человеческим каналом, чтобы
|
|
4
|
+
* машинный потребитель видел провалы проб/конфига/безопасности.
|
|
5
5
|
*/
|
|
6
6
|
export function buildJsonResult(result, diagnostics) {
|
|
7
7
|
return {
|
|
@@ -20,7 +20,7 @@ export function buildJsonResult(result, diagnostics) {
|
|
|
20
20
|
diagnostics,
|
|
21
21
|
};
|
|
22
22
|
}
|
|
23
|
-
/**
|
|
23
|
+
/** Документ провала для throw, так и не давшего `AgentResult`. */
|
|
24
24
|
export function buildJsonError(error, diagnostics = []) {
|
|
25
25
|
return {
|
|
26
26
|
success: false,
|
package/dist/cli/main.js
CHANGED
|
@@ -1,37 +1,64 @@
|
|
|
1
|
+
// Точка входа CLI: parse, one-shot/REPL/web-ветки, JSON-режим, автоапдейт.
|
|
1
2
|
import { createProgram } from "./commands";
|
|
2
3
|
import { bootstrap, setOneShotMode, applyReasoningCliOverride } from "../core/bootstrap";
|
|
3
4
|
import { Repl } from "./repl";
|
|
4
5
|
import { Renderer } from "../ui/renderer";
|
|
6
|
+
import { resolveVerbosity } from "../ui/theme";
|
|
5
7
|
import { printRunResult } from "./run-result";
|
|
6
8
|
import { runSetup } from "./setup";
|
|
9
|
+
import { runWeb, parsePort } from "./web-command";
|
|
7
10
|
import { applyAnswersToConfig } from "./setup-order";
|
|
8
11
|
import { relaunchCli } from "./relaunch";
|
|
9
12
|
import { defaultOutputBus, getDefaultChannel, JsonOutputSink, writeMachineJson } from "../output";
|
|
10
13
|
import { buildJsonError, buildJsonResult } from "./json-payload";
|
|
11
14
|
import { saveConfig, loadConfig } from "../config/config";
|
|
12
|
-
import { t } from "../i18n/index";
|
|
15
|
+
import { t, setLocale } from "../i18n/index";
|
|
13
16
|
import { pc } from "../ui/colors";
|
|
14
|
-
import { existsSync } from "fs";
|
|
17
|
+
import { existsSync, readFileSync } from "fs";
|
|
15
18
|
import { join, dirname } from "path";
|
|
16
|
-
import { homedir } from "os";
|
|
17
19
|
import { fileURLToPath } from "url";
|
|
18
20
|
import { UpdaterModule, isDevEntryPath } from "../modules/updater/index";
|
|
19
21
|
import { installCrashHandlers } from "../core/crash-handler";
|
|
20
22
|
import { readMmaVersion } from "../core/version";
|
|
21
23
|
import { closestCommand } from "./command-suggest";
|
|
22
24
|
import { errMsg } from "../utils";
|
|
25
|
+
import { globalMmaDir } from "../config/paths";
|
|
26
|
+
import { MMA_ENV, readEnv } from "../config/env";
|
|
23
27
|
/**
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* (
|
|
27
|
-
* `mma --json` (
|
|
28
|
+
* Взведён только для one-shot `--json`-прогонов (позиционный промпт есть). На уровне
|
|
29
|
+
* модуля, чтобы топ-уровневый `main().catch` отдал валидный документ, даже когда
|
|
30
|
+
* `bootstrap` (или что-то до JSON-ветки) бросил с пустым stdout. Интерактивный
|
|
31
|
+
* `mma --json` (без промпта) его не ставит, иначе краш REPL эмитил бы JSON.
|
|
28
32
|
*/
|
|
29
33
|
let jsonMode = false;
|
|
30
|
-
/**
|
|
34
|
+
/**
|
|
35
|
+
* Резолвит UI-локаль ДО `createProgram()`: описания команд и подсказка-тайпоупор
|
|
36
|
+
* строятся через `t()` в момент регистрации, так что установка локали только в
|
|
37
|
+
* bootstrap оставляла `--help` и near-miss хинты английскими при `locale: ru`.
|
|
38
|
+
* Дешёвое защитное чтение файла, не полный лоад конфига.
|
|
39
|
+
*/
|
|
40
|
+
function resolveEarlyLocale() {
|
|
41
|
+
const env = readEnv("LOCALE");
|
|
42
|
+
if (env)
|
|
43
|
+
return env;
|
|
44
|
+
const dir = globalMmaDir();
|
|
45
|
+
for (const p of [join(dir, "config", "core.json"), join(dir, "config.json")]) {
|
|
46
|
+
try {
|
|
47
|
+
const parsed = JSON.parse(readFileSync(p, "utf-8"));
|
|
48
|
+
if (typeof parsed.locale === "string")
|
|
49
|
+
return parsed.locale;
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
/* missing/invalid file — try the next candidate */
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
/** Fire-and-forget самоапдейт фоном (старт никогда не блокирует). */
|
|
31
58
|
function startAutoUpdate(config) {
|
|
32
|
-
// Dev
|
|
33
|
-
//
|
|
34
|
-
//
|
|
59
|
+
// Dev-прогоны грузят TypeScript-исходники; опубликованный бандл — dist/main.js.
|
|
60
|
+
// Из чекаута не автоапдейтимся: его package.json может отставать от npm, а
|
|
61
|
+
// global-install поверх юзерской установки деструктивен.
|
|
35
62
|
if (isDevEntryPath(fileURLToPath(import.meta.url)))
|
|
36
63
|
return undefined;
|
|
37
64
|
try {
|
|
@@ -44,20 +71,20 @@ function startAutoUpdate(config) {
|
|
|
44
71
|
return module;
|
|
45
72
|
}
|
|
46
73
|
catch {
|
|
47
|
-
//
|
|
74
|
+
// Автоапдейт best-effort; ронять старт ему нельзя.
|
|
48
75
|
return undefined;
|
|
49
76
|
}
|
|
50
77
|
}
|
|
51
78
|
async function main() {
|
|
52
|
-
//
|
|
53
|
-
// ~/.mma/logs/crash.jsonl (
|
|
79
|
+
// Глобальные краш-хендлеры первым делом: каждый краш ложится в
|
|
80
|
+
// ~/.mma/logs/crash.jsonl (с env-репортом), а не голым стеком в stderr.
|
|
54
81
|
installCrashHandlers();
|
|
55
|
-
//
|
|
56
|
-
//
|
|
57
|
-
//
|
|
58
|
-
//
|
|
59
|
-
// first channel use would have no terminal subscriber and be dropped.
|
|
82
|
+
// Канал-дефолт создаём жадно, чтобы подписался на `defaultOutputBus` ДО того, как
|
|
83
|
+
// конфиг/bootstrap что-то эмитит (варнинги конфига, сводка миграции, апдейтер).
|
|
84
|
+
// Канал ленив через `getDefaultChannel()`: без этого вызова каждое событие шины
|
|
85
|
+
// до первого использования канала осталось бы без терминального подписчика и дропнулось.
|
|
60
86
|
getDefaultChannel();
|
|
87
|
+
setLocale(resolveEarlyLocale() ?? "en");
|
|
61
88
|
const program = createProgram();
|
|
62
89
|
// Определяем подкоманду ДО parse: commander запускает async-action синхронно
|
|
63
90
|
// из parse(), поэтому флаг one-shot нужно выставить заранее, иначе bootstrap
|
|
@@ -76,49 +103,116 @@ async function main() {
|
|
|
76
103
|
firstPositional = a;
|
|
77
104
|
break;
|
|
78
105
|
}
|
|
79
|
-
|
|
106
|
+
const onboardingStart = firstPositional === "meet" ? "meet" : firstPositional === "agents" ? "init" : null;
|
|
107
|
+
if (firstPositional &&
|
|
108
|
+
!onboardingStart &&
|
|
109
|
+
program.commands.some((c) => c.name() === firstPositional)) {
|
|
80
110
|
setOneShotMode(true);
|
|
81
111
|
}
|
|
82
112
|
program.parse(process.argv);
|
|
83
113
|
const cmdNames = new Set(program.commands.map((c) => c.name()));
|
|
84
114
|
const opts = program.opts();
|
|
85
|
-
|
|
115
|
+
// commander превращает `--no-agents-md` в отрицаемый `agentsMd`-bool
|
|
116
|
+
// (дефолт true); ключа `noAgentsMd` нет.
|
|
117
|
+
const noAgentsMd = opts.agentsMd === false;
|
|
86
118
|
const projectDir = opts.dir;
|
|
87
119
|
const exitOnComplete = opts.exitOnComplete === true;
|
|
88
120
|
const jsonOpt = opts.json === true;
|
|
89
121
|
const reasoningLevel = opts.reasoning;
|
|
90
|
-
const
|
|
122
|
+
const verboseOpt = opts.verbose === true;
|
|
123
|
+
const contextLog = opts.contextLog === true;
|
|
124
|
+
// Quiet-чат прячет структурные info-логи; --verbose (или verbose-конфиг) их
|
|
125
|
+
// возвращает. Ставим до bootstrap, чтобы его собственные логи уважали флаг.
|
|
126
|
+
// Диагностика петли (`Logger.diagnostic`) следует тому же правилу видимости.
|
|
127
|
+
const applyLogVisibility = (verbose) => {
|
|
128
|
+
getDefaultChannel().setSuppressInfoLogs(!verbose);
|
|
129
|
+
getDefaultChannel().setShowDiagnostics(verbose);
|
|
130
|
+
};
|
|
131
|
+
applyLogVisibility(verboseOpt);
|
|
132
|
+
// `web` долгоживущий: его action — no-op, сервер стартует здесь, после parse,
|
|
133
|
+
// чтобы пережить one-shot exit-хук (на `web` в commands.ts он осознанно не вешается).
|
|
134
|
+
if (program.args[0] === "web") {
|
|
135
|
+
const webOpts = (program.commands.find((c) => c.name() === "web")?.opts() ?? {});
|
|
136
|
+
let port;
|
|
137
|
+
try {
|
|
138
|
+
port = parsePort(webOpts.port);
|
|
139
|
+
}
|
|
140
|
+
catch (err) {
|
|
141
|
+
getDefaultChannel().writeLine(pc.red(` ${errMsg(err)}`), "stderr");
|
|
142
|
+
process.exit(2);
|
|
143
|
+
}
|
|
144
|
+
await runWeb({
|
|
145
|
+
port,
|
|
146
|
+
host: webOpts.host,
|
|
147
|
+
token: webOpts.token,
|
|
148
|
+
noOpen: webOpts.open === false,
|
|
149
|
+
projectDir,
|
|
150
|
+
noAgentsMd,
|
|
151
|
+
});
|
|
152
|
+
process.exit(0);
|
|
153
|
+
}
|
|
154
|
+
const isSubcommand = program.args.length > 0 && cmdNames.has(program.args[0]) && !onboardingStart;
|
|
91
155
|
if (isSubcommand) {
|
|
92
156
|
return;
|
|
93
157
|
}
|
|
94
|
-
//
|
|
95
|
-
//
|
|
96
|
-
//
|
|
97
|
-
if (program.args.length > 0) {
|
|
158
|
+
// Тайпо-сторож: субкоманда с опечаткой не должна молча уходить в LLM как
|
|
159
|
+
// промпт ("mma sesion list" → чат). На near-miss известной команды — warn и выход;
|
|
160
|
+
// свободные промпты так не выглядят никогда.
|
|
161
|
+
if (program.args.length > 0 && !onboardingStart) {
|
|
98
162
|
const suggestion = closestCommand(program.args[0], [...cmdNames]);
|
|
99
163
|
if (suggestion && suggestion !== program.args[0]) {
|
|
100
164
|
getDefaultChannel().writeLine(pc.yellow(`${t("cli.unknown_command", { input: program.args[0], suggestion })}`), "stderr");
|
|
101
165
|
process.exit(2);
|
|
102
166
|
}
|
|
103
167
|
}
|
|
104
|
-
if (program.args.length > 0) {
|
|
105
|
-
// `--json`
|
|
106
|
-
//
|
|
107
|
-
//
|
|
108
|
-
//
|
|
109
|
-
//
|
|
110
|
-
//
|
|
111
|
-
// interactive REPL, so neither quiet nor the sink is set there.
|
|
168
|
+
if (program.args.length > 0 && !onboardingStart) {
|
|
169
|
+
// `--json` владеет stdout ТОЛЬКО в one-shot: гасим человеческий канал до
|
|
170
|
+
// bootstrap, чтобы варнинги конфига не запачкали машиночитаемый документ,
|
|
171
|
+
// и подписываем sink ДО bootstrap, чтобы warn/error bootstrap попали в
|
|
172
|
+
// captured-диагностику. Info-нотисы миграции осознанно не каптурятся
|
|
173
|
+
// (диагностика — только warn/error). Вызов без промпта (`mma --json`)
|
|
174
|
+
// открывает интерактивный REPL: ни quiet, ни sink там не ставятся.
|
|
112
175
|
if (jsonOpt) {
|
|
113
176
|
jsonMode = true;
|
|
114
177
|
getDefaultChannel().setQuiet(true);
|
|
115
178
|
}
|
|
116
179
|
const jsonSink = jsonOpt ? new JsonOutputSink(defaultOutputBus) : undefined;
|
|
117
180
|
const prompt = program.args.join(" ");
|
|
118
|
-
const
|
|
181
|
+
const mmaDir = globalMmaDir();
|
|
182
|
+
const { hasDomainFiles } = await import("../config/domains");
|
|
183
|
+
const virgin = !existsSync(join(mmaDir, "config.json")) && !hasDomainFiles(mmaDir);
|
|
184
|
+
const { agent, config, baseDir, legacyDetected, contextProbe } = await bootstrap(undefined, projectDir, noAgentsMd, exitOnComplete, reasoningLevel, contextLog);
|
|
185
|
+
if (verboseOpt)
|
|
186
|
+
config.ui.verbosity = "verbose";
|
|
187
|
+
applyLogVisibility(verboseOpt || config.ui.verbose || config.ui.verbosity === "verbose");
|
|
119
188
|
if (legacyDetected) {
|
|
120
189
|
getDefaultChannel().writeLine(pc.yellow(` ${t("config.legacy_hint")}`), "stderr");
|
|
121
190
|
}
|
|
191
|
+
if (virgin && !jsonOpt) {
|
|
192
|
+
getDefaultChannel().writeLine(pc.yellow(` ${t("cli.first_run_oneshot")}`), "stderr");
|
|
193
|
+
}
|
|
194
|
+
// Расхождение загруженного и настроенного контекста показываем и в one-shot
|
|
195
|
+
// (раньше только Repl.start() рендерил). Под --json скипаем.
|
|
196
|
+
if (contextProbe && !jsonOpt) {
|
|
197
|
+
try {
|
|
198
|
+
const probe = await contextProbe;
|
|
199
|
+
if (probe) {
|
|
200
|
+
if (probe.actual < config.contextWindow) {
|
|
201
|
+
getDefaultChannel().writeLine(pc.yellow(t("repl.context_probe_small", {
|
|
202
|
+
model: probe.model,
|
|
203
|
+
actual: String(probe.actual),
|
|
204
|
+
configured: String(config.contextWindow),
|
|
205
|
+
})));
|
|
206
|
+
}
|
|
207
|
+
else if (probe.actual > config.contextWindow) {
|
|
208
|
+
getDefaultChannel().writeLine(pc.dim(t("repl.context_probe_big", { model: probe.model, actual: String(probe.actual) })));
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
catch {
|
|
213
|
+
// best-effort.
|
|
214
|
+
}
|
|
215
|
+
}
|
|
122
216
|
const updater = exitOnComplete ? undefined : startAutoUpdate(config);
|
|
123
217
|
if (jsonMode) {
|
|
124
218
|
let result;
|
|
@@ -126,9 +220,9 @@ async function main() {
|
|
|
126
220
|
result = await agent.run(prompt);
|
|
127
221
|
}
|
|
128
222
|
catch (err) {
|
|
129
|
-
// --json
|
|
130
|
-
//
|
|
131
|
-
//
|
|
223
|
+
// --json не эмитит сырые стеки никогда: и AbortError, и рухнувший
|
|
224
|
+
// тул/плагин дают валидный машиночитаемый результат; shutdown/waitForIdle
|
|
225
|
+
// всё равно отрабатывают.
|
|
132
226
|
const message = errMsg(err);
|
|
133
227
|
agent.shutdown();
|
|
134
228
|
const diagnostics = jsonSink?.diagnostics() ?? [];
|
|
@@ -144,12 +238,13 @@ async function main() {
|
|
|
144
238
|
await updater?.waitForIdle(10_000);
|
|
145
239
|
process.exit(result.success ? 0 : 1);
|
|
146
240
|
}
|
|
147
|
-
// TODO(output): one-shot
|
|
148
|
-
// (
|
|
149
|
-
//
|
|
241
|
+
// TODO(output): one-shot прогоны не показывают варнинг контекст-пробника
|
|
242
|
+
// (рендерит только Repl.start()). Показать здесь, когда bootstrap отдаст
|
|
243
|
+
// результат пробника в эту ветку.
|
|
150
244
|
const renderer = new Renderer({
|
|
151
245
|
spinner: config.ui?.spinner ?? true,
|
|
152
246
|
baseDir,
|
|
247
|
+
verbosity: resolveVerbosity(config.ui),
|
|
153
248
|
});
|
|
154
249
|
renderer.showLoader();
|
|
155
250
|
let result;
|
|
@@ -168,11 +263,11 @@ async function main() {
|
|
|
168
263
|
else {
|
|
169
264
|
renderer.thinkingEnd();
|
|
170
265
|
}
|
|
171
|
-
});
|
|
266
|
+
}, (reasoning) => renderer.reasoning(reasoning));
|
|
172
267
|
}
|
|
173
268
|
catch (err) {
|
|
174
|
-
//
|
|
175
|
-
//
|
|
269
|
+
// Throw из цикла агента не должен скипать shutdown/updater или дампить
|
|
270
|
+
// голый стек: показываем как чистый error-результат.
|
|
176
271
|
result = {
|
|
177
272
|
success: false,
|
|
178
273
|
text: "",
|
|
@@ -190,7 +285,11 @@ async function main() {
|
|
|
190
285
|
process.exit(exitCode);
|
|
191
286
|
}
|
|
192
287
|
else {
|
|
193
|
-
|
|
288
|
+
if (onboardingStart === "meet")
|
|
289
|
+
process.env[MMA_ENV.START_MEET] = "1";
|
|
290
|
+
if (onboardingStart === "init")
|
|
291
|
+
process.env[MMA_ENV.START_INIT] = "1";
|
|
292
|
+
const mmaDir = globalMmaDir();
|
|
194
293
|
const legacyConfigPath = join(mmaDir, "config.json");
|
|
195
294
|
let hasAnyConfig = existsSync(legacyConfigPath);
|
|
196
295
|
if (!hasAnyConfig) {
|
|
@@ -198,38 +297,43 @@ async function main() {
|
|
|
198
297
|
const { hasDomainFiles } = await import("../config/domains");
|
|
199
298
|
hasAnyConfig = hasDomainFiles(mmaDir);
|
|
200
299
|
}
|
|
201
|
-
catch {
|
|
300
|
+
catch {
|
|
301
|
+
// Пробник доменов best-effort: отсутствующий/битый модуль не блокирует
|
|
302
|
+
// CLI. Фолбэк — проверка legacy config.json выше.
|
|
303
|
+
}
|
|
202
304
|
}
|
|
203
305
|
const projectConfigPath = projectDir ? join(projectDir, ".mmrc") : join(process.cwd(), ".mmrc");
|
|
204
|
-
//
|
|
205
|
-
//
|
|
206
|
-
//
|
|
207
|
-
//
|
|
208
|
-
//
|
|
209
|
-
//
|
|
210
|
-
//
|
|
211
|
-
if (!hasAnyConfig && !exitOnComplete &&
|
|
212
|
-
getDefaultChannel().writeLine(
|
|
306
|
+
// Первый запуск: собираем настройки, персистим, затем ПЕРЕИСПОЛНЯЕМ CLI в свежем
|
|
307
|
+
// процессе и выходим. Визард и REPL не делят процесс: на Bun/Windows raw-режимный
|
|
308
|
+
// LineEditor получает keypress, только будучи первым потребителем stdin, а
|
|
309
|
+
// переиспользование одного редактора через wizard → bootstrap → REPL протекает
|
|
310
|
+
// состоянием промпта/кадра. Перезапущенный процесс видит сохранённый конфиг,
|
|
311
|
+
// скипает визард и создаёт редактор первым делом. `MMA_POST_SETUP=1` сторожит
|
|
312
|
+
// от петли перезапуска.
|
|
313
|
+
if (!hasAnyConfig && !exitOnComplete && readEnv("POST_SETUP") !== "1") {
|
|
314
|
+
getDefaultChannel().writeLine(`\n ${t("cli.first_run")}\n`);
|
|
213
315
|
const answers = await runSetup();
|
|
214
316
|
const { config } = loadConfig({ configDir: mmaDir, projectConfigPath });
|
|
215
|
-
//
|
|
216
|
-
//
|
|
217
|
-
// config).
|
|
317
|
+
// Сохраняем CLI-оверрайд --reasoning (bootstrap в свежем процессе применил бы
|
|
318
|
+
// его тоже, но персистим сейчас, чтобы ребёнок прочитал финальный конфиг).
|
|
218
319
|
applyReasoningCliOverride(config, reasoningLevel);
|
|
219
320
|
applyAnswersToConfig(config, answers);
|
|
220
321
|
saveConfig(config, legacyConfigPath, dirname(legacyConfigPath));
|
|
221
322
|
getDefaultChannel().writeLine(pc.dim(` ${t("cli.setup_saved_restart")}`));
|
|
222
323
|
relaunchCli();
|
|
223
324
|
}
|
|
224
|
-
const { agent, config, sessionManager, skillsModule, pluginManager, execModule, configDir, baseDir, logger, envReport, contextProbe, } = await bootstrap(undefined, projectDir, noAgentsMd, exitOnComplete, reasoningLevel);
|
|
325
|
+
const { agent, config, sessionManager, skillsModule, pluginManager, execModule, configDir, baseDir, logger, envReport, contextProbe, } = await bootstrap(undefined, projectDir, noAgentsMd, exitOnComplete, reasoningLevel, contextLog);
|
|
326
|
+
if (verboseOpt)
|
|
327
|
+
config.ui.verbosity = "verbose";
|
|
328
|
+
applyLogVisibility(verboseOpt || config.ui.verbose || config.ui.verbosity === "verbose");
|
|
225
329
|
const repl = new Repl(agent, config, sessionManager, skillsModule, pluginManager, configDir, baseDir, noAgentsMd, logger, true, envReport, undefined, execModule, contextProbe);
|
|
226
330
|
startAutoUpdate(config);
|
|
227
331
|
await repl.start();
|
|
228
332
|
}
|
|
229
333
|
}
|
|
230
334
|
main().catch((err) => {
|
|
231
|
-
//
|
|
232
|
-
//
|
|
335
|
+
// Throw до/во время bootstrap иначе оставил бы `--json`-вызывающих с пустым
|
|
336
|
+
// stdout; эмитим валидный failure-документ вместо человеческого стека.
|
|
233
337
|
if (jsonMode) {
|
|
234
338
|
writeMachineJson(buildJsonError(errMsg(err)));
|
|
235
339
|
}
|
|
@@ -238,4 +342,5 @@ main().catch((err) => {
|
|
|
238
342
|
}
|
|
239
343
|
process.exit(1);
|
|
240
344
|
});
|
|
345
|
+
/** Точка входа CLI (диспатч веток + топ-уровневый catch для `--json`). */
|
|
241
346
|
export { main };
|