@narumitw/pi-statusline 0.50.2 → 0.50.4

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 ADDED
@@ -0,0 +1,120 @@
1
+ # @narumitw/pi-statusline
2
+
3
+ ## 0.50.4
4
+
5
+ ### Patch Changes
6
+
7
+ - bed3e2b: Retain provider-total provenance across all session usage entries without changing numeric costs. Show the source in `/statusline status` and the optional Starship cost `$source` variable; mixed, legacy, empty, and incomplete totals remain unconfirmed.
8
+ - 54f2700: Preserve fullscreen viewport capture through custom list wrappers so default and configured paging keys reach the focused list. Keep native transcript search, unrelated overlays, free-text modes, paste, and hard cancellation unchanged. Filter Kit key hints according to each screen's capture policy.
9
+
10
+ Update Recall and File Context to the current Kit dependency range. The selected consumer releases require the fixed Kit patch through Changesets dependency-floor updates.
11
+ - e484010: Include the existing package-root CHANGELOG.md in extension tarballs so Pi can show native update notices. Keep Changesets version headings and Pi's first-observation and collapseChangelog behavior unchanged.
12
+ - 0339567: Bound Git status and repository-root output, discard incomplete results, and clear stale status counts after output overflow.
13
+ - Updated dependencies [54f2700]
14
+ - Updated dependencies [6c76ef1]
15
+ - @narumitw/pi-tui-kit@0.69.0
16
+
17
+ ## 0.50.3
18
+
19
+ ### Patch Changes
20
+
21
+ - 9d3e0d7: Unreference passive refresh, debounce, expiry, and background startup timers so they do not keep the host process alive when other work has stopped. Keep normal cancellation and resource cleanup unchanged.
22
+ - Updated dependencies [9d3e0d7]
23
+ - @narumitw/pi-tui-kit@0.68.1
24
+
25
+ ## 0.50.2
26
+
27
+ ### Patch Changes
28
+
29
+ - 8abd5b7: Keep generated extension runtime graphs inside Pi's Jiti-loaded TypeScript path to avoid duplicate peer-runtime evaluation during startup. Add measured generated runtimes for Context Management, Herdr, and TypeSafe Search.
30
+
31
+ ## 0.50.1
32
+
33
+ ### Patch Changes
34
+
35
+ - 67a3049: Adapt provider, transcript, usage, deferred-tool, and telemetry behavior to Pi's current runtime contracts, including accurate cache-warming accounting and exclusion from ordinary generation traces.
36
+
37
+ ## 0.50.0
38
+
39
+ ### Minor Changes
40
+
41
+ - b87641b: Show when Pi is waiting for blocking extension UI input and restore the underlying activity after the prompt closes.
42
+
43
+ Expose `waiting`, `$kind`, and `$title` through pi-starship's activity module.
44
+
45
+ ### Patch Changes
46
+
47
+ - 36a5ad5: Honor Pi's effective terminal capabilities when rendering pull request hyperlinks and RGB footer colors.
48
+
49
+ ## 0.49.15
50
+
51
+ ### Patch Changes
52
+
53
+ - Updated dependencies [40182e5]
54
+ - @narumitw/pi-tui-kit@0.59.0
55
+
56
+ ## 0.49.14
57
+
58
+ ### Patch Changes
59
+
60
+ - dc9802e: Keep Ctrl+C available as a hard-cancel input when configurable cancellation bindings are remapped.
61
+ - Updated dependencies [78276b0]
62
+ - Updated dependencies [dc9802e]
63
+ - @narumitw/pi-tui-kit@0.58.1
64
+
65
+ ## 0.49.13
66
+
67
+ ### Patch Changes
68
+
69
+ - 3346683: Publish generated lazy chunks at the JavaScript paths referenced by each extension runtime so deferred menus and implementations load correctly through Pi's Jiti loader.
70
+ - Updated dependencies [b9eba3a]
71
+ - @narumitw/pi-tui-kit@0.58.0
72
+
73
+ ## 0.49.12
74
+
75
+ ### Patch Changes
76
+
77
+ - Updated dependencies [6574232]
78
+ - Updated dependencies [cddc265]
79
+ - @narumitw/pi-tui-kit@0.57.0
80
+
81
+ ## 0.49.11
82
+
83
+ ### Patch Changes
84
+
85
+ - e7ae16e: Load the extension from a generated split TypeScript runtime to reduce Jiti package startup work while preserving the lazy command boundary.
86
+
87
+ ## 0.49.10
88
+
89
+ ### Patch Changes
90
+
91
+ - 5f0ccd3: Load lightweight Pi TUI Kit helpers without evaluating the full menu runtime during extension startup.
92
+
93
+ ## 0.49.9
94
+
95
+ ### Patch Changes
96
+
97
+ - Updated dependencies [8bead31]
98
+ - @narumitw/pi-tui-kit@0.56.0
99
+
100
+ ## 0.49.8
101
+
102
+ ### Patch Changes
103
+
104
+ - Updated dependencies [3176172]
105
+ - @narumitw/pi-tui-kit@0.55.0
106
+
107
+ ## 0.49.7
108
+
109
+ ### Patch Changes
110
+
111
+ - d26be16: Reuse Pi TUI Kit's display-only terminal sanitizer for footer model, symbol, and path text.
112
+
113
+ ## 0.49.6
114
+
115
+ ### Patch Changes
116
+
117
+ - 247083f: Use Pi TUI Kit's published live-choice interaction for palette previews while preserving statusline-owned settings, rollback, and footer updates.
118
+ - Updated dependencies [4a0358b]
119
+ - Updated dependencies [93b507b]
120
+ - @narumitw/pi-tui-kit@0.53.0
package/README.md CHANGED
@@ -90,7 +90,7 @@ The `tools` segment takes no space while idle.
90
90
  | --- | --- |
91
91
  | `/statusline` | Customize footer appearance, information density, and layout. |
92
92
  | `/statusline settings` | Edit the settings JSON. |
93
- | `/statusline status` | Show effective settings and diagnostics. |
93
+ | `/statusline status` | Show effective settings, session cost source, and diagnostics. |
94
94
  | `/statusline help` | Show command and schema guidance. |
95
95
 
96
96
  The menu and editor require TUI; RPC receives notifications instead, including the manual settings path for `settings`.
@@ -137,6 +137,11 @@ If the last remaining segment is itself wider than the row, that row renders emp
137
137
  This includes assistant messages, nested-LLM tool results, compactions, branch summaries, and persisted cache-warming usage, including abandoned branches retained in the session.
138
138
  - Cache tokens are `R<read>`, `W<write>`, and `CH<rate>`.
139
139
  `R` and `W` are cumulative; `CH` uses only the latest assistant prompt: `cacheRead / (input + cacheRead + cacheWrite) * 100`.
140
+ - `/statusline status` labels session cost as `provider-reported` only for a nonempty, finite total when every included usage record has a finite nonnegative `cost.total` and `cost.totalFromProvider === true`.
141
+ Catalog estimates, mixed provenance, older sessions, empty sessions, and missing totals are `unconfirmed`; records without usage do not contribute.
142
+ - The footer keeps its current cost format and sums Pi's best available `cost.total`, not catalog-estimated components.
143
+ Components can differ from a provider total and do not establish exact prompt-cache savings.
144
+ Session-response costs are separate from account/key quotas and balances.
140
145
  - Subscription-backed OAuth models and `kimi-coding` append `(sub)` to cost.
141
146
  The dollar value is usage cost, not proof of an amount billed under a subscription.
142
147
  - Pi's public extension API does not expose the current auto-compaction toggle, so this footer cannot reliably show the native `(auto)` marker.
@@ -666,6 +666,46 @@ function formatError(error) {
666
666
  return error instanceof Error ? error.message : String(error);
667
667
  }
668
668
 
669
+ // src/usage.ts
670
+ function summarizeFooterUsage(entries) {
671
+ const totals = {
672
+ input: 0,
673
+ output: 0,
674
+ cacheRead: 0,
675
+ cacheWrite: 0,
676
+ cost: 0,
677
+ costTotalFromProvider: false
678
+ };
679
+ let hasUsage = false;
680
+ let allTotalsFromProvider = true;
681
+ for (const entry of entries) {
682
+ let usage;
683
+ if (entry.type === "message" && entry.message.role === "assistant") {
684
+ usage = entry.message.usage;
685
+ const input = usage?.input ?? 0;
686
+ const cacheRead = usage?.cacheRead ?? 0;
687
+ const cacheWrite = usage?.cacheWrite ?? 0;
688
+ const promptTokens = input + cacheRead + cacheWrite;
689
+ totals.latestCacheHitRate = promptTokens > 0 ? cacheRead / promptTokens * 100 : void 0;
690
+ } else if (entry.type === "message" && entry.message.role === "toolResult") {
691
+ usage = entry.message.usage;
692
+ } else if (entry.type === "compaction" || entry.type === "branch_summary" || entry.type === "usage") {
693
+ usage = entry.usage;
694
+ }
695
+ if (!usage) continue;
696
+ totals.input += usage.input ?? 0;
697
+ totals.output += usage.output ?? 0;
698
+ totals.cacheRead += usage.cacheRead ?? 0;
699
+ totals.cacheWrite += usage.cacheWrite ?? 0;
700
+ totals.cost += usage.cost?.total ?? 0;
701
+ hasUsage = true;
702
+ const cost = usage.cost;
703
+ allTotalsFromProvider &&= cost?.totalFromProvider === true && typeof cost.total === "number" && Number.isFinite(cost.total) && cost.total >= 0;
704
+ }
705
+ totals.costTotalFromProvider = hasUsage && allTotalsFromProvider && Number.isFinite(totals.cost);
706
+ return totals;
707
+ }
708
+
669
709
  export {
670
710
  completeStatuslineArguments,
671
711
  SEGMENT_NAMES,
@@ -684,6 +724,7 @@ export {
684
724
  loadStatuslineSettingsForAgent,
685
725
  saveStatuslineSettingsDocument,
686
726
  removeStatuslineSettingsDocumentIfMatches,
687
- consumeStatuslineSettingsNotice
727
+ consumeStatuslineSettingsNotice,
728
+ summarizeFooterUsage
688
729
  };
689
- //# sourceMappingURL=chunk-LARLXEUL.ts.map
730
+ //# sourceMappingURL=chunk-HJJWE7KU.ts.map
@@ -1,7 +1,7 @@
1
1
  {
2
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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",
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", "../../src/usage.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", "import type { SessionEntry } from \"@earendil-works/pi-coding-agent\";\n\ninterface UsageLike {\n input?: number;\n output?: number;\n cacheRead?: number;\n cacheWrite?: number;\n cost?: { total?: number; totalFromProvider?: boolean };\n}\n\nexport interface FooterUsageSummary {\n input: number;\n output: number;\n cacheRead: number;\n cacheWrite: number;\n cost: number;\n costTotalFromProvider: boolean;\n latestCacheHitRate?: number;\n}\n\nexport function summarizeFooterUsage(entries: readonly SessionEntry[]): FooterUsageSummary {\n const totals: FooterUsageSummary = {\n input: 0,\n output: 0,\n cacheRead: 0,\n cacheWrite: 0,\n cost: 0,\n costTotalFromProvider: false,\n };\n let hasUsage = false;\n let allTotalsFromProvider = true;\n\n for (const entry of entries) {\n let usage: UsageLike | undefined;\n if (entry.type === \"message\" && entry.message.role === \"assistant\") {\n usage = entry.message.usage;\n const input = usage?.input ?? 0;\n const cacheRead = usage?.cacheRead ?? 0;\n const cacheWrite = usage?.cacheWrite ?? 0;\n const promptTokens = input + cacheRead + cacheWrite;\n totals.latestCacheHitRate = promptTokens > 0 ? (cacheRead / promptTokens) * 100 : undefined;\n } else if (entry.type === \"message\" && entry.message.role === \"toolResult\") {\n usage = entry.message.usage;\n } else if (entry.type === \"compaction\" || entry.type === \"branch_summary\" || entry.type === \"usage\") {\n usage = entry.usage;\n }\n if (!usage) continue;\n\n totals.input += usage.input ?? 0;\n totals.output += usage.output ?? 0;\n totals.cacheRead += usage.cacheRead ?? 0;\n totals.cacheWrite += usage.cacheWrite ?? 0;\n totals.cost += usage.cost?.total ?? 0;\n hasUsage = true;\n const cost = usage.cost;\n allTotalsFromProvider &&=\n cost?.totalFromProvider === true &&\n typeof cost.total === \"number\" &&\n Number.isFinite(cost.total) &&\n cost.total >= 0;\n }\n\n // Empty or incomplete accounting cannot establish a provider-reported total.\n totals.costTotalFromProvider = hasUsage && allTotalsFromProvider && Number.isFinite(totals.cost);\n return totals;\n}\n"],
5
+ "mappings": ";;;;AAEO,IAAM,yBAAsD;AAAA,EACjE,EAAE,OAAO,YAAY,OAAO,YAAY,aAAa,0BAA0B;AAAA,EAC/E,EAAE,OAAO,UAAU,OAAO,UAAU,aAAa,qCAAqC;AAAA,EACtF,EAAE,OAAO,QAAQ,OAAO,QAAQ,aAAa,0BAA0B;AACzE;AAEO,SAAS,4BAA4B,QAA2C;AACrF,QAAM,aAAa,OAAO,KAAK,EAAE,YAAY;AAC7C,QAAM,UAAU,uBAAuB,OAAO,CAAC,SAAS,KAAK,MAAM,WAAW,UAAU,CAAC;AACzF,SAAO,QAAQ,SAAS,IAAI,CAAC,GAAG,OAAO,IAAI;AAC7C;;;ACVO,IAAM,gBAAgB;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAGO,IAAM,0BAA0B;AAGhC,IAAM,gBAAgB,CAAC,eAAe,SAAS,UAAU,UAAU,SAAS,QAAQ,MAAM;AAG1F,IAAM,uBAAuB,CAAC,GAAG,eAAe,QAAQ;AAGxD,IAAM,YAAY,CAAC,WAAW,MAAM;AAGpC,IAAM,kBAAkB,CAAC,QAAQ,OAAO,OAAO,aAAa,OAAO;AAGnE,IAAM,wBAAwB,CAAC,SAAS,UAAU,KAAK;;;AC/B9D,IAAM,cAAoC,CAAC,UAAU,aAAa,OAAO,WAAW,OAAO;AAIpF,SAAS,iBAAiB,aAA2C;AAC1E,SAAO;AAAA,IACL,MAAM,YAAY,CAAC;AAAA,IACnB,QAAQ,OAAO;AAAA,MACb,YAAY,IAAI,CAAC,OAAO,UAAU;AAChC,cAAM,aAAa,YAAY,KAAK;AACpC,eAAO,CAAC,OAAO,EAAE,IAAI,cAAc,UAAU,GAAG,IAAI,WAAW,CAAC;AAAA,MAClE,CAAC;AAAA,IACH;AAAA,IACA,oBAAoB,YAAY,CAAC;AAAA,EACnC;AACF;AAEA,SAAS,cAAc,KAAqB;AAC1C,QAAM,aAAa,kBAAkB,GAAG;AACxC,QAAM,OAAO,kBAAkB,SAAS;AACxC,QAAM,QAAQ,kBAAkB,SAAS;AACzC,SAAO,cAAc,YAAY,IAAI,KAAK,cAAc,YAAY,KAAK,IAAI,YAAY;AAC3F;AAEA,SAAS,cAAc,MAAc,OAAuB;AAC1D,UAAQ,KAAK,IAAI,MAAM,KAAK,IAAI,SAAS,KAAK,IAAI,MAAM,KAAK,IAAI;AACnE;AAEA,SAAS,kBAAkB,KAAqB;AAC9C,QAAM,aAAa,IAAI,MAAM,CAAC;AAC9B,QAAM,WAAW,CAAC,GAAG,GAAG,CAAC,EAAE,IAAI,CAAC,WAAW;AACzC,UAAM,QAAQ,OAAO,SAAS,WAAW,MAAM,QAAQ,SAAS,CAAC,GAAG,EAAE,IAAI;AAC1E,WAAO,SAAS,UAAU,QAAQ,UAAU,QAAQ,SAAS,UAAU;AAAA,EACzE,CAAC;AACD,SAAO,UAAU,SAAS,CAAC,KAAK,KAAK,UAAU,SAAS,CAAC,KAAK,KAAK,UAAU,SAAS,CAAC,KAAK;AAC9F;;;ACpCO,IAAM,eAAe,iBAAiB,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS,CAAC;;;ACA7F,IAAM,gBAAiC;AAAA,EAC5C,QAAQ;AAAA,IACN,QAAQ,CAAC;AAAA,IACT,WAAW,CAAC;AAAA,IACZ,KAAK,CAAC;AAAA,IACN,SAAS,CAAC;AAAA,IACV,OAAO,CAAC;AAAA,EACV;AACF;;;ACRO,IAAM,gBAAgB,iBAAiB,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS,CAAC;;;ACA9F,IAAM,cAAc,iBAAiB,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS,CAAC;;;ACA5F,IAAM,cAAc,iBAAiB,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS,CAAC;;;ACA5F,IAAM,eAAe,iBAAiB,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS,CAAC;;;ACA7F,IAAM,gBAAgB,iBAAiB,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS,CAAC;;;ACA9F,IAAM,qBAAsC;AAAA,EACjD,MAAM;AAAA,EACN,QAAQ;AAAA,IACN,QAAQ,EAAE,IAAI,WAAW,IAAI,UAAU;AAAA,IACvC,WAAW,EAAE,IAAI,WAAW,IAAI,UAAU;AAAA,IAC1C,KAAK,EAAE,IAAI,WAAW,IAAI,UAAU;AAAA,IACpC,SAAS,EAAE,IAAI,WAAW,IAAI,UAAU;AAAA,IACxC,OAAO,EAAE,IAAI,WAAW,IAAI,UAAU;AAAA,EACxC;AAAA,EACA,oBAAoB;AACtB;;;ACMA,IAAM,UAAU;AAAA,EACd,eAAe;AAAA,EACf,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,MAAM;AAAA,EACN,MAAM;AAAA,EACN,QAAQ;AACV;AAEA,IAAM,iBAA0D;AAAA,EAC9D,OAAO;AAAA,EACP,UAAU;AAAA,EACV,OAAO;AAAA,EACP,UAAU;AAAA,EACV,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AACR;AAEO,SAAS,cAAc,QAAwC;AACpE,SAAO,QAAQ,MAAM;AACvB;AAEO,SAAS,wBAAwB,QAAqC;AAC3E,QAAM,SAAS,QAAQ,MAAM,EAAE;AAC/B,SAAO,OAAO,YAAY,cAAc,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,GAAG,OAAO,eAAe,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;AACpG;;;AClDO,IAAM,4BAA4B,CAAC,WAAW,YAAY,UAAU;AAIpE,IAAM,uBAAyF;AAAA,EACpG,SAAS,CAAC,SAAS,OAAO,UAAU,SAAS;AAAA,EAC7C,UAAU,CAAC,SAAS,YAAY,OAAO,UAAU,SAAS,WAAW,MAAM;AAAA,EAC3E,UAAU,CAAC,YAAY,SAAS,YAAY,OAAO,UAAU,SAAS,WAAW,UAAU,SAAS,QAAQ,MAAM;AACpH;AAEO,SAAS,wBAAwB,UAA4D;AAClG,aAAW,QAAQ,2BAA2B;AAC5C,UAAM,UAAU,qBAAqB,IAAI;AACzC,QAAI,SAAS,WAAW,QAAQ,UAAU,SAAS,MAAM,CAAC,SAAS,UAAU,YAAY,QAAQ,KAAK,CAAC,GAAG;AACxG,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;;;ACpBA,SAAS,kBAAkB;AAC3B,SAAS,WAAW,WAAW,cAAc,YAAY,QAAQ,qBAAqB;AACtF,SAAS,SAAS,YAAY;AAC9B,SAAS,mBAAmB;AAkBrB,IAAM,qBAAqB;AAClC,IAAM,4BAA4B;AAElC,IAAM,0CAAkE;AAAA,EACtE,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,mBAAmB;AAAA,EACnB,WAAW;AAAA,EACX,aAAa;AAAA,EACb,MAAM;AAAA,EACN,gBAAgB;AAAA,EAChB,KAAK;AAAA,EACL,aAAa;AAAA,EACb,OAAO;AAAA,EACP,WAAW;AAAA,EACX,MAAM;AAAA,EACN,OAAO;AACT;AAEO,IAAM,iCAAyD;AAAA,EACpE,GAAG;AAAA,EACH,eAAe;AAAA,EACf,QAAQ;AAAA,EACR,uBAAuB;AACzB;AAEA,IAAM,0BAA0B;AAAA,EAC9B,QAAQ;AAAA,EACR,uBAAuB;AACzB;AAEA,IAAM,mBAAkC,CAAC,GAAG,qBAAqB,QAAQ;AAElE,IAAM,4BAA8C;AAAA,EACzD,eAAe;AAAA,EACf,SAAS,wBAAwB,aAAa;AAAA,EAC9C,SAAS;AAAA,EACT,WAAW;AAAA,EACX,UAAU;AAAA,EACV,aAAa;AAAA,IACX,OAAO,EAAE,QAAQ,IAAI,QAAQ,GAAG;AAAA,IAChC,UAAU,EAAE,QAAQ,cAAO,QAAQ,GAAG;AAAA,IACtC,OAAO;AAAA,MACL,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,kBAAkB;AAAA,MAClB,kBAAkB;AAAA,MAClB,qBAAqB;AAAA,IACvB;AAAA,IACA,UAAU,EAAE,QAAQ,cAAO,QAAQ,GAAG;AAAA,IACtC,KAAK,EAAE,QAAQ,cAAO,QAAQ,GAAG;AAAA,IACjC,QAAQ,EAAE,QAAQ,cAAO,QAAQ,GAAG;AAAA,IACpC,OAAO,EAAE,QAAQ,IAAI,QAAQ,GAAG;AAAA,IAChC,SAAS,EAAE,QAAQ,kBAAW,QAAQ,GAAG;AAAA,IACzC,QAAQ,EAAE,QAAQ,cAAO,QAAQ,GAAG;AAAA,IACpC,OAAO,EAAE,QAAQ,cAAO,QAAQ,GAAG;AAAA,IACnC,MAAM,EAAE,QAAQ,eAAQ,QAAQ,GAAG;AAAA,IACnC,MAAM,EAAE,QAAQ,cAAO,QAAQ,GAAG;AAAA,IAClC,MAAM,EAAE,QAAQ,eAAQ,QAAQ,GAAG;AAAA,EACrC;AAAA,EACA,sBAAsB;AACxB;AAEA,IAAM,qCAAqC;AAAA,EACzC,eAAe,0BAA0B;AAAA,EACzC,SAAS,0BAA0B;AAAA,EACnC,WAAW,0BAA0B;AAAA,EACrC,UAAU;AAAA,EACV,aAAa,0BAA0B;AAAA,EACvC,sBAAsB;AACxB;AAEO,IAAM,8BAA8B,GAAG,KAAK,UAAU,oCAAoC,MAAM,GAAI,CAAC;AAAA;AAyB5G,IAAI;AAEG,SAAS,iBAAiB,WAAW,YAAY,GAAW;AACjE,SAAO,KAAK,UAAU,kBAAkB;AAC1C;AAEO,SAAS,sBAAwC;AACtD,SAAO,YAAY,yBAAyB;AAC9C;AAEO,SAAS,0BAA0B,OAGxC;AACA,QAAM,SAAS,oBAAoB;AACnC,QAAM,cAA4C,CAAC;AACnD,MAAI,CAAC,SAAS,KAAK,GAAG;AACpB,WAAO;AAAA,MACL;AAAA,MACA,aAAa,CAAC,kBAAkB,IAAI,uCAAuC,OAAO,CAAC;AAAA,IACrF;AAAA,EACF;AACA,QAAM,YAAY,oBAAI,IAAI;AAAA,IACxB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACD,aAAW,OAAO,OAAO,KAAK,KAAK,GAAG;AACpC,QAAI,CAAC,UAAU,IAAI,GAAG,EAAG,aAAY,KAAK,kBAAkB,GAAG,CAAC;AAAA,EAClE;AAEA,mBAAiB,MAAM,SAAS,QAAQ,WAAW;AACnD,gBAAc,OAAO,iBAAiB,sBAAsB,QAAQ,WAAW;AAC/E,MAAI,CAAC,SAAS,MAAM,OAAO,KAAK,cAAc,OAAO,aAAa,GAAG;AACnE,WAAO,UAAU,wBAAwB,OAAO,aAAa;AAAA,EAC/D;AACA,gBAAc,OAAO,WAAW,WAAW,QAAQ,WAAW;AAC9D,gBAAc,OAAO,aAAa,iBAAiB,QAAQ,WAAW;AAEtE,MAAI,MAAM,aAAa,QAAW;AAChC,QAAI,CAAC,MAAM,QAAQ,MAAM,QAAQ,GAAG;AAClC,kBAAY,KAAK,kBAAkB,YAAY,oCAAoC,CAAC;AAAA,IACtF,OAAO;AACL,YAAM,WAAgC,CAAC;AACvC,YAAM,OAAO,oBAAI,IAAiB;AAClC,iBAAW,CAAC,OAAO,IAAI,KAAK,MAAM,SAAS,QAAQ,GAAG;AACpD,cAAM,OAAO,YAAY,KAAK;AAC9B,YAAI,OAAO,SAAS,YAAY,CAAC,oBAAoB,IAAI,GAAG;AAC1D,sBAAY,KAAK,kBAAkB,MAAM,oCAAoC,CAAC;AAC9E;AAAA,QACF;AACA,YAAI,SAAS,yBAAyB;AACpC,cAAI,SAAS,GAAG,EAAE,MAAM,yBAAyB;AAC/C,wBAAY,KAAK,kBAAkB,MAAM,iDAAiD,CAAC;AAC3F;AAAA,UACF;AACA,mBAAS,KAAK,IAAI;AAClB;AAAA,QACF;AACA,YAAI,KAAK,IAAI,IAAI,GAAG;AAClB,sBAAY,KAAK,kBAAkB,MAAM,qBAAqB,KAAK,UAAU,IAAI,CAAC,EAAE,CAAC;AACrF;AAAA,QACF;AACA,aAAK,IAAI,IAAI;AACb,iBAAS,KAAK,IAAI;AAAA,MACpB;AACA,aAAO,WAAW;AAAA,IACpB;AAAA,EACF;AAEA,MAAI,MAAM,gBAAgB,QAAW;AACnC,QAAI,CAAC,SAAS,MAAM,WAAW,GAAG;AAChC,kBAAY,KAAK,kBAAkB,eAAe,oBAAoB,CAAC;AAAA,IACzE,OAAO;AACL,iBAAW,CAAC,MAAM,YAAY,KAAK,OAAO,QAAQ,MAAM,WAAW,GAAG;AACpE,cAAM,OAAO,eAAe,IAAI;AAChC,YAAI,CAAC,cAAc,IAAI,GAAG;AACxB,sBAAY,KAAK,kBAAkB,IAAI,CAAC;AACxC;AAAA,QACF;AACA,YAAI,CAAC,SAAS,YAAY,GAAG;AAC3B,sBAAY,KAAK,kBAAkB,MAAM,oBAAoB,CAAC;AAC9D;AAAA,QACF;AACA,cAAM,cAAc,oBAAI,IAAI;AAAA,UAC1B;AAAA,UACA;AAAA,UACA,GAAI,SAAS,UAAU,CAAC,oBAAoB,oBAAoB,qBAAqB,IAAI,CAAC;AAAA,QAC5F,CAAC;AACD,mBAAW,OAAO,OAAO,KAAK,YAAY,GAAG;AAC3C,cAAI,CAAC,YAAY,IAAI,GAAG,EAAG,aAAY,KAAK,kBAAkB,GAAG,IAAI,IAAI,GAAG,EAAE,CAAC;AAAA,QACjF;AACA,mBAAW,SAAS,CAAC,UAAU,QAAQ,GAAY;AACjD,gBAAM,aAAa,aAAa,KAAK;AACrC,cAAI,eAAe,OAAW;AAC9B,cAAI,CAAC,kBAAkB,YAAY,GAAG,IAAI,IAAI,KAAK,IAAI,WAAW,EAAG;AACrE,iBAAO,YAAY,IAAI,EAAE,KAAK,IAAI;AAAA,QACpC;AACA,YAAI,SAAS,SAAS;AACpB,mCAAyB,cAAc,QAAQ,WAAW;AAAA,QAC5D;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,MAAI,MAAM,yBAAyB,QAAW;AAC5C,QAAI,CAAC,SAAS,MAAM,oBAAoB,GAAG;AACzC,kBAAY,KAAK,kBAAkB,wBAAwB,oBAAoB,CAAC;AAAA,IAClF,OAAO;AACL,iBAAW,CAAC,KAAK,IAAI,KAAK,OAAO,QAAQ,MAAM,oBAAoB,GAAG;AACpE,YAAI,OAAO,SAAS,UAAU;AAC5B,sBAAY,KAAK,kBAAkB,wBAAwB,GAAG,IAAI,mBAAmB,CAAC;AACtF;AAAA,QACF;AACA,eAAO,eAAe,OAAO,sBAAsB,KAAK;AAAA,UACtD,OAAO;AAAA,UACP,YAAY;AAAA,UACZ,cAAc;AAAA,UACd,UAAU;AAAA,QACZ,CAAC;AAAA,MACH;AACA,iBAAW,CAAC,WAAW,YAAY,KAAK,OAAO,QAAQ,uBAAuB,GAAG;AAC/E,cAAM,aAAa,OAAO,OAAO,MAAM,sBAAsB,SAAS,IAClE,MAAM,qBAAqB,SAAS,IACpC;AACJ,cAAM,gBAAgB,OAAO,OAAO,MAAM,sBAAsB,YAAY,IACxE,MAAM,qBAAqB,YAAY,IACvC;AACJ,cAAM,YAAY,OAAO,kBAAkB,WAAW,YAAY;AAClE,cAAM,gBACJ,OAAO,kBAAkB,WAAW,gBAAgB,OAAO,eAAe,WAAW,aAAa;AACpG,YAAI,kBAAkB,OAAW;AACjC,eAAO,eAAe,OAAO,sBAAsB,WAAW;AAAA,UAC5D,OAAO;AAAA,UACP,YAAY;AAAA,UACZ,cAAc;AAAA,UACd,UAAU;AAAA,QACZ,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAEA,SAAO,EAAE,QAAQ,YAAY;AAC/B;AAEO,SAAS,uBAAuB,cAAgD;AACrF,MAAI;AACJ,MAAI;AACF,kBAAc,aAAa,cAAc,MAAM;AAAA,EACjD,SAAS,OAAO;AACd,QAAK,MAAgC,SAAS,YAAY,CAAC,WAAW,YAAY,GAAG;AACnF,aAAO,gBAAgB,YAAY;AAAA,IACrC;AACA,WAAO,gBAAgB,cAAc;AAAA,MACnC,WAAW,SAAS,MAAM,IAAI,4BAA4B,YAAY,KAAK,CAAC,EAAE;AAAA,IAChF,CAAC;AAAA,EACH;AAEA,MAAI;AACJ,MAAI;AACF,aAAS,KAAK,MAAM,WAAW;AAAA,EACjC,SAAS,OAAO;AACd,WAAO;AAAA,MACL,GAAG,gBAAgB,cAAc;AAAA,QAC/B,WAAW,SAAS,SAAS,IAAI,yBAAyB,YAAY,KAAK,CAAC,EAAE;AAAA,MAChF,CAAC;AAAA,MACD;AAAA,IACF;AAAA,EACF;AACA,QAAM,aAAa,0BAA0B,MAAM;AACnD,SAAO;AAAA,IACL,QAAQ,WAAW;AAAA,IACnB,QAAQ,WAAW,YAAY,KAAK,CAAC,SAAS,KAAK,aAAa,OAAO,IAAI,aAAa;AAAA,IACxF;AAAA,IACA;AAAA,IACA,aAAa,WAAW;AAAA,EAC1B;AACF;AAEO,SAAS,+BAA+B,WAAW,YAAY,GAA6B;AACjG,0BAAwB;AACxB,QAAM,gBAAgB,iBAAiB,QAAQ;AAC/C,QAAM,aAAa,KAAK,UAAU,yBAAyB;AAC3D,QAAM,YAAY,uBAAuB,aAAa;AACtD,MAAI,CAAC,4BAA4B,SAAS,GAAG;AAC3C,QAAI,CAAC,4BAA4B,uBAAuB,UAAU,CAAC,GAAG;AACpE,8BAAwB,GAAG,yBAAyB,oBAAoB,kBAAkB;AAAA,IAC5F;AACA,WAAO;AAAA,EACT;AACA,QAAM,SAAS,uBAAuB,UAAU;AAChD,SAAO,4BAA4B,MAAM,IAAI,YAAY,sBAAsB,eAAe,MAAM;AACtG;AAEA,SAAS,sBAAsB,eAAuB,QAA4D;AAChH,QAAM,iBAAiB,uBAAuB,aAAa;AAC3D,MAAI,CAAC,4BAA4B,cAAc,GAAG;AAChD,4BAAwB,GAAG,yBAAyB,oBAAoB,kBAAkB;AAC1F,WAAO;AAAA,EACT;AACA,MACE,OAAO,WAAW,UAClB,OAAO,gBAAgB,UACvB,oBAAoB,OAAO,WAAW,EAAE,SAAS,GACjD;AACA,4BAAwB,GAAG,yBAAyB;AACpD,WAAO;AAAA,EACT;AACA,0BAAwB,gBAAgB,yBAAyB,kBAAkB,kBAAkB,wBAAwB,kBAAkB;AAC/I,SAAO;AACT;AAEA,SAAS,4BAA4B,UAA6C;AAChF,SAAO,SAAS,WAAW,cAAc,SAAS,gBAAgB,UAAa,SAAS,YAAY,WAAW;AACjH;AAEO,SAAS,+BACd,cACA,aACA,YAAuC,CAAC,GACd;AAC1B,MAAI;AACJ,MAAI;AACF,aAAS,KAAK,MAAM,WAAW;AAAA,EACjC,SAAS,OAAO;AACd,UAAM,IAAI,MAAM,yBAAyB,YAAY,KAAK,CAAC,EAAE;AAAA,EAC/D;AACA,QAAM,aAAa,0BAA0B,MAAM;AACnD,QAAM,WAAW,oBAAoB,WAAW,WAAW;AAC3D,MAAI,SAAS,SAAS,GAAG;AACvB,UAAM,IAAI,MAAM,SAAS,IAAI,CAAC,SAAS,GAAG,KAAK,QAAQ,MAAM,KAAK,KAAK,OAAO,EAAE,EAAE,KAAK,IAAI,CAAC;AAAA,EAC9F;AAEA,QAAM,KAAK,EAAE,WAAW,eAAe,YAAY,QAAQ,GAAG,UAAU;AACxE,QAAM,kBAAkB,gBAAgB,YAAY;AACpD,QAAM,gBAAgB,sBAAsB,YAAY;AACxD,MAAI;AACJ,MAAI;AACF,OAAG,UAAU,QAAQ,YAAY,GAAG,EAAE,WAAW,KAAK,CAAC;AACvD,OAAG,cAAc,eAAe,aAAa,EAAE,UAAU,QAAQ,MAAM,KAAK,CAAC;AAC7E,UAAM,OAAO,UAAU,aAAa;AACpC,mBAAe,EAAE,KAAK,KAAK,KAAK,KAAK,KAAK,IAAI;AAC9C,QAAI,CAAC,mBAAmB,gBAAgB,YAAY,GAAG;AACrD,YAAM,IAAI,MAAM,GAAG,kBAAkB,uDAAuD;AAAA,IAC9F;AACA,OAAG,WAAW,eAAe,YAAY;AAAA,EAC3C,UAAE;AACA,wBAAoB,GAAG,QAAQ,aAAa;AAAA,EAC9C;AACA,SAAO;AAAA,IACL,QAAQ,WAAW;AAAA,IACnB,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA,GAAI,eAAe,EAAE,aAAa,IAAI,CAAC;AAAA,IACvC,aAAa,WAAW;AAAA,EAC1B;AACF;AAEO,SAAS,0CACd,cACA,qBACA,kBACM;AACN,QAAM,iBAAiB,KAAK,QAAQ,YAAY,GAAG,IAAI,kBAAkB,IAAI,WAAW,CAAC,WAAW;AACpG,QAAM,SAAS,UAAU,YAAY;AACrC,MAAI,OAAO,QAAQ,iBAAiB,OAAO,OAAO,QAAQ,iBAAiB,KAAK;AAC9E,UAAM,IAAI,MAAM,wEAAwE;AAAA,EAC1F;AACA,aAAW,cAAc,cAAc;AACvC,QAAM,cAAc,UAAU,cAAc;AAC5C,QAAM,uBACJ,YAAY,OAAO,KACnB,CAAC,YAAY,eAAe,KAC5B,YAAY,QAAQ,iBAAiB,OACrC,YAAY,QAAQ,iBAAiB;AACvC,MAAI,wBAAwB,aAAa,gBAAgB,MAAM,MAAM,qBAAqB;AACxF,WAAO,cAAc;AACrB;AAAA,EACF;AACA,MAAI,wBAAwB,CAAC,gBAAgB,YAAY,GAAG;AAC1D,QAAI;AACF,iBAAW,gBAAgB,YAAY;AAAA,IACzC,QAAQ;AAAA,IAER;AAAA,EACF;AACA,QAAM,IAAI,MAAM,wEAAwE;AAC1F;AAEO,SAAS,kCAAsD;AACpE,QAAM,SAAS;AACf,0BAAwB;AACxB,SAAO;AACT;AAUA,SAAS,iBAAiB,OAAgB,QAA0B,aAA2C;AAC7G,MAAI,UAAU,OAAW;AACzB,MAAI,OAAO,UAAU,UAAU;AAC7B,QAAI,CAAE,cAAoC,SAAS,KAAK,GAAG;AACzD,kBAAY;AAAA,QACV,kBAAkB,WAAW,wCAAwC,cAAc,KAAK,IAAI,CAAC,EAAE;AAAA,MACjG;AACA;AAAA,IACF;AACA,WAAO,gBAAgB;AACvB;AAAA,EACF;AACA,MAAI,CAAC,SAAS,KAAK,GAAG;AACpB,gBAAY,KAAK,kBAAkB,WAAW,2BAA2B,CAAC;AAC1E;AAAA,EACF;AAEA,QAAM,UAA0B,CAAC;AACjC,SAAO,UAAU;AACjB,aAAW,CAAC,MAAM,MAAM,KAAK,OAAO,QAAQ,KAAK,GAAG;AAClD,UAAM,OAAO,WAAW,IAAI;AAC5B,QAAI,CAAC,cAAc,IAAI,GAAG;AACxB,kBAAY,KAAK,kBAAkB,IAAI,CAAC;AACxC;AAAA,IACF;AACA,QAAI,CAAC,SAAS,MAAM,GAAG;AACrB,kBAAY,KAAK,kBAAkB,MAAM,oBAAoB,CAAC;AAC9D;AAAA,IACF;AACA,UAAM,mBAA6D,CAAC;AACpE,YAAQ,IAAI,IAAI;AAChB,eAAW,CAAC,OAAO,KAAK,KAAK,OAAO,QAAQ,MAAM,GAAG;AACnD,YAAM,YAAY,GAAG,IAAI,IAAI,KAAK;AAClC,UAAI,UAAU,QAAQ,UAAU,MAAM;AACpC,oBAAY,KAAK,kBAAkB,SAAS,CAAC;AAC7C;AAAA,MACF;AACA,UAAI,OAAO,UAAU,YAAY,CAAC,mBAAmB,KAAK,KAAK,GAAG;AAChE,oBAAY,KAAK,kBAAkB,WAAW,2CAA2C,CAAC;AAC1F;AAAA,MACF;AACA,uBAAiB,KAAK,IAAI,MAAM,YAAY;AAAA,IAC9C;AAAA,EACF;AACA,SAAO,UAAU;AACjB,SAAO,gBAAgB;AACzB;AAEA,SAAS,yBACP,cACA,QACA,aACA;AACA,QAAM,OAAO;AACb,QAAM,SAAS,aAAa;AAC5B,MAAI,WAAW,QAAW;AACxB,QAAI,OAAO,WAAW,YAAY,CAAC,OAAO,UAAU,MAAM,KAAK,SAAS,KAAK,SAAS,KAAM;AAC1F,kBAAY,KAAK,kBAAkB,GAAG,IAAI,qBAAqB,yCAAyC,CAAC;AAAA,IAC3G,MAAO,QAAO,YAAY,MAAM,mBAAmB;AAAA,EACrD;AAEA,QAAM,SAAS,aAAa;AAC5B,MAAI,WAAW,UAAa,kBAAkB,QAAQ,GAAG,IAAI,qBAAqB,WAAW,GAAG;AAC9F,WAAO,YAAY,MAAM,mBAAmB;AAAA,EAC9C;AAEA,QAAM,YAAY,aAAa;AAC/B,MAAI,cAAc,QAAW;AAC3B,QACE,OAAO,cAAc,YACrB,CAAC,sBAAsB,SAAS,SAAmD,GACnF;AACA,kBAAY;AAAA,QACV,kBAAkB,GAAG,IAAI,wBAAwB,oBAAoB,sBAAsB,KAAK,IAAI,CAAC,EAAE;AAAA,MACzG;AAAA,IACF,OAAO;AACL,aAAO,YAAY,MAAM,sBAAsB;AAAA,IACjD;AAAA,EACF;AACF;AAEA,SAAS,kBAAkB,OAAgB,MAAc,aAA4D;AACnH,MAAI,OAAO,UAAU,UAAU;AAC7B,gBAAY,KAAK,kBAAkB,MAAM,mBAAmB,CAAC;AAC7D,WAAO;AAAA,EACT;AACA,MAAI,sBAAsB,KAAK,KAAK,GAAG;AACrC,gBAAY,KAAK,kBAAkB,MAAM,6CAA6C,CAAC;AACvF,WAAO;AAAA,EACT;AACA,MAAI,oBAAoB,KAAK,GAAG;AAC9B,gBAAY,KAAK,kBAAkB,MAAM,oCAAoC,CAAC;AAC9E,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,SAAS,cACP,OACA,OACA,UACA,QACA,aACA;AACA,QAAM,YAAY,MAAM,KAAK;AAC7B,MAAI,cAAc,OAAW;AAC7B,MAAI,OAAO,cAAc,YAAY,CAAC,SAAS,SAAS,SAAc,GAAG;AACvE,gBAAY,KAAK,kBAAkB,OAAO,oBAAoB,SAAS,IAAI,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;AAChG;AAAA,EACF;AACA,SAAO,KAAK,IAAI;AAClB;AAEA,SAAS,oBAAoB,SAAyC;AACpE,SAAO,OAAO,YAAY,OAAO,QAAQ,OAAO,EAAE,IAAI,CAAC,CAAC,MAAM,MAAM,MAAM,CAAC,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC;AAClG;AAEA,SAAS,YAAY,QAA4C;AAC/D,SAAO;AAAA,IACL,GAAG;AAAA,IACH,SAAS,oBAAoB,OAAO,OAAO;AAAA,IAC3C,UAAU,CAAC,GAAG,OAAO,QAAQ;AAAA,IAC7B,aAAa,OAAO;AAAA,MAClB,cAAc,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,GAAG,OAAO,YAAY,IAAI,EAAE,CAAC,CAAC;AAAA,IACrE;AAAA,IACA,sBAAsB,EAAE,GAAG,OAAO,qBAAqB;AAAA,EACzD;AACF;AAEA,SAAS,gBACP,cACA,cAA4C,CAAC,GACnB;AAC1B,SAAO;AAAA,IACL,QAAQ,oBAAoB;AAAA,IAC5B,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,oBAAoB,OAAwB;AACnD,aAAW,aAAa,OAAO;AAC7B,UAAM,YAAY,UAAU,YAAY,CAAC,KAAK;AAC9C,QAAI,aAAa,MAAS,aAAa,OAAQ,aAAa,IAAO,QAAO;AAAA,EAC5E;AACA,SAAO;AACT;AAEA,SAAS,SAAS,OAAkD;AAClE,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAAS,oBAAoB,OAA2C;AACtE,SAAO,UAAU,2BAA2B,cAAc,KAAK;AACjE;AAEA,SAAS,cAAc,OAAgE;AACrF,SAAQ,cAA+D,SAAS,KAAK;AACvF;AAEA,SAAS,cAAc,OAAqC;AAC1D,SAAQ,cAAoC,SAAS,KAAK;AAC5D;AAEA,SAAS,oBAAoB,aAAkF;AAC7G,SAAO,YAAY,OAAO,CAAC,SAAS,KAAK,SAAS,SAAS;AAC7D;AAEA,SAAS,kBAAkB,MAA0C;AACnE,SAAO,WAAW,WAAW,WAAW,MAAM,mBAAmB,KAAK,UAAU,IAAI,CAAC,EAAE;AACzF;AAEA,SAAS,kBACP,MACA,SACA,WAAmD,WACvB;AAC5B,SAAO,WAAW,UAAU,WAAW,MAAM,OAAO;AACtD;AAEA,SAAS,WACP,UACA,MACA,MACA,SAC4B;AAC5B,SAAO,EAAE,UAAU,MAAM,MAAM,QAAQ;AACzC;AAEA,SAAS,sBAAsB,cAA8B;AAC3D,SAAO,KAAK,QAAQ,YAAY,GAAG,IAAI,kBAAkB,IAAI,WAAW,CAAC,MAAM;AACjF;AAEA,SAAS,oBAAoB,QAAuB,eAAuB;AACzE,MAAI;AACF,WAAO,eAAe,EAAE,OAAO,KAAK,CAAC;AAAA,EACvC,QAAQ;AAAA,EAER;AACF;AAEA,SAAS,WAAW,MAAuB;AACzC,MAAI;AACF,cAAU,IAAI;AACd,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,gBAAgB,MAAuB;AAC9C,MAAI;AACF,cAAU,IAAI;AACd,WAAO;AAAA,EACT,SAAS,OAAO;AACd,QAAK,MAAgC,SAAS,SAAU,QAAO;AAC/D,UAAM;AAAA,EACR;AACF;AAEA,SAAS,YAAY,OAAwB;AAC3C,SAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC9D;;;ACrnBO,SAAS,qBAAqB,SAAsD;AACzF,QAAM,SAA6B;AAAA,IACjC,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,YAAY;AAAA,IACZ,MAAM;AAAA,IACN,uBAAuB;AAAA,EACzB;AACA,MAAI,WAAW;AACf,MAAI,wBAAwB;AAE5B,aAAW,SAAS,SAAS;AAC3B,QAAI;AACJ,QAAI,MAAM,SAAS,aAAa,MAAM,QAAQ,SAAS,aAAa;AAClE,cAAQ,MAAM,QAAQ;AACtB,YAAM,QAAQ,OAAO,SAAS;AAC9B,YAAM,YAAY,OAAO,aAAa;AACtC,YAAM,aAAa,OAAO,cAAc;AACxC,YAAM,eAAe,QAAQ,YAAY;AACzC,aAAO,qBAAqB,eAAe,IAAK,YAAY,eAAgB,MAAM;AAAA,IACpF,WAAW,MAAM,SAAS,aAAa,MAAM,QAAQ,SAAS,cAAc;AAC1E,cAAQ,MAAM,QAAQ;AAAA,IACxB,WAAW,MAAM,SAAS,gBAAgB,MAAM,SAAS,oBAAoB,MAAM,SAAS,SAAS;AACnG,cAAQ,MAAM;AAAA,IAChB;AACA,QAAI,CAAC,MAAO;AAEZ,WAAO,SAAS,MAAM,SAAS;AAC/B,WAAO,UAAU,MAAM,UAAU;AACjC,WAAO,aAAa,MAAM,aAAa;AACvC,WAAO,cAAc,MAAM,cAAc;AACzC,WAAO,QAAQ,MAAM,MAAM,SAAS;AACpC,eAAW;AACX,UAAM,OAAO,MAAM;AACnB,8BACE,MAAM,sBAAsB,QAC5B,OAAO,KAAK,UAAU,YACtB,OAAO,SAAS,KAAK,KAAK,KAC1B,KAAK,SAAS;AAAA,EAClB;AAGA,SAAO,wBAAwB,YAAY,yBAAyB,OAAO,SAAS,OAAO,IAAI;AAC/F,SAAO;AACT;",
6
6
  "names": []
7
7
  }
@@ -12,8 +12,9 @@ import {
12
12
  inferInformationProfile,
13
13
  removeStatuslineSettingsDocumentIfMatches,
14
14
  saveStatuslineSettingsDocument,
15
- segmentPaletteForPreset
16
- } from "./chunk-LARLXEUL.ts";
15
+ segmentPaletteForPreset,
16
+ summarizeFooterUsage
17
+ } from "./chunk-HJJWE7KU.ts";
17
18
 
18
19
  // src/commands.ts
19
20
  import {
@@ -406,6 +407,7 @@ async function chooseSegments(ctx, options) {
406
407
  };
407
408
  updateThemedText();
408
409
  return {
410
+ capturesViewportInput: true,
409
411
  render: (width) => container.render(width),
410
412
  invalidate() {
411
413
  container.invalidate();
@@ -671,6 +673,8 @@ function editableSettings(current, action) {
671
673
  function showStatus(ctx, options) {
672
674
  if (!canNotify(ctx)) return;
673
675
  const loaded = options.getLoaded();
676
+ const usage = summarizeFooterUsage(ctx.sessionManager.getEntries());
677
+ const costSource = usage.costTotalFromProvider ? "provider-reported" : "unconfirmed";
674
678
  const diagnostics = loaded.diagnostics.slice(0, 5).map((item) => `${item.path || "root"}: ${item.message}`).join("; ");
675
679
  ctx.ui.notify(
676
680
  [
@@ -682,6 +686,7 @@ function showStatus(ctx, options) {
682
686
  `separator: ${loaded.config.separator}`,
683
687
  `information: ${inferInformationProfile(loaded.config.segments)}`,
684
688
  `segments: ${loaded.config.segments.join(", ") || "none"}`,
689
+ `session cost: $${usage.cost.toFixed(usage.cost >= 1 ? 2 : 3)} (${costSource})`,
685
690
  diagnostics ? `warnings: ${diagnostics}` : "warnings: none"
686
691
  ].join("\n"),
687
692
  loaded.diagnostics.length > 0 ? "warning" : "info"
@@ -693,7 +698,7 @@ function showHelp(ctx, settingsPath) {
693
698
  [
694
699
  "/statusline \u2014 open Appearance, Information, Advanced, Status, and Help",
695
700
  "/statusline settings \u2014 edit and apply JSON",
696
- "/statusline status \u2014 show source, path, information level, and warnings",
701
+ "/statusline status \u2014 show settings, session cost source, and warnings",
697
702
  "/statusline help \u2014 show this help",
698
703
  "Menu actions: Appearance, Information, Advanced, Status, Help.",
699
704
  "Information levels: minimal, balanced, detailed; any other segment array is custom.",
@@ -727,4 +732,4 @@ export {
727
732
  handleStatuslineCommand,
728
733
  registerStatuslineCommand
729
734
  };
730
- //# sourceMappingURL=commands-KDWSOSZZ.ts.map
735
+ //# sourceMappingURL=commands-WV3JHCQ6.ts.map