@hoilab/ada-cli 0.84.21 → 0.84.22
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 +20 -0
- package/README.es.md +163 -0
- package/README.md +99 -652
- package/dist/cli/args.d.ts +3 -0
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +11 -0
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/file-processor.d.ts.map +1 -1
- package/dist/cli/file-processor.js +2 -1
- package/dist/cli/file-processor.js.map +1 -1
- package/dist/cli/home-screen.d.ts.map +1 -1
- package/dist/cli/home-screen.js +2 -2
- package/dist/cli/home-screen.js.map +1 -1
- package/dist/cli/startup-ui.d.ts.map +1 -1
- package/dist/cli/startup-ui.js +9 -3
- package/dist/cli/startup-ui.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +2 -1
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session.d.ts +57 -7
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +449 -73
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +4 -3
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js +3 -0
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +4 -3
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +41 -32
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/defaults.d.ts +1 -0
- package/dist/core/defaults.d.ts.map +1 -1
- package/dist/core/defaults.js +9 -0
- package/dist/core/defaults.js.map +1 -1
- package/dist/core/engine-personality.d.ts +12 -0
- package/dist/core/engine-personality.d.ts.map +1 -0
- package/dist/core/engine-personality.js +53 -0
- package/dist/core/engine-personality.js.map +1 -0
- package/dist/core/extensions/index.d.ts +1 -1
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +10 -5
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/types.d.ts +23 -4
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +2 -1
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/memory-engine/audit-export.d.ts +54 -0
- package/dist/core/memory-engine/audit-export.d.ts.map +1 -0
- package/dist/core/memory-engine/audit-export.js +85 -0
- package/dist/core/memory-engine/audit-export.js.map +1 -0
- package/dist/core/memory-engine/audit.d.ts.map +1 -1
- package/dist/core/memory-engine/audit.js +7 -8
- package/dist/core/memory-engine/audit.js.map +1 -1
- package/dist/core/memory-engine/engine.d.ts +2 -3
- package/dist/core/memory-engine/engine.d.ts.map +1 -1
- package/dist/core/memory-engine/engine.js +148 -50
- package/dist/core/memory-engine/engine.js.map +1 -1
- package/dist/core/memory-engine/inverted-index.d.ts.map +1 -1
- package/dist/core/memory-engine/inverted-index.js +67 -10
- package/dist/core/memory-engine/inverted-index.js.map +1 -1
- package/dist/core/memory-engine/keychain.d.ts.map +1 -1
- package/dist/core/memory-engine/keychain.js +1 -6
- package/dist/core/memory-engine/keychain.js.map +1 -1
- package/dist/core/memory-engine/observation-store.d.ts +1 -0
- package/dist/core/memory-engine/observation-store.d.ts.map +1 -1
- package/dist/core/memory-engine/observation-store.js +37 -8
- package/dist/core/memory-engine/observation-store.js.map +1 -1
- package/dist/core/memory-engine/scanner.d.ts.map +1 -1
- package/dist/core/memory-engine/scanner.js +25 -5
- package/dist/core/memory-engine/scanner.js.map +1 -1
- package/dist/core/memory-engine/security.d.ts.map +1 -1
- package/dist/core/memory-engine/security.js +131 -23
- package/dist/core/memory-engine/security.js.map +1 -1
- package/dist/core/memory-engine/session-indexer.d.ts.map +1 -1
- package/dist/core/memory-engine/session-indexer.js +8 -2
- package/dist/core/memory-engine/session-indexer.js.map +1 -1
- package/dist/core/memory-engine/tools.d.ts +2 -2
- package/dist/core/memory-engine/tools.d.ts.map +1 -1
- package/dist/core/memory-engine/tools.js +14 -7
- package/dist/core/memory-engine/tools.js.map +1 -1
- package/dist/core/memory-engine/vault.d.ts.map +1 -1
- package/dist/core/memory-engine/vault.js +2 -2
- package/dist/core/memory-engine/vault.js.map +1 -1
- package/dist/core/model-config.d.ts.map +1 -1
- package/dist/core/model-config.js +2 -1
- package/dist/core/model-config.js.map +1 -1
- package/dist/core/model-resolver.d.ts +1 -0
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +12 -6
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/models-store.d.ts.map +1 -1
- package/dist/core/models-store.js +2 -1
- package/dist/core/models-store.js.map +1 -1
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +11 -6
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/pi-manifest.d.ts.map +1 -1
- package/dist/core/pi-manifest.js +2 -1
- package/dist/core/pi-manifest.js.map +1 -1
- package/dist/core/prompt-optimizer.d.ts +53 -0
- package/dist/core/prompt-optimizer.d.ts.map +1 -0
- package/dist/core/prompt-optimizer.js +138 -0
- package/dist/core/prompt-optimizer.js.map +1 -0
- package/dist/core/provider-attribution.d.ts.map +1 -1
- package/dist/core/provider-attribution.js +1 -1
- package/dist/core/provider-attribution.js.map +1 -1
- package/dist/core/remote-catalog-provider.d.ts.map +1 -1
- package/dist/core/remote-catalog-provider.js +2 -1
- package/dist/core/remote-catalog-provider.js.map +1 -1
- package/dist/core/resource-loader.d.ts +50 -0
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +233 -7
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/sdk.d.ts +8 -0
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +11 -1
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +2 -1
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-diagnostics.d.ts +9 -0
- package/dist/core/settings-diagnostics.d.ts.map +1 -0
- package/dist/core/settings-diagnostics.js +21 -0
- package/dist/core/settings-diagnostics.js.map +1 -0
- package/dist/core/settings-manager.d.ts +52 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +204 -10
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js +51 -33
- package/dist/core/skills.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +2 -1
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/tools/edit-diff.d.ts +0 -5
- package/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/dist/core/tools/edit-diff.js +2 -5
- package/dist/core/tools/edit-diff.js.map +1 -1
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +20 -4
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +2 -2
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/project-memory-tool.d.ts.map +1 -1
- package/dist/core/tools/project-memory-tool.js +4 -1
- package/dist/core/tools/project-memory-tool.js.map +1 -1
- package/dist/core/trust-manager.d.ts.map +1 -1
- package/dist/core/trust-manager.js +2 -1
- package/dist/core/trust-manager.js.map +1 -1
- package/dist/core/workflows/agent-runner.d.ts +86 -0
- package/dist/core/workflows/agent-runner.d.ts.map +1 -0
- package/dist/core/workflows/agent-runner.js +225 -0
- package/dist/core/workflows/agent-runner.js.map +1 -0
- package/dist/core/workflows/builtins.d.ts +41 -0
- package/dist/core/workflows/builtins.d.ts.map +1 -0
- package/dist/core/workflows/builtins.js +282 -0
- package/dist/core/workflows/builtins.js.map +1 -0
- package/dist/core/workflows/goal-engine/engine.d.ts +134 -0
- package/dist/core/workflows/goal-engine/engine.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/engine.js +462 -0
- package/dist/core/workflows/goal-engine/engine.js.map +1 -0
- package/dist/core/workflows/goal-engine/errors.d.ts +7 -0
- package/dist/core/workflows/goal-engine/errors.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/errors.js +9 -0
- package/dist/core/workflows/goal-engine/errors.js.map +1 -0
- package/dist/core/workflows/goal-engine/index.d.ts +13 -0
- package/dist/core/workflows/goal-engine/index.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/index.js +8 -0
- package/dist/core/workflows/goal-engine/index.js.map +1 -0
- package/dist/core/workflows/goal-engine/persistence.d.ts +31 -0
- package/dist/core/workflows/goal-engine/persistence.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/persistence.js +145 -0
- package/dist/core/workflows/goal-engine/persistence.js.map +1 -0
- package/dist/core/workflows/goal-engine/prompts.d.ts +37 -0
- package/dist/core/workflows/goal-engine/prompts.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/prompts.js +131 -0
- package/dist/core/workflows/goal-engine/prompts.js.map +1 -0
- package/dist/core/workflows/goal-engine/state.d.ts +41 -0
- package/dist/core/workflows/goal-engine/state.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/state.js +397 -0
- package/dist/core/workflows/goal-engine/state.js.map +1 -0
- package/dist/core/workflows/goal-engine/tools.d.ts +31 -0
- package/dist/core/workflows/goal-engine/tools.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/tools.js +211 -0
- package/dist/core/workflows/goal-engine/tools.js.map +1 -0
- package/dist/core/workflows/goal-engine/types.d.ts +286 -0
- package/dist/core/workflows/goal-engine/types.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/types.js +17 -0
- package/dist/core/workflows/goal-engine/types.js.map +1 -0
- package/dist/core/workflows/goal-engine/worktree-fingerprint.d.ts +23 -0
- package/dist/core/workflows/goal-engine/worktree-fingerprint.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/worktree-fingerprint.js +72 -0
- package/dist/core/workflows/goal-engine/worktree-fingerprint.js.map +1 -0
- package/dist/core/workflows/graph-sync.d.ts +67 -0
- package/dist/core/workflows/graph-sync.d.ts.map +1 -0
- package/dist/core/workflows/graph-sync.js +188 -0
- package/dist/core/workflows/graph-sync.js.map +1 -0
- package/dist/core/workflows/graph.d.ts +143 -0
- package/dist/core/workflows/graph.d.ts.map +1 -0
- package/dist/core/workflows/graph.js +319 -0
- package/dist/core/workflows/graph.js.map +1 -0
- package/dist/core/workflows/index.d.ts +18 -0
- package/dist/core/workflows/index.d.ts.map +1 -0
- package/dist/core/workflows/index.js +14 -0
- package/dist/core/workflows/index.js.map +1 -0
- package/dist/core/workflows/journal.d.ts +68 -0
- package/dist/core/workflows/journal.d.ts.map +1 -0
- package/dist/core/workflows/journal.js +83 -0
- package/dist/core/workflows/journal.js.map +1 -0
- package/dist/core/workflows/manager.d.ts +112 -0
- package/dist/core/workflows/manager.d.ts.map +1 -0
- package/dist/core/workflows/manager.js +327 -0
- package/dist/core/workflows/manager.js.map +1 -0
- package/dist/core/workflows/resolve-script.d.ts +35 -0
- package/dist/core/workflows/resolve-script.d.ts.map +1 -0
- package/dist/core/workflows/resolve-script.js +66 -0
- package/dist/core/workflows/resolve-script.js.map +1 -0
- package/dist/core/workflows/runtime.d.ts +49 -0
- package/dist/core/workflows/runtime.d.ts.map +1 -0
- package/dist/core/workflows/runtime.js +301 -0
- package/dist/core/workflows/runtime.js.map +1 -0
- package/dist/core/workflows/shared-store.d.ts +31 -0
- package/dist/core/workflows/shared-store.d.ts.map +1 -0
- package/dist/core/workflows/shared-store.js +80 -0
- package/dist/core/workflows/shared-store.js.map +1 -0
- package/dist/core/workflows/subagent-host.d.ts +50 -0
- package/dist/core/workflows/subagent-host.d.ts.map +1 -0
- package/dist/core/workflows/subagent-host.js +225 -0
- package/dist/core/workflows/subagent-host.js.map +1 -0
- package/dist/core/workflows/tool-workflow.d.ts +22 -0
- package/dist/core/workflows/tool-workflow.d.ts.map +1 -0
- package/dist/core/workflows/tool-workflow.js +120 -0
- package/dist/core/workflows/tool-workflow.js.map +1 -0
- package/dist/core/workflows/types.d.ts +142 -0
- package/dist/core/workflows/types.d.ts.map +1 -0
- package/dist/core/workflows/types.js +26 -0
- package/dist/core/workflows/types.js.map +1 -0
- package/dist/core/workflows/worktree.d.ts +42 -0
- package/dist/core/workflows/worktree.d.ts.map +1 -0
- package/dist/core/workflows/worktree.js +107 -0
- package/dist/core/workflows/worktree.js.map +1 -0
- package/dist/extensions/llama/index.d.ts.map +1 -1
- package/dist/extensions/llama/index.js +2 -0
- package/dist/extensions/llama/index.js.map +1 -1
- package/dist/extensions/llama/provider.d.ts.map +1 -1
- package/dist/extensions/llama/provider.js +6 -2
- package/dist/extensions/llama/provider.js.map +1 -1
- package/dist/index.d.ts +16 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -11
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts +4 -0
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +20 -15
- package/dist/main.js.map +1 -1
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js +4 -3
- package/dist/migrations.js.map +1 -1
- package/dist/modes/interactive/components/home-screen.d.ts.map +1 -1
- package/dist/modes/interactive/components/home-screen.js +2 -2
- package/dist/modes/interactive/components/home-screen.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts +2 -3
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +16 -6
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/prompt-optimization.d.ts +16 -0
- package/dist/modes/interactive/components/prompt-optimization.d.ts.map +1 -0
- package/dist/modes/interactive/components/prompt-optimization.js +46 -0
- package/dist/modes/interactive/components/prompt-optimization.js.map +1 -0
- package/dist/modes/interactive/components/settings-selector.d.ts +19 -1
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +247 -46
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-submenu.d.ts +72 -0
- package/dist/modes/interactive/components/settings-submenu.d.ts.map +1 -0
- package/dist/modes/interactive/components/settings-submenu.js +165 -0
- package/dist/modes/interactive/components/settings-submenu.js.map +1 -0
- package/dist/modes/interactive/components/thinking-selector.d.ts +8 -3
- package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.js +29 -3
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
- package/dist/modes/interactive/external-editor.d.ts.map +1 -1
- package/dist/modes/interactive/external-editor.js +2 -1
- package/dist/modes/interactive/external-editor.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +24 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +677 -34
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +4 -3
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/json-event.d.ts +16 -13
- package/dist/modes/json-event.d.ts.map +1 -1
- package/dist/modes/json-event.js +20 -6
- package/dist/modes/json-event.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +173 -0
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +29 -0
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/package-manager-cli.d.ts.map +1 -1
- package/dist/package-manager-cli.js +1 -1
- package/dist/package-manager-cli.js.map +1 -1
- package/dist/skills/ada-engine/SKILL.md +153 -0
- package/dist/utils/frontmatter.d.ts.map +1 -1
- package/dist/utils/frontmatter.js +2 -1
- package/dist/utils/frontmatter.js.map +1 -1
- package/dist/utils/management-http.d.ts +5 -3
- package/dist/utils/management-http.d.ts.map +1 -1
- package/dist/utils/management-http.js +14 -10
- package/dist/utils/management-http.js.map +1 -1
- package/dist/utils/text.d.ts +8 -0
- package/dist/utils/text.d.ts.map +1 -0
- package/dist/utils/text.js +9 -0
- package/dist/utils/text.js.map +1 -0
- package/docs/compaction.md +15 -0
- package/docs/custom-provider.md +5 -2
- package/docs/extensions.md +11 -2
- package/docs/json.md +7 -2
- package/docs/llama-cpp.md +2 -0
- package/docs/models.md +8 -2
- package/docs/rpc.md +9 -3
- package/docs/settings.md +2 -2
- package/docs/skills.md +4 -3
- package/examples/extensions/border-status-editor.ts +1 -1
- package/examples/extensions/git-checkpoint.ts +2 -2
- package/examples/extensions/notify.ts +3 -1
- package/examples/extensions/subagent/README.md +1 -1
- package/examples/extensions/subagent/index.ts +6 -1
- package/examples/extensions/titlebar-spinner.ts +1 -1
- package/examples/rpc-extension-ui.ts +1 -1
- package/examples/sdk/06-extensions.ts +1 -1
- package/examples/sdk/README.md +1 -1
- package/npm-shrinkwrap.json +2 -12
- package/package.json +3 -3
|
@@ -14,6 +14,7 @@ import { APP_NAME, APP_TITLE, CONFIG_DIR_NAME, getAgentDir, getAuthPath, getDebu
|
|
|
14
14
|
import { parseSkillBlock } from "../../core/agent-session.js";
|
|
15
15
|
import { SessionImportFileNotFoundError } from "../../core/agent-session-runtime.js";
|
|
16
16
|
import { CACHE_TTL_MS, collectCacheMisses, computeCacheWaste, detectCacheMiss, } from "../../core/cache-stats.js";
|
|
17
|
+
import { DEFAULT_THINKING_LEVEL, THINKING_LEVEL_OPTIONS } from "../../core/defaults.js";
|
|
17
18
|
import { FooterDataProvider } from "../../core/footer-data-provider.js";
|
|
18
19
|
import { configureHttpDispatcher, formatHttpIdleTimeoutMs } from "../../core/http-dispatcher.js";
|
|
19
20
|
import { KeybindingsManager } from "../../core/keybindings.js";
|
|
@@ -27,6 +28,7 @@ import { BUILTIN_SLASH_COMMANDS } from "../../core/slash-commands.js";
|
|
|
27
28
|
import { isInstallTelemetryEnabled } from "../../core/telemetry.js";
|
|
28
29
|
import { hasTrustRequiringProjectResources, ProjectTrustStore } from "../../core/trust-manager.js";
|
|
29
30
|
import { getUsageCostBreakdown } from "../../core/usage-totals.js";
|
|
31
|
+
import { reduceGoal } from "../../core/workflows/goal-engine/state.js";
|
|
30
32
|
import { getChangelogPath, getNewEntries, normalizeChangelogLinks, parseChangelog } from "../../utils/changelog.js";
|
|
31
33
|
import { copyToClipboard, readClipboardText } from "../../utils/clipboard.js";
|
|
32
34
|
import { extensionForImageMimeType, readClipboardImage } from "../../utils/clipboard-image.js";
|
|
@@ -58,11 +60,13 @@ import { LoginDialogComponent } from "./components/login-dialog.js";
|
|
|
58
60
|
import { createMermaidMarkdownTransformer } from "./components/mermaid.js";
|
|
59
61
|
import { ModelSelectorComponent } from "./components/model-selector.js";
|
|
60
62
|
import { formatAuthSelectorProviderType, OAuthSelectorComponent, } from "./components/oauth-selector.js";
|
|
63
|
+
import { PromptOptimization } from "./components/prompt-optimization.js";
|
|
61
64
|
import { ScopedModelsSelectorComponent } from "./components/scoped-models-selector.js";
|
|
62
65
|
import { SessionSelectorComponent } from "./components/session-selector.js";
|
|
63
66
|
import { SettingsSelectorComponent } from "./components/settings-selector.js";
|
|
64
67
|
import { SkillInvocationMessageComponent } from "./components/skill-invocation-message.js";
|
|
65
68
|
import { BranchSummaryStatusIndicator, CompactionStatusIndicator, IdleStatus, RetryStatusIndicator, WorkingStatusIndicator, } from "./components/status-indicator.js";
|
|
69
|
+
import { ThinkingSelectorComponent } from "./components/thinking-selector.js";
|
|
66
70
|
import { ToolExecutionComponent } from "./components/tool-execution.js";
|
|
67
71
|
import { TreeSelectorComponent } from "./components/tree-selector.js";
|
|
68
72
|
import { TrustSelectorComponent } from "./components/trust-selector.js";
|
|
@@ -91,6 +95,9 @@ class ExpandableText extends Text {
|
|
|
91
95
|
function isCustomSessionEntry(item) {
|
|
92
96
|
return "type" in item && item.type === "custom";
|
|
93
97
|
}
|
|
98
|
+
function isCompactionCostNotice(item) {
|
|
99
|
+
return "type" in item && item.type === "compaction_cost";
|
|
100
|
+
}
|
|
94
101
|
const DEAD_TERMINAL_ERROR_CODES = new Set(["EIO", "EPIPE", "ENOTCONN"]);
|
|
95
102
|
function isDeadTerminalError(error) {
|
|
96
103
|
if (!error || typeof error !== "object" || !("code" in error)) {
|
|
@@ -99,6 +106,34 @@ function isDeadTerminalError(error) {
|
|
|
99
106
|
const code = error.code;
|
|
100
107
|
return code !== undefined && DEAD_TERMINAL_ERROR_CODES.has(code);
|
|
101
108
|
}
|
|
109
|
+
export function parseDefaultFlagArgs(commandName, args) {
|
|
110
|
+
if (!args?.trim())
|
|
111
|
+
return { persist: false };
|
|
112
|
+
let persist = false;
|
|
113
|
+
const searchTerms = [];
|
|
114
|
+
for (const token of args.trim().split(/\s+/u)) {
|
|
115
|
+
if (token === "--default") {
|
|
116
|
+
persist = true;
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
if (token.startsWith("--default=")) {
|
|
120
|
+
persist = true;
|
|
121
|
+
const value = token.slice("--default=".length);
|
|
122
|
+
if (value)
|
|
123
|
+
searchTerms.push(value);
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
if (token.startsWith("--")) {
|
|
127
|
+
return {
|
|
128
|
+
persist,
|
|
129
|
+
searchTerm: searchTerms.join(" ") || undefined,
|
|
130
|
+
error: `Unknown /${commandName} option "${token}". Supported option: --default.`,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
searchTerms.push(token);
|
|
134
|
+
}
|
|
135
|
+
return { persist, searchTerm: searchTerms.join(" ") || undefined };
|
|
136
|
+
}
|
|
102
137
|
const ANTHROPIC_SUBSCRIPTION_AUTH_WARNING = "Anthropic subscription auth is active. Third-party harness usage draws from extra usage and is billed per token, not your Claude plan limits. Manage extra usage at https://claude.ai/settings/usage. Disable this warning in /settings.";
|
|
103
138
|
function isAnthropicSubscriptionAuthKey(apiKey) {
|
|
104
139
|
return typeof apiKey === "string" && apiKey.startsWith("sk-ant-oat");
|
|
@@ -130,6 +165,11 @@ export function formatResumeCommand(sessionManager) {
|
|
|
130
165
|
function hasDefaultModelProvider(providerId) {
|
|
131
166
|
return providerId in defaultModelPerProvider;
|
|
132
167
|
}
|
|
168
|
+
function llamaCppPostLoginGuidance(actionLabel, loadedModelCount) {
|
|
169
|
+
return loadedModelCount === 0
|
|
170
|
+
? `${actionLabel}. No llama.cpp models are loaded. Use /llama to load a model, then /model to select it.`
|
|
171
|
+
: `${actionLabel}. Use /model to select a loaded llama.cpp model, or /llama to manage models.`;
|
|
172
|
+
}
|
|
133
173
|
const AUTH_TYPE_ORDER = { oauth: 0, api_key: 1 };
|
|
134
174
|
function createFuzzyAutocompleteItems(items, prefix, getSearchText, toAutocompleteItem) {
|
|
135
175
|
const filtered = fuzzyFilter(items, prefix, getSearchText);
|
|
@@ -446,6 +486,15 @@ export class InteractiveMode {
|
|
|
446
486
|
const modelCommand = slashCommands.find((command) => command.name === "model");
|
|
447
487
|
if (modelCommand) {
|
|
448
488
|
modelCommand.getArgumentCompletions = (prefix) => {
|
|
489
|
+
const trimmedPrefix = prefix.trimStart();
|
|
490
|
+
if (trimmedPrefix.startsWith("--") && !trimmedPrefix.includes(" ")) {
|
|
491
|
+
return "--default".startsWith(trimmedPrefix)
|
|
492
|
+
? [{ value: "--default ", label: "--default", description: "Set as startup default" }]
|
|
493
|
+
: null;
|
|
494
|
+
}
|
|
495
|
+
const parsed = parseDefaultFlagArgs("model", prefix);
|
|
496
|
+
if (parsed.error)
|
|
497
|
+
return null;
|
|
449
498
|
const models = this.session.scopedModels.length > 0
|
|
450
499
|
? this.session.scopedModels.map((s) => s.model)
|
|
451
500
|
: this.session.modelRuntime.getAvailableSnapshot();
|
|
@@ -458,10 +507,31 @@ export class InteractiveMode {
|
|
|
458
507
|
name: m.name,
|
|
459
508
|
label: `${m.provider}/${m.id}`,
|
|
460
509
|
}));
|
|
461
|
-
|
|
462
|
-
|
|
510
|
+
const searchPrefix = parsed.persist ? (parsed.searchTerm ?? "") : prefix;
|
|
511
|
+
return createFuzzyAutocompleteItems(items, searchPrefix, getModelSearchText, (item) => ({
|
|
512
|
+
value: parsed.persist ? `--default ${item.label}` : item.label,
|
|
463
513
|
label: item.id,
|
|
464
|
-
description: item.provider,
|
|
514
|
+
description: parsed.persist ? `${item.provider} · set as startup default` : item.provider,
|
|
515
|
+
}));
|
|
516
|
+
};
|
|
517
|
+
}
|
|
518
|
+
const thinkingCommand = slashCommands.find((command) => command.name === "thinking");
|
|
519
|
+
if (thinkingCommand) {
|
|
520
|
+
thinkingCommand.getArgumentCompletions = (prefix) => {
|
|
521
|
+
const trimmedPrefix = prefix.trimStart();
|
|
522
|
+
if (trimmedPrefix.startsWith("--") && !trimmedPrefix.includes(" ")) {
|
|
523
|
+
return "--default".startsWith(trimmedPrefix)
|
|
524
|
+
? [{ value: "--default ", label: "--default", description: "Set as startup default" }]
|
|
525
|
+
: null;
|
|
526
|
+
}
|
|
527
|
+
const parsed = parseDefaultFlagArgs("thinking", prefix);
|
|
528
|
+
if (parsed.error)
|
|
529
|
+
return null;
|
|
530
|
+
const searchPrefix = parsed.persist ? (parsed.searchTerm ?? "") : prefix;
|
|
531
|
+
return createFuzzyAutocompleteItems(this.session.getAvailableThinkingLevels(), searchPrefix, (level) => level, (level) => ({
|
|
532
|
+
value: parsed.persist ? `--default ${level}` : level,
|
|
533
|
+
label: level,
|
|
534
|
+
description: parsed.persist ? "set as startup default" : undefined,
|
|
465
535
|
}));
|
|
466
536
|
};
|
|
467
537
|
}
|
|
@@ -679,7 +749,7 @@ export class InteractiveMode {
|
|
|
679
749
|
const accent = (text) => theme.fg("accent", text);
|
|
680
750
|
const dim = (text) => theme.fg("dim", text);
|
|
681
751
|
const muted = (text) => theme.fg("muted", text);
|
|
682
|
-
const
|
|
752
|
+
const _logo = theme.bold(theme.fg("accent", APP_NAME)) + theme.fg("dim", ` v${this.version}`);
|
|
683
753
|
// Welcome screen (central): ASCII logo + environment status + quick commands
|
|
684
754
|
const asciiLogo = [
|
|
685
755
|
" █████╗ ██████╗ █████╗",
|
|
@@ -836,7 +906,18 @@ export class InteractiveMode {
|
|
|
836
906
|
}
|
|
837
907
|
});
|
|
838
908
|
// Show startup warnings
|
|
839
|
-
const { migratedProviders, modelFallbackMessage, initialMessage, initialImages, initialMessages } = this.options;
|
|
909
|
+
const { migratedProviders, startupDiagnostics, modelFallbackMessage, initialMessage, initialImages, initialMessages, } = this.options;
|
|
910
|
+
for (const diagnostic of startupDiagnostics ?? []) {
|
|
911
|
+
if (diagnostic.type === "error") {
|
|
912
|
+
this.showError(diagnostic.message);
|
|
913
|
+
}
|
|
914
|
+
else if (diagnostic.type === "warning") {
|
|
915
|
+
this.showWarning(diagnostic.message);
|
|
916
|
+
}
|
|
917
|
+
else {
|
|
918
|
+
this.showStatus(diagnostic.message);
|
|
919
|
+
}
|
|
920
|
+
}
|
|
840
921
|
if (migratedProviders && migratedProviders.length > 0) {
|
|
841
922
|
this.showWarning(`Migrated credentials to auth.json: ${migratedProviders.join(", ")}`);
|
|
842
923
|
}
|
|
@@ -2373,9 +2454,23 @@ export class InteractiveMode {
|
|
|
2373
2454
|
return;
|
|
2374
2455
|
}
|
|
2375
2456
|
if (text === "/model" || text.startsWith("/model ")) {
|
|
2376
|
-
const
|
|
2457
|
+
const args = parseDefaultFlagArgs("model", text.startsWith("/model ") ? text.slice(7).trim() : undefined);
|
|
2377
2458
|
this.editor.setText("");
|
|
2378
|
-
|
|
2459
|
+
if (args.error) {
|
|
2460
|
+
this.showError(args.error);
|
|
2461
|
+
return;
|
|
2462
|
+
}
|
|
2463
|
+
await this.handleModelCommand(args.searchTerm, { persist: args.persist });
|
|
2464
|
+
return;
|
|
2465
|
+
}
|
|
2466
|
+
if (text === "/thinking" || text.startsWith("/thinking ")) {
|
|
2467
|
+
const args = parseDefaultFlagArgs("thinking", text.startsWith("/thinking ") ? text.slice(10).trim() : undefined);
|
|
2468
|
+
this.editor.setText("");
|
|
2469
|
+
if (args.error) {
|
|
2470
|
+
this.showError(args.error);
|
|
2471
|
+
return;
|
|
2472
|
+
}
|
|
2473
|
+
this.handleThinkingCommand(args.searchTerm, { persist: args.persist });
|
|
2379
2474
|
return;
|
|
2380
2475
|
}
|
|
2381
2476
|
if (text === "/export" || text.startsWith("/export ")) {
|
|
@@ -2429,6 +2524,24 @@ export class InteractiveMode {
|
|
|
2429
2524
|
void this.handleVaultCommand(args);
|
|
2430
2525
|
return;
|
|
2431
2526
|
}
|
|
2527
|
+
if (text === "/goal" || text.startsWith("/goal ")) {
|
|
2528
|
+
const args = text.startsWith("/goal ") ? text.slice(6).trim() : "";
|
|
2529
|
+
this.editor.setText("");
|
|
2530
|
+
void this.handleGoalCommand(args);
|
|
2531
|
+
return;
|
|
2532
|
+
}
|
|
2533
|
+
if (text === "/graph" || text.startsWith("/graph ")) {
|
|
2534
|
+
const args = text.startsWith("/graph ") ? text.slice(7).trim() : "";
|
|
2535
|
+
this.editor.setText("");
|
|
2536
|
+
void this.handleGraphCommand(args);
|
|
2537
|
+
return;
|
|
2538
|
+
}
|
|
2539
|
+
if (text === "/workflow" || text.startsWith("/workflow ")) {
|
|
2540
|
+
const args = text.startsWith("/workflow ") ? text.slice(10).trim() : "";
|
|
2541
|
+
this.editor.setText("");
|
|
2542
|
+
void this.handleWorkflowCommand(args);
|
|
2543
|
+
return;
|
|
2544
|
+
}
|
|
2432
2545
|
if (text === "/changelog") {
|
|
2433
2546
|
this.handleChangelogCommand();
|
|
2434
2547
|
this.editor.setText("");
|
|
@@ -2584,6 +2697,9 @@ export class InteractiveMode {
|
|
|
2584
2697
|
this.showStatus(event.message);
|
|
2585
2698
|
}
|
|
2586
2699
|
break;
|
|
2700
|
+
case "prompt_optimization":
|
|
2701
|
+
this.showPromptOptimization(event);
|
|
2702
|
+
break;
|
|
2587
2703
|
case "agent_start":
|
|
2588
2704
|
this.pendingTools.clear();
|
|
2589
2705
|
if (this.settingsManager.getShowTerminalProgress()) {
|
|
@@ -2788,9 +2904,21 @@ export class InteractiveMode {
|
|
|
2788
2904
|
}
|
|
2789
2905
|
}
|
|
2790
2906
|
else if (event.result) {
|
|
2907
|
+
const entries = this.sessionManager.buildContextEntries();
|
|
2908
|
+
if (entries[0]?.type !== "compaction") {
|
|
2909
|
+
throw new Error("Completed compaction is missing from the session context");
|
|
2910
|
+
}
|
|
2791
2911
|
this.chatContainer.clear();
|
|
2792
|
-
|
|
2912
|
+
// The latest compaction is prepended for model context; append it below at its chronological position.
|
|
2913
|
+
this.renderSessionEntries(entries.slice(1));
|
|
2793
2914
|
this.addMessageToChat(createCompactionSummaryMessage(event.result.summary, event.result.tokensBefore, new Date().toISOString()));
|
|
2915
|
+
if (event.result.usage) {
|
|
2916
|
+
this.addCompactionCostNotice({
|
|
2917
|
+
type: "compaction_cost",
|
|
2918
|
+
kind: "compaction",
|
|
2919
|
+
usage: event.result.usage,
|
|
2920
|
+
});
|
|
2921
|
+
}
|
|
2794
2922
|
this.footer.invalidate();
|
|
2795
2923
|
}
|
|
2796
2924
|
else if (event.errorMessage) {
|
|
@@ -2882,6 +3010,23 @@ export class InteractiveMode {
|
|
|
2882
3010
|
* If multiple status messages are emitted back-to-back (without anything else being added to the chat),
|
|
2883
3011
|
* we update the previous status line instead of appending new ones to avoid log spam.
|
|
2884
3012
|
*/
|
|
3013
|
+
/** Muestra cómo el optimizador mejoró el prompt (o qué pregunta aclarar). */
|
|
3014
|
+
showPromptOptimization(event) {
|
|
3015
|
+
const component = new PromptOptimization(this.ui, event);
|
|
3016
|
+
if (this.streamingComponent) {
|
|
3017
|
+
const idx = this.chatContainer.children.indexOf(this.streamingComponent);
|
|
3018
|
+
if (idx >= 0) {
|
|
3019
|
+
this.chatContainer.children.splice(idx, 0, component);
|
|
3020
|
+
}
|
|
3021
|
+
else {
|
|
3022
|
+
this.chatContainer.addChild(component);
|
|
3023
|
+
}
|
|
3024
|
+
}
|
|
3025
|
+
else {
|
|
3026
|
+
this.chatContainer.addChild(component);
|
|
3027
|
+
}
|
|
3028
|
+
this.ui.requestRender();
|
|
3029
|
+
}
|
|
2885
3030
|
showStatus(message) {
|
|
2886
3031
|
const children = this.chatContainer.children;
|
|
2887
3032
|
const last = children.length > 0 ? children[children.length - 1] : undefined;
|
|
@@ -2936,8 +3081,7 @@ export class InteractiveMode {
|
|
|
2936
3081
|
// (sensitive data will not be stored in memory).
|
|
2937
3082
|
const text = customMessageText(message.content);
|
|
2938
3083
|
this.chatContainer.addChild(new Spacer(1));
|
|
2939
|
-
this.chatContainer.addChild(new Text(theme.fg("warning", "⚠️ ") + theme.bold(theme.fg("warning", "Ada Memory"))
|
|
2940
|
-
"\n" + text, 1, 0));
|
|
3084
|
+
this.chatContainer.addChild(new Text(`${theme.fg("warning", "⚠️ ") + theme.bold(theme.fg("warning", "Ada Memory"))}\n${text}`, 1, 0));
|
|
2941
3085
|
break;
|
|
2942
3086
|
}
|
|
2943
3087
|
const renderer = this.session.extensionRunner.getMessageRenderer(message.customType);
|
|
@@ -3021,6 +3165,10 @@ export class InteractiveMode {
|
|
|
3021
3165
|
this.addCustomEntryToChat(item);
|
|
3022
3166
|
continue;
|
|
3023
3167
|
}
|
|
3168
|
+
if (isCompactionCostNotice(item)) {
|
|
3169
|
+
this.addCompactionCostNotice(item);
|
|
3170
|
+
continue;
|
|
3171
|
+
}
|
|
3024
3172
|
const message = item;
|
|
3025
3173
|
// Assistant messages need special handling for tool calls
|
|
3026
3174
|
if (message.role === "assistant") {
|
|
@@ -3088,10 +3236,28 @@ export class InteractiveMode {
|
|
|
3088
3236
|
if (entry.type === "custom") {
|
|
3089
3237
|
return [entry];
|
|
3090
3238
|
}
|
|
3091
|
-
|
|
3239
|
+
const messages = sessionEntryToContextMessages(entry);
|
|
3240
|
+
if ((entry.type === "compaction" || entry.type === "branch_summary") && entry.usage && messages.length > 0) {
|
|
3241
|
+
return [...messages, { type: "compaction_cost", kind: entry.type, usage: entry.usage }];
|
|
3242
|
+
}
|
|
3243
|
+
return messages;
|
|
3092
3244
|
});
|
|
3093
3245
|
this.renderSessionItems(items, options);
|
|
3094
3246
|
}
|
|
3247
|
+
/**
|
|
3248
|
+
* Render billing usage for a compaction or branch summary. The notice is derived
|
|
3249
|
+
* from persisted summary usage and is not stored as a separate session entry.
|
|
3250
|
+
*/
|
|
3251
|
+
addCompactionCostNotice(notice) {
|
|
3252
|
+
if (!this.settingsManager.getShowCacheMissNotices())
|
|
3253
|
+
return;
|
|
3254
|
+
const { usage } = notice;
|
|
3255
|
+
const tokens = usage.input + usage.output + usage.cacheRead + usage.cacheWrite;
|
|
3256
|
+
const cost = usage.cost.total >= 0.01 ? ` (~$${usage.cost.total.toFixed(2)})` : "";
|
|
3257
|
+
const label = notice.kind === "compaction" ? "Compaction" : "Branch summary";
|
|
3258
|
+
this.chatContainer.addChild(new Spacer(1));
|
|
3259
|
+
this.chatContainer.addChild(new Text(theme.fg("warning", `${label}: ${formatTokens(tokens)} tokens billed${cost}`), 1, 0));
|
|
3260
|
+
}
|
|
3095
3261
|
/**
|
|
3096
3262
|
* Show a transcript notice when a completed assistant message paid for a
|
|
3097
3263
|
* significant cache miss. Only states observable facts: the miss itself,
|
|
@@ -3728,21 +3894,34 @@ export class InteractiveMode {
|
|
|
3728
3894
|
showSettingsSelector() {
|
|
3729
3895
|
this.showSelector((done) => {
|
|
3730
3896
|
let selector;
|
|
3897
|
+
const defaultProvider = this.settingsManager.getDefaultProvider();
|
|
3898
|
+
const defaultModelId = this.settingsManager.getDefaultModel();
|
|
3899
|
+
const defaultModel = defaultProvider && defaultModelId ? `${defaultProvider}/${defaultModelId}` : "not set";
|
|
3731
3900
|
selector = new SettingsSelectorComponent({
|
|
3732
3901
|
autoCompact: this.session.autoCompactionEnabled,
|
|
3902
|
+
defaultModel,
|
|
3903
|
+
availableDefaultModels: this.session.modelRuntime.getAvailableSnapshot(),
|
|
3733
3904
|
showImages: this.settingsManager.getShowImages(),
|
|
3734
3905
|
imageWidthCells: this.settingsManager.getImageWidthCells(),
|
|
3735
3906
|
autoResizeImages: this.settingsManager.getImageAutoResize(),
|
|
3736
3907
|
blockImages: this.settingsManager.getBlockImages(),
|
|
3737
3908
|
projectMemory: this.settingsManager.getProjectMemoryEnabled(),
|
|
3738
3909
|
memoryMode: this.settingsManager.getMemoryMode(),
|
|
3910
|
+
// Ada Intelligence Engine (§16.2)
|
|
3911
|
+
workflowsEnabled: this.settingsManager.getWorkflowsEnabled(),
|
|
3912
|
+
goalEngineEnabled: this.settingsManager.getGoalEngineEnabled(),
|
|
3913
|
+
goalWorkTier: this.settingsManager.getGoalWorkTier(),
|
|
3914
|
+
goalMaxTurns: this.settingsManager.getGoalMaxTurns(),
|
|
3915
|
+
goalRepeatTolerance: this.settingsManager.getGoalRepeatTolerance(),
|
|
3916
|
+
promptOptimizerMode: this.settingsManager.getPromptOptimizerMode(),
|
|
3739
3917
|
enableSkillCommands: this.settingsManager.getEnableSkillCommands(),
|
|
3740
3918
|
steeringMode: this.session.steeringMode,
|
|
3741
3919
|
followUpMode: this.session.followUpMode,
|
|
3742
3920
|
transport: this.settingsManager.getTransport(),
|
|
3743
3921
|
httpIdleTimeoutMs: this.settingsManager.getHttpIdleTimeoutMs(),
|
|
3744
|
-
thinkingLevel: this.
|
|
3745
|
-
availableThinkingLevels:
|
|
3922
|
+
thinkingLevel: this.settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL,
|
|
3923
|
+
availableThinkingLevels: [...THINKING_LEVEL_OPTIONS],
|
|
3924
|
+
modelThinkingLevels: this.settingsManager.getAllModelThinkingLevels(),
|
|
3746
3925
|
currentTheme: this.themeController.getThemeSelection() || "dark",
|
|
3747
3926
|
terminalTheme: this.themeController.getTerminalTheme(),
|
|
3748
3927
|
availableThemes: getAvailableThemes(),
|
|
@@ -3770,6 +3949,19 @@ export class InteractiveMode {
|
|
|
3770
3949
|
this.session.setAutoCompactionEnabled(enabled);
|
|
3771
3950
|
this.footer.setAutoCompactEnabled(enabled);
|
|
3772
3951
|
},
|
|
3952
|
+
onDefaultModelChange: async (model) => {
|
|
3953
|
+
try {
|
|
3954
|
+
await this.session.setModel(model, { persist: true });
|
|
3955
|
+
this.footer.invalidate();
|
|
3956
|
+
this.updateEditorBorderColor();
|
|
3957
|
+
this.showStatus(`Default model: ${model.provider}/${model.id}`);
|
|
3958
|
+
void this.maybeWarnAboutAnthropicSubscriptionAuth(model);
|
|
3959
|
+
this.checkDaxnutsEasterEgg(model);
|
|
3960
|
+
}
|
|
3961
|
+
catch (error) {
|
|
3962
|
+
this.showError(error instanceof Error ? error.message : String(error));
|
|
3963
|
+
}
|
|
3964
|
+
},
|
|
3773
3965
|
onShowImagesChange: (enabled) => {
|
|
3774
3966
|
this.settingsManager.setShowImages(enabled);
|
|
3775
3967
|
for (const child of this.chatContainer.children) {
|
|
@@ -3800,6 +3992,26 @@ export class InteractiveMode {
|
|
|
3800
3992
|
// Rebuild the prompt so the new injection mode takes effect.
|
|
3801
3993
|
this.session.rebuildSystemPrompt();
|
|
3802
3994
|
},
|
|
3995
|
+
onWorkflowsEnabledChange: (enabled) => {
|
|
3996
|
+
this.settingsManager.setWorkflowsEnabled(enabled);
|
|
3997
|
+
},
|
|
3998
|
+
onPromptOptimizerModeChange: (mode) => {
|
|
3999
|
+
this.settingsManager.setPromptOptimizerMode(mode);
|
|
4000
|
+
// Aplica el modo en la sesión en vivo (sin reiniciar).
|
|
4001
|
+
this.session.setPromptOptimizerMode(mode);
|
|
4002
|
+
},
|
|
4003
|
+
onGoalEngineEnabledChange: (enabled) => {
|
|
4004
|
+
this.settingsManager.setGoalEngineEnabled(enabled);
|
|
4005
|
+
},
|
|
4006
|
+
onGoalWorkTierChange: (tier) => {
|
|
4007
|
+
this.settingsManager.setGoalWorkTier(tier);
|
|
4008
|
+
},
|
|
4009
|
+
onGoalMaxTurnsChange: (turns) => {
|
|
4010
|
+
this.settingsManager.setGoalMaxTurns(turns);
|
|
4011
|
+
},
|
|
4012
|
+
onRepeatToleranceChange: (tolerance) => {
|
|
4013
|
+
this.settingsManager.setGoalRepeatTolerance(tolerance);
|
|
4014
|
+
},
|
|
3803
4015
|
onEnableSkillCommandsChange: (enabled) => {
|
|
3804
4016
|
this.settingsManager.setEnableSkillCommands(enabled);
|
|
3805
4017
|
this.setupAutocompleteProvider();
|
|
@@ -3820,10 +4032,31 @@ export class InteractiveMode {
|
|
|
3820
4032
|
this.showStatus(`HTTP idle timeout: ${formatHttpIdleTimeoutMs(timeoutMs)}`);
|
|
3821
4033
|
},
|
|
3822
4034
|
onThinkingLevelChange: (level) => {
|
|
3823
|
-
this.session.setThinkingLevel(level);
|
|
4035
|
+
this.session.setThinkingLevel(level, { persist: true });
|
|
3824
4036
|
this.footer.invalidate();
|
|
3825
4037
|
this.updateEditorBorderColor();
|
|
3826
4038
|
},
|
|
4039
|
+
onModelThinkingLevelChange: (provider, modelId, level) => {
|
|
4040
|
+
this.settingsManager.setModelThinkingLevel(provider, modelId, level);
|
|
4041
|
+
// If the override is for the current model, apply it to the session too
|
|
4042
|
+
const current = this.session.model;
|
|
4043
|
+
if (current && current.provider === provider && current.id === modelId) {
|
|
4044
|
+
this.session.setThinkingLevel(level);
|
|
4045
|
+
this.footer.invalidate();
|
|
4046
|
+
this.updateEditorBorderColor();
|
|
4047
|
+
}
|
|
4048
|
+
},
|
|
4049
|
+
onModelThinkingLevelRemove: (provider, modelId) => {
|
|
4050
|
+
this.settingsManager.removeModelThinkingLevel(provider, modelId);
|
|
4051
|
+
// If the override was for the current model, revert to global default
|
|
4052
|
+
const current = this.session.model;
|
|
4053
|
+
if (current && current.provider === provider && current.id === modelId) {
|
|
4054
|
+
const globalDefault = this.settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL;
|
|
4055
|
+
this.session.setThinkingLevel(globalDefault);
|
|
4056
|
+
this.footer.invalidate();
|
|
4057
|
+
this.updateEditorBorderColor();
|
|
4058
|
+
}
|
|
4059
|
+
},
|
|
3827
4060
|
onThemeChange: (themeSetting) => {
|
|
3828
4061
|
this.settingsManager.setTheme(themeSetting);
|
|
3829
4062
|
void this.themeController.setThemeSetting(themeSetting);
|
|
@@ -3943,18 +4176,56 @@ export class InteractiveMode {
|
|
|
3943
4176
|
return { component: selector, focus: selector.getSettingsList() };
|
|
3944
4177
|
});
|
|
3945
4178
|
}
|
|
3946
|
-
|
|
4179
|
+
handleThinkingCommand(searchTerm, options = {}) {
|
|
4180
|
+
const availableLevels = this.session.getAvailableThinkingLevels();
|
|
3947
4181
|
if (!searchTerm) {
|
|
3948
|
-
this.
|
|
4182
|
+
this.showThinkingSelector(options);
|
|
4183
|
+
return;
|
|
4184
|
+
}
|
|
4185
|
+
const normalized = searchTerm.trim().toLowerCase();
|
|
4186
|
+
const level = availableLevels.find((candidate) => candidate.toLowerCase() === normalized);
|
|
4187
|
+
if (!level) {
|
|
4188
|
+
this.showError(`Unknown thinking level "${searchTerm}". Available levels: ${availableLevels.join(", ")}.`);
|
|
4189
|
+
return;
|
|
4190
|
+
}
|
|
4191
|
+
this.selectThinkingLevel(level, options.persist === true);
|
|
4192
|
+
}
|
|
4193
|
+
selectThinkingLevel(level, persist) {
|
|
4194
|
+
try {
|
|
4195
|
+
this.session.setThinkingLevel(level, { persist });
|
|
4196
|
+
this.footer.invalidate();
|
|
4197
|
+
this.updateEditorBorderColor();
|
|
4198
|
+
this.showStatus(persist ? `Default thinking level: ${level}` : `Thinking level: ${level}`);
|
|
4199
|
+
}
|
|
4200
|
+
catch (error) {
|
|
4201
|
+
this.showError(error instanceof Error ? error.message : String(error));
|
|
4202
|
+
}
|
|
4203
|
+
}
|
|
4204
|
+
showThinkingSelector(options = {}) {
|
|
4205
|
+
this.showSelector((done) => {
|
|
4206
|
+
const selectLevel = (level, persist) => {
|
|
4207
|
+
this.selectThinkingLevel(level, persist);
|
|
4208
|
+
done();
|
|
4209
|
+
};
|
|
4210
|
+
const selector = new ThinkingSelectorComponent(this.session.thinkingLevel ?? DEFAULT_THINKING_LEVEL, this.session.getAvailableThinkingLevels(), (level) => selectLevel(level, options.persist === true), () => {
|
|
4211
|
+
done();
|
|
4212
|
+
this.ui.requestRender();
|
|
4213
|
+
}, (level) => selectLevel(level, true));
|
|
4214
|
+
return { component: selector, focus: selector };
|
|
4215
|
+
});
|
|
4216
|
+
}
|
|
4217
|
+
async handleModelCommand(searchTerm, options = {}) {
|
|
4218
|
+
if (!searchTerm) {
|
|
4219
|
+
this.showModelSelector(undefined, options);
|
|
3949
4220
|
return;
|
|
3950
4221
|
}
|
|
3951
4222
|
const model = await this.findExactModelMatch(searchTerm);
|
|
3952
4223
|
if (model) {
|
|
3953
4224
|
try {
|
|
3954
|
-
await this.session.setModel(model);
|
|
4225
|
+
await this.session.setModel(model, { persist: options.persist === true });
|
|
3955
4226
|
this.footer.invalidate();
|
|
3956
4227
|
this.updateEditorBorderColor();
|
|
3957
|
-
this.showStatus(`Model: ${model.id}`);
|
|
4228
|
+
this.showStatus(options.persist ? `Default model: ${model.provider}/${model.id}` : `Model: ${model.id}`);
|
|
3958
4229
|
void this.maybeWarnAboutAnthropicSubscriptionAuth(model);
|
|
3959
4230
|
this.checkDaxnutsEasterEgg(model);
|
|
3960
4231
|
}
|
|
@@ -3963,7 +4234,7 @@ export class InteractiveMode {
|
|
|
3963
4234
|
}
|
|
3964
4235
|
return;
|
|
3965
4236
|
}
|
|
3966
|
-
this.showModelSelector(searchTerm);
|
|
4237
|
+
this.showModelSelector(searchTerm, options);
|
|
3967
4238
|
}
|
|
3968
4239
|
async findExactModelMatch(searchTerm) {
|
|
3969
4240
|
const cachedModels = this.session.scopedModels.length > 0
|
|
@@ -4078,15 +4349,15 @@ export class InteractiveMode {
|
|
|
4078
4349
|
return { component: selector, focus: selector };
|
|
4079
4350
|
});
|
|
4080
4351
|
}
|
|
4081
|
-
showModelSelector(initialSearchInput) {
|
|
4352
|
+
showModelSelector(initialSearchInput, options = {}) {
|
|
4082
4353
|
this.showSelector((done) => {
|
|
4083
|
-
const
|
|
4354
|
+
const selectModel = async (model, persist) => {
|
|
4084
4355
|
try {
|
|
4085
|
-
await this.session.setModel(model);
|
|
4356
|
+
await this.session.setModel(model, { persist });
|
|
4086
4357
|
this.footer.invalidate();
|
|
4087
4358
|
this.updateEditorBorderColor();
|
|
4088
4359
|
done();
|
|
4089
|
-
this.showStatus(`Model: ${model.id}`);
|
|
4360
|
+
this.showStatus(persist ? `Default model: ${model.provider}/${model.id}` : `Model: ${model.id}`);
|
|
4090
4361
|
void this.maybeWarnAboutAnthropicSubscriptionAuth(model);
|
|
4091
4362
|
this.checkDaxnutsEasterEgg(model);
|
|
4092
4363
|
}
|
|
@@ -4094,10 +4365,11 @@ export class InteractiveMode {
|
|
|
4094
4365
|
done();
|
|
4095
4366
|
this.showError(error instanceof Error ? error.message : String(error));
|
|
4096
4367
|
}
|
|
4097
|
-
}
|
|
4368
|
+
};
|
|
4369
|
+
const selector = new ModelSelectorComponent(this.ui, this.session.model, this.session.modelRuntime, this.session.scopedModels, (model) => selectModel(model, options.persist === true), () => {
|
|
4098
4370
|
done();
|
|
4099
4371
|
this.ui.requestRender();
|
|
4100
|
-
}, initialSearchInput);
|
|
4372
|
+
}, initialSearchInput, (model) => selectModel(model, true));
|
|
4101
4373
|
return { component: selector, focus: selector, dispose: () => selector.dispose() };
|
|
4102
4374
|
});
|
|
4103
4375
|
}
|
|
@@ -4653,7 +4925,11 @@ export class InteractiveMode {
|
|
|
4653
4925
|
if (isUnknownModel(previousModel)) {
|
|
4654
4926
|
const availableModels = this.session.modelRuntime.getAvailableSnapshot();
|
|
4655
4927
|
const providerModels = availableModels.filter((model) => model.provider === providerId);
|
|
4656
|
-
|
|
4928
|
+
// Matches LLAMA_PROVIDER_ID from extensions/llama/provider.ts; kept inline to avoid coupling interactive mode to the built-in extension.
|
|
4929
|
+
if (providerId === "llama.cpp") {
|
|
4930
|
+
selectionError = llamaCppPostLoginGuidance(actionLabel, providerModels.length);
|
|
4931
|
+
}
|
|
4932
|
+
else if (!hasDefaultModelProvider(providerId)) {
|
|
4657
4933
|
selectionError = `${actionLabel}, but no default model is configured for provider "${providerId}". Use /model to select a model.`;
|
|
4658
4934
|
}
|
|
4659
4935
|
else if (providerModels.length === 0) {
|
|
@@ -4667,7 +4943,7 @@ export class InteractiveMode {
|
|
|
4667
4943
|
}
|
|
4668
4944
|
else {
|
|
4669
4945
|
try {
|
|
4670
|
-
await this.session.setModel(selectedModel);
|
|
4946
|
+
await this.session.setModel(selectedModel, { persist: true });
|
|
4671
4947
|
}
|
|
4672
4948
|
catch (error) {
|
|
4673
4949
|
selectedModel = undefined;
|
|
@@ -5251,7 +5527,10 @@ export class InteractiveMode {
|
|
|
5251
5527
|
let info = `${theme.bold("🧠 Ada Memory")}\n\n`;
|
|
5252
5528
|
info += `${theme.fg("dim", "Enabled:")} ${status.enabled ? "yes" : "no"} · ${theme.fg("dim", "Mode:")} ${status.mode}\n`;
|
|
5253
5529
|
info += `${theme.fg("dim", "Indexes:")} ${status.memoryIndexDocs} memory docs · ${status.sessionIndexDocs} session docs\n\n`;
|
|
5254
|
-
info +=
|
|
5530
|
+
info +=
|
|
5531
|
+
entries.length > 0
|
|
5532
|
+
? entries.join("\n")
|
|
5533
|
+
: theme.fg("dim", "No memory entries yet. Ask the agent to remember something, or use memory_add.");
|
|
5255
5534
|
this.chatContainer.addChild(new Spacer(1));
|
|
5256
5535
|
this.chatContainer.addChild(new Text(info, 1, 0));
|
|
5257
5536
|
this.ui.requestRender();
|
|
@@ -5295,7 +5574,7 @@ export class InteractiveMode {
|
|
|
5295
5574
|
const entries = await memoryEngine.auditEntries(25);
|
|
5296
5575
|
const lines = [
|
|
5297
5576
|
`${theme.bold("🛡️ Memory audit")}`,
|
|
5298
|
-
`${theme.fg("dim", "Integrity:")} ${integrity.valid ? theme.fg("success",
|
|
5577
|
+
`${theme.fg("dim", "Integrity:")} ${integrity.valid ? theme.fg("success", `OK (${integrity.entriesChecked} entries)`) : theme.fg("error", `TAMPERED at ${integrity.tamperedAt ?? "?"}`)}`,
|
|
5299
5578
|
];
|
|
5300
5579
|
if (entries.length === 0) {
|
|
5301
5580
|
lines.push(theme.fg("dim", "No audit entries yet."));
|
|
@@ -5358,7 +5637,10 @@ export class InteractiveMode {
|
|
|
5358
5637
|
return;
|
|
5359
5638
|
}
|
|
5360
5639
|
vault.add(name, value);
|
|
5361
|
-
show([
|
|
5640
|
+
show([
|
|
5641
|
+
`✅ '${name}' saved to the project vault (encrypted).`,
|
|
5642
|
+
` Use @vault:${name} in a message to pass it to the agent.`,
|
|
5643
|
+
]);
|
|
5362
5644
|
return;
|
|
5363
5645
|
}
|
|
5364
5646
|
case "session": {
|
|
@@ -5406,7 +5688,7 @@ export class InteractiveMode {
|
|
|
5406
5688
|
}
|
|
5407
5689
|
if (!name) {
|
|
5408
5690
|
const names = available
|
|
5409
|
-
.map((e) => ` ${e.name} (${e.source === "session" ? "sesión" : "proyecto"}${e.category ?
|
|
5691
|
+
.map((e) => ` ${e.name} (${e.source === "session" ? "sesión" : "proyecto"}${e.category ? ` · ${e.category}` : ""})`)
|
|
5410
5692
|
.join("\n");
|
|
5411
5693
|
show([
|
|
5412
5694
|
"Secretos disponibles:",
|
|
@@ -5418,12 +5700,13 @@ export class InteractiveMode {
|
|
|
5418
5700
|
}
|
|
5419
5701
|
const exists = available.some((e) => e.name === name);
|
|
5420
5702
|
show(exists
|
|
5421
|
-
? [
|
|
5703
|
+
? [
|
|
5704
|
+
`Listo. Escribe esto en el chat: @vault:${name}`,
|
|
5705
|
+
"El agente recibirá el valor; nunca se persiste en la sesión.",
|
|
5706
|
+
]
|
|
5422
5707
|
: [`No existe el secreto '${name}'. /vault list para verlos.`]);
|
|
5423
5708
|
return;
|
|
5424
5709
|
}
|
|
5425
|
-
case "list":
|
|
5426
|
-
case "status":
|
|
5427
5710
|
default: {
|
|
5428
5711
|
const status = vault.status();
|
|
5429
5712
|
const entries = vault.list();
|
|
@@ -5447,6 +5730,366 @@ export class InteractiveMode {
|
|
|
5447
5730
|
}
|
|
5448
5731
|
}
|
|
5449
5732
|
}
|
|
5733
|
+
/** /goal <intent> | status | approve | pause | resume | list — Goal Engine CLI (§16.4). */
|
|
5734
|
+
async handleGoalCommand(args) {
|
|
5735
|
+
const goalEngine = this.session.resourceLoader.getGoalEngine?.();
|
|
5736
|
+
const show = (lines) => {
|
|
5737
|
+
this.chatContainer.addChild(new Spacer(1));
|
|
5738
|
+
this.chatContainer.addChild(new Text(lines.join("\n"), 1, 0));
|
|
5739
|
+
this.ui.requestRender();
|
|
5740
|
+
};
|
|
5741
|
+
if (!goalEngine) {
|
|
5742
|
+
show(["Goal Engine unavailable."]);
|
|
5743
|
+
return;
|
|
5744
|
+
}
|
|
5745
|
+
const [action, ...rest] = args.split(/\s+/).filter(Boolean);
|
|
5746
|
+
switch (action ?? "list") {
|
|
5747
|
+
case "list": {
|
|
5748
|
+
const goals = await goalEngine.list().catch(() => []);
|
|
5749
|
+
show([
|
|
5750
|
+
"Goals:",
|
|
5751
|
+
...(goals.length === 0
|
|
5752
|
+
? [" (none)"]
|
|
5753
|
+
: goals.map((g) => ` ${g.status === "active" ? "◆" : "·"} ${g.id} [${g.status}] ${g.goal}`)),
|
|
5754
|
+
]);
|
|
5755
|
+
return;
|
|
5756
|
+
}
|
|
5757
|
+
case "status": {
|
|
5758
|
+
const id = rest[0] ?? "";
|
|
5759
|
+
if (!id) {
|
|
5760
|
+
show(["Uso: /goal status <id>"]);
|
|
5761
|
+
return;
|
|
5762
|
+
}
|
|
5763
|
+
const state = await goalEngine.get(id);
|
|
5764
|
+
if (!state) {
|
|
5765
|
+
show([`Goal no encontrado: ${id}`]);
|
|
5766
|
+
return;
|
|
5767
|
+
}
|
|
5768
|
+
show([
|
|
5769
|
+
`Goal: ${state.goal}`,
|
|
5770
|
+
` id: ${state.id} · fase: ${state.phase} · estado: ${state.status}`,
|
|
5771
|
+
` turnos: ${state.turnsUsed}/25 · repetidos: ${state.repeatedTurns}`,
|
|
5772
|
+
` iteración: ${state.iteration}${state.iterations.length > 0 ? ` (${state.iterations.length} registrada${state.iterations.length === 1 ? "" : "s"})` : ""}`,
|
|
5773
|
+
...(state.judge.lastVerdict
|
|
5774
|
+
? [` juez: ${state.judge.lastVerdict} — ${state.judge.lastReason ?? ""}`]
|
|
5775
|
+
: []),
|
|
5776
|
+
...(state.replanRationale ? [` último replan: ${state.replanRationale}`] : []),
|
|
5777
|
+
...(state.evidence.length > 0 ? [` evidencia: ${state.evidence.length} citas`] : []),
|
|
5778
|
+
...(state.tasks.length > 0
|
|
5779
|
+
? [
|
|
5780
|
+
` plan (${state.tasks.length}):`,
|
|
5781
|
+
...state.tasks.map((t) => ` ${t.status === "done" ? "✓" : t.status === "running" ? "◐" : "○"} ${t.title}`),
|
|
5782
|
+
]
|
|
5783
|
+
: []),
|
|
5784
|
+
]);
|
|
5785
|
+
return;
|
|
5786
|
+
}
|
|
5787
|
+
case "replan": {
|
|
5788
|
+
// P1: re-planificación manual (también automática tras continue).
|
|
5789
|
+
const id = rest[0] ?? "";
|
|
5790
|
+
if (!id) {
|
|
5791
|
+
show(["Uso: /goal replan <id>"]);
|
|
5792
|
+
return;
|
|
5793
|
+
}
|
|
5794
|
+
const state = await goalEngine.replan(id).catch((e) => {
|
|
5795
|
+
show(["No se pudo re-planificar:", ` ${e instanceof Error ? e.message : String(e)}`]);
|
|
5796
|
+
return null;
|
|
5797
|
+
});
|
|
5798
|
+
if (state)
|
|
5799
|
+
show([
|
|
5800
|
+
`Re-planificado → iteración ${state.iteration}`,
|
|
5801
|
+
` ${state.replanRationale ?? ""}`,
|
|
5802
|
+
...state.tasks.map((t) => ` ○ ${t.title}`),
|
|
5803
|
+
]);
|
|
5804
|
+
return;
|
|
5805
|
+
}
|
|
5806
|
+
case "add": {
|
|
5807
|
+
// P2: añadir sub-tarea en cualquier fase.
|
|
5808
|
+
const id = rest[0] ?? "";
|
|
5809
|
+
const title = rest.slice(1).join(" ");
|
|
5810
|
+
if (!id || !title) {
|
|
5811
|
+
show(["Uso: /goal add <id> <título>"]);
|
|
5812
|
+
return;
|
|
5813
|
+
}
|
|
5814
|
+
const state = await goalEngine.addTask(id, title).catch(() => null);
|
|
5815
|
+
show(state
|
|
5816
|
+
? [`Añadida: ${title}`, ` plan (${state.tasks.length} sub-tareas)`]
|
|
5817
|
+
: ["No se pudo añadir (id inválido)"]);
|
|
5818
|
+
return;
|
|
5819
|
+
}
|
|
5820
|
+
case "rm": {
|
|
5821
|
+
// P2: quitar sub-tarea.
|
|
5822
|
+
const id = rest[0] ?? "";
|
|
5823
|
+
const taskId = rest[1] ?? "";
|
|
5824
|
+
if (!id || !taskId) {
|
|
5825
|
+
show(["Uso: /goal rm <id> <taskId>"]);
|
|
5826
|
+
return;
|
|
5827
|
+
}
|
|
5828
|
+
const state = await goalEngine.get(id);
|
|
5829
|
+
if (!state) {
|
|
5830
|
+
show(["Goal no encontrado"]);
|
|
5831
|
+
return;
|
|
5832
|
+
}
|
|
5833
|
+
const { state: next } = reduceGoal(state, { type: "goal_task_remove", taskId }, {
|
|
5834
|
+
repeatTolerance: 1,
|
|
5835
|
+
});
|
|
5836
|
+
await goalEngine.commit(state, next);
|
|
5837
|
+
show([`Quitada. Plan (${next.tasks.length}):`, ...next.tasks.map((t) => ` ${t.title}`)]);
|
|
5838
|
+
return;
|
|
5839
|
+
}
|
|
5840
|
+
case "mv": {
|
|
5841
|
+
// P2: reordenar sub-tarea.
|
|
5842
|
+
const id = rest[0] ?? "";
|
|
5843
|
+
const taskId = rest[1] ?? "";
|
|
5844
|
+
const dir = rest[2] === "down" ? "down" : "up";
|
|
5845
|
+
if (!id || !taskId) {
|
|
5846
|
+
show(["Uso: /goal mv <id> <taskId> up|down"]);
|
|
5847
|
+
return;
|
|
5848
|
+
}
|
|
5849
|
+
const state = await goalEngine.get(id);
|
|
5850
|
+
if (!state) {
|
|
5851
|
+
show(["Goal no encontrado"]);
|
|
5852
|
+
return;
|
|
5853
|
+
}
|
|
5854
|
+
const { state: next } = reduceGoal(state, { type: "goal_task_move", taskId, dir }, {
|
|
5855
|
+
repeatTolerance: 1,
|
|
5856
|
+
});
|
|
5857
|
+
await goalEngine.commit(state, next);
|
|
5858
|
+
show([`Reordenado. Plan (${next.tasks.length}):`, ...next.tasks.map((t) => ` ${t.title}`)]);
|
|
5859
|
+
return;
|
|
5860
|
+
}
|
|
5861
|
+
case "new": {
|
|
5862
|
+
const intent = rest.join(" ");
|
|
5863
|
+
if (!intent) {
|
|
5864
|
+
show(["Uso: /goal new <intent>"]);
|
|
5865
|
+
return;
|
|
5866
|
+
}
|
|
5867
|
+
const state = await goalEngine.createGoal({
|
|
5868
|
+
goal: intent,
|
|
5869
|
+
doneCriteria: [],
|
|
5870
|
+
verifyCommand: "",
|
|
5871
|
+
});
|
|
5872
|
+
show([`Contrato creado: ${state.id}`, " Aprueba con: /goal approve <id>", ` ${intent}`]);
|
|
5873
|
+
return;
|
|
5874
|
+
}
|
|
5875
|
+
case "approve": {
|
|
5876
|
+
const id = rest[0] ?? "";
|
|
5877
|
+
if (!id) {
|
|
5878
|
+
show(["Uso: /goal approve <id>"]);
|
|
5879
|
+
return;
|
|
5880
|
+
}
|
|
5881
|
+
const state = await goalEngine.approve(id).catch(() => null);
|
|
5882
|
+
show(state ? [`Goal activo: ${state.goal}`] : ["No se pudo aprobar (id inválido)"]);
|
|
5883
|
+
return;
|
|
5884
|
+
}
|
|
5885
|
+
case "pause": {
|
|
5886
|
+
const id = rest[0] ?? "";
|
|
5887
|
+
if (!id) {
|
|
5888
|
+
show(["Uso: /goal pause <id>"]);
|
|
5889
|
+
return;
|
|
5890
|
+
}
|
|
5891
|
+
const state = await goalEngine.pause(id, "pausado desde CLI");
|
|
5892
|
+
show([`Pausado: ${state.status}`]);
|
|
5893
|
+
return;
|
|
5894
|
+
}
|
|
5895
|
+
case "resume": {
|
|
5896
|
+
const id = rest[0] ?? "";
|
|
5897
|
+
if (!id) {
|
|
5898
|
+
show(["Uso: /goal resume <id>"]);
|
|
5899
|
+
return;
|
|
5900
|
+
}
|
|
5901
|
+
const state = await goalEngine.resume(id).catch(() => null);
|
|
5902
|
+
show(state ? [`Reanudado: ${state.status}`] : ["No se pudo reanudar"]);
|
|
5903
|
+
return;
|
|
5904
|
+
}
|
|
5905
|
+
case "plan-on": {
|
|
5906
|
+
// P5: modo plan-only (persistente).
|
|
5907
|
+
this.settingsManager.setPlanOnlyEnabled(true);
|
|
5908
|
+
show(["Plan-only ACTIVADO: el goal no ejecutará hasta aprobar el plan."]);
|
|
5909
|
+
return;
|
|
5910
|
+
}
|
|
5911
|
+
case "plan-off": {
|
|
5912
|
+
this.settingsManager.setPlanOnlyEnabled(false);
|
|
5913
|
+
show(["Plan-only desactivado: el goal lanza sub-tareas automáticamente."]);
|
|
5914
|
+
return;
|
|
5915
|
+
}
|
|
5916
|
+
default:
|
|
5917
|
+
show([
|
|
5918
|
+
"Subcomandos: new <intent> | list | status <id> | approve <id> | pause <id> | resume <id> | replan <id> | add <id> <título> | rm <id> <taskId> | mv <id> <taskId> up|down | plan-on | plan-off",
|
|
5919
|
+
]);
|
|
5920
|
+
return;
|
|
5921
|
+
}
|
|
5922
|
+
}
|
|
5923
|
+
/** /graph gaps | context <id> | search <term> | add — Grafo CLI (§16.4). */
|
|
5924
|
+
async handleGraphCommand(args) {
|
|
5925
|
+
const graph = this.session.resourceLoader.getGraph?.();
|
|
5926
|
+
const show = (lines) => {
|
|
5927
|
+
this.chatContainer.addChild(new Spacer(1));
|
|
5928
|
+
this.chatContainer.addChild(new Text(lines.join("\n"), 1, 0));
|
|
5929
|
+
this.ui.requestRender();
|
|
5930
|
+
};
|
|
5931
|
+
if (!graph) {
|
|
5932
|
+
show(["Graph unavailable."]);
|
|
5933
|
+
return;
|
|
5934
|
+
}
|
|
5935
|
+
const [action, ...rest] = args.split(/\s+/).filter(Boolean);
|
|
5936
|
+
switch (action ?? "gaps") {
|
|
5937
|
+
case "gaps": {
|
|
5938
|
+
const gaps = graph.gaps();
|
|
5939
|
+
show([
|
|
5940
|
+
"Gaps (spine incompleto):",
|
|
5941
|
+
...(gaps.length === 0 ? [" ✓ spine completo"] : gaps.map((g) => ` ${g.id}: falta ${g.missing}`)),
|
|
5942
|
+
]);
|
|
5943
|
+
return;
|
|
5944
|
+
}
|
|
5945
|
+
case "context": {
|
|
5946
|
+
const id = rest[0] ?? "";
|
|
5947
|
+
if (!id) {
|
|
5948
|
+
show(["Uso: /graph context <id>"]);
|
|
5949
|
+
return;
|
|
5950
|
+
}
|
|
5951
|
+
const res = graph.context(id);
|
|
5952
|
+
if (!res.ok || !res.data || !res.data.node) {
|
|
5953
|
+
show([`Error: ${res.error ?? "no encontrado"}`]);
|
|
5954
|
+
return;
|
|
5955
|
+
}
|
|
5956
|
+
show([
|
|
5957
|
+
`Nodo: ${res.data.node.id} [${res.data.node.type}]`,
|
|
5958
|
+
` ${res.data.node.description}`,
|
|
5959
|
+
` vecinos: ${res.data.neighbors.length}`,
|
|
5960
|
+
...res.data.neighbors.map((e) => ` ${e.subject} --${e.predicate}--> ${e.object}`),
|
|
5961
|
+
]);
|
|
5962
|
+
return;
|
|
5963
|
+
}
|
|
5964
|
+
case "search": {
|
|
5965
|
+
const term = rest.join(" ");
|
|
5966
|
+
if (!term) {
|
|
5967
|
+
show(["Uso: /graph search <term>"]);
|
|
5968
|
+
return;
|
|
5969
|
+
}
|
|
5970
|
+
const hits = graph.search(term);
|
|
5971
|
+
show([
|
|
5972
|
+
`Resultados para "${term}":`,
|
|
5973
|
+
...(hits.length === 0 ? [" (ninguno)"] : hits.map((h) => ` ${h.node.id} — ${h.node.description}`)),
|
|
5974
|
+
]);
|
|
5975
|
+
return;
|
|
5976
|
+
}
|
|
5977
|
+
case "gate": {
|
|
5978
|
+
const res = graph.gate();
|
|
5979
|
+
show(res.data?.passed ? ["✓ Gate superado"] : [`✗ Gate bloqueado:`, ...(res.data?.failures ?? [])]);
|
|
5980
|
+
return;
|
|
5981
|
+
}
|
|
5982
|
+
default:
|
|
5983
|
+
show(["Subcomandos: gaps | context <id> | search <term> | gate"]);
|
|
5984
|
+
return;
|
|
5985
|
+
}
|
|
5986
|
+
}
|
|
5987
|
+
/** /workflow run <name> [k=v...] | list | status <id> | abort <id> — CLI del engine (§16.4). */
|
|
5988
|
+
async handleWorkflowCommand(args) {
|
|
5989
|
+
const manager = this.session.resourceLoader.getWorkflowManager?.();
|
|
5990
|
+
const show = (lines) => {
|
|
5991
|
+
this.chatContainer.addChild(new Spacer(1));
|
|
5992
|
+
this.chatContainer.addChild(new Text(lines.join("\n"), 1, 0));
|
|
5993
|
+
this.ui.requestRender();
|
|
5994
|
+
};
|
|
5995
|
+
if (!manager) {
|
|
5996
|
+
show(["Workflow manager unavailable."]);
|
|
5997
|
+
return;
|
|
5998
|
+
}
|
|
5999
|
+
const [action, ...rest] = args.split(/\s+/).filter(Boolean);
|
|
6000
|
+
switch (action ?? "list") {
|
|
6001
|
+
case "list": {
|
|
6002
|
+
const runs = await manager.list().catch(() => []);
|
|
6003
|
+
show([
|
|
6004
|
+
"Workflow runs:",
|
|
6005
|
+
...(runs.length === 0
|
|
6006
|
+
? [" (ninguno)"]
|
|
6007
|
+
: runs.slice(0, 20).map((r) => ` ${r.runId} [${r.status}] ${r.name} — ${r.updatedAt}`)),
|
|
6008
|
+
]);
|
|
6009
|
+
return;
|
|
6010
|
+
}
|
|
6011
|
+
case "status": {
|
|
6012
|
+
const runId = rest[0] ?? "";
|
|
6013
|
+
if (!runId) {
|
|
6014
|
+
show(["Uso: /workflow status <runId>"]);
|
|
6015
|
+
return;
|
|
6016
|
+
}
|
|
6017
|
+
const state = await manager.state(runId).catch(() => null);
|
|
6018
|
+
if (!state) {
|
|
6019
|
+
show([`Run no encontrado: ${runId}`]);
|
|
6020
|
+
return;
|
|
6021
|
+
}
|
|
6022
|
+
show([
|
|
6023
|
+
`Run: ${state.name} (${state.runId})`,
|
|
6024
|
+
` estado: ${state.status} · fase: ${state.currentPhase ?? "—"}`,
|
|
6025
|
+
` agentes: ${state.agentCount} · tokens: ${state.tokenUsage.total} · coste: $${state.tokenUsage.cost.toFixed(4)}`,
|
|
6026
|
+
]);
|
|
6027
|
+
return;
|
|
6028
|
+
}
|
|
6029
|
+
case "abort": {
|
|
6030
|
+
const runId = rest[0] ?? "";
|
|
6031
|
+
if (!runId) {
|
|
6032
|
+
show(["Uso: /workflow abort <runId>"]);
|
|
6033
|
+
return;
|
|
6034
|
+
}
|
|
6035
|
+
const aborted = manager.abort(runId);
|
|
6036
|
+
show(aborted ? [`Abort solicitado: ${runId}`] : [`No se pudo abortar (¿run inexistente?): ${runId}`]);
|
|
6037
|
+
return;
|
|
6038
|
+
}
|
|
6039
|
+
case "run": {
|
|
6040
|
+
const name = rest[0];
|
|
6041
|
+
if (!name) {
|
|
6042
|
+
show([
|
|
6043
|
+
"Uso: /workflow run <name> [k=v...]",
|
|
6044
|
+
" builtins: deep_research · code_review · product_build · codebase_audit · multi_perspective",
|
|
6045
|
+
]);
|
|
6046
|
+
return;
|
|
6047
|
+
}
|
|
6048
|
+
// args k=v
|
|
6049
|
+
const wfArgs = {};
|
|
6050
|
+
for (const part of rest.slice(1)) {
|
|
6051
|
+
const eq = part.indexOf("=");
|
|
6052
|
+
if (eq > 0)
|
|
6053
|
+
wfArgs[part.slice(0, eq)] = part.slice(eq + 1);
|
|
6054
|
+
}
|
|
6055
|
+
const script = await this.resolveBuiltinWorkflow(name);
|
|
6056
|
+
if (!script) {
|
|
6057
|
+
show([`Workflow no encontrado: ${name}`]);
|
|
6058
|
+
return;
|
|
6059
|
+
}
|
|
6060
|
+
// Confirmación de coste estimado (fail-closed).
|
|
6061
|
+
const ok = await this.confirm(`Lanzar workflow "${name}" con ${Object.keys(wfArgs).length} args. Coste estimado: variable (ver settings.workflows.budget). ¿Continuar?`);
|
|
6062
|
+
if (!ok) {
|
|
6063
|
+
show(["Cancelado."]);
|
|
6064
|
+
return;
|
|
6065
|
+
}
|
|
6066
|
+
show([`Lanzando ${name}… (progreso: /workflow list, /workflow status <runId>)`]);
|
|
6067
|
+
void manager
|
|
6068
|
+
.execute(script, { args: wfArgs, sessionId: this.session.sessionManager.getSessionId() })
|
|
6069
|
+
.then((r) => show([`✓ ${name} terminó (${r.runId}).`]))
|
|
6070
|
+
.catch((e) => show([`✗ ${name} falló: ${e instanceof Error ? e.message : String(e)}`]));
|
|
6071
|
+
return;
|
|
6072
|
+
}
|
|
6073
|
+
default:
|
|
6074
|
+
show(["Subcomandos: run <name> [k=v...] | list | status <runId> | abort <runId>"]);
|
|
6075
|
+
return;
|
|
6076
|
+
}
|
|
6077
|
+
}
|
|
6078
|
+
/**
|
|
6079
|
+
* Confirmación fail-closed del TUI: pide "y"/"yes" explícito en el input
|
|
6080
|
+
* de diálogo. Cualquier otra respuesta (o escape) = NO.
|
|
6081
|
+
*/
|
|
6082
|
+
async confirm(prompt) {
|
|
6083
|
+
const answer = await this.showExtensionInput(`${prompt} [y/N]`, "y");
|
|
6084
|
+
const normalized = (answer ?? "").trim().toLowerCase();
|
|
6085
|
+
return normalized === "y" || normalized === "yes";
|
|
6086
|
+
}
|
|
6087
|
+
/** Resuelve un workflow builtin (deep_research, code_review, …) a su script. */
|
|
6088
|
+
/** Resuelve un workflow por nombre: builtin o script guardado del usuario. */
|
|
6089
|
+
async resolveBuiltinWorkflow(name) {
|
|
6090
|
+
const { resolveWorkflowScriptByName } = await import("../../core/workflows/resolve-script.js");
|
|
6091
|
+
return resolveWorkflowScriptByName(this.session.resourceLoader.getAgentDir(), name)?.script ?? null;
|
|
6092
|
+
}
|
|
5450
6093
|
handleChangelogCommand() {
|
|
5451
6094
|
const changelogPath = getChangelogPath();
|
|
5452
6095
|
const allEntries = parseChangelog(changelogPath);
|