@oh-my-pi/pi-coding-agent 12.7.6 → 12.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 +37 -37
- package/README.md +9 -1052
- package/package.json +7 -7
- package/src/cli/args.ts +1 -0
- package/src/cli/update-cli.ts +49 -35
- package/src/cli/web-search-cli.ts +3 -2
- package/src/commands/web-search.ts +1 -0
- package/src/config/model-registry.ts +6 -0
- package/src/config/settings-schema.ts +25 -3
- package/src/config/settings.ts +1 -0
- package/src/extensibility/extensions/wrapper.ts +20 -13
- package/src/extensibility/slash-commands.ts +12 -91
- package/src/lsp/client.ts +24 -27
- package/src/lsp/index.ts +92 -42
- package/src/mcp/config-writer.ts +33 -0
- package/src/mcp/config.ts +6 -1
- package/src/mcp/types.ts +1 -0
- package/src/modes/components/custom-editor.ts +8 -5
- package/src/modes/components/settings-defs.ts +2 -1
- package/src/modes/controllers/command-controller.ts +12 -6
- package/src/modes/controllers/input-controller.ts +21 -186
- package/src/modes/controllers/mcp-command-controller.ts +60 -3
- package/src/modes/interactive-mode.ts +2 -2
- package/src/modes/types.ts +1 -1
- package/src/sdk.ts +23 -1
- package/src/secrets/index.ts +116 -0
- package/src/secrets/obfuscator.ts +269 -0
- package/src/secrets/regex.ts +21 -0
- package/src/session/agent-session.ts +143 -21
- package/src/session/compaction/branch-summarization.ts +2 -2
- package/src/session/compaction/compaction.ts +10 -3
- package/src/session/compaction/utils.ts +25 -1
- package/src/slash-commands/builtin-registry.ts +419 -0
- package/src/web/scrapers/github.ts +50 -12
- package/src/web/search/index.ts +5 -5
- package/src/web/search/provider.ts +13 -2
- package/src/web/search/providers/brave.ts +165 -0
- package/src/web/search/types.ts +1 -1
- package/docs/compaction.md +0 -436
- package/docs/config-usage.md +0 -176
- package/docs/custom-tools.md +0 -585
- package/docs/environment-variables.md +0 -257
- package/docs/extension-loading.md +0 -106
- package/docs/extensions.md +0 -1342
- package/docs/fs-scan-cache-architecture.md +0 -50
- package/docs/hooks.md +0 -906
- package/docs/models.md +0 -234
- package/docs/python-repl.md +0 -110
- package/docs/rpc.md +0 -1173
- package/docs/sdk.md +0 -1039
- package/docs/session-tree-plan.md +0 -84
- package/docs/session.md +0 -368
- package/docs/skills.md +0 -254
- package/docs/theme.md +0 -696
- package/docs/tree.md +0 -206
- package/docs/tui.md +0 -487
package/docs/theme.md
DELETED
|
@@ -1,696 +0,0 @@
|
|
|
1
|
-
> omp can create themes. Ask it to build one for your use case.
|
|
2
|
-
|
|
3
|
-
# OMP Coding Agent Themes
|
|
4
|
-
|
|
5
|
-
Themes allow you to customize the colors used throughout the coding agent TUI.
|
|
6
|
-
|
|
7
|
-
## Color Tokens
|
|
8
|
-
|
|
9
|
-
Every theme must define all color tokens. There are no optional colors.
|
|
10
|
-
|
|
11
|
-
### Core UI (11 colors)
|
|
12
|
-
|
|
13
|
-
| Token | Purpose | Examples |
|
|
14
|
-
| -------------- | --------------------- | ------------------------------------ |
|
|
15
|
-
| `accent` | Primary accent color | Logo, selected items, cursor (›) |
|
|
16
|
-
| `border` | Normal borders | Selector borders, horizontal lines |
|
|
17
|
-
| `borderAccent` | Highlighted borders | Changelog borders, special panels |
|
|
18
|
-
| `borderMuted` | Subtle borders | Editor borders, secondary separators |
|
|
19
|
-
| `success` | Success states | Success messages, diff additions |
|
|
20
|
-
| `error` | Error states | Error messages, diff deletions |
|
|
21
|
-
| `warning` | Warning states | Warning messages |
|
|
22
|
-
| `muted` | Secondary/dimmed text | Metadata, descriptions, output |
|
|
23
|
-
| `dim` | Very dimmed text | Less important info, placeholders |
|
|
24
|
-
| `text` | Default text color | Main content (usually `""`) |
|
|
25
|
-
| `thinkingText` | Thinking block text | Assistant reasoning traces |
|
|
26
|
-
|
|
27
|
-
### Backgrounds & Content Text (11 colors)
|
|
28
|
-
|
|
29
|
-
| Token | Purpose |
|
|
30
|
-
| -------------------- | ----------------------------------------------------------------- |
|
|
31
|
-
| `selectedBg` | Selected/active line background (e.g., tree selector) |
|
|
32
|
-
| `userMessageBg` | User message background |
|
|
33
|
-
| `userMessageText` | User message text color |
|
|
34
|
-
| `customMessageBg` | Hook custom message background |
|
|
35
|
-
| `customMessageText` | Hook custom message text color |
|
|
36
|
-
| `customMessageLabel` | Hook custom message label/type text |
|
|
37
|
-
| `toolPendingBg` | Tool execution box (pending state) |
|
|
38
|
-
| `toolSuccessBg` | Tool execution box (success state) |
|
|
39
|
-
| `toolErrorBg` | Tool execution box (error state) |
|
|
40
|
-
| `toolTitle` | Tool execution title/heading (e.g., `$ command`, `read file.txt`) |
|
|
41
|
-
| `toolOutput` | Tool execution output text |
|
|
42
|
-
|
|
43
|
-
### Markdown (10 colors)
|
|
44
|
-
|
|
45
|
-
| Token | Purpose |
|
|
46
|
-
| ------------------- | ----------------------------- |
|
|
47
|
-
| `mdHeading` | Heading text (`#`, `##`, etc) |
|
|
48
|
-
| `mdLink` | Link text |
|
|
49
|
-
| `mdLinkUrl` | Link URL (in parentheses) |
|
|
50
|
-
| `mdCode` | Inline code (backticks) |
|
|
51
|
-
| `mdCodeBlock` | Code block content |
|
|
52
|
-
| `mdCodeBlockBorder` | Code block fences (```) |
|
|
53
|
-
| `mdQuote` | Blockquote text |
|
|
54
|
-
| `mdQuoteBorder` | Blockquote border (`│`) |
|
|
55
|
-
| `mdHr` | Horizontal rule (`---`) |
|
|
56
|
-
| `mdListBullet` | List bullets/numbers |
|
|
57
|
-
|
|
58
|
-
### Tool Diffs (3 colors)
|
|
59
|
-
|
|
60
|
-
| Token | Purpose |
|
|
61
|
-
| ----------------- | --------------------------- |
|
|
62
|
-
| `toolDiffAdded` | Added lines in tool diffs |
|
|
63
|
-
| `toolDiffRemoved` | Removed lines in tool diffs |
|
|
64
|
-
| `toolDiffContext` | Context lines in tool diffs |
|
|
65
|
-
|
|
66
|
-
Note: Diff colors are specific to tool execution boxes and must work with tool background colors.
|
|
67
|
-
|
|
68
|
-
### Syntax Highlighting (9 colors)
|
|
69
|
-
|
|
70
|
-
Used for native syntax highlighting in tool output and editors:
|
|
71
|
-
|
|
72
|
-
| Token | Purpose |
|
|
73
|
-
| ------------------- | -------------------------------- |
|
|
74
|
-
| `syntaxComment` | Comments |
|
|
75
|
-
| `syntaxKeyword` | Keywords (`if`, `function`, etc) |
|
|
76
|
-
| `syntaxFunction` | Function names |
|
|
77
|
-
| `syntaxVariable` | Variable names |
|
|
78
|
-
| `syntaxString` | String literals |
|
|
79
|
-
| `syntaxNumber` | Number literals |
|
|
80
|
-
| `syntaxType` | Type names |
|
|
81
|
-
| `syntaxOperator` | Operators (`+`, `-`, etc) |
|
|
82
|
-
| `syntaxPunctuation` | Punctuation (`;`, `,`, etc) |
|
|
83
|
-
|
|
84
|
-
### Thinking Level Borders (6 colors)
|
|
85
|
-
|
|
86
|
-
Editor border colors that indicate the current thinking/reasoning level:
|
|
87
|
-
|
|
88
|
-
| Token | Purpose |
|
|
89
|
-
| ----------------- | ------------------------------------------ |
|
|
90
|
-
| `thinkingOff` | Border when thinking is off (most subtle) |
|
|
91
|
-
| `thinkingMinimal` | Border for minimal thinking |
|
|
92
|
-
| `thinkingLow` | Border for low thinking |
|
|
93
|
-
| `thinkingMedium` | Border for medium thinking |
|
|
94
|
-
| `thinkingHigh` | Border for high thinking |
|
|
95
|
-
| `thinkingXhigh` | Border for xhigh thinking (most prominent) |
|
|
96
|
-
|
|
97
|
-
These create a visual hierarchy: off → minimal → low → medium → high → xhigh
|
|
98
|
-
|
|
99
|
-
### Mode Borders (2 colors)
|
|
100
|
-
|
|
101
|
-
| Token | Purpose |
|
|
102
|
-
| ------------ | ------------------------------------------------ |
|
|
103
|
-
| `bashMode` | Editor border color when in bash mode (! prefix) |
|
|
104
|
-
| `pythonMode` | Editor border color when in python mode (>>>) |
|
|
105
|
-
|
|
106
|
-
### Status Line (14 colors)
|
|
107
|
-
|
|
108
|
-
| Token | Purpose |
|
|
109
|
-
| --------------------- | --------------------------------------- |
|
|
110
|
-
| `statusLineBg` | Status line background |
|
|
111
|
-
| `statusLineSep` | Separators between status line segments |
|
|
112
|
-
| `statusLineModel` | Model segment text |
|
|
113
|
-
| `statusLinePath` | Working directory segment |
|
|
114
|
-
| `statusLineGitClean` | Git segment (clean) |
|
|
115
|
-
| `statusLineGitDirty` | Git segment (dirty) |
|
|
116
|
-
| `statusLineContext` | Context window usage segment |
|
|
117
|
-
| `statusLineSpend` | Token input/total segment |
|
|
118
|
-
| `statusLineStaged` | Git staged count |
|
|
119
|
-
| `statusLineDirty` | Git unstaged count |
|
|
120
|
-
| `statusLineUntracked` | Git untracked count |
|
|
121
|
-
| `statusLineOutput` | Token output/cache output segment |
|
|
122
|
-
| `statusLineCost` | Cost segment |
|
|
123
|
-
| `statusLineSubagents` | Subagent count segment |
|
|
124
|
-
|
|
125
|
-
**Total: 66 color tokens** (all required)
|
|
126
|
-
|
|
127
|
-
### HTML Export Colors (optional)
|
|
128
|
-
|
|
129
|
-
The `export` section is optional and controls colors used when exporting sessions to HTML via `/export`. If not specified, these colors are automatically derived from `userMessageBg` based on luminance detection.
|
|
130
|
-
|
|
131
|
-
| Token | Purpose |
|
|
132
|
-
| -------- | ------------------------------------------------------------- |
|
|
133
|
-
| `pageBg` | Page background color |
|
|
134
|
-
| `cardBg` | Card/container background (headers, stats boxes) |
|
|
135
|
-
| `infoBg` | Info sections background (system prompt, notices, compaction) |
|
|
136
|
-
|
|
137
|
-
Example:
|
|
138
|
-
|
|
139
|
-
```json
|
|
140
|
-
{
|
|
141
|
-
"export": {
|
|
142
|
-
"pageBg": "#18181e",
|
|
143
|
-
"cardBg": "#1e1e24",
|
|
144
|
-
"infoBg": "#3c3728"
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
## Theme Format
|
|
150
|
-
|
|
151
|
-
Themes are defined in JSON files with the following structure:
|
|
152
|
-
|
|
153
|
-
```json
|
|
154
|
-
{
|
|
155
|
-
"$schema": "https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/modes/theme/theme-schema.json",
|
|
156
|
-
"name": "my-theme",
|
|
157
|
-
"vars": {
|
|
158
|
-
"blue": "#0066cc",
|
|
159
|
-
"gray": 242,
|
|
160
|
-
"brightCyan": 51
|
|
161
|
-
},
|
|
162
|
-
"colors": {
|
|
163
|
-
"accent": "blue",
|
|
164
|
-
"muted": "gray",
|
|
165
|
-
"thinkingText": "gray",
|
|
166
|
-
"text": "",
|
|
167
|
-
...
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
## Symbols
|
|
173
|
-
|
|
174
|
-
Themes can also customize specific UI symbols (icons, separators, bullets, etc.). Use `symbols.preset` (`unicode`, `nerd`, `ascii`) to set a theme default (overridden by the `symbolPreset` setting), and `symbols.overrides` to override individual keys.
|
|
175
|
-
|
|
176
|
-
Example:
|
|
177
|
-
|
|
178
|
-
```json
|
|
179
|
-
{
|
|
180
|
-
"symbols": {
|
|
181
|
-
"preset": "ascii",
|
|
182
|
-
"overrides": {
|
|
183
|
-
"icon.model": "[M]",
|
|
184
|
-
"sep.powerlineLeft": ">",
|
|
185
|
-
"sep.powerlineRight": "<"
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
Symbol keys by category:
|
|
192
|
-
|
|
193
|
-
- Status: `status.success`, `status.error`, `status.warning`, `status.info`, `status.pending`, `status.disabled`, `status.enabled`, `status.running`, `status.shadowed`, `status.aborted`
|
|
194
|
-
- Navigation: `nav.cursor`, `nav.selected`, `nav.expand`, `nav.collapse`, `nav.back`
|
|
195
|
-
- Tree: `tree.branch`, `tree.last`, `tree.vertical`, `tree.horizontal`, `tree.hook`
|
|
196
|
-
- Boxes (rounded): `boxRound.topLeft`, `boxRound.topRight`, `boxRound.bottomLeft`, `boxRound.bottomRight`, `boxRound.horizontal`, `boxRound.vertical`
|
|
197
|
-
- Boxes (sharp): `boxSharp.topLeft`, `boxSharp.topRight`, `boxSharp.bottomLeft`, `boxSharp.bottomRight`, `boxSharp.horizontal`, `boxSharp.vertical`, `boxSharp.cross`, `boxSharp.teeDown`, `boxSharp.teeUp`, `boxSharp.teeRight`, `boxSharp.teeLeft`
|
|
198
|
-
- Separators: `sep.powerline`, `sep.powerlineThin`, `sep.powerlineLeft`, `sep.powerlineRight`, `sep.powerlineThinLeft`, `sep.powerlineThinRight`, `sep.block`, `sep.space`, `sep.asciiLeft`, `sep.asciiRight`, `sep.dot`, `sep.slash`, `sep.pipe`
|
|
199
|
-
- Icons: `icon.model`, `icon.plan`, `icon.folder`, `icon.file`, `icon.git`, `icon.branch`, `icon.tokens`, `icon.context`, `icon.cost`, `icon.time`, `icon.pi`, `icon.agents`, `icon.cache`, `icon.input`, `icon.output`, `icon.host`, `icon.session`, `icon.package`, `icon.warning`, `icon.rewind`, `icon.auto`, `icon.extensionSkill`, `icon.extensionTool`, `icon.extensionSlashCommand`, `icon.extensionMcp`, `icon.extensionRule`, `icon.extensionHook`, `icon.extensionPrompt`, `icon.extensionContextFile`, `icon.extensionInstruction`
|
|
200
|
-
- Thinking: `thinking.minimal`, `thinking.low`, `thinking.medium`, `thinking.high`, `thinking.xhigh`
|
|
201
|
-
- Checkboxes: `checkbox.checked`, `checkbox.unchecked`
|
|
202
|
-
- Formatting: `format.bullet`, `format.dash`, `format.bracketLeft`, `format.bracketRight`
|
|
203
|
-
- Markdown: `md.quoteBorder`, `md.hrChar`, `md.bullet`
|
|
204
|
-
- Language icons: `lang.default`, `lang.typescript`, `lang.javascript`, `lang.python`, `lang.rust`, `lang.go`, `lang.java`, `lang.c`, `lang.cpp`, `lang.csharp`, `lang.ruby`, `lang.php`, `lang.swift`, `lang.kotlin`, `lang.shell`, `lang.html`, `lang.css`, `lang.json`, `lang.yaml`, `lang.markdown`, `lang.sql`, `lang.docker`, `lang.lua`, `lang.text`, `lang.env`, `lang.toml`, `lang.xml`, `lang.ini`, `lang.conf`, `lang.log`, `lang.csv`, `lang.tsv`, `lang.image`, `lang.pdf`, `lang.archive`, `lang.binary`
|
|
205
|
-
- Settings tabs: `tab.display`, `tab.agent`, `tab.input`, `tab.tools`, `tab.config`, `tab.services`, `tab.bash`, `tab.lsp`, `tab.ttsr`, `tab.status`
|
|
206
|
-
|
|
207
|
-
### Color Values
|
|
208
|
-
|
|
209
|
-
Four formats are supported:
|
|
210
|
-
|
|
211
|
-
1. **Hex colors**: `"#ff0000"` (6-digit hex RGB)
|
|
212
|
-
2. **256-color palette**: `39` (number 0-255, xterm 256-color palette)
|
|
213
|
-
3. **Color references**: `"blue"` (must be defined in `vars`)
|
|
214
|
-
4. **Terminal default**: `""` (empty string, uses terminal's default color)
|
|
215
|
-
|
|
216
|
-
### The `vars` Section
|
|
217
|
-
|
|
218
|
-
The optional `vars` section allows you to define reusable colors:
|
|
219
|
-
|
|
220
|
-
```json
|
|
221
|
-
{
|
|
222
|
-
"vars": {
|
|
223
|
-
"nord0": "#2E3440",
|
|
224
|
-
"nord1": "#3B4252",
|
|
225
|
-
"nord8": "#88C0D0",
|
|
226
|
-
"brightBlue": 39
|
|
227
|
-
},
|
|
228
|
-
"colors": {
|
|
229
|
-
"accent": "nord8",
|
|
230
|
-
"muted": "nord1",
|
|
231
|
-
"mdLink": "brightBlue"
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
```
|
|
235
|
-
|
|
236
|
-
Benefits:
|
|
237
|
-
|
|
238
|
-
- Reuse colors across multiple tokens
|
|
239
|
-
- Easier to maintain theme consistency
|
|
240
|
-
- Can reference standard color palettes
|
|
241
|
-
|
|
242
|
-
Variables can be hex colors (`"#ff0000"`), 256-color indices (`42`), or references to other variables.
|
|
243
|
-
|
|
244
|
-
### Terminal Default (empty string)
|
|
245
|
-
|
|
246
|
-
Use `""` (empty string) to inherit the terminal's default foreground/background color:
|
|
247
|
-
|
|
248
|
-
```json
|
|
249
|
-
{
|
|
250
|
-
"colors": {
|
|
251
|
-
"text": "" // Uses terminal's default text color
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
```
|
|
255
|
-
|
|
256
|
-
This is useful for:
|
|
257
|
-
|
|
258
|
-
- Main text color (adapts to user's terminal theme)
|
|
259
|
-
- Creating themes that blend with terminal appearance
|
|
260
|
-
|
|
261
|
-
## Built-in Themes
|
|
262
|
-
|
|
263
|
-
OMP ships with `dark` (default), `light`, and 90+ curated themes under `src/modes/theme/defaults/`. Examples include:
|
|
264
|
-
|
|
265
|
-
- **Dark themes**: `dark-aurora`, `dark-gruvbox`, `dark-nord`, `dark-tokyo-night`, `dark-catppuccin`, `dark-dracula`, `dark-solarized`, `dark-github`, `dark-monokai`, `dark-synthwave`
|
|
266
|
-
- **Light themes**: `light-solarized`, `light-gruvbox`, `light-github`, `light-catppuccin`, `light-paper`, `light-dawn`, `light-frost`
|
|
267
|
-
- **Neutral/material**: `graphite`, `obsidian`, `onyx`, `titanium`, `marble`, `pearl`, `alabaster`, `anthracite`
|
|
268
|
-
|
|
269
|
-
## Selecting a Theme
|
|
270
|
-
|
|
271
|
-
Themes are configured in the Settings UI (Display → Theme) or via the config CLI:
|
|
272
|
-
|
|
273
|
-
```bash
|
|
274
|
-
omp config set theme dark
|
|
275
|
-
```
|
|
276
|
-
|
|
277
|
-
On first run, OMP uses the terminal background reported by `COLORFGBG` and falls back to `dark` if unavailable.
|
|
278
|
-
|
|
279
|
-
## Custom Themes
|
|
280
|
-
|
|
281
|
-
### Theme Locations
|
|
282
|
-
|
|
283
|
-
Custom themes are loaded from `~/.omp/agent/themes/*.json` by default, or from `$PI_CODING_AGENT_DIR/themes` if that environment variable is set.
|
|
284
|
-
|
|
285
|
-
### Creating a Custom Theme
|
|
286
|
-
|
|
287
|
-
1. **Create theme directory:**
|
|
288
|
-
|
|
289
|
-
```bash
|
|
290
|
-
mkdir -p "${PI_CODING_AGENT_DIR:-~/.omp/agent}/themes"
|
|
291
|
-
```
|
|
292
|
-
|
|
293
|
-
2. **Create theme file:**
|
|
294
|
-
|
|
295
|
-
```bash
|
|
296
|
-
vim "${PI_CODING_AGENT_DIR:-~/.omp/agent}/themes/my-theme.json"
|
|
297
|
-
```
|
|
298
|
-
|
|
299
|
-
3. **Define all colors (see the schema for the full list; snippet below shows structure):**
|
|
300
|
-
|
|
301
|
-
```json
|
|
302
|
-
{
|
|
303
|
-
"$schema": "https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/modes/theme/theme-schema.json",
|
|
304
|
-
"name": "my-theme",
|
|
305
|
-
"vars": {
|
|
306
|
-
"primary": "#00aaff",
|
|
307
|
-
"secondary": 242,
|
|
308
|
-
"brightGreen": 46
|
|
309
|
-
},
|
|
310
|
-
"colors": {
|
|
311
|
-
"accent": "primary",
|
|
312
|
-
"border": "primary",
|
|
313
|
-
"borderAccent": "#00ffff",
|
|
314
|
-
"borderMuted": "secondary",
|
|
315
|
-
"success": "brightGreen",
|
|
316
|
-
"error": "#ff0000",
|
|
317
|
-
"warning": "#ffff00",
|
|
318
|
-
"muted": "secondary",
|
|
319
|
-
"text": "",
|
|
320
|
-
|
|
321
|
-
"userMessageBg": "#2d2d30",
|
|
322
|
-
"userMessageText": "",
|
|
323
|
-
"toolPendingBg": "#1e1e2e",
|
|
324
|
-
"toolSuccessBg": "#1e2e1e",
|
|
325
|
-
"toolErrorBg": "#2e1e1e",
|
|
326
|
-
"toolTitle": "",
|
|
327
|
-
"toolOutput": "",
|
|
328
|
-
// ...
|
|
329
|
-
|
|
330
|
-
"mdHeading": "#ffaa00",
|
|
331
|
-
"mdLink": "primary",
|
|
332
|
-
"mdCode": "#00ffff",
|
|
333
|
-
"mdCodeBlock": "#00ff00",
|
|
334
|
-
"mdCodeBlockBorder": "secondary",
|
|
335
|
-
"mdQuote": "secondary",
|
|
336
|
-
"mdQuoteBorder": "secondary",
|
|
337
|
-
"mdHr": "secondary",
|
|
338
|
-
"mdListBullet": "#00ffff",
|
|
339
|
-
|
|
340
|
-
"toolDiffAdded": "#00ff00",
|
|
341
|
-
"toolDiffRemoved": "#ff0000",
|
|
342
|
-
"toolDiffContext": "secondary",
|
|
343
|
-
|
|
344
|
-
"syntaxComment": "secondary",
|
|
345
|
-
"syntaxKeyword": "primary",
|
|
346
|
-
"syntaxFunction": "#00aaff",
|
|
347
|
-
"syntaxVariable": "#ffaa00",
|
|
348
|
-
"syntaxString": "#00ff00",
|
|
349
|
-
"syntaxNumber": "#ff00ff",
|
|
350
|
-
"syntaxType": "#00aaff",
|
|
351
|
-
"syntaxOperator": "primary",
|
|
352
|
-
"syntaxPunctuation": "secondary",
|
|
353
|
-
|
|
354
|
-
"thinkingOff": "secondary",
|
|
355
|
-
"thinkingMinimal": "primary",
|
|
356
|
-
"thinkingLow": "#00aaff",
|
|
357
|
-
"thinkingMedium": "#00ffff",
|
|
358
|
-
"thinkingHigh": "#ff00ff",
|
|
359
|
-
"thinkingXhigh": "#ff88ff"
|
|
360
|
-
// ... plus bashMode, pythonMode, statusLine* colors
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
```
|
|
364
|
-
|
|
365
|
-
4. **Select your theme:**
|
|
366
|
-
- Use the Settings UI (Display → Theme)
|
|
367
|
-
- Or run `omp config set theme my-theme`
|
|
368
|
-
|
|
369
|
-
## Tips
|
|
370
|
-
|
|
371
|
-
### Light vs Dark Themes
|
|
372
|
-
|
|
373
|
-
**For dark terminals:**
|
|
374
|
-
|
|
375
|
-
- Use bright, saturated colors
|
|
376
|
-
- Higher contrast
|
|
377
|
-
- Example: `#00ffff` (bright cyan)
|
|
378
|
-
|
|
379
|
-
**For light terminals:**
|
|
380
|
-
|
|
381
|
-
- Use darker, muted colors
|
|
382
|
-
- Lower contrast to avoid eye strain
|
|
383
|
-
- Example: `#008888` (dark cyan)
|
|
384
|
-
|
|
385
|
-
### Color Harmony
|
|
386
|
-
|
|
387
|
-
- Start with a base palette (e.g., Nord, Gruvbox, Tokyo Night)
|
|
388
|
-
- Define your palette in `vars`
|
|
389
|
-
- Reference colors consistently
|
|
390
|
-
|
|
391
|
-
### Testing
|
|
392
|
-
|
|
393
|
-
Test your theme with:
|
|
394
|
-
|
|
395
|
-
- Different message types (user, assistant, errors)
|
|
396
|
-
- Tool executions (success and error states)
|
|
397
|
-
- Markdown content (headings, code, lists, etc)
|
|
398
|
-
- Long text that wraps
|
|
399
|
-
|
|
400
|
-
## Color Format Reference
|
|
401
|
-
|
|
402
|
-
### Hex Colors
|
|
403
|
-
|
|
404
|
-
Standard 6-digit hex format:
|
|
405
|
-
|
|
406
|
-
- `"#ff0000"` - Red
|
|
407
|
-
- `"#00ff00"` - Green
|
|
408
|
-
- `"#0000ff"` - Blue
|
|
409
|
-
- `"#808080"` - Gray
|
|
410
|
-
- `"#ffffff"` - White
|
|
411
|
-
- `"#000000"` - Black
|
|
412
|
-
|
|
413
|
-
RGB values: `#RRGGBB` where each component is `00-ff` (0-255)
|
|
414
|
-
|
|
415
|
-
### 256-Color Palette
|
|
416
|
-
|
|
417
|
-
Use numeric indices (0-255) to reference the xterm 256-color palette:
|
|
418
|
-
|
|
419
|
-
**Colors 0-15:** Basic ANSI colors (terminal-dependent, may be themed)
|
|
420
|
-
|
|
421
|
-
- `0` - Black
|
|
422
|
-
- `1` - Red
|
|
423
|
-
- `2` - Green
|
|
424
|
-
- `3` - Yellow
|
|
425
|
-
- `4` - Blue
|
|
426
|
-
- `5` - Magenta
|
|
427
|
-
- `6` - Cyan
|
|
428
|
-
- `7` - White
|
|
429
|
-
- `8-15` - Bright variants
|
|
430
|
-
|
|
431
|
-
**Colors 16-231:** 6×6×6 RGB cube (standardized)
|
|
432
|
-
|
|
433
|
-
- Formula: `16 + 36×R + 6×G + B` where R, G, B are 0-5
|
|
434
|
-
- Example: `39` = bright cyan, `196` = bright red
|
|
435
|
-
|
|
436
|
-
**Colors 232-255:** Grayscale ramp (standardized)
|
|
437
|
-
|
|
438
|
-
- `232` - Darkest gray
|
|
439
|
-
- `255` - Near white
|
|
440
|
-
|
|
441
|
-
Example usage:
|
|
442
|
-
|
|
443
|
-
```json
|
|
444
|
-
{
|
|
445
|
-
"vars": {
|
|
446
|
-
"gray": 242,
|
|
447
|
-
"brightCyan": 51,
|
|
448
|
-
"darkBlue": 18
|
|
449
|
-
},
|
|
450
|
-
"colors": {
|
|
451
|
-
"muted": "gray",
|
|
452
|
-
"accent": "brightCyan"
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
```
|
|
456
|
-
|
|
457
|
-
**Benefits:**
|
|
458
|
-
|
|
459
|
-
- Works everywhere (`TERM=xterm-256color`)
|
|
460
|
-
- No truecolor detection needed
|
|
461
|
-
- Standardized RGB cube (16-231) looks the same on all terminals
|
|
462
|
-
|
|
463
|
-
### Terminal Compatibility
|
|
464
|
-
|
|
465
|
-
OMP prefers 24-bit RGB colors (`\x1b[38;2;R;G;Bm`) and assumes truecolor on modern terminals.
|
|
466
|
-
|
|
467
|
-
Color mode detection:
|
|
468
|
-
|
|
469
|
-
- `COLORTERM=truecolor|24bit` or `WT_SESSION` → truecolor
|
|
470
|
-
- `TERM=dumb`, `TERM=linux`, or empty `TERM` → 256-color fallback
|
|
471
|
-
- Otherwise → truecolor
|
|
472
|
-
|
|
473
|
-
If you need to confirm terminal hints:
|
|
474
|
-
|
|
475
|
-
```bash
|
|
476
|
-
echo $COLORTERM
|
|
477
|
-
```
|
|
478
|
-
|
|
479
|
-
## Example Themes
|
|
480
|
-
|
|
481
|
-
See the built-in themes for complete examples:
|
|
482
|
-
|
|
483
|
-
- [Dark theme](../src/modes/theme/dark.json)
|
|
484
|
-
- [Light theme](../src/modes/theme/light.json)
|
|
485
|
-
- [Defaults library](../src/modes/theme/defaults)
|
|
486
|
-
|
|
487
|
-
## Schema Validation
|
|
488
|
-
|
|
489
|
-
Themes are validated on load using [TypeBox](https://github.com/sinclairzx81/typebox) and the TypeBox compiler.
|
|
490
|
-
|
|
491
|
-
Invalid themes will show an error with details about what's wrong:
|
|
492
|
-
|
|
493
|
-
```
|
|
494
|
-
Invalid theme "my-theme":
|
|
495
|
-
|
|
496
|
-
Missing required color tokens:
|
|
497
|
-
- mdHeading
|
|
498
|
-
- mdLink
|
|
499
|
-
|
|
500
|
-
Other errors:
|
|
501
|
-
- /colors/accent: Expected union value
|
|
502
|
-
```
|
|
503
|
-
|
|
504
|
-
For editor support, the JSON schema is available at:
|
|
505
|
-
|
|
506
|
-
```
|
|
507
|
-
https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/modes/theme/theme-schema.json
|
|
508
|
-
```
|
|
509
|
-
|
|
510
|
-
Add to your theme file for auto-completion and validation:
|
|
511
|
-
|
|
512
|
-
```json
|
|
513
|
-
{
|
|
514
|
-
"$schema": "https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/modes/theme/theme-schema.json",
|
|
515
|
-
...
|
|
516
|
-
}
|
|
517
|
-
```
|
|
518
|
-
|
|
519
|
-
## Implementation
|
|
520
|
-
|
|
521
|
-
### Theme Class
|
|
522
|
-
|
|
523
|
-
Themes are loaded and converted to a `Theme` class that provides type-safe color methods:
|
|
524
|
-
|
|
525
|
-
```typescript
|
|
526
|
-
class Theme {
|
|
527
|
-
// Apply foreground color
|
|
528
|
-
fg(color: ThemeColor, text: string): string;
|
|
529
|
-
|
|
530
|
-
// Apply background color
|
|
531
|
-
bg(color: ThemeBg, text: string): string;
|
|
532
|
-
|
|
533
|
-
// Text attributes (preserve current colors)
|
|
534
|
-
bold(text: string): string;
|
|
535
|
-
italic(text: string): string;
|
|
536
|
-
underline(text: string): string;
|
|
537
|
-
strikethrough(text: string): string;
|
|
538
|
-
inverse(text: string): string;
|
|
539
|
-
|
|
540
|
-
// Raw ANSI codes (for composing with other formatters)
|
|
541
|
-
getFgAnsi(color: ThemeColor): string;
|
|
542
|
-
getBgAnsi(color: ThemeBg): string;
|
|
543
|
-
|
|
544
|
-
// Symbol access
|
|
545
|
-
symbol(key: SymbolKey): string;
|
|
546
|
-
styledSymbol(key: SymbolKey, color: ThemeColor): string;
|
|
547
|
-
getSymbolPreset(): SymbolPreset;
|
|
548
|
-
|
|
549
|
-
// Category accessors (return grouped symbol objects)
|
|
550
|
-
get status(): { success, error, warning, ... };
|
|
551
|
-
get nav(): { cursor, selected, expand, collapse, back };
|
|
552
|
-
get icon(): { model, folder, file, git, ... };
|
|
553
|
-
get boxRound(): { topLeft, topRight, ... };
|
|
554
|
-
get boxSharp(): { topLeft, topRight, ... };
|
|
555
|
-
get sep(): { powerline, dot, slash, pipe, ... };
|
|
556
|
-
get thinking(): { minimal, low, medium, high, xhigh };
|
|
557
|
-
get spinnerFrames(): string[];
|
|
558
|
-
|
|
559
|
-
// Language icon lookup
|
|
560
|
-
getLangIcon(lang: string | undefined): string;
|
|
561
|
-
}
|
|
562
|
-
```
|
|
563
|
-
|
|
564
|
-
### Global Theme Instance
|
|
565
|
-
|
|
566
|
-
The active theme is available as a global singleton in `coding-agent`:
|
|
567
|
-
|
|
568
|
-
```typescript
|
|
569
|
-
// theme.ts
|
|
570
|
-
export let theme: Theme;
|
|
571
|
-
|
|
572
|
-
export async function initTheme(
|
|
573
|
-
themeName?: string,
|
|
574
|
-
enableWatcher?: boolean,
|
|
575
|
-
symbolPreset?: SymbolPreset,
|
|
576
|
-
colorBlindMode?: boolean
|
|
577
|
-
): Promise<void>;
|
|
578
|
-
export async function setTheme(name: string, enableWatcher?: boolean): Promise<{ success: boolean; error?: string }>;
|
|
579
|
-
|
|
580
|
-
// Usage throughout coding-agent
|
|
581
|
-
import { theme } from "./theme.js";
|
|
582
|
-
|
|
583
|
-
theme.fg("accent", "Selected");
|
|
584
|
-
theme.bg("userMessageBg", content);
|
|
585
|
-
```
|
|
586
|
-
|
|
587
|
-
### TUI Component Theming
|
|
588
|
-
|
|
589
|
-
TUI components (like `Markdown`, `SelectList`, `Editor`) are in the `@oh-my-pi/pi-tui` package and don't have direct access to the theme. Instead, they define interfaces for the colors they need:
|
|
590
|
-
|
|
591
|
-
```typescript
|
|
592
|
-
// In @oh-my-pi/pi-tui
|
|
593
|
-
export interface MarkdownTheme {
|
|
594
|
-
heading: (text: string) => string;
|
|
595
|
-
link: (text: string) => string;
|
|
596
|
-
linkUrl: (text: string) => string;
|
|
597
|
-
code: (text: string) => string;
|
|
598
|
-
codeBlock: (text: string) => string;
|
|
599
|
-
codeBlockBorder: (text: string) => string;
|
|
600
|
-
quote: (text: string) => string;
|
|
601
|
-
quoteBorder: (text: string) => string;
|
|
602
|
-
hr: (text: string) => string;
|
|
603
|
-
listBullet: (text: string) => string;
|
|
604
|
-
bold: (text: string) => string;
|
|
605
|
-
italic: (text: string) => string;
|
|
606
|
-
strikethrough: (text: string) => string;
|
|
607
|
-
underline: (text: string) => string;
|
|
608
|
-
highlightCode?: (code: string, lang?: string) => string[];
|
|
609
|
-
getMermaidImage?: (sourceHash: string) => MermaidImage | null;
|
|
610
|
-
symbols: SymbolTheme;
|
|
611
|
-
}
|
|
612
|
-
```
|
|
613
|
-
|
|
614
|
-
The `coding-agent` bridges the theme to TUI components via exported helpers:
|
|
615
|
-
|
|
616
|
-
```typescript
|
|
617
|
-
// Exported helper in theme.ts
|
|
618
|
-
export function getMarkdownTheme(): MarkdownTheme {
|
|
619
|
-
return {
|
|
620
|
-
heading: (text) => theme.fg("mdHeading", text),
|
|
621
|
-
link: (text) => theme.fg("mdLink", text),
|
|
622
|
-
// ... all color mappings ...
|
|
623
|
-
bold: (text) => theme.bold(text),
|
|
624
|
-
italic: (text) => theme.italic(text),
|
|
625
|
-
underline: (text) => theme.underline(text),
|
|
626
|
-
strikethrough: (text) => chalk.strikethrough(text),
|
|
627
|
-
symbols: getSymbolTheme(),
|
|
628
|
-
getMermaidImage,
|
|
629
|
-
highlightCode: (code, lang) => {
|
|
630
|
-
/* uses native syntax highlighter */
|
|
631
|
-
},
|
|
632
|
-
};
|
|
633
|
-
}
|
|
634
|
-
```
|
|
635
|
-
|
|
636
|
-
This approach:
|
|
637
|
-
|
|
638
|
-
- Keeps TUI components theme-agnostic (reusable in other projects)
|
|
639
|
-
- Maintains type safety via interfaces
|
|
640
|
-
- Centralizes theme access in `coding-agent`
|
|
641
|
-
|
|
642
|
-
Similar helpers exist for other TUI components: `getSelectListTheme()`, `getEditorTheme()`, `getSettingsListTheme()`, `getSymbolTheme()`.
|
|
643
|
-
|
|
644
|
-
**Example usage:**
|
|
645
|
-
|
|
646
|
-
```typescript
|
|
647
|
-
await initTheme("dark");
|
|
648
|
-
|
|
649
|
-
// Apply foreground colors
|
|
650
|
-
theme.fg("accent", "Selected");
|
|
651
|
-
theme.fg("success", "✓ Done");
|
|
652
|
-
theme.fg("error", "Failed");
|
|
653
|
-
|
|
654
|
-
// Apply background colors
|
|
655
|
-
theme.bg("userMessageBg", content);
|
|
656
|
-
theme.bg("toolSuccessBg", output);
|
|
657
|
-
|
|
658
|
-
// Combine styles
|
|
659
|
-
theme.bold(theme.fg("accent", "Title"));
|
|
660
|
-
theme.italic(theme.fg("muted", "metadata"));
|
|
661
|
-
|
|
662
|
-
// Nested foreground + background
|
|
663
|
-
const userMsg = theme.bg("userMessageBg", theme.fg("userMessageText", "Hello"));
|
|
664
|
-
```
|
|
665
|
-
|
|
666
|
-
**Color resolution:**
|
|
667
|
-
|
|
668
|
-
1. **Detect terminal capabilities:**
|
|
669
|
-
- `COLORTERM=truecolor|24bit` or `WT_SESSION` → truecolor
|
|
670
|
-
- `TERM=dumb`, `TERM=linux`, or empty `TERM` → 256-color
|
|
671
|
-
- Otherwise → truecolor
|
|
672
|
-
|
|
673
|
-
2. **Load JSON theme file**
|
|
674
|
-
|
|
675
|
-
3. **Resolve `vars` references recursively:**
|
|
676
|
-
|
|
677
|
-
```json
|
|
678
|
-
{
|
|
679
|
-
"vars": {
|
|
680
|
-
"primary": "#0066cc",
|
|
681
|
-
"accent": "primary"
|
|
682
|
-
},
|
|
683
|
-
"colors": {
|
|
684
|
-
"accent": "accent" // → "primary" → "#0066cc"
|
|
685
|
-
}
|
|
686
|
-
}
|
|
687
|
-
```
|
|
688
|
-
|
|
689
|
-
4. **Convert colors to ANSI codes based on terminal capability:**
|
|
690
|
-
- Empty string (`""`) → terminal default (foreground/background reset)
|
|
691
|
-
- 256-color (`42`) → `\x1b[38;5;42m` / `\x1b[48;5;42m`
|
|
692
|
-
- Hex or resolved vars → `Bun.color(value, "ansi-16m" | "ansi-256")`
|
|
693
|
-
|
|
694
|
-
5. **Cache as `Theme` instance**
|
|
695
|
-
|
|
696
|
-
This ensures themes work correctly regardless of terminal capabilities, with graceful degradation from truecolor to 256-color.
|