@bastani/atomic 0.8.1 → 0.8.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 +12 -0
- package/dist/builtin/intercom/config.ts +3 -4
- package/dist/builtin/intercom/index.ts +6 -6
- package/dist/builtin/intercom/package.json +1 -1
- package/dist/builtin/mcp/agent-dir.ts +11 -2
- package/dist/builtin/mcp/cli.js +12 -6
- package/dist/builtin/mcp/config.ts +31 -22
- package/dist/builtin/mcp/package.json +1 -1
- package/dist/builtin/subagents/package.json +1 -1
- package/dist/builtin/subagents/src/agents/agents.ts +63 -23
- package/dist/builtin/subagents/src/agents/skills.ts +21 -21
- package/dist/builtin/subagents/src/extension/index.ts +9 -8
- package/dist/builtin/subagents/src/runs/shared/run-history.ts +13 -10
- package/dist/builtin/subagents/src/runs/shared/subagent-prompt-runtime.ts +3 -3
- package/dist/builtin/subagents/src/shared/artifacts.ts +18 -17
- package/dist/builtin/subagents/src/shared/types.ts +4 -4
- package/dist/builtin/web-access/config-paths.ts +11 -0
- package/dist/builtin/web-access/exa.ts +3 -2
- package/dist/builtin/web-access/gemini-api.ts +2 -1
- package/dist/builtin/web-access/gemini-search.ts +2 -1
- package/dist/builtin/web-access/gemini-web-config.ts +2 -1
- package/dist/builtin/web-access/github-extract.ts +2 -1
- package/dist/builtin/web-access/index.ts +11 -8
- package/dist/builtin/web-access/package.json +1 -1
- package/dist/builtin/web-access/perplexity.ts +2 -1
- package/dist/builtin/web-access/video-extract.ts +2 -1
- package/dist/builtin/web-access/youtube-extract.ts +2 -1
- package/dist/builtin/workflows/builtin/deep-research-codebase.ts +4 -0
- package/dist/builtin/workflows/builtin/open-claude-design.ts +39 -22
- package/dist/builtin/workflows/builtin/ralph.ts +7 -0
- package/dist/builtin/workflows/package.json +1 -1
- package/dist/builtin/workflows/skills/workflow/SKILL.md +28 -20
- package/dist/builtin/workflows/skills/workflow/references/design-checklist.md +8 -4
- package/dist/builtin/workflows/skills/workflow/references/running-workflows.md +52 -23
- package/dist/builtin/workflows/skills/workflow/references/sdk-authoring.md +41 -12
- package/dist/builtin/workflows/src/extension/config-loader.ts +13 -14
- package/dist/builtin/workflows/src/extension/discovery.ts +4 -6
- package/dist/builtin/workflows/src/extension/index.ts +675 -524
- package/dist/builtin/workflows/src/extension/runtime.ts +40 -16
- package/dist/builtin/workflows/src/extension/wiring.ts +3 -0
- package/dist/builtin/workflows/src/extension/workflow-schema.ts +43 -33
- package/dist/builtin/workflows/src/runs/foreground/executor.ts +34 -10
- package/dist/builtin/workflows/src/shared/types.ts +1 -5
- package/dist/builtin/workflows/src/tui/graph-view.ts +245 -75
- package/dist/builtin/workflows/src/tui/overlay-adapter.ts +23 -0
- package/dist/builtin/workflows/src/tui/stage-chat-view.ts +259 -149
- package/dist/builtin/workflows/src/tui/status-helpers.ts +3 -3
- package/dist/builtin/workflows/src/tui/store-widget-installer.ts +99 -10
- package/dist/builtin/workflows/src/tui/switcher.ts +4 -5
- package/dist/builtin/workflows/src/tui/workflow-attach-pane.ts +29 -0
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +11 -8
- package/dist/cli/args.js.map +1 -1
- package/dist/config.d.ts +21 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +59 -4
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session.d.ts +1 -1
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +2 -2
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-storage.d.ts +3 -1
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +31 -8
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +9 -0
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +11 -0
- 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 +3 -2
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +25 -8
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/package-manager.d.ts +3 -0
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +97 -58
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/resource-loader.d.ts +1 -0
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +37 -36
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/sdk.d.ts +5 -4
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +2 -2
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/settings-manager.d.ts +7 -1
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +29 -8
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/system-prompt.d.ts +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/telemetry.d.ts.map +1 -1
- package/dist/core/telemetry.js +2 -2
- package/dist/core/telemetry.js.map +1 -1
- package/dist/core/timings.d.ts.map +1 -1
- package/dist/core/timings.js +2 -2
- package/dist/core/timings.js.map +1 -1
- package/dist/core/tools/index.d.ts +1 -0
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +8 -0
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/todos.d.ts.map +1 -1
- package/dist/core/tools/todos.js +3 -3
- package/dist/core/tools/todos.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +6 -6
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/atomic-banner.d.ts +4 -0
- package/dist/modes/interactive/components/atomic-banner.d.ts.map +1 -0
- package/dist/modes/interactive/components/atomic-banner.js +34 -0
- package/dist/modes/interactive/components/atomic-banner.js.map +1 -0
- package/dist/modes/interactive/components/chat-message-renderer.d.ts +99 -0
- package/dist/modes/interactive/components/chat-message-renderer.d.ts.map +1 -0
- package/dist/modes/interactive/components/chat-message-renderer.js +450 -0
- package/dist/modes/interactive/components/chat-message-renderer.js.map +1 -0
- package/dist/modes/interactive/components/chat-transcript.d.ts +69 -0
- package/dist/modes/interactive/components/chat-transcript.d.ts.map +1 -0
- package/dist/modes/interactive/components/chat-transcript.js +183 -0
- package/dist/modes/interactive/components/chat-transcript.js.map +1 -0
- package/dist/modes/interactive/components/footer.d.ts +16 -4
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +110 -137
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/index.d.ts +2 -0
- package/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/dist/modes/interactive/components/index.js +2 -0
- package/dist/modes/interactive/components/index.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +9 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +192 -137
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/theme/catppuccin-mocha.json +5 -5
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +11 -0
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js +2 -2
- package/dist/utils/tools-manager.js.map +1 -1
- package/dist/utils/version-check.d.ts.map +1 -1
- package/dist/utils/version-check.js +2 -2
- package/dist/utils/version-check.js.map +1 -1
- package/package.json +1 -1
|
@@ -9,7 +9,7 @@ import * as path from "node:path";
|
|
|
9
9
|
import { getProviders, } from "@earendil-works/pi-ai";
|
|
10
10
|
import { CombinedAutocompleteProvider, Container, fuzzyFilter, getCapabilities, hyperlink, Loader, Markdown, matchesKey, ProcessTerminal, Spacer, setKeybindings, Text, TruncatedText, TUI, visibleWidth, } from "@earendil-works/pi-tui";
|
|
11
11
|
import { spawn, spawnSync } from "child_process";
|
|
12
|
-
import { APP_NAME, APP_TITLE, CHANGELOG_URL, ENV_OFFLINE, getAgentDir, getAuthPath, getDebugLogPath, getDocsPath, getShareViewerUrl, VERSION, } from "../../config.js";
|
|
12
|
+
import { APP_NAME, APP_TITLE, CHANGELOG_URL, ENV_OFFLINE, getEnvValue, getAgentDir, getAuthPath, getDebugLogPath, getDocsPath, getShareViewerUrl, VERSION, } from "../../config.js";
|
|
13
13
|
import { parseSkillBlock, } from "../../core/agent-session.js";
|
|
14
14
|
import { pickWhimsicalWorkingMessage } from "./whimsical-messages.js";
|
|
15
15
|
import { SessionImportFileNotFoundError, } from "../../core/agent-session-runtime.js";
|
|
@@ -37,18 +37,21 @@ import { AssistantMessageComponent } from "./components/assistant-message.js";
|
|
|
37
37
|
import { BashExecutionComponent } from "./components/bash-execution.js";
|
|
38
38
|
import { BorderedLoader } from "./components/bordered-loader.js";
|
|
39
39
|
import { BranchSummaryMessageComponent } from "./components/branch-summary-message.js";
|
|
40
|
+
import { chatEntriesFromAgentMessages, renderChatMessageEntry, } from "./components/chat-message-renderer.js";
|
|
41
|
+
import { addChatTranscriptEntry } from "./components/chat-transcript.js";
|
|
40
42
|
import { CompactionSummaryMessageComponent } from "./components/compaction-summary-message.js";
|
|
41
43
|
import { CountdownTimer } from "./components/countdown-timer.js";
|
|
42
44
|
import { CustomEditor } from "./components/custom-editor.js";
|
|
43
45
|
import { CustomMessageComponent } from "./components/custom-message.js";
|
|
44
46
|
import { DaxnutsComponent } from "./components/daxnuts.js";
|
|
47
|
+
import { renderAtomicAnsiBanner } from "./components/atomic-banner.js";
|
|
45
48
|
import { DynamicBorder } from "./components/dynamic-border.js";
|
|
46
49
|
import { EarendilAnnouncementComponent } from "./components/earendil-announcement.js";
|
|
47
50
|
import { ExtensionEditorComponent } from "./components/extension-editor.js";
|
|
48
51
|
import { ExtensionInputComponent } from "./components/extension-input.js";
|
|
49
52
|
import { ExtensionSelectorComponent } from "./components/extension-selector.js";
|
|
50
|
-
import { FooterComponent } from "./components/footer.js";
|
|
51
|
-
import { formatKeyText, keyDisplayText,
|
|
53
|
+
import { FooterComponent, UsageMeterComponent } from "./components/footer.js";
|
|
54
|
+
import { formatKeyText, keyDisplayText, keyText, } from "./components/keybinding-hints.js";
|
|
52
55
|
import { LoginDialogComponent } from "./components/login-dialog.js";
|
|
53
56
|
import { ModelSelectorComponent } from "./components/model-selector.js";
|
|
54
57
|
import { OAuthSelectorComponent, } from "./components/oauth-selector.js";
|
|
@@ -72,9 +75,14 @@ class ExpandableText extends Text {
|
|
|
72
75
|
super(expanded ? getExpandedText() : getCollapsedText(), paddingX, paddingY);
|
|
73
76
|
this.getCollapsedText = getCollapsedText;
|
|
74
77
|
this.getExpandedText = getExpandedText;
|
|
78
|
+
this.expanded = expanded;
|
|
75
79
|
}
|
|
76
80
|
setExpanded(expanded) {
|
|
77
|
-
this.
|
|
81
|
+
this.expanded = expanded;
|
|
82
|
+
this.refresh();
|
|
83
|
+
}
|
|
84
|
+
refresh() {
|
|
85
|
+
this.setText(this.expanded ? this.getExpandedText() : this.getCollapsedText());
|
|
78
86
|
}
|
|
79
87
|
}
|
|
80
88
|
const DEAD_TERMINAL_ERROR_CODES = new Set(["EIO", "EPIPE", "ENOTCONN"]);
|
|
@@ -218,7 +226,8 @@ export class InteractiveMode {
|
|
|
218
226
|
this.editorContainer.addChild(this.editor);
|
|
219
227
|
this.footerDataProvider = new FooterDataProvider(this.sessionManager.getCwd());
|
|
220
228
|
this.footer = new FooterComponent(this.session, this.footerDataProvider);
|
|
221
|
-
this.
|
|
229
|
+
this.usageMeter = new UsageMeterComponent(this.session);
|
|
230
|
+
this.usageMeter.setAutoCompactEnabled(this.session.autoCompactionEnabled);
|
|
222
231
|
// Load hide thinking block setting
|
|
223
232
|
this.hideThinkingBlock = this.settingsManager.getHideThinkingBlock();
|
|
224
233
|
// Register themes from resource loader and initialize
|
|
@@ -385,43 +394,10 @@ export class InteractiveMode {
|
|
|
385
394
|
this.fdPath = fdPath;
|
|
386
395
|
// Add header container as first child
|
|
387
396
|
this.ui.addChild(this.headerContainer);
|
|
388
|
-
// Add
|
|
397
|
+
// Add the quiet startup identity (unless silenced). Resource details are
|
|
398
|
+
// disclosed separately in the chat canvas via the tools/resources toggle.
|
|
389
399
|
if (this.options.verbose || !this.settingsManager.getQuietStartup()) {
|
|
390
|
-
|
|
391
|
-
theme.fg("dim", ` v${this.version}`);
|
|
392
|
-
// Build startup instructions using keybinding hint helpers
|
|
393
|
-
const hint = (keybinding, description) => keyHint(keybinding, description);
|
|
394
|
-
const expandedInstructions = [
|
|
395
|
-
hint("app.interrupt", "to interrupt"),
|
|
396
|
-
hint("app.clear", "to clear"),
|
|
397
|
-
rawKeyHint(`${keyText("app.clear")} twice`, "to exit"),
|
|
398
|
-
hint("app.exit", "to exit (empty)"),
|
|
399
|
-
hint("app.suspend", "to suspend"),
|
|
400
|
-
keyHint("tui.editor.deleteToLineEnd", "to delete to end"),
|
|
401
|
-
hint("app.thinking.cycle", "to cycle thinking level"),
|
|
402
|
-
rawKeyHint(`${keyText("app.model.cycleForward")}/${keyText("app.model.cycleBackward")}`, "to cycle models"),
|
|
403
|
-
hint("app.model.select", "to select model"),
|
|
404
|
-
hint("app.tools.expand", "to expand tools"),
|
|
405
|
-
hint("app.thinking.toggle", "to expand thinking"),
|
|
406
|
-
hint("app.editor.external", "for external editor"),
|
|
407
|
-
rawKeyHint("/", "for commands"),
|
|
408
|
-
rawKeyHint("!", "to run bash"),
|
|
409
|
-
rawKeyHint("!!", "to run bash (no context)"),
|
|
410
|
-
hint("app.message.followUp", "to queue follow-up"),
|
|
411
|
-
hint("app.message.dequeue", "to edit all queued messages"),
|
|
412
|
-
hint("app.clipboard.pasteImage", "to paste image"),
|
|
413
|
-
rawKeyHint("drop files", "to attach"),
|
|
414
|
-
].join("\n");
|
|
415
|
-
const compactInstructions = [
|
|
416
|
-
hint("app.interrupt", "interrupt"),
|
|
417
|
-
rawKeyHint(`${keyText("app.clear")}/${keyText("app.exit")}`, "clear/exit"),
|
|
418
|
-
rawKeyHint("/", "commands"),
|
|
419
|
-
rawKeyHint("!", "bash"),
|
|
420
|
-
hint("app.tools.expand", "more"),
|
|
421
|
-
].join(theme.fg("muted", " · "));
|
|
422
|
-
const compactOnboarding = theme.fg("dim", `Press ${keyText("app.tools.expand")} to show full startup help and loaded resources.`);
|
|
423
|
-
const onboarding = theme.fg("dim", `Atomic is built with Pi. Pi can explain its own features and look up its docs. Ask it how to use or extend Pi.`);
|
|
424
|
-
this.builtInHeader = new ExpandableText(() => `${logo}\n${compactInstructions}\n${compactOnboarding}\n\n${onboarding}`, () => `${logo}\n${expandedInstructions}\n\n${onboarding}`, this.getStartupExpansionState(), 1, 0);
|
|
400
|
+
this.builtInHeader = new ExpandableText(() => this.getStartupIdentityText(), () => this.getStartupIdentityText(), this.getStartupExpansionState(), 1, 0);
|
|
425
401
|
// Setup UI layout
|
|
426
402
|
this.headerContainer.addChild(new Spacer(1));
|
|
427
403
|
this.headerContainer.addChild(this.builtInHeader);
|
|
@@ -437,6 +413,7 @@ export class InteractiveMode {
|
|
|
437
413
|
this.ui.addChild(this.statusContainer);
|
|
438
414
|
this.renderWidgets(); // Initialize with default spacer
|
|
439
415
|
this.ui.addChild(this.widgetContainerAbove);
|
|
416
|
+
this.ui.addChild(this.usageMeter);
|
|
440
417
|
this.ui.addChild(this.editorContainer);
|
|
441
418
|
this.ui.addChild(this.widgetContainerBelow);
|
|
442
419
|
this.ui.addChild(this.footer);
|
|
@@ -547,7 +524,7 @@ export class InteractiveMode {
|
|
|
547
524
|
}
|
|
548
525
|
}
|
|
549
526
|
async checkForPackageUpdates() {
|
|
550
|
-
if (
|
|
527
|
+
if (getEnvValue(ENV_OFFLINE)) {
|
|
551
528
|
return [];
|
|
552
529
|
}
|
|
553
530
|
try {
|
|
@@ -632,7 +609,7 @@ export class InteractiveMode {
|
|
|
632
609
|
return undefined;
|
|
633
610
|
}
|
|
634
611
|
reportInstallTelemetry(version) {
|
|
635
|
-
if (
|
|
612
|
+
if (getEnvValue(ENV_OFFLINE)) {
|
|
636
613
|
return;
|
|
637
614
|
}
|
|
638
615
|
if (!isInstallTelemetryEnabled(this.settingsManager)) {
|
|
@@ -681,6 +658,25 @@ export class InteractiveMode {
|
|
|
681
658
|
}
|
|
682
659
|
return this.formatDisplayPath(absolutePath);
|
|
683
660
|
}
|
|
661
|
+
getStartupIdentityText() {
|
|
662
|
+
const appLabel = APP_NAME.length > 0
|
|
663
|
+
? `${APP_NAME[0].toUpperCase()}${APP_NAME.slice(1)}`
|
|
664
|
+
: "Atomic";
|
|
665
|
+
const title = `${theme.bold(theme.fg("text", appLabel))} ${theme.fg("muted", `v${this.version}`)}`;
|
|
666
|
+
const model = this.session.state.model;
|
|
667
|
+
const provider = model ? theme.fg("dim", `(${model.provider})`) : theme.fg("dim", "(no-provider)");
|
|
668
|
+
const thinking = model?.reasoning ? ` ${this.session.thinkingLevel || "off"}` : "";
|
|
669
|
+
const modelLine = `${provider} ${theme.fg("muted", `${model?.id ?? "no-model"}${thinking}`)}`;
|
|
670
|
+
const cwd = theme.fg("muted", this.formatDisplayPath(this.sessionManager.getCwd()));
|
|
671
|
+
const metaLines = [title, modelLine, cwd];
|
|
672
|
+
const markLines = this.getAtomicAnsiMarkLines();
|
|
673
|
+
return markLines
|
|
674
|
+
.map((line, index) => `${line} ${metaLines[index] ?? ""}`.trimEnd())
|
|
675
|
+
.join("\n");
|
|
676
|
+
}
|
|
677
|
+
getAtomicAnsiMarkLines() {
|
|
678
|
+
return renderAtomicAnsiBanner(theme, this.session.thinkingLevel || "off");
|
|
679
|
+
}
|
|
684
680
|
getStartupExpansionState() {
|
|
685
681
|
return this.options.verbose || this.toolOutputExpanded;
|
|
686
682
|
}
|
|
@@ -952,6 +948,63 @@ export class InteractiveMode {
|
|
|
952
948
|
}
|
|
953
949
|
return lines.join("\n");
|
|
954
950
|
}
|
|
951
|
+
getResourceDiagnosticsTotal(values) {
|
|
952
|
+
return values.reduce((total, diagnostics) => total + diagnostics.length, 0);
|
|
953
|
+
}
|
|
954
|
+
formatResourceCount(count, singular, plural = `${singular}s`) {
|
|
955
|
+
if (count <= 0) {
|
|
956
|
+
return undefined;
|
|
957
|
+
}
|
|
958
|
+
return `${count} ${count === 1 ? singular : plural}`;
|
|
959
|
+
}
|
|
960
|
+
addResourceDisclosure(options) {
|
|
961
|
+
const contextLabels = options.contextFiles.map((contextFile) => this.formatContextPath(contextFile.path));
|
|
962
|
+
const promptCount = options.prompts.length + options.templates.length;
|
|
963
|
+
const summaryParts = [
|
|
964
|
+
contextLabels.length > 0 ? contextLabels.join(", ") : "context ready",
|
|
965
|
+
this.formatResourceCount(options.skills.length, "skill"),
|
|
966
|
+
this.formatResourceCount(promptCount, "prompt"),
|
|
967
|
+
this.formatResourceCount(options.extensions.length, "extension"),
|
|
968
|
+
this.formatResourceCount(options.themes.length, "theme"),
|
|
969
|
+
this.formatResourceCount(options.diagnosticsTotal, "issue"),
|
|
970
|
+
].filter((part) => part !== undefined && part.length > 0);
|
|
971
|
+
const collapsed = `${theme.bold(theme.fg("muted", "RESOURCES"))} ${theme.fg("muted", summaryParts.join(" · "))}`;
|
|
972
|
+
const ok = theme.fg("success", "✓");
|
|
973
|
+
const pending = theme.fg("dim", "○");
|
|
974
|
+
const sep = theme.fg("dim", " · ");
|
|
975
|
+
const label = (value) => theme.bold(theme.fg("text", value.padEnd(10)));
|
|
976
|
+
const mutedList = (values, maxItems = 4) => {
|
|
977
|
+
if (values.length === 0) {
|
|
978
|
+
return theme.fg("dim", "none");
|
|
979
|
+
}
|
|
980
|
+
const shown = values.slice(0, maxItems).join(", ");
|
|
981
|
+
const suffix = values.length > maxItems ? `, +${values.length - maxItems}` : "";
|
|
982
|
+
return theme.fg("dim", `${shown}${suffix}`);
|
|
983
|
+
};
|
|
984
|
+
const extensionLabels = this.getCompactExtensionLabels([...options.extensions]);
|
|
985
|
+
const themeLabels = options.themes.map((loadedTheme) => loadedTheme.name ??
|
|
986
|
+
(loadedTheme.sourcePath
|
|
987
|
+
? this.getCompactPathLabel(loadedTheme.sourcePath, undefined)
|
|
988
|
+
: "theme"));
|
|
989
|
+
const expandedSummary = [
|
|
990
|
+
`${ok} ${label("Ready")} ${contextLabels.length > 0 ? contextLabels.join(", ") : "context loaded"}`,
|
|
991
|
+
`${ok} ${label("Skills")} ${options.skills.length} available${sep}${mutedList(options.skills.map((skill) => skill.name))}`,
|
|
992
|
+
`${ok} ${label("Prompts")} ${promptCount} available${sep}${mutedList([
|
|
993
|
+
...options.templates.map((template) => `/${template.name}`),
|
|
994
|
+
...options.prompts.map((prompt) => prompt.name),
|
|
995
|
+
])}`,
|
|
996
|
+
`${ok} ${label("Extensions")} ${options.extensions.length} available${sep}${mutedList(extensionLabels)}`,
|
|
997
|
+
];
|
|
998
|
+
if (themeLabels.length > 0) {
|
|
999
|
+
expandedSummary.push(`${ok} ${label("Themes")} ${themeLabels.length} loaded${sep}${mutedList(themeLabels)}`);
|
|
1000
|
+
}
|
|
1001
|
+
if (options.diagnosticsTotal > 0) {
|
|
1002
|
+
expandedSummary.push(`${pending} ${label("Issues")} ${options.diagnosticsTotal} noted${sep}${theme.fg("dim", "details below")}`);
|
|
1003
|
+
}
|
|
1004
|
+
const expanded = `${collapsed}\n${expandedSummary.join("\n")}${options.expandedBody.length > 0 ? `\n\n${options.expandedBody}` : ""}`;
|
|
1005
|
+
this.chatContainer.addChild(new ExpandableText(() => collapsed, () => expanded, this.getStartupExpansionState(), 0, 0));
|
|
1006
|
+
this.chatContainer.addChild(new Spacer(1));
|
|
1007
|
+
}
|
|
955
1008
|
showLoadedResources(options) {
|
|
956
1009
|
const showListing = options?.force ||
|
|
957
1010
|
this.options.verbose ||
|
|
@@ -960,21 +1013,6 @@ export class InteractiveMode {
|
|
|
960
1013
|
if (!showListing && !showDiagnostics) {
|
|
961
1014
|
return;
|
|
962
1015
|
}
|
|
963
|
-
const sectionHeader = (name, color = "mdHeading") => theme.fg(color, `[${name}]`);
|
|
964
|
-
const formatCompactList = (items, options) => {
|
|
965
|
-
const labels = items
|
|
966
|
-
.map((item) => item.trim())
|
|
967
|
-
.filter((item) => item.length > 0);
|
|
968
|
-
if (options?.sort !== false) {
|
|
969
|
-
labels.sort((a, b) => a.localeCompare(b));
|
|
970
|
-
}
|
|
971
|
-
return theme.fg("dim", ` ${labels.join(", ")}`);
|
|
972
|
-
};
|
|
973
|
-
const addLoadedSection = (name, collapsedBody, expandedBody = collapsedBody, color = "mdHeading") => {
|
|
974
|
-
const section = new ExpandableText(() => `${sectionHeader(name, color)}\n${collapsedBody}`, () => `${sectionHeader(name, color)}\n${expandedBody}`, this.getStartupExpansionState(), 0, 0);
|
|
975
|
-
this.chatContainer.addChild(section);
|
|
976
|
-
this.chatContainer.addChild(new Spacer(1));
|
|
977
|
-
};
|
|
978
1016
|
const skillsResult = this.session.resourceLoader.getSkills();
|
|
979
1017
|
const promptsResult = this.session.resourceLoader.getPrompts();
|
|
980
1018
|
const themesResult = this.session.resourceLoader.getThemes();
|
|
@@ -1008,13 +1046,13 @@ export class InteractiveMode {
|
|
|
1008
1046
|
}
|
|
1009
1047
|
if (showListing) {
|
|
1010
1048
|
const contextFiles = this.session.resourceLoader.getAgentsFiles().agentsFiles;
|
|
1049
|
+
const templates = this.session.promptTemplates;
|
|
1050
|
+
const customThemes = themesResult.themes.filter((t) => t.sourcePath);
|
|
1051
|
+
const expandedSections = [];
|
|
1011
1052
|
if (contextFiles.length > 0) {
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
.
|
|
1015
|
-
.join("\n");
|
|
1016
|
-
const contextCompactList = formatCompactList(contextFiles.map((contextFile) => this.formatContextPath(contextFile.path)), { sort: false });
|
|
1017
|
-
addLoadedSection("Context", contextCompactList, contextList);
|
|
1053
|
+
expandedSections.push(`${theme.bold(theme.fg("muted", "CONTEXT"))}\n${contextFiles
|
|
1054
|
+
.map((contextFile) => theme.fg("dim", ` ${this.formatDisplayPath(contextFile.path)}`))
|
|
1055
|
+
.join("\n")}`);
|
|
1018
1056
|
}
|
|
1019
1057
|
const skills = skillsResult.skills;
|
|
1020
1058
|
if (skills.length > 0) {
|
|
@@ -1022,21 +1060,18 @@ export class InteractiveMode {
|
|
|
1022
1060
|
path: skill.filePath,
|
|
1023
1061
|
sourceInfo: skill.sourceInfo,
|
|
1024
1062
|
})));
|
|
1025
|
-
|
|
1063
|
+
expandedSections.push(`${theme.bold(theme.fg("muted", "SKILLS"))}\n${this.formatScopeGroups(groups, {
|
|
1026
1064
|
formatPath: (item) => this.formatDisplayPath(item.path),
|
|
1027
1065
|
formatPackagePath: (item) => this.getShortPath(item.path, item.sourceInfo),
|
|
1028
|
-
});
|
|
1029
|
-
const skillCompactList = formatCompactList(skills.map((skill) => skill.name));
|
|
1030
|
-
addLoadedSection("Skills", skillCompactList, skillList);
|
|
1066
|
+
})}`);
|
|
1031
1067
|
}
|
|
1032
|
-
const templates = this.session.promptTemplates;
|
|
1033
1068
|
if (templates.length > 0) {
|
|
1034
1069
|
const groups = this.buildScopeGroups(templates.map((template) => ({
|
|
1035
1070
|
path: template.filePath,
|
|
1036
1071
|
sourceInfo: template.sourceInfo,
|
|
1037
1072
|
})));
|
|
1038
1073
|
const templateByPath = new Map(templates.map((t) => [t.filePath, t]));
|
|
1039
|
-
|
|
1074
|
+
expandedSections.push(`${theme.bold(theme.fg("muted", "PROMPTS"))}\n${this.formatScopeGroups(groups, {
|
|
1040
1075
|
formatPath: (item) => {
|
|
1041
1076
|
const template = templateByPath.get(item.path);
|
|
1042
1077
|
return template
|
|
@@ -1049,35 +1084,62 @@ export class InteractiveMode {
|
|
|
1049
1084
|
? `/${template.name}`
|
|
1050
1085
|
: this.formatDisplayPath(item.path);
|
|
1051
1086
|
},
|
|
1052
|
-
});
|
|
1053
|
-
|
|
1054
|
-
|
|
1087
|
+
})}`);
|
|
1088
|
+
}
|
|
1089
|
+
const prompts = promptsResult.prompts;
|
|
1090
|
+
if (prompts.length > 0) {
|
|
1091
|
+
const groups = this.buildScopeGroups(prompts.map((prompt) => ({
|
|
1092
|
+
path: prompt.filePath,
|
|
1093
|
+
sourceInfo: prompt.sourceInfo,
|
|
1094
|
+
})));
|
|
1095
|
+
const promptByPath = new Map(prompts.map((prompt) => [prompt.filePath, prompt]));
|
|
1096
|
+
expandedSections.push(`${theme.bold(theme.fg("muted", "PROMPTS"))}\n${this.formatScopeGroups(groups, {
|
|
1097
|
+
formatPath: (item) => promptByPath.get(item.path)?.name ?? this.formatDisplayPath(item.path),
|
|
1098
|
+
formatPackagePath: (item) => promptByPath.get(item.path)?.name ?? this.formatDisplayPath(item.path),
|
|
1099
|
+
})}`);
|
|
1055
1100
|
}
|
|
1056
1101
|
if (extensions.length > 0) {
|
|
1057
1102
|
const groups = this.buildScopeGroups(extensions);
|
|
1058
|
-
|
|
1103
|
+
expandedSections.push(`${theme.bold(theme.fg("muted", "EXTENSIONS"))}\n${this.formatScopeGroups(groups, {
|
|
1059
1104
|
formatPath: (item) => this.formatExtensionDisplayPath(item.path),
|
|
1060
1105
|
formatPackagePath: (item) => this.formatExtensionDisplayPath(this.getShortPath(item.path, item.sourceInfo)),
|
|
1061
|
-
});
|
|
1062
|
-
const extensionCompactList = formatCompactList(this.getCompactExtensionLabels(extensions));
|
|
1063
|
-
addLoadedSection("Extensions", extensionCompactList, extList, "mdHeading");
|
|
1106
|
+
})}`);
|
|
1064
1107
|
}
|
|
1065
|
-
// Show loaded themes (excluding built-in)
|
|
1066
|
-
const loadedThemes = themesResult.themes;
|
|
1067
|
-
const customThemes = loadedThemes.filter((t) => t.sourcePath);
|
|
1068
1108
|
if (customThemes.length > 0) {
|
|
1069
1109
|
const groups = this.buildScopeGroups(customThemes.map((loadedTheme) => ({
|
|
1070
1110
|
path: loadedTheme.sourcePath,
|
|
1071
1111
|
sourceInfo: loadedTheme.sourceInfo,
|
|
1072
1112
|
})));
|
|
1073
|
-
|
|
1113
|
+
expandedSections.push(`${theme.bold(theme.fg("muted", "THEMES"))}\n${this.formatScopeGroups(groups, {
|
|
1074
1114
|
formatPath: (item) => this.formatDisplayPath(item.path),
|
|
1075
1115
|
formatPackagePath: (item) => this.getShortPath(item.path, item.sourceInfo),
|
|
1116
|
+
})}`);
|
|
1117
|
+
}
|
|
1118
|
+
const extensionDiagnostics = [];
|
|
1119
|
+
const extensionErrors = this.session.resourceLoader.getExtensions().errors;
|
|
1120
|
+
for (const error of extensionErrors) {
|
|
1121
|
+
extensionDiagnostics.push({
|
|
1122
|
+
type: "error",
|
|
1123
|
+
message: error.error,
|
|
1124
|
+
path: error.path,
|
|
1076
1125
|
});
|
|
1077
|
-
const themeCompactList = formatCompactList(customThemes.map((loadedTheme) => loadedTheme.name ??
|
|
1078
|
-
this.getCompactPathLabel(loadedTheme.sourcePath, loadedTheme.sourceInfo)));
|
|
1079
|
-
addLoadedSection("Themes", themeCompactList, themeList);
|
|
1080
1126
|
}
|
|
1127
|
+
extensionDiagnostics.push(...this.session.extensionRunner.getCommandDiagnostics(), ...this.getBuiltInCommandConflictDiagnostics(this.session.extensionRunner), ...this.session.extensionRunner.getShortcutDiagnostics());
|
|
1128
|
+
this.addResourceDisclosure({
|
|
1129
|
+
contextFiles,
|
|
1130
|
+
skills,
|
|
1131
|
+
prompts,
|
|
1132
|
+
templates,
|
|
1133
|
+
extensions,
|
|
1134
|
+
themes: customThemes,
|
|
1135
|
+
diagnosticsTotal: this.getResourceDiagnosticsTotal([
|
|
1136
|
+
skillsResult.diagnostics,
|
|
1137
|
+
promptsResult.diagnostics,
|
|
1138
|
+
extensionDiagnostics,
|
|
1139
|
+
themesResult.diagnostics,
|
|
1140
|
+
]),
|
|
1141
|
+
expandedBody: this.options.verbose ? expandedSections.join("\n\n") : "",
|
|
1142
|
+
});
|
|
1081
1143
|
}
|
|
1082
1144
|
if (showDiagnostics) {
|
|
1083
1145
|
const skillDiagnostics = skillsResult.diagnostics;
|
|
@@ -1207,7 +1269,8 @@ export class InteractiveMode {
|
|
|
1207
1269
|
}
|
|
1208
1270
|
applyRuntimeSettings() {
|
|
1209
1271
|
this.footer.setSession(this.session);
|
|
1210
|
-
this.
|
|
1272
|
+
this.usageMeter.setSession(this.session);
|
|
1273
|
+
this.usageMeter.setAutoCompactEnabled(this.session.autoCompactionEnabled);
|
|
1211
1274
|
this.footerDataProvider.setCwd(this.sessionManager.getCwd());
|
|
1212
1275
|
this.hideThinkingBlock = this.settingsManager.getHideThinkingBlock();
|
|
1213
1276
|
this.ui.setShowHardwareCursor(this.settingsManager.getShowHardwareCursor());
|
|
@@ -1602,6 +1665,15 @@ export class InteractiveMode {
|
|
|
1602
1665
|
},
|
|
1603
1666
|
getToolsExpanded: () => this.toolOutputExpanded,
|
|
1604
1667
|
setToolsExpanded: (expanded) => this.setToolsExpanded(expanded),
|
|
1668
|
+
getChatRenderSettings: () => ({
|
|
1669
|
+
hideThinkingBlock: this.hideThinkingBlock,
|
|
1670
|
+
hiddenThinkingLabel: this.hiddenThinkingLabel,
|
|
1671
|
+
toolOutputExpanded: this.toolOutputExpanded,
|
|
1672
|
+
showImages: this.settingsManager.getShowImages(),
|
|
1673
|
+
imageWidthCells: this.settingsManager.getImageWidthCells(),
|
|
1674
|
+
getToolDefinition: (toolName) => this.getRegisteredToolDefinition(toolName),
|
|
1675
|
+
getCustomMessageRenderer: (customType) => this.session.extensionRunner.getMessageRenderer(customType),
|
|
1676
|
+
}),
|
|
1605
1677
|
};
|
|
1606
1678
|
}
|
|
1607
1679
|
/**
|
|
@@ -2224,6 +2296,7 @@ export class InteractiveMode {
|
|
|
2224
2296
|
break;
|
|
2225
2297
|
case "thinking_level_changed":
|
|
2226
2298
|
this.footer.invalidate();
|
|
2299
|
+
this.refreshBuiltInHeader();
|
|
2227
2300
|
this.updateEditorBorderColor();
|
|
2228
2301
|
break;
|
|
2229
2302
|
case "message_start":
|
|
@@ -2499,6 +2572,25 @@ export class InteractiveMode {
|
|
|
2499
2572
|
this.lastStatusText = text;
|
|
2500
2573
|
this.ui.requestRender();
|
|
2501
2574
|
}
|
|
2575
|
+
chatMessageRenderOptions() {
|
|
2576
|
+
return {
|
|
2577
|
+
ui: this.ui,
|
|
2578
|
+
cwd: this.sessionManager.getCwd(),
|
|
2579
|
+
markdownTheme: this.getMarkdownThemeWithSettings(),
|
|
2580
|
+
hideThinkingBlock: this.hideThinkingBlock,
|
|
2581
|
+
hiddenThinkingLabel: this.hiddenThinkingLabel,
|
|
2582
|
+
toolOutputExpanded: this.toolOutputExpanded,
|
|
2583
|
+
showImages: this.settingsManager.getShowImages(),
|
|
2584
|
+
imageWidthCells: this.settingsManager.getImageWidthCells(),
|
|
2585
|
+
getToolDefinition: (toolName) => this.getRegisteredToolDefinition(toolName),
|
|
2586
|
+
getCustomMessageRenderer: (customType) => this.session.extensionRunner.getMessageRenderer(customType),
|
|
2587
|
+
};
|
|
2588
|
+
}
|
|
2589
|
+
addRenderedChatEntry(entry) {
|
|
2590
|
+
const component = renderChatMessageEntry(entry, this.chatMessageRenderOptions());
|
|
2591
|
+
addChatTranscriptEntry(this.chatContainer, component, entry.role);
|
|
2592
|
+
return component;
|
|
2593
|
+
}
|
|
2502
2594
|
addMessageToChat(message, options) {
|
|
2503
2595
|
switch (message.role) {
|
|
2504
2596
|
case "bashExecution": {
|
|
@@ -2585,64 +2677,22 @@ export class InteractiveMode {
|
|
|
2585
2677
|
*/
|
|
2586
2678
|
renderSessionContext(sessionContext, options = {}) {
|
|
2587
2679
|
this.pendingTools.clear();
|
|
2588
|
-
const renderedPendingTools = new Map();
|
|
2589
2680
|
if (options.updateFooter) {
|
|
2590
2681
|
this.footer.invalidate();
|
|
2591
2682
|
this.updateEditorBorderColor();
|
|
2592
2683
|
}
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
const component = new ToolExecutionComponent(content.name, content.id, content.arguments, {
|
|
2601
|
-
showImages: this.settingsManager.getShowImages(),
|
|
2602
|
-
imageWidthCells: this.settingsManager.getImageWidthCells(),
|
|
2603
|
-
}, this.getRegisteredToolDefinition(content.name), this.ui, this.sessionManager.getCwd());
|
|
2604
|
-
component.setExpanded(this.toolOutputExpanded);
|
|
2605
|
-
this.chatContainer.addChild(component);
|
|
2606
|
-
if (message.stopReason === "aborted" ||
|
|
2607
|
-
message.stopReason === "error") {
|
|
2608
|
-
let errorMessage;
|
|
2609
|
-
if (message.stopReason === "aborted") {
|
|
2610
|
-
const retryAttempt = this.session.retryAttempt;
|
|
2611
|
-
errorMessage =
|
|
2612
|
-
retryAttempt > 0
|
|
2613
|
-
? `Aborted after ${retryAttempt} retry attempt${retryAttempt > 1 ? "s" : ""}`
|
|
2614
|
-
: "Operation aborted";
|
|
2615
|
-
}
|
|
2616
|
-
else {
|
|
2617
|
-
errorMessage = message.errorMessage || "Error";
|
|
2618
|
-
}
|
|
2619
|
-
component.updateResult({
|
|
2620
|
-
content: [{ type: "text", text: errorMessage }],
|
|
2621
|
-
isError: true,
|
|
2622
|
-
});
|
|
2623
|
-
}
|
|
2624
|
-
else {
|
|
2625
|
-
renderedPendingTools.set(content.id, component);
|
|
2626
|
-
}
|
|
2627
|
-
}
|
|
2628
|
-
}
|
|
2684
|
+
const entries = chatEntriesFromAgentMessages(sessionContext.messages);
|
|
2685
|
+
for (const entry of entries) {
|
|
2686
|
+
const component = this.addRenderedChatEntry(entry);
|
|
2687
|
+
if (entry.kind === "tool" &&
|
|
2688
|
+
entry.isPartial !== false &&
|
|
2689
|
+
component instanceof ToolExecutionComponent) {
|
|
2690
|
+
this.pendingTools.set(entry.toolCallId, component);
|
|
2629
2691
|
}
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
const component = renderedPendingTools.get(message.toolCallId);
|
|
2633
|
-
if (component) {
|
|
2634
|
-
component.updateResult(message);
|
|
2635
|
-
renderedPendingTools.delete(message.toolCallId);
|
|
2636
|
-
}
|
|
2637
|
-
}
|
|
2638
|
-
else {
|
|
2639
|
-
// All other messages use standard rendering
|
|
2640
|
-
this.addMessageToChat(message, options);
|
|
2692
|
+
if (options.populateHistory && entry.kind === "user") {
|
|
2693
|
+
this.editor.addToHistory?.(entry.text);
|
|
2641
2694
|
}
|
|
2642
2695
|
}
|
|
2643
|
-
for (const [toolCallId, component] of renderedPendingTools) {
|
|
2644
|
-
this.pendingTools.set(toolCallId, component);
|
|
2645
|
-
}
|
|
2646
2696
|
this.ui.requestRender();
|
|
2647
2697
|
}
|
|
2648
2698
|
renderInitialMessages() {
|
|
@@ -2862,6 +2912,11 @@ export class InteractiveMode {
|
|
|
2862
2912
|
this.showStatus(`Restored ${restored} queued message${restored > 1 ? "s" : ""} to editor`);
|
|
2863
2913
|
}
|
|
2864
2914
|
}
|
|
2915
|
+
refreshBuiltInHeader() {
|
|
2916
|
+
if (this.builtInHeader instanceof ExpandableText) {
|
|
2917
|
+
this.builtInHeader.refresh();
|
|
2918
|
+
}
|
|
2919
|
+
}
|
|
2865
2920
|
updateEditorBorderColor() {
|
|
2866
2921
|
if (this.isBashMode) {
|
|
2867
2922
|
this.editor.borderColor = theme.getBashModeBorderColor();
|
|
@@ -3243,7 +3298,7 @@ export class InteractiveMode {
|
|
|
3243
3298
|
}, {
|
|
3244
3299
|
onAutoCompactChange: (enabled) => {
|
|
3245
3300
|
this.session.setAutoCompactionEnabled(enabled);
|
|
3246
|
-
this.
|
|
3301
|
+
this.usageMeter.setAutoCompactEnabled(enabled);
|
|
3247
3302
|
},
|
|
3248
3303
|
onShowImagesChange: (enabled) => {
|
|
3249
3304
|
this.settingsManager.setShowImages(enabled);
|