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/assets/setup.js
CHANGED
|
@@ -103,6 +103,7 @@
|
|
|
103
103
|
securityBashBlock: false,
|
|
104
104
|
securityFlagsBlock: false,
|
|
105
105
|
securityPathsRestrict: true,
|
|
106
|
+
securityDetail: { bash: {}, paths: {}, flags: {}, network: {}, advanced: {} },
|
|
106
107
|
},
|
|
107
108
|
};
|
|
108
109
|
|
|
@@ -118,6 +119,12 @@
|
|
|
118
119
|
state.answers.contextWindow = r.data.defaults.contextWindow || state.answers.contextWindow;
|
|
119
120
|
state.answers.maxToolIterations =
|
|
120
121
|
r.data.defaults.maxToolIterations || state.answers.maxToolIterations;
|
|
122
|
+
if (r.data.defaults.security) {
|
|
123
|
+
state.answers.securityDetail = Object.assign(
|
|
124
|
+
state.answers.securityDetail,
|
|
125
|
+
r.data.defaults.security,
|
|
126
|
+
);
|
|
127
|
+
}
|
|
121
128
|
}
|
|
122
129
|
const first = (r.data.providers || [])[0];
|
|
123
130
|
if (first) {
|
|
@@ -137,6 +144,7 @@
|
|
|
137
144
|
// --- rendering -------------------------------------------------------------
|
|
138
145
|
|
|
139
146
|
function render() {
|
|
147
|
+
closePopup();
|
|
140
148
|
const wrap = h("div", "setup-wrap");
|
|
141
149
|
const title = h("h1", "setup-h");
|
|
142
150
|
title.appendChild(h("span", "glyph", "◇"));
|
|
@@ -258,6 +266,27 @@
|
|
|
258
266
|
});
|
|
259
267
|
box.appendChild(field(tr("web.setup.provider.base_url"), input));
|
|
260
268
|
|
|
269
|
+
const actions = h("div", "setup-row-inline");
|
|
270
|
+
const test = h("button", "setup-btn", tr("web.setup.provider.test"));
|
|
271
|
+
test.type = "button";
|
|
272
|
+
test.addEventListener("click", async () => {
|
|
273
|
+
if (!state.answers.apiBase) {
|
|
274
|
+
setMsg(box, "err", tr("web.setup.provider.required"));
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
test.disabled = true;
|
|
278
|
+
setMsg(box, "", tr("web.setup.provider.testing"));
|
|
279
|
+
const r = await api("/api/setup/models", {
|
|
280
|
+
method: "POST",
|
|
281
|
+
body: { baseUrl: state.answers.apiBase, apiKey: state.answers.apiKey },
|
|
282
|
+
});
|
|
283
|
+
test.disabled = false;
|
|
284
|
+
const models = (r.ok && r.data && r.data.models) || [];
|
|
285
|
+
if (r.ok && models.length) setMsg(box, "ok", tr("web.setup.provider.test_ok"));
|
|
286
|
+
else setMsg(box, "warn", tr("web.setup.provider.test_fail"));
|
|
287
|
+
});
|
|
288
|
+
actions.appendChild(test);
|
|
289
|
+
|
|
261
290
|
if (state.answers.provider === "openai-compat" || state.answers.provider === "lmstudio") {
|
|
262
291
|
const scan = h("button", "setup-btn", tr("web.setup.provider.scan"));
|
|
263
292
|
scan.type = "button";
|
|
@@ -291,8 +320,11 @@
|
|
|
291
320
|
results.appendChild(b);
|
|
292
321
|
});
|
|
293
322
|
});
|
|
294
|
-
|
|
323
|
+
actions.appendChild(scan);
|
|
324
|
+
box.appendChild(actions);
|
|
295
325
|
box.appendChild(results);
|
|
326
|
+
} else {
|
|
327
|
+
box.appendChild(actions);
|
|
296
328
|
}
|
|
297
329
|
box.appendChild(messageEl());
|
|
298
330
|
return box;
|
|
@@ -393,6 +425,38 @@
|
|
|
393
425
|
});
|
|
394
426
|
box.appendChild(field(tr("web.setup.context.contextWindow"), cw));
|
|
395
427
|
|
|
428
|
+
const detect = h("button", "setup-btn", tr("web.setup.context.detect"));
|
|
429
|
+
detect.type = "button";
|
|
430
|
+
detect.addEventListener("click", async () => {
|
|
431
|
+
if (!state.answers.apiBase || !state.answers.model) {
|
|
432
|
+
setMsg(box, "err", tr("web.setup.context.detect_fail"));
|
|
433
|
+
return;
|
|
434
|
+
}
|
|
435
|
+
detect.disabled = true;
|
|
436
|
+
setMsg(box, "", tr("web.setup.context.detecting"));
|
|
437
|
+
const r = await api("/api/setup/context", {
|
|
438
|
+
method: "POST",
|
|
439
|
+
body: {
|
|
440
|
+
baseUrl: state.answers.apiBase,
|
|
441
|
+
apiKey: state.answers.apiKey,
|
|
442
|
+
model: state.answers.model,
|
|
443
|
+
providerType: state.answers.provider,
|
|
444
|
+
},
|
|
445
|
+
});
|
|
446
|
+
detect.disabled = false;
|
|
447
|
+
const n = r.ok && r.data && r.data.contextWindow;
|
|
448
|
+
if (r.ok && r.data && r.data.ok && typeof n === "number" && n > 0) {
|
|
449
|
+
state.answers.contextWindow = n;
|
|
450
|
+
cw.value = String(n);
|
|
451
|
+
setMsg(box, "ok", tr("web.setup.context.detect_ok", { count: n }));
|
|
452
|
+
} else {
|
|
453
|
+
setMsg(box, "warn", tr("web.setup.context.detect_fail"));
|
|
454
|
+
}
|
|
455
|
+
});
|
|
456
|
+
const row = h("div", "setup-row-inline");
|
|
457
|
+
row.appendChild(detect);
|
|
458
|
+
box.appendChild(row);
|
|
459
|
+
|
|
396
460
|
const it = h("input", "setup-input");
|
|
397
461
|
it.type = "number";
|
|
398
462
|
it.min = "1";
|
|
@@ -408,25 +472,219 @@
|
|
|
408
472
|
function renderSecurity() {
|
|
409
473
|
const box = stepBody("security");
|
|
410
474
|
const toggles = [
|
|
411
|
-
["securityPathsRestrict", "web.setup.security.paths"],
|
|
412
|
-
["securityBashBlock", "web.setup.security.bash"],
|
|
413
|
-
["securityFlagsBlock", "web.setup.security.flags"],
|
|
475
|
+
["securityPathsRestrict", "web.setup.security.paths", "web.setup.security.paths_desc", "paths"],
|
|
476
|
+
["securityBashBlock", "web.setup.security.bash", "web.setup.security.bash_desc", "bash"],
|
|
477
|
+
["securityFlagsBlock", "web.setup.security.flags", "web.setup.security.flags_desc", "flags"],
|
|
414
478
|
];
|
|
415
|
-
toggles.forEach(([key, labelKey]) => {
|
|
416
|
-
const row = h("
|
|
479
|
+
toggles.forEach(([key, labelKey, descKey, group]) => {
|
|
480
|
+
const row = h("div", "setup-sec-row");
|
|
481
|
+
const label = h("label", "setup-toggle");
|
|
417
482
|
const cb = h("input");
|
|
418
483
|
cb.type = "checkbox";
|
|
419
484
|
cb.checked = Boolean(state.answers[key]);
|
|
420
485
|
cb.addEventListener("change", () => {
|
|
421
486
|
state.answers[key] = cb.checked;
|
|
422
487
|
});
|
|
423
|
-
|
|
424
|
-
|
|
488
|
+
label.appendChild(cb);
|
|
489
|
+
const texts = h("span", "setup-toggle-texts");
|
|
490
|
+
texts.appendChild(h("span", "t", tr(labelKey)));
|
|
491
|
+
const desc = tr(descKey);
|
|
492
|
+
if (desc !== descKey) texts.appendChild(h("span", "d", desc));
|
|
493
|
+
label.appendChild(texts);
|
|
494
|
+
row.appendChild(label);
|
|
495
|
+
row.appendChild(detailButton(group, tr(labelKey)));
|
|
425
496
|
box.appendChild(row);
|
|
426
497
|
});
|
|
498
|
+
|
|
499
|
+
const advRow = h("div", "setup-sec-row");
|
|
500
|
+
const advTexts = h("span", "setup-toggle setup-adv-label");
|
|
501
|
+
advTexts.appendChild(h("span", "t", tr("web.setup.security.advanced")));
|
|
502
|
+
advRow.appendChild(advTexts);
|
|
503
|
+
advRow.appendChild(detailButton("advanced", tr("web.setup.security.advanced")));
|
|
504
|
+
box.appendChild(advRow);
|
|
427
505
|
return box;
|
|
428
506
|
}
|
|
429
507
|
|
|
508
|
+
// Описание поп-апов тонкой настройки: путь в securityDetail + тип поля.
|
|
509
|
+
const SECURITY_POPUPS = {
|
|
510
|
+
paths: [
|
|
511
|
+
["paths.denied", "list", "web.setup.security.denied"],
|
|
512
|
+
["paths.allowed", "list", "web.setup.security.allowed"],
|
|
513
|
+
],
|
|
514
|
+
bash: [
|
|
515
|
+
["bash.blacklist", "list", "web.setup.security.blacklist"],
|
|
516
|
+
["bash.whitelist", "list", "web.setup.security.whitelist"],
|
|
517
|
+
["bash.logCommands", "bool", "web.setup.security.log_commands"],
|
|
518
|
+
],
|
|
519
|
+
flags: [
|
|
520
|
+
["flags.dangerousFlags", "list", "web.setup.security.dangerous_flags"],
|
|
521
|
+
["flags.dangerousOperators", "list", "web.setup.security.dangerous_operators"],
|
|
522
|
+
],
|
|
523
|
+
advanced: [
|
|
524
|
+
["network.enabled", "bool", "web.setup.security.network_enabled"],
|
|
525
|
+
["network.deniedDomains", "list", "web.setup.security.denied_domains"],
|
|
526
|
+
["network.allowedDomains", "list", "web.setup.security.allowed_domains"],
|
|
527
|
+
["network.requestTimeout", "int", "web.setup.security.request_timeout"],
|
|
528
|
+
["network.maxResponseSize", "int", "web.setup.security.max_response_size"],
|
|
529
|
+
["advanced.maxRecursionDepth", "int", "web.setup.security.max_recursion"],
|
|
530
|
+
["advanced.maxFileOperations", "int", "web.setup.security.max_file_ops"],
|
|
531
|
+
["advanced.maxRequestsPerMinute", "int", "web.setup.security.rate_rpm"],
|
|
532
|
+
["advanced.maxParallelTasks", "int", "web.setup.security.rate_parallel"],
|
|
533
|
+
["advanced.contentScanEnabled", "bool", "web.setup.security.content_scan"],
|
|
534
|
+
["advanced.sessionEncryptionEnabled", "bool", "web.setup.security.session_encryption"],
|
|
535
|
+
["advanced.auditNotifierEnabled", "bool", "web.setup.security.audit_enabled"],
|
|
536
|
+
["advanced.auditNotifierMinSeverity", "enum", "web.setup.security.audit_severity"],
|
|
537
|
+
["advanced.auditNotifierEventTypes", "list", "web.setup.security.audit_events"],
|
|
538
|
+
["advanced.auditNotifierMaxRetries", "int", "web.setup.security.audit_retries"],
|
|
539
|
+
["advanced.auditNotifierWebhookTimeout", "int", "web.setup.security.audit_timeout"],
|
|
540
|
+
],
|
|
541
|
+
};
|
|
542
|
+
const SEVERITIES = ["low", "medium", "high", "critical"];
|
|
543
|
+
const GROUP_KEYS = {
|
|
544
|
+
paths: ["paths"],
|
|
545
|
+
bash: ["bash"],
|
|
546
|
+
flags: ["flags"],
|
|
547
|
+
advanced: ["network", "advanced"],
|
|
548
|
+
};
|
|
549
|
+
|
|
550
|
+
function getPath(obj, path) {
|
|
551
|
+
return path.split(".").reduce((o, k) => (o == null ? undefined : o[k]), obj);
|
|
552
|
+
}
|
|
553
|
+
function setPath(obj, path, value) {
|
|
554
|
+
const keys = path.split(".");
|
|
555
|
+
let cur = obj;
|
|
556
|
+
for (let i = 0; i < keys.length - 1; i++) {
|
|
557
|
+
if (typeof cur[keys[i]] !== "object" || cur[keys[i]] === null) cur[keys[i]] = {};
|
|
558
|
+
cur = cur[keys[i]];
|
|
559
|
+
}
|
|
560
|
+
cur[keys[keys.length - 1]] = value;
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
function detailButton(group, title) {
|
|
564
|
+
const btn = h("button", "setup-detail-btn");
|
|
565
|
+
btn.type = "button";
|
|
566
|
+
btn.appendChild(h("span", "g", "⚙"));
|
|
567
|
+
btn.appendChild(h("span", "t", tr("web.setup.security.configure")));
|
|
568
|
+
btn.title = title;
|
|
569
|
+
btn.addEventListener("click", (e) => {
|
|
570
|
+
e.preventDefault();
|
|
571
|
+
openSecurityPopup(group, title);
|
|
572
|
+
});
|
|
573
|
+
return btn;
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
let popup = null;
|
|
577
|
+
|
|
578
|
+
function openSecurityPopup(group, title) {
|
|
579
|
+
const overlay = h("div", "setup-overlay");
|
|
580
|
+
const modal = h("div", "setup-modal");
|
|
581
|
+
modal.setAttribute("role", "dialog");
|
|
582
|
+
modal.setAttribute("aria-modal", "true");
|
|
583
|
+
|
|
584
|
+
const head = h("div", "setup-modal-head");
|
|
585
|
+
const hIcon = h("span", "glyph", "⚙");
|
|
586
|
+
head.appendChild(hIcon);
|
|
587
|
+
head.appendChild(h("span", "setup-modal-title", title));
|
|
588
|
+
const close = h("button", "setup-modal-x", "✕");
|
|
589
|
+
close.type = "button";
|
|
590
|
+
close.addEventListener("click", closePopup);
|
|
591
|
+
head.appendChild(close);
|
|
592
|
+
modal.appendChild(head);
|
|
593
|
+
|
|
594
|
+
const body = h("div", "setup-modal-body");
|
|
595
|
+
body.appendChild(h("p", "setup-hint", tr("web.setup.security.popup_hint")));
|
|
596
|
+
SECURITY_POPUPS[group].forEach(([path, type, labelKey]) => {
|
|
597
|
+
body.appendChild(popupField(path, type, tr(labelKey)));
|
|
598
|
+
});
|
|
599
|
+
modal.appendChild(body);
|
|
600
|
+
|
|
601
|
+
const foot = h("div", "setup-modal-foot");
|
|
602
|
+
const reset = h("button", "setup-btn link", tr("web.setup.security.reset"));
|
|
603
|
+
reset.type = "button";
|
|
604
|
+
reset.addEventListener("click", () => {
|
|
605
|
+
const defaults = (state.display && state.display.defaults && state.display.defaults.security) || {};
|
|
606
|
+
(GROUP_KEYS[group] || [group]).forEach((src) => {
|
|
607
|
+
const fresh = defaults[src] || {};
|
|
608
|
+
Object.keys(fresh).forEach((k) => setPath(state.answers.securityDetail, src + "." + k, fresh[k]));
|
|
609
|
+
});
|
|
610
|
+
closePopup();
|
|
611
|
+
openSecurityPopup(group, title);
|
|
612
|
+
});
|
|
613
|
+
foot.appendChild(reset);
|
|
614
|
+
foot.appendChild(h("span", "spacer"));
|
|
615
|
+
const done = h("button", "setup-btn primary", tr("web.setup.security.popup_done"));
|
|
616
|
+
done.type = "button";
|
|
617
|
+
done.addEventListener("click", closePopup);
|
|
618
|
+
foot.appendChild(done);
|
|
619
|
+
modal.appendChild(foot);
|
|
620
|
+
|
|
621
|
+
overlay.appendChild(modal);
|
|
622
|
+
overlay.addEventListener("click", (e) => {
|
|
623
|
+
if (e.target === overlay) closePopup();
|
|
624
|
+
});
|
|
625
|
+
popup = overlay;
|
|
626
|
+
gate.appendChild(overlay);
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
function popupField(path, type, label) {
|
|
630
|
+
const wrap = h("div", "setup-field");
|
|
631
|
+
if (type === "list") {
|
|
632
|
+
wrap.appendChild(h("label", "setup-label", label));
|
|
633
|
+
const ta = h("textarea", "setup-input setup-textarea");
|
|
634
|
+
const cur = getPath(state.answers.securityDetail, path);
|
|
635
|
+
ta.value = Array.isArray(cur) ? cur.join("\n") : "";
|
|
636
|
+
ta.rows = 5;
|
|
637
|
+
ta.spellcheck = false;
|
|
638
|
+
ta.addEventListener("input", () => {
|
|
639
|
+
const items = ta.value
|
|
640
|
+
.split("\n")
|
|
641
|
+
.map((s) => s.trim())
|
|
642
|
+
.filter(Boolean);
|
|
643
|
+
setPath(state.answers.securityDetail, path, items);
|
|
644
|
+
});
|
|
645
|
+
wrap.appendChild(ta);
|
|
646
|
+
} else if (type === "bool") {
|
|
647
|
+
const row = h("label", "setup-toggle");
|
|
648
|
+
const cb = h("input");
|
|
649
|
+
cb.type = "checkbox";
|
|
650
|
+
cb.checked = Boolean(getPath(state.answers.securityDetail, path));
|
|
651
|
+
cb.addEventListener("change", () => setPath(state.answers.securityDetail, path, cb.checked));
|
|
652
|
+
row.appendChild(cb);
|
|
653
|
+
row.appendChild(h("span", "t", label));
|
|
654
|
+
wrap.appendChild(row);
|
|
655
|
+
} else if (type === "int") {
|
|
656
|
+
wrap.appendChild(h("label", "setup-label", label));
|
|
657
|
+
const inp = h("input", "setup-input");
|
|
658
|
+
inp.type = "number";
|
|
659
|
+
inp.min = "1";
|
|
660
|
+
const cur = getPath(state.answers.securityDetail, path);
|
|
661
|
+
inp.value = typeof cur === "number" ? String(cur) : "";
|
|
662
|
+
inp.addEventListener("input", () => {
|
|
663
|
+
const n = parseInt(inp.value, 10);
|
|
664
|
+
setPath(state.answers.securityDetail, path, Number.isFinite(n) && n > 0 ? n : undefined);
|
|
665
|
+
});
|
|
666
|
+
wrap.appendChild(inp);
|
|
667
|
+
} else if (type === "enum") {
|
|
668
|
+
wrap.appendChild(h("label", "setup-label", label));
|
|
669
|
+
const sel = h("select", "setup-input");
|
|
670
|
+
const cur = getPath(state.answers.securityDetail, path);
|
|
671
|
+
SEVERITIES.forEach((sev) => {
|
|
672
|
+
const opt = h("option", null, tr("web.setup.security.severity." + sev));
|
|
673
|
+
opt.value = sev;
|
|
674
|
+
if (cur === sev) opt.selected = true;
|
|
675
|
+
sel.appendChild(opt);
|
|
676
|
+
});
|
|
677
|
+
sel.addEventListener("change", () => setPath(state.answers.securityDetail, path, sel.value));
|
|
678
|
+
wrap.appendChild(sel);
|
|
679
|
+
}
|
|
680
|
+
return wrap;
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
function closePopup() {
|
|
684
|
+
if (popup && popup.parentNode) popup.parentNode.removeChild(popup);
|
|
685
|
+
popup = null;
|
|
686
|
+
}
|
|
687
|
+
|
|
430
688
|
function securitySummary() {
|
|
431
689
|
const on = [];
|
|
432
690
|
if (state.answers.securityPathsRestrict) on.push(tr("web.setup.security.paths"));
|
|
@@ -534,6 +792,7 @@
|
|
|
534
792
|
securityBashBlock: state.answers.securityBashBlock,
|
|
535
793
|
securityFlagsBlock: state.answers.securityFlagsBlock,
|
|
536
794
|
securityPathsRestrict: state.answers.securityPathsRestrict,
|
|
795
|
+
securityDetail: state.answers.securityDetail,
|
|
537
796
|
},
|
|
538
797
|
});
|
|
539
798
|
if (!r.ok) {
|
package/dist/assets/styles.css
CHANGED
|
@@ -229,7 +229,7 @@ body[data-font="large"] { font-size: 17px; }
|
|
|
229
229
|
.layout { flex: 1; display: flex; min-height: 0; }
|
|
230
230
|
|
|
231
231
|
/* chat */
|
|
232
|
-
.chat { flex: 1; display: flex; flex-direction: column; min-width: 0; }
|
|
232
|
+
.chat { flex: 1; display: flex; flex-direction: column; min-width: 0; position: relative; }
|
|
233
233
|
.msgs { flex: 1; overflow-y: auto; overflow-x: hidden; padding: 18px 22px; display: flex; flex-direction: column; gap: 11px; }
|
|
234
234
|
.msgs > * { flex-shrink: 0; min-height: fit-content; }
|
|
235
235
|
/* messages live inside a per-tab `.feed` wrapper; it must mirror the `.msgs`
|
|
@@ -452,6 +452,18 @@ body.light .imgcard .ph { background: var(--ph-light); }
|
|
|
452
452
|
}
|
|
453
453
|
.empty .g { color: var(--green); }
|
|
454
454
|
|
|
455
|
+
/* jump-to-latest pill: only visible when the reader scrolled up */
|
|
456
|
+
.to-latest {
|
|
457
|
+
position: absolute; left: 50%; bottom: 148px; transform: translateX(-50%);
|
|
458
|
+
z-index: 20; font: inherit; font-size: 12.5px; cursor: pointer;
|
|
459
|
+
color: var(--accent); background: var(--panel);
|
|
460
|
+
border: 1px solid var(--border-2); border-radius: 999px;
|
|
461
|
+
padding: 5px 14px; box-shadow: var(--shadow-menu);
|
|
462
|
+
white-space: nowrap;
|
|
463
|
+
}
|
|
464
|
+
.to-latest:hover { border-color: var(--accent); }
|
|
465
|
+
.to-latest[hidden] { display: none; }
|
|
466
|
+
|
|
455
467
|
/* ---- composer: selectors, attachments, input, autocomplete ---- */
|
|
456
468
|
.input-area { margin: 14px 22px 16px; position: relative; }
|
|
457
469
|
.selectors { display: flex; gap: 8px; margin-bottom: 8px; flex-wrap: wrap; min-width: 0; }
|
|
@@ -590,6 +602,61 @@ body.light .sel > button { border: 1px solid var(--border); }
|
|
|
590
602
|
.input-area.dragover .composer { border-color: var(--accent); box-shadow: 0 0 0 2px var(--input-shadow); }
|
|
591
603
|
@keyframes blink { 50% { opacity: 0; } }
|
|
592
604
|
|
|
605
|
+
/* ---- chat motion ("magic"): entrances, caret, pulses, pops -----------------
|
|
606
|
+
Rules: only opacity/transform animations (never height/margin), 100–200ms,
|
|
607
|
+
calm single pulses. Killed globally by the `prefers-reduced-motion` block
|
|
608
|
+
below. Glyphs stay textual per STYLE.md — motion, not decoration. */
|
|
609
|
+
@keyframes rise { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
|
|
610
|
+
@keyframes pop { from { opacity: 0; transform: scale(.98) translateY(2px); } to { opacity: 1; transform: none; } }
|
|
611
|
+
@keyframes softPulse { 50% { opacity: .45; } }
|
|
612
|
+
@keyframes fadeIn { from { opacity: 0; } }
|
|
613
|
+
|
|
614
|
+
/* new rows rise in softly (a bulk history render animates once as a whole —
|
|
615
|
+
one shared fade, still cheap: opacity/transform only) */
|
|
616
|
+
.feed > :is(.u, .md, .act, .think, .q, .filecard, .planblock, .imgcard, .linkline,
|
|
617
|
+
.toolout, .metric, .detail, .metaln, .warnline, .errline, .cmdout, .sysline,
|
|
618
|
+
.startbanner, .grouped, .msg-actions, .busy) {
|
|
619
|
+
animation: rise .18s ease-out;
|
|
620
|
+
}
|
|
621
|
+
/* quiet-mode run folding fades instead of snapping away */
|
|
622
|
+
.fold-out { opacity: 0; transition: opacity .15s ease-out; }
|
|
623
|
+
|
|
624
|
+
/* streaming caret at the tail of live markdown */
|
|
625
|
+
.md.streaming::after {
|
|
626
|
+
content: "▌"; color: var(--accent); margin-left: 2px;
|
|
627
|
+
animation: blink 1s steps(2, start) infinite;
|
|
628
|
+
}
|
|
629
|
+
/* alive labels: in-feed spinner, the *live* think block, rail phase,
|
|
630
|
+
a running tool. Finished blocks stay static — a pulsing "думаю" after
|
|
631
|
+
the turn reads as hung. */
|
|
632
|
+
.busy .lab, .think.live .think-h .lab, .rail-l1 .lab, .act.running .lab {
|
|
633
|
+
animation: softPulse 1.6s ease-in-out infinite;
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
/* menus, autocomplete and dialogs pop instead of snapping */
|
|
637
|
+
.dd.open .dd-menu, .sel.open .menu, .cmdk:not([hidden]) { animation: pop .12s ease-out; }
|
|
638
|
+
.to-latest:not([hidden]) { animation: pop .15s ease-out; }
|
|
639
|
+
.overlay.open { animation: fadeIn .15s ease-out; }
|
|
640
|
+
.overlay.open .modal { animation: rise .18s ease-out; }
|
|
641
|
+
|
|
642
|
+
/* hover/active blends */
|
|
643
|
+
.sel > button, .menu .mi, .stab, .q .qopt, .q .qsend, .filecard, .icon-btn,
|
|
644
|
+
.btn, .linkbtn, .chip, .cb-copy, .act-btn, .copy-btn, .composer .attach-btn,
|
|
645
|
+
.composer .send-btn, .dd-menu .si, .dd-menu .act, .cmdk-item, .toggle {
|
|
646
|
+
transition: background-color .12s, color .12s, border-color .12s;
|
|
647
|
+
}
|
|
648
|
+
.composer { transition: border-color .15s, box-shadow .15s; }
|
|
649
|
+
|
|
650
|
+
/* scroll edge fades on the transcript (classes from the feed scroll hook) */
|
|
651
|
+
.msgs::before, .msgs::after {
|
|
652
|
+
content: ""; position: sticky; display: block; height: 22px; flex: 0 0 auto;
|
|
653
|
+
pointer-events: none; z-index: 5; opacity: 0; transition: opacity .25s;
|
|
654
|
+
}
|
|
655
|
+
.msgs::before { top: 0; margin-bottom: -22px; background: linear-gradient(var(--bg), transparent); }
|
|
656
|
+
.msgs::after { bottom: 0; margin-top: -22px; background: linear-gradient(transparent, var(--bg)); }
|
|
657
|
+
.msgs.scrolled::before { opacity: 1; }
|
|
658
|
+
.msgs.unfollowed::after { opacity: 1; }
|
|
659
|
+
|
|
593
660
|
/* ---- activity rail — indicator above the composer while a turn runs ----
|
|
594
661
|
Reproduces docs/design/ui/demo-activity-rail-chat.html (variant №12).
|
|
595
662
|
`l-line` (default) = compact one-liner, `l-meta` = inside the hint row,
|
|
@@ -686,6 +753,66 @@ body.light .sel > button { border: 1px solid var(--border); }
|
|
|
686
753
|
.sec.plan-sec { flex: 1 1 auto; }
|
|
687
754
|
.sec.usage-sec { flex: 0 1 auto; max-height: 45%; }
|
|
688
755
|
|
|
756
|
+
/* ---- sidebar tabs ---- */
|
|
757
|
+
.sb-tabs { display: flex; gap: 6px; padding: 10px 14px; border-bottom: 1px solid var(--border); flex-shrink: 0; }
|
|
758
|
+
.sb-tab {
|
|
759
|
+
position: relative; width: 34px; height: 34px; flex: 0 0 auto;
|
|
760
|
+
display: inline-flex; align-items: center; justify-content: center; padding: 0;
|
|
761
|
+
border: 1px solid var(--border-2); border-radius: 6px;
|
|
762
|
+
background: transparent; color: var(--stab-fg); cursor: pointer; font: inherit;
|
|
763
|
+
}
|
|
764
|
+
.sb-tab:hover { color: var(--fg); background: var(--hover-bg); }
|
|
765
|
+
.sb-tab.on { color: var(--accent); background: var(--accent-bg); border-color: transparent; }
|
|
766
|
+
.sb-tab .sb-ico svg { width: 17px; height: 17px; }
|
|
767
|
+
.sb-tab .sb-dot {
|
|
768
|
+
position: absolute; top: 4px; right: 4px; width: 6px; height: 6px; border-radius: 50%;
|
|
769
|
+
background: var(--accent); opacity: 0; transition: opacity .2s;
|
|
770
|
+
}
|
|
771
|
+
.sb-tab[data-indicator="live"] .sb-dot { opacity: 1; animation: sbPulse 1s ease-in-out infinite; }
|
|
772
|
+
.sb-tab[data-indicator="busy"] .sb-dot { opacity: 1; background: var(--accent); }
|
|
773
|
+
.sb-tab[data-indicator="stale"] .sb-dot { opacity: 1; background: var(--yellow); }
|
|
774
|
+
@keyframes sbPulse { 0%,100% { opacity: 1 } 50% { opacity: .25 } }
|
|
775
|
+
|
|
776
|
+
.sb-name {
|
|
777
|
+
display: flex; align-items: center; gap: 8px; flex-shrink: 0;
|
|
778
|
+
padding: 10px 16px; color: var(--fg); font-size: 12.5px; font-weight: 600;
|
|
779
|
+
letter-spacing: .03em; border-bottom: 1px solid var(--border);
|
|
780
|
+
}
|
|
781
|
+
.sb-name .sb-ico svg { width: 14px; height: 14px; color: var(--accent); }
|
|
782
|
+
|
|
783
|
+
.sb-pane { display: flex; flex-direction: column; flex: 1; min-height: 0; }
|
|
784
|
+
.sb-pane[hidden] { display: none; }
|
|
785
|
+
|
|
786
|
+
/* master-detail expansion */
|
|
787
|
+
.sb { transition: width .22s ease, min-width .22s ease; }
|
|
788
|
+
.sb.sb-expanded { width: 680px; min-width: 680px; }
|
|
789
|
+
#pane-trace { flex-direction: row; }
|
|
790
|
+
.sb-expanded #pane-trace { position: relative; }
|
|
791
|
+
.trace-list { flex: 1; min-width: 0; overflow-y: auto; padding: 6px 10px 12px; display: flex; flex-direction: column; gap: 1px; }
|
|
792
|
+
.trace-turn { color: var(--dim-c); font-size: 11px; margin: 8px 6px 2px; }
|
|
793
|
+
.trc { display: flex; gap: 8px; align-items: baseline; padding: 4px 6px; font-size: 12px; color: var(--muted); border-radius: 4px; cursor: pointer; }
|
|
794
|
+
.trc:hover { background: var(--hover-bg); }
|
|
795
|
+
.trc.sel { background: var(--accent-bg); }
|
|
796
|
+
.trc .g { flex: 0 0 auto; }
|
|
797
|
+
.trc.recon .g { color: var(--cyan); } .trc.mutate .g { color: var(--purple); }
|
|
798
|
+
.trc.execute .g { color: var(--accent); } .trc.meta .g { color: var(--meta); } .trc.phase .g { color: var(--think); }
|
|
799
|
+
.trc .lab { color: var(--fg); white-space: nowrap; }
|
|
800
|
+
.trc .args { color: var(--args); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; flex: 1; }
|
|
801
|
+
.trc .t { color: var(--dim-b); margin-left: auto; flex: 0 0 auto; }
|
|
802
|
+
.trc.warn .g, .trc.warn .lab { color: var(--yellow); }
|
|
803
|
+
.trc.phase .lab { color: var(--think); }
|
|
804
|
+
.trc-detail { display: flex; flex-direction: column; flex: 0 0 340px; min-width: 0; border-left: 1px solid var(--border); }
|
|
805
|
+
.trc-detail[hidden] { display: none; }
|
|
806
|
+
.detail-h { display: flex; gap: 8px; align-items: center; padding: 10px 14px; border-bottom: 1px solid var(--border); color: var(--fg); font-size: 12.5px; flex-shrink: 0; }
|
|
807
|
+
.detail-h .g { color: var(--accent); }
|
|
808
|
+
.detail-h .x { margin-left: auto; color: var(--dim-b); cursor: pointer; }
|
|
809
|
+
.detail-b { padding: 10px 14px; display: flex; flex-direction: column; gap: 12px; overflow-y: auto; }
|
|
810
|
+
.detail-b h5 { margin: 0 0 4px; font-size: 10.5px; text-transform: uppercase; letter-spacing: .06em; color: var(--sec-h); font-weight: 600; }
|
|
811
|
+
.map-sec { flex: 1 1 auto; }
|
|
812
|
+
.map-reindex { margin-top: 10px; font: inherit; font-size: 12px; color: var(--accent); background: transparent; border: 1px solid var(--border-2); border-radius: 5px; padding: 4px 10px; cursor: pointer; width: fit-content; }
|
|
813
|
+
.map-reindex:disabled { color: var(--dim-b); cursor: default; }
|
|
814
|
+
.kv.wn b { color: var(--yellow); }
|
|
815
|
+
|
|
689
816
|
::-webkit-scrollbar { width: 8px; }
|
|
690
817
|
::-webkit-scrollbar-thumb { background: var(--scroll-thumb); border-radius: 4px; }
|
|
691
818
|
|
|
@@ -1212,6 +1339,7 @@ button.toggle:disabled { opacity: .5; cursor: default; }
|
|
|
1212
1339
|
.chat { min-height: 0; }
|
|
1213
1340
|
/* Phones: sidebar hidden, opens as an overlay drawer via body.sb-open. */
|
|
1214
1341
|
.sb { display: none; }
|
|
1342
|
+
.sb-tab[data-tab="trace"], #pane-trace { display: none; }
|
|
1215
1343
|
body.sb-open .sb {
|
|
1216
1344
|
display: flex; position: fixed; top: 41px; right: 0; bottom: 0; z-index: 45;
|
|
1217
1345
|
width: min(360px, 85vw); min-width: 0; max-height: none;
|
|
@@ -1349,8 +1477,45 @@ body.setup-active .layout { display: none; }
|
|
|
1349
1477
|
.setup-summary .k { color: var(--dim-a); width: 150px; flex: 0 0 auto; }
|
|
1350
1478
|
.setup-summary .v { color: var(--fg); word-break: break-all; }
|
|
1351
1479
|
|
|
1352
|
-
.setup-toggle { display: flex; align-items:
|
|
1353
|
-
.setup-toggle input { accent-color: var(--green-fill); width: 15px; height: 15px; }
|
|
1480
|
+
.setup-toggle { display: flex; align-items: flex-start; gap: 9px; padding: 7px 0; font-size: 13px; cursor: pointer; }
|
|
1481
|
+
.setup-toggle input { accent-color: var(--green-fill); width: 15px; height: 15px; margin-top: 2px; flex: 0 0 auto; }
|
|
1482
|
+
.setup-toggle-texts { display: flex; flex-direction: column; gap: 2px; }
|
|
1483
|
+
.setup-toggle-texts .t { font-weight: 500; }
|
|
1484
|
+
.setup-toggle-texts .d { color: var(--dim-a); font-size: 12px; line-height: 1.5; }
|
|
1485
|
+
|
|
1486
|
+
.setup-sec-row { display: flex; align-items: center; gap: 8px; }
|
|
1487
|
+
.setup-sec-row .setup-toggle { flex: 1; }
|
|
1488
|
+
.setup-adv-label { padding: 7px 0; }
|
|
1489
|
+
.setup-detail-btn {
|
|
1490
|
+
display: inline-flex; align-items: center; gap: 5px; flex: 0 0 auto;
|
|
1491
|
+
background: transparent; color: var(--dim-a);
|
|
1492
|
+
border: 1px solid var(--border); border-radius: 7px;
|
|
1493
|
+
padding: 5px 9px; font-size: 12px; font-family: inherit; cursor: pointer;
|
|
1494
|
+
}
|
|
1495
|
+
.setup-detail-btn:hover { background: var(--hover-bg); color: var(--fg); }
|
|
1496
|
+
.setup-detail-btn .g { color: var(--accent); }
|
|
1497
|
+
|
|
1498
|
+
.setup-textarea { resize: vertical; min-height: 84px; font-family: var(--mono, ui-monospace, monospace); font-size: 12.5px; line-height: 1.5; }
|
|
1499
|
+
|
|
1500
|
+
.setup-overlay {
|
|
1501
|
+
position: fixed; inset: 0; z-index: 60;
|
|
1502
|
+
background: rgba(0, 0, 0, .55);
|
|
1503
|
+
display: flex; align-items: center; justify-content: center; padding: 20px;
|
|
1504
|
+
}
|
|
1505
|
+
.setup-modal {
|
|
1506
|
+
width: 100%; max-width: 560px; max-height: 86vh; display: flex; flex-direction: column;
|
|
1507
|
+
background: var(--surface); border: 1px solid var(--border-2); border-radius: 10px;
|
|
1508
|
+
box-shadow: 0 18px 50px rgba(0, 0, 0, .45);
|
|
1509
|
+
}
|
|
1510
|
+
.setup-modal-head { display: flex; align-items: center; gap: 8px; padding: 14px 16px; border-bottom: 1px solid var(--border-3); }
|
|
1511
|
+
.setup-modal-head .glyph { color: var(--accent); }
|
|
1512
|
+
.setup-modal-title { font-weight: 600; font-size: 14px; flex: 1; }
|
|
1513
|
+
.setup-modal-x { background: none; border: none; color: var(--dim-a); font-size: 15px; cursor: pointer; padding: 2px 6px; }
|
|
1514
|
+
.setup-modal-x:hover { color: var(--fg); }
|
|
1515
|
+
.setup-modal-body { padding: 14px 16px; overflow-y: auto; }
|
|
1516
|
+
.setup-modal-body .setup-field:last-child { margin-bottom: 0; }
|
|
1517
|
+
.setup-modal-foot { display: flex; align-items: center; gap: 10px; padding: 12px 16px; border-top: 1px solid var(--border-3); }
|
|
1518
|
+
.setup-modal-foot .spacer { flex: 1; }
|
|
1354
1519
|
|
|
1355
1520
|
@media (max-width: 640px) {
|
|
1356
1521
|
.setup-gate { padding: 24px 14px; }
|
package/dist/cli/cache-line.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
// Подсказки при опечатках в командах: расстояние Левенштейна.
|
|
2
|
+
/** Редакционное расстояние Левенштейна между строками (без учёта регистра). */
|
|
2
3
|
export function levenshtein(a, b) {
|
|
3
4
|
const s = a.toLowerCase();
|
|
4
5
|
const t = b.toLowerCase();
|
|
@@ -20,9 +21,9 @@ export function levenshtein(a, b) {
|
|
|
20
21
|
return prev[t.length];
|
|
21
22
|
}
|
|
22
23
|
/**
|
|
23
|
-
*
|
|
24
|
-
* `undefined
|
|
25
|
-
* (`mma sesion list`)
|
|
24
|
+
* Известная команда, чьё имя в пределах `maxDistance` от `input`, или
|
|
25
|
+
* `undefined`, если близких нет. Ловит опечатки в субкомандах
|
|
26
|
+
* (`mma sesion list`), которые иначе молча ушли бы в LLM.
|
|
26
27
|
*/
|
|
27
28
|
export function closestCommand(input, known, maxDistance = 2) {
|
|
28
29
|
let best;
|