@oh-my-pi/pi-coding-agent 3.14.0 → 3.15.1
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 +89 -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/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 +518 -40
- 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-editor.ts +1 -0
- 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 +172 -223
- 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 +99 -13
- package/src/modes/interactive/theme/dark.json +3 -2
- package/src/modes/interactive/theme/defaults/alabaster.json +99 -0
- package/src/modes/interactive/theme/defaults/amethyst.json +103 -0
- package/src/modes/interactive/theme/defaults/anthracite.json +100 -0
- package/src/modes/interactive/theme/defaults/basalt.json +90 -0
- package/src/modes/interactive/theme/defaults/birch.json +101 -0
- package/src/modes/interactive/theme/defaults/dark-abyss.json +97 -0
- package/src/modes/interactive/theme/defaults/dark-arctic.json +111 -0
- package/src/modes/interactive/theme/defaults/dark-aurora.json +94 -0
- package/src/modes/interactive/theme/defaults/dark-catppuccin.json +106 -0
- package/src/modes/interactive/theme/defaults/dark-cavern.json +97 -0
- package/src/modes/interactive/theme/defaults/dark-copper.json +94 -0
- package/src/modes/interactive/theme/defaults/dark-cosmos.json +96 -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-eclipse.json +97 -0
- package/src/modes/interactive/theme/defaults/dark-ember.json +94 -0
- package/src/modes/interactive/theme/defaults/dark-equinox.json +96 -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-lavender.json +94 -0
- package/src/modes/interactive/theme/defaults/dark-lunar.json +95 -0
- package/src/modes/interactive/theme/defaults/dark-midnight.json +94 -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-nebula.json +96 -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-rainforest.json +97 -0
- package/src/modes/interactive/theme/defaults/dark-reef.json +97 -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-sakura.json +94 -0
- package/src/modes/interactive/theme/defaults/dark-slate.json +94 -0
- package/src/modes/interactive/theme/defaults/dark-solarized.json +96 -0
- package/src/modes/interactive/theme/defaults/dark-solstice.json +96 -0
- package/src/modes/interactive/theme/defaults/dark-starfall.json +97 -0
- package/src/modes/interactive/theme/defaults/dark-sunset.json +106 -0
- package/src/modes/interactive/theme/defaults/dark-swamp.json +96 -0
- package/src/modes/interactive/theme/defaults/dark-synthwave.json +102 -0
- package/src/modes/interactive/theme/defaults/dark-taiga.json +97 -0
- package/src/modes/interactive/theme/defaults/dark-terminal.json +94 -0
- package/src/modes/interactive/theme/defaults/dark-tokyo-night.json +108 -0
- package/src/modes/interactive/theme/defaults/dark-tundra.json +97 -0
- package/src/modes/interactive/theme/defaults/dark-twilight.json +97 -0
- package/src/modes/interactive/theme/defaults/dark-volcanic.json +97 -0
- package/src/modes/interactive/theme/defaults/graphite.json +99 -0
- package/src/modes/interactive/theme/defaults/index.ts +195 -0
- package/src/modes/interactive/theme/defaults/light-arctic.json +106 -0
- package/src/modes/interactive/theme/defaults/light-aurora-day.json +97 -0
- package/src/modes/interactive/theme/defaults/light-canyon.json +97 -0
- package/src/modes/interactive/theme/defaults/light-catppuccin.json +105 -0
- package/src/modes/interactive/theme/defaults/light-cirrus.json +96 -0
- package/src/modes/interactive/theme/defaults/light-coral.json +94 -0
- package/src/modes/interactive/theme/defaults/light-cyberpunk.json +103 -0
- package/src/modes/interactive/theme/defaults/light-dawn.json +96 -0
- package/src/modes/interactive/theme/defaults/light-dunes.json +97 -0
- package/src/modes/interactive/theme/defaults/light-eucalyptus.json +94 -0
- package/src/modes/interactive/theme/defaults/light-forest.json +107 -0
- package/src/modes/interactive/theme/defaults/light-frost.json +94 -0
- package/src/modes/interactive/theme/defaults/light-github.json +114 -0
- package/src/modes/interactive/theme/defaults/light-glacier.json +97 -0
- package/src/modes/interactive/theme/defaults/light-gruvbox.json +115 -0
- package/src/modes/interactive/theme/defaults/light-haze.json +96 -0
- package/src/modes/interactive/theme/defaults/light-honeycomb.json +94 -0
- package/src/modes/interactive/theme/defaults/light-lagoon.json +97 -0
- package/src/modes/interactive/theme/defaults/light-lavender.json +94 -0
- package/src/modes/interactive/theme/defaults/light-meadow.json +97 -0
- package/src/modes/interactive/theme/defaults/light-mint.json +94 -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-opal.json +97 -0
- package/src/modes/interactive/theme/defaults/light-orchard.json +97 -0
- package/src/modes/interactive/theme/defaults/light-paper.json +94 -0
- package/src/modes/interactive/theme/defaults/light-prism.json +96 -0
- package/src/modes/interactive/theme/defaults/light-retro.json +105 -0
- package/src/modes/interactive/theme/defaults/light-sand.json +94 -0
- package/src/modes/interactive/theme/defaults/light-savanna.json +97 -0
- package/src/modes/interactive/theme/defaults/light-solarized.json +101 -0
- package/src/modes/interactive/theme/defaults/light-soleil.json +96 -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/defaults/light-wetland.json +97 -0
- package/src/modes/interactive/theme/defaults/light-zenith.json +95 -0
- package/src/modes/interactive/theme/defaults/limestone.json +100 -0
- package/src/modes/interactive/theme/defaults/mahogany.json +104 -0
- package/src/modes/interactive/theme/defaults/marble.json +99 -0
- package/src/modes/interactive/theme/defaults/obsidian.json +90 -0
- package/src/modes/interactive/theme/defaults/onyx.json +90 -0
- package/src/modes/interactive/theme/defaults/pearl.json +99 -0
- package/src/modes/interactive/theme/defaults/porcelain.json +90 -0
- package/src/modes/interactive/theme/defaults/quartz.json +102 -0
- package/src/modes/interactive/theme/defaults/sandstone.json +101 -0
- package/src/modes/interactive/theme/defaults/titanium.json +89 -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
|
@@ -438,7 +438,11 @@ class TreeList implements Component {
|
|
|
438
438
|
// Build prefix with gutters at their correct positions
|
|
439
439
|
// Each gutter has a position (displayIndent where its connector was shown)
|
|
440
440
|
const connector =
|
|
441
|
-
flatNode.showConnector && !flatNode.isVirtualRootChild
|
|
441
|
+
flatNode.showConnector && !flatNode.isVirtualRootChild
|
|
442
|
+
? flatNode.isLast
|
|
443
|
+
? `${theme.boxSharp.bottomLeft}${theme.boxSharp.horizontal} `
|
|
444
|
+
: `${theme.boxSharp.teeRight}${theme.boxSharp.horizontal} `
|
|
445
|
+
: "";
|
|
442
446
|
const connectorPosition = connector ? displayIndent - 1 : -1;
|
|
443
447
|
|
|
444
448
|
// Build prefix char by char, placing gutters and connector at their positions
|
|
@@ -452,16 +456,16 @@ class TreeList implements Component {
|
|
|
452
456
|
const gutter = flatNode.gutters.find((g) => g.position === level);
|
|
453
457
|
if (gutter) {
|
|
454
458
|
if (posInLevel === 0) {
|
|
455
|
-
prefixChars.push(gutter.show ?
|
|
459
|
+
prefixChars.push(gutter.show ? theme.boxSharp.vertical : " ");
|
|
456
460
|
} else {
|
|
457
461
|
prefixChars.push(" ");
|
|
458
462
|
}
|
|
459
463
|
} else if (connector && level === connectorPosition) {
|
|
460
464
|
// Connector at this level
|
|
461
465
|
if (posInLevel === 0) {
|
|
462
|
-
prefixChars.push(flatNode.isLast ?
|
|
466
|
+
prefixChars.push(flatNode.isLast ? theme.boxSharp.bottomLeft : theme.boxSharp.teeRight);
|
|
463
467
|
} else if (posInLevel === 1) {
|
|
464
|
-
prefixChars.push(
|
|
468
|
+
prefixChars.push(theme.boxSharp.horizontal);
|
|
465
469
|
} else {
|
|
466
470
|
prefixChars.push(" ");
|
|
467
471
|
}
|
|
@@ -473,7 +477,7 @@ class TreeList implements Component {
|
|
|
473
477
|
|
|
474
478
|
// Active path marker - shown right before the entry text
|
|
475
479
|
const isOnActivePath = this.activePathIds.has(entry.id);
|
|
476
|
-
const pathMarker = isOnActivePath ? theme.fg("accent",
|
|
480
|
+
const pathMarker = isOnActivePath ? theme.fg("accent", `${theme.md.bullet} `) : "";
|
|
477
481
|
|
|
478
482
|
const label = flatNode.node.label ? theme.fg("warning", `[${flatNode.node.label}] `) : "";
|
|
479
483
|
const content = this.getEntryDisplayText(flatNode.node, isSelected);
|
|
@@ -816,7 +820,14 @@ export class TreeSelectorComponent extends Container {
|
|
|
816
820
|
this.addChild(new DynamicBorder());
|
|
817
821
|
this.addChild(new Text(theme.bold(" Session Tree"), 1, 0));
|
|
818
822
|
this.addChild(
|
|
819
|
-
new TruncatedText(
|
|
823
|
+
new TruncatedText(
|
|
824
|
+
theme.fg(
|
|
825
|
+
"muted",
|
|
826
|
+
" Up/Down: move. Left/Right: page. l: label. Ctrl+O/Shift+Ctrl+O: filter. Type to search",
|
|
827
|
+
),
|
|
828
|
+
0,
|
|
829
|
+
0,
|
|
830
|
+
),
|
|
820
831
|
);
|
|
821
832
|
this.addChild(new SearchLine(this.treeList));
|
|
822
833
|
this.addChild(new DynamicBorder());
|
|
@@ -38,13 +38,13 @@ export class TtsrNotificationComponent extends Container {
|
|
|
38
38
|
private rebuild(): void {
|
|
39
39
|
this.box.clear();
|
|
40
40
|
|
|
41
|
-
// Build header:
|
|
41
|
+
// Build header: warning symbol + rule name + rewind icon
|
|
42
42
|
const ruleNames = this.rules.map((r) => theme.bold(r.name)).join(", ");
|
|
43
43
|
const label = this.rules.length === 1 ? "rule" : "rules";
|
|
44
|
-
const header =
|
|
44
|
+
const header = `${theme.icon.warning} Injecting ${label}: ${ruleNames}`;
|
|
45
45
|
|
|
46
46
|
// Create header with rewind icon on the right
|
|
47
|
-
const rewindIcon =
|
|
47
|
+
const rewindIcon = theme.icon.rewind;
|
|
48
48
|
|
|
49
49
|
this.box.addChild(new Text(`${header} ${rewindIcon}`, 0, 0));
|
|
50
50
|
|
|
@@ -59,7 +59,7 @@ export class TtsrNotificationComponent extends Container {
|
|
|
59
59
|
// Truncate to first 2 lines
|
|
60
60
|
const lines = displayText.split("\n");
|
|
61
61
|
if (lines.length > 2) {
|
|
62
|
-
displayText = `${lines.slice(0, 2).join("\n")}
|
|
62
|
+
displayText = `${lines.slice(0, 2).join("\n")}${theme.format.ellipsis}`;
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type Component, visibleWidth } from "@oh-my-pi/pi-tui";
|
|
1
|
+
import { type Component, truncateToWidth, visibleWidth } from "@oh-my-pi/pi-tui";
|
|
2
2
|
import { APP_NAME } from "../../../config";
|
|
3
3
|
import { theme } from "../theme/theme";
|
|
4
4
|
|
|
@@ -80,7 +80,7 @@ export class WelcomeComponent implements Component {
|
|
|
80
80
|
|
|
81
81
|
// Right column separator
|
|
82
82
|
const separatorWidth = rightCol - 2; // padding on each side
|
|
83
|
-
const separator = ` ${theme.fg("dim",
|
|
83
|
+
const separator = ` ${theme.fg("dim", theme.boxRound.horizontal.repeat(separatorWidth))}`;
|
|
84
84
|
|
|
85
85
|
// Recent sessions content
|
|
86
86
|
const sessionLines: string[] = [];
|
|
@@ -89,7 +89,7 @@ export class WelcomeComponent implements Component {
|
|
|
89
89
|
} else {
|
|
90
90
|
for (const session of this.recentSessions.slice(0, 3)) {
|
|
91
91
|
sessionLines.push(
|
|
92
|
-
` ${theme.fg("dim",
|
|
92
|
+
` ${theme.fg("dim", `${theme.md.bullet} `)}${theme.fg("muted", session.name)}${theme.fg("dim", ` (${session.timeAgo})`)}`,
|
|
93
93
|
);
|
|
94
94
|
}
|
|
95
95
|
}
|
|
@@ -102,10 +102,10 @@ export class WelcomeComponent implements Component {
|
|
|
102
102
|
for (const server of this.lspServers) {
|
|
103
103
|
const icon =
|
|
104
104
|
server.status === "ready"
|
|
105
|
-
? theme.
|
|
105
|
+
? theme.styledSymbol("status.success", "success")
|
|
106
106
|
: server.status === "connecting"
|
|
107
|
-
? theme.
|
|
108
|
-
: theme.
|
|
107
|
+
? theme.styledSymbol("status.disabled", "warning")
|
|
108
|
+
: theme.styledSymbol("status.error", "error");
|
|
109
109
|
const exts = server.fileTypes.slice(0, 3).join(" ");
|
|
110
110
|
lspLines.push(` ${icon} ${theme.fg("muted", server.name)} ${theme.fg("dim", exts)}`);
|
|
111
111
|
}
|
|
@@ -127,21 +127,24 @@ export class WelcomeComponent implements Component {
|
|
|
127
127
|
];
|
|
128
128
|
|
|
129
129
|
// Border characters (dim)
|
|
130
|
-
const
|
|
131
|
-
const
|
|
132
|
-
const
|
|
133
|
-
const
|
|
134
|
-
const
|
|
135
|
-
const
|
|
130
|
+
const hChar = theme.boxRound.horizontal;
|
|
131
|
+
const h = theme.fg("dim", hChar);
|
|
132
|
+
const v = theme.fg("dim", theme.boxRound.vertical);
|
|
133
|
+
const tl = theme.fg("dim", theme.boxRound.topLeft);
|
|
134
|
+
const tr = theme.fg("dim", theme.boxRound.topRight);
|
|
135
|
+
const bl = theme.fg("dim", theme.boxRound.bottomLeft);
|
|
136
|
+
const br = theme.fg("dim", theme.boxRound.bottomRight);
|
|
136
137
|
|
|
137
138
|
const lines: string[] = [];
|
|
138
139
|
|
|
139
140
|
// Top border with embedded title
|
|
140
141
|
const title = ` ${APP_NAME} v${this.version} `;
|
|
141
|
-
const
|
|
142
|
-
const
|
|
142
|
+
const titlePrefixRaw = hChar.repeat(3);
|
|
143
|
+
const titleStyled = theme.fg("dim", titlePrefixRaw) + theme.fg("muted", title);
|
|
144
|
+
const titleVisLen = visibleWidth(titlePrefixRaw) + visibleWidth(title);
|
|
143
145
|
const afterTitle = boxWidth - 2 - titleVisLen;
|
|
144
|
-
|
|
146
|
+
const afterTitleText = afterTitle > 0 ? theme.fg("dim", hChar.repeat(afterTitle)) : "";
|
|
147
|
+
lines.push(tl + titleStyled + afterTitleText + tr);
|
|
145
148
|
|
|
146
149
|
// Content rows
|
|
147
150
|
const maxRows = Math.max(leftLines.length, rightLines.length);
|
|
@@ -152,7 +155,7 @@ export class WelcomeComponent implements Component {
|
|
|
152
155
|
}
|
|
153
156
|
|
|
154
157
|
// Bottom border
|
|
155
|
-
lines.push(bl + h.repeat(leftCol) + theme.fg("dim",
|
|
158
|
+
lines.push(bl + h.repeat(leftCol) + theme.fg("dim", theme.boxSharp.teeUp) + h.repeat(rightCol) + br);
|
|
156
159
|
|
|
157
160
|
return lines;
|
|
158
161
|
}
|
|
@@ -160,7 +163,9 @@ export class WelcomeComponent implements Component {
|
|
|
160
163
|
/** Center text within a given width */
|
|
161
164
|
private centerText(text: string, width: number): string {
|
|
162
165
|
const visLen = visibleWidth(text);
|
|
163
|
-
if (visLen >= width)
|
|
166
|
+
if (visLen >= width) {
|
|
167
|
+
return truncateToWidth(text, width, theme.format.ellipsis);
|
|
168
|
+
}
|
|
164
169
|
const leftPad = Math.floor((width - visLen) / 2);
|
|
165
170
|
const rightPad = width - visLen - leftPad;
|
|
166
171
|
return " ".repeat(leftPad) + text + " ".repeat(rightPad);
|
|
@@ -200,6 +205,9 @@ export class WelcomeComponent implements Component {
|
|
|
200
205
|
private fitToWidth(str: string, width: number): string {
|
|
201
206
|
const visLen = visibleWidth(str);
|
|
202
207
|
if (visLen > width) {
|
|
208
|
+
const ellipsis = theme.format.ellipsis;
|
|
209
|
+
const ellipsisWidth = visibleWidth(ellipsis);
|
|
210
|
+
const maxWidth = Math.max(0, width - ellipsisWidth);
|
|
203
211
|
let truncated = "";
|
|
204
212
|
let currentWidth = 0;
|
|
205
213
|
let inEscape = false;
|
|
@@ -208,12 +216,12 @@ export class WelcomeComponent implements Component {
|
|
|
208
216
|
if (inEscape) {
|
|
209
217
|
truncated += char;
|
|
210
218
|
if (char === "m") inEscape = false;
|
|
211
|
-
} else if (currentWidth <
|
|
219
|
+
} else if (currentWidth < maxWidth) {
|
|
212
220
|
truncated += char;
|
|
213
221
|
currentWidth++;
|
|
214
222
|
}
|
|
215
223
|
}
|
|
216
|
-
return `${truncated}
|
|
224
|
+
return `${truncated}${ellipsis}`;
|
|
217
225
|
}
|
|
218
226
|
return str + " ".repeat(width - visLen);
|
|
219
227
|
}
|
|
@@ -34,6 +34,7 @@ import type { TruncationResult } from "../../core/tools/truncate";
|
|
|
34
34
|
import { disableProvider, enableProvider } from "../../discovery";
|
|
35
35
|
import { getChangelogPath, parseChangelog } from "../../utils/changelog";
|
|
36
36
|
import { copyToClipboard, readImageFromClipboard } from "../../utils/clipboard";
|
|
37
|
+
import { registerAsyncCleanup } from "../cleanup";
|
|
37
38
|
import { ArminComponent } from "./components/armin";
|
|
38
39
|
import { AssistantMessageComponent } from "./components/assistant-message";
|
|
39
40
|
import { BashExecutionComponent } from "./components/bash-execution";
|
|
@@ -62,7 +63,9 @@ import {
|
|
|
62
63
|
getAvailableThemes,
|
|
63
64
|
getEditorTheme,
|
|
64
65
|
getMarkdownTheme,
|
|
66
|
+
getSymbolTheme,
|
|
65
67
|
onThemeChange,
|
|
68
|
+
setSymbolPreset,
|
|
66
69
|
setTheme,
|
|
67
70
|
type Theme,
|
|
68
71
|
theme,
|
|
@@ -115,6 +118,9 @@ export class InteractiveMode {
|
|
|
115
118
|
// Agent subscription unsubscribe function
|
|
116
119
|
private unsubscribe?: () => void;
|
|
117
120
|
|
|
121
|
+
// Signal cleanup unsubscribe function (for SIGINT/SIGTERM flush)
|
|
122
|
+
private cleanupUnsubscribe?: () => void;
|
|
123
|
+
|
|
118
124
|
// Track if editor is in bash mode (text starts with !)
|
|
119
125
|
private isBashMode = false;
|
|
120
126
|
|
|
@@ -174,6 +180,7 @@ export class InteractiveMode {
|
|
|
174
180
|
this.pendingMessagesContainer = new Container();
|
|
175
181
|
this.statusContainer = new Container();
|
|
176
182
|
this.editor = new CustomEditor(getEditorTheme());
|
|
183
|
+
this.editor.setUseTerminalCursor(true);
|
|
177
184
|
this.editorContainer = new Container();
|
|
178
185
|
this.editorContainer.addChild(this.editor);
|
|
179
186
|
this.statusLine = new StatusLineComponent(session);
|
|
@@ -198,6 +205,7 @@ export class InteractiveMode {
|
|
|
198
205
|
{ name: "new", description: "Start a new session" },
|
|
199
206
|
{ name: "compact", description: "Manually compact the session context" },
|
|
200
207
|
{ name: "resume", description: "Resume a different session" },
|
|
208
|
+
{ name: "exit", description: "Exit the application" },
|
|
201
209
|
];
|
|
202
210
|
|
|
203
211
|
// Load hide thinking block setting
|
|
@@ -233,6 +241,9 @@ export class InteractiveMode {
|
|
|
233
241
|
async init(): Promise<void> {
|
|
234
242
|
if (this.isInitialized) return;
|
|
235
243
|
|
|
244
|
+
// Register session manager flush for signal handlers (SIGINT, SIGTERM, SIGHUP)
|
|
245
|
+
this.cleanupUnsubscribe = registerAsyncCleanup(() => this.sessionManager.flush());
|
|
246
|
+
|
|
236
247
|
// Get current model info for welcome screen
|
|
237
248
|
const modelName = this.session.model?.name ?? "Unknown";
|
|
238
249
|
const providerName = this.session.model?.provider ?? "Unknown";
|
|
@@ -403,7 +414,9 @@ export class InteractiveMode {
|
|
|
403
414
|
this.pendingTools.clear();
|
|
404
415
|
|
|
405
416
|
this.chatContainer.addChild(new Spacer(1));
|
|
406
|
-
this.chatContainer.addChild(
|
|
417
|
+
this.chatContainer.addChild(
|
|
418
|
+
new Text(`${theme.fg("accent", `${theme.status.success} New session started`)}`, 1, 1),
|
|
419
|
+
);
|
|
407
420
|
this.ui.requestRender();
|
|
408
421
|
|
|
409
422
|
return { cancelled: false };
|
|
@@ -838,6 +851,11 @@ export class InteractiveMode {
|
|
|
838
851
|
this.editor.setText("");
|
|
839
852
|
return;
|
|
840
853
|
}
|
|
854
|
+
if (text === "/exit") {
|
|
855
|
+
this.editor.setText("");
|
|
856
|
+
void this.shutdown();
|
|
857
|
+
return;
|
|
858
|
+
}
|
|
841
859
|
|
|
842
860
|
// Handle bash command
|
|
843
861
|
if (text.startsWith("!")) {
|
|
@@ -908,9 +926,9 @@ export class InteractiveMode {
|
|
|
908
926
|
const registry = this.session.modelRegistry;
|
|
909
927
|
const smolModel = this.settingsManager.getModelRole("smol");
|
|
910
928
|
generateSessionTitle(text, registry, smolModel)
|
|
911
|
-
.then((title) => {
|
|
929
|
+
.then(async (title) => {
|
|
912
930
|
if (title) {
|
|
913
|
-
this.sessionManager.setSessionTitle(title);
|
|
931
|
+
await this.sessionManager.setSessionTitle(title);
|
|
914
932
|
setTerminalTitle(`omp: ${title}`);
|
|
915
933
|
}
|
|
916
934
|
})
|
|
@@ -951,7 +969,8 @@ export class InteractiveMode {
|
|
|
951
969
|
this.ui,
|
|
952
970
|
(spinner) => theme.fg("accent", spinner),
|
|
953
971
|
(text) => theme.fg("muted", text),
|
|
954
|
-
|
|
972
|
+
`Working${theme.format.ellipsis} (esc to interrupt)`,
|
|
973
|
+
getSymbolTheme().spinnerFrames,
|
|
955
974
|
);
|
|
956
975
|
this.statusContainer.addChild(this.loadingAnimation);
|
|
957
976
|
this.ui.requestRender();
|
|
@@ -1118,7 +1137,8 @@ export class InteractiveMode {
|
|
|
1118
1137
|
this.ui,
|
|
1119
1138
|
(spinner) => theme.fg("accent", spinner),
|
|
1120
1139
|
(text) => theme.fg("muted", text),
|
|
1121
|
-
`${reasonText}Auto-compacting
|
|
1140
|
+
`${reasonText}Auto-compacting${theme.format.ellipsis} (esc to cancel)`,
|
|
1141
|
+
getSymbolTheme().spinnerFrames,
|
|
1122
1142
|
);
|
|
1123
1143
|
this.statusContainer.addChild(this.autoCompactionLoader);
|
|
1124
1144
|
this.ui.requestRender();
|
|
@@ -1173,7 +1193,8 @@ export class InteractiveMode {
|
|
|
1173
1193
|
this.ui,
|
|
1174
1194
|
(spinner) => theme.fg("warning", spinner),
|
|
1175
1195
|
(text) => theme.fg("muted", text),
|
|
1176
|
-
`Retrying (${event.attempt}/${event.maxAttempts}) in ${delaySeconds}s
|
|
1196
|
+
`Retrying (${event.attempt}/${event.maxAttempts}) in ${delaySeconds}s${theme.format.ellipsis} (esc to cancel)`,
|
|
1197
|
+
getSymbolTheme().spinnerFrames,
|
|
1177
1198
|
);
|
|
1178
1199
|
this.statusContainer.addChild(this.retryLoader);
|
|
1179
1200
|
this.ui.requestRender();
|
|
@@ -1287,7 +1308,7 @@ export class InteractiveMode {
|
|
|
1287
1308
|
case "fileMention": {
|
|
1288
1309
|
// Render compact file mention display
|
|
1289
1310
|
for (const file of message.files) {
|
|
1290
|
-
const text = `${theme.fg("dim",
|
|
1311
|
+
const text = `${theme.fg("dim", `${theme.tree.hook} `)}${theme.fg("muted", "Read")} ${theme.fg("accent", file.path)} ${theme.fg("dim", `(${file.lineCount} lines)`)}`;
|
|
1291
1312
|
this.chatContainer.addChild(new Text(text, 0, 0));
|
|
1292
1313
|
}
|
|
1293
1314
|
break;
|
|
@@ -1434,6 +1455,9 @@ export class InteractiveMode {
|
|
|
1434
1455
|
* Emits shutdown event to hooks and tools, then exits.
|
|
1435
1456
|
*/
|
|
1436
1457
|
private async shutdown(): Promise<void> {
|
|
1458
|
+
// Flush pending session writes before shutdown
|
|
1459
|
+
await this.sessionManager.flush();
|
|
1460
|
+
|
|
1437
1461
|
// Emit shutdown event to hooks
|
|
1438
1462
|
const hookRunner = this.session.hookRunner;
|
|
1439
1463
|
if (hookRunner?.hasHandlers("session_shutdown")) {
|
|
@@ -1714,11 +1738,26 @@ export class InteractiveMode {
|
|
|
1714
1738
|
this.ui.requestRender();
|
|
1715
1739
|
}
|
|
1716
1740
|
},
|
|
1741
|
+
onStatusLinePreview: (settings) => {
|
|
1742
|
+
// Update status line with preview settings
|
|
1743
|
+
const currentSettings = this.settingsManager.getStatusLineSettings();
|
|
1744
|
+
this.statusLine.updateSettings({ ...currentSettings, ...settings });
|
|
1745
|
+
this.updateEditorTopBorder();
|
|
1746
|
+
this.ui.requestRender();
|
|
1747
|
+
},
|
|
1748
|
+
getStatusLinePreview: () => {
|
|
1749
|
+
// Return the rendered status line for inline preview
|
|
1750
|
+
const width = this.ui.getWidth();
|
|
1751
|
+
return this.statusLine.getTopBorder(width).content;
|
|
1752
|
+
},
|
|
1717
1753
|
onPluginsChanged: () => {
|
|
1718
1754
|
this.ui.requestRender();
|
|
1719
1755
|
},
|
|
1720
1756
|
onCancel: () => {
|
|
1721
1757
|
done();
|
|
1758
|
+
// Restore status line to saved settings
|
|
1759
|
+
this.statusLine.updateSettings(this.settingsManager.getStatusLineSettings());
|
|
1760
|
+
this.updateEditorTopBorder();
|
|
1722
1761
|
this.ui.requestRender();
|
|
1723
1762
|
},
|
|
1724
1763
|
},
|
|
@@ -1797,12 +1836,40 @@ export class InteractiveMode {
|
|
|
1797
1836
|
break;
|
|
1798
1837
|
case "theme": {
|
|
1799
1838
|
const result = setTheme(value as string, true);
|
|
1839
|
+
this.statusLine.invalidate();
|
|
1840
|
+
this.updateEditorTopBorder();
|
|
1800
1841
|
this.ui.invalidate();
|
|
1801
1842
|
if (!result.success) {
|
|
1802
1843
|
this.showError(`Failed to load theme "${value}": ${result.error}\nFell back to dark theme.`);
|
|
1803
1844
|
}
|
|
1804
1845
|
break;
|
|
1805
1846
|
}
|
|
1847
|
+
case "symbolPreset": {
|
|
1848
|
+
setSymbolPreset(value as "unicode" | "nerd" | "ascii");
|
|
1849
|
+
this.statusLine.invalidate();
|
|
1850
|
+
this.updateEditorTopBorder();
|
|
1851
|
+
this.ui.invalidate();
|
|
1852
|
+
break;
|
|
1853
|
+
}
|
|
1854
|
+
case "statusLinePreset":
|
|
1855
|
+
case "statusLineSeparator":
|
|
1856
|
+
case "statusLineShowHooks":
|
|
1857
|
+
case "statusLineSegments":
|
|
1858
|
+
case "statusLineModelThinking":
|
|
1859
|
+
case "statusLinePathAbbreviate":
|
|
1860
|
+
case "statusLinePathMaxLength":
|
|
1861
|
+
case "statusLinePathStripWorkPrefix":
|
|
1862
|
+
case "statusLineGitShowBranch":
|
|
1863
|
+
case "statusLineGitShowStaged":
|
|
1864
|
+
case "statusLineGitShowUnstaged":
|
|
1865
|
+
case "statusLineGitShowUntracked":
|
|
1866
|
+
case "statusLineTimeFormat":
|
|
1867
|
+
case "statusLineTimeShowSeconds": {
|
|
1868
|
+
this.statusLine.updateSettings(this.settingsManager.getStatusLineSettings());
|
|
1869
|
+
this.updateEditorTopBorder();
|
|
1870
|
+
this.ui.requestRender();
|
|
1871
|
+
break;
|
|
1872
|
+
}
|
|
1806
1873
|
|
|
1807
1874
|
// All other settings are handled by the definitions (get/set on SettingsManager)
|
|
1808
1875
|
// No additional side effects needed
|
|
@@ -1930,6 +1997,7 @@ export class InteractiveMode {
|
|
|
1930
1997
|
(spinner) => theme.fg("accent", spinner),
|
|
1931
1998
|
(text) => theme.fg("muted", text),
|
|
1932
1999
|
"Summarizing branch... (esc to cancel)",
|
|
2000
|
+
getSymbolTheme().spinnerFrames,
|
|
1933
2001
|
);
|
|
1934
2002
|
this.statusContainer.addChild(summaryLoader);
|
|
1935
2003
|
this.ui.requestRender();
|
|
@@ -2092,7 +2160,11 @@ export class InteractiveMode {
|
|
|
2092
2160
|
this.session.modelRegistry.refresh();
|
|
2093
2161
|
this.chatContainer.addChild(new Spacer(1));
|
|
2094
2162
|
this.chatContainer.addChild(
|
|
2095
|
-
new Text(
|
|
2163
|
+
new Text(
|
|
2164
|
+
theme.fg("success", `${theme.status.success} Successfully logged in to ${providerId}`),
|
|
2165
|
+
1,
|
|
2166
|
+
0,
|
|
2167
|
+
),
|
|
2096
2168
|
);
|
|
2097
2169
|
this.chatContainer.addChild(
|
|
2098
2170
|
new Text(theme.fg("dim", `Credentials saved to ${getAuthPath()}`), 1, 0),
|
|
@@ -2108,7 +2180,11 @@ export class InteractiveMode {
|
|
|
2108
2180
|
this.session.modelRegistry.refresh();
|
|
2109
2181
|
this.chatContainer.addChild(new Spacer(1));
|
|
2110
2182
|
this.chatContainer.addChild(
|
|
2111
|
-
new Text(
|
|
2183
|
+
new Text(
|
|
2184
|
+
theme.fg("success", `${theme.status.success} Successfully logged out of ${providerId}`),
|
|
2185
|
+
1,
|
|
2186
|
+
0,
|
|
2187
|
+
),
|
|
2112
2188
|
);
|
|
2113
2189
|
this.chatContainer.addChild(
|
|
2114
2190
|
new Text(theme.fg("dim", `Credentials removed from ${getAuthPath()}`), 1, 0),
|
|
@@ -2346,8 +2422,8 @@ export class InteractiveMode {
|
|
|
2346
2422
|
|
|
2347
2423
|
this.chatContainer.addChild(new Spacer(1));
|
|
2348
2424
|
this.chatContainer.addChild(new DynamicBorder());
|
|
2349
|
-
this.
|
|
2350
|
-
this.
|
|
2425
|
+
this.chatContainer.addChild(new Text(theme.bold(theme.fg("accent", "What's New")), 1, 0));
|
|
2426
|
+
this.chatContainer.addChild(new Spacer(1));
|
|
2351
2427
|
this.chatContainer.addChild(new Markdown(changelogMarkdown, 1, 1, getMarkdownTheme()));
|
|
2352
2428
|
this.chatContainer.addChild(new DynamicBorder());
|
|
2353
2429
|
this.ui.requestRender();
|
|
@@ -2420,7 +2496,9 @@ export class InteractiveMode {
|
|
|
2420
2496
|
this.pendingTools.clear();
|
|
2421
2497
|
|
|
2422
2498
|
this.chatContainer.addChild(new Spacer(1));
|
|
2423
|
-
this.chatContainer.addChild(
|
|
2499
|
+
this.chatContainer.addChild(
|
|
2500
|
+
new Text(`${theme.fg("accent", `${theme.status.success} New session started`)}`, 1, 1),
|
|
2501
|
+
);
|
|
2424
2502
|
this.ui.requestRender();
|
|
2425
2503
|
}
|
|
2426
2504
|
|
|
@@ -2451,7 +2529,11 @@ export class InteractiveMode {
|
|
|
2451
2529
|
|
|
2452
2530
|
this.chatContainer.addChild(new Spacer(1));
|
|
2453
2531
|
this.chatContainer.addChild(
|
|
2454
|
-
new Text(
|
|
2532
|
+
new Text(
|
|
2533
|
+
`${theme.fg("accent", `${theme.status.success} Debug log written`)}\n${theme.fg("muted", debugLogPath)}`,
|
|
2534
|
+
1,
|
|
2535
|
+
1,
|
|
2536
|
+
),
|
|
2455
2537
|
);
|
|
2456
2538
|
this.ui.requestRender();
|
|
2457
2539
|
}
|
|
@@ -2537,6 +2619,7 @@ export class InteractiveMode {
|
|
|
2537
2619
|
(spinner) => theme.fg("accent", spinner),
|
|
2538
2620
|
(text) => theme.fg("muted", text),
|
|
2539
2621
|
label,
|
|
2622
|
+
getSymbolTheme().spinnerFrames,
|
|
2540
2623
|
);
|
|
2541
2624
|
this.statusContainer.addChild(compactingLoader);
|
|
2542
2625
|
this.ui.requestRender();
|
|
@@ -2576,6 +2659,9 @@ export class InteractiveMode {
|
|
|
2576
2659
|
if (this.unsubscribe) {
|
|
2577
2660
|
this.unsubscribe();
|
|
2578
2661
|
}
|
|
2662
|
+
if (this.cleanupUnsubscribe) {
|
|
2663
|
+
this.cleanupUnsubscribe();
|
|
2664
|
+
}
|
|
2579
2665
|
if (this.isInitialized) {
|
|
2580
2666
|
this.ui.stop();
|
|
2581
2667
|
this.isInitialized = false;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"$schema": "https://raw.githubusercontent.com/
|
|
2
|
+
"$schema": "https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/theme-schema.json",
|
|
3
3
|
"name": "dark",
|
|
4
4
|
"vars": {
|
|
5
5
|
"cyan": "#0088fa",
|
|
@@ -91,7 +91,8 @@
|
|
|
91
91
|
"statusLineDirty": 178,
|
|
92
92
|
"statusLineUntracked": 39,
|
|
93
93
|
"statusLineOutput": 205,
|
|
94
|
-
"statusLineCost": 205
|
|
94
|
+
"statusLineCost": 205,
|
|
95
|
+
"statusLineSubagents": "accent"
|
|
95
96
|
},
|
|
96
97
|
"export": {
|
|
97
98
|
"pageBg": "#18181e",
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/theme-schema.json",
|
|
3
|
+
"name": "alabaster",
|
|
4
|
+
"vars": {
|
|
5
|
+
"alabaster": "#fdfcfb",
|
|
6
|
+
"chiseledBlack": "#1a1c20",
|
|
7
|
+
"shadowGray": "#505860",
|
|
8
|
+
"carvedDepth": "#6a7080",
|
|
9
|
+
"subtleShadow": "#e8e8ec",
|
|
10
|
+
"lightShadow": "#f0f0f4",
|
|
11
|
+
"accent": "#404850",
|
|
12
|
+
"warmShadow": "#8a7060",
|
|
13
|
+
"selectedBg": "#f0eff0",
|
|
14
|
+
"userMsgBg": "#f5f4f5",
|
|
15
|
+
"toolPendingBg": "#f3f3f8",
|
|
16
|
+
"toolSuccessBg": "#f4f5f4",
|
|
17
|
+
"toolErrorBg": "#f8f3f3",
|
|
18
|
+
"customMsgBg": "#f6f4f7"
|
|
19
|
+
},
|
|
20
|
+
"colors": {
|
|
21
|
+
"accent": "shadowGray",
|
|
22
|
+
"border": "subtleShadow",
|
|
23
|
+
"borderAccent": "shadowGray",
|
|
24
|
+
"borderMuted": "lightShadow",
|
|
25
|
+
"success": "#405840",
|
|
26
|
+
"error": "#704040",
|
|
27
|
+
"warning": "#806850",
|
|
28
|
+
"muted": "carvedDepth",
|
|
29
|
+
"dim": "#909098",
|
|
30
|
+
"text": "",
|
|
31
|
+
"thinkingText": "carvedDepth",
|
|
32
|
+
|
|
33
|
+
"selectedBg": "selectedBg",
|
|
34
|
+
"userMessageBg": "userMsgBg",
|
|
35
|
+
"userMessageText": "",
|
|
36
|
+
"customMessageBg": "customMsgBg",
|
|
37
|
+
"customMessageText": "",
|
|
38
|
+
"customMessageLabel": "shadowGray",
|
|
39
|
+
"toolPendingBg": "toolPendingBg",
|
|
40
|
+
"toolSuccessBg": "toolSuccessBg",
|
|
41
|
+
"toolErrorBg": "toolErrorBg",
|
|
42
|
+
"toolTitle": "",
|
|
43
|
+
"toolOutput": "carvedDepth",
|
|
44
|
+
|
|
45
|
+
"mdHeading": "chiseledBlack",
|
|
46
|
+
"mdLink": "shadowGray",
|
|
47
|
+
"mdLinkUrl": "carvedDepth",
|
|
48
|
+
"mdCode": "accent",
|
|
49
|
+
"mdCodeBlock": "shadowGray",
|
|
50
|
+
"mdCodeBlockBorder": "subtleShadow",
|
|
51
|
+
"mdQuote": "carvedDepth",
|
|
52
|
+
"mdQuoteBorder": "subtleShadow",
|
|
53
|
+
"mdHr": "subtleShadow",
|
|
54
|
+
"mdListBullet": "shadowGray",
|
|
55
|
+
|
|
56
|
+
"toolDiffAdded": "#405840",
|
|
57
|
+
"toolDiffRemoved": "#704040",
|
|
58
|
+
"toolDiffContext": "carvedDepth",
|
|
59
|
+
|
|
60
|
+
"syntaxComment": "#707880",
|
|
61
|
+
"syntaxKeyword": "#303840",
|
|
62
|
+
"syntaxFunction": "chiseledBlack",
|
|
63
|
+
"syntaxVariable": "chiseledBlack",
|
|
64
|
+
"syntaxString": "warmShadow",
|
|
65
|
+
"syntaxNumber": "shadowGray",
|
|
66
|
+
"syntaxType": "#303840",
|
|
67
|
+
"syntaxOperator": "#404850",
|
|
68
|
+
"syntaxPunctuation": "#505860",
|
|
69
|
+
|
|
70
|
+
"thinkingOff": "#c0c0c8",
|
|
71
|
+
"thinkingMinimal": "#a0a0a8",
|
|
72
|
+
"thinkingLow": "#808090",
|
|
73
|
+
"thinkingMedium": "#606870",
|
|
74
|
+
"thinkingHigh": "#505860",
|
|
75
|
+
"thinkingXhigh": "#303840",
|
|
76
|
+
|
|
77
|
+
"bashMode": "#405840",
|
|
78
|
+
|
|
79
|
+
"statusLineBg": "#ececf0",
|
|
80
|
+
"statusLineSep": "#a0a0a8",
|
|
81
|
+
"statusLineModel": "#505860",
|
|
82
|
+
"statusLinePath": "#404850",
|
|
83
|
+
"statusLineGitClean": "#305030",
|
|
84
|
+
"statusLineGitDirty": "#806030",
|
|
85
|
+
"statusLineContext": "#404860",
|
|
86
|
+
"statusLineSpend": "#405050",
|
|
87
|
+
"statusLineStaged": 28,
|
|
88
|
+
"statusLineDirty": 136,
|
|
89
|
+
"statusLineUntracked": 31,
|
|
90
|
+
"statusLineOutput": 133,
|
|
91
|
+
"statusLineCost": 133,
|
|
92
|
+
"statusLineSubagents": "shadowGray"
|
|
93
|
+
},
|
|
94
|
+
"export": {
|
|
95
|
+
"pageBg": "#fdfcfb",
|
|
96
|
+
"cardBg": "#ffffff",
|
|
97
|
+
"infoBg": "#faf9f8"
|
|
98
|
+
}
|
|
99
|
+
}
|