@narumitw/pi-statusline 0.50.0 → 0.50.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/README.md +29 -209
- package/dist/chunks/{chunk-74QZGJ7L.js → chunk-J2ZSGEDQ.js} +18 -97
- package/dist/chunks/chunk-J2ZSGEDQ.js.map +7 -0
- package/dist/chunks/{commands-C2G2G7C6.js → commands-PPT3AJTL.js} +14 -58
- package/dist/chunks/commands-PPT3AJTL.js.map +7 -0
- package/dist/index.ts +21 -76
- package/dist/index.ts.map +2 -2
- package/docs/configuration.md +194 -0
- package/package.json +51 -51
- package/src/ansi.ts +18 -24
- package/src/command-contract.ts +6 -6
- package/src/commands.ts +759 -818
- package/src/directory.ts +27 -31
- package/src/extension-status.ts +186 -219
- package/src/git-status.ts +103 -111
- package/src/information-profiles.ts +12 -31
- package/src/powerline.ts +120 -127
- package/src/presets/candy.ts +1 -7
- package/src/presets/create-ramp.ts +21 -23
- package/src/presets/custom.ts +7 -7
- package/src/presets/forest.ts +1 -7
- package/src/presets/index.ts +30 -32
- package/src/presets/mono.ts +1 -7
- package/src/presets/neon.ts +1 -7
- package/src/presets/ocean.ts +1 -7
- package/src/presets/sunset.ts +1 -7
- package/src/presets/tokyo-night.ts +9 -9
- package/src/presets/types.ts +5 -5
- package/src/render.ts +277 -306
- package/src/settings.ts +516 -568
- package/src/statusline.ts +347 -372
- package/src/types.ts +34 -42
- package/src/usage.ts +40 -40
- package/dist/chunks/chunk-74QZGJ7L.js.map +0 -7
- package/dist/chunks/commands-C2G2G7C6.js.map +0 -7
package/README.md
CHANGED
|
@@ -88,17 +88,15 @@ The `tools` segment takes no space while idle.
|
|
|
88
88
|
|
|
89
89
|
| Command | Purpose |
|
|
90
90
|
| --- | --- |
|
|
91
|
-
| `/statusline` |
|
|
92
|
-
| `/statusline settings` |
|
|
93
|
-
| `/statusline status` | Show
|
|
94
|
-
| `/statusline help` | Show command and schema guidance |
|
|
95
|
-
|
|
96
|
-
The
|
|
97
|
-
|
|
98
|
-
RPC receives notifications instead of TUI-only controls.
|
|
91
|
+
| `/statusline` | Customize footer appearance, information density, and layout. |
|
|
92
|
+
| `/statusline settings` | Edit the settings JSON. |
|
|
93
|
+
| `/statusline status` | Show effective settings and diagnostics. |
|
|
94
|
+
| `/statusline help` | Show command and schema guidance. |
|
|
95
|
+
|
|
96
|
+
The menu and editor require TUI; RPC receives notifications instead, including the manual settings path for `settings`.
|
|
97
|
+
Status and help support TUI and RPC; print and JSON modes produce no command output.
|
|
99
98
|
Unknown subcommands and trailing arguments are rejected.
|
|
100
|
-
|
|
101
|
-
The width-aware layout editor and JSON editor remain specialized UI.
|
|
99
|
+
Palette previews save on Enter and revert on Escape, but layout changes save immediately and are not undone by closing the editor; see the [configuration guide](./docs/configuration.md).
|
|
102
100
|
|
|
103
101
|
## 📐 Runtime behavior
|
|
104
102
|
|
|
@@ -136,7 +134,7 @@ If the last remaining segment is itself wider than the row, that row renders emp
|
|
|
136
134
|
- `context` renders one-decimal current usage and the model window, such as `2.4%/272k`.
|
|
137
135
|
After compaction it can temporarily render `?/272k` until the next valid assistant response.
|
|
138
136
|
- `tokens`, `cache`, and `cost` total every usage-bearing session entry, matching Pi's native footer.
|
|
139
|
-
This includes assistant messages, nested-LLM tool results, compactions,
|
|
137
|
+
This includes assistant messages, nested-LLM tool results, compactions, branch summaries, and persisted cache-warming usage, including abandoned branches retained in the session.
|
|
140
138
|
- Cache tokens are `R<read>`, `W<write>`, and `CH<rate>`.
|
|
141
139
|
`R` and `W` are cumulative; `CH` uses only the latest assistant prompt: `cacheRead / (input + cacheRead + cacheWrite) * 100`.
|
|
142
140
|
- Subscription-backed OAuth models and `kimi-coding` append `(sub)` to cost.
|
|
@@ -145,188 +143,28 @@ If the last remaining segment is itself wider than the row, that row renders emp
|
|
|
145
143
|
|
|
146
144
|
## ⚙️ Settings
|
|
147
145
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
```text
|
|
151
|
-
<getAgentDir()>/pi-statusline.json
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
There are no project or environment overrides.
|
|
155
|
-
When the file is absent, pi-statusline uses built-in defaults without creating the file or its parent directory.
|
|
156
|
-
The first successful settings save creates a complete editable document atomically.
|
|
157
|
-
Malformed or unreadable settings are never overwritten.
|
|
158
|
-
Settings reload on startup, `/reload`, and session replacement.
|
|
159
|
-
|
|
160
|
-
A valid legacy `pi-statusline-settings.json` remains readable with a warning and is never modified automatically; rename it to `pi-statusline.json`.
|
|
161
|
-
If both files exist, `pi-statusline.json` wins.
|
|
162
|
-
|
|
163
|
-
### Settings reference
|
|
146
|
+
Use `/statusline` for appearance and information presets, or **Advanced → Edit settings JSON** (`/statusline settings`) for a custom document.
|
|
147
|
+
The only settings file is `<getAgentDir()>/pi-statusline.json`; there are no project or environment overrides.
|
|
164
148
|
|
|
165
|
-
|
|
166
|
-
| --- | --- | --- |
|
|
167
|
-
| `palettePreset` | `tokyo-night`, `ocean`, `sunset`, `forest`, `candy`, `neon`, `mono`, `custom` | Select the active color preset |
|
|
168
|
-
| `palette` | Per-segment `fg`/`bg` `#RRGGBB` colors | Define colors used by `custom` |
|
|
169
|
-
| `density` | `compact`, `cozy` | Control horizontal padding |
|
|
170
|
-
| `separator` | `none`, `dot`, `bar`, `powerline`, `round` | Separate adjacent segments in one color block |
|
|
171
|
-
| `segments` | Ordered unique segment names and `line_break` | Control visibility, order, and rows |
|
|
172
|
-
| `segmentText` | Per-segment `prefix` and `suffix`; model truncation fields | Format Pi-owned dynamic values |
|
|
173
|
-
| `extensionStatusIcons` | Raw status key or `namespace:*` to icon string | Customize extension status icons |
|
|
174
|
-
|
|
175
|
-
All fields are optional in an existing document.
|
|
176
|
-
Missing fields use defaults.
|
|
177
|
-
Menu saves warn about and preserve unknown fields.
|
|
178
|
-
Invalid recognized values block saving and leave the file and live footer unchanged.
|
|
179
|
-
|
|
180
|
-
A compact customization example:
|
|
149
|
+
A minimal customization selects a palette and a few segments:
|
|
181
150
|
|
|
182
151
|
```json
|
|
183
152
|
{
|
|
184
153
|
"palettePreset": "ocean",
|
|
185
|
-
"
|
|
186
|
-
"separator": "dot",
|
|
187
|
-
"segments": ["model", "thinking", "cwd", "branch", "context", "cache", "cost"],
|
|
188
|
-
"segmentText": {
|
|
189
|
-
"model": {
|
|
190
|
-
"truncationLength": 40,
|
|
191
|
-
"truncationSymbol": "…",
|
|
192
|
-
"truncationDirection": "middle"
|
|
193
|
-
},
|
|
194
|
-
"context": { "prefix": "ctx ", "suffix": "" }
|
|
195
|
-
},
|
|
196
|
-
"extensionStatusIcons": {
|
|
197
|
-
"goal": "◎",
|
|
198
|
-
"foo:*": "🧪"
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
Use **Advanced → Edit settings JSON** or `/statusline settings` to edit, validate, atomically save, and apply the file.
|
|
204
|
-
|
|
205
|
-
## 🎨 Appearance
|
|
206
|
-
|
|
207
|
-
Named palettes provide contrast-checked color ramps.
|
|
208
|
-
Appearance previews update while the picker moves, but save only when Enter is pressed; Escape restores the saved palette.
|
|
209
|
-
|
|
210
|
-
When `palettePreset` is `custom`, `palette` maps segment names to foreground/background colors:
|
|
211
|
-
|
|
212
|
-
```json
|
|
213
|
-
{
|
|
214
|
-
"palettePreset": "custom",
|
|
215
|
-
"palette": {
|
|
216
|
-
"model": { "fg": "#090c0c", "bg": "#a3aed2" },
|
|
217
|
-
"context": { "fg": "#c0caf5", "bg": "#1d2230" }
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
```
|
|
221
|
-
|
|
222
|
-
- Selecting `custom` without a palette copies the active named preset as a starting point.
|
|
223
|
-
- A manually authored `"palettePreset": "custom"` without `palette` uses Tokyo Night colors.
|
|
224
|
-
- Named presets ignore but preserve an existing custom palette.
|
|
225
|
-
- A `palette` object without `palettePreset` selects `custom`.
|
|
226
|
-
- Legacy string palettes such as `"palette": "ocean"` remain accepted.
|
|
227
|
-
- Missing custom colors remain unstyled instead of inheriting Tokyo Night.
|
|
228
|
-
- Adjacent segments with identical colors share one block; transitions use ``.
|
|
229
|
-
- Hex palette colors render as ANSI-256 when Pi's effective terminal capabilities disable true color.
|
|
230
|
-
|
|
231
|
-
`segmentText` values must be single-line text without terminal control characters.
|
|
232
|
-
Use `line_break` for another row rather than inserting a newline into a prefix or suffix.
|
|
233
|
-
|
|
234
|
-
### Model truncation
|
|
235
|
-
|
|
236
|
-
Long model IDs are truncated out of the box so the balanced footer can retain useful model context:
|
|
237
|
-
|
|
238
|
-
```json
|
|
239
|
-
{
|
|
240
|
-
"segmentText": {
|
|
241
|
-
"model": {
|
|
242
|
-
"truncationLength": 36,
|
|
243
|
-
"truncationSymbol": "…",
|
|
244
|
-
"truncationDirection": "start"
|
|
245
|
-
}
|
|
246
|
-
}
|
|
154
|
+
"segments": ["model", "cwd", "branch", "context"]
|
|
247
155
|
}
|
|
248
156
|
```
|
|
249
157
|
|
|
250
|
-
|
|
251
|
-
The
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
- `middle` retains both ends.
|
|
256
|
-
- `end` retains the prefix.
|
|
257
|
-
|
|
258
|
-
Truncation runs after the built-in Claude/GPT shortening rules but before the configured model prefix and suffix.
|
|
259
|
-
It changes display only—the provider model ID is untouched.
|
|
260
|
-
Terminal control sequences in model IDs are removed at render time, and unsafe configured symbols are rejected.
|
|
261
|
-
An empty `truncationSymbol` truncates without a marker.
|
|
262
|
-
pi-statusline treats model IDs as opaque strings and does not parse paths, repositories, GGUF suffixes, or quantization names.
|
|
263
|
-
At very narrow widths, the existing responsive priorities may still omit the model rather than overflow the terminal.
|
|
158
|
+
A missing file uses the balanced built-in footer without creating the file or its parent directory.
|
|
159
|
+
The first successful save creates an editable document atomically.
|
|
160
|
+
Menu saves preserve unknown fields; invalid recognized values block saving and keep the live footer unchanged.
|
|
161
|
+
Malformed or unreadable files are never overwritten.
|
|
162
|
+
Manual edits load at startup, `/reload`, or session replacement.
|
|
264
163
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
Open **Advanced → Custom layout** when the curated levels are not enough.
|
|
268
|
-
|
|
269
|
-
| Key | Action |
|
|
270
|
-
| --- | --- |
|
|
271
|
-
| Up/Down | Navigate |
|
|
272
|
-
| Page Up/Page Down | Move by one viewport |
|
|
273
|
-
| Enter/Space | Show or hide the selected segment |
|
|
274
|
-
| `M` | Enter or leave Move mode |
|
|
275
|
-
| Up/Down in Move mode | Reorder the selected visible segment |
|
|
276
|
-
| `Alt+Up` / `Alt+Down` | Reorder without entering Move mode |
|
|
277
|
-
| `B` | Add or remove a line break after the selected segment |
|
|
278
|
-
| Configured Back key (Escape by default) | Leave Move mode first, then close the screen |
|
|
279
|
-
| Ctrl+C | Close the screen immediately, including from Move mode |
|
|
280
|
-
|
|
281
|
-
The layout displays the effective Back key and keeps Ctrl+C available when Back is remapped.
|
|
282
|
-
Every successful change saves and applies immediately.
|
|
283
|
-
Closing the screen does not roll it back.
|
|
284
|
-
|
|
285
|
-
Available data segments:
|
|
286
|
-
|
|
287
|
-
```text
|
|
288
|
-
brand provider model thinking cwd branch tools context tokens cache cost time turn
|
|
289
|
-
```
|
|
290
|
-
|
|
291
|
-
Data segments must be unique.
|
|
292
|
-
`line_break` may repeat when data segments separate occurrences, but consecutive breaks are invalid.
|
|
293
|
-
It has no `segmentText` entry.
|
|
294
|
-
The menu cleans up leading, trailing, and newly consecutive breaks after visibility changes.
|
|
295
|
-
Manually authored leading/trailing breaks represent empty rows.
|
|
296
|
-
|
|
297
|
-
```json
|
|
298
|
-
{
|
|
299
|
-
"segments": ["model", "line_break", "cwd", "branch", "context"]
|
|
300
|
-
}
|
|
301
|
-
```
|
|
302
|
-
|
|
303
|
-
An empty `segments` array hides the main powerline while extension statuses can still render.
|
|
304
|
-
|
|
305
|
-
## 🔌 Extension statuses and icons
|
|
306
|
-
|
|
307
|
-
Other extension statuses appear below the main powerline, wrap to terminal width, and are limited to five items.
|
|
308
|
-
Icons use this order:
|
|
309
|
-
|
|
310
|
-
1. Exact configured raw key, such as `goal` or `foo:server`.
|
|
311
|
-
2. Longest configured colon wildcard, such as `foo:*` or `foo:server:*`.
|
|
312
|
-
3. Unambiguous installed-package alias, such as `@vendor/pi-foo`, `pi-foo`, or `foo`.
|
|
313
|
-
4. Leading emoji supplied by the status text.
|
|
314
|
-
5. Built-in icon.
|
|
315
|
-
6. Generic `🔌` fallback.
|
|
316
|
-
|
|
317
|
-
Set an icon to `""` to hide only the icon.
|
|
318
|
-
Wildcards match colon namespaces, not slash-delimited keys.
|
|
319
|
-
Configure slash keys exactly.
|
|
320
|
-
Compatibility fallbacks retain `codex-usage`, `pisync`, and `unknown-error-retry`; an explicit canonical key wins.
|
|
321
|
-
|
|
322
|
-
For interoperable extensions, prefer one aggregated key or a stable coexistence slot:
|
|
323
|
-
|
|
324
|
-
```text
|
|
325
|
-
<extension-id>
|
|
326
|
-
<extension-id>:<stable-slot>
|
|
327
|
-
```
|
|
164
|
+
Appearance previews save only on Enter, while Escape restores the saved palette.
|
|
165
|
+
Custom-layout changes save immediately, so closing that screen does not undo them.
|
|
328
166
|
|
|
329
|
-
|
|
167
|
+
Read the [configuration reference](./docs/configuration.md) for all settings, palettes, model truncation, multiline layouts, effective layout controls, extension-status icon precedence, and legacy-file handling.
|
|
330
168
|
|
|
331
169
|
## 🚧 Limitations
|
|
332
170
|
|
|
@@ -345,34 +183,16 @@ Put transient activity in the value, and clear the exact key that was set.
|
|
|
345
183
|
|
|
346
184
|
```text
|
|
347
185
|
packages/pi-statusline/
|
|
348
|
-
├──
|
|
349
|
-
├──
|
|
350
|
-
│ └──
|
|
351
|
-
├──
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
│ ├── render.ts
|
|
356
|
-
│ ├── directory.ts
|
|
357
|
-
│ ├── usage.ts
|
|
358
|
-
│ ├── powerline.ts
|
|
359
|
-
│ ├── information-profiles.ts
|
|
360
|
-
│ ├── commands.ts
|
|
361
|
-
│ ├── settings.ts
|
|
362
|
-
│ ├── extension-status.ts
|
|
363
|
-
│ ├── git-status.ts
|
|
364
|
-
│ ├── ansi.ts
|
|
365
|
-
│ ├── types.ts
|
|
366
|
-
│ └── presets/
|
|
367
|
-
├── test/
|
|
368
|
-
├── README.md
|
|
369
|
-
├── LICENSE
|
|
370
|
-
├── tsconfig.json
|
|
371
|
-
└── package.json
|
|
186
|
+
├── src/ # Authoritative implementation and helpers
|
|
187
|
+
│ ├── index.ts # Thin Pi entrypoint
|
|
188
|
+
│ └── statusline.ts # Responsive footer lifecycle
|
|
189
|
+
├── dist/ # Generated Jiti runtime
|
|
190
|
+
├── scripts/build-runtime.mjs # Runtime builder
|
|
191
|
+
├── docs/ # Published reference documentation
|
|
192
|
+
└── test/ # Behavior and lifecycle coverage
|
|
372
193
|
```
|
|
373
194
|
|
|
374
|
-
|
|
375
|
-
The package build emits the sole declared Pi entrypoint at `dist/index.ts` without forwarding back into `src`.
|
|
195
|
+
The generated runtime is built from `src/index.ts` and does not import back into `src`.
|
|
376
196
|
|
|
377
197
|
## 🔎 Keywords
|
|
378
198
|
|
|
@@ -30,15 +30,7 @@ var SEGMENT_NAMES = [
|
|
|
30
30
|
"turn"
|
|
31
31
|
];
|
|
32
32
|
var LINE_BREAK_SEGMENT_NAME = "line_break";
|
|
33
|
-
var PALETTE_NAMES = [
|
|
34
|
-
"tokyo-night",
|
|
35
|
-
"ocean",
|
|
36
|
-
"sunset",
|
|
37
|
-
"forest",
|
|
38
|
-
"candy",
|
|
39
|
-
"neon",
|
|
40
|
-
"mono"
|
|
41
|
-
];
|
|
33
|
+
var PALETTE_NAMES = ["tokyo-night", "ocean", "sunset", "forest", "candy", "neon", "mono"];
|
|
42
34
|
var PALETTE_PRESET_NAMES = [...PALETTE_NAMES, "custom"];
|
|
43
35
|
var DENSITIES = ["compact", "cozy"];
|
|
44
36
|
var SEPARATOR_NAMES = ["none", "dot", "bar", "powerline", "round"];
|
|
@@ -77,13 +69,7 @@ function relativeLuminance(hex) {
|
|
|
77
69
|
}
|
|
78
70
|
|
|
79
71
|
// src/presets/candy.ts
|
|
80
|
-
var CANDY_PRESET = createRampPreset([
|
|
81
|
-
"#f5c2e7",
|
|
82
|
-
"#cba6f7",
|
|
83
|
-
"#89b4fa",
|
|
84
|
-
"#745f9a",
|
|
85
|
-
"#403a5c"
|
|
86
|
-
]);
|
|
72
|
+
var CANDY_PRESET = createRampPreset(["#f5c2e7", "#cba6f7", "#89b4fa", "#745f9a", "#403a5c"]);
|
|
87
73
|
|
|
88
74
|
// src/presets/custom.ts
|
|
89
75
|
var CUSTOM_PRESET = {
|
|
@@ -97,49 +83,19 @@ var CUSTOM_PRESET = {
|
|
|
97
83
|
};
|
|
98
84
|
|
|
99
85
|
// src/presets/forest.ts
|
|
100
|
-
var FOREST_PRESET = createRampPreset([
|
|
101
|
-
"#a7c080",
|
|
102
|
-
"#83c092",
|
|
103
|
-
"#5f9f75",
|
|
104
|
-
"#3f6f55",
|
|
105
|
-
"#293f35"
|
|
106
|
-
]);
|
|
86
|
+
var FOREST_PRESET = createRampPreset(["#a7c080", "#83c092", "#5f9f75", "#3f6f55", "#293f35"]);
|
|
107
87
|
|
|
108
88
|
// src/presets/mono.ts
|
|
109
|
-
var MONO_PRESET = createRampPreset([
|
|
110
|
-
"#d4d4d4",
|
|
111
|
-
"#a3a3a3",
|
|
112
|
-
"#686868",
|
|
113
|
-
"#404040",
|
|
114
|
-
"#262626"
|
|
115
|
-
]);
|
|
89
|
+
var MONO_PRESET = createRampPreset(["#d4d4d4", "#a3a3a3", "#686868", "#404040", "#262626"]);
|
|
116
90
|
|
|
117
91
|
// src/presets/neon.ts
|
|
118
|
-
var NEON_PRESET = createRampPreset([
|
|
119
|
-
"#39ff14",
|
|
120
|
-
"#00f5ff",
|
|
121
|
-
"#ff4fd8",
|
|
122
|
-
"#7a2cf3",
|
|
123
|
-
"#29134f"
|
|
124
|
-
]);
|
|
92
|
+
var NEON_PRESET = createRampPreset(["#39ff14", "#00f5ff", "#ff4fd8", "#7a2cf3", "#29134f"]);
|
|
125
93
|
|
|
126
94
|
// src/presets/ocean.ts
|
|
127
|
-
var OCEAN_PRESET = createRampPreset([
|
|
128
|
-
"#7dcfff",
|
|
129
|
-
"#4f9fba",
|
|
130
|
-
"#2d6f88",
|
|
131
|
-
"#23475b",
|
|
132
|
-
"#182b3a"
|
|
133
|
-
]);
|
|
95
|
+
var OCEAN_PRESET = createRampPreset(["#7dcfff", "#4f9fba", "#2d6f88", "#23475b", "#182b3a"]);
|
|
134
96
|
|
|
135
97
|
// src/presets/sunset.ts
|
|
136
|
-
var SUNSET_PRESET = createRampPreset([
|
|
137
|
-
"#ffcf70",
|
|
138
|
-
"#f59e6f",
|
|
139
|
-
"#dc718a",
|
|
140
|
-
"#8f5b78",
|
|
141
|
-
"#493447"
|
|
142
|
-
]);
|
|
98
|
+
var SUNSET_PRESET = createRampPreset(["#ffcf70", "#f59e6f", "#dc718a", "#8f5b78", "#493447"]);
|
|
143
99
|
|
|
144
100
|
// src/presets/tokyo-night.ts
|
|
145
101
|
var TOKYO_NIGHT_PRESET = {
|
|
@@ -185,9 +141,7 @@ function resolvePreset(preset) {
|
|
|
185
141
|
}
|
|
186
142
|
function segmentPaletteForPreset(preset) {
|
|
187
143
|
const blocks = PRESETS[preset].blocks;
|
|
188
|
-
return Object.fromEntries(
|
|
189
|
-
SEGMENT_NAMES.map((name) => [name, { ...blocks[SEGMENT_BLOCKS[name]] }])
|
|
190
|
-
);
|
|
144
|
+
return Object.fromEntries(SEGMENT_NAMES.map((name) => [name, { ...blocks[SEGMENT_BLOCKS[name]] }]));
|
|
191
145
|
}
|
|
192
146
|
|
|
193
147
|
// src/information-profiles.ts
|
|
@@ -195,19 +149,7 @@ var INFORMATION_PROFILE_NAMES = ["minimal", "balanced", "detailed"];
|
|
|
195
149
|
var INFORMATION_PROFILES = {
|
|
196
150
|
minimal: ["model", "cwd", "branch", "context"],
|
|
197
151
|
balanced: ["model", "thinking", "cwd", "branch", "tools", "context", "time"],
|
|
198
|
-
detailed: [
|
|
199
|
-
"provider",
|
|
200
|
-
"model",
|
|
201
|
-
"thinking",
|
|
202
|
-
"cwd",
|
|
203
|
-
"branch",
|
|
204
|
-
"tools",
|
|
205
|
-
"context",
|
|
206
|
-
"tokens",
|
|
207
|
-
"cache",
|
|
208
|
-
"cost",
|
|
209
|
-
"time"
|
|
210
|
-
]
|
|
152
|
+
detailed: ["provider", "model", "thinking", "cwd", "branch", "tools", "context", "tokens", "cache", "cost", "time"]
|
|
211
153
|
};
|
|
212
154
|
function inferInformationProfile(segments) {
|
|
213
155
|
for (const name of INFORMATION_PROFILE_NAMES) {
|
|
@@ -289,11 +231,7 @@ var DEFAULT_STATUSLINE_DOCUMENT_CONFIG = {
|
|
|
289
231
|
segmentText: DEFAULT_STATUSLINE_CONFIG.segmentText,
|
|
290
232
|
extensionStatusIcons: DEFAULT_DOCUMENT_EXTENSION_STATUS_ICONS
|
|
291
233
|
};
|
|
292
|
-
var DEFAULT_STATUSLINE_DOCUMENT = `${JSON.stringify(
|
|
293
|
-
DEFAULT_STATUSLINE_DOCUMENT_CONFIG,
|
|
294
|
-
null,
|
|
295
|
-
" "
|
|
296
|
-
)}
|
|
234
|
+
var DEFAULT_STATUSLINE_DOCUMENT = `${JSON.stringify(DEFAULT_STATUSLINE_DOCUMENT_CONFIG, null, " ")}
|
|
297
235
|
`;
|
|
298
236
|
var pendingSettingsNotice;
|
|
299
237
|
function settingsFilePath(agentDir = getAgentDir()) {
|
|
@@ -344,9 +282,7 @@ function normalizeStatuslineConfig(value) {
|
|
|
344
282
|
}
|
|
345
283
|
if (item === LINE_BREAK_SEGMENT_NAME) {
|
|
346
284
|
if (segments.at(-1) === LINE_BREAK_SEGMENT_NAME) {
|
|
347
|
-
diagnostics.push(
|
|
348
|
-
invalidDiagnostic(path, "Consecutive line_break segments are not allowed")
|
|
349
|
-
);
|
|
285
|
+
diagnostics.push(invalidDiagnostic(path, "Consecutive line_break segments are not allowed"));
|
|
350
286
|
continue;
|
|
351
287
|
}
|
|
352
288
|
segments.push(item);
|
|
@@ -529,10 +465,7 @@ function saveStatuslineSettingsDocument(settingsPath, rawDocument, overrides = {
|
|
|
529
465
|
};
|
|
530
466
|
}
|
|
531
467
|
function removeStatuslineSettingsDocumentIfMatches(settingsPath, expectedRawDocument, expectedIdentity) {
|
|
532
|
-
const quarantinePath = join(
|
|
533
|
-
dirname(settingsPath),
|
|
534
|
-
`.${SETTINGS_FILE_NAME}.${randomUUID()}.rollback`
|
|
535
|
-
);
|
|
468
|
+
const quarantinePath = join(dirname(settingsPath), `.${SETTINGS_FILE_NAME}.${randomUUID()}.rollback`);
|
|
536
469
|
const before = lstatSync(settingsPath);
|
|
537
470
|
if (before.dev !== expectedIdentity.dev || before.ino !== expectedIdentity.ino) {
|
|
538
471
|
throw new Error("Statusline settings changed concurrently; the newer file was preserved");
|
|
@@ -562,10 +495,7 @@ function normalizePalette(value, config, diagnostics) {
|
|
|
562
495
|
if (typeof value === "string") {
|
|
563
496
|
if (!PALETTE_NAMES.includes(value)) {
|
|
564
497
|
diagnostics.push(
|
|
565
|
-
invalidDiagnostic(
|
|
566
|
-
"palette",
|
|
567
|
-
`Expected a palette object or one of: ${PALETTE_NAMES.join(", ")}`
|
|
568
|
-
)
|
|
498
|
+
invalidDiagnostic("palette", `Expected a palette object or one of: ${PALETTE_NAMES.join(", ")}`)
|
|
569
499
|
);
|
|
570
500
|
return;
|
|
571
501
|
}
|
|
@@ -611,9 +541,7 @@ function normalizeModelTruncation(presentation, config, diagnostics) {
|
|
|
611
541
|
const length = presentation.truncationLength;
|
|
612
542
|
if (length !== void 0) {
|
|
613
543
|
if (typeof length !== "number" || !Number.isInteger(length) || length < 0 || length > 1e3) {
|
|
614
|
-
diagnostics.push(
|
|
615
|
-
invalidDiagnostic(`${path}.truncationLength`, "Expected an integer from 0 through 1000")
|
|
616
|
-
);
|
|
544
|
+
diagnostics.push(invalidDiagnostic(`${path}.truncationLength`, "Expected an integer from 0 through 1000"));
|
|
617
545
|
} else config.segmentText.model.truncationLength = length;
|
|
618
546
|
}
|
|
619
547
|
const symbol = presentation.truncationSymbol;
|
|
@@ -624,10 +552,7 @@ function normalizeModelTruncation(presentation, config, diagnostics) {
|
|
|
624
552
|
if (direction !== void 0) {
|
|
625
553
|
if (typeof direction !== "string" || !TRUNCATION_DIRECTIONS.includes(direction)) {
|
|
626
554
|
diagnostics.push(
|
|
627
|
-
invalidDiagnostic(
|
|
628
|
-
`${path}.truncationDirection`,
|
|
629
|
-
`Expected one of: ${TRUNCATION_DIRECTIONS.join(", ")}`
|
|
630
|
-
)
|
|
555
|
+
invalidDiagnostic(`${path}.truncationDirection`, `Expected one of: ${TRUNCATION_DIRECTIONS.join(", ")}`)
|
|
631
556
|
);
|
|
632
557
|
} else {
|
|
633
558
|
config.segmentText.model.truncationDirection = direction;
|
|
@@ -653,17 +578,13 @@ function normalizeEnum(value, field, accepted, config, diagnostics) {
|
|
|
653
578
|
const candidate = value[field];
|
|
654
579
|
if (candidate === void 0) return;
|
|
655
580
|
if (typeof candidate !== "string" || !accepted.includes(candidate)) {
|
|
656
|
-
diagnostics.push(
|
|
657
|
-
invalidDiagnostic(field, `Expected one of: ${accepted.map(String).join(", ")}`)
|
|
658
|
-
);
|
|
581
|
+
diagnostics.push(invalidDiagnostic(field, `Expected one of: ${accepted.map(String).join(", ")}`));
|
|
659
582
|
return;
|
|
660
583
|
}
|
|
661
584
|
config[field] = candidate;
|
|
662
585
|
}
|
|
663
586
|
function cloneSegmentPalette(palette) {
|
|
664
|
-
return Object.fromEntries(
|
|
665
|
-
Object.entries(palette).map(([name, colors]) => [name, { ...colors }])
|
|
666
|
-
);
|
|
587
|
+
return Object.fromEntries(Object.entries(palette).map(([name, colors]) => [name, { ...colors }]));
|
|
667
588
|
}
|
|
668
589
|
function cloneConfig(config) {
|
|
669
590
|
return {
|
|
@@ -765,4 +686,4 @@ export {
|
|
|
765
686
|
removeStatuslineSettingsDocumentIfMatches,
|
|
766
687
|
consumeStatuslineSettingsNotice
|
|
767
688
|
};
|
|
768
|
-
//# sourceMappingURL=chunk-
|
|
689
|
+
//# sourceMappingURL=chunk-J2ZSGEDQ.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/command-contract.ts", "../../src/types.ts", "../../src/presets/create-ramp.ts", "../../src/presets/candy.ts", "../../src/presets/custom.ts", "../../src/presets/forest.ts", "../../src/presets/mono.ts", "../../src/presets/neon.ts", "../../src/presets/ocean.ts", "../../src/presets/sunset.ts", "../../src/presets/tokyo-night.ts", "../../src/presets/index.ts", "../../src/information-profiles.ts", "../../src/settings.ts"],
|
|
4
|
+
"sourcesContent": ["import type { AutocompleteItem } from \"@earendil-works/pi-tui\";\n\nexport const STATUSLINE_SUBCOMMANDS: readonly AutocompleteItem[] = [\n { value: \"settings\", label: \"settings\", description: \"Edit pi-statusline.json\" },\n { value: \"status\", label: \"status\", description: \"Show effective statusline settings\" },\n { value: \"help\", label: \"help\", description: \"Show configuration help\" },\n];\n\nexport function completeStatuslineArguments(prefix: string): AutocompleteItem[] | null {\n const normalized = prefix.trim().toLowerCase();\n const matches = STATUSLINE_SUBCOMMANDS.filter((item) => item.value.startsWith(normalized));\n return matches.length > 0 ? [...matches] : null;\n}\n", "import type { ThemeColor } from \"@earendil-works/pi-coding-agent\";\n\nexport const SEGMENT_NAMES = [\n \"brand\",\n \"provider\",\n \"model\",\n \"thinking\",\n \"cwd\",\n \"branch\",\n \"tools\",\n \"context\",\n \"tokens\",\n \"cache\",\n \"cost\",\n \"time\",\n \"turn\",\n] as const;\nexport type SegmentName = (typeof SEGMENT_NAMES)[number];\n\nexport const LINE_BREAK_SEGMENT_NAME = \"line_break\" as const;\nexport type ConfigSegmentName = SegmentName | typeof LINE_BREAK_SEGMENT_NAME;\n\nexport const PALETTE_NAMES = [\"tokyo-night\", \"ocean\", \"sunset\", \"forest\", \"candy\", \"neon\", \"mono\"] as const;\nexport type PaletteName = (typeof PALETTE_NAMES)[number];\n\nexport const PALETTE_PRESET_NAMES = [...PALETTE_NAMES, \"custom\"] as const;\nexport type PalettePreset = (typeof PALETTE_PRESET_NAMES)[number];\n\nexport const DENSITIES = [\"compact\", \"cozy\"] as const;\nexport type Density = (typeof DENSITIES)[number];\n\nexport const SEPARATOR_NAMES = [\"none\", \"dot\", \"bar\", \"powerline\", \"round\"] as const;\nexport type SeparatorName = (typeof SEPARATOR_NAMES)[number];\n\nexport const TRUNCATION_DIRECTIONS = [\"start\", \"middle\", \"end\"] as const;\nexport type TruncationDirection = (typeof TRUNCATION_DIRECTIONS)[number];\n\nexport type PowerlineBlockName = \"header\" | \"directory\" | \"git\" | \"runtime\" | \"meter\";\n\nexport interface SegmentTextConfig {\n prefix: string;\n suffix: string;\n}\n\nexport interface ModelSegmentTextConfig extends SegmentTextConfig {\n truncationLength: number;\n truncationSymbol: string;\n truncationDirection: TruncationDirection;\n}\n\nexport interface SegmentPaletteColor {\n fg?: string;\n bg?: string;\n}\n\nexport type SegmentPalette = Partial<Record<SegmentName, SegmentPaletteColor>>;\n\nexport interface StatuslineConfig {\n palettePreset: PalettePreset;\n palette: SegmentPalette;\n density: Density;\n separator: SeparatorName;\n segments: ConfigSegmentName[];\n segmentText: Record<SegmentName, SegmentTextConfig> & { model: ModelSegmentTextConfig };\n extensionStatusIcons: Record<string, string>;\n}\n\nexport interface RenderSegment {\n name: SegmentName;\n text: string;\n color: ThemeColor;\n block: PowerlineBlockName;\n emphasis?: boolean;\n}\n\nexport interface RenderLineBreak {\n name: typeof LINE_BREAK_SEGMENT_NAME;\n}\n\nexport type RenderItem = RenderSegment | RenderLineBreak;\n", "import type { PowerlineBlockName } from \"../types.js\";\nimport type { PowerlinePreset } from \"./types.js\";\n\nconst BLOCK_NAMES: PowerlineBlockName[] = [\"header\", \"directory\", \"git\", \"runtime\", \"meter\"];\n\ntype PaletteRamp = readonly [string, string, string, string, string];\n\nexport function createRampPreset(backgrounds: PaletteRamp): PowerlinePreset {\n return {\n lead: backgrounds[0],\n blocks: Object.fromEntries(\n BLOCK_NAMES.map((block, index) => {\n const background = backgrounds[index];\n return [block, { fg: contrastColor(background), bg: background }];\n }),\n ) as Record<PowerlineBlockName, { fg: string; bg: string }>,\n extensionSeparator: backgrounds[2],\n };\n}\n\nfunction contrastColor(hex: string): string {\n const background = relativeLuminance(hex);\n const dark = relativeLuminance(\"#090c0c\");\n const light = relativeLuminance(\"#f0f0f0\");\n return contrastRatio(background, dark) >= contrastRatio(background, light) ? \"#090c0c\" : \"#f0f0f0\";\n}\n\nfunction contrastRatio(left: number, right: number): number {\n return (Math.max(left, right) + 0.05) / (Math.min(left, right) + 0.05);\n}\n\nfunction relativeLuminance(hex: string): number {\n const normalized = hex.slice(1);\n const channels = [0, 2, 4].map((offset) => {\n const value = Number.parseInt(normalized.slice(offset, offset + 2), 16) / 255;\n return value <= 0.04045 ? value / 12.92 : ((value + 0.055) / 1.055) ** 2.4;\n });\n return 0.2126 * (channels[0] ?? 0) + 0.7152 * (channels[1] ?? 0) + 0.0722 * (channels[2] ?? 0);\n}\n", "import { createRampPreset } from \"./create-ramp.js\";\n\nexport const CANDY_PRESET = createRampPreset([\"#f5c2e7\", \"#cba6f7\", \"#89b4fa\", \"#745f9a\", \"#403a5c\"]);\n", "import type { PowerlinePreset } from \"./types.js\";\n\nexport const CUSTOM_PRESET: PowerlinePreset = {\n blocks: {\n header: {},\n directory: {},\n git: {},\n runtime: {},\n meter: {},\n },\n};\n", "import { createRampPreset } from \"./create-ramp.js\";\n\nexport const FOREST_PRESET = createRampPreset([\"#a7c080\", \"#83c092\", \"#5f9f75\", \"#3f6f55\", \"#293f35\"]);\n", "import { createRampPreset } from \"./create-ramp.js\";\n\nexport const MONO_PRESET = createRampPreset([\"#d4d4d4\", \"#a3a3a3\", \"#686868\", \"#404040\", \"#262626\"]);\n", "import { createRampPreset } from \"./create-ramp.js\";\n\nexport const NEON_PRESET = createRampPreset([\"#39ff14\", \"#00f5ff\", \"#ff4fd8\", \"#7a2cf3\", \"#29134f\"]);\n", "import { createRampPreset } from \"./create-ramp.js\";\n\nexport const OCEAN_PRESET = createRampPreset([\"#7dcfff\", \"#4f9fba\", \"#2d6f88\", \"#23475b\", \"#182b3a\"]);\n", "import { createRampPreset } from \"./create-ramp.js\";\n\nexport const SUNSET_PRESET = createRampPreset([\"#ffcf70\", \"#f59e6f\", \"#dc718a\", \"#8f5b78\", \"#493447\"]);\n", "import type { PowerlinePreset } from \"./types.js\";\n\nexport const TOKYO_NIGHT_PRESET: PowerlinePreset = {\n lead: \"#a3aed2\",\n blocks: {\n header: { fg: \"#090c0c\", bg: \"#a3aed2\" },\n directory: { fg: \"#e3e5e5\", bg: \"#769ff0\" },\n git: { fg: \"#769ff0\", bg: \"#394260\" },\n runtime: { fg: \"#769ff0\", bg: \"#212736\" },\n meter: { fg: \"#a0a9cb\", bg: \"#1d2230\" },\n },\n extensionSeparator: \"#394260\",\n};\n", "import {\n type PaletteName,\n type PalettePreset,\n type PowerlineBlockName,\n SEGMENT_NAMES,\n type SegmentName,\n type SegmentPalette,\n} from \"../types.js\";\nimport { CANDY_PRESET } from \"./candy.js\";\nimport { CUSTOM_PRESET } from \"./custom.js\";\nimport { FOREST_PRESET } from \"./forest.js\";\nimport { MONO_PRESET } from \"./mono.js\";\nimport { NEON_PRESET } from \"./neon.js\";\nimport { OCEAN_PRESET } from \"./ocean.js\";\nimport { SUNSET_PRESET } from \"./sunset.js\";\nimport { TOKYO_NIGHT_PRESET } from \"./tokyo-night.js\";\nimport type { PowerlinePreset } from \"./types.js\";\n\nconst PRESETS = {\n \"tokyo-night\": TOKYO_NIGHT_PRESET,\n ocean: OCEAN_PRESET,\n sunset: SUNSET_PRESET,\n forest: FOREST_PRESET,\n candy: CANDY_PRESET,\n neon: NEON_PRESET,\n mono: MONO_PRESET,\n custom: CUSTOM_PRESET,\n} satisfies Record<PalettePreset, PowerlinePreset>;\n\nconst SEGMENT_BLOCKS: Record<SegmentName, PowerlineBlockName> = {\n brand: \"header\",\n provider: \"header\",\n model: \"header\",\n thinking: \"header\",\n cwd: \"directory\",\n branch: \"git\",\n tools: \"runtime\",\n context: \"runtime\",\n tokens: \"runtime\",\n cache: \"runtime\",\n cost: \"meter\",\n time: \"meter\",\n turn: \"meter\",\n};\n\nexport function resolvePreset(preset: PalettePreset): PowerlinePreset {\n return PRESETS[preset];\n}\n\nexport function segmentPaletteForPreset(preset: PaletteName): SegmentPalette {\n const blocks = PRESETS[preset].blocks;\n return Object.fromEntries(SEGMENT_NAMES.map((name) => [name, { ...blocks[SEGMENT_BLOCKS[name]] }])) as SegmentPalette;\n}\n", "import type { ConfigSegmentName, SegmentName } from \"./types.js\";\n\nexport const INFORMATION_PROFILE_NAMES = [\"minimal\", \"balanced\", \"detailed\"] as const;\nexport type InformationProfileName = (typeof INFORMATION_PROFILE_NAMES)[number];\nexport type InformationProfile = InformationProfileName | \"custom\";\n\nexport const INFORMATION_PROFILES: Readonly<Record<InformationProfileName, readonly SegmentName[]>> = {\n minimal: [\"model\", \"cwd\", \"branch\", \"context\"],\n balanced: [\"model\", \"thinking\", \"cwd\", \"branch\", \"tools\", \"context\", \"time\"],\n detailed: [\"provider\", \"model\", \"thinking\", \"cwd\", \"branch\", \"tools\", \"context\", \"tokens\", \"cache\", \"cost\", \"time\"],\n};\n\nexport function inferInformationProfile(segments: readonly ConfigSegmentName[]): InformationProfile {\n for (const name of INFORMATION_PROFILE_NAMES) {\n const profile = INFORMATION_PROFILES[name];\n if (segments.length === profile.length && segments.every((segment, index) => segment === profile[index])) {\n return name;\n }\n }\n return \"custom\";\n}\n", "import { randomUUID } from \"node:crypto\";\nimport { lstatSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { getAgentDir } from \"@earendil-works/pi-coding-agent\";\nimport { INFORMATION_PROFILES } from \"./information-profiles.js\";\nimport { segmentPaletteForPreset } from \"./presets/index.js\";\nimport {\n type ConfigSegmentName,\n DENSITIES,\n LINE_BREAK_SEGMENT_NAME,\n PALETTE_NAMES,\n PALETTE_PRESET_NAMES,\n type PaletteName,\n SEGMENT_NAMES,\n SEPARATOR_NAMES,\n type SegmentName,\n type SegmentPalette,\n type StatuslineConfig,\n TRUNCATION_DIRECTIONS,\n} from \"./types.js\";\n\nexport const SETTINGS_FILE_NAME = \"pi-statusline.json\";\nconst LEGACY_SETTINGS_FILE_NAME = \"pi-statusline-settings.json\";\n\nconst DEFAULT_DOCUMENT_EXTENSION_STATUS_ICONS: Record<string, string> = {\n accounts: \"\uD83D\uDC64\",\n caffeinate: \"\uD83D\uDC8A\",\n \"chrome-devtools\": \"\uD83C\uDF10\",\n firecrawl: \"\uD83D\uDD25\",\n \"github-pr\": \"\uD83D\uDD0E\",\n goal: \"\uD83C\uDFAF\",\n \"google-genai\": \"\u2728\",\n lsp: \"\uD83E\uDDF0\",\n \"plan-mode\": \"\uD83D\uDCDD\",\n retry: \"\uD83D\uDD01\",\n subagents: \"\uD83E\uDDD1\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1\",\n sync: \"\uD83D\uDD04\",\n usage: \"\uD83D\uDCCA\",\n};\n\nexport const DEFAULT_EXTENSION_STATUS_ICONS: Record<string, string> = {\n ...DEFAULT_DOCUMENT_EXTENSION_STATUS_ICONS,\n \"codex-usage\": \"\uD83D\uDCCA\",\n pisync: \"\uD83D\uDD04\",\n \"unknown-error-retry\": \"\uD83D\uDD01\",\n};\n\nconst LEGACY_STATUS_ICON_KEYS = {\n pisync: \"sync\",\n \"unknown-error-retry\": \"retry\",\n} as const;\n\nconst DEFAULT_SEGMENTS: SegmentName[] = [...INFORMATION_PROFILES.balanced];\n\nexport const DEFAULT_STATUSLINE_CONFIG: StatuslineConfig = {\n palettePreset: \"tokyo-night\",\n palette: segmentPaletteForPreset(\"tokyo-night\"),\n density: \"compact\",\n separator: \"none\",\n segments: DEFAULT_SEGMENTS,\n segmentText: {\n brand: { prefix: \"\", suffix: \"\" },\n provider: { prefix: \"\uD83D\uDD0C \", suffix: \"\" },\n model: {\n prefix: \"\uD83E\uDD16 \",\n suffix: \"\",\n truncationLength: 36,\n truncationSymbol: \"\u2026\",\n truncationDirection: \"start\",\n },\n thinking: { prefix: \"\uD83E\uDDE0 \", suffix: \"\" },\n cwd: { prefix: \"\uD83D\uDCC1 \", suffix: \"\" },\n branch: { prefix: \"\uD83C\uDF3F \", suffix: \"\" },\n tools: { prefix: \"\", suffix: \"\" },\n context: { prefix: \"\uD83E\uDE9F ctx \", suffix: \"\" },\n tokens: { prefix: \"\uD83D\uDD22 \", suffix: \"\" },\n cache: { prefix: \"\uD83D\uDCE6 \", suffix: \"\" },\n cost: { prefix: \"\uD83D\uDCB8 $\", suffix: \"\" },\n time: { prefix: \"\uD83D\uDD52 \", suffix: \"\" },\n turn: { prefix: \"\uD83D\uDD01 #\", suffix: \"\" },\n },\n extensionStatusIcons: DEFAULT_EXTENSION_STATUS_ICONS,\n};\n\nconst DEFAULT_STATUSLINE_DOCUMENT_CONFIG = {\n palettePreset: DEFAULT_STATUSLINE_CONFIG.palettePreset,\n density: DEFAULT_STATUSLINE_CONFIG.density,\n separator: DEFAULT_STATUSLINE_CONFIG.separator,\n segments: DEFAULT_SEGMENTS,\n segmentText: DEFAULT_STATUSLINE_CONFIG.segmentText,\n extensionStatusIcons: DEFAULT_DOCUMENT_EXTENSION_STATUS_ICONS,\n} satisfies Omit<StatuslineConfig, \"palette\">;\n\nexport const DEFAULT_STATUSLINE_DOCUMENT = `${JSON.stringify(DEFAULT_STATUSLINE_DOCUMENT_CONFIG, null, \"\\t\")}\\n`;\n\nexport interface StatuslineConfigDiagnostic {\n severity: \"warning\" | \"error\";\n code: \"unknown\" | \"invalid\" | \"parse\" | \"io\";\n path: string;\n message: string;\n}\n\nexport interface LoadedStatuslineSettings {\n config: StatuslineConfig;\n source: \"built-in\" | \"user\";\n settingsPath: string;\n rawDocument?: string;\n fileIdentity?: { dev: number; ino: number };\n diagnostics: StatuslineConfigDiagnostic[];\n}\n\ninterface AtomicFileSystem {\n mkdirSync: typeof mkdirSync;\n writeFileSync: typeof writeFileSync;\n renameSync: typeof renameSync;\n rmSync: typeof rmSync;\n}\n\nlet pendingSettingsNotice: string | undefined;\n\nexport function settingsFilePath(agentDir = getAgentDir()): string {\n return join(agentDir, SETTINGS_FILE_NAME);\n}\n\nexport function createDefaultConfig(): StatuslineConfig {\n return cloneConfig(DEFAULT_STATUSLINE_CONFIG);\n}\n\nexport function normalizeStatuslineConfig(value: unknown): {\n config: StatuslineConfig;\n diagnostics: StatuslineConfigDiagnostic[];\n} {\n const config = createDefaultConfig();\n const diagnostics: StatuslineConfigDiagnostic[] = [];\n if (!isRecord(value)) {\n return {\n config,\n diagnostics: [invalidDiagnostic(\"\", \"Settings must contain a JSON object\", \"error\")],\n };\n }\n const knownRoot = new Set([\n \"palettePreset\",\n \"palette\",\n \"density\",\n \"separator\",\n \"segments\",\n \"segmentText\",\n \"extensionStatusIcons\",\n ]);\n for (const key of Object.keys(value)) {\n if (!knownRoot.has(key)) diagnostics.push(unknownDiagnostic(key));\n }\n\n normalizePalette(value.palette, config, diagnostics);\n normalizeEnum(value, \"palettePreset\", PALETTE_PRESET_NAMES, config, diagnostics);\n if (!isRecord(value.palette) && isPaletteName(config.palettePreset)) {\n config.palette = segmentPaletteForPreset(config.palettePreset);\n }\n normalizeEnum(value, \"density\", DENSITIES, config, diagnostics);\n normalizeEnum(value, \"separator\", SEPARATOR_NAMES, config, diagnostics);\n\n if (value.segments !== undefined) {\n if (!Array.isArray(value.segments)) {\n diagnostics.push(invalidDiagnostic(\"segments\", \"Expected an array of segment names\"));\n } else {\n const segments: ConfigSegmentName[] = [];\n const seen = new Set<SegmentName>();\n for (const [index, item] of value.segments.entries()) {\n const path = `segments[${index}]`;\n if (typeof item !== \"string\" || !isConfigSegmentName(item)) {\n diagnostics.push(invalidDiagnostic(path, \"Unknown or non-string segment name\"));\n continue;\n }\n if (item === LINE_BREAK_SEGMENT_NAME) {\n if (segments.at(-1) === LINE_BREAK_SEGMENT_NAME) {\n diagnostics.push(invalidDiagnostic(path, \"Consecutive line_break segments are not allowed\"));\n continue;\n }\n segments.push(item);\n continue;\n }\n if (seen.has(item)) {\n diagnostics.push(invalidDiagnostic(path, `Duplicate segment ${JSON.stringify(item)}`));\n continue;\n }\n seen.add(item);\n segments.push(item);\n }\n config.segments = segments;\n }\n }\n\n if (value.segmentText !== undefined) {\n if (!isRecord(value.segmentText)) {\n diagnostics.push(invalidDiagnostic(\"segmentText\", \"Expected an object\"));\n } else {\n for (const [name, presentation] of Object.entries(value.segmentText)) {\n const path = `segmentText.${name}`;\n if (!isSegmentName(name)) {\n diagnostics.push(unknownDiagnostic(path));\n continue;\n }\n if (!isRecord(presentation)) {\n diagnostics.push(invalidDiagnostic(path, \"Expected an object\"));\n continue;\n }\n const knownFields = new Set([\n \"prefix\",\n \"suffix\",\n ...(name === \"model\" ? [\"truncationLength\", \"truncationSymbol\", \"truncationDirection\"] : []),\n ]);\n for (const key of Object.keys(presentation)) {\n if (!knownFields.has(key)) diagnostics.push(unknownDiagnostic(`${path}.${key}`));\n }\n for (const field of [\"prefix\", \"suffix\"] as const) {\n const fieldValue = presentation[field];\n if (fieldValue === undefined) continue;\n if (!isSafeSegmentText(fieldValue, `${path}.${field}`, diagnostics)) continue;\n config.segmentText[name][field] = fieldValue;\n }\n if (name === \"model\") {\n normalizeModelTruncation(presentation, config, diagnostics);\n }\n }\n }\n }\n\n if (value.extensionStatusIcons !== undefined) {\n if (!isRecord(value.extensionStatusIcons)) {\n diagnostics.push(invalidDiagnostic(\"extensionStatusIcons\", \"Expected an object\"));\n } else {\n for (const [key, icon] of Object.entries(value.extensionStatusIcons)) {\n if (typeof icon !== \"string\") {\n diagnostics.push(invalidDiagnostic(`extensionStatusIcons.${key}`, \"Expected a string\"));\n continue;\n }\n Object.defineProperty(config.extensionStatusIcons, key, {\n value: icon,\n enumerable: true,\n configurable: true,\n writable: true,\n });\n }\n for (const [legacyKey, canonicalKey] of Object.entries(LEGACY_STATUS_ICON_KEYS)) {\n const legacyIcon = Object.hasOwn(value.extensionStatusIcons, legacyKey)\n ? value.extensionStatusIcons[legacyKey]\n : undefined;\n const canonicalIcon = Object.hasOwn(value.extensionStatusIcons, canonicalKey)\n ? value.extensionStatusIcons[canonicalKey]\n : undefined;\n const targetKey = typeof canonicalIcon === \"string\" ? legacyKey : canonicalKey;\n const inheritedIcon =\n typeof canonicalIcon === \"string\" ? canonicalIcon : typeof legacyIcon === \"string\" ? legacyIcon : undefined;\n if (inheritedIcon === undefined) continue;\n Object.defineProperty(config.extensionStatusIcons, targetKey, {\n value: inheritedIcon,\n enumerable: true,\n configurable: true,\n writable: true,\n });\n }\n }\n }\n\n return { config, diagnostics };\n}\n\nexport function loadStatuslineSettings(settingsPath: string): LoadedStatuslineSettings {\n let rawDocument: string;\n try {\n rawDocument = readFileSync(settingsPath, \"utf8\");\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\" && !pathExists(settingsPath)) {\n return builtInSettings(settingsPath);\n }\n return builtInSettings(settingsPath, [\n diagnostic(\"error\", \"io\", \"\", `Unable to read settings: ${formatError(error)}`),\n ]);\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(rawDocument);\n } catch (error) {\n return {\n ...builtInSettings(settingsPath, [\n diagnostic(\"error\", \"parse\", \"\", `Unable to parse JSON: ${formatError(error)}`),\n ]),\n rawDocument,\n };\n }\n const normalized = normalizeStatuslineConfig(parsed);\n return {\n config: normalized.config,\n source: normalized.diagnostics.some((item) => item.severity === \"error\") ? \"built-in\" : \"user\",\n settingsPath,\n rawDocument,\n diagnostics: normalized.diagnostics,\n };\n}\n\nexport function loadStatuslineSettingsForAgent(agentDir = getAgentDir()): LoadedStatuslineSettings {\n pendingSettingsNotice = undefined;\n const canonicalPath = settingsFilePath(agentDir);\n const legacyPath = join(agentDir, LEGACY_SETTINGS_FILE_NAME);\n const canonical = loadStatuslineSettings(canonicalPath);\n if (!isMissingStatuslineSettings(canonical)) {\n if (!isMissingStatuslineSettings(loadStatuslineSettings(legacyPath))) {\n pendingSettingsNotice = `${LEGACY_SETTINGS_FILE_NAME} ignored because ${SETTINGS_FILE_NAME} takes precedence.`;\n }\n return canonical;\n }\n const legacy = loadStatuslineSettings(legacyPath);\n return isMissingStatuslineSettings(legacy) ? canonical : migrateLegacySettings(canonicalPath, legacy);\n}\n\nfunction migrateLegacySettings(canonicalPath: string, legacy: LoadedStatuslineSettings): LoadedStatuslineSettings {\n const racedCanonical = loadStatuslineSettings(canonicalPath);\n if (!isMissingStatuslineSettings(racedCanonical)) {\n pendingSettingsNotice = `${LEGACY_SETTINGS_FILE_NAME} ignored because ${SETTINGS_FILE_NAME} was created concurrently.`;\n return racedCanonical;\n }\n if (\n legacy.source !== \"user\" ||\n legacy.rawDocument === undefined ||\n blockingDiagnostics(legacy.diagnostics).length > 0\n ) {\n pendingSettingsNotice = `${LEGACY_SETTINGS_FILE_NAME} is invalid and was ignored.`;\n return legacy;\n }\n pendingSettingsNotice = `Using legacy ${LEGACY_SETTINGS_FILE_NAME}; rename it to ${SETTINGS_FILE_NAME}. Future saves write ${SETTINGS_FILE_NAME} without modifying the legacy file.`;\n return legacy;\n}\n\nfunction isMissingStatuslineSettings(settings: LoadedStatuslineSettings): boolean {\n return settings.source === \"built-in\" && settings.rawDocument === undefined && settings.diagnostics.length === 0;\n}\n\nexport function saveStatuslineSettingsDocument(\n settingsPath: string,\n rawDocument: string,\n overrides: Partial<AtomicFileSystem> = {},\n): LoadedStatuslineSettings {\n let parsed: unknown;\n try {\n parsed = JSON.parse(rawDocument);\n } catch (error) {\n throw new Error(`Unable to parse JSON: ${formatError(error)}`);\n }\n const normalized = normalizeStatuslineConfig(parsed);\n const blocking = blockingDiagnostics(normalized.diagnostics);\n if (blocking.length > 0) {\n throw new Error(blocking.map((item) => `${item.path || \"root\"}: ${item.message}`).join(\"\\n\"));\n }\n\n const fs = { mkdirSync, writeFileSync, renameSync, rmSync, ...overrides };\n const replaceExisting = pathEntryExists(settingsPath);\n const temporaryPath = temporarySettingsPath(settingsPath);\n let fileIdentity: { dev: number; ino: number } | undefined;\n try {\n fs.mkdirSync(dirname(settingsPath), { recursive: true });\n fs.writeFileSync(temporaryPath, rawDocument, { encoding: \"utf8\", flag: \"wx\" });\n const info = lstatSync(temporaryPath);\n fileIdentity = { dev: info.dev, ino: info.ino };\n if (!replaceExisting && pathEntryExists(settingsPath)) {\n throw new Error(`${SETTINGS_FILE_NAME} was created concurrently; reopen settings and retry.`);\n }\n fs.renameSync(temporaryPath, settingsPath);\n } finally {\n removeTemporaryFile(fs.rmSync, temporaryPath);\n }\n return {\n config: normalized.config,\n source: \"user\",\n settingsPath,\n rawDocument,\n ...(fileIdentity ? { fileIdentity } : {}),\n diagnostics: normalized.diagnostics,\n };\n}\n\nexport function removeStatuslineSettingsDocumentIfMatches(\n settingsPath: string,\n expectedRawDocument: string,\n expectedIdentity: { dev: number; ino: number },\n): void {\n const quarantinePath = join(dirname(settingsPath), `.${SETTINGS_FILE_NAME}.${randomUUID()}.rollback`);\n const before = lstatSync(settingsPath);\n if (before.dev !== expectedIdentity.dev || before.ino !== expectedIdentity.ino) {\n throw new Error(\"Statusline settings changed concurrently; the newer file was preserved\");\n }\n renameSync(settingsPath, quarantinePath);\n const quarantined = lstatSync(quarantinePath);\n const quarantinedSavedFile =\n quarantined.isFile() &&\n !quarantined.isSymbolicLink() &&\n quarantined.dev === expectedIdentity.dev &&\n quarantined.ino === expectedIdentity.ino;\n if (quarantinedSavedFile && readFileSync(quarantinePath, \"utf8\") === expectedRawDocument) {\n rmSync(quarantinePath);\n return;\n }\n if (quarantinedSavedFile && !pathEntryExists(settingsPath)) {\n try {\n renameSync(quarantinePath, settingsPath);\n } catch {\n // Keep the quarantine for recovery when its atomic restoration fails.\n }\n }\n throw new Error(\"Statusline settings changed concurrently; the newer file was preserved\");\n}\n\nexport function consumeStatuslineSettingsNotice(): string | undefined {\n const notice = pendingSettingsNotice;\n pendingSettingsNotice = undefined;\n return notice;\n}\n\nexport function readStatuslineSettings(settingsPath?: string): StatuslineConfig {\n return settingsPath ? loadStatuslineSettings(settingsPath).config : loadStatuslineSettingsForAgent().config;\n}\n\nexport function normalizeStatuslineSettings(value: unknown): StatuslineConfig {\n return normalizeStatuslineConfig(value).config;\n}\n\nfunction normalizePalette(value: unknown, config: StatuslineConfig, diagnostics: StatuslineConfigDiagnostic[]) {\n if (value === undefined) return;\n if (typeof value === \"string\") {\n if (!(PALETTE_NAMES as readonly string[]).includes(value)) {\n diagnostics.push(\n invalidDiagnostic(\"palette\", `Expected a palette object or one of: ${PALETTE_NAMES.join(\", \")}`),\n );\n return;\n }\n config.palettePreset = value as (typeof PALETTE_NAMES)[number];\n return;\n }\n if (!isRecord(value)) {\n diagnostics.push(invalidDiagnostic(\"palette\", \"Expected a palette object\"));\n return;\n }\n\n const palette: SegmentPalette = {};\n config.palette = palette;\n for (const [name, colors] of Object.entries(value)) {\n const path = `palette.${name}`;\n if (!isSegmentName(name)) {\n diagnostics.push(unknownDiagnostic(path));\n continue;\n }\n if (!isRecord(colors)) {\n diagnostics.push(invalidDiagnostic(path, \"Expected an object\"));\n continue;\n }\n const normalizedColors: NonNullable<SegmentPalette[SegmentName]> = {};\n palette[name] = normalizedColors;\n for (const [field, color] of Object.entries(colors)) {\n const colorPath = `${path}.${field}`;\n if (field !== \"fg\" && field !== \"bg\") {\n diagnostics.push(unknownDiagnostic(colorPath));\n continue;\n }\n if (typeof color !== \"string\" || !/^#[0-9a-f]{6}$/iu.test(color)) {\n diagnostics.push(invalidDiagnostic(colorPath, \"Expected a full #RRGGBB hexadecimal color\"));\n continue;\n }\n normalizedColors[field] = color.toLowerCase();\n }\n }\n config.palette = palette;\n config.palettePreset = \"custom\";\n}\n\nfunction normalizeModelTruncation(\n presentation: Record<string, unknown>,\n config: StatuslineConfig,\n diagnostics: StatuslineConfigDiagnostic[],\n) {\n const path = \"segmentText.model\";\n const length = presentation.truncationLength;\n if (length !== undefined) {\n if (typeof length !== \"number\" || !Number.isInteger(length) || length < 0 || length > 1000) {\n diagnostics.push(invalidDiagnostic(`${path}.truncationLength`, \"Expected an integer from 0 through 1000\"));\n } else config.segmentText.model.truncationLength = length;\n }\n\n const symbol = presentation.truncationSymbol;\n if (symbol !== undefined && isSafeSegmentText(symbol, `${path}.truncationSymbol`, diagnostics)) {\n config.segmentText.model.truncationSymbol = symbol;\n }\n\n const direction = presentation.truncationDirection;\n if (direction !== undefined) {\n if (\n typeof direction !== \"string\" ||\n !TRUNCATION_DIRECTIONS.includes(direction as (typeof TRUNCATION_DIRECTIONS)[number])\n ) {\n diagnostics.push(\n invalidDiagnostic(`${path}.truncationDirection`, `Expected one of: ${TRUNCATION_DIRECTIONS.join(\", \")}`),\n );\n } else {\n config.segmentText.model.truncationDirection = direction as (typeof TRUNCATION_DIRECTIONS)[number];\n }\n }\n}\n\nfunction isSafeSegmentText(value: unknown, path: string, diagnostics: StatuslineConfigDiagnostic[]): value is string {\n if (typeof value !== \"string\") {\n diagnostics.push(invalidDiagnostic(path, \"Expected a string\"));\n return false;\n }\n if (/[\\r\\n\\u2028\\u2029]/u.test(value)) {\n diagnostics.push(invalidDiagnostic(path, \"Line breaks are not allowed; use line_break\"));\n return false;\n }\n if (hasControlCharacter(value)) {\n diagnostics.push(invalidDiagnostic(path, \"Control characters are not allowed\"));\n return false;\n }\n return true;\n}\n\nfunction normalizeEnum<K extends \"palettePreset\" | \"density\" | \"separator\", T extends StatuslineConfig[K]>(\n value: Record<string, unknown>,\n field: K,\n accepted: readonly T[],\n config: StatuslineConfig,\n diagnostics: StatuslineConfigDiagnostic[],\n) {\n const candidate = value[field];\n if (candidate === undefined) return;\n if (typeof candidate !== \"string\" || !accepted.includes(candidate as T)) {\n diagnostics.push(invalidDiagnostic(field, `Expected one of: ${accepted.map(String).join(\", \")}`));\n return;\n }\n config[field] = candidate as StatuslineConfig[K];\n}\n\nfunction cloneSegmentPalette(palette: SegmentPalette): SegmentPalette {\n return Object.fromEntries(Object.entries(palette).map(([name, colors]) => [name, { ...colors }])) as SegmentPalette;\n}\n\nfunction cloneConfig(config: StatuslineConfig): StatuslineConfig {\n return {\n ...config,\n palette: cloneSegmentPalette(config.palette),\n segments: [...config.segments],\n segmentText: Object.fromEntries(\n SEGMENT_NAMES.map((name) => [name, { ...config.segmentText[name] }]),\n ) as StatuslineConfig[\"segmentText\"],\n extensionStatusIcons: { ...config.extensionStatusIcons },\n };\n}\n\nfunction builtInSettings(\n settingsPath: string,\n diagnostics: StatuslineConfigDiagnostic[] = [],\n): LoadedStatuslineSettings {\n return {\n config: createDefaultConfig(),\n source: \"built-in\",\n settingsPath,\n diagnostics,\n };\n}\n\nfunction hasControlCharacter(value: string): boolean {\n for (const character of value) {\n const codePoint = character.codePointAt(0) ?? 0;\n if (codePoint <= 0x1f || (codePoint >= 0x7f && codePoint <= 0x9f)) return true;\n }\n return false;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isConfigSegmentName(value: string): value is ConfigSegmentName {\n return value === LINE_BREAK_SEGMENT_NAME || isSegmentName(value);\n}\n\nfunction isPaletteName(value: StatuslineConfig[\"palettePreset\"]): value is PaletteName {\n return (PALETTE_NAMES as readonly StatuslineConfig[\"palettePreset\"][]).includes(value);\n}\n\nfunction isSegmentName(value: string): value is SegmentName {\n return (SEGMENT_NAMES as readonly string[]).includes(value);\n}\n\nfunction blockingDiagnostics(diagnostics: readonly StatuslineConfigDiagnostic[]): StatuslineConfigDiagnostic[] {\n return diagnostics.filter((item) => item.code !== \"unknown\");\n}\n\nfunction unknownDiagnostic(path: string): StatuslineConfigDiagnostic {\n return diagnostic(\"warning\", \"unknown\", path, `Unknown setting ${JSON.stringify(path)}`);\n}\n\nfunction invalidDiagnostic(\n path: string,\n message: string,\n severity: StatuslineConfigDiagnostic[\"severity\"] = \"warning\",\n): StatuslineConfigDiagnostic {\n return diagnostic(severity, \"invalid\", path, message);\n}\n\nfunction diagnostic(\n severity: StatuslineConfigDiagnostic[\"severity\"],\n code: StatuslineConfigDiagnostic[\"code\"],\n path: string,\n message: string,\n): StatuslineConfigDiagnostic {\n return { severity, code, path, message };\n}\n\nfunction temporarySettingsPath(settingsPath: string): string {\n return join(dirname(settingsPath), `.${SETTINGS_FILE_NAME}.${randomUUID()}.tmp`);\n}\n\nfunction removeTemporaryFile(remove: typeof rmSync, temporaryPath: string) {\n try {\n remove(temporaryPath, { force: true });\n } catch {\n // Best-effort cleanup must not replace the original operation result.\n }\n}\n\nfunction pathExists(path: string): boolean {\n try {\n lstatSync(path);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction pathEntryExists(path: string): boolean {\n try {\n lstatSync(path);\n return true;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return false;\n throw error;\n }\n}\n\nfunction formatError(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|