micro-models-agent 2.11.0 → 2.13.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +39 -0
- package/dist/assets/app.js +22 -2
- package/dist/assets/index.html +39 -9
- package/dist/assets/js/dom.js +15 -0
- package/dist/assets/js/feed.js +129 -10
- package/dist/assets/js/sidebar.js +512 -0
- package/dist/assets/js/tabs.js +30 -5
- package/dist/assets/setup.js +267 -8
- package/dist/assets/styles.css +168 -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/en.json +89 -3
- package/dist/i18n/index.js +37 -3
- package/dist/i18n/ru.json +89 -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 +888 -139
- 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/ui/line-math.js
CHANGED
|
@@ -1,15 +1,19 @@
|
|
|
1
|
+
// Математика строк редактора: ANSI-стрип, перенос по ширине, буфер↔экран маппинг.
|
|
1
2
|
import stringWidth from "string-width";
|
|
2
3
|
const ANSI_RE = /\x1b\[[0-9;?]*[ -/]*[@-~]/g;
|
|
4
|
+
/** Срезает ANSI-последовательности. */
|
|
3
5
|
export function stripAnsi(s) {
|
|
4
6
|
return s.replace(ANSI_RE, "");
|
|
5
7
|
}
|
|
8
|
+
/** Длина в символах (не в байтах/ячейках). */
|
|
6
9
|
export function charLen(s) {
|
|
7
10
|
return Array.from(s).length;
|
|
8
11
|
}
|
|
12
|
+
/** Перенос строки по ширине (по словам, CJK-корректно). */
|
|
9
13
|
export function wrapLine(line, width, firstRowWidth) {
|
|
10
14
|
const w = width > 0 ? width : 80;
|
|
11
|
-
//
|
|
12
|
-
// (
|
|
15
|
+
// Только ПЕРВАЯ визуальная строка делит экранную строку с чем-то ещё
|
|
16
|
+
// (напр. с промптом); все продолжения — на полную ширину.
|
|
13
17
|
let limit = firstRowWidth !== undefined && firstRowWidth > 0 ? firstRowWidth : w;
|
|
14
18
|
const chars = Array.from(line);
|
|
15
19
|
const rows = [];
|
|
@@ -54,6 +58,7 @@ export function wrapLine(line, width, firstRowWidth) {
|
|
|
54
58
|
rows.push({ text: chars.slice(start).join(""), charStart: start });
|
|
55
59
|
return rows;
|
|
56
60
|
}
|
|
61
|
+
/** Раскладка всех строк буфера в визуальные ряды. */
|
|
57
62
|
export function buildLayout(lines, width, firstRowWidth) {
|
|
58
63
|
const rows = [];
|
|
59
64
|
for (let b = 0; b < lines.length; b++) {
|
|
@@ -63,6 +68,7 @@ export function buildLayout(lines, width, firstRowWidth) {
|
|
|
63
68
|
}
|
|
64
69
|
return rows;
|
|
65
70
|
}
|
|
71
|
+
/** Индекс визуального ряда по позиции буфера. */
|
|
66
72
|
export function layoutIndexFor(rows, bufRow, col) {
|
|
67
73
|
let idx = 0;
|
|
68
74
|
for (let i = 0; i < rows.length; i++) {
|
|
@@ -71,11 +77,13 @@ export function layoutIndexFor(rows, bufRow, col) {
|
|
|
71
77
|
}
|
|
72
78
|
return idx;
|
|
73
79
|
}
|
|
80
|
+
/** Визуальная колонка по смещению в буфере. */
|
|
74
81
|
export function visualColAt(rows, idx, col) {
|
|
75
82
|
const r = rows[idx];
|
|
76
83
|
const upTo = col - r.charStart;
|
|
77
84
|
return stringWidth(Array.from(r.text).slice(0, upTo).join(""));
|
|
78
85
|
}
|
|
86
|
+
/** Смещение в буфере по визуальной колонке. */
|
|
79
87
|
export function charOffsetFor(rows, idx, visualCol) {
|
|
80
88
|
const r = rows[idx];
|
|
81
89
|
const chars = Array.from(r.text);
|
package/dist/ui/md-formatter.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
// Markdown-форматтер чата: стриминг строк, подсветка кода, таблицы (см. STYLE.md).
|
|
1
2
|
import { pc } from "./colors";
|
|
2
3
|
import stringWidth from "string-width";
|
|
3
4
|
import { t } from "../i18n/index";
|
|
4
5
|
import { formatTable, getTerminalWidth } from "./table";
|
|
6
|
+
import { glyph } from "./theme";
|
|
5
7
|
const KW = /\b(import|export|from|const|let|var|function|return|if|else|for|while|do|switch|case|break|continue|new|class|extends|implements|interface|type|enum|namespace|module|declare|abstract|async|await|yield|throw|try|catch|finally|typeof|instanceof|in|of|as|is|keyof|readonly|static|private|public|protected|get|set|constructor|this|super|void|never|any|unknown|boolean|string|number|symbol|object|true|false|null|undefined|default)\b/g;
|
|
6
8
|
const STRING = /('[^']*'|"[^"]*"|`[^`]*`)/g;
|
|
7
9
|
const COMMENT = /(\/\/[^\n]*|\/\*[\s\S]*?\*\/|#[^\n]*)/g;
|
|
@@ -11,8 +13,8 @@ const ATTR = /\b([a-zA-Z-]+=)"([^"]*)"/g;
|
|
|
11
13
|
function highlight(code, lang) {
|
|
12
14
|
if (lang === "html" || lang === "xml" || lang === "svg") {
|
|
13
15
|
code = code.replace(COMMENT, (m) => pc.dim(pc.green(m)));
|
|
14
|
-
code = code.replace(ATTR, (_m, attr, val) => pc.yellow(attr)
|
|
15
|
-
code = code.replace(TAG, (_m, tag) =>
|
|
16
|
+
code = code.replace(ATTR, (_m, attr, val) => `${pc.yellow(attr)}=${pc.green(`"${val}"`)}`);
|
|
17
|
+
code = code.replace(TAG, (_m, tag) => `<${pc.cyan(tag)}`);
|
|
16
18
|
}
|
|
17
19
|
else if (lang === "css" || lang === "scss" || lang === "less") {
|
|
18
20
|
code = code.replace(COMMENT, (m) => pc.dim(pc.green(m)));
|
|
@@ -46,6 +48,7 @@ function isTableRow(line) {
|
|
|
46
48
|
function isHorizontalRule(line) {
|
|
47
49
|
return /^(-{3,}|\*{3,}|_{3,})\s*$/.test(line.trim());
|
|
48
50
|
}
|
|
51
|
+
/** Стриминговый форматтер markdown в терминальные строки. */
|
|
49
52
|
export class FormattingStream {
|
|
50
53
|
buffer = "";
|
|
51
54
|
inCodeBlock = false;
|
|
@@ -55,15 +58,15 @@ export class FormattingStream {
|
|
|
55
58
|
onWrite;
|
|
56
59
|
onRawWrite;
|
|
57
60
|
width;
|
|
58
|
-
/**
|
|
61
|
+
/** Колонок сырого партиала, показанного сейчас в терминале. */
|
|
59
62
|
partialWritten = 0;
|
|
60
|
-
/**
|
|
63
|
+
/** Сколько символов pending-строки уже стримлено сырьём. */
|
|
61
64
|
streamedChars = 0;
|
|
62
|
-
/**
|
|
65
|
+
/** Колонок зарезервировано слева (префикс вызывающего), чтобы партиал не враппился. */
|
|
63
66
|
reservedCols;
|
|
64
67
|
/**
|
|
65
|
-
*
|
|
66
|
-
*
|
|
68
|
+
* Стрим текущей (ещё не завершённой переводом строки) строки сырьём для живого
|
|
69
|
+
* фидбэка. По умолчанию выкл; офлайн-вызывающие используют `formatMarkdown`.
|
|
67
70
|
*/
|
|
68
71
|
streamPartials;
|
|
69
72
|
constructor(onWrite, width, onRawWrite, opts = {}) {
|
|
@@ -87,16 +90,15 @@ export class FormattingStream {
|
|
|
87
90
|
}
|
|
88
91
|
}
|
|
89
92
|
/**
|
|
90
|
-
*
|
|
91
|
-
*
|
|
93
|
+
* Стримит pending-строку сырьём для real-time фидбэка; форматированная строка
|
|
94
|
+
* заменяет её по приходу перевода строки.
|
|
92
95
|
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
* line is rendered when it completes.
|
|
96
|
+
* Замена — ОТНОСИТЕЛЬНЫМ движением курсора (`\x1b[<cols>D`), корректным лишь
|
|
97
|
+
* пока стримленный текст сидит на одной визуальной строке, с которой начал.
|
|
98
|
+
* Если партиал шире терминала, он враппится и каждый относительный сдвиг бьёт
|
|
99
|
+
* мимо — та самая битая выдача после рефактора вывода 1.0.0 (потерянные/
|
|
100
|
+
* переставленные символы, потёкшие маркеры, ломаные таблицы). Поэтому стрим
|
|
101
|
+
* замирает на последнем влезшем чанке, а строка рендерится по завершении.
|
|
100
102
|
*/
|
|
101
103
|
streamPartial() {
|
|
102
104
|
if (!this.streamPartials)
|
|
@@ -113,36 +115,36 @@ export class FormattingStream {
|
|
|
113
115
|
}
|
|
114
116
|
emitPartialRewind() {
|
|
115
117
|
if (this.partialWritten > 0) {
|
|
116
|
-
//
|
|
117
|
-
//
|
|
118
|
+
// Откат поверх стримленного партиала + стереть хвост, оставшийся от более
|
|
119
|
+
// короткой форматированной замены, до рендера строки вызывающим.
|
|
118
120
|
this.onRawWrite(`\x1b[${this.partialWritten}D\x1b[K`);
|
|
119
121
|
this.partialWritten = 0;
|
|
120
122
|
}
|
|
121
123
|
this.streamedChars = 0;
|
|
122
124
|
}
|
|
123
|
-
/**
|
|
125
|
+
/** Есть ли показанный партиал или необработанный буфер. @internal */
|
|
124
126
|
hasPartial() {
|
|
125
127
|
return this.partialWritten > 0 || this.buffer.length > 0 || this.tableBuffer.length > 0;
|
|
126
128
|
}
|
|
127
129
|
/**
|
|
128
|
-
*
|
|
129
|
-
*
|
|
130
|
-
* `onRawWrite`);
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
*
|
|
130
|
+
* Финализирует показанный сырой партиал, чтобы следующая запись началась с новой строки.
|
|
131
|
+
* Терминируется только уже стримленный партиал (одиночный перевод строки через
|
|
132
|
+
* `onRawWrite`); pending-буфер таблицы сбрасывается. Открытый кодовый блок
|
|
133
|
+
* осознанно не трогается: закрытие здесь сделало бы настоящий закрывающий fence
|
|
134
|
+
* похожим на новый открывающий и испортило бы всю прозу дальше. Блок эмитит
|
|
135
|
+
* финальный `flush()`. Идемпотентно.
|
|
134
136
|
*/
|
|
135
137
|
flushPartialNow() {
|
|
136
138
|
if (this.partialWritten > 0) {
|
|
137
|
-
//
|
|
138
|
-
//
|
|
139
|
+
// Строка уже на экране сырьём; терминируем как есть (может быть оборвана
|
|
140
|
+
// посреди markdown) и дропаем, чтобы не отрендерить дважды.
|
|
139
141
|
this.onRawWrite("\n");
|
|
140
142
|
this.partialWritten = 0;
|
|
141
143
|
this.streamedChars = 0;
|
|
142
144
|
this.buffer = "";
|
|
143
145
|
}
|
|
144
146
|
else if (this.buffer.length > 0 && !this.inCodeBlock) {
|
|
145
|
-
//
|
|
147
|
+
// Не стримлено (plain-режим) — рендерим pending-строку сейчас.
|
|
146
148
|
const line = this.buffer;
|
|
147
149
|
this.buffer = "";
|
|
148
150
|
this.streamedChars = 0;
|
|
@@ -158,8 +160,15 @@ export class FormattingStream {
|
|
|
158
160
|
}
|
|
159
161
|
if (this.inCodeBlock) {
|
|
160
162
|
if (this.buffer.length > 0) {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
+
// Закрывающий fence в EOF без trailing newline: считаем закрытием, а не
|
|
164
|
+
// контентом кода (иначе "```" потечёт в блок).
|
|
165
|
+
if (this.buffer.trim().startsWith("```")) {
|
|
166
|
+
this.buffer = "";
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
this.codeLines.push(this.buffer);
|
|
170
|
+
this.buffer = "";
|
|
171
|
+
}
|
|
163
172
|
}
|
|
164
173
|
if (this.codeLines.length > 0) {
|
|
165
174
|
this.emitCodeBlock();
|
|
@@ -181,6 +190,10 @@ export class FormattingStream {
|
|
|
181
190
|
this.emitCodeBlock();
|
|
182
191
|
}
|
|
183
192
|
else {
|
|
193
|
+
// Pending-таблица не должна эмититься ПОСЛЕ идущего за ней кодового блока:
|
|
194
|
+
// сбрасываем до входа в fence.
|
|
195
|
+
if (this.tableBuffer.length > 0)
|
|
196
|
+
this.flushTable();
|
|
184
197
|
this.inCodeBlock = true;
|
|
185
198
|
this.codeLang = line.trim().slice(3).trim();
|
|
186
199
|
this.codeLines = [];
|
|
@@ -220,19 +233,19 @@ export class FormattingStream {
|
|
|
220
233
|
if (this.codeLines.length > 0) {
|
|
221
234
|
const code = this.codeLines.join("\n");
|
|
222
235
|
const highlighted = highlight(code, this.codeLang);
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
this.
|
|
236
|
+
// Без рамки: только dim-ярлык языка и левый гуттер. Коробочные кодовые
|
|
237
|
+
// блоки запрещены стилем чата (docs/design/ui/STYLE.md).
|
|
238
|
+
if (this.codeLang)
|
|
239
|
+
this.onWrite(pc.dim(` ${this.codeLang}`));
|
|
226
240
|
for (const l of highlighted.split("\n")) {
|
|
227
|
-
this.onWrite(pc.dim(
|
|
241
|
+
this.onWrite(pc.dim(`${glyph.group} `) + l);
|
|
228
242
|
}
|
|
229
|
-
this.onWrite(pc.dim(`└${"─".repeat(Math.max(0, this.width - 1))}┘`));
|
|
230
243
|
}
|
|
231
244
|
this.codeLines = [];
|
|
232
245
|
this.codeLang = "";
|
|
233
246
|
}
|
|
234
247
|
formatLine(line) {
|
|
235
|
-
|
|
248
|
+
const result = line;
|
|
236
249
|
const heading = result.match(/^(#{1,6})\s+(.+)$/);
|
|
237
250
|
if (heading) {
|
|
238
251
|
const level = heading[1].length;
|
|
@@ -272,18 +285,22 @@ export class FormattingStream {
|
|
|
272
285
|
codeSpans.push(pc.yellow(c));
|
|
273
286
|
return `\u0000${codeSpans.length - 1}\u0000`;
|
|
274
287
|
});
|
|
288
|
+
// `***text***` (bold+italic) до одиночных `**`/`*`, иначе вложенность
|
|
289
|
+
// рвётся и во вложении остаётся висящая звёздочка.
|
|
290
|
+
result = result.replace(/\*\*\*(.+?)\*\*\*/g, (_, s) => pc.bold(pc.italic(s)));
|
|
275
291
|
result = result.replace(/\*\*(.+?)\*\*/g, (_, s) => pc.bold(s));
|
|
276
292
|
result = result.replace(/~~(.+?)~~/g, (_, s) => pc.strikethrough(s));
|
|
277
293
|
result = result.replace(/\*([^*]+)\*/g, (_, s) => pc.italic(s));
|
|
278
294
|
result = result.replace(/(^|\s)_([^_\n]+)_(?=\s|$)/g, (_m, pre, s) => pre + pc.italic(s));
|
|
279
295
|
result = result.replace(/\[([^\]]+)\]\(([^)]+)\)/g, (_, label, url) => {
|
|
280
|
-
const short = url.length > 80 ? url.slice(0, 77)
|
|
296
|
+
const short = url.length > 80 ? `${url.slice(0, 77)}…` : url;
|
|
281
297
|
return `${pc.cyan(label)} ${pc.dim(`(${short})`)}`;
|
|
282
298
|
});
|
|
283
299
|
result = result.replace(/\u0000(\d+)\u0000/g, (_m, i) => codeSpans[Number(i)]);
|
|
284
300
|
return result;
|
|
285
301
|
}
|
|
286
302
|
}
|
|
303
|
+
/** Форматирует markdown-текст целиком в терминальные строки. */
|
|
287
304
|
export function formatMarkdown(text) {
|
|
288
305
|
const lines = [];
|
|
289
306
|
const stream = new FormattingStream((l) => lines.push(l));
|
|
@@ -291,12 +308,15 @@ export function formatMarkdown(text) {
|
|
|
291
308
|
stream.flush();
|
|
292
309
|
return lines.join("\n");
|
|
293
310
|
}
|
|
311
|
+
/** Форматирует ошибку (красный префикс из i18n). */
|
|
294
312
|
export function formatError(text) {
|
|
295
313
|
return pc.red(pc.bold(t("ui.error_prefix")) + text);
|
|
296
314
|
}
|
|
315
|
+
/** Форматирует успех (зелёный префикс из i18n). */
|
|
297
316
|
export function formatSuccess(text) {
|
|
298
317
|
return pc.green(pc.bold(t("ui.success_prefix")) + text);
|
|
299
318
|
}
|
|
319
|
+
/** Форматирует предупреждение (жёлтый префикс из i18n). */
|
|
300
320
|
export function formatWarning(text) {
|
|
301
321
|
return pc.yellow(pc.bold(t("ui.warning_prefix")) + text);
|
|
302
322
|
}
|
package/dist/ui/output.js
CHANGED
|
@@ -1,14 +1,19 @@
|
|
|
1
|
+
// Короткие писатели в канал: markdown/ошибка/успех/предупреждение.
|
|
1
2
|
import { getDefaultChannel } from "../output";
|
|
2
3
|
import { formatMarkdown, formatError, formatSuccess, formatWarning } from "./md-formatter";
|
|
4
|
+
/** Пишет markdown-текст в stdout. */
|
|
3
5
|
export function writeOutput(text) {
|
|
4
|
-
getDefaultChannel().writeRaw(formatMarkdown(text)
|
|
6
|
+
getDefaultChannel().writeRaw(`${formatMarkdown(text)}\n`);
|
|
5
7
|
}
|
|
8
|
+
/** Пишет ошибку в stderr. */
|
|
6
9
|
export function writeError(text) {
|
|
7
|
-
getDefaultChannel().writeRaw(formatError(text)
|
|
10
|
+
getDefaultChannel().writeRaw(`${formatError(text)}\n`, "stderr");
|
|
8
11
|
}
|
|
12
|
+
/** Пишет успех в stdout. */
|
|
9
13
|
export function writeSuccess(text) {
|
|
10
|
-
getDefaultChannel().writeRaw(formatSuccess(text)
|
|
14
|
+
getDefaultChannel().writeRaw(`${formatSuccess(text)}\n`);
|
|
11
15
|
}
|
|
16
|
+
/** Пишет предупреждение блочной строкой. */
|
|
12
17
|
export function writeWarning(text) {
|
|
13
18
|
getDefaultChannel().writeLine(formatWarning(text));
|
|
14
19
|
}
|
package/dist/ui/plan-view.js
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
|
+
// Вид плана в чате: чтение active.json, чеклист с прогресс-баром, контекст шага.
|
|
1
2
|
import { existsSync, readFileSync } from "fs";
|
|
2
3
|
import { join } from "path";
|
|
3
4
|
import { pc } from "./colors";
|
|
5
|
+
import { glyph } from "./theme";
|
|
4
6
|
import { extractFileLikeTokens, stripUrls } from "../modules/hallucination/js-identifiers";
|
|
5
7
|
import { t } from "../i18n/index";
|
|
8
|
+
import { projectMmaDir } from "../config/paths";
|
|
9
|
+
/** Читает активный план из .mma/plans/active.json. Нет/бит — null. */
|
|
6
10
|
export function readActivePlan(baseDir) {
|
|
7
|
-
const p = join(baseDir, "
|
|
11
|
+
const p = join(projectMmaDir(baseDir), "plans", "active.json");
|
|
8
12
|
if (!existsSync(p))
|
|
9
13
|
return null;
|
|
10
14
|
try {
|
|
@@ -27,34 +31,36 @@ export function readActivePlan(baseDir) {
|
|
|
27
31
|
return null;
|
|
28
32
|
}
|
|
29
33
|
}
|
|
34
|
+
/** Индекс текущего шага (первый не done/skipped). */
|
|
30
35
|
export function currentStepIndex(plan) {
|
|
31
36
|
return plan.steps.findIndex((s) => s.status !== "done" && s.status !== "skipped");
|
|
32
37
|
}
|
|
33
38
|
function stepMark(step) {
|
|
34
39
|
switch (step.status) {
|
|
35
40
|
case "done":
|
|
36
|
-
return pc.green(
|
|
41
|
+
return pc.green(glyph.success);
|
|
37
42
|
case "in_progress":
|
|
38
|
-
return pc.
|
|
43
|
+
return pc.cyan(glyph.action);
|
|
39
44
|
case "failed":
|
|
40
|
-
return pc.red(
|
|
45
|
+
return pc.red(glyph.failure);
|
|
41
46
|
case "skipped":
|
|
42
|
-
return pc.dim("
|
|
47
|
+
return pc.dim("–");
|
|
43
48
|
default:
|
|
44
|
-
return pc.dim("
|
|
49
|
+
return pc.dim("○");
|
|
45
50
|
}
|
|
46
51
|
}
|
|
52
|
+
/** Рендерит чеклист плана с прогресс-баром ▰▱ построчно. */
|
|
47
53
|
export function formatPlanChecklist(plan) {
|
|
48
54
|
const done = plan.steps.filter((s) => s.status === "done" || s.status === "skipped").length;
|
|
49
55
|
const total = plan.steps.length;
|
|
50
56
|
const pct = total === 0 ? 0 : Math.round((done / total) * 100);
|
|
51
57
|
const cur = currentStepIndex(plan);
|
|
52
|
-
const barLen =
|
|
58
|
+
const barLen = 10;
|
|
53
59
|
const filled = Math.round((pct / 100) * barLen);
|
|
54
|
-
const bar = pc.green("
|
|
60
|
+
const bar = pc.green("▰".repeat(filled)) + pc.dim("▱".repeat(barLen - filled));
|
|
55
61
|
const title = plan.title.replace(/^\[\d+[^]]*\]\s*/, "");
|
|
56
62
|
const lines = [
|
|
57
|
-
`${pc.cyan(
|
|
63
|
+
`${pc.cyan(glyph.action)} ${pc.bold(title)} ${bar} ${pc.dim(`${done}/${total}`)}`,
|
|
58
64
|
];
|
|
59
65
|
for (let i = 0; i < plan.steps.length; i++) {
|
|
60
66
|
const step = plan.steps[i];
|
|
@@ -62,13 +68,14 @@ export function formatPlanChecklist(plan) {
|
|
|
62
68
|
const desc = active ? pc.yellow(step.description) : pc.dim(step.description);
|
|
63
69
|
lines.push(` ${stepMark(step)} ${step.id}. ${desc}`);
|
|
64
70
|
for (const sub of step.subtasks ?? []) {
|
|
65
|
-
lines.push(` ${sub.done ? pc.green(
|
|
71
|
+
lines.push(` ${sub.done ? pc.green(glyph.success) : pc.dim("○")} [${sub.id}] ${sub.text}`);
|
|
66
72
|
}
|
|
67
73
|
}
|
|
68
74
|
return lines;
|
|
69
75
|
}
|
|
70
76
|
const STRUCTURAL_TOOLS = new Set([
|
|
71
77
|
"plan",
|
|
78
|
+
"plan_step",
|
|
72
79
|
"todo",
|
|
73
80
|
"verify",
|
|
74
81
|
"project_map",
|
|
@@ -78,6 +85,10 @@ const STRUCTURAL_TOOLS = new Set([
|
|
|
78
85
|
function truncate(s, max = 48) {
|
|
79
86
|
return s.length > max ? `${s.slice(0, max - 1)}…` : s;
|
|
80
87
|
}
|
|
88
|
+
/**
|
|
89
|
+
* Подбирает шаг плана под вызов тула по файловым токенам аргументов.
|
|
90
|
+
* Структурные тулы и вызовы без путей — null.
|
|
91
|
+
*/
|
|
81
92
|
export function stepContextForTool(plan, tool, args) {
|
|
82
93
|
if (!plan || STRUCTURAL_TOOLS.has(tool))
|
|
83
94
|
return null;
|