@ashx-j/lunr 0.2.12 → 0.2.14
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 +16 -1
- package/README.md +6 -3
- package/dist/builtin-extensions/ashxj-tui.d.ts +16 -1
- package/dist/builtin-extensions/ashxj-tui.d.ts.map +1 -1
- package/dist/builtin-extensions/ashxj-tui.js +44 -20
- package/dist/builtin-extensions/ashxj-tui.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/index.d.ts +2 -0
- package/dist/builtin-extensions/pi-subagents/src/extension/index.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/index.js +27 -22
- package/dist/builtin-extensions/pi-subagents/src/extension/index.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-execution.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-execution.js +5 -2
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-execution.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-resume.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-resume.js +12 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-resume.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-status.d.ts +1 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-status.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-status.js +3 -2
- package/dist/builtin-extensions/pi-subagents/src/runs/background/async-status.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/chain-append.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/chain-append.js +1 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/background/chain-append.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/chain-root-attachment.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/chain-root-attachment.js +3 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/background/chain-root-attachment.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/fleet-view.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/fleet-view.js +3 -3
- package/dist/builtin-extensions/pi-subagents/src/runs/background/fleet-view.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/run-status.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/run-status.js +2 -2
- package/dist/builtin-extensions/pi-subagents/src/runs/background/run-status.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.js +3 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.js +7 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.js +2 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.d.ts +1 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js +19 -3
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.d.ts +10 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.js +19 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.d.ts +1 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/child-spec.d.ts +2 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/child-spec.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/child-spec.js +17 -0
- package/dist/builtin-extensions/pi-subagents/src/shared/child-spec.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/formatters.d.ts +3 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/formatters.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/formatters.js +14 -3
- package/dist/builtin-extensions/pi-subagents/src/shared/formatters.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/types.d.ts +14 -0
- package/dist/builtin-extensions/pi-subagents/src/shared/types.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/types.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/tui/fleet.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/tui/fleet.js +2 -2
- package/dist/builtin-extensions/pi-subagents/src/tui/fleet.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/tui/render.js +12 -10
- package/dist/builtin-extensions/pi-subagents/src/tui/render.js.map +1 -1
- package/dist/catalog/models.json +1 -1
- package/dist/catalog/providers/amazon-bedrock.json +1 -1
- package/dist/catalog/providers/anthropic.json +1 -1
- package/dist/catalog/providers/azure-openai-responses.json +1 -1
- package/dist/catalog/providers/cloudflare-ai-gateway.json +1 -1
- package/dist/catalog/providers/cloudflare-workers-ai.json +1 -1
- package/dist/catalog/providers/fireworks.json +1 -1
- package/dist/catalog/providers/github-copilot.json +1 -1
- package/dist/catalog/providers/google-vertex.json +1 -1
- package/dist/catalog/providers/google.json +1 -1
- package/dist/catalog/providers/groq.json +1 -1
- package/dist/catalog/providers/huggingface.json +1 -1
- package/dist/catalog/providers/nvidia.json +1 -1
- package/dist/catalog/providers/openai-codex.json +1 -1
- package/dist/catalog/providers/openai.json +1 -1
- package/dist/catalog/providers/opencode-go.json +1 -1
- package/dist/catalog/providers/opencode.json +1 -1
- package/dist/catalog/providers/openrouter.json +1 -1
- package/dist/catalog/providers/together.json +1 -1
- package/dist/catalog/providers/vercel-ai-gateway.json +1 -1
- package/dist/catalog/publication.json +131 -3
- package/dist/cli/list-models.d.ts.map +1 -1
- package/dist/cli/list-models.js +1 -0
- package/dist/cli/list-models.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +52 -27
- package/dist/cli.js.map +1 -1
- package/dist/core/catalog-cache-scope.d.ts +3 -0
- package/dist/core/catalog-cache-scope.d.ts.map +1 -0
- package/dist/core/catalog-cache-scope.js +12 -0
- package/dist/core/catalog-cache-scope.js.map +1 -0
- package/dist/core/catalog-merge.d.ts +2 -0
- package/dist/core/catalog-merge.d.ts.map +1 -1
- package/dist/core/catalog-merge.js +29 -2
- package/dist/core/catalog-merge.js.map +1 -1
- package/dist/core/catalog-refresh-polling.d.ts +8 -0
- package/dist/core/catalog-refresh-polling.d.ts.map +1 -0
- package/dist/core/catalog-refresh-polling.js +30 -0
- package/dist/core/catalog-refresh-polling.js.map +1 -0
- package/dist/core/codex-catalog.d.ts +3 -0
- package/dist/core/codex-catalog.d.ts.map +1 -0
- package/dist/core/codex-catalog.js +15 -0
- package/dist/core/codex-catalog.js.map +1 -0
- package/dist/core/context-breakdown.d.ts +3 -1
- package/dist/core/context-breakdown.d.ts.map +1 -1
- package/dist/core/context-breakdown.js +5 -2
- package/dist/core/context-breakdown.js.map +1 -1
- package/dist/core/customize.d.ts +2 -4
- package/dist/core/customize.d.ts.map +1 -1
- package/dist/core/customize.js +2 -8
- package/dist/core/customize.js.map +1 -1
- package/dist/core/footer-data-provider.d.ts +3 -4
- package/dist/core/footer-data-provider.d.ts.map +1 -1
- package/dist/core/footer-data-provider.js +54 -82
- package/dist/core/footer-data-provider.js.map +1 -1
- package/dist/core/live-catalog.d.ts +5 -2
- package/dist/core/live-catalog.d.ts.map +1 -1
- package/dist/core/live-catalog.js +108 -27
- package/dist/core/live-catalog.js.map +1 -1
- package/dist/core/model-runtime.d.ts +8 -0
- package/dist/core/model-runtime.d.ts.map +1 -1
- package/dist/core/model-runtime.js +64 -12
- package/dist/core/model-runtime.js.map +1 -1
- package/dist/core/official-catalog.d.ts +4 -0
- package/dist/core/official-catalog.d.ts.map +1 -1
- package/dist/core/official-catalog.js +86 -21
- package/dist/core/official-catalog.js.map +1 -1
- package/dist/core/settings-manager.d.ts +7 -6
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +13 -17
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +1 -0
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts +2 -0
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +106 -50
- package/dist/main.js.map +1 -1
- package/dist/migrations.d.ts +2 -0
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js +14 -4
- package/dist/migrations.js.map +1 -1
- package/dist/modes/interactive/components/assistant-message.d.ts +1 -3
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js +4 -32
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-editor.js +2 -1
- package/dist/modes/interactive/components/custom-editor.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +4 -1
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/plan-message.d.ts +1 -3
- package/dist/modes/interactive/components/plan-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/plan-message.js +1 -16
- package/dist/modes/interactive/components/plan-message.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +3 -5
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +113 -117
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/user-message.d.ts +1 -3
- package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/user-message.js +2 -19
- package/dist/modes/interactive/components/user-message.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +12 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +153 -130
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/skill-tag-autocomplete.d.ts +13 -0
- package/dist/modes/interactive/skill-tag-autocomplete.d.ts.map +1 -0
- package/dist/modes/interactive/skill-tag-autocomplete.js +72 -0
- package/dist/modes/interactive/skill-tag-autocomplete.js.map +1 -0
- package/dist/modes/interactive/theme/moon.json +0 -1
- package/dist/modes/interactive/theme/theme-schema.json +3 -3
- package/dist/modes/interactive/theme/theme.d.ts +1 -1
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +95 -90
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/startup/interactive-view.d.ts +55 -0
- package/dist/startup/interactive-view.d.ts.map +1 -0
- package/dist/startup/interactive-view.js +332 -0
- package/dist/startup/interactive-view.js.map +1 -0
- package/dist/startup/launch-routing.d.ts +8 -0
- package/dist/startup/launch-routing.d.ts.map +1 -0
- package/dist/startup/launch-routing.js +29 -0
- package/dist/startup/launch-routing.js.map +1 -0
- package/dist/startup/startup-milestones.d.ts +4 -0
- package/dist/startup/startup-milestones.d.ts.map +1 -0
- package/dist/startup/startup-milestones.js +14 -0
- package/dist/startup/startup-milestones.js.map +1 -0
- package/dist/utils/syntax-highlight.d.ts.map +1 -1
- package/dist/utils/syntax-highlight.js +10 -4
- package/dist/utils/syntax-highlight.js.map +1 -1
- package/docs/features.md +2 -2
- package/docs/interactive-startup.md +58 -0
- package/docs/keybindings.md +1 -1
- package/docs/model-catalog.md +29 -0
- package/docs/quickstart.md +1 -1
- package/docs/settings.md +2 -3
- package/docs/skills.md +10 -0
- package/docs/terminal-setup.md +2 -2
- package/docs/usage.md +2 -1
- package/docs/windows.md +1 -1
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/package.json +16 -16
|
@@ -7,7 +7,7 @@ import * as fs from "node:fs";
|
|
|
7
7
|
import * as os from "node:os";
|
|
8
8
|
import * as path from "node:path";
|
|
9
9
|
import { getSupportedThinkingLevels, } from "@ashx-j/lunr-ai/compat";
|
|
10
|
-
import {
|
|
10
|
+
import { CombinedAutocompleteProvider, Container, collectImageMarkerIds, formatImageMarker, fuzzyFilter, isFocusable, Markdown, matchesKey, ProcessTerminal, Spacer, setKeybindings, Text, TruncatedText, TUI, visibleWidth, } from "@ashx-j/lunr-tui";
|
|
11
11
|
import chalk from "chalk";
|
|
12
12
|
import { spawn, spawnSync } from "child_process";
|
|
13
13
|
import { APP_NAME, APP_TITLE, appendDebugLog, CONFIG_DIR_NAME, getAgentDir, getAuthPath, getDebugLogPath, getDocsPath, getShareViewerUrl, VERSION, } from "../../config.js";
|
|
@@ -15,13 +15,13 @@ 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
17
|
import { formatCatalogRefreshSummary } from "../../core/catalog-merge.js";
|
|
18
|
+
import { startCatalogRefreshPolling } from "../../core/catalog-refresh-polling.js";
|
|
18
19
|
import { computeContextBreakdown } from "../../core/context-breakdown.js";
|
|
19
20
|
import { FooterDataProvider } from "../../core/footer-data-provider.js";
|
|
20
21
|
import { hasGrokCliXaiAuth } from "../../core/grok-cli-auth.js";
|
|
21
22
|
import { configureHttpDispatcher, formatHttpIdleTimeoutMs } from "../../core/http-dispatcher.js";
|
|
22
23
|
import { detectInjectedPrompt } from "../../core/injected-prompt.js";
|
|
23
24
|
import { KeybindingsManager } from "../../core/keybindings.js";
|
|
24
|
-
import { applyIncompleteAnswers, describeIncomplete, INCOMPLETE_PROMPT_CAP, parsePositiveInt, } from "../../core/live-catalog.js";
|
|
25
25
|
import { createCompactionSummaryMessage } from "../../core/messages.js";
|
|
26
26
|
import { isValidProviderBaseUrl, parseModelIds, slugifyProviderId, upsertCustomProvider, } from "../../core/model-config-writer.js";
|
|
27
27
|
import { defaultModelPerProvider, findExactModelReferenceMatch, resolveModelScope } from "../../core/model-resolver.js";
|
|
@@ -43,7 +43,7 @@ import { time } from "../../core/timings.js";
|
|
|
43
43
|
import { hasTrustRequiringProjectResources, ProjectTrustStore } from "../../core/trust-manager.js";
|
|
44
44
|
import { checkForUpdate, markUpdateNotified } from "../../core/update-check.js";
|
|
45
45
|
import { getAllPlanUsageResults, getUsageServiceBridge } from "../../core/usage-service.js";
|
|
46
|
-
import {
|
|
46
|
+
import { markStartupMilestone } from "../../startup/startup-milestones.js";
|
|
47
47
|
import { copyToClipboard, readClipboardText } from "../../utils/clipboard.js";
|
|
48
48
|
import { extensionForImageMimeType, readClipboardImage } from "../../utils/clipboard-image.js";
|
|
49
49
|
import { parseGitUrl } from "../../utils/git.js";
|
|
@@ -89,6 +89,7 @@ import { renderUsageBox } from "./components/usage-view.js";
|
|
|
89
89
|
import { UserMessageComponent } from "./components/user-message.js";
|
|
90
90
|
import { UserMessageSelectorComponent } from "./components/user-message-selector.js";
|
|
91
91
|
import { getModelSearchText } from "./model-search.js";
|
|
92
|
+
import { wrapSkillTagAutocomplete } from "./skill-tag-autocomplete.js";
|
|
92
93
|
import { computeSmoothRevealStep, countGraphemesBeforeToolCall, countMessageGraphemes, sliceMessageContent, } from "./smooth-streaming.js";
|
|
93
94
|
import { getAvailableThemes, getAvailableThemesWithPaths, getEditorTheme, getMarkdownTheme, getThemeByName, getThemeName, onThemeChange, setRegisteredThemes, stopThemeWatcher, Theme, theme, } from "./theme/theme.js";
|
|
94
95
|
import { InteractiveThemeController } from "./theme/theme-controller.js";
|
|
@@ -198,6 +199,11 @@ function formatLoginProviderCompletionDescription(provider) {
|
|
|
198
199
|
const authTypes = provider.authTypes.map(formatAuthSelectorProviderType).join("/");
|
|
199
200
|
return provider.name === provider.id ? authTypes : `${provider.name} · ${authTypes}`;
|
|
200
201
|
}
|
|
202
|
+
export async function startInteractiveToolInstalls(currentFdPath, onFdInstalled, installer = ensureTool) {
|
|
203
|
+
const [fdPath] = await Promise.all([installer("fd", true), installer("rg", true)]);
|
|
204
|
+
if (fdPath && fdPath !== currentFdPath)
|
|
205
|
+
onFdInstalled(fdPath);
|
|
206
|
+
}
|
|
201
207
|
export class InteractiveMode {
|
|
202
208
|
runtimeHost;
|
|
203
209
|
ui;
|
|
@@ -218,6 +224,7 @@ export class InteractiveMode {
|
|
|
218
224
|
keybindings;
|
|
219
225
|
version;
|
|
220
226
|
isInitialized = false;
|
|
227
|
+
stopCatalogRefresh;
|
|
221
228
|
onInputCallback;
|
|
222
229
|
pendingUserInputs = [];
|
|
223
230
|
stagedSubmitImages;
|
|
@@ -312,6 +319,8 @@ export class InteractiveMode {
|
|
|
312
319
|
autoTrustOnReloadCwd;
|
|
313
320
|
themeController;
|
|
314
321
|
deferredBuiltinsAttached = false;
|
|
322
|
+
startupReadyPromise;
|
|
323
|
+
startupFeatureError;
|
|
315
324
|
deferredBuiltinAttachPromise;
|
|
316
325
|
// Convenience accessors
|
|
317
326
|
get session() {
|
|
@@ -352,7 +361,7 @@ export class InteractiveMode {
|
|
|
352
361
|
this.syncPermissionModeEffects(this.settingsManager.getDefaultPermissionMode());
|
|
353
362
|
});
|
|
354
363
|
this.version = VERSION;
|
|
355
|
-
this.ui = new TUI(new ProcessTerminal(), this.settingsManager.getShowHardwareCursor());
|
|
364
|
+
this.ui = options.startupView?.ui ?? new TUI(new ProcessTerminal(), this.settingsManager.getShowHardwareCursor());
|
|
356
365
|
this.ui.setClearOnShrink(this.settingsManager.getClearOnShrink());
|
|
357
366
|
// lunr: register the permission-mode footer bridge (provider-side: InteractiveMode owns the state).
|
|
358
367
|
registerPermissionModeBridge(() => getPermissionMode());
|
|
@@ -363,21 +372,29 @@ export class InteractiveMode {
|
|
|
363
372
|
// lunr: reset permission mode to configured default on startup.
|
|
364
373
|
resetPermissions(this.settingsManager.getDefaultPermissionMode());
|
|
365
374
|
this.headerContainer = new Container();
|
|
375
|
+
if (options.startupView) {
|
|
376
|
+
this.headerContainer.addChild(new Spacer(1));
|
|
377
|
+
this.headerContainer.addChild(options.startupView.header);
|
|
378
|
+
this.customFooter = options.startupView.footer;
|
|
379
|
+
}
|
|
366
380
|
this.loadedResourcesContainer = new Container();
|
|
367
381
|
this.chatContainer = new Container();
|
|
368
382
|
this.pendingMessagesContainer = new Container();
|
|
369
|
-
this.statusContainer = new Container();
|
|
383
|
+
this.statusContainer = options.startupView?.statusContainer ?? new Container();
|
|
370
384
|
this.widgetContainerAbove = new Container();
|
|
371
385
|
this.widgetContainerBelow = new Container();
|
|
372
|
-
this.keybindings = KeybindingsManager.create();
|
|
386
|
+
this.keybindings = options.startupView?.keybindings ?? KeybindingsManager.create();
|
|
373
387
|
setKeybindings(this.keybindings);
|
|
374
388
|
const editorPaddingX = this.settingsManager.getEditorPaddingX();
|
|
375
389
|
const autocompleteMaxVisible = this.settingsManager.getAutocompleteMaxVisible();
|
|
376
|
-
this.defaultEditor =
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
390
|
+
this.defaultEditor =
|
|
391
|
+
options.startupView?.editor ??
|
|
392
|
+
new CustomEditor(this.ui, getEditorTheme(), this.keybindings, {
|
|
393
|
+
paddingX: editorPaddingX,
|
|
394
|
+
autocompleteMaxVisible,
|
|
395
|
+
});
|
|
380
396
|
this.editor = this.defaultEditor;
|
|
397
|
+
options.startupView?.setCurrentEditor(() => this.editor);
|
|
381
398
|
this.editorContainer = new Container();
|
|
382
399
|
this.editorContainer.addChild(this.editor);
|
|
383
400
|
this.footerDataProvider = new FooterDataProvider(this.sessionManager.getCwd());
|
|
@@ -511,11 +528,17 @@ export class InteractiveMode {
|
|
|
511
528
|
});
|
|
512
529
|
}
|
|
513
530
|
}
|
|
514
|
-
return new CombinedAutocompleteProvider([...slashCommands, ...templateCommands, ...extensionCommands, ...skillCommandList], this.sessionManager.getCwd(), this.fdPath)
|
|
531
|
+
return wrapSkillTagAutocomplete(new CombinedAutocompleteProvider([...slashCommands, ...templateCommands, ...extensionCommands, ...skillCommandList], this.sessionManager.getCwd(), this.fdPath), {
|
|
532
|
+
character: this.settingsManager.getSkillTagCharacter(),
|
|
533
|
+
skills: this.session.resourceLoader.getSkills().skills.map((skill) => ({
|
|
534
|
+
name: skill.name,
|
|
535
|
+
description: this.prefixAutocompleteDescription(skill.description, skill.sourceInfo),
|
|
536
|
+
})),
|
|
537
|
+
});
|
|
515
538
|
}
|
|
516
539
|
setupAutocompleteProvider() {
|
|
517
540
|
let provider = this.createBaseAutocompleteProvider();
|
|
518
|
-
const triggerCharacters = [];
|
|
541
|
+
const triggerCharacters = [...(provider.triggerCharacters ?? [])];
|
|
519
542
|
for (const wrapProvider of this.autocompleteProviderWrappers) {
|
|
520
543
|
provider = wrapProvider(provider);
|
|
521
544
|
triggerCharacters.push(...(provider.triggerCharacters ?? []));
|
|
@@ -533,14 +556,10 @@ export class InteractiveMode {
|
|
|
533
556
|
if (this.isInitialized)
|
|
534
557
|
return;
|
|
535
558
|
this.registerSignalHandlers();
|
|
536
|
-
// Use already-installed fd immediately. Download in the background so a
|
|
537
|
-
// missing binary or GitHub outage cannot block first paint.
|
|
538
559
|
this.fdPath = getToolPath("fd") ?? undefined;
|
|
539
|
-
void
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
this.setupAutocompleteProvider();
|
|
543
|
-
}
|
|
560
|
+
void startInteractiveToolInstalls(this.fdPath, (fdPath) => {
|
|
561
|
+
this.fdPath = fdPath;
|
|
562
|
+
this.setupAutocompleteProvider();
|
|
544
563
|
});
|
|
545
564
|
time("ensureTools");
|
|
546
565
|
if (this.session.scopedModels.length > 0 && (this.options.verbose || !this.settingsManager.getQuietStartup())) {
|
|
@@ -556,6 +575,10 @@ export class InteractiveMode {
|
|
|
556
575
|
: "";
|
|
557
576
|
console.log(theme.fg("dim", `Model scope: ${modelList}${cycleHint}`));
|
|
558
577
|
}
|
|
578
|
+
if (this.options.startupView) {
|
|
579
|
+
this.ui.pinFrom(null);
|
|
580
|
+
this.ui.clear();
|
|
581
|
+
}
|
|
559
582
|
// Add header container as first child. Populate it after applying theme settings.
|
|
560
583
|
// Keep loaded resources before chat so restored session messages never precede them.
|
|
561
584
|
this.ui.addChild(this.headerContainer);
|
|
@@ -567,14 +590,16 @@ export class InteractiveMode {
|
|
|
567
590
|
this.ui.addChild(this.widgetContainerAbove);
|
|
568
591
|
this.ui.addChild(this.editorContainer);
|
|
569
592
|
this.ui.addChild(this.widgetContainerBelow);
|
|
570
|
-
this.ui.addChild(this.footer);
|
|
593
|
+
this.ui.addChild(this.customFooter ?? this.footer);
|
|
571
594
|
this.ui.setFocus(this.editor);
|
|
572
|
-
this.setupKeyHandlers();
|
|
573
|
-
this.setupEditorSubmitHandler();
|
|
574
595
|
this.ui.pinFrom(this.widgetContainerAbove);
|
|
596
|
+
this.setupKeyHandlers();
|
|
597
|
+
if (!this.options.startupView)
|
|
598
|
+
this.setupEditorSubmitHandler();
|
|
575
599
|
this.ui.setAlternateScreen(true);
|
|
576
600
|
// Start the UI before initializing extensions so session_start handlers can use interactive dialogs
|
|
577
|
-
this.
|
|
601
|
+
if (!this.options.startupView)
|
|
602
|
+
this.ui.start();
|
|
578
603
|
this.isInitialized = true;
|
|
579
604
|
time("ui.start");
|
|
580
605
|
void this.maybeNotifyCliUpdate();
|
|
@@ -611,6 +636,7 @@ export class InteractiveMode {
|
|
|
611
636
|
setRollbackWarningHandler((msg) => this.showStatus(msg));
|
|
612
637
|
this.syncPermissionModeEffects(this.settingsManager.getDefaultPermissionMode());
|
|
613
638
|
await this.themeController.applyFromSettings();
|
|
639
|
+
this.headerContainer.clear();
|
|
614
640
|
// Add boot screen header (unless silenced)
|
|
615
641
|
if (this.options.verbose || !this.settingsManager.getQuietStartup()) {
|
|
616
642
|
const header = theme.bold(theme.fg("accent", APP_NAME)) + theme.fg("dim", ` v${this.version}`);
|
|
@@ -630,9 +656,32 @@ export class InteractiveMode {
|
|
|
630
656
|
await this.rebindCurrentSession();
|
|
631
657
|
time("rebindCurrentSession");
|
|
632
658
|
this.renderInitialMessages();
|
|
659
|
+
this.ui.requestRender();
|
|
660
|
+
for (const diagnostic of this.options.startupDiagnostics ?? [])
|
|
661
|
+
this.showStatus(diagnostic.message);
|
|
662
|
+
for (const warning of this.options.deprecationWarnings ?? [])
|
|
663
|
+
this.showWarning(warning);
|
|
633
664
|
this.deferredBuiltinAttachPromise = this.attachDeferredBuiltinExtensions();
|
|
634
|
-
|
|
665
|
+
this.startupReadyPromise = this.deferredBuiltinAttachPromise.then(() => {
|
|
666
|
+
if (!this.isInitialized)
|
|
667
|
+
return;
|
|
668
|
+
if (this.startupFeatureError)
|
|
669
|
+
throw this.startupFeatureError;
|
|
670
|
+
if (this.options.startupView) {
|
|
671
|
+
this.setupEditorSubmitHandler();
|
|
672
|
+
// Extensions can replace the editor. Wire its submit callback after readiness as well.
|
|
673
|
+
this.editor.onSubmit = this.defaultEditor.onSubmit;
|
|
674
|
+
this.options.startupView.activate();
|
|
675
|
+
}
|
|
635
676
|
time("attachDeferredBuiltins");
|
|
677
|
+
markStartupMilestone("prompt_barrier_open");
|
|
678
|
+
void this.options.deferredMaintenance?.();
|
|
679
|
+
});
|
|
680
|
+
void this.startupReadyPromise.catch((error) => {
|
|
681
|
+
if (this.options.startupView)
|
|
682
|
+
this.options.startupView.showError(error);
|
|
683
|
+
else
|
|
684
|
+
this.showError(String(error));
|
|
636
685
|
});
|
|
637
686
|
// Set up theme file watcher
|
|
638
687
|
onThemeChange(() => {
|
|
@@ -648,6 +697,21 @@ export class InteractiveMode {
|
|
|
648
697
|
void this.updateAvailableProviderCount().then(() => {
|
|
649
698
|
time("updateAvailableProviderCount");
|
|
650
699
|
});
|
|
700
|
+
void this.waitForDeferredBuiltins().then(() => {
|
|
701
|
+
if (!this.isInitialized)
|
|
702
|
+
return;
|
|
703
|
+
this.stopCatalogRefresh = startCatalogRefreshPolling({
|
|
704
|
+
refresh: (signal) => this.session.modelRuntime.refreshIfStale({ signal }),
|
|
705
|
+
isBusy: () => this.session.isStreaming,
|
|
706
|
+
onUpdate: () => {
|
|
707
|
+
this.session.refreshModelFromRegistry();
|
|
708
|
+
this.footer.invalidate();
|
|
709
|
+
},
|
|
710
|
+
});
|
|
711
|
+
});
|
|
712
|
+
}
|
|
713
|
+
async waitForStartupReady() {
|
|
714
|
+
await this.startupReadyPromise;
|
|
651
715
|
}
|
|
652
716
|
/** Wait until deferred builtins have attached (or were skipped). */
|
|
653
717
|
async waitForDeferredBuiltins() {
|
|
@@ -708,6 +772,7 @@ export class InteractiveMode {
|
|
|
708
772
|
if (!this.isInitialized) {
|
|
709
773
|
await this.init();
|
|
710
774
|
}
|
|
775
|
+
await this.waitForStartupReady();
|
|
711
776
|
// Check tmux keyboard setup asynchronously
|
|
712
777
|
this.checkTmuxKeyboardSetup().then((warning) => {
|
|
713
778
|
if (warning) {
|
|
@@ -1275,6 +1340,8 @@ export class InteractiveMode {
|
|
|
1275
1340
|
catch (error) {
|
|
1276
1341
|
this.deferredBuiltinsAttached = false;
|
|
1277
1342
|
const message = error instanceof Error ? error.message : String(error);
|
|
1343
|
+
if (this.options.startupView)
|
|
1344
|
+
this.startupFeatureError = new Error(message);
|
|
1278
1345
|
this.showError(`Failed to load deferred extensions: ${message}`);
|
|
1279
1346
|
}
|
|
1280
1347
|
finally {
|
|
@@ -1935,6 +2002,7 @@ export class InteractiveMode {
|
|
|
1935
2002
|
this.editorComponentFactory = factory;
|
|
1936
2003
|
// Save text from current editor before switching
|
|
1937
2004
|
const currentText = this.editor.getText();
|
|
2005
|
+
const startupImages = this.options.startupView ? this.editor.getPendingImages?.() : undefined;
|
|
1938
2006
|
this.editorContainer.clear();
|
|
1939
2007
|
if (factory) {
|
|
1940
2008
|
// Create the custom editor with tui, theme, and keybindings
|
|
@@ -1943,7 +2011,16 @@ export class InteractiveMode {
|
|
|
1943
2011
|
newEditor.onSubmit = this.defaultEditor.onSubmit;
|
|
1944
2012
|
newEditor.onChange = this.defaultEditor.onChange;
|
|
1945
2013
|
// Copy text from previous editor
|
|
1946
|
-
newEditor.
|
|
2014
|
+
if (newEditor !== this.editor) {
|
|
2015
|
+
newEditor.setText(currentText);
|
|
2016
|
+
if (startupImages?.length) {
|
|
2017
|
+
if (newEditor.restoreImageMarkers)
|
|
2018
|
+
newEditor.restoreImageMarkers(startupImages);
|
|
2019
|
+
else
|
|
2020
|
+
for (const image of startupImages)
|
|
2021
|
+
this.fallbackImageAttachments.set(image.id, image);
|
|
2022
|
+
}
|
|
2023
|
+
}
|
|
1947
2024
|
// Copy appearance settings if supported
|
|
1948
2025
|
if (newEditor.borderColor !== undefined) {
|
|
1949
2026
|
newEditor.borderColor = this.defaultEditor.borderColor;
|
|
@@ -1958,16 +2035,15 @@ export class InteractiveMode {
|
|
|
1958
2035
|
// If extending CustomEditor, copy app-level handlers
|
|
1959
2036
|
// Use duck typing since instanceof fails across jiti module boundaries
|
|
1960
2037
|
const customEditor = newEditor;
|
|
1961
|
-
if (
|
|
2038
|
+
if (newEditor !== this.defaultEditor &&
|
|
2039
|
+
"actionHandlers" in customEditor &&
|
|
2040
|
+
customEditor.actionHandlers instanceof Map) {
|
|
1962
2041
|
if (!customEditor.onEscape) {
|
|
1963
2042
|
customEditor.onEscape = () => this.defaultEditor.onEscape?.();
|
|
1964
2043
|
}
|
|
1965
2044
|
if (!customEditor.onCtrlD) {
|
|
1966
2045
|
customEditor.onCtrlD = () => this.defaultEditor.onCtrlD?.();
|
|
1967
2046
|
}
|
|
1968
|
-
if (!customEditor.onPasteImage) {
|
|
1969
|
-
customEditor.onPasteImage = () => this.defaultEditor.onPasteImage?.();
|
|
1970
|
-
}
|
|
1971
2047
|
if (!customEditor.onExtensionShortcut) {
|
|
1972
2048
|
customEditor.onExtensionShortcut = (data) => this.defaultEditor.onExtensionShortcut?.(data);
|
|
1973
2049
|
}
|
|
@@ -1980,7 +2056,8 @@ export class InteractiveMode {
|
|
|
1980
2056
|
}
|
|
1981
2057
|
else {
|
|
1982
2058
|
// Restore default editor with text from custom editor
|
|
1983
|
-
this.defaultEditor
|
|
2059
|
+
if (this.editor !== this.defaultEditor)
|
|
2060
|
+
this.defaultEditor.setText(currentText);
|
|
1984
2061
|
this.editor = this.defaultEditor;
|
|
1985
2062
|
}
|
|
1986
2063
|
this.editorContainer.addChild(this.editor);
|
|
@@ -2142,6 +2219,7 @@ export class InteractiveMode {
|
|
|
2142
2219
|
// lunr: tool/thinking expand is per-item click; ctrl+o is not bound (tree filter still uses ctrl+o).
|
|
2143
2220
|
this.defaultEditor.onAction("app.thinking.toggle", () => this.toggleThinkingBlockVisibility());
|
|
2144
2221
|
this.defaultEditor.onAction("app.editor.external", () => this.openExternalEditor());
|
|
2222
|
+
this.defaultEditor.onAction("app.clipboard.pasteImage", () => void this.handleClipboardPaste());
|
|
2145
2223
|
this.defaultEditor.onAction("app.message.copy", () => void this.handleCopyCommand());
|
|
2146
2224
|
this.defaultEditor.onAction("app.message.followUp", () => this.handleFollowUp());
|
|
2147
2225
|
this.defaultEditor.onAction("app.message.dequeue", () => this.handleDequeue());
|
|
@@ -2156,12 +2234,6 @@ export class InteractiveMode {
|
|
|
2156
2234
|
this.updateEditorBorderColor();
|
|
2157
2235
|
}
|
|
2158
2236
|
};
|
|
2159
|
-
// Handle clipboard paste (keybinding: app.clipboard.pasteImage, Alt+V on Windows —
|
|
2160
|
-
// Ctrl+V is owned by the terminal and never reaches us). Images become `[image_n]`
|
|
2161
|
-
// chips; otherwise, paste plain text from the system clipboard.
|
|
2162
|
-
this.defaultEditor.onPasteImage = () => {
|
|
2163
|
-
void this.handleClipboardPaste();
|
|
2164
|
-
};
|
|
2165
2237
|
this.ui.addInputListener((data) => {
|
|
2166
2238
|
if (!this.ui.isPinned())
|
|
2167
2239
|
return;
|
|
@@ -2283,7 +2355,7 @@ export class InteractiveMode {
|
|
|
2283
2355
|
restoreEditorFromTreeResult(result) {
|
|
2284
2356
|
this.restoreEditorDraft(result.editorText ?? "", result.editorImages);
|
|
2285
2357
|
}
|
|
2286
|
-
async handleClipboardPaste() {
|
|
2358
|
+
async handleClipboardPaste(options = {}) {
|
|
2287
2359
|
try {
|
|
2288
2360
|
const image = await readClipboardImage();
|
|
2289
2361
|
if (image) {
|
|
@@ -2293,13 +2365,15 @@ export class InteractiveMode {
|
|
|
2293
2365
|
this.showStatus(`Pasted ${formatImageMarker(id)}`);
|
|
2294
2366
|
return;
|
|
2295
2367
|
}
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2368
|
+
if (options.textFallback !== false) {
|
|
2369
|
+
const text = await readClipboardText();
|
|
2370
|
+
if (text) {
|
|
2371
|
+
this.editor.insertTextAtCursor?.(text);
|
|
2372
|
+
this.ui.requestRender();
|
|
2373
|
+
return;
|
|
2374
|
+
}
|
|
2301
2375
|
}
|
|
2302
|
-
this.showStatus("Clipboard contains no image or text");
|
|
2376
|
+
this.showStatus(options.textFallback === false ? "Clipboard contains no image" : "Clipboard contains no image or text");
|
|
2303
2377
|
}
|
|
2304
2378
|
catch (err) {
|
|
2305
2379
|
this.showStatus(`Clipboard paste failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -2315,6 +2389,11 @@ export class InteractiveMode {
|
|
|
2315
2389
|
const images = this.consumeStagedSubmitImages() ?? (await this.loadImageAttachments(this.takeSubmittedImages(text)));
|
|
2316
2390
|
this.ui.setChatScroll(0);
|
|
2317
2391
|
// Handle commands
|
|
2392
|
+
if (text === "/paste-image") {
|
|
2393
|
+
this.editor.setText("");
|
|
2394
|
+
await this.handleClipboardPaste({ textFallback: false });
|
|
2395
|
+
return;
|
|
2396
|
+
}
|
|
2318
2397
|
if (text === "/settings") {
|
|
2319
2398
|
void this.showSettingsSelector();
|
|
2320
2399
|
this.editor.setText("");
|
|
@@ -2734,7 +2813,7 @@ export class InteractiveMode {
|
|
|
2734
2813
|
this.ui.requestRender();
|
|
2735
2814
|
}
|
|
2736
2815
|
else if (event.message.role === "assistant") {
|
|
2737
|
-
this.streamingComponent = new AssistantMessageComponent(undefined, this.hideThinkingBlock, this.getMarkdownThemeWithSettings(), this.hiddenThinkingLabel, this.outputPad, this.
|
|
2816
|
+
this.streamingComponent = new AssistantMessageComponent(undefined, this.hideThinkingBlock, this.getMarkdownThemeWithSettings(), this.hiddenThinkingLabel, this.outputPad, this.thinkingCollapse);
|
|
2738
2817
|
// lunr: collapsible reasoning — fresh timing array for this message.
|
|
2739
2818
|
this.thinkingRunTimings = [];
|
|
2740
2819
|
this.streamingComponent.setThinkingTimings(this.thinkingRunTimings);
|
|
@@ -2871,6 +2950,7 @@ export class InteractiveMode {
|
|
|
2871
2950
|
break;
|
|
2872
2951
|
}
|
|
2873
2952
|
case "agent_end":
|
|
2953
|
+
this.session.refreshModelFromRegistry();
|
|
2874
2954
|
if (this.settingsManager.getShowTerminalProgress()) {
|
|
2875
2955
|
this.ui.terminal.setProgress(false);
|
|
2876
2956
|
}
|
|
@@ -3082,12 +3162,12 @@ export class InteractiveMode {
|
|
|
3082
3162
|
// Render user message separately if present
|
|
3083
3163
|
if (skillBlock.userMessage) {
|
|
3084
3164
|
this.chatContainer.addChild(new Spacer(1));
|
|
3085
|
-
const userComponent = new UserMessageComponent(skillBlock.userMessage, this.getMarkdownThemeWithSettings(), this.outputPad
|
|
3165
|
+
const userComponent = new UserMessageComponent(skillBlock.userMessage, this.getMarkdownThemeWithSettings(), this.outputPad);
|
|
3086
3166
|
this.chatContainer.addChild(userComponent);
|
|
3087
3167
|
}
|
|
3088
3168
|
}
|
|
3089
3169
|
else {
|
|
3090
|
-
const userComponent = new UserMessageComponent(textContent, this.getMarkdownThemeWithSettings(), this.outputPad
|
|
3170
|
+
const userComponent = new UserMessageComponent(textContent, this.getMarkdownThemeWithSettings(), this.outputPad);
|
|
3091
3171
|
this.chatContainer.addChild(userComponent);
|
|
3092
3172
|
}
|
|
3093
3173
|
if (options?.populateHistory) {
|
|
@@ -3097,7 +3177,7 @@ export class InteractiveMode {
|
|
|
3097
3177
|
break;
|
|
3098
3178
|
}
|
|
3099
3179
|
case "assistant": {
|
|
3100
|
-
const assistantComponent = new AssistantMessageComponent(message, this.hideThinkingBlock, this.getMarkdownThemeWithSettings(), this.hiddenThinkingLabel, this.outputPad, this.
|
|
3180
|
+
const assistantComponent = new AssistantMessageComponent(message, this.hideThinkingBlock, this.getMarkdownThemeWithSettings(), this.hiddenThinkingLabel, this.outputPad, this.thinkingCollapse);
|
|
3101
3181
|
// lunr: collapsible reasoning — re-attach live timings when this
|
|
3102
3182
|
// message was streamed in this session (undefined = history).
|
|
3103
3183
|
assistantComponent.setThinkingTimings(this.thinkingTimingsByMessage.get(message));
|
|
@@ -3891,6 +3971,7 @@ export class InteractiveMode {
|
|
|
3891
3971
|
autoResizeImages: this.settingsManager.getImageAutoResize(),
|
|
3892
3972
|
blockImages: this.settingsManager.getBlockImages(),
|
|
3893
3973
|
enableSkillCommands: this.settingsManager.getEnableSkillCommands(),
|
|
3974
|
+
skillTagCharacter: this.settingsManager.getSkillTagCharacter(),
|
|
3894
3975
|
steeringMode: this.session.steeringMode,
|
|
3895
3976
|
followUpMode: this.session.followUpMode,
|
|
3896
3977
|
transport: this.settingsManager.getTransport(),
|
|
@@ -3921,8 +4002,6 @@ export class InteractiveMode {
|
|
|
3921
4002
|
memoryCharCap: this.settingsManager.getMemoryCharCap(),
|
|
3922
4003
|
searchCurator: getSearchCuratorSetting(),
|
|
3923
4004
|
// lunr: TUI customize settings
|
|
3924
|
-
gutterRail: this.settingsManager.getGutterRail(),
|
|
3925
|
-
promptSymbol: this.settingsManager.getPromptSymbol(),
|
|
3926
4005
|
footerMcp: this.settingsManager.getFooterMcp(),
|
|
3927
4006
|
footerLsp: this.settingsManager.getFooterLsp(),
|
|
3928
4007
|
footerContext: this.settingsManager.getFooterContext(),
|
|
@@ -3973,6 +4052,10 @@ export class InteractiveMode {
|
|
|
3973
4052
|
this.settingsManager.setEnableSkillCommands(enabled);
|
|
3974
4053
|
this.setupAutocompleteProvider();
|
|
3975
4054
|
},
|
|
4055
|
+
onSkillTagCharacterChange: (character) => {
|
|
4056
|
+
this.settingsManager.setSkillTagCharacter(character);
|
|
4057
|
+
this.setupAutocompleteProvider();
|
|
4058
|
+
},
|
|
3976
4059
|
onSteeringModeChange: (mode) => {
|
|
3977
4060
|
this.session.setSteeringMode(mode);
|
|
3978
4061
|
},
|
|
@@ -4120,12 +4203,6 @@ export class InteractiveMode {
|
|
|
4120
4203
|
}
|
|
4121
4204
|
},
|
|
4122
4205
|
// lunr: TUI customize callbacks
|
|
4123
|
-
onGutterRailChange: (enabled) => {
|
|
4124
|
-
this.settingsManager.setGutterRail(enabled);
|
|
4125
|
-
},
|
|
4126
|
-
onPromptSymbolChange: (enabled) => {
|
|
4127
|
-
this.settingsManager.setPromptSymbol(enabled);
|
|
4128
|
-
},
|
|
4129
4206
|
onFooterMcpChange: (enabled) => {
|
|
4130
4207
|
this.settingsManager.setFooterMcp(enabled);
|
|
4131
4208
|
},
|
|
@@ -4245,40 +4322,9 @@ export class InteractiveMode {
|
|
|
4245
4322
|
this.footer.invalidate();
|
|
4246
4323
|
return;
|
|
4247
4324
|
}
|
|
4248
|
-
|
|
4249
|
-
const
|
|
4250
|
-
const extraDefaults = Math.max(0, incomplete.length - toPrompt.length);
|
|
4251
|
-
const persisted = [];
|
|
4325
|
+
// Discovered metadata stays in its cache, not in user overrides. Enrichment is automatic.
|
|
4326
|
+
const extraDefaults = result.incomplete.length;
|
|
4252
4327
|
const asked = [];
|
|
4253
|
-
let skipRemaining = false;
|
|
4254
|
-
for (const item of toPrompt) {
|
|
4255
|
-
if (skipRemaining) {
|
|
4256
|
-
persisted.push(modelToUserEntry(item.draft));
|
|
4257
|
-
continue;
|
|
4258
|
-
}
|
|
4259
|
-
const choice = await this.showExtensionSelector(describeIncomplete(item), [
|
|
4260
|
-
"Enter details",
|
|
4261
|
-
"Use defaults",
|
|
4262
|
-
"Skip remaining",
|
|
4263
|
-
]);
|
|
4264
|
-
asked.push(`${item.provider}/${item.id}`);
|
|
4265
|
-
if (choice === "Skip remaining") {
|
|
4266
|
-
skipRemaining = true;
|
|
4267
|
-
persisted.push(modelToUserEntry(item.draft));
|
|
4268
|
-
continue;
|
|
4269
|
-
}
|
|
4270
|
-
if (choice === "Enter details") {
|
|
4271
|
-
const detailed = await this.promptIncompleteModelDetails(item);
|
|
4272
|
-
persisted.push(modelToUserEntry(detailed ?? item.draft));
|
|
4273
|
-
continue;
|
|
4274
|
-
}
|
|
4275
|
-
persisted.push(modelToUserEntry(item.draft));
|
|
4276
|
-
}
|
|
4277
|
-
for (const item of incomplete.slice(toPrompt.length)) {
|
|
4278
|
-
persisted.push(modelToUserEntry(item.draft));
|
|
4279
|
-
}
|
|
4280
|
-
if (persisted.length > 0)
|
|
4281
|
-
runtime.persistUserModels(persisted);
|
|
4282
4328
|
let ollama;
|
|
4283
4329
|
const runner = this.session.extensionRunner;
|
|
4284
4330
|
const cloudRefresh = globalThis[Symbol.for("@lunr/ollama-cloud-refresh")];
|
|
@@ -4299,53 +4345,26 @@ export class InteractiveMode {
|
|
|
4299
4345
|
evictedUserRows: result.official.evictedUserRows,
|
|
4300
4346
|
}
|
|
4301
4347
|
: undefined,
|
|
4302
|
-
providers:
|
|
4303
|
-
|
|
4304
|
-
|
|
4305
|
-
|
|
4306
|
-
|
|
4307
|
-
|
|
4308
|
-
|
|
4348
|
+
providers: [
|
|
4349
|
+
...result.live.map((entry) => ({
|
|
4350
|
+
id: entry.providerId,
|
|
4351
|
+
status: entry.status,
|
|
4352
|
+
added: entry.added,
|
|
4353
|
+
total: entry.total,
|
|
4354
|
+
error: entry.error,
|
|
4355
|
+
})),
|
|
4356
|
+
...Object.entries(result.official?.errors ?? {}).map(([id, error]) => ({
|
|
4357
|
+
id,
|
|
4358
|
+
status: "error",
|
|
4359
|
+
error,
|
|
4360
|
+
})),
|
|
4361
|
+
],
|
|
4309
4362
|
asked,
|
|
4310
4363
|
extraDefaults,
|
|
4311
4364
|
ollama,
|
|
4312
4365
|
}));
|
|
4313
4366
|
this.footer.invalidate();
|
|
4314
4367
|
}
|
|
4315
|
-
async promptIncompleteModelDetails(item) {
|
|
4316
|
-
const contextInput = await this.showExtensionInput(`${item.provider}/${item.id} — context window:`, String(item.draft.contextWindow || 128000));
|
|
4317
|
-
if (contextInput === undefined)
|
|
4318
|
-
return undefined;
|
|
4319
|
-
const maxTokensInput = await this.showExtensionInput(`${item.provider}/${item.id} — max output tokens:`, String(item.draft.maxTokens || 8192));
|
|
4320
|
-
if (maxTokensInput === undefined)
|
|
4321
|
-
return undefined;
|
|
4322
|
-
const inputChoice = await this.showExtensionSelector(`${item.provider}/${item.id} — input:`, [
|
|
4323
|
-
"text",
|
|
4324
|
-
"text + image",
|
|
4325
|
-
]);
|
|
4326
|
-
if (inputChoice === undefined)
|
|
4327
|
-
return undefined;
|
|
4328
|
-
const reasoningChoice = await this.showExtensionSelector(`${item.provider}/${item.id} — reasoning:`, [
|
|
4329
|
-
"yes",
|
|
4330
|
-
"no",
|
|
4331
|
-
]);
|
|
4332
|
-
if (reasoningChoice === undefined)
|
|
4333
|
-
return undefined;
|
|
4334
|
-
let api = item.draft.api;
|
|
4335
|
-
if (item.availableApis.length > 1) {
|
|
4336
|
-
const apiChoice = await this.showExtensionSelector(`${item.provider}/${item.id} — API protocol:`, item.availableApis.map(String));
|
|
4337
|
-
if (apiChoice === undefined)
|
|
4338
|
-
return undefined;
|
|
4339
|
-
api = apiChoice;
|
|
4340
|
-
}
|
|
4341
|
-
return applyIncompleteAnswers(item.draft, {
|
|
4342
|
-
contextWindow: parsePositiveInt(contextInput, item.draft.contextWindow),
|
|
4343
|
-
maxTokens: parsePositiveInt(maxTokensInput, item.draft.maxTokens),
|
|
4344
|
-
input: inputChoice === "text + image" ? ["text", "image"] : ["text"],
|
|
4345
|
-
reasoning: reasoningChoice === "yes",
|
|
4346
|
-
api,
|
|
4347
|
-
});
|
|
4348
|
-
}
|
|
4349
4368
|
async findExactModelMatch(searchTerm) {
|
|
4350
4369
|
const models = await this.getModelCandidates();
|
|
4351
4370
|
return findExactModelReferenceMatch(searchTerm, models);
|
|
@@ -6123,6 +6142,7 @@ export class InteractiveMode {
|
|
|
6123
6142
|
tools,
|
|
6124
6143
|
messages: this.session.messages,
|
|
6125
6144
|
contextWindow,
|
|
6145
|
+
globalAgentsPath: path.join(getAgentDir(), "AGENTS.md"),
|
|
6126
6146
|
});
|
|
6127
6147
|
}
|
|
6128
6148
|
handleFastCommand(arg) {
|
|
@@ -6387,7 +6407,7 @@ export class InteractiveMode {
|
|
|
6387
6407
|
// the result text the model sees. Esc/close counts as Decline.
|
|
6388
6408
|
showPlanInChat(summary) {
|
|
6389
6409
|
this.chatContainer.addChild(new Spacer(1));
|
|
6390
|
-
this.chatContainer.addChild(new PlanMessageComponent(summary, this.getMarkdownThemeWithSettings(), this.outputPad
|
|
6410
|
+
this.chatContainer.addChild(new PlanMessageComponent(summary, this.getMarkdownThemeWithSettings(), this.outputPad));
|
|
6391
6411
|
this.ui.requestRender();
|
|
6392
6412
|
}
|
|
6393
6413
|
async showPlanApprovalDialog(summary) {
|
|
@@ -6601,6 +6621,7 @@ ${cycleThinkingLevel ? `| \`${cycleThinkingLevel}\` | Cycle thinking level |\n`
|
|
|
6601
6621
|
| \`${followUp}\` | Queue follow-up message |
|
|
6602
6622
|
| \`${dequeue}\` | Restore queued messages |
|
|
6603
6623
|
| \`${pasteImage}\` | Paste image or text from clipboard |
|
|
6624
|
+
| \`/paste-image\` | Paste image without a terminal shortcut |
|
|
6604
6625
|
| \`/\` | Slash commands |
|
|
6605
6626
|
| \`!\` | Run bash command |
|
|
6606
6627
|
| \`!!\` | Run bash command (excluded from context) |
|
|
@@ -6769,6 +6790,8 @@ ${cycleThinkingLevel ? `| \`${cycleThinkingLevel}\` | Cycle thinking level |\n`
|
|
|
6769
6790
|
}
|
|
6770
6791
|
}
|
|
6771
6792
|
stop() {
|
|
6793
|
+
this.stopCatalogRefresh?.();
|
|
6794
|
+
this.stopCatalogRefresh = undefined;
|
|
6772
6795
|
if (this.settingsManager.getShowTerminalProgress()) {
|
|
6773
6796
|
this.ui.terminal.setProgress(false);
|
|
6774
6797
|
}
|