@bastani/atomic 0.8.30 → 0.8.31-alpha.2
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 +29 -0
- package/README.md +12 -10
- package/dist/builtin/cursor/CHANGELOG.md +4 -0
- package/dist/builtin/cursor/package.json +2 -2
- package/dist/builtin/intercom/CHANGELOG.md +4 -0
- package/dist/builtin/intercom/package.json +2 -2
- package/dist/builtin/mcp/CHANGELOG.md +4 -0
- package/dist/builtin/mcp/package.json +3 -3
- package/dist/builtin/subagents/CHANGELOG.md +13 -0
- package/dist/builtin/subagents/agents/codebase-online-researcher.md +8 -8
- package/dist/builtin/subagents/agents/debugger.md +6 -6
- package/dist/builtin/subagents/package.json +4 -4
- package/dist/builtin/subagents/skills/effective-liteparse/SKILL.md +118 -0
- package/dist/builtin/subagents/skills/effective-liteparse/scripts/search.py +128 -0
- package/dist/builtin/subagents/skills/playwright-cli/SKILL.md +404 -0
- package/dist/builtin/subagents/skills/playwright-cli/references/element-attributes.md +23 -0
- package/dist/builtin/subagents/skills/playwright-cli/references/playwright-tests.md +39 -0
- package/dist/builtin/subagents/skills/playwright-cli/references/request-mocking.md +87 -0
- package/dist/builtin/subagents/skills/playwright-cli/references/running-code.md +241 -0
- package/dist/builtin/subagents/skills/playwright-cli/references/session-management.md +225 -0
- package/dist/builtin/subagents/skills/playwright-cli/references/spec-driven-testing.md +305 -0
- package/dist/builtin/subagents/skills/playwright-cli/references/storage-state.md +275 -0
- package/dist/builtin/subagents/skills/playwright-cli/references/test-generation.md +134 -0
- package/dist/builtin/subagents/skills/playwright-cli/references/tracing.md +139 -0
- package/dist/builtin/subagents/skills/playwright-cli/references/video-recording.md +143 -0
- package/dist/builtin/web-access/CHANGELOG.md +4 -0
- package/dist/builtin/web-access/package.json +2 -2
- package/dist/builtin/workflows/CHANGELOG.md +16 -0
- package/dist/builtin/workflows/README.md +4 -4
- package/dist/builtin/workflows/builtin/deep-research-codebase.ts +1 -1
- package/dist/builtin/workflows/builtin/goal.ts +2 -2
- package/dist/builtin/workflows/builtin/open-claude-design.ts +60 -57
- package/dist/builtin/workflows/builtin/ralph.ts +117 -14
- package/dist/builtin/workflows/builtin/shared-prompts.ts +1 -1
- package/dist/builtin/workflows/package.json +2 -2
- package/dist/builtin/workflows/skills/research-codebase/SKILL.md +1 -1
- package/dist/builtin/workflows/src/extension/workflow-schema.ts +3 -1
- package/dist/builtin/workflows/src/runs/foreground/stage-runner.ts +5 -0
- package/dist/builtin/workflows/src/runs/shared/model-fallback.ts +95 -8
- package/dist/builtin/workflows/src/shared/authoring-contract.d.ts +11 -0
- package/dist/cli/args.d.ts +1 -0
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +21 -1
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/list-models.d.ts.map +1 -1
- package/dist/cli/list-models.js +2 -1
- package/dist/cli/list-models.js.map +1 -1
- package/dist/core/agent-session-services.d.ts +2 -0
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +2 -0
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session.d.ts +18 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +182 -19
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js +20 -5
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/context-compaction.d.ts.map +1 -1
- package/dist/core/compaction/context-compaction.js +14 -3
- package/dist/core/compaction/context-compaction.js.map +1 -1
- package/dist/core/context-window.d.ts +39 -0
- package/dist/core/context-window.d.ts.map +1 -0
- package/dist/core/context-window.js +99 -0
- package/dist/core/context-window.js.map +1 -0
- package/dist/core/copilot-errors.d.ts +9 -0
- package/dist/core/copilot-errors.d.ts.map +1 -0
- package/dist/core/copilot-errors.js +32 -0
- package/dist/core/copilot-errors.js.map +1 -0
- package/dist/core/copilot-model-catalog.d.ts +135 -0
- package/dist/core/copilot-model-catalog.d.ts.map +1 -0
- package/dist/core/copilot-model-catalog.js +257 -0
- package/dist/core/copilot-model-catalog.js.map +1 -0
- package/dist/core/export-html/template.js +10 -1
- package/dist/core/extensions/types.d.ts +3 -1
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/model-registry.d.ts +10 -0
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +107 -4
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +4 -0
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/project-trust.d.ts.map +1 -1
- package/dist/core/project-trust.js +2 -1
- package/dist/core/project-trust.js.map +1 -1
- package/dist/core/provider-attribution.d.ts.map +1 -1
- package/dist/core/provider-attribution.js +17 -7
- package/dist/core/provider-attribution.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 +58 -0
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.d.ts +8 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +19 -3
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts +15 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +124 -1
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +1 -0
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tools/edit-diff.d.ts +1 -2
- package/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/dist/core/tools/edit-diff.js +1 -2
- package/dist/core/tools/edit-diff.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +24 -1
- package/dist/main.js.map +1 -1
- package/dist/modes/index.d.ts +1 -1
- package/dist/modes/index.d.ts.map +1 -1
- package/dist/modes/index.js.map +1 -1
- package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/config-selector.js +5 -7
- package/dist/modes/interactive/components/config-selector.js.map +1 -1
- package/dist/modes/interactive/components/context-window-selector.d.ts +53 -0
- package/dist/modes/interactive/components/context-window-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/context-window-selector.js +136 -0
- package/dist/modes/interactive/components/context-window-selector.js.map +1 -0
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +2 -1
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.js +4 -1
- package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +2 -0
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +165 -15
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/tree-selector.js +51 -4
- package/dist/modes/interactive/components/tree-selector.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +6 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +115 -55
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/model-search.d.ts +7 -0
- package/dist/modes/interactive/model-search.d.ts.map +1 -0
- package/dist/modes/interactive/model-search.js +6 -0
- package/dist/modes/interactive/model-search.js.map +1 -0
- package/dist/modes/interactive/theme/theme-controller.d.ts +30 -0
- package/dist/modes/interactive/theme/theme-controller.d.ts.map +1 -0
- package/dist/modes/interactive/theme/theme-controller.js +108 -0
- package/dist/modes/interactive/theme/theme-controller.js.map +1 -0
- package/dist/modes/interactive/theme/theme-schema.json +2 -1
- package/dist/modes/interactive/theme/theme.d.ts +5 -0
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +70 -29
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts +14 -2
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +23 -3
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +31 -2
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +23 -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 +39 -9
- package/dist/package-manager-cli.js.map +1 -1
- package/docs/custom-provider.md +4 -1
- package/docs/extensions.md +21 -0
- package/docs/json.md +3 -1
- package/docs/models.md +78 -2
- package/docs/packages.md +13 -9
- package/docs/providers.md +3 -0
- package/docs/quickstart.md +14 -0
- package/docs/rpc.md +80 -1
- package/docs/sdk.md +35 -11
- package/docs/session-format.md +15 -1
- package/docs/sessions.md +1 -1
- package/docs/settings.md +12 -2
- package/docs/themes.md +3 -1
- package/docs/tui.md +1 -1
- package/docs/usage.md +12 -9
- package/docs/workflows.md +34 -10
- 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/preset.ts +10 -4
- package/examples/extensions/provider-payload.ts +5 -5
- package/examples/extensions/sandbox/index.ts +2 -2
- package/examples/extensions/sandbox/package-lock.json +3 -3
- package/examples/extensions/sandbox/package.json +2 -2
- package/examples/extensions/subagent/agents.ts +2 -2
- package/examples/extensions/subagent/index.ts +4 -2
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/package.json +5 -5
- package/dist/builtin/subagents/skills/browser/EXAMPLES.md +0 -151
- package/dist/builtin/subagents/skills/browser/LICENSE.txt +0 -21
- package/dist/builtin/subagents/skills/browser/REFERENCE.md +0 -451
- package/dist/builtin/subagents/skills/browser/SKILL.md +0 -170
|
@@ -48,6 +48,9 @@ import { CustomMessageComponent } from "./components/custom-message.js";
|
|
|
48
48
|
import { DaxnutsComponent } from "./components/daxnuts.js";
|
|
49
49
|
import { renderAtomicAnsiBanner } from "./components/atomic-banner.js";
|
|
50
50
|
import { DynamicBorder } from "./components/dynamic-border.js";
|
|
51
|
+
import { ContextWindowSelectorComponent } from "./components/context-window-selector.js";
|
|
52
|
+
import { formatContextWindow } from "../../core/context-window.js";
|
|
53
|
+
import { copilotApiBaseUrlFromToken, copilotCatalogCacheHost, copilotCatalogCachePath, fetchCopilotModelCatalog, readCopilotCatalogCache, setActiveCopilotModelCatalog, writeCopilotCatalogCache, } from "../../core/copilot-model-catalog.js";
|
|
51
54
|
import { EarendilAnnouncementComponent } from "./components/earendil-announcement.js";
|
|
52
55
|
import { ExtensionEditorComponent } from "./components/extension-editor.js";
|
|
53
56
|
import { ExtensionInputComponent } from "./components/extension-input.js";
|
|
@@ -68,7 +71,9 @@ import { TrustSelectorComponent } from "./components/trust-selector.js";
|
|
|
68
71
|
import { hasProjectConfigDir, ProjectTrustStore } from "../../core/trust-manager.js";
|
|
69
72
|
import { UserMessageComponent } from "./components/user-message.js";
|
|
70
73
|
import { UserMessageSelectorComponent } from "./components/user-message-selector.js";
|
|
71
|
-
import {
|
|
74
|
+
import { getModelSearchText } from "./model-search.js";
|
|
75
|
+
import { getAvailableThemes, getAvailableThemesWithPaths, getEditorTheme, getMarkdownTheme, getThemeByName, onThemeChange, setRegisteredThemes, stopThemeWatcher, Theme, theme, } from "./theme/theme.js";
|
|
76
|
+
import { InteractiveThemeController } from "./theme/theme-controller.js";
|
|
72
77
|
function isExpandable(obj) {
|
|
73
78
|
return (typeof obj === "object" &&
|
|
74
79
|
obj !== null &&
|
|
@@ -161,6 +166,8 @@ export class InteractiveMode {
|
|
|
161
166
|
constructor(runtimeHost, options = {}) {
|
|
162
167
|
this.autocompleteProviderWrappers = [];
|
|
163
168
|
this.isInitialized = false;
|
|
169
|
+
// GitHub Copilot CAPI context-window catalog load state (gated on the Copilot provider).
|
|
170
|
+
this.copilotCatalogApplied = false;
|
|
164
171
|
this.pendingUserInputs = [];
|
|
165
172
|
this.loadingAnimation = undefined;
|
|
166
173
|
this.workingMessage = undefined;
|
|
@@ -265,23 +272,7 @@ export class InteractiveMode {
|
|
|
265
272
|
this.hideThinkingBlock = this.settingsManager.getHideThinkingBlock();
|
|
266
273
|
// Register themes from resource loader and initialize
|
|
267
274
|
setRegisteredThemes(this.session.resourceLoader.getThemes().themes);
|
|
268
|
-
|
|
269
|
-
}
|
|
270
|
-
async detectThemeIfUnset() {
|
|
271
|
-
if (this.settingsManager.getTheme()) {
|
|
272
|
-
return;
|
|
273
|
-
}
|
|
274
|
-
const detection = await detectTerminalBackgroundTheme({ ui: this.ui, timeoutMs: 100 });
|
|
275
|
-
const result = setTheme(detection.theme, true);
|
|
276
|
-
if (!result.success) {
|
|
277
|
-
return;
|
|
278
|
-
}
|
|
279
|
-
if (detection.confidence === "high") {
|
|
280
|
-
this.settingsManager.setTheme(detection.theme);
|
|
281
|
-
await this.settingsManager.flush();
|
|
282
|
-
}
|
|
283
|
-
this.updateEditorBorderColor();
|
|
284
|
-
this.ui.requestRender();
|
|
275
|
+
this.themeController = new InteractiveThemeController(this.ui, this.settingsManager, (message) => this.showError(message), () => this.updateEditorBorderColor());
|
|
285
276
|
}
|
|
286
277
|
getAutocompleteSourceTag(sourceInfo) {
|
|
287
278
|
if (!sourceInfo) {
|
|
@@ -356,10 +347,11 @@ export class InteractiveMode {
|
|
|
356
347
|
const items = models.map((m) => ({
|
|
357
348
|
id: m.id,
|
|
358
349
|
provider: m.provider,
|
|
350
|
+
name: m.name,
|
|
359
351
|
label: `${m.provider}/${m.id}`,
|
|
360
352
|
}));
|
|
361
|
-
// Fuzzy filter by model ID + provider
|
|
362
|
-
const filtered = fuzzyFilter(items, prefix,
|
|
353
|
+
// Fuzzy filter by model ID + provider in either order.
|
|
354
|
+
const filtered = fuzzyFilter(items, prefix, getModelSearchText);
|
|
363
355
|
if (filtered.length === 0)
|
|
364
356
|
return null;
|
|
365
357
|
return filtered.map((item) => ({
|
|
@@ -450,7 +442,7 @@ export class InteractiveMode {
|
|
|
450
442
|
this.registerSignalHandlers();
|
|
451
443
|
// Load changelog (only show new entries, skip for resumed sessions)
|
|
452
444
|
this.changelogMarkdown = this.getChangelogForDisplay();
|
|
453
|
-
// Add header container as first child. Populate it after
|
|
445
|
+
// Add header container as first child. Populate it after theme initialization.
|
|
454
446
|
this.ui.addChild(this.headerContainer);
|
|
455
447
|
this.ui.addChild(this.chatContainer);
|
|
456
448
|
this.ui.addChild(this.pendingMessagesContainer);
|
|
@@ -478,7 +470,7 @@ export class InteractiveMode {
|
|
|
478
470
|
this.ui.start();
|
|
479
471
|
recordTimeSinceReset("time-to-first-frame");
|
|
480
472
|
this.isInitialized = true;
|
|
481
|
-
await this.
|
|
473
|
+
await this.themeController.applyFromSettings();
|
|
482
474
|
// Add the quiet startup identity (unless silenced). Resource details are
|
|
483
475
|
// disclosed separately in the chat canvas via the tools/resources toggle.
|
|
484
476
|
if (this.options.verbose || !this.settingsManager.getQuietStartup()) {
|
|
@@ -541,6 +533,9 @@ export class InteractiveMode {
|
|
|
541
533
|
*/
|
|
542
534
|
async run() {
|
|
543
535
|
await this.init();
|
|
536
|
+
// Load GitHub Copilot context-window tiers from CAPI early (gated on the Copilot provider) so
|
|
537
|
+
// the footer and /model picker reflect GitHub's real windows. Best-effort, never blocks startup.
|
|
538
|
+
void this.refreshCopilotModelCatalog();
|
|
544
539
|
// Start version check asynchronously
|
|
545
540
|
checkForNewPiVersion(this.version).then((newVersion) => {
|
|
546
541
|
if (newVersion) {
|
|
@@ -1853,16 +1848,11 @@ export class InteractiveMode {
|
|
|
1853
1848
|
getTheme: (name) => getThemeByName(name),
|
|
1854
1849
|
setTheme: (themeOrName) => {
|
|
1855
1850
|
if (themeOrName instanceof Theme) {
|
|
1856
|
-
setThemeInstance(themeOrName);
|
|
1857
|
-
this.ui.requestRender();
|
|
1858
|
-
return { success: true };
|
|
1851
|
+
return this.themeController.setThemeInstance(themeOrName);
|
|
1859
1852
|
}
|
|
1860
|
-
const result =
|
|
1861
|
-
if (result.success) {
|
|
1862
|
-
|
|
1863
|
-
this.settingsManager.setTheme(themeOrName);
|
|
1864
|
-
}
|
|
1865
|
-
this.ui.requestRender();
|
|
1853
|
+
const result = this.themeController.setThemeName(themeOrName);
|
|
1854
|
+
if (result.success && this.settingsManager.getThemeSetting() !== themeOrName) {
|
|
1855
|
+
this.settingsManager.setTheme(themeOrName);
|
|
1866
1856
|
}
|
|
1867
1857
|
return result;
|
|
1868
1858
|
},
|
|
@@ -2619,6 +2609,11 @@ export class InteractiveMode {
|
|
|
2619
2609
|
this.refreshBuiltInHeader();
|
|
2620
2610
|
this.updateEditorBorderColor();
|
|
2621
2611
|
break;
|
|
2612
|
+
case "context_window_changed":
|
|
2613
|
+
this.footer.invalidate();
|
|
2614
|
+
this.usageMeter.invalidate();
|
|
2615
|
+
this.ui.requestRender();
|
|
2616
|
+
break;
|
|
2622
2617
|
case "message_start":
|
|
2623
2618
|
if (event.message.role === "custom") {
|
|
2624
2619
|
this.addMessageToChat(event.message);
|
|
@@ -3118,6 +3113,7 @@ export class InteractiveMode {
|
|
|
3118
3113
|
// dispatch and re-sends the signal if only its own listeners remain.
|
|
3119
3114
|
if (options?.fromSignal) {
|
|
3120
3115
|
await this.runtimeHost.dispose();
|
|
3116
|
+
this.themeController.disableAutoSync();
|
|
3121
3117
|
// Drain any in-flight Kitty key release events before stopping.
|
|
3122
3118
|
// This prevents escape sequences from leaking to the parent shell over slow SSH.
|
|
3123
3119
|
await this.ui.terminal.drainInput(1000);
|
|
@@ -3126,6 +3122,7 @@ export class InteractiveMode {
|
|
|
3126
3122
|
}
|
|
3127
3123
|
// Drain any in-flight Kitty key release events before stopping.
|
|
3128
3124
|
// This prevents escape sequences from leaking to the parent shell over slow SSH.
|
|
3125
|
+
this.themeController.disableAutoSync();
|
|
3129
3126
|
await this.ui.terminal.drainInput(1000);
|
|
3130
3127
|
this.stop();
|
|
3131
3128
|
await this.runtimeHost.dispose();
|
|
@@ -3413,7 +3410,7 @@ export class InteractiveMode {
|
|
|
3413
3410
|
this.ui.requestRender();
|
|
3414
3411
|
}
|
|
3415
3412
|
showPackageUpdateNotification(packages) {
|
|
3416
|
-
const action = theme.fg("accent", `${APP_NAME} update`);
|
|
3413
|
+
const action = theme.fg("accent", `${APP_NAME} update --extensions`);
|
|
3417
3414
|
const updateInstruction = theme.fg("muted", "Package updates are available. Run ") + action;
|
|
3418
3415
|
const packageLines = packages.map((pkg) => `- ${pkg}`).join("\n");
|
|
3419
3416
|
this.chatContainer.addChild(new Spacer(1));
|
|
@@ -3655,7 +3652,8 @@ export class InteractiveMode {
|
|
|
3655
3652
|
httpIdleTimeoutMs: this.settingsManager.getHttpIdleTimeoutMs(),
|
|
3656
3653
|
thinkingLevel: this.session.thinkingLevel,
|
|
3657
3654
|
availableThinkingLevels: this.session.getAvailableThinkingLevels(),
|
|
3658
|
-
currentTheme: this.settingsManager.
|
|
3655
|
+
currentTheme: this.settingsManager.getThemeSetting() || "dark",
|
|
3656
|
+
terminalTheme: this.themeController.getTerminalTheme(),
|
|
3659
3657
|
availableThemes: getAvailableThemes(),
|
|
3660
3658
|
hideThinkingBlock: this.hideThinkingBlock,
|
|
3661
3659
|
collapseChangelog: this.settingsManager.getCollapseChangelog(),
|
|
@@ -3720,21 +3718,11 @@ export class InteractiveMode {
|
|
|
3720
3718
|
this.footer.invalidate();
|
|
3721
3719
|
this.updateEditorBorderColor();
|
|
3722
3720
|
},
|
|
3723
|
-
onThemeChange: (
|
|
3724
|
-
|
|
3725
|
-
this.
|
|
3726
|
-
this.ui.invalidate();
|
|
3727
|
-
if (!result.success) {
|
|
3728
|
-
this.showError(`Failed to load theme "${themeName}": ${result.error}\nFell back to dark theme.`);
|
|
3729
|
-
}
|
|
3730
|
-
},
|
|
3731
|
-
onThemePreview: (themeName) => {
|
|
3732
|
-
const result = setTheme(themeName, true);
|
|
3733
|
-
if (result.success) {
|
|
3734
|
-
this.ui.invalidate();
|
|
3735
|
-
this.ui.requestRender();
|
|
3736
|
-
}
|
|
3721
|
+
onThemeChange: (themeSetting) => {
|
|
3722
|
+
this.settingsManager.setTheme(themeSetting);
|
|
3723
|
+
void this.themeController.applyFromSettings();
|
|
3737
3724
|
},
|
|
3725
|
+
onThemePreview: (themeName) => this.themeController.preview(themeName),
|
|
3738
3726
|
onHideThinkingBlockChange: (hidden) => {
|
|
3739
3727
|
this.hideThinkingBlock = hidden;
|
|
3740
3728
|
this.settingsManager.setHideThinkingBlock(hidden);
|
|
@@ -3832,6 +3820,7 @@ export class InteractiveMode {
|
|
|
3832
3820
|
if (this.session.scopedModels.length > 0) {
|
|
3833
3821
|
return this.session.scopedModels.map((scoped) => scoped.model);
|
|
3834
3822
|
}
|
|
3823
|
+
await this.refreshCopilotModelCatalog();
|
|
3835
3824
|
this.session.modelRegistry.refresh();
|
|
3836
3825
|
try {
|
|
3837
3826
|
return await this.session.modelRegistry.getAvailable();
|
|
@@ -3840,6 +3829,51 @@ export class InteractiveMode {
|
|
|
3840
3829
|
return [];
|
|
3841
3830
|
}
|
|
3842
3831
|
}
|
|
3832
|
+
/**
|
|
3833
|
+
* Load GitHub Copilot's context-window tiers from the live CAPI catalog, but only when the user
|
|
3834
|
+
* actually has the GitHub Copilot provider authenticated. Cache-first (30-min TTL); on a
|
|
3835
|
+
* successful load the model registry is refreshed so the /model context-window picker reflects
|
|
3836
|
+
* GitHub's real tiers (e.g. gpt-5.5 1.05m, Claude/Gemini 1m). Best-effort and gated: offline,
|
|
3837
|
+
* unauthenticated, or non-Copilot sessions silently keep no long-context options.
|
|
3838
|
+
*/
|
|
3839
|
+
async refreshCopilotModelCatalog() {
|
|
3840
|
+
if (this.copilotCatalogApplied)
|
|
3841
|
+
return;
|
|
3842
|
+
if (!this.copilotCatalogInFlight) {
|
|
3843
|
+
this.copilotCatalogInFlight = this.loadCopilotModelCatalog();
|
|
3844
|
+
}
|
|
3845
|
+
try {
|
|
3846
|
+
await this.copilotCatalogInFlight;
|
|
3847
|
+
}
|
|
3848
|
+
finally {
|
|
3849
|
+
this.copilotCatalogInFlight = undefined;
|
|
3850
|
+
}
|
|
3851
|
+
}
|
|
3852
|
+
async loadCopilotModelCatalog() {
|
|
3853
|
+
const registry = this.session.modelRegistry;
|
|
3854
|
+
const cred = registry.authStorage.get("github-copilot");
|
|
3855
|
+
// Gate: do nothing unless the user has the GitHub Copilot provider.
|
|
3856
|
+
if (!cred || cred.type !== "oauth")
|
|
3857
|
+
return;
|
|
3858
|
+
try {
|
|
3859
|
+
const token = await registry.getApiKeyForProvider("github-copilot");
|
|
3860
|
+
if (!token)
|
|
3861
|
+
return;
|
|
3862
|
+
const baseUrl = copilotApiBaseUrlFromToken(token);
|
|
3863
|
+
const cachePath = copilotCatalogCachePath(getAgentDir());
|
|
3864
|
+
let catalog = readCopilotCatalogCache(cachePath, { host: copilotCatalogCacheHost(baseUrl) });
|
|
3865
|
+
if (!catalog) {
|
|
3866
|
+
catalog = await fetchCopilotModelCatalog({ token, baseUrl });
|
|
3867
|
+
writeCopilotCatalogCache(cachePath, baseUrl, catalog);
|
|
3868
|
+
}
|
|
3869
|
+
setActiveCopilotModelCatalog(catalog);
|
|
3870
|
+
registry.refresh();
|
|
3871
|
+
this.copilotCatalogApplied = true;
|
|
3872
|
+
}
|
|
3873
|
+
catch {
|
|
3874
|
+
// Best-effort: leave the active catalog as-is on any failure (offline, auth, parse).
|
|
3875
|
+
}
|
|
3876
|
+
}
|
|
3843
3877
|
/** Update the footer's available provider count from current model candidates */
|
|
3844
3878
|
async updateAvailableProviderCount() {
|
|
3845
3879
|
const models = await this.getModelCandidates();
|
|
@@ -3882,9 +3916,14 @@ export class InteractiveMode {
|
|
|
3882
3916
|
this.footer.invalidate();
|
|
3883
3917
|
this.updateEditorBorderColor();
|
|
3884
3918
|
done();
|
|
3885
|
-
this.showStatus(`Model: ${model.id}`);
|
|
3886
3919
|
void this.maybeWarnAboutAnthropicSubscriptionAuth(model);
|
|
3887
3920
|
this.checkDaxnutsEasterEgg(model);
|
|
3921
|
+
if (this.session.supportsContextWindowSelection()) {
|
|
3922
|
+
this.showContextWindowSelector(model);
|
|
3923
|
+
}
|
|
3924
|
+
else {
|
|
3925
|
+
this.showStatus(`Model: ${model.id}`);
|
|
3926
|
+
}
|
|
3888
3927
|
}
|
|
3889
3928
|
catch (error) {
|
|
3890
3929
|
done();
|
|
@@ -3897,6 +3936,32 @@ export class InteractiveMode {
|
|
|
3897
3936
|
return { component: selector, focus: selector };
|
|
3898
3937
|
});
|
|
3899
3938
|
}
|
|
3939
|
+
showContextWindowSelector(model) {
|
|
3940
|
+
const availableContextWindows = this.session.getAvailableContextWindows();
|
|
3941
|
+
const currentContextWindow = this.session.model?.contextWindow ?? availableContextWindows[0] ?? 0;
|
|
3942
|
+
this.showSelector((done) => {
|
|
3943
|
+
const selector = new ContextWindowSelectorComponent(model.name ?? model.id, availableContextWindows, currentContextWindow, (contextWindow) => {
|
|
3944
|
+
try {
|
|
3945
|
+
this.session.setContextWindow(contextWindow, {
|
|
3946
|
+
persistDefault: true,
|
|
3947
|
+
});
|
|
3948
|
+
this.footer.invalidate();
|
|
3949
|
+
this.usageMeter.invalidate();
|
|
3950
|
+
this.updateEditorBorderColor();
|
|
3951
|
+
done();
|
|
3952
|
+
this.showStatus(`Model: ${model.id} \u00b7 ${formatContextWindow(contextWindow)} context`);
|
|
3953
|
+
}
|
|
3954
|
+
catch (error) {
|
|
3955
|
+
done();
|
|
3956
|
+
this.showError(error instanceof Error ? error.message : String(error));
|
|
3957
|
+
}
|
|
3958
|
+
}, () => {
|
|
3959
|
+
done();
|
|
3960
|
+
this.showStatus(`Model: ${model.id}`);
|
|
3961
|
+
});
|
|
3962
|
+
return { component: selector, focus: selector };
|
|
3963
|
+
});
|
|
3964
|
+
}
|
|
3900
3965
|
async showModelsSelector() {
|
|
3901
3966
|
// Get all available models
|
|
3902
3967
|
this.session.modelRegistry.refresh();
|
|
@@ -4602,13 +4667,7 @@ export class InteractiveMode {
|
|
|
4602
4667
|
}
|
|
4603
4668
|
setRegisteredThemes(this.session.resourceLoader.getThemes().themes);
|
|
4604
4669
|
this.hideThinkingBlock = this.settingsManager.getHideThinkingBlock();
|
|
4605
|
-
|
|
4606
|
-
const themeResult = themeName
|
|
4607
|
-
? setTheme(themeName, true)
|
|
4608
|
-
: { success: true };
|
|
4609
|
-
if (!themeResult.success) {
|
|
4610
|
-
this.showError(`Failed to load theme "${themeName}": ${themeResult.error}\nFell back to dark theme.`);
|
|
4611
|
-
}
|
|
4670
|
+
await this.themeController.applyFromSettings();
|
|
4612
4671
|
const editorPaddingX = this.settingsManager.getEditorPaddingX();
|
|
4613
4672
|
const autocompleteMaxVisible = this.settingsManager.getAutocompleteMaxVisible();
|
|
4614
4673
|
this.defaultEditor.setPaddingX(editorPaddingX);
|
|
@@ -5189,6 +5248,7 @@ export class InteractiveMode {
|
|
|
5189
5248
|
this.loadingAnimation.stop();
|
|
5190
5249
|
this.loadingAnimation = undefined;
|
|
5191
5250
|
}
|
|
5251
|
+
this.themeController.disableAutoSync();
|
|
5192
5252
|
this.clearExtensionTerminalInputListeners();
|
|
5193
5253
|
this.footer.dispose();
|
|
5194
5254
|
this.footerDataProvider.dispose();
|