micro-models-agent 2.16.1 → 2.17.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 +28 -0
- package/dist/assets/app.js +1 -314
- package/dist/assets/hljs.js +5 -1244
- package/dist/assets/index.html +11 -0
- package/dist/assets/js/api.js +1 -28
- package/dist/assets/js/core/menus.js +1 -0
- package/dist/assets/js/core/store/feed.js +1 -0
- package/dist/assets/js/core/store/index.js +1 -0
- package/dist/assets/js/core/store/session.js +1 -0
- package/dist/assets/js/core/store/settings.js +1 -0
- package/dist/assets/js/core/store/tabs.js +1 -0
- package/dist/assets/js/dialog.js +1 -105
- package/dist/assets/js/dom.js +1 -178
- package/dist/assets/js/feed/core.js +1 -0
- package/dist/assets/js/feed/history.js +1 -0
- package/dist/assets/js/feed/plan.js +1 -0
- package/dist/assets/js/feed/question.js +3 -0
- package/dist/assets/js/feed/sidebar.js +1 -0
- package/dist/assets/js/feed/stream.js +1 -0
- package/dist/assets/js/feed/turn.js +5 -0
- package/dist/assets/js/feed.js +1 -1250
- package/dist/assets/js/format.js +2 -122
- package/dist/assets/js/i18n.js +1 -46
- package/dist/assets/js/rail.js +1 -114
- package/dist/assets/js/session/cmdk.js +1 -0
- package/dist/assets/js/session/composer.js +1 -0
- package/dist/assets/js/session/sessions-menu.js +1 -0
- package/dist/assets/js/session/tabs.js +1 -0
- package/dist/assets/js/settings/controls.js +1 -0
- package/dist/assets/js/settings/editors.js +1 -0
- package/dist/assets/js/settings/form.js +1 -0
- package/dist/assets/js/settings/modal.js +1 -0
- package/dist/assets/js/settings/panels.js +1 -0
- package/dist/assets/js/settings/providers.js +1 -0
- package/dist/assets/js/settings/search.js +1 -0
- package/dist/assets/js/settings/subdialog.js +1 -0
- package/dist/assets/js/settings/write.js +1 -0
- package/dist/assets/js/settings.js +1 -1914
- package/dist/assets/js/sidebar/core.js +1 -0
- package/dist/assets/js/sidebar/lsp.js +2 -0
- package/dist/assets/js/sidebar/map.js +1 -0
- package/dist/assets/js/sidebar/state.js +1 -0
- package/dist/assets/js/sidebar/trace.js +5 -0
- package/dist/assets/js/sidebar.js +1 -705
- package/dist/assets/js/store.js +1 -82
- package/dist/assets/js/subdialog.js +1 -0
- package/dist/assets/md.js +1 -291
- package/dist/assets/setup.js +3 -816
- package/dist/assets/smd.js +29 -1665
- package/dist/assets/styles.css +1 -1598
- package/dist/certification/certifications.json +1 -494
- package/dist/i18n/en.json +1 -1851
- package/dist/i18n/ru.json +1 -1854
- package/dist/main.js +815 -55797
- package/dist/modules/browser/bridge-server.mjs +2 -252
- package/package.json +10 -5
- package/dist/assets/js/settings-controls.js +0 -452
- package/dist/assets/js/tabs.js +0 -867
- package/dist/cli/cache-line.js +0 -31
- package/dist/cli/command-suggest.js +0 -39
- package/dist/cli/commands.js +0 -781
- package/dist/cli/completer.js +0 -268
- package/dist/cli/index.js +0 -3
- package/dist/cli/json-payload.js +0 -32
- package/dist/cli/main.js +0 -346
- package/dist/cli/onboarding-commands.js +0 -126
- package/dist/cli/plugin-commands.js +0 -38
- package/dist/cli/relaunch.js +0 -40
- package/dist/cli/repl-commands-lsp.js +0 -75
- package/dist/cli/repl-commands-skills.js +0 -105
- package/dist/cli/repl-commands.js +0 -1218
- package/dist/cli/repl.js +0 -1238
- package/dist/cli/run-result.js +0 -38
- package/dist/cli/security-commands.js +0 -177
- package/dist/cli/setup-order.js +0 -6
- package/dist/cli/setup-prompt.js +0 -50
- package/dist/cli/setup.js +0 -161
- package/dist/cli/web-command.js +0 -98
- package/dist/config/budget.js +0 -48
- package/dist/config/config.js +0 -345
- package/dist/config/defaults.js +0 -197
- package/dist/config/domains.js +0 -135
- package/dist/config/env.js +0 -46
- package/dist/config/experts.js +0 -17
- package/dist/config/index.js +0 -5
- package/dist/config/paths.js +0 -56
- package/dist/config/redact.js +0 -44
- package/dist/config/registry-extra.js +0 -334
- package/dist/config/registry.js +0 -584
- package/dist/config/security.js +0 -212
- package/dist/config/timeouts.js +0 -74
- package/dist/config/types.js +0 -1
- package/dist/config/utils.js +0 -57
- package/dist/core/agent/artifact-progress.js +0 -59
- package/dist/core/agent/artifact-resolve.js +0 -79
- package/dist/core/agent/audit-gate.js +0 -53
- package/dist/core/agent/compaction.js +0 -89
- package/dist/core/agent/constants.js +0 -90
- package/dist/core/agent/context-log.js +0 -454
- package/dist/core/agent/context-renderer.js +0 -45
- package/dist/core/agent/critic-gate.js +0 -132
- package/dist/core/agent/hallucination-gate.js +0 -197
- package/dist/core/agent/loop-state.js +0 -68
- package/dist/core/agent/prefix-monitor.js +0 -101
- package/dist/core/agent/reasoning-resolver.js +0 -65
- package/dist/core/agent/token-tracker.js +0 -99
- package/dist/core/agent/tool-batch.js +0 -312
- package/dist/core/agent/tool-images.js +0 -18
- package/dist/core/agent/tool-output.js +0 -116
- package/dist/core/agent/tool-pairing.js +0 -60
- package/dist/core/agent-moe.js +0 -248
- package/dist/core/agent.js +0 -1299
- package/dist/core/bootstrap/agent-phase.js +0 -66
- package/dist/core/bootstrap/config-phase.js +0 -86
- package/dist/core/bootstrap/modules-phase.js +0 -269
- package/dist/core/bootstrap/provider-phase.js +0 -183
- package/dist/core/bootstrap/session-phase.js +0 -204
- package/dist/core/bootstrap/state.js +0 -94
- package/dist/core/bootstrap/workspace-phase.js +0 -115
- package/dist/core/bootstrap.js +0 -112
- package/dist/core/crash-handler.js +0 -62
- package/dist/core/environment.js +0 -224
- package/dist/core/host-plan.js +0 -43
- package/dist/core/host.js +0 -23
- package/dist/core/index.js +0 -3
- package/dist/core/prompt-builder.js +0 -95
- package/dist/core/prompt-overflow.js +0 -306
- package/dist/core/session-logger.js +0 -375
- package/dist/core/system-prompt.js +0 -117
- package/dist/core/types.js +0 -1
- package/dist/core/version.js +0 -28
- package/dist/core/web-host.js +0 -34
- package/dist/core/workspace.js +0 -80
- package/dist/i18n/index.js +0 -80
- package/dist/index.js +0 -30
- package/dist/llm/cache-usage.js +0 -76
- package/dist/llm/image-utils.js +0 -138
- package/dist/llm/index.js +0 -4
- package/dist/llm/llm-errors.js +0 -50
- package/dist/llm/model-loader.js +0 -86
- package/dist/llm/models-dev.js +0 -121
- package/dist/llm/openai-compat.js +0 -756
- package/dist/llm/orchestrator.js +0 -294
- package/dist/llm/provider-budget.js +0 -68
- package/dist/llm/provider-context.js +0 -233
- package/dist/llm/provider.js +0 -9
- package/dist/llm/response.js +0 -44
- package/dist/llm/stream-state.js +0 -26
- package/dist/llm/token-counter.js +0 -83
- package/dist/llm/types.js +0 -1
- package/dist/logger/app-logger.js +0 -212
- package/dist/logger/file-log.js +0 -160
- package/dist/logger/index.js +0 -2
- package/dist/migration/backup.js +0 -56
- package/dist/migration/detect.js +0 -61
- package/dist/migration/index.js +0 -3
- package/dist/modules/artifacts/store.js +0 -62
- package/dist/modules/browser/actions.js +0 -79
- package/dist/modules/browser/bridge-client.js +0 -203
- package/dist/modules/browser/bridge-path.js +0 -10
- package/dist/modules/browser/console-buffer.js +0 -37
- package/dist/modules/browser/cookie-store.js +0 -29
- package/dist/modules/browser/driver-types.js +0 -1
- package/dist/modules/browser/driver.js +0 -186
- package/dist/modules/browser/index.js +0 -9
- package/dist/modules/browser/module.js +0 -30
- package/dist/modules/browser/session.js +0 -322
- package/dist/modules/browser/snapshot.js +0 -154
- package/dist/modules/browser/types.js +0 -13
- package/dist/modules/certification/cli.js +0 -264
- package/dist/modules/certification/fact-checker.js +0 -90
- package/dist/modules/certification/loader.js +0 -127
- package/dist/modules/certification/manifest.js +0 -231
- package/dist/modules/certification/runner.js +0 -233
- package/dist/modules/certification/scenarios.js +0 -586
- package/dist/modules/certification/syntax-scenarios.js +0 -50
- package/dist/modules/certification/types.js +0 -1
- package/dist/modules/context/chunk-query.js +0 -122
- package/dist/modules/context/fact-extractor.js +0 -170
- package/dist/modules/context/history.js +0 -15
- package/dist/modules/context/index.js +0 -2
- package/dist/modules/context/manager.js +0 -482
- package/dist/modules/critic/client.js +0 -176
- package/dist/modules/critic/evidence.js +0 -81
- package/dist/modules/critic/provider.js +0 -45
- package/dist/modules/critic/tools.js +0 -78
- package/dist/modules/critic/types.js +0 -1
- package/dist/modules/execution/audit-runners.js +0 -206
- package/dist/modules/execution/auditor.js +0 -222
- package/dist/modules/execution/execution-plugin.js +0 -478
- package/dist/modules/execution/index.js +0 -8
- package/dist/modules/execution/input-from.js +0 -70
- package/dist/modules/execution/module.js +0 -891
- package/dist/modules/execution/moe-executor.js +0 -443
- package/dist/modules/execution/plan-actions.js +0 -642
- package/dist/modules/execution/plan-checks.js +0 -35
- package/dist/modules/execution/plan-coverage.js +0 -71
- package/dist/modules/execution/plan-persister.js +0 -46
- package/dist/modules/execution/plan-steps.js +0 -31
- package/dist/modules/execution/plan-store.js +0 -274
- package/dist/modules/execution/plan-tool.js +0 -249
- package/dist/modules/execution/plan-validator.js +0 -197
- package/dist/modules/execution/planner.js +0 -103
- package/dist/modules/execution/stuck-detector.js +0 -834
- package/dist/modules/execution/tracker.js +0 -92
- package/dist/modules/execution/transient-error.js +0 -30
- package/dist/modules/execution/types.js +0 -1
- package/dist/modules/execution/verifier.js +0 -343
- package/dist/modules/execution/windows-commands.js +0 -52
- package/dist/modules/hallucination/artifact-claim.js +0 -93
- package/dist/modules/hallucination/confidence.js +0 -81
- package/dist/modules/hallucination/consistency.js +0 -37
- package/dist/modules/hallucination/detector.js +0 -57
- package/dist/modules/hallucination/factual.js +0 -205
- package/dist/modules/hallucination/index.js +0 -6
- package/dist/modules/hallucination/js-identifiers.js +0 -261
- package/dist/modules/hallucination/llm-judge.js +0 -116
- package/dist/modules/hallucination/success-claim.js +0 -59
- package/dist/modules/index.js +0 -5
- package/dist/modules/indexer/cache.js +0 -88
- package/dist/modules/indexer/index.js +0 -4
- package/dist/modules/indexer/map-command.js +0 -33
- package/dist/modules/indexer/map-select.js +0 -87
- package/dist/modules/indexer/module.js +0 -293
- package/dist/modules/indexer/project-profile.js +0 -184
- package/dist/modules/indexer/symbols.js +0 -189
- package/dist/modules/indexer/walker.js +0 -285
- package/dist/modules/lsp/check-tool.js +0 -61
- package/dist/modules/lsp/client.js +0 -406
- package/dist/modules/lsp/command.js +0 -53
- package/dist/modules/lsp/config.js +0 -189
- package/dist/modules/lsp/index.js +0 -4
- package/dist/modules/lsp/module.js +0 -295
- package/dist/modules/lsp/probe.js +0 -86
- package/dist/modules/lsp/project-root.js +0 -69
- package/dist/modules/lsp/startup-check.js +0 -154
- package/dist/modules/lsp/types.js +0 -1
- package/dist/modules/mcp/client.js +0 -445
- package/dist/modules/mcp/index.js +0 -4
- package/dist/modules/mcp/module.js +0 -295
- package/dist/modules/mcp/registry.js +0 -20
- package/dist/modules/memory/index.js +0 -2
- package/dist/modules/memory/module.js +0 -101
- package/dist/modules/memory/search.js +0 -45
- package/dist/modules/memory/store.js +0 -107
- package/dist/modules/onboarding/init.js +0 -47
- package/dist/modules/onboarding/meet.js +0 -30
- package/dist/modules/onboarding/mode.js +0 -30
- package/dist/modules/onboarding/prompts.js +0 -43
- package/dist/modules/pipelines/engine.js +0 -70
- package/dist/modules/pipelines/index.js +0 -4
- package/dist/modules/pipelines/parser.js +0 -59
- package/dist/modules/pipelines/template.js +0 -18
- package/dist/modules/plugins/builtin/lint-on-write.js +0 -377
- package/dist/modules/plugins/builtin/notify.js +0 -11
- package/dist/modules/plugins/index.js +0 -2
- package/dist/modules/plugins/loader.js +0 -85
- package/dist/modules/plugins/manager.js +0 -244
- package/dist/modules/plugins/types.js +0 -1
- package/dist/modules/pricing/index.js +0 -70
- package/dist/modules/pricing/prices.js +0 -147
- package/dist/modules/processes/detect.js +0 -34
- package/dist/modules/processes/index.js +0 -4
- package/dist/modules/processes/kill-tree.js +0 -52
- package/dist/modules/processes/registry.js +0 -294
- package/dist/modules/processes/runner.js +0 -23
- package/dist/modules/providers/cache.js +0 -23
- package/dist/modules/providers/capabilities.js +0 -28
- package/dist/modules/providers/create.js +0 -21
- package/dist/modules/providers/factory.js +0 -28
- package/dist/modules/providers/fallback.js +0 -81
- package/dist/modules/providers/health.js +0 -47
- package/dist/modules/providers/index.js +0 -6
- package/dist/modules/providers/manager.js +0 -207
- package/dist/modules/providers/naming.js +0 -15
- package/dist/modules/providers/preflight.js +0 -71
- package/dist/modules/providers/presets.js +0 -232
- package/dist/modules/providers/registry.js +0 -27
- package/dist/modules/providers/types.js +0 -1
- package/dist/modules/reasoning/policy.js +0 -42
- package/dist/modules/reasoning/probe.js +0 -116
- package/dist/modules/registry.js +0 -48
- package/dist/modules/security/audit-log.js +0 -119
- package/dist/modules/security/audit-notifier.js +0 -267
- package/dist/modules/security/command-validator.js +0 -272
- package/dist/modules/security/content-scanner.js +0 -53
- package/dist/modules/security/data-sanitizer.js +0 -82
- package/dist/modules/security/encryption.js +0 -216
- package/dist/modules/security/index.js +0 -15
- package/dist/modules/security/network-validator.js +0 -236
- package/dist/modules/security/path-validator.js +0 -261
- package/dist/modules/security/protected-paths.js +0 -73
- package/dist/modules/security/rate-limiter.js +0 -98
- package/dist/modules/security/security-policies.js +0 -499
- package/dist/modules/security/session-encryption.js +0 -182
- package/dist/modules/security/session-isolation.js +0 -75
- package/dist/modules/session/auto-name.js +0 -63
- package/dist/modules/session/export.js +0 -98
- package/dist/modules/session/index.js +0 -4
- package/dist/modules/session/manager.js +0 -234
- package/dist/modules/session/module.js +0 -33
- package/dist/modules/session/store.js +0 -295
- package/dist/modules/session/types.js +0 -1
- package/dist/modules/setup/answers.js +0 -35
- package/dist/modules/setup/apply.js +0 -79
- package/dist/modules/setup/discovery.js +0 -72
- package/dist/modules/skills/index.js +0 -3
- package/dist/modules/skills/loader.js +0 -86
- package/dist/modules/skills/matcher.js +0 -27
- package/dist/modules/skills/module.js +0 -141
- package/dist/modules/types.js +0 -1
- package/dist/modules/updater/changelog-reader.js +0 -93
- package/dist/modules/updater/checker.js +0 -101
- package/dist/modules/updater/dev-detect.js +0 -18
- package/dist/modules/updater/index.js +0 -4
- package/dist/modules/updater/module.js +0 -129
- package/dist/modules/user-profile/compressor.js +0 -18
- package/dist/modules/user-profile/index.js +0 -2
- package/dist/modules/user-profile/profile.js +0 -77
- package/dist/modules/webui/answer-api.js +0 -29
- package/dist/modules/webui/assets.js +0 -50
- package/dist/modules/webui/body.js +0 -21
- package/dist/modules/webui/commands-settings.js +0 -209
- package/dist/modules/webui/commands-shared.js +0 -60
- package/dist/modules/webui/commands.js +0 -174
- package/dist/modules/webui/config-api.js +0 -134
- package/dist/modules/webui/file-api.js +0 -202
- package/dist/modules/webui/forward.js +0 -159
- package/dist/modules/webui/history-api.js +0 -112
- package/dist/modules/webui/host-state.js +0 -60
- package/dist/modules/webui/i18n-api.js +0 -9
- package/dist/modules/webui/limits.js +0 -6
- package/dist/modules/webui/log-forward.js +0 -20
- package/dist/modules/webui/memory-commands.js +0 -64
- package/dist/modules/webui/model-cache.js +0 -18
- package/dist/modules/webui/module.js +0 -148
- package/dist/modules/webui/persist.js +0 -24
- package/dist/modules/webui/prompt-io.js +0 -97
- package/dist/modules/webui/providers-api.js +0 -337
- package/dist/modules/webui/providers-view.js +0 -56
- package/dist/modules/webui/reasoning-view.js +0 -15
- package/dist/modules/webui/run-agent.js +0 -81
- package/dist/modules/webui/server.js +0 -284
- package/dist/modules/webui/sessions-api.js +0 -178
- package/dist/modules/webui/settings-api.js +0 -561
- package/dist/modules/webui/setup-api.js +0 -201
- package/dist/modules/webui/state.js +0 -74
- package/dist/modules/webui/util.js +0 -261
- package/dist/output/bus.js +0 -37
- package/dist/output/channel.js +0 -285
- package/dist/output/format.js +0 -15
- package/dist/output/index.js +0 -8
- package/dist/output/json-sink.js +0 -24
- package/dist/output/machine.js +0 -9
- package/dist/output/session-sink.js +0 -27
- package/dist/output/types.js +0 -1
- package/dist/tools/approve.js +0 -41
- package/dist/tools/attach-image.js +0 -102
- package/dist/tools/auto-fixer.js +0 -180
- package/dist/tools/auto-tags.js +0 -83
- package/dist/tools/bash.js +0 -649
- package/dist/tools/browser.js +0 -160
- package/dist/tools/chunk-query.js +0 -112
- package/dist/tools/create-dir.js +0 -60
- package/dist/tools/delete-file.js +0 -67
- package/dist/tools/download-file.js +0 -142
- package/dist/tools/edit-file.js +0 -136
- package/dist/tools/enable-tools.js +0 -59
- package/dist/tools/executor.js +0 -304
- package/dist/tools/file-info.js +0 -49
- package/dist/tools/filter-tools.js +0 -17
- package/dist/tools/glob-tool.js +0 -37
- package/dist/tools/grep-tool.js +0 -142
- package/dist/tools/hidden-tools-block.js +0 -37
- package/dist/tools/index.js +0 -88
- package/dist/tools/list-dir.js +0 -53
- package/dist/tools/load-skill.js +0 -51
- package/dist/tools/mcp-call.js +0 -80
- package/dist/tools/meet-done.js +0 -14
- package/dist/tools/move-file.js +0 -94
- package/dist/tools/path-utils.js +0 -108
- package/dist/tools/pipeline-run.js +0 -167
- package/dist/tools/preview.js +0 -2
- package/dist/tools/process-ids.js +0 -31
- package/dist/tools/process-kill.js +0 -33
- package/dist/tools/process-list.js +0 -38
- package/dist/tools/process-log.js +0 -49
- package/dist/tools/process-wait.js +0 -63
- package/dist/tools/prompt-io.js +0 -29
- package/dist/tools/question.js +0 -288
- package/dist/tools/read-file.js +0 -200
- package/dist/tools/recall.js +0 -124
- package/dist/tools/registry.js +0 -48
- package/dist/tools/remember.js +0 -72
- package/dist/tools/scope-check.js +0 -32
- package/dist/tools/scope-request.js +0 -96
- package/dist/tools/search-history.js +0 -88
- package/dist/tools/session-info.js +0 -46
- package/dist/tools/set-thinking.js +0 -75
- package/dist/tools/subagent.js +0 -257
- package/dist/tools/syntax-validator.js +0 -379
- package/dist/tools/types.js +0 -1
- package/dist/tools/user-input.js +0 -134
- package/dist/tools/web-browse.js +0 -93
- package/dist/tools/web-fetch.js +0 -108
- package/dist/tools/web-search.js +0 -107
- package/dist/tools/write-file.js +0 -128
- package/dist/ui/action-log.js +0 -13
- package/dist/ui/box.js +0 -78
- package/dist/ui/colors.js +0 -6
- package/dist/ui/diff.js +0 -189
- package/dist/ui/index.js +0 -7
- package/dist/ui/line-editor.js +0 -1083
- package/dist/ui/line-math.js +0 -98
- package/dist/ui/md-formatter.js +0 -322
- package/dist/ui/output.js +0 -19
- package/dist/ui/plan-view.js +0 -109
- package/dist/ui/renderer.js +0 -589
- package/dist/ui/spinner.js +0 -91
- package/dist/ui/table.js +0 -142
- package/dist/ui/theme.js +0 -143
- package/dist/utils/child-run.js +0 -20
- package/dist/utils/error.js +0 -4
- package/dist/utils/index.js +0 -6
- package/dist/utils/retry.js +0 -17
- package/dist/utils/sleep.js +0 -23
- package/dist/utils/truncate.js +0 -9
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { estimateTokens } from "../../llm/token-counter";
|
|
2
|
-
import { MEET_SYSTEM_PROMPT, MEET_TOOLS } from "./prompts";
|
|
3
|
-
/**
|
|
4
|
-
* Входит в meet-режим на shared-агенте: режет тулы до allowlist, создаёт
|
|
5
|
-
* shared-состояние онбординга (с блоком гайда) и инжектит гайд интервью.
|
|
6
|
-
* Режим живёт между ходами REPL до `exitMeetMode` (по сентинелу `meet_done`).
|
|
7
|
-
*/
|
|
8
|
-
export function enterMeetMode(ctx) {
|
|
9
|
-
const block = {
|
|
10
|
-
content: MEET_SYSTEM_PROMPT,
|
|
11
|
-
priority: "high",
|
|
12
|
-
essential: true,
|
|
13
|
-
estimatedTokens: estimateTokens(MEET_SYSTEM_PROMPT),
|
|
14
|
-
};
|
|
15
|
-
ctx.toolCtx.toolAllowlist = [...MEET_TOOLS];
|
|
16
|
-
ctx.toolCtx.onboarding = { done: false, block };
|
|
17
|
-
ctx.agent.pushPromptBlock(block);
|
|
18
|
-
}
|
|
19
|
-
/** Выходит из meet-режима: убирает гайд и возвращает полные тулы. */
|
|
20
|
-
export function exitMeetMode(ctx) {
|
|
21
|
-
const block = ctx.toolCtx.onboarding?.block;
|
|
22
|
-
if (block)
|
|
23
|
-
ctx.agent.removePromptBlock(block);
|
|
24
|
-
ctx.toolCtx.toolAllowlist = undefined;
|
|
25
|
-
ctx.toolCtx.onboarding = undefined;
|
|
26
|
-
}
|
|
27
|
-
/** True, когда сентинел-тул сработал в активной meet-сессии. */
|
|
28
|
-
export function isMeetDone(ctx) {
|
|
29
|
-
return ctx.toolCtx.onboarding?.done === true;
|
|
30
|
-
}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
// Промпты и allowlist онбординга: интервью «Познакомимся» и автор AGENTS.md.
|
|
2
|
-
/** Тулы, доступные во время интервью (строгий allowlist). */
|
|
3
|
-
export const MEET_TOOLS = ["remember", "question", "meet_done"];
|
|
4
|
-
/** Тулы, доступные при генерации AGENTS.md (строгий allowlist). */
|
|
5
|
-
export const INIT_TOOLS = [
|
|
6
|
-
"read_file",
|
|
7
|
-
"list_dir",
|
|
8
|
-
"glob",
|
|
9
|
-
"grep",
|
|
10
|
-
"project_map",
|
|
11
|
-
"question",
|
|
12
|
-
"write_file",
|
|
13
|
-
"edit_file",
|
|
14
|
-
];
|
|
15
|
-
/**
|
|
16
|
-
* Полускриптовое интервью. Гайд отвечает за покрытие и вайтлист ключей
|
|
17
|
-
* преференсов; модель — за формулировки и лёгкие уточнения. Домен-нейтрально.
|
|
18
|
-
* Тело промпта — на английском: уходит модели как есть.
|
|
19
|
-
*/
|
|
20
|
-
export const MEET_SYSTEM_PROMPT = `You are getting acquainted with the user. This is a short interview, not a task.
|
|
21
|
-
Rules:
|
|
22
|
-
- Ask 1-3 short questions per turn, in the user's language.
|
|
23
|
-
- For closed / multiple-choice questions (e.g. response style, autonomy), use the "question" tool and provide explicit options. For open-ended questions, ask in plain text.
|
|
24
|
-
- START by asking what the user will mainly use the agent for (their domain / usage profile): e.g. software development, working with APIs, smart home, automation, personal assistant, web search, computer setup — or anything else. Never assume their use case is software development.
|
|
25
|
-
- Then cover: name; reply language; response style (concise | balanced | detailed); tools & experience; working habits; hard "do not do without asking" rules; goals.
|
|
26
|
-
- Only if the user named software development as a use case may you ask about code / commit language.
|
|
27
|
-
- Save each answer with the "remember" tool. Use category=preferences with these keys ONLY: domain, name, language, response_style, autonomy, code_language. Use category=facts (free text, user's language) for experience, habits, goals and any concrete "do not" rule (preserve it verbatim).
|
|
28
|
-
- Leave code_language out entirely when development is not a use case.
|
|
29
|
-
- Keep preference values as canonical English tokens: domain=development,api; response_style=concise|balanced|detailed; autonomy=ask|act. Record language as the token the user chose (e.g. language=ru) and name exactly as the user wrote it.
|
|
30
|
-
- Never touch the file system, run commands, or inspect the repository.
|
|
31
|
-
- When every topic is covered (or the user wants to stop), give a one-line summary of what you remembered, then call the "meet_done" tool.`;
|
|
32
|
-
/**
|
|
33
|
-
* Гайд автора AGENTS.md. Домен-нейтрален: код, доки, заметки или конфиги;
|
|
34
|
-
* код — лишь частный случай. Тело промпта — на английском: уходит модели как есть.
|
|
35
|
-
*/
|
|
36
|
-
export const INIT_SYSTEM_PROMPT = `You create or improve an AGENTS.md file for the current workspace.
|
|
37
|
-
Rules:
|
|
38
|
-
- First read what is here: use project_map, read_file, list_dir, glob, grep. The workspace may be code, docs, notes, configs or mixed — never assume a programming project.
|
|
39
|
-
- If AGENTS.md already exists, IMPROVE it in place: produce a proposed full version, show it, and let the user confirm before writing. Never silently overwrite.
|
|
40
|
-
- Capture: purpose & usage profile; key structure; how to run/use things (only if applicable); conventions; setup quirks/gotchas; references to existing instruction sources (e.g. Cursor/Copilot rules).
|
|
41
|
-
- Ask targeted questions only when the files cannot answer.
|
|
42
|
-
- Keep it concise and within the instructions budget.
|
|
43
|
-
- Write with write_file or edit_file; do not run shell commands.`;
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
import { t } from "../../i18n/index";
|
|
2
|
-
/** Движок пайплайна: порядок обхода зависимостей и учёт статусов шагов. */
|
|
3
|
-
export class PipelineEngine {
|
|
4
|
-
stepStatus = new Map();
|
|
5
|
-
/**
|
|
6
|
-
* Топологически сортирует шаги по `depends_on`. Бросает при цикле.
|
|
7
|
-
* Возвращает id в порядке выполнения.
|
|
8
|
-
*/
|
|
9
|
-
resolveDependencies(steps) {
|
|
10
|
-
const visited = new Set();
|
|
11
|
-
const inStack = new Set();
|
|
12
|
-
const order = [];
|
|
13
|
-
function visit(stepId, stepMap) {
|
|
14
|
-
if (inStack.has(stepId))
|
|
15
|
-
throw new Error(t("pipeline.circular", { stepId }));
|
|
16
|
-
if (visited.has(stepId))
|
|
17
|
-
return;
|
|
18
|
-
inStack.add(stepId);
|
|
19
|
-
const step = stepMap.get(stepId);
|
|
20
|
-
if (step?.depends_on) {
|
|
21
|
-
for (const dep of step.depends_on) {
|
|
22
|
-
visit(dep, stepMap);
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
inStack.delete(stepId);
|
|
26
|
-
visited.add(stepId);
|
|
27
|
-
order.push(stepId);
|
|
28
|
-
}
|
|
29
|
-
const stepMap = new Map(steps.map((s) => [s.id, s]));
|
|
30
|
-
for (const step of steps) {
|
|
31
|
-
if (!visited.has(step.id)) {
|
|
32
|
-
visit(step.id, stepMap);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
return order;
|
|
36
|
-
}
|
|
37
|
-
/** Шаги, готовые к запуску: не завершены, не в работе/провале, зависимости закрыты. */
|
|
38
|
-
getReadySteps(steps, completed) {
|
|
39
|
-
return steps.filter((s) => {
|
|
40
|
-
if (completed.has(s.id))
|
|
41
|
-
return false;
|
|
42
|
-
if (this.stepStatus.get(s.id) === "running")
|
|
43
|
-
return false;
|
|
44
|
-
if (this.stepStatus.get(s.id) === "failed")
|
|
45
|
-
return false;
|
|
46
|
-
if (!s.depends_on || s.depends_on.length === 0)
|
|
47
|
-
return true;
|
|
48
|
-
return s.depends_on.every((d) => completed.has(d));
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
/** Ставит статус шага. */
|
|
52
|
-
setStepStatus(stepId, status) {
|
|
53
|
-
this.stepStatus.set(stepId, status);
|
|
54
|
-
}
|
|
55
|
-
/** Статус шага; неизвестному — `pending`. */
|
|
56
|
-
getStepStatus(stepId) {
|
|
57
|
-
return this.stepStatus.get(stepId) || "pending";
|
|
58
|
-
}
|
|
59
|
-
/** True, когда все шаги `done` или `skipped`. */
|
|
60
|
-
isComplete(stepIds) {
|
|
61
|
-
return stepIds.every((id) => {
|
|
62
|
-
const s = this.stepStatus.get(id);
|
|
63
|
-
return s === "done" || s === "skipped";
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
/** Сбрасывает все статусы (перезапуск пайплайна). */
|
|
67
|
-
reset() {
|
|
68
|
-
this.stepStatus.clear();
|
|
69
|
-
}
|
|
70
|
-
}
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
// Минималистичный парсер YAML-описаний пайплайнов (без внешних зависимостей).
|
|
2
|
-
import { t } from "../../i18n/index";
|
|
3
|
-
/** Парсер описания пайплайна. Бросает при невалидном YAML/полях. */
|
|
4
|
-
export class PipelineParser {
|
|
5
|
-
/** Разбирает YAML в `Pipeline`; бросает с локализованной ошибкой. */
|
|
6
|
-
static parse(yaml) {
|
|
7
|
-
const lines = yaml.split("\n").filter((l) => l.trim());
|
|
8
|
-
const result = {};
|
|
9
|
-
let currentSection = null;
|
|
10
|
-
const currentSteps = [];
|
|
11
|
-
for (const line of lines) {
|
|
12
|
-
if (line.match(/^\w+:/) && !line.startsWith(" ") && !line.startsWith(" -")) {
|
|
13
|
-
const [key, ...valParts] = line.split(":");
|
|
14
|
-
const val = valParts.join(":").trim();
|
|
15
|
-
if (key === "steps") {
|
|
16
|
-
currentSection = "steps";
|
|
17
|
-
}
|
|
18
|
-
else {
|
|
19
|
-
result[key] = val;
|
|
20
|
-
currentSection = null;
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
else if (currentSection === "steps") {
|
|
24
|
-
const stepMatch = line.match(/^\s+- id:\s*(\S+)/);
|
|
25
|
-
if (stepMatch) {
|
|
26
|
-
currentSteps.push({ id: stepMatch[1] });
|
|
27
|
-
}
|
|
28
|
-
else if (currentSteps.length > 0) {
|
|
29
|
-
const lastStep = currentSteps[currentSteps.length - 1];
|
|
30
|
-
const kvMatch = line.match(/^\s+(\w+):\s*(.+)$/);
|
|
31
|
-
if (kvMatch) {
|
|
32
|
-
const key = kvMatch[1];
|
|
33
|
-
let val = kvMatch[2].trim();
|
|
34
|
-
if (val === "true")
|
|
35
|
-
val = true;
|
|
36
|
-
else if (val === "false")
|
|
37
|
-
val = false;
|
|
38
|
-
else if (val.startsWith("[") && val.endsWith("]")) {
|
|
39
|
-
val = val
|
|
40
|
-
.slice(1, -1)
|
|
41
|
-
.split(",")
|
|
42
|
-
.map((s) => s.trim().replace(/^['"]|['"]$/g, ""));
|
|
43
|
-
}
|
|
44
|
-
lastStep[key] = val;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
if (!result.name || currentSteps.length === 0) {
|
|
50
|
-
throw new Error(t("pipeline.invalid"));
|
|
51
|
-
}
|
|
52
|
-
for (const step of currentSteps) {
|
|
53
|
-
if (!step.id || !step.agent || !step.prompt) {
|
|
54
|
-
throw new Error(t("pipeline.step_missing_fields", { step: JSON.stringify(step) }));
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
return { name: result.name, steps: currentSteps };
|
|
58
|
-
}
|
|
59
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
// Подстановка в шаблоны: `{param}` из params и `{{steps.<id>.output}}` из выходов шагов.
|
|
2
|
-
export class TemplateEngine {
|
|
3
|
-
/**
|
|
4
|
-
* Рендерит шаблон. Неизвестный выход шага остаётся плейсхолдером как есть.
|
|
5
|
-
*/
|
|
6
|
-
static render(template, params, stepOutputs) {
|
|
7
|
-
let result = template;
|
|
8
|
-
for (const [key, val] of Object.entries(params)) {
|
|
9
|
-
result = result.replace(new RegExp(`\\{${key}\\}`, "g"), val);
|
|
10
|
-
}
|
|
11
|
-
if (stepOutputs) {
|
|
12
|
-
result = result.replace(/\{\{steps\.(\w+)\.output\}\}/g, (_, stepId) => {
|
|
13
|
-
return stepOutputs[stepId]?.output || `{{steps.${stepId}.output}}`;
|
|
14
|
-
});
|
|
15
|
-
}
|
|
16
|
-
return result;
|
|
17
|
-
}
|
|
18
|
-
}
|
|
@@ -1,377 +0,0 @@
|
|
|
1
|
-
import { spawn, execSync } from "child_process";
|
|
2
|
-
import { existsSync, readFileSync, writeFileSync } from "fs";
|
|
3
|
-
import { resolve, extname, join } from "path";
|
|
4
|
-
import { platform } from "os";
|
|
5
|
-
import { findProjectRoot, resolveTscCommand } from "../../lsp/project-root";
|
|
6
|
-
import { autoFixErrors, parseTscOutput } from "../../../tools/auto-fixer";
|
|
7
|
-
import { LINT_TYPE_CHECK_DEBOUNCE_MS as TYPE_CHECK_DEBOUNCE_MS } from "../../../config/timeouts";
|
|
8
|
-
import { settleChildClose } from "../../../utils/child-run";
|
|
9
|
-
// Проекты, чей lint-скрипт ссылается на неустановленный бинарник
|
|
10
|
-
// (ключ baseDir::script). Сам прогон дорог, а маркер провала — чистый шум,
|
|
11
|
-
// поэтому пропускаем до конца процесса.
|
|
12
|
-
const missingLintBinaries = new Set();
|
|
13
|
-
function lintCacheKey(baseDir, lintScript) {
|
|
14
|
-
return `${baseDir}::${lintScript}`;
|
|
15
|
-
}
|
|
16
|
-
// Шелл-уровень "command not found" по локалям/рантаймам: POSIX `sh` пишет
|
|
17
|
-
// "command not found" (exit 127); Windows cmd.exe — "is not recognized"
|
|
18
|
-
// (en) / "не является внутренней или внешней командой" (ru), exit 1/9009.
|
|
19
|
-
const MISSING_BINARY_RE = /command not found|not recognized|не является внутренней|не распознан|не є внутрішньою|".+?" не является/i;
|
|
20
|
-
function isMissingBinaryError(err, combinedOutput) {
|
|
21
|
-
// 127 = POSIX sh "command not found"; 9009 = Windows cmd.exe "is not
|
|
22
|
-
// recognized" — оба авторитетны независимо от кодировки вывода.
|
|
23
|
-
if (err.status === 127 || err.status === 9009)
|
|
24
|
-
return true;
|
|
25
|
-
if (err.code === "ENOENT")
|
|
26
|
-
return true;
|
|
27
|
-
return MISSING_BINARY_RE.test(combinedOutput);
|
|
28
|
-
}
|
|
29
|
-
// Пофайловые синтаксис-проверки кешируются по (путь, хеш содержимого): перезапись
|
|
30
|
-
// файла с тем же содержимым скипает (дорогую) проверку. Смена контента →
|
|
31
|
-
// промах кеша → свежая проверка.
|
|
32
|
-
const syntaxCache = new Map();
|
|
33
|
-
function contentHash(content) {
|
|
34
|
-
let h = 5381;
|
|
35
|
-
for (let i = 0; i < content.length; i++) {
|
|
36
|
-
h = ((h << 5) + h + content.charCodeAt(i)) | 0;
|
|
37
|
-
}
|
|
38
|
-
return String(h);
|
|
39
|
-
}
|
|
40
|
-
let _winDecoder;
|
|
41
|
-
/**
|
|
42
|
-
* OEM-декодер активной консольной кодовой страницы (CP866 на русской Windows).
|
|
43
|
-
* Зеркалит `getOemDecoder()` из modules/processes/registry.ts: транзиентный
|
|
44
|
-
* провал chcp.com под нагрузкой НЕ кешируется — мемоизируется только успешный
|
|
45
|
-
* проб (или жёсткий фолбэк ibm866).
|
|
46
|
-
*/
|
|
47
|
-
function getWinDecoder() {
|
|
48
|
-
if (_winDecoder !== undefined)
|
|
49
|
-
return _winDecoder;
|
|
50
|
-
if (platform() !== "win32") {
|
|
51
|
-
_winDecoder = new TextDecoder("utf-8");
|
|
52
|
-
return _winDecoder;
|
|
53
|
-
}
|
|
54
|
-
let decoder = null;
|
|
55
|
-
try {
|
|
56
|
-
const cpOut = execSync("chcp.com", {
|
|
57
|
-
encoding: "buffer",
|
|
58
|
-
timeout: 2000,
|
|
59
|
-
windowsHide: true,
|
|
60
|
-
}).toString("latin1");
|
|
61
|
-
const m = cpOut.match(/(\d+)/);
|
|
62
|
-
if (m)
|
|
63
|
-
decoder = new TextDecoder(`ibm${m[1]}`);
|
|
64
|
-
}
|
|
65
|
-
catch {
|
|
66
|
-
/* chcp упал (нагрузка/ENOENT) — повторим при следующем вызове */
|
|
67
|
-
}
|
|
68
|
-
if (!decoder) {
|
|
69
|
-
try {
|
|
70
|
-
decoder = new TextDecoder("ibm866");
|
|
71
|
-
}
|
|
72
|
-
catch {
|
|
73
|
-
return new TextDecoder("utf-8"); // неизвестная кодировка — не кешируем
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
_winDecoder = decoder;
|
|
77
|
-
return _winDecoder;
|
|
78
|
-
}
|
|
79
|
-
/**
|
|
80
|
-
* Декодирует вывод дочернего процесса в UTF-8. Современные тулы (bun, node,
|
|
81
|
-
* npm, tsc) пишут UTF-8 в пайп; встроенные команды/ошибки cmd.exe — OEM-страницу.
|
|
82
|
-
* Сначала строгий UTF-8; на невалидных байтах — откат на OEM.
|
|
83
|
-
*/
|
|
84
|
-
function decodeOutput(chunks) {
|
|
85
|
-
const raw = Buffer.concat(chunks);
|
|
86
|
-
try {
|
|
87
|
-
return new TextDecoder("utf-8", { fatal: true }).decode(raw);
|
|
88
|
-
}
|
|
89
|
-
catch {
|
|
90
|
-
/* невалидный UTF-8 → вывод в OEM-кодировке */
|
|
91
|
-
}
|
|
92
|
-
try {
|
|
93
|
-
return getWinDecoder().decode(raw);
|
|
94
|
-
}
|
|
95
|
-
catch {
|
|
96
|
-
return raw.toString("latin1");
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
/** Встроенный плагин: проверяет каждую запись/правку файла (синтаксис, lint, типы). */
|
|
100
|
-
export class LintOnWritePlugin {
|
|
101
|
-
name = "lint-on-write";
|
|
102
|
-
priority = 10;
|
|
103
|
-
isBuiltin = true;
|
|
104
|
-
// Дебаунснутый проектный typecheck по корню проекта. Один общий слот
|
|
105
|
-
// протекал tsc-ошибками одного проекта в записи другого (монорепо).
|
|
106
|
-
_checks = new Map();
|
|
107
|
-
/** После записи/правки: синтаксис файла, затем проектные lint и typecheck. */
|
|
108
|
-
async onAfterTool(ctx, call, result) {
|
|
109
|
-
if (call.name !== "write_file" && call.name !== "edit_file") {
|
|
110
|
-
return;
|
|
111
|
-
}
|
|
112
|
-
if (!result.success) {
|
|
113
|
-
return;
|
|
114
|
-
}
|
|
115
|
-
const path = String(call.arguments.path || "");
|
|
116
|
-
if (!path)
|
|
117
|
-
return;
|
|
118
|
-
const fullPath = resolve(ctx.baseDir, path);
|
|
119
|
-
if (!existsSync(fullPath))
|
|
120
|
-
return;
|
|
121
|
-
const signal = ctx.signal;
|
|
122
|
-
if (signal?.aborted)
|
|
123
|
-
return;
|
|
124
|
-
const ext = extname(fullPath);
|
|
125
|
-
const syntaxError = await this.checkSyntax(fullPath, ext, ctx.baseDir, signal);
|
|
126
|
-
if (signal?.aborted)
|
|
127
|
-
return;
|
|
128
|
-
if (syntaxError) {
|
|
129
|
-
result.output += `\n\n[Syntax check failed]: ${syntaxError}`;
|
|
130
|
-
return;
|
|
131
|
-
}
|
|
132
|
-
await this.runProjectLint(ctx, result, signal);
|
|
133
|
-
if (signal?.aborted)
|
|
134
|
-
return;
|
|
135
|
-
await this.runProjectTypeCheck(fullPath, ctx.baseDir, result, signal);
|
|
136
|
-
}
|
|
137
|
-
async checkSyntax(filePath, ext, baseDir, signal) {
|
|
138
|
-
if (ext === ".ts" || ext === ".tsx" || ext === ".cts" || ext === ".mts") {
|
|
139
|
-
// Проверка только синтаксиса парсером bun (~200мс) вместо `npx tsc`
|
|
140
|
-
// (~3-5с на запись). Полные ошибки типов всё равно отдаёт дебаунснутый
|
|
141
|
-
// проектный typecheck ниже, когда есть tsconfig.
|
|
142
|
-
let content = "";
|
|
143
|
-
try {
|
|
144
|
-
content = readFileSync(filePath, "utf-8");
|
|
145
|
-
}
|
|
146
|
-
catch {
|
|
147
|
-
return null;
|
|
148
|
-
}
|
|
149
|
-
const hash = contentHash(content);
|
|
150
|
-
const cached = syntaxCache.get(filePath);
|
|
151
|
-
if (cached && cached.hash === hash) {
|
|
152
|
-
return cached.error;
|
|
153
|
-
}
|
|
154
|
-
try {
|
|
155
|
-
await runAsync({ file: "bun", args: ["build", "--no-bundle", "--target=bun", filePath] }, baseDir, 10000, signal);
|
|
156
|
-
// Прерванная проверка (interrupt) файл не валидировала — не кешируем.
|
|
157
|
-
if (signal?.aborted)
|
|
158
|
-
return null;
|
|
159
|
-
syntaxCache.set(filePath, { hash, error: null });
|
|
160
|
-
return null;
|
|
161
|
-
}
|
|
162
|
-
catch (err) {
|
|
163
|
-
if (err.status === 127 ||
|
|
164
|
-
err.message.includes("not found") ||
|
|
165
|
-
err.message.includes("ENOENT")) {
|
|
166
|
-
return null;
|
|
167
|
-
}
|
|
168
|
-
const stderr = err.stderr?.toString() || err.stdout?.toString() || "";
|
|
169
|
-
const firstError = stderr.split("\n").find((line) => line.trim()) || "TypeScript syntax error";
|
|
170
|
-
syntaxCache.set(filePath, { hash, error: firstError.trim() });
|
|
171
|
-
return firstError.trim();
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
if (ext === ".js" || ext === ".jsx" || ext === ".cjs" || ext === ".mjs") {
|
|
175
|
-
try {
|
|
176
|
-
await runAsync({ file: "node", args: ["--check", filePath] }, baseDir, 5000, signal);
|
|
177
|
-
return null;
|
|
178
|
-
}
|
|
179
|
-
catch (err) {
|
|
180
|
-
const stderr = err.stderr?.toString() || "";
|
|
181
|
-
const firstError = stderr.split("\n").find((line) => line.trim()) || "JavaScript syntax error";
|
|
182
|
-
return firstError.trim();
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
return null;
|
|
186
|
-
}
|
|
187
|
-
async runProjectLint(ctx, result, signal) {
|
|
188
|
-
let lintScript;
|
|
189
|
-
try {
|
|
190
|
-
const packageJsonPath = join(ctx.baseDir, "package.json");
|
|
191
|
-
if (!existsSync(packageJsonPath)) {
|
|
192
|
-
return;
|
|
193
|
-
}
|
|
194
|
-
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
|
|
195
|
-
lintScript = packageJson.scripts?.lint;
|
|
196
|
-
if (!lintScript) {
|
|
197
|
-
return;
|
|
198
|
-
}
|
|
199
|
-
// Объявленный, но неустановленный бинарник линтера ("eslint" не стоит) —
|
|
200
|
-
// пробел проектного сетапа, а не проблема кода: дописывание его к каждой
|
|
201
|
-
// записи засоряло контекст ~25×/сессию (ses_mt4fn58c). Детектим раз
|
|
202
|
-
// и дальше скипаем молча до конца процесса.
|
|
203
|
-
if (missingLintBinaries.has(lintCacheKey(ctx.baseDir, lintScript))) {
|
|
204
|
-
ctx.logger.debug(`Lint skipped (linter for "${lintScript}" not installed)`);
|
|
205
|
-
return;
|
|
206
|
-
}
|
|
207
|
-
ctx.logger.debug(`Running lint: ${lintScript}`);
|
|
208
|
-
await runAsync(lintScript, ctx.baseDir, 30_000, signal);
|
|
209
|
-
ctx.logger.debug("Lint passed");
|
|
210
|
-
}
|
|
211
|
-
catch (err) {
|
|
212
|
-
const stderr = (err.stderr?.toString?.() || "").trim();
|
|
213
|
-
const stdout = (err.stdout?.toString?.() || "").trim();
|
|
214
|
-
const combined = `${stderr}\n${stdout}`;
|
|
215
|
-
if (lintScript && isMissingBinaryError(err, combined)) {
|
|
216
|
-
missingLintBinaries.add(lintCacheKey(ctx.baseDir, lintScript));
|
|
217
|
-
ctx.logger.debug(`Lint binary missing — skipping project lint for this session`);
|
|
218
|
-
return;
|
|
219
|
-
}
|
|
220
|
-
const detail = combined
|
|
221
|
-
.trim()
|
|
222
|
-
.split("\n")
|
|
223
|
-
.filter(Boolean)
|
|
224
|
-
.slice(-5)
|
|
225
|
-
.join("\n");
|
|
226
|
-
ctx.logger.warn(`Lint failed: ${err.message}`);
|
|
227
|
-
result.output += `\n\n[Project lint failed]: ${detail}`;
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
async runProjectTypeCheck(filePath, baseDir, result, signal) {
|
|
231
|
-
// Корень проекта резолвим от РЕДАКТИРОВАННОГО ФАЙЛА, а не от baseDir агента.
|
|
232
|
-
// Во вложенной раскладке (`baseDir/proj/tsconfig.json`) старый поиск от
|
|
233
|
-
// baseDir молча скипал typecheck на каждой записи — вся сессия шла
|
|
234
|
-
// вообще без типового фидбэка (наблюдено в ses_mst2r0r5).
|
|
235
|
-
const projectRoot = findProjectRoot(filePath, baseDir, ["tsconfig.json", "package.json"]);
|
|
236
|
-
const tsconfigPath = join(projectRoot, "tsconfig.json");
|
|
237
|
-
if (!existsSync(tsconfigPath)) {
|
|
238
|
-
return;
|
|
239
|
-
}
|
|
240
|
-
// Без локального tsc проверка невозможна — не платим npx-задержку.
|
|
241
|
-
const tsc = resolveTscCommand(projectRoot);
|
|
242
|
-
if (!tsc) {
|
|
243
|
-
return;
|
|
244
|
-
}
|
|
245
|
-
const now = Date.now();
|
|
246
|
-
const prev = this._checks.get(projectRoot);
|
|
247
|
-
if (prev && now - prev.at < TYPE_CHECK_DEBOUNCE_MS) {
|
|
248
|
-
const error = await prev.promise;
|
|
249
|
-
if (error) {
|
|
250
|
-
result.output += `\n\n[Project typecheck failed]: ${error}`;
|
|
251
|
-
}
|
|
252
|
-
return;
|
|
253
|
-
}
|
|
254
|
-
const promise = this.runTscCheck(tsc, projectRoot, signal);
|
|
255
|
-
this._checks.set(projectRoot, { at: now, promise });
|
|
256
|
-
const error = await promise;
|
|
257
|
-
if (error) {
|
|
258
|
-
// Пробуем автофиксить чинимые ошибки
|
|
259
|
-
const { stdout, stderr } = await runAsync(`${tsc} --noEmit --skipLibCheck 2>&1`, projectRoot, 30000, signal).catch(() => ({ stdout: "", stderr: error }));
|
|
260
|
-
const output = stderr || stdout;
|
|
261
|
-
const errors = parseTscOutput(output);
|
|
262
|
-
if (errors.length > 0) {
|
|
263
|
-
const fixResult = autoFixErrors(filePath, readFileSync(filePath, "utf-8"), errors);
|
|
264
|
-
if (fixResult.fixed) {
|
|
265
|
-
// Пишем починенное содержимое
|
|
266
|
-
writeFileSync(filePath, fixResult.newContent, "utf-8");
|
|
267
|
-
result.output += `\n\n[Auto-fixed]: ${fixResult.applied.join("; ")}`;
|
|
268
|
-
// Если остались ошибки — показываем их
|
|
269
|
-
if (fixResult.remaining.length > 0) {
|
|
270
|
-
const remainingMsg = fixResult.remaining
|
|
271
|
-
.map((e) => `TS${e.code}: ${e.message}`)
|
|
272
|
-
.join("\n");
|
|
273
|
-
result.output += `\n\n[Remaining errors]: ${remainingMsg}`;
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
else {
|
|
277
|
-
result.output += `\n\n[Project typecheck failed]: ${error}`;
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
else {
|
|
281
|
-
result.output += `\n\n[Project typecheck failed]: ${error}`;
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
async runTscCheck(tsc, baseDir, signal) {
|
|
286
|
-
try {
|
|
287
|
-
await runAsync(`${tsc} --noEmit --skipLibCheck`, baseDir, 30000, signal);
|
|
288
|
-
return null;
|
|
289
|
-
}
|
|
290
|
-
catch (err) {
|
|
291
|
-
if (err.status === 127 ||
|
|
292
|
-
err.message.includes("not found") ||
|
|
293
|
-
err.message.includes("ENOENT")) {
|
|
294
|
-
return null;
|
|
295
|
-
}
|
|
296
|
-
const stderr = err.stderr?.toString() || err.stdout?.toString() || "";
|
|
297
|
-
if (stderr.includes("error TS")) {
|
|
298
|
-
const firstError = stderr.split("\n").find((line) => line.includes("error TS")) ||
|
|
299
|
-
"TypeScript type error";
|
|
300
|
-
return firstError.trim();
|
|
301
|
-
}
|
|
302
|
-
return null;
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
/**
|
|
307
|
-
* Гоняет команду асинхронно (не стопая event loop) и резолвится на выходе.
|
|
308
|
-
* Реджектит с захваченными stderr/stdout при ненулевом коде или таймауте.
|
|
309
|
-
*
|
|
310
|
-
* Простая строка идёт через шелл (проектные скрипты). Спецификация
|
|
311
|
-
* `{file,args}` спавнится БЕЗ шелла — обязательно для всего, собранного из
|
|
312
|
-
* модельного пути (`bun build … <file>`, `node --check <file>`): в имени могут
|
|
313
|
-
* быть `$()`, бектики или `%VAR%`, а shell:true их исполнил бы (инъекция).
|
|
314
|
-
*/
|
|
315
|
-
function runAsync(command, cwd, timeoutMs, signal) {
|
|
316
|
-
return new Promise((resolve, reject) => {
|
|
317
|
-
const child = typeof command === "string"
|
|
318
|
-
? spawn(command, {
|
|
319
|
-
cwd,
|
|
320
|
-
shell: true,
|
|
321
|
-
windowsHide: true,
|
|
322
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
323
|
-
})
|
|
324
|
-
: spawn(command.file, command.args, {
|
|
325
|
-
cwd,
|
|
326
|
-
shell: false,
|
|
327
|
-
windowsHide: true,
|
|
328
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
329
|
-
});
|
|
330
|
-
const utf8Chunks = [];
|
|
331
|
-
const oemChunks = [];
|
|
332
|
-
child.stdout?.on("data", (d) => {
|
|
333
|
-
utf8Chunks.push(Buffer.from(d));
|
|
334
|
-
});
|
|
335
|
-
child.stderr?.on("data", (d) => {
|
|
336
|
-
oemChunks.push(Buffer.from(d));
|
|
337
|
-
});
|
|
338
|
-
const timer = setTimeout(() => {
|
|
339
|
-
child.kill();
|
|
340
|
-
reject(new Error(`Command timed out after ${timeoutMs}ms`));
|
|
341
|
-
}, timeoutMs);
|
|
342
|
-
// Прерывание (Esc/Ctrl+C): убиваем ребёнка, чтобы петля агента сразу
|
|
343
|
-
// вернулась в промпт, а не высиживала длинный tsc/lint. Хендлер close
|
|
344
|
-
// при аборте резолвит пусто — гард `signal.aborted` вызывающего результат
|
|
345
|
-
// всё равно отбрасывает.
|
|
346
|
-
const onAbort = () => child.kill();
|
|
347
|
-
if (signal?.aborted) {
|
|
348
|
-
child.kill();
|
|
349
|
-
}
|
|
350
|
-
else {
|
|
351
|
-
signal?.addEventListener("abort", onAbort, { once: true });
|
|
352
|
-
}
|
|
353
|
-
child.on("error", (err) => {
|
|
354
|
-
clearTimeout(timer);
|
|
355
|
-
signal?.removeEventListener("abort", onAbort);
|
|
356
|
-
if (signal?.aborted) {
|
|
357
|
-
resolve({ stdout: decodeOutput(utf8Chunks), stderr: decodeOutput(oemChunks) });
|
|
358
|
-
}
|
|
359
|
-
else {
|
|
360
|
-
reject(err);
|
|
361
|
-
}
|
|
362
|
-
});
|
|
363
|
-
child.on("close", (code) => {
|
|
364
|
-
clearTimeout(timer);
|
|
365
|
-
signal?.removeEventListener("abort", onAbort);
|
|
366
|
-
const stdout = decodeOutput(utf8Chunks);
|
|
367
|
-
const stderr = decodeOutput(oemChunks);
|
|
368
|
-
if (signal?.aborted) {
|
|
369
|
-
resolve({ stdout, stderr });
|
|
370
|
-
return;
|
|
371
|
-
}
|
|
372
|
-
settleChildClose(code, stdout, stderr, `Command failed with exit code ${code}`, resolve, reject);
|
|
373
|
-
});
|
|
374
|
-
});
|
|
375
|
-
}
|
|
376
|
-
/** Готовый инстанс для регистрации. */
|
|
377
|
-
export const plugin = new LintOnWritePlugin();
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/** Встроенный плагин: пишет в лог завершение сессии. */
|
|
2
|
-
export class NotifyPlugin {
|
|
3
|
-
name = "notify";
|
|
4
|
-
priority = 5;
|
|
5
|
-
isBuiltin = true;
|
|
6
|
-
onSessionEnd(ctx) {
|
|
7
|
-
ctx.logger.info("Session ended");
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
/** Готовый инстанс для регистрации. */
|
|
11
|
-
export const plugin = new NotifyPlugin();
|