@gajae-code/coding-agent 0.7.11 → 0.8.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 +33 -0
- package/README.md +1 -1
- package/dist/types/capability/mcp.d.ts +2 -0
- package/dist/types/config/settings-schema.d.ts +25 -2
- package/dist/types/discovery/cursor.d.ts +4 -1
- package/dist/types/discovery/index.d.ts +0 -1
- package/dist/types/discovery/windsurf.d.ts +3 -1
- package/dist/types/gjc-runtime/session-state-sidecar.d.ts +5 -0
- package/dist/types/modes/components/custom-editor.d.ts +4 -0
- package/dist/types/modes/components/settings-selector.d.ts +1 -0
- package/dist/types/modes/components/status-line.d.ts +8 -0
- package/dist/types/modes/components/two-column-body.d.ts +9 -0
- package/dist/types/modes/components/welcome.d.ts +9 -1
- package/dist/types/modes/controllers/input-controller.d.ts +1 -1
- package/dist/types/modes/controllers/selector-controller.d.ts +8 -0
- package/dist/types/modes/interactive-mode.d.ts +1 -0
- package/dist/types/modes/rpc/rpc-types.d.ts +1 -0
- package/dist/types/modes/types.d.ts +1 -0
- package/dist/types/runtime-mcp/config-writer.d.ts +9 -0
- package/dist/types/runtime-mcp/config.d.ts +2 -0
- package/dist/types/runtime-mcp/loader.d.ts +2 -0
- package/dist/types/runtime-mcp/manager.d.ts +2 -0
- package/dist/types/runtime-mcp/types.d.ts +6 -0
- package/dist/types/system-prompt.d.ts +7 -0
- package/dist/types/workflow/workflow-intent-diff.d.ts +19 -0
- package/package.json +10 -10
- package/src/capability/mcp.ts +2 -0
- package/src/config/mcp-schema.json +5 -1
- package/src/config/settings-schema.ts +18 -2
- package/src/coordinator-mcp/server.ts +6 -0
- package/src/discovery/builtin.ts +12 -0
- package/src/discovery/cursor.ts +5 -84
- package/src/discovery/gemini.ts +3 -89
- package/src/discovery/index.ts +4 -1
- package/src/discovery/mcp-json.ts +11 -0
- package/src/discovery/opencode.ts +5 -122
- package/src/discovery/windsurf.ts +4 -82
- package/src/edit/read-file.ts +9 -1
- package/src/gjc-runtime/session-state-sidecar.ts +167 -24
- package/src/gjc-runtime/team-runtime.ts +56 -51
- package/src/internal-urls/docs-index.generated.ts +4 -4
- package/src/modes/components/agent-dashboard.ts +1 -34
- package/src/modes/components/custom-editor.ts +18 -0
- package/src/modes/components/extensions/extension-dashboard.ts +2 -48
- package/src/modes/components/model-selector.ts +58 -2
- package/src/modes/components/session-selector.ts +19 -9
- package/src/modes/components/settings-selector.ts +13 -0
- package/src/modes/components/status-line.ts +215 -86
- package/src/modes/components/tree-selector.ts +28 -8
- package/src/modes/components/two-column-body.ts +36 -0
- package/src/modes/components/welcome.ts +171 -35
- package/src/modes/controllers/event-controller.ts +4 -0
- package/src/modes/controllers/input-controller.ts +151 -30
- package/src/modes/controllers/selector-controller.ts +25 -28
- package/src/modes/interactive-mode.ts +20 -23
- package/src/modes/rpc/rpc-types.ts +1 -0
- package/src/modes/shared/agent-wire/deep-interview-gate.ts +9 -3
- package/src/modes/shared/agent-wire/workflow-gate-schema.ts +20 -0
- package/src/modes/types.ts +1 -0
- package/src/notifications/index.ts +20 -1
- package/src/notifications/lifecycle-control-runtime.ts +12 -3
- package/src/prompts/system/system-prompt.md +15 -1
- package/src/runtime-mcp/config-writer.ts +28 -0
- package/src/runtime-mcp/config.ts +7 -0
- package/src/runtime-mcp/loader.ts +3 -0
- package/src/runtime-mcp/manager.ts +3 -0
- package/src/runtime-mcp/types.ts +6 -0
- package/src/sdk.ts +4 -0
- package/src/session/agent-session.ts +21 -1
- package/src/session/session-manager.ts +58 -18
- package/src/system-prompt.ts +8 -0
- package/src/task/executor.ts +5 -0
- package/src/tools/ast-grep.ts +10 -7
- package/src/tools/bash.ts +15 -6
- package/src/tools/index.ts +8 -1
- package/src/workflow/workflow-intent-diff.ts +199 -0
- package/dist/types/discovery/vscode.d.ts +0 -1
- package/src/discovery/vscode.ts +0 -105
|
@@ -23,13 +23,11 @@ import {
|
|
|
23
23
|
extractPrintableText,
|
|
24
24
|
Input,
|
|
25
25
|
matchesKey,
|
|
26
|
-
padding,
|
|
27
26
|
replaceTabs,
|
|
28
27
|
resolveTerminalColumns,
|
|
29
28
|
Spacer,
|
|
30
29
|
Text,
|
|
31
30
|
truncateToWidth,
|
|
32
|
-
visibleWidth,
|
|
33
31
|
wrapTextWithAnsi,
|
|
34
32
|
} from "@gajae-code/tui";
|
|
35
33
|
import { isEnoent, prompt } from "@gajae-code/utils";
|
|
@@ -52,6 +50,7 @@ import { shortenPath } from "../../tools/render-utils";
|
|
|
52
50
|
import { theme } from "../theme/theme";
|
|
53
51
|
import { matchesAppInterrupt } from "../utils/keybinding-matchers";
|
|
54
52
|
import { DynamicBorder } from "./dynamic-border";
|
|
53
|
+
import { TwoColumnBody } from "./two-column-body";
|
|
55
54
|
|
|
56
55
|
type SourceTabId = "all" | AgentSource;
|
|
57
56
|
type AgentScope = "project" | "user";
|
|
@@ -296,38 +295,6 @@ class AgentInspectorPane implements Component {
|
|
|
296
295
|
invalidate(): void {}
|
|
297
296
|
}
|
|
298
297
|
|
|
299
|
-
class TwoColumnBody implements Component {
|
|
300
|
-
constructor(
|
|
301
|
-
private readonly leftPane: AgentListPane,
|
|
302
|
-
private readonly rightPane: AgentInspectorPane,
|
|
303
|
-
private readonly maxHeight: number,
|
|
304
|
-
) {}
|
|
305
|
-
|
|
306
|
-
render(width: number): string[] {
|
|
307
|
-
const leftWidth = Math.floor(width * 0.5);
|
|
308
|
-
const rightWidth = width - leftWidth - 3;
|
|
309
|
-
const leftLines = this.leftPane.render(leftWidth);
|
|
310
|
-
const rightLines = this.rightPane.render(rightWidth);
|
|
311
|
-
const lineCount = Math.min(this.maxHeight, Math.max(leftLines.length, rightLines.length));
|
|
312
|
-
const out: string[] = [];
|
|
313
|
-
const separator = theme.fg("dim", ` ${theme.boxSharp.vertical} `);
|
|
314
|
-
|
|
315
|
-
for (let i = 0; i < lineCount; i++) {
|
|
316
|
-
const left = truncateToWidth(leftLines[i] ?? "", leftWidth);
|
|
317
|
-
const leftPadded = left + padding(Math.max(0, leftWidth - visibleWidth(left)));
|
|
318
|
-
const right = truncateToWidth(rightLines[i] ?? "", rightWidth);
|
|
319
|
-
out.push(leftPadded + separator + right);
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
return out;
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
invalidate(): void {
|
|
326
|
-
this.leftPane.invalidate?.();
|
|
327
|
-
this.rightPane.invalidate?.();
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
|
|
331
298
|
export class AgentDashboard extends Container {
|
|
332
299
|
#settingsManager: Settings | null = null;
|
|
333
300
|
#allAgents: DashboardAgent[] = [];
|
|
@@ -103,6 +103,10 @@ export class CustomEditor extends Editor {
|
|
|
103
103
|
onQueue?: () => void;
|
|
104
104
|
/** Called when Caps Lock is pressed. */
|
|
105
105
|
onCapsLock?: () => void;
|
|
106
|
+
/** Called when PageUp/PageDown should scroll the transcript viewport instead of prompt history. */
|
|
107
|
+
onViewportPageScroll?: (direction: -1 | 1) => void;
|
|
108
|
+
/** Called before regular composer input should return the transcript viewport to the live bottom. */
|
|
109
|
+
onViewportFollowLive?: () => void;
|
|
106
110
|
|
|
107
111
|
/** Custom key handlers from extensions and non-built-in app actions. */
|
|
108
112
|
#customKeyHandlers = new Map<KeyId, () => boolean | undefined>();
|
|
@@ -243,6 +247,20 @@ export class CustomEditor extends Editor {
|
|
|
243
247
|
return;
|
|
244
248
|
}
|
|
245
249
|
}
|
|
250
|
+
if (!this.isShowingAutocomplete()) {
|
|
251
|
+
if (matchesKey(data, "pageUp") && this.onViewportPageScroll) {
|
|
252
|
+
this.onViewportPageScroll(-1);
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
if (matchesKey(data, "pageDown") && this.onViewportPageScroll) {
|
|
256
|
+
this.onViewportPageScroll(1);
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
if (!matchesKey(data, "pageUp") && !matchesKey(data, "pageDown")) {
|
|
262
|
+
this.onViewportFollowLive?.();
|
|
263
|
+
}
|
|
246
264
|
// Intercept configured image paste (async - fires and handles result)
|
|
247
265
|
if (this.#matchesAction(data, "app.clipboard.pasteImage") && this.onPasteImage) {
|
|
248
266
|
void this.onPasteImage();
|
|
@@ -11,20 +11,12 @@
|
|
|
11
11
|
* - Space: Toggle selected item (or master switch)
|
|
12
12
|
* - Esc: Close dashboard (clears search first if active)
|
|
13
13
|
*/
|
|
14
|
-
import {
|
|
15
|
-
type Component,
|
|
16
|
-
Container,
|
|
17
|
-
matchesKey,
|
|
18
|
-
padding,
|
|
19
|
-
Spacer,
|
|
20
|
-
Text,
|
|
21
|
-
truncateToWidth,
|
|
22
|
-
visibleWidth,
|
|
23
|
-
} from "@gajae-code/tui";
|
|
14
|
+
import { Container, matchesKey, Spacer, Text } from "@gajae-code/tui";
|
|
24
15
|
import { Settings } from "../../../config/settings";
|
|
25
16
|
import { DynamicBorder } from "../../../modes/components/dynamic-border";
|
|
26
17
|
import { theme } from "../../../modes/theme/theme";
|
|
27
18
|
import { matchesAppInterrupt } from "../../../modes/utils/keybinding-matchers";
|
|
19
|
+
import { TwoColumnBody } from "../two-column-body";
|
|
28
20
|
import { ExtensionList } from "./extension-list";
|
|
29
21
|
import { InspectorPanel } from "./inspector-panel";
|
|
30
22
|
import {
|
|
@@ -310,41 +302,3 @@ export class ExtensionDashboard extends Container {
|
|
|
310
302
|
}
|
|
311
303
|
}
|
|
312
304
|
}
|
|
313
|
-
|
|
314
|
-
/**
|
|
315
|
-
* Two-column body component for side-by-side rendering.
|
|
316
|
-
*/
|
|
317
|
-
class TwoColumnBody implements Component {
|
|
318
|
-
constructor(
|
|
319
|
-
private readonly leftPane: ExtensionList,
|
|
320
|
-
private readonly rightPane: InspectorPanel,
|
|
321
|
-
private readonly maxHeight: number,
|
|
322
|
-
) {}
|
|
323
|
-
|
|
324
|
-
render(width: number): string[] {
|
|
325
|
-
const leftWidth = Math.floor(width * 0.5);
|
|
326
|
-
const rightWidth = Math.max(0, width - leftWidth - 3);
|
|
327
|
-
|
|
328
|
-
const leftLines = this.leftPane.render(leftWidth);
|
|
329
|
-
const rightLines = this.rightPane.render(rightWidth);
|
|
330
|
-
|
|
331
|
-
// Limit to maxHeight lines
|
|
332
|
-
const numLines = Math.min(this.maxHeight, Math.max(leftLines.length, rightLines.length));
|
|
333
|
-
const combined: string[] = [];
|
|
334
|
-
const separator = theme.fg("dim", ` ${theme.boxSharp.vertical} `);
|
|
335
|
-
|
|
336
|
-
for (let i = 0; i < numLines; i++) {
|
|
337
|
-
const left = truncateToWidth(leftLines[i] ?? "", leftWidth);
|
|
338
|
-
const leftPadded = left + padding(Math.max(0, leftWidth - visibleWidth(left)));
|
|
339
|
-
const right = truncateToWidth(rightLines[i] ?? "", rightWidth);
|
|
340
|
-
combined.push(leftPadded + separator + right);
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
return combined;
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
invalidate(): void {
|
|
347
|
-
this.leftPane.invalidate?.();
|
|
348
|
-
this.rightPane.invalidate?.();
|
|
349
|
-
}
|
|
350
|
-
}
|
|
@@ -1030,11 +1030,51 @@ export class ModelSelectorComponent extends Container {
|
|
|
1030
1030
|
this.#filterModels(this.#searchInput.getValue());
|
|
1031
1031
|
}
|
|
1032
1032
|
|
|
1033
|
+
/**
|
|
1034
|
+
* "What is this session running right now" summary for the preset landing
|
|
1035
|
+
* header: active preset (when one is applied), the effective current model
|
|
1036
|
+
* and thinking level, and one line per assigned role (default, executor,
|
|
1037
|
+
* planner, critic, architect).
|
|
1038
|
+
*/
|
|
1039
|
+
#formatCurrentSessionLines(): string[] {
|
|
1040
|
+
const lines: string[] = [];
|
|
1041
|
+
const parts: string[] = [];
|
|
1042
|
+
if (this.#activeModelProfile) {
|
|
1043
|
+
const profile = this.#getProfileByName(this.#activeModelProfile);
|
|
1044
|
+
const displayName = profile ? getModelProfilePresentation(profile).displayName : this.#activeModelProfile;
|
|
1045
|
+
parts.push(`preset ${theme.fg("accent", displayName)}`);
|
|
1046
|
+
}
|
|
1047
|
+
if (this.#currentModel) {
|
|
1048
|
+
parts.push(this.#formatAssignedModelLabel(this.#currentModel, this.#currentThinkingLevel));
|
|
1049
|
+
}
|
|
1050
|
+
if (parts.length > 0) lines.push(theme.fg("muted", `Current: ${parts.join(" · ")}`));
|
|
1051
|
+
for (const role of PROFILE_ROLE_PREVIEW_ORDER) {
|
|
1052
|
+
const assigned = this.#roles[role];
|
|
1053
|
+
if (!assigned) continue;
|
|
1054
|
+
const label = GJC_MODEL_ASSIGNMENT_TARGETS[role].tag ?? role.toUpperCase();
|
|
1055
|
+
lines.push(
|
|
1056
|
+
theme.fg("dim", ` ${label}: ${this.#formatAssignedModelLabel(assigned.model, assigned.thinkingLevel)}`),
|
|
1057
|
+
);
|
|
1058
|
+
}
|
|
1059
|
+
return lines;
|
|
1060
|
+
}
|
|
1061
|
+
|
|
1062
|
+
#formatAssignedModelLabel(model: Model, thinkingLevel: ThinkingLevel | undefined): string {
|
|
1063
|
+
let label = `${model.provider}/${model.id}`;
|
|
1064
|
+
if (thinkingLevel && thinkingLevel !== ThinkingLevel.Inherit) {
|
|
1065
|
+
label += ` (${getThinkingLevelMetadata(thinkingLevel).label})`;
|
|
1066
|
+
}
|
|
1067
|
+
return label;
|
|
1068
|
+
}
|
|
1069
|
+
|
|
1033
1070
|
#renderPresetLanding(): void {
|
|
1034
1071
|
this.#headerContainer.clear();
|
|
1035
1072
|
this.#tabBar = null;
|
|
1036
1073
|
this.#listContainer.clear();
|
|
1037
1074
|
this.#headerContainer.addChild(new Text(theme.fg("accent", "Model presets"), 0, 0));
|
|
1075
|
+
for (const line of this.#formatCurrentSessionLines()) {
|
|
1076
|
+
this.#headerContainer.addChild(new Text(line, 0, 0));
|
|
1077
|
+
}
|
|
1038
1078
|
const rows = this.#getPresetRows();
|
|
1039
1079
|
for (let i = 0; i < rows.length; i++) {
|
|
1040
1080
|
const row = rows[i];
|
|
@@ -1065,17 +1105,23 @@ export class ModelSelectorComponent extends Container {
|
|
|
1065
1105
|
if (row.kind === "group") {
|
|
1066
1106
|
const authenticated = this.#isPresetGroupUsable(row.profiles);
|
|
1067
1107
|
const mark = this.#providerAuthPending ? "…" : authenticated ? "✓" : "✗";
|
|
1108
|
+
const containsActive =
|
|
1109
|
+
this.#activeModelProfile !== undefined &&
|
|
1110
|
+
row.profiles.some(profile => profile.name === this.#activeModelProfile);
|
|
1068
1111
|
const label = `${mark} ${row.groupId}`;
|
|
1069
1112
|
const renderedLabel = selected ? theme.fg("accent", label) : authenticated ? label : theme.fg("dim", label);
|
|
1070
|
-
|
|
1113
|
+
const activeSuffix = containsActive ? theme.fg("muted", " (current)") : "";
|
|
1114
|
+
this.#listContainer.addChild(new Text(`${prefix}${renderedLabel}${activeSuffix}`, 0, 0));
|
|
1071
1115
|
continue;
|
|
1072
1116
|
}
|
|
1073
1117
|
const presentation = getModelProfilePresentation(row.profile);
|
|
1074
1118
|
const authenticated = this.#isPresetAuthenticated(row.profile);
|
|
1075
1119
|
const mark = this.#providerAuthPending ? "…" : authenticated ? "✓" : "✗";
|
|
1120
|
+
const isActive = row.profile.name === this.#activeModelProfile;
|
|
1076
1121
|
const label = ` ${mark} ${presentation.displayName}`;
|
|
1077
1122
|
const renderedLabel = selected ? theme.fg("accent", label) : authenticated ? label : theme.fg("dim", label);
|
|
1078
|
-
|
|
1123
|
+
const activeSuffix = isActive ? theme.fg("muted", " (current)") : "";
|
|
1124
|
+
this.#listContainer.addChild(new Text(`${prefix}${renderedLabel}${activeSuffix}`, 0, 0));
|
|
1079
1125
|
}
|
|
1080
1126
|
if (this.#presetLoginHint) {
|
|
1081
1127
|
this.#listContainer.addChild(new Spacer(1));
|
|
@@ -1538,7 +1584,17 @@ export class ModelSelectorComponent extends Container {
|
|
|
1538
1584
|
const missing = this.#getMissingProviders(row.profiles);
|
|
1539
1585
|
this.#presetLoginHint = `Run ${missing.map(provider => `/login ${provider}`).join(", ")}`;
|
|
1540
1586
|
this.#renderPresetLanding();
|
|
1587
|
+
return;
|
|
1588
|
+
}
|
|
1589
|
+
// Enter toggles a usable group's expansion so drilling into presets
|
|
1590
|
+
// works without reaching for the arrow keys (right/left still work).
|
|
1591
|
+
if (this.#expandedPresetProviderId === row.groupId) {
|
|
1592
|
+
this.#collapseSelectedPresetProvider();
|
|
1593
|
+
} else {
|
|
1594
|
+
this.#expandSelectedPresetProvider();
|
|
1541
1595
|
}
|
|
1596
|
+
this.#presetLoginHint = undefined;
|
|
1597
|
+
this.#renderPresetLanding();
|
|
1542
1598
|
return;
|
|
1543
1599
|
}
|
|
1544
1600
|
const missing = this.#getMissingProviders(row.profile);
|
|
@@ -50,6 +50,14 @@ class SessionList implements Component {
|
|
|
50
50
|
};
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
#clampSelectedIndex(): void {
|
|
54
|
+
if (this.#filteredSessions.length === 0) {
|
|
55
|
+
this.#selectedIndex = 0;
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
this.#selectedIndex = Math.max(0, Math.min(this.#selectedIndex, this.#filteredSessions.length - 1));
|
|
59
|
+
}
|
|
60
|
+
|
|
53
61
|
#filterSessions(query: string): void {
|
|
54
62
|
this.#filteredSessions = fuzzyFilter(this.allSessions, query, session => {
|
|
55
63
|
const parts = [
|
|
@@ -62,7 +70,7 @@ class SessionList implements Component {
|
|
|
62
70
|
];
|
|
63
71
|
return parts.filter(Boolean).join(" ");
|
|
64
72
|
});
|
|
65
|
-
this.#
|
|
73
|
+
this.#clampSelectedIndex();
|
|
66
74
|
}
|
|
67
75
|
|
|
68
76
|
removeSession(sessionPath: string): void {
|
|
@@ -71,10 +79,6 @@ class SessionList implements Component {
|
|
|
71
79
|
this.allSessions.splice(index, 1);
|
|
72
80
|
// Re-filter to update filteredSessions
|
|
73
81
|
this.#filterSessions(this.#searchInput.getValue());
|
|
74
|
-
// Adjust selectedIndex if we deleted the last item or beyond
|
|
75
|
-
if (this.#selectedIndex >= this.#filteredSessions.length) {
|
|
76
|
-
this.#selectedIndex = Math.max(0, this.#filteredSessions.length - 1);
|
|
77
|
-
}
|
|
78
82
|
}
|
|
79
83
|
|
|
80
84
|
invalidate(): void {
|
|
@@ -182,6 +186,12 @@ class SessionList implements Component {
|
|
|
182
186
|
}
|
|
183
187
|
|
|
184
188
|
handleInput(keyData: string): void {
|
|
189
|
+
const moveSelection = (delta: number): void => {
|
|
190
|
+
if (this.#filteredSessions.length === 0) return;
|
|
191
|
+
this.#selectedIndex += delta;
|
|
192
|
+
this.#clampSelectedIndex();
|
|
193
|
+
};
|
|
194
|
+
|
|
185
195
|
// Delete key - request delete confirmation from parent
|
|
186
196
|
if (matchesKey(keyData, "delete")) {
|
|
187
197
|
const selected = this.#filteredSessions[this.#selectedIndex];
|
|
@@ -193,22 +203,22 @@ class SessionList implements Component {
|
|
|
193
203
|
|
|
194
204
|
// Up arrow
|
|
195
205
|
if (matchesKey(keyData, "up")) {
|
|
196
|
-
|
|
206
|
+
moveSelection(-1);
|
|
197
207
|
return;
|
|
198
208
|
}
|
|
199
209
|
// Down arrow
|
|
200
210
|
if (matchesKey(keyData, "down")) {
|
|
201
|
-
|
|
211
|
+
moveSelection(1);
|
|
202
212
|
return;
|
|
203
213
|
}
|
|
204
214
|
// Page up - jump up by maxVisible items
|
|
205
215
|
if (matchesKey(keyData, "pageUp")) {
|
|
206
|
-
|
|
216
|
+
moveSelection(-this.#maxVisible);
|
|
207
217
|
return;
|
|
208
218
|
}
|
|
209
219
|
// Page down - jump down by maxVisible items
|
|
210
220
|
if (matchesKey(keyData, "pageDown")) {
|
|
211
|
-
|
|
221
|
+
moveSelection(this.#maxVisible);
|
|
212
222
|
return;
|
|
213
223
|
}
|
|
214
224
|
// Enter
|
|
@@ -670,6 +670,7 @@ export interface StatusLinePreviewSettings {
|
|
|
670
670
|
segmentOptions?: StatusLineSegmentOptions;
|
|
671
671
|
previewHighlightSegment?: StatusLineSegmentId;
|
|
672
672
|
sessionAccent?: boolean;
|
|
673
|
+
maxRows?: number;
|
|
673
674
|
}
|
|
674
675
|
|
|
675
676
|
export interface SettingsCallbacks {
|
|
@@ -908,6 +909,18 @@ export class SettingsSelectorComponent extends Container {
|
|
|
908
909
|
this.callbacks.onStatusLinePreview?.({ separator, previewHighlightSegment: undefined });
|
|
909
910
|
this.#updateStatusPreview();
|
|
910
911
|
};
|
|
912
|
+
} else if (def.path === "statusLine.maxRows") {
|
|
913
|
+
onPreview = value => {
|
|
914
|
+
this.callbacks.onStatusLinePreview?.({ maxRows: Number(value) });
|
|
915
|
+
this.#updateStatusPreview();
|
|
916
|
+
};
|
|
917
|
+
onPreviewCancel = () => {
|
|
918
|
+
this.callbacks.onStatusLinePreview?.({
|
|
919
|
+
maxRows: settings.get("statusLine.maxRows"),
|
|
920
|
+
previewHighlightSegment: undefined,
|
|
921
|
+
});
|
|
922
|
+
this.#updateStatusPreview();
|
|
923
|
+
};
|
|
911
924
|
}
|
|
912
925
|
|
|
913
926
|
// Provide status line preview for theme selection
|