apex-code 0.2.0 → 0.3.0
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 +18 -0
- package/README.md +1 -1
- package/dist/core/export-html/tool-renderer.d.ts.map +1 -1
- package/dist/core/export-html/tool-renderer.js +3 -0
- package/dist/core/export-html/tool-renderer.js.map +1 -1
- package/dist/core/extensions/types.d.ts +7 -0
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/keybindings.d.ts +1 -1
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +1 -1
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/tools/bash.d.ts +6 -0
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +71 -24
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +47 -7
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/shell-operation.d.ts +34 -0
- package/dist/core/tools/shell-operation.d.ts.map +1 -0
- package/dist/core/tools/shell-operation.js +69 -0
- package/dist/core/tools/shell-operation.js.map +1 -0
- package/dist/modes/interactive/components/keybinding-hints.d.ts +7 -1
- package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
- package/dist/modes/interactive/components/keybinding-hints.js +3 -2
- package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
- package/dist/modes/interactive/components/model-row.d.ts +84 -0
- package/dist/modes/interactive/components/model-row.d.ts.map +1 -0
- package/dist/modes/interactive/components/model-row.js +206 -0
- package/dist/modes/interactive/components/model-row.js.map +1 -0
- package/dist/modes/interactive/components/model-selector.d.ts +39 -4
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +158 -27
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts +2 -0
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +8 -0
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +53 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +99 -26
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/theme/theme.d.ts +16 -0
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +19 -1
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/npm-shrinkwrap.json +5 -5
- package/package.json +2 -2
|
@@ -82,9 +82,28 @@ import { refreshModelCatalogs } from "./model-catalog-refresh.js";
|
|
|
82
82
|
import { getModelSearchText } from "./model-search.js";
|
|
83
83
|
import { getAvailableThemes, getAvailableThemesWithPaths, getEditorTheme, getMarkdownTheme, getThemeByName, onThemeChange, setRegisteredThemes, stopThemeWatcher, Theme, theme, } from "./theme/theme.js";
|
|
84
84
|
import { InteractiveThemeController } from "./theme/theme-controller.js";
|
|
85
|
+
const CHAT_DETAIL_ORDER = ["overview", "details", "all"];
|
|
86
|
+
/** The next rung, wrapping from `all` back to `overview`. */
|
|
87
|
+
export function nextChatDetail(detail) {
|
|
88
|
+
return CHAT_DETAIL_ORDER[(CHAT_DETAIL_ORDER.indexOf(detail) + 1) % CHAT_DETAIL_ORDER.length] ?? "details";
|
|
89
|
+
}
|
|
90
|
+
/** The single place the three rungs turn into rendering flags. */
|
|
91
|
+
export function chatDetailView(detail) {
|
|
92
|
+
return {
|
|
93
|
+
toolOutputExpanded: detail === "all",
|
|
94
|
+
editDiffsExpanded: detail !== "overview",
|
|
95
|
+
revealThinking: detail === "all",
|
|
96
|
+
};
|
|
97
|
+
}
|
|
85
98
|
function isExpandable(obj) {
|
|
86
99
|
return typeof obj === "object" && obj !== null && "setExpanded" in obj && typeof obj.setExpanded === "function";
|
|
87
100
|
}
|
|
101
|
+
function hasEditDiffsExpansion(obj) {
|
|
102
|
+
return (typeof obj === "object" &&
|
|
103
|
+
obj !== null &&
|
|
104
|
+
"setEditDiffsExpanded" in obj &&
|
|
105
|
+
typeof obj.setEditDiffsExpanded === "function");
|
|
106
|
+
}
|
|
88
107
|
class ExpandableText extends Text {
|
|
89
108
|
getCollapsedText;
|
|
90
109
|
getExpandedText;
|
|
@@ -318,7 +337,9 @@ export class InteractiveMode {
|
|
|
318
337
|
// Tool execution tracking: toolCallId -> component
|
|
319
338
|
pendingTools = new Map();
|
|
320
339
|
// Tool output expansion state
|
|
340
|
+
chatDetail = "details";
|
|
321
341
|
toolOutputExpanded = false;
|
|
342
|
+
editDiffsExpanded = true;
|
|
322
343
|
// Thinking block visibility state
|
|
323
344
|
hideThinkingBlock = false;
|
|
324
345
|
outputPad = 1;
|
|
@@ -2153,7 +2174,7 @@ export class InteractiveMode {
|
|
|
2153
2174
|
}, {
|
|
2154
2175
|
tui: this.ui,
|
|
2155
2176
|
timeout: opts?.timeout,
|
|
2156
|
-
onToggleToolsExpanded: () => this.
|
|
2177
|
+
onToggleToolsExpanded: () => this.cycleChatDetail(),
|
|
2157
2178
|
enableSearch,
|
|
2158
2179
|
preamble: opts?.preview ? renderPermissionPreview(opts.preview) : undefined,
|
|
2159
2180
|
});
|
|
@@ -2520,7 +2541,7 @@ export class InteractiveMode {
|
|
|
2520
2541
|
// Global debug handler on TUI (works regardless of focus)
|
|
2521
2542
|
this.ui.onDebug = () => this.handleDebugCommand();
|
|
2522
2543
|
this.defaultEditor.onAction("app.model.select", () => this.showModelSelector());
|
|
2523
|
-
this.defaultEditor.onAction("app.tools.expand", () => this.
|
|
2544
|
+
this.defaultEditor.onAction("app.tools.expand", () => this.cycleChatDetail());
|
|
2524
2545
|
this.defaultEditor.onAction("app.thinking.toggle", () => this.toggleThinkingBlockVisibility());
|
|
2525
2546
|
this.defaultEditor.onAction("app.editor.external", () => void this.handleOpenExternalEditor());
|
|
2526
2547
|
this.defaultEditor.onAction("app.message.copy", () => void this.handleCopyCommand({ flashConfirmation: true, preferSelection: true }));
|
|
@@ -2874,7 +2895,7 @@ export class InteractiveMode {
|
|
|
2874
2895
|
this.ui.requestRender();
|
|
2875
2896
|
}
|
|
2876
2897
|
else if (event.message.role === "assistant") {
|
|
2877
|
-
this.streamingComponent = new AssistantMessageComponent(undefined, this.
|
|
2898
|
+
this.streamingComponent = new AssistantMessageComponent(undefined, this.isThinkingHidden(), this.getMarkdownThemeWithSettings(), this.hiddenThinkingLabel, this.outputPad, this.getMarkdownTransformers());
|
|
2878
2899
|
this.streamingMessage = event.message;
|
|
2879
2900
|
this.chatContainer.addChild(this.streamingComponent);
|
|
2880
2901
|
this.streamingComponent.updateContent(this.streamingMessage, true);
|
|
@@ -2893,7 +2914,7 @@ export class InteractiveMode {
|
|
|
2893
2914
|
showImages: this.settingsManager.getShowImages(),
|
|
2894
2915
|
imageWidthCells: this.settingsManager.getImageWidthCells(),
|
|
2895
2916
|
}, this.getRegisteredToolDefinition(content.name), this.ui, this.sessionManager.getCwd());
|
|
2896
|
-
|
|
2917
|
+
this.adoptChatDetail(component);
|
|
2897
2918
|
this.chatContainer.addChild(component);
|
|
2898
2919
|
this.pendingTools.set(content.id, component);
|
|
2899
2920
|
this.offerFirstUseHint("tool-expand");
|
|
@@ -2960,7 +2981,7 @@ export class InteractiveMode {
|
|
|
2960
2981
|
showImages: this.settingsManager.getShowImages(),
|
|
2961
2982
|
imageWidthCells: this.settingsManager.getImageWidthCells(),
|
|
2962
2983
|
}, this.getRegisteredToolDefinition(event.toolName), this.ui, this.sessionManager.getCwd());
|
|
2963
|
-
|
|
2984
|
+
this.adoptChatDetail(component);
|
|
2964
2985
|
this.chatContainer.addChild(component);
|
|
2965
2986
|
this.pendingTools.set(event.toolCallId, component);
|
|
2966
2987
|
}
|
|
@@ -3161,7 +3182,7 @@ export class InteractiveMode {
|
|
|
3161
3182
|
return;
|
|
3162
3183
|
}
|
|
3163
3184
|
const component = new CustomEntryComponent(entry, renderer);
|
|
3164
|
-
|
|
3185
|
+
this.adoptChatDetail(component);
|
|
3165
3186
|
if (!component.hasContent()) {
|
|
3166
3187
|
return;
|
|
3167
3188
|
}
|
|
@@ -3189,7 +3210,7 @@ export class InteractiveMode {
|
|
|
3189
3210
|
if (message.display) {
|
|
3190
3211
|
const renderer = this.session.extensionRunner.getMessageRenderer(message.customType);
|
|
3191
3212
|
const component = new CustomMessageComponent(message, renderer, this.getMarkdownThemeWithSettings(), this.outputPad);
|
|
3192
|
-
|
|
3213
|
+
this.adoptChatDetail(component);
|
|
3193
3214
|
this.chatContainer.addChild(component);
|
|
3194
3215
|
}
|
|
3195
3216
|
break;
|
|
@@ -3197,14 +3218,14 @@ export class InteractiveMode {
|
|
|
3197
3218
|
case "compactionSummary": {
|
|
3198
3219
|
this.chatContainer.addChild(new Spacer(1));
|
|
3199
3220
|
const component = new CompactionSummaryMessageComponent(message, this.getMarkdownThemeWithSettings());
|
|
3200
|
-
|
|
3221
|
+
this.adoptChatDetail(component);
|
|
3201
3222
|
this.chatContainer.addChild(component);
|
|
3202
3223
|
break;
|
|
3203
3224
|
}
|
|
3204
3225
|
case "branchSummary": {
|
|
3205
3226
|
this.chatContainer.addChild(new Spacer(1));
|
|
3206
3227
|
const component = new BranchSummaryMessageComponent(message, this.getMarkdownThemeWithSettings());
|
|
3207
|
-
|
|
3228
|
+
this.adoptChatDetail(component);
|
|
3208
3229
|
this.chatContainer.addChild(component);
|
|
3209
3230
|
break;
|
|
3210
3231
|
}
|
|
@@ -3218,7 +3239,7 @@ export class InteractiveMode {
|
|
|
3218
3239
|
if (skillBlock) {
|
|
3219
3240
|
// Render skill block (collapsible)
|
|
3220
3241
|
const component = new SkillInvocationMessageComponent(skillBlock, this.getMarkdownThemeWithSettings());
|
|
3221
|
-
|
|
3242
|
+
this.adoptChatDetail(component);
|
|
3222
3243
|
this.chatContainer.addChild(component);
|
|
3223
3244
|
// Render user message separately if present
|
|
3224
3245
|
if (skillBlock.userMessage) {
|
|
@@ -3238,7 +3259,7 @@ export class InteractiveMode {
|
|
|
3238
3259
|
break;
|
|
3239
3260
|
}
|
|
3240
3261
|
case "assistant": {
|
|
3241
|
-
const assistantComponent = new AssistantMessageComponent(message, this.
|
|
3262
|
+
const assistantComponent = new AssistantMessageComponent(message, this.isThinkingHidden(), this.getMarkdownThemeWithSettings(), this.hiddenThinkingLabel, this.outputPad, this.getMarkdownTransformers());
|
|
3242
3263
|
this.chatContainer.addChild(assistantComponent);
|
|
3243
3264
|
break;
|
|
3244
3265
|
}
|
|
@@ -3283,7 +3304,7 @@ export class InteractiveMode {
|
|
|
3283
3304
|
showImages: this.settingsManager.getShowImages(),
|
|
3284
3305
|
imageWidthCells: this.settingsManager.getImageWidthCells(),
|
|
3285
3306
|
}, this.getRegisteredToolDefinition(content.name), this.ui, this.sessionManager.getCwd());
|
|
3286
|
-
|
|
3307
|
+
this.adoptChatDetail(component);
|
|
3287
3308
|
this.chatContainer.addChild(component);
|
|
3288
3309
|
if (message.stopReason === "aborted" || message.stopReason === "error") {
|
|
3289
3310
|
let errorMessage;
|
|
@@ -3694,31 +3715,76 @@ export class InteractiveMode {
|
|
|
3694
3715
|
this.showError(error instanceof Error ? error.message : String(error));
|
|
3695
3716
|
}
|
|
3696
3717
|
}
|
|
3697
|
-
|
|
3698
|
-
|
|
3718
|
+
/**
|
|
3719
|
+
* Bring a freshly created transcript component up to the current detail level.
|
|
3720
|
+
*
|
|
3721
|
+
* Components are constructed collapsed and adopted here, so a new component
|
|
3722
|
+
* type joins the cycle by having the methods rather than by its call site
|
|
3723
|
+
* remembering to set every axis.
|
|
3724
|
+
*/
|
|
3725
|
+
adoptChatDetail(component) {
|
|
3726
|
+
if (isExpandable(component))
|
|
3727
|
+
component.setExpanded(this.toolOutputExpanded);
|
|
3728
|
+
if (hasEditDiffsExpansion(component))
|
|
3729
|
+
component.setEditDiffsExpanded(this.editDiffsExpanded);
|
|
3730
|
+
}
|
|
3731
|
+
cycleChatDetail() {
|
|
3732
|
+
this.setChatDetail(nextChatDetail(this.chatDetail));
|
|
3699
3733
|
}
|
|
3700
|
-
|
|
3701
|
-
|
|
3734
|
+
/**
|
|
3735
|
+
* Presentation only. This never rewrites messages, settings, or the session
|
|
3736
|
+
* transcript, which is why it may override the persisted thinking preference
|
|
3737
|
+
* at `all` without saving that override.
|
|
3738
|
+
*/
|
|
3739
|
+
setChatDetail(detail) {
|
|
3740
|
+
if (detail === this.chatDetail)
|
|
3702
3741
|
return;
|
|
3703
|
-
this.
|
|
3742
|
+
this.chatDetail = detail;
|
|
3743
|
+
const view = chatDetailView(detail);
|
|
3744
|
+
this.toolOutputExpanded = view.toolOutputExpanded;
|
|
3745
|
+
this.editDiffsExpanded = view.editDiffsExpanded;
|
|
3746
|
+
this.applyChatDetail();
|
|
3747
|
+
this.showStatus(`Conversation detail: ${detail}`);
|
|
3748
|
+
}
|
|
3749
|
+
/** True when thinking blocks are hidden right now, setting and detail level combined. */
|
|
3750
|
+
isThinkingHidden() {
|
|
3751
|
+
return this.hideThinkingBlock && !chatDetailView(this.chatDetail).revealThinking;
|
|
3752
|
+
}
|
|
3753
|
+
applyChatDetail() {
|
|
3704
3754
|
const activeHeader = this.customHeader ?? this.builtInHeader;
|
|
3705
3755
|
if (isExpandable(activeHeader)) {
|
|
3706
|
-
activeHeader.setExpanded(
|
|
3756
|
+
activeHeader.setExpanded(this.toolOutputExpanded);
|
|
3707
3757
|
}
|
|
3708
3758
|
for (const container of [this.loadedResourcesContainer, this.chatContainer]) {
|
|
3709
3759
|
for (const child of container.children) {
|
|
3760
|
+
if (child instanceof AssistantMessageComponent) {
|
|
3761
|
+
child.setHideThinkingBlock(this.isThinkingHidden());
|
|
3762
|
+
}
|
|
3710
3763
|
if (isExpandable(child)) {
|
|
3711
|
-
child.setExpanded(
|
|
3764
|
+
child.setExpanded(this.toolOutputExpanded);
|
|
3765
|
+
}
|
|
3766
|
+
if (hasEditDiffsExpansion(child)) {
|
|
3767
|
+
child.setEditDiffsExpanded(this.editDiffsExpanded);
|
|
3712
3768
|
}
|
|
3713
3769
|
}
|
|
3714
3770
|
}
|
|
3715
|
-
this.
|
|
3771
|
+
this.ui.requestRender();
|
|
3772
|
+
}
|
|
3773
|
+
/**
|
|
3774
|
+
* The extension-facing boolean, which names one axis of three.
|
|
3775
|
+
*
|
|
3776
|
+
* Collapsing maps to `details` rather than `overview`, because an extension
|
|
3777
|
+
* asking to collapse tool output has not asked to hide edit diffs, and
|
|
3778
|
+
* `details` is the level where only tool output is collapsed.
|
|
3779
|
+
*/
|
|
3780
|
+
setToolsExpanded(expanded) {
|
|
3781
|
+
this.setChatDetail(expanded ? "all" : "details");
|
|
3716
3782
|
}
|
|
3717
3783
|
/** Update rendered assistant messages without rebuilding live tool components. */
|
|
3718
3784
|
updateThinkingBlockVisibility() {
|
|
3719
3785
|
for (const child of this.chatContainer.children) {
|
|
3720
3786
|
if (child instanceof AssistantMessageComponent) {
|
|
3721
|
-
child.setHideThinkingBlock(this.
|
|
3787
|
+
child.setHideThinkingBlock(this.isThinkingHidden());
|
|
3722
3788
|
}
|
|
3723
3789
|
}
|
|
3724
3790
|
this.ui.requestRender();
|
|
@@ -4456,14 +4522,21 @@ export class InteractiveMode {
|
|
|
4456
4522
|
}
|
|
4457
4523
|
showModelSelector(initialSearchInput) {
|
|
4458
4524
|
this.showSelector((done) => {
|
|
4459
|
-
const selectModel = async (model, persist) => {
|
|
4525
|
+
const selectModel = async (model, persist, thinkingLevel) => {
|
|
4460
4526
|
try {
|
|
4461
4527
|
await this.session.setModel(model, { persist });
|
|
4528
|
+
// setModel already applied the level this model switches to, so this
|
|
4529
|
+
// only overrides it when the picker's effort was actually dialled. The
|
|
4530
|
+
// cast is the session's own: it stores and clamps "off" but types the
|
|
4531
|
+
// field as ThinkingLevel, which does not name it.
|
|
4532
|
+
if (thinkingLevel !== undefined)
|
|
4533
|
+
this.session.setThinkingLevel(thinkingLevel);
|
|
4462
4534
|
this.updateAvailableProviderCount();
|
|
4463
4535
|
this.footer.invalidate();
|
|
4464
4536
|
this.updateEditorBorderColor();
|
|
4465
4537
|
done();
|
|
4466
|
-
|
|
4538
|
+
const effort = thinkingLevel === undefined ? "" : ` · ${thinkingLevel}`;
|
|
4539
|
+
this.showStatus(persist ? `Default model: ${model.provider}/${model.id}${effort}` : `Model: ${model.id}${effort}`);
|
|
4467
4540
|
void this.maybeWarnAboutAnthropicSubscriptionAuth(model);
|
|
4468
4541
|
this.checkDaxnutsEasterEgg(model);
|
|
4469
4542
|
}
|
|
@@ -4474,10 +4547,10 @@ export class InteractiveMode {
|
|
|
4474
4547
|
};
|
|
4475
4548
|
const defaultProvider = this.settingsManager.getDefaultProvider();
|
|
4476
4549
|
const defaultModel = this.settingsManager.getDefaultModel();
|
|
4477
|
-
const selector = new ModelSelectorComponent(this.ui, this.session.model, this.session.modelRuntime, this.session.scopedModels, (model) => selectModel(model, false), () => {
|
|
4550
|
+
const selector = new ModelSelectorComponent(this.ui, this.session.model, this.session.modelRuntime, this.session.scopedModels, (model, thinkingLevel) => selectModel(model, false, thinkingLevel), () => {
|
|
4478
4551
|
done();
|
|
4479
4552
|
this.ui.requestRender();
|
|
4480
|
-
}, initialSearchInput, (model) => selectModel(model, true), defaultProvider && defaultModel ? { provider: defaultProvider, id: defaultModel } : undefined);
|
|
4553
|
+
}, initialSearchInput, (model, thinkingLevel) => selectModel(model, true, thinkingLevel), defaultProvider && defaultModel ? { provider: defaultProvider, id: defaultModel } : undefined, { thinkingLevel: this.session.thinkingLevel });
|
|
4481
4554
|
return { component: selector, focus: selector, dispose: () => selector.dispose() };
|
|
4482
4555
|
});
|
|
4483
4556
|
}
|
|
@@ -5745,7 +5818,7 @@ export class InteractiveMode {
|
|
|
5745
5818
|
| \`${cycleThinkingLevel}\` | Cycle thinking level |
|
|
5746
5819
|
| \`${cycleModelForward}\` / \`${cycleModelBackward}\` | Cycle models |
|
|
5747
5820
|
| \`${selectModel}\` | Open model selector |
|
|
5748
|
-
| \`${expandTools}\` |
|
|
5821
|
+
| \`${expandTools}\` | Cycle conversation detail (overview / details / all) |
|
|
5749
5822
|
| \`${toggleThinking}\` | Toggle thinking block visibility |
|
|
5750
5823
|
| \`${externalEditor}\` | Edit message in external editor |
|
|
5751
5824
|
| \`${copyMessage}\` | Copy last assistant message |
|