@oh-my-pi/pi-coding-agent 3.13.1337 → 3.15.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 +88 -0
- package/docs/theme.md +38 -5
- package/examples/sdk/11-sessions.ts +2 -2
- package/package.json +7 -4
- package/src/cli/file-processor.ts +51 -2
- package/src/cli/plugin-cli.ts +25 -19
- package/src/cli/update-cli.ts +4 -3
- package/src/core/agent-session.ts +31 -4
- package/src/core/compaction/branch-summarization.ts +4 -32
- package/src/core/compaction/compaction.ts +6 -84
- package/src/core/compaction/utils.ts +2 -3
- package/src/core/custom-tools/types.ts +2 -0
- package/src/core/export-html/index.ts +1 -1
- package/src/core/hooks/index.ts +1 -1
- package/src/core/hooks/tool-wrapper.ts +0 -1
- package/src/core/hooks/types.ts +2 -2
- package/src/core/plugins/doctor.ts +9 -1
- package/src/core/sdk.ts +2 -1
- package/src/core/session-manager.ts +552 -41
- package/src/core/settings-manager.ts +174 -0
- package/src/core/system-prompt.ts +9 -14
- package/src/core/title-generator.ts +2 -8
- package/src/core/tools/ask.ts +19 -37
- package/src/core/tools/bash.ts +2 -37
- package/src/core/tools/edit.ts +2 -9
- package/src/core/tools/exa/render.ts +52 -48
- package/src/core/tools/find.ts +10 -8
- package/src/core/tools/grep.ts +45 -17
- package/src/core/tools/ls.ts +22 -2
- package/src/core/tools/lsp/clients/biome-client.ts +207 -0
- package/src/core/tools/lsp/clients/index.ts +49 -0
- package/src/core/tools/lsp/clients/lsp-linter-client.ts +98 -0
- package/src/core/tools/lsp/config.ts +3 -0
- package/src/core/tools/lsp/index.ts +107 -55
- package/src/core/tools/lsp/render.ts +192 -79
- package/src/core/tools/lsp/types.ts +27 -0
- package/src/core/tools/lsp/utils.ts +62 -22
- package/src/core/tools/notebook.ts +9 -1
- package/src/core/tools/output.ts +37 -14
- package/src/core/tools/read.ts +349 -34
- package/src/core/tools/renderers.ts +290 -89
- package/src/core/tools/review.ts +12 -5
- package/src/core/tools/task/agents.ts +5 -5
- package/src/core/tools/task/commands.ts +3 -3
- package/src/core/tools/task/executor.ts +33 -1
- package/src/core/tools/task/index.ts +93 -6
- package/src/core/tools/task/render.ts +147 -66
- package/src/core/tools/task/types.ts +14 -9
- package/src/core/tools/web-fetch.ts +242 -103
- package/src/core/tools/web-search/index.ts +64 -20
- package/src/core/tools/web-search/providers/exa.ts +68 -172
- package/src/core/tools/web-search/render.ts +264 -74
- package/src/core/tools/write.ts +2 -8
- package/src/main.ts +10 -6
- package/src/modes/cleanup.ts +23 -0
- package/src/modes/index.ts +9 -4
- package/src/modes/interactive/components/bash-execution.ts +6 -3
- package/src/modes/interactive/components/branch-summary-message.ts +1 -1
- package/src/modes/interactive/components/compaction-summary-message.ts +1 -1
- package/src/modes/interactive/components/dynamic-border.ts +1 -1
- package/src/modes/interactive/components/extensions/extension-dashboard.ts +4 -5
- package/src/modes/interactive/components/extensions/extension-list.ts +18 -16
- package/src/modes/interactive/components/extensions/inspector-panel.ts +8 -8
- package/src/modes/interactive/components/hook-message.ts +2 -2
- package/src/modes/interactive/components/hook-selector.ts +1 -1
- package/src/modes/interactive/components/model-selector.ts +22 -9
- package/src/modes/interactive/components/oauth-selector.ts +20 -4
- package/src/modes/interactive/components/plugin-settings.ts +4 -2
- package/src/modes/interactive/components/session-selector.ts +9 -6
- package/src/modes/interactive/components/settings-defs.ts +285 -1
- package/src/modes/interactive/components/settings-selector.ts +176 -3
- package/src/modes/interactive/components/status-line/index.ts +4 -0
- package/src/modes/interactive/components/status-line/presets.ts +94 -0
- package/src/modes/interactive/components/status-line/segments.ts +350 -0
- package/src/modes/interactive/components/status-line/separators.ts +55 -0
- package/src/modes/interactive/components/status-line/types.ts +81 -0
- package/src/modes/interactive/components/status-line-segment-editor.ts +357 -0
- package/src/modes/interactive/components/status-line.ts +169 -233
- package/src/modes/interactive/components/tool-execution.ts +446 -211
- package/src/modes/interactive/components/tree-selector.ts +17 -6
- package/src/modes/interactive/components/ttsr-notification.ts +4 -4
- package/src/modes/interactive/components/welcome.ts +27 -19
- package/src/modes/interactive/interactive-mode.ts +98 -13
- package/src/modes/interactive/theme/dark.json +3 -2
- package/src/modes/interactive/theme/defaults/dark-arctic.json +111 -0
- package/src/modes/interactive/theme/defaults/dark-catppuccin.json +106 -0
- package/src/modes/interactive/theme/defaults/dark-cyberpunk.json +109 -0
- package/src/modes/interactive/theme/defaults/dark-dracula.json +105 -0
- package/src/modes/interactive/theme/defaults/dark-forest.json +103 -0
- package/src/modes/interactive/theme/defaults/dark-github.json +112 -0
- package/src/modes/interactive/theme/defaults/dark-gruvbox.json +119 -0
- package/src/modes/interactive/theme/defaults/dark-monochrome.json +101 -0
- package/src/modes/interactive/theme/defaults/dark-monokai.json +105 -0
- package/src/modes/interactive/theme/defaults/dark-nord.json +104 -0
- package/src/modes/interactive/theme/defaults/dark-ocean.json +108 -0
- package/src/modes/interactive/theme/defaults/dark-one.json +107 -0
- package/src/modes/interactive/theme/defaults/dark-retro.json +99 -0
- package/src/modes/interactive/theme/defaults/dark-rose-pine.json +95 -0
- package/src/modes/interactive/theme/defaults/dark-solarized.json +96 -0
- package/src/modes/interactive/theme/defaults/dark-sunset.json +106 -0
- package/src/modes/interactive/theme/defaults/dark-synthwave.json +102 -0
- package/src/modes/interactive/theme/defaults/dark-tokyo-night.json +108 -0
- package/src/modes/interactive/theme/defaults/index.ts +67 -0
- package/src/modes/interactive/theme/defaults/light-arctic.json +106 -0
- package/src/modes/interactive/theme/defaults/light-catppuccin.json +105 -0
- package/src/modes/interactive/theme/defaults/light-cyberpunk.json +103 -0
- package/src/modes/interactive/theme/defaults/light-forest.json +107 -0
- package/src/modes/interactive/theme/defaults/light-github.json +114 -0
- package/src/modes/interactive/theme/defaults/light-gruvbox.json +115 -0
- package/src/modes/interactive/theme/defaults/light-monochrome.json +100 -0
- package/src/modes/interactive/theme/defaults/light-ocean.json +106 -0
- package/src/modes/interactive/theme/defaults/light-one.json +105 -0
- package/src/modes/interactive/theme/defaults/light-retro.json +105 -0
- package/src/modes/interactive/theme/defaults/light-solarized.json +101 -0
- package/src/modes/interactive/theme/defaults/light-sunset.json +106 -0
- package/src/modes/interactive/theme/defaults/light-synthwave.json +105 -0
- package/src/modes/interactive/theme/defaults/light-tokyo-night.json +118 -0
- package/src/modes/interactive/theme/light.json +3 -2
- package/src/modes/interactive/theme/theme-schema.json +120 -4
- package/src/modes/interactive/theme/theme.ts +1228 -14
- package/src/prompts/branch-summary-preamble.md +3 -0
- package/src/prompts/branch-summary.md +28 -0
- package/src/prompts/compaction-summary.md +34 -0
- package/src/prompts/compaction-turn-prefix.md +16 -0
- package/src/prompts/compaction-update-summary.md +41 -0
- package/src/prompts/init.md +30 -0
- package/src/{core/tools/task/bundled-agents → prompts}/reviewer.md +6 -0
- package/src/prompts/summarization-system.md +3 -0
- package/src/prompts/system-prompt.md +27 -0
- package/src/{core/tools/task/bundled-agents → prompts}/task.md +2 -0
- package/src/prompts/title-system.md +8 -0
- package/src/prompts/tools/ask.md +24 -0
- package/src/prompts/tools/bash.md +23 -0
- package/src/prompts/tools/edit.md +9 -0
- package/src/prompts/tools/find.md +6 -0
- package/src/prompts/tools/grep.md +12 -0
- package/src/prompts/tools/lsp.md +14 -0
- package/src/prompts/tools/output.md +23 -0
- package/src/prompts/tools/read.md +25 -0
- package/src/prompts/tools/web-fetch.md +8 -0
- package/src/prompts/tools/web-search.md +10 -0
- package/src/prompts/tools/write.md +10 -0
- package/src/commands/init.md +0 -20
- /package/src/{core/tools/task/bundled-commands → prompts}/architect-plan.md +0 -0
- /package/src/{core/tools/task/bundled-agents → prompts}/browser.md +0 -0
- /package/src/{core/tools/task/bundled-agents → prompts}/explore.md +0 -0
- /package/src/{core/tools/task/bundled-commands → prompts}/implement-with-critic.md +0 -0
- /package/src/{core/tools/task/bundled-commands → prompts}/implement.md +0 -0
- /package/src/{core/tools/task/bundled-agents → prompts}/plan.md +0 -0
|
@@ -16,11 +16,13 @@ import {
|
|
|
16
16
|
type TabBarTheme,
|
|
17
17
|
Text,
|
|
18
18
|
} from "@oh-my-pi/pi-tui";
|
|
19
|
-
import type { SettingsManager } from "../../../core/settings-manager";
|
|
19
|
+
import type { SettingsManager, StatusLineSettings } from "../../../core/settings-manager";
|
|
20
20
|
import { getSelectListTheme, getSettingsListTheme, theme } from "../theme/theme";
|
|
21
21
|
import { DynamicBorder } from "./dynamic-border";
|
|
22
22
|
import { PluginSettingsComponent } from "./plugin-settings";
|
|
23
23
|
import { getSettingsForTab, type SettingDef } from "./settings-defs";
|
|
24
|
+
import { getPreset } from "./status-line/presets";
|
|
25
|
+
import { StatusLineSegmentEditorComponent } from "./status-line-segment-editor";
|
|
24
26
|
|
|
25
27
|
function getTabBarTheme(): TabBarTheme {
|
|
26
28
|
return {
|
|
@@ -36,6 +38,8 @@ function getTabBarTheme(): TabBarTheme {
|
|
|
36
38
|
*/
|
|
37
39
|
class SelectSubmenu extends Container {
|
|
38
40
|
private selectList: SelectList;
|
|
41
|
+
private previewText: Text | null = null;
|
|
42
|
+
private getPreview: (() => string) | undefined;
|
|
39
43
|
|
|
40
44
|
constructor(
|
|
41
45
|
title: string,
|
|
@@ -45,8 +49,10 @@ class SelectSubmenu extends Container {
|
|
|
45
49
|
onSelect: (value: string) => void,
|
|
46
50
|
onCancel: () => void,
|
|
47
51
|
onSelectionChange?: (value: string) => void,
|
|
52
|
+
getPreview?: () => string,
|
|
48
53
|
) {
|
|
49
54
|
super();
|
|
55
|
+
this.getPreview = getPreview;
|
|
50
56
|
|
|
51
57
|
// Title
|
|
52
58
|
this.addChild(new Text(theme.bold(theme.fg("accent", title)), 0, 0));
|
|
@@ -57,6 +63,14 @@ class SelectSubmenu extends Container {
|
|
|
57
63
|
this.addChild(new Text(theme.fg("muted", description), 0, 0));
|
|
58
64
|
}
|
|
59
65
|
|
|
66
|
+
// Preview (if provided)
|
|
67
|
+
if (getPreview) {
|
|
68
|
+
this.addChild(new Spacer(1));
|
|
69
|
+
this.addChild(new Text(theme.fg("muted", "Preview:"), 0, 0));
|
|
70
|
+
this.previewText = new Text(getPreview(), 0, 0);
|
|
71
|
+
this.addChild(this.previewText);
|
|
72
|
+
}
|
|
73
|
+
|
|
60
74
|
// Spacer
|
|
61
75
|
this.addChild(new Spacer(1));
|
|
62
76
|
|
|
@@ -78,6 +92,8 @@ class SelectSubmenu extends Container {
|
|
|
78
92
|
if (onSelectionChange) {
|
|
79
93
|
this.selectList.onSelectionChange = (item) => {
|
|
80
94
|
onSelectionChange(item.value);
|
|
95
|
+
// Update preview after the preview callback has applied changes
|
|
96
|
+
this.updatePreview();
|
|
81
97
|
};
|
|
82
98
|
}
|
|
83
99
|
|
|
@@ -88,6 +104,12 @@ class SelectSubmenu extends Container {
|
|
|
88
104
|
this.addChild(new Text(theme.fg("dim", " Enter to select · Esc to go back"), 0, 0));
|
|
89
105
|
}
|
|
90
106
|
|
|
107
|
+
private updatePreview(): void {
|
|
108
|
+
if (this.previewText && this.getPreview) {
|
|
109
|
+
this.previewText.setText(this.getPreview());
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
91
113
|
handleInput(data: string): void {
|
|
92
114
|
this.selectList.handleInput(data);
|
|
93
115
|
}
|
|
@@ -97,6 +119,7 @@ type TabId = string;
|
|
|
97
119
|
|
|
98
120
|
const SETTINGS_TABS: Tab[] = [
|
|
99
121
|
{ id: "config", label: "Config" },
|
|
122
|
+
{ id: "status", label: "Status" },
|
|
100
123
|
{ id: "lsp", label: "LSP" },
|
|
101
124
|
{ id: "exa", label: "Exa" },
|
|
102
125
|
{ id: "plugins", label: "Plugins" },
|
|
@@ -128,6 +151,10 @@ export interface SettingsCallbacks {
|
|
|
128
151
|
onChange: SettingChangeHandler;
|
|
129
152
|
/** Called for theme preview while browsing */
|
|
130
153
|
onThemePreview?: (theme: string) => void;
|
|
154
|
+
/** Called for status line preview while configuring - updates actual status line */
|
|
155
|
+
onStatusLinePreview?: (settings: Partial<StatusLineSettings>) => void;
|
|
156
|
+
/** Get current rendered status line for inline preview */
|
|
157
|
+
getStatusLinePreview?: () => string;
|
|
131
158
|
/** Called when plugins change */
|
|
132
159
|
onPluginsChanged?: () => void;
|
|
133
160
|
/** Called when settings panel is closed */
|
|
@@ -143,6 +170,9 @@ export class SettingsSelectorComponent extends Container {
|
|
|
143
170
|
private currentList: SettingsList | null = null;
|
|
144
171
|
private currentSubmenu: Container | null = null;
|
|
145
172
|
private pluginComponent: PluginSettingsComponent | null = null;
|
|
173
|
+
private statusPreviewContainer: Container | null = null;
|
|
174
|
+
private statusPreviewText: Text | null = null;
|
|
175
|
+
private currentTabId: TabId = "config";
|
|
146
176
|
|
|
147
177
|
private settingsManager: SettingsManager;
|
|
148
178
|
private context: SettingsRuntimeContext;
|
|
@@ -176,6 +206,8 @@ export class SettingsSelectorComponent extends Container {
|
|
|
176
206
|
}
|
|
177
207
|
|
|
178
208
|
private switchToTab(tabId: TabId): void {
|
|
209
|
+
this.currentTabId = tabId;
|
|
210
|
+
|
|
179
211
|
// Remove current content
|
|
180
212
|
if (this.currentList) {
|
|
181
213
|
this.removeChild(this.currentList);
|
|
@@ -185,6 +217,11 @@ export class SettingsSelectorComponent extends Container {
|
|
|
185
217
|
this.removeChild(this.pluginComponent);
|
|
186
218
|
this.pluginComponent = null;
|
|
187
219
|
}
|
|
220
|
+
if (this.statusPreviewContainer) {
|
|
221
|
+
this.removeChild(this.statusPreviewContainer);
|
|
222
|
+
this.statusPreviewContainer = null;
|
|
223
|
+
this.statusPreviewText = null;
|
|
224
|
+
}
|
|
188
225
|
|
|
189
226
|
// Remove bottom border temporarily
|
|
190
227
|
const bottomBorder = this.children[this.children.length - 1];
|
|
@@ -262,6 +299,11 @@ export class SettingsSelectorComponent extends Container {
|
|
|
262
299
|
currentValue: string,
|
|
263
300
|
done: (value?: string) => void,
|
|
264
301
|
): Container {
|
|
302
|
+
// Special case: segment editor
|
|
303
|
+
if (def.id === "statusLineSegments") {
|
|
304
|
+
return this.createSegmentEditor(done);
|
|
305
|
+
}
|
|
306
|
+
|
|
265
307
|
let options = def.getOptions(this.settingsManager);
|
|
266
308
|
|
|
267
309
|
// Special case: inject runtime options
|
|
@@ -274,8 +316,55 @@ export class SettingsSelectorComponent extends Container {
|
|
|
274
316
|
options = this.context.availableThemes.map((t) => ({ value: t, label: t }));
|
|
275
317
|
}
|
|
276
318
|
|
|
277
|
-
|
|
278
|
-
|
|
319
|
+
// Preview handlers
|
|
320
|
+
let onPreview: ((value: string) => void) | undefined;
|
|
321
|
+
let onPreviewCancel: (() => void) | undefined;
|
|
322
|
+
|
|
323
|
+
if (def.id === "theme") {
|
|
324
|
+
onPreview = this.callbacks.onThemePreview;
|
|
325
|
+
onPreviewCancel = () => this.callbacks.onThemePreview?.(currentValue);
|
|
326
|
+
} else if (def.id === "statusLinePreset") {
|
|
327
|
+
onPreview = (value) => {
|
|
328
|
+
const presetDef = getPreset((value as StatusLineSettings["preset"]) ?? "default");
|
|
329
|
+
this.callbacks.onStatusLinePreview?.({
|
|
330
|
+
preset: value as StatusLineSettings["preset"],
|
|
331
|
+
leftSegments: presetDef.leftSegments,
|
|
332
|
+
rightSegments: presetDef.rightSegments,
|
|
333
|
+
separator: presetDef.separator,
|
|
334
|
+
});
|
|
335
|
+
this.updateStatusPreview();
|
|
336
|
+
};
|
|
337
|
+
onPreviewCancel = () => {
|
|
338
|
+
const currentPreset = this.settingsManager.getStatusLinePreset();
|
|
339
|
+
const presetDef = getPreset(currentPreset);
|
|
340
|
+
this.callbacks.onStatusLinePreview?.({
|
|
341
|
+
preset: currentPreset,
|
|
342
|
+
leftSegments: presetDef.leftSegments,
|
|
343
|
+
rightSegments: presetDef.rightSegments,
|
|
344
|
+
separator: presetDef.separator,
|
|
345
|
+
});
|
|
346
|
+
this.updateStatusPreview();
|
|
347
|
+
};
|
|
348
|
+
} else if (def.id === "statusLineSeparator") {
|
|
349
|
+
onPreview = (value) => {
|
|
350
|
+
this.callbacks.onStatusLinePreview?.({
|
|
351
|
+
separator: value as StatusLineSettings["separator"],
|
|
352
|
+
});
|
|
353
|
+
this.updateStatusPreview();
|
|
354
|
+
};
|
|
355
|
+
onPreviewCancel = () => {
|
|
356
|
+
const currentSettings = this.settingsManager.getStatusLineSettings();
|
|
357
|
+
const separator =
|
|
358
|
+
currentSettings.separator ?? getPreset(this.settingsManager.getStatusLinePreset()).separator;
|
|
359
|
+
this.callbacks.onStatusLinePreview?.({
|
|
360
|
+
separator,
|
|
361
|
+
});
|
|
362
|
+
this.updateStatusPreview();
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
// Provide status line preview for theme selection
|
|
367
|
+
const getPreview = def.id === "theme" ? this.callbacks.getStatusLinePreview : undefined;
|
|
279
368
|
|
|
280
369
|
return new SelectSubmenu(
|
|
281
370
|
def.label,
|
|
@@ -294,9 +383,48 @@ export class SettingsSelectorComponent extends Container {
|
|
|
294
383
|
done();
|
|
295
384
|
},
|
|
296
385
|
onPreview,
|
|
386
|
+
getPreview,
|
|
297
387
|
);
|
|
298
388
|
}
|
|
299
389
|
|
|
390
|
+
/**
|
|
391
|
+
* Create the segment editor component.
|
|
392
|
+
*/
|
|
393
|
+
private createSegmentEditor(done: (value?: string) => void): Container {
|
|
394
|
+
const currentSettings = this.settingsManager.getStatusLineSettings();
|
|
395
|
+
const preset = currentSettings.preset ?? "default";
|
|
396
|
+
const presetDef = getPreset(preset);
|
|
397
|
+
|
|
398
|
+
const leftSegments = currentSettings.leftSegments ?? presetDef.leftSegments;
|
|
399
|
+
const rightSegments = currentSettings.rightSegments ?? presetDef.rightSegments;
|
|
400
|
+
|
|
401
|
+
return new StatusLineSegmentEditorComponent(leftSegments, rightSegments, {
|
|
402
|
+
onSave: (left, right) => {
|
|
403
|
+
this.settingsManager.setStatusLineLeftSegments(left);
|
|
404
|
+
this.settingsManager.setStatusLineRightSegments(right);
|
|
405
|
+
this.callbacks.onChange("statusLineSegments", "saved");
|
|
406
|
+
this.callbacks.onStatusLinePreview?.({ leftSegments: left, rightSegments: right });
|
|
407
|
+
this.updateStatusPreview();
|
|
408
|
+
done("saved");
|
|
409
|
+
},
|
|
410
|
+
onCancel: () => {
|
|
411
|
+
// Restore preview to saved state
|
|
412
|
+
const saved = this.settingsManager.getStatusLineSettings();
|
|
413
|
+
const savedPreset = getPreset(saved.preset ?? "default");
|
|
414
|
+
this.callbacks.onStatusLinePreview?.({
|
|
415
|
+
leftSegments: saved.leftSegments ?? savedPreset.leftSegments,
|
|
416
|
+
rightSegments: saved.rightSegments ?? savedPreset.rightSegments,
|
|
417
|
+
});
|
|
418
|
+
this.updateStatusPreview();
|
|
419
|
+
done();
|
|
420
|
+
},
|
|
421
|
+
onPreview: (left, right) => {
|
|
422
|
+
this.callbacks.onStatusLinePreview?.({ leftSegments: left, rightSegments: right });
|
|
423
|
+
this.updateStatusPreview();
|
|
424
|
+
},
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
|
|
300
428
|
/**
|
|
301
429
|
* Show a settings tab using definitions.
|
|
302
430
|
*/
|
|
@@ -311,6 +439,17 @@ export class SettingsSelectorComponent extends Container {
|
|
|
311
439
|
}
|
|
312
440
|
}
|
|
313
441
|
|
|
442
|
+
// Add status line preview for status tab
|
|
443
|
+
if (tabId === "status") {
|
|
444
|
+
this.statusPreviewContainer = new Container();
|
|
445
|
+
this.statusPreviewContainer.addChild(new Spacer(1));
|
|
446
|
+
this.statusPreviewContainer.addChild(new Text(theme.fg("muted", "Preview:"), 0, 0));
|
|
447
|
+
this.statusPreviewText = new Text(this.getStatusPreviewString(), 0, 0);
|
|
448
|
+
this.statusPreviewContainer.addChild(this.statusPreviewText);
|
|
449
|
+
this.statusPreviewContainer.addChild(new Spacer(1));
|
|
450
|
+
this.addChild(this.statusPreviewContainer);
|
|
451
|
+
}
|
|
452
|
+
|
|
314
453
|
this.currentList = new SettingsList(
|
|
315
454
|
items,
|
|
316
455
|
10,
|
|
@@ -324,6 +463,11 @@ export class SettingsSelectorComponent extends Container {
|
|
|
324
463
|
const boolValue = newValue === "true";
|
|
325
464
|
def.set(this.settingsManager, boolValue);
|
|
326
465
|
this.callbacks.onChange(id, boolValue);
|
|
466
|
+
|
|
467
|
+
// Trigger status line preview for status tab boolean settings
|
|
468
|
+
if (tabId === "status") {
|
|
469
|
+
this.triggerStatusLinePreview();
|
|
470
|
+
}
|
|
327
471
|
} else if (def.type === "enum") {
|
|
328
472
|
def.set(this.settingsManager, newValue);
|
|
329
473
|
this.callbacks.onChange(id, newValue);
|
|
@@ -336,6 +480,35 @@ export class SettingsSelectorComponent extends Container {
|
|
|
336
480
|
this.addChild(this.currentList);
|
|
337
481
|
}
|
|
338
482
|
|
|
483
|
+
/**
|
|
484
|
+
* Get the status line preview string.
|
|
485
|
+
*/
|
|
486
|
+
private getStatusPreviewString(): string {
|
|
487
|
+
if (this.callbacks.getStatusLinePreview) {
|
|
488
|
+
return this.callbacks.getStatusLinePreview();
|
|
489
|
+
}
|
|
490
|
+
return theme.fg("dim", "(preview not available)");
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
/**
|
|
494
|
+
* Trigger status line preview with current settings.
|
|
495
|
+
*/
|
|
496
|
+
private triggerStatusLinePreview(): void {
|
|
497
|
+
const settings = this.settingsManager.getStatusLineSettings();
|
|
498
|
+
this.callbacks.onStatusLinePreview?.(settings);
|
|
499
|
+
// Update inline preview
|
|
500
|
+
this.updateStatusPreview();
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
/**
|
|
504
|
+
* Update the inline status preview text.
|
|
505
|
+
*/
|
|
506
|
+
private updateStatusPreview(): void {
|
|
507
|
+
if (this.statusPreviewText && this.currentTabId === "status") {
|
|
508
|
+
this.statusPreviewText.setText(this.getStatusPreviewString());
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
|
|
339
512
|
private showPluginsTab(): void {
|
|
340
513
|
this.pluginComponent = new PluginSettingsComponent(this.context.cwd, {
|
|
341
514
|
onClose: () => this.callbacks.onCancel(),
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import type { PresetDef, StatusLinePreset } from "./types";
|
|
2
|
+
|
|
3
|
+
export const STATUS_LINE_PRESETS: Record<StatusLinePreset, PresetDef> = {
|
|
4
|
+
default: {
|
|
5
|
+
// Matches current behavior
|
|
6
|
+
leftSegments: ["pi", "model", "path", "git", "context_pct", "token_total", "cost"],
|
|
7
|
+
rightSegments: [],
|
|
8
|
+
separator: "powerline-thin",
|
|
9
|
+
segmentOptions: {
|
|
10
|
+
model: { showThinkingLevel: true },
|
|
11
|
+
path: { abbreviate: true, maxLength: 40, stripWorkPrefix: true },
|
|
12
|
+
git: { showBranch: true, showStaged: true, showUnstaged: true, showUntracked: true },
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
|
|
16
|
+
minimal: {
|
|
17
|
+
leftSegments: ["path", "git"],
|
|
18
|
+
rightSegments: ["context_pct"],
|
|
19
|
+
separator: "slash",
|
|
20
|
+
segmentOptions: {
|
|
21
|
+
path: { abbreviate: true, maxLength: 30 },
|
|
22
|
+
git: { showBranch: true, showStaged: false, showUnstaged: false, showUntracked: false },
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
|
|
26
|
+
compact: {
|
|
27
|
+
leftSegments: ["model", "git"],
|
|
28
|
+
rightSegments: ["cost", "context_pct"],
|
|
29
|
+
separator: "powerline-thin",
|
|
30
|
+
segmentOptions: {
|
|
31
|
+
model: { showThinkingLevel: false },
|
|
32
|
+
git: { showBranch: true, showStaged: true, showUnstaged: true, showUntracked: false },
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
full: {
|
|
37
|
+
leftSegments: ["pi", "hostname", "model", "path", "git", "subagents"],
|
|
38
|
+
rightSegments: ["token_in", "token_out", "cache_read", "cost", "context_pct", "time_spent", "time"],
|
|
39
|
+
separator: "powerline",
|
|
40
|
+
segmentOptions: {
|
|
41
|
+
model: { showThinkingLevel: true },
|
|
42
|
+
path: { abbreviate: true, maxLength: 50 },
|
|
43
|
+
git: { showBranch: true, showStaged: true, showUnstaged: true, showUntracked: true },
|
|
44
|
+
time: { format: "24h", showSeconds: false },
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
|
|
48
|
+
nerd: {
|
|
49
|
+
// Full preset with all Nerd Font icons
|
|
50
|
+
leftSegments: ["pi", "hostname", "model", "path", "git", "session", "subagents"],
|
|
51
|
+
rightSegments: [
|
|
52
|
+
"token_in",
|
|
53
|
+
"token_out",
|
|
54
|
+
"cache_read",
|
|
55
|
+
"cache_write",
|
|
56
|
+
"cost",
|
|
57
|
+
"context_pct",
|
|
58
|
+
"context_total",
|
|
59
|
+
"time_spent",
|
|
60
|
+
"time",
|
|
61
|
+
],
|
|
62
|
+
separator: "powerline",
|
|
63
|
+
segmentOptions: {
|
|
64
|
+
model: { showThinkingLevel: true },
|
|
65
|
+
path: { abbreviate: true, maxLength: 60 },
|
|
66
|
+
git: { showBranch: true, showStaged: true, showUnstaged: true, showUntracked: true },
|
|
67
|
+
time: { format: "24h", showSeconds: true },
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
|
|
71
|
+
ascii: {
|
|
72
|
+
// No Nerd Font dependencies
|
|
73
|
+
leftSegments: ["model", "path", "git"],
|
|
74
|
+
rightSegments: ["token_total", "cost", "context_pct"],
|
|
75
|
+
separator: "ascii",
|
|
76
|
+
segmentOptions: {
|
|
77
|
+
model: { showThinkingLevel: true },
|
|
78
|
+
path: { abbreviate: true, maxLength: 40 },
|
|
79
|
+
git: { showBranch: true, showStaged: true, showUnstaged: true, showUntracked: true },
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
|
|
83
|
+
custom: {
|
|
84
|
+
// User-defined - these are just defaults that get overridden
|
|
85
|
+
leftSegments: ["model", "path", "git"],
|
|
86
|
+
rightSegments: ["token_total", "cost", "context_pct"],
|
|
87
|
+
separator: "powerline-thin",
|
|
88
|
+
segmentOptions: {},
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
export function getPreset(name: StatusLinePreset): PresetDef {
|
|
93
|
+
return STATUS_LINE_PRESETS[name] ?? STATUS_LINE_PRESETS.default;
|
|
94
|
+
}
|