@narumitw/pi-statusline 0.50.0 → 0.50.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -209
- package/dist/chunks/{chunk-74QZGJ7L.js → chunk-LARLXEUL.ts} +18 -97
- package/dist/chunks/chunk-LARLXEUL.ts.map +7 -0
- package/dist/chunks/{commands-C2G2G7C6.js → commands-KDWSOSZZ.ts} +14 -58
- package/dist/chunks/commands-KDWSOSZZ.ts.map +7 -0
- package/dist/index.ts +21 -76
- package/dist/index.ts.map +2 -2
- package/docs/configuration.md +194 -0
- package/package.json +51 -51
- package/src/ansi.ts +18 -24
- package/src/command-contract.ts +6 -6
- package/src/commands.ts +759 -818
- package/src/directory.ts +27 -31
- package/src/extension-status.ts +186 -219
- package/src/git-status.ts +103 -111
- package/src/information-profiles.ts +12 -31
- package/src/powerline.ts +120 -127
- package/src/presets/candy.ts +1 -7
- package/src/presets/create-ramp.ts +21 -23
- package/src/presets/custom.ts +7 -7
- package/src/presets/forest.ts +1 -7
- package/src/presets/index.ts +30 -32
- package/src/presets/mono.ts +1 -7
- package/src/presets/neon.ts +1 -7
- package/src/presets/ocean.ts +1 -7
- package/src/presets/sunset.ts +1 -7
- package/src/presets/tokyo-night.ts +9 -9
- package/src/presets/types.ts +5 -5
- package/src/render.ts +277 -306
- package/src/settings.ts +516 -568
- package/src/statusline.ts +347 -372
- package/src/types.ts +34 -42
- package/src/usage.ts +40 -40
- package/dist/chunks/chunk-74QZGJ7L.js.map +0 -7
- package/dist/chunks/commands-C2G2G7C6.js.map +0 -7
package/dist/index.ts.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/statusline.ts", "../src/extension-status.ts", "../src/powerline.ts", "../src/ansi.ts", "../src/git-status.ts", "../src/render.ts", "../src/directory.ts", "../src/usage.ts"],
|
|
4
|
-
"sourcesContent": ["import { homedir } from \"node:os\";\nimport {\n\ttype ExtensionAPI,\n\ttype ExtensionContext,\n\tgetAgentDir,\n} from \"@earendil-works/pi-coding-agent\";\nimport { getCapabilities } from \"@earendil-works/pi-tui\";\nimport { completeStatuslineArguments } from \"./command-contract.js\";\nimport type { StatuslineCommandOptions } from \"./commands.js\";\nimport {\n\tbuildExtensionStatusIconAliases,\n\ttype ExtensionStatusIconAliasMap,\n\tfindDuplicateExtensions,\n\treadInstalledExtensionPackages,\n} from \"./extension-status.js\";\nimport { type GitStatusSummary, gitStatusSummaryEqual, readGitStatus } from \"./git-status.js\";\nimport { type RuntimeState, renderExtensionStatusline, renderStatusline } from \"./render.js\";\nimport {\n\tconsumeStatuslineSettingsNotice,\n\ttype LoadedStatuslineSettings,\n\tloadStatuslineSettings,\n\tloadStatuslineSettingsForAgent,\n\tsettingsFilePath,\n} from \"./settings.js\";\nimport type { PalettePreset } from \"./types.js\";\n\nconst STATUSLINE_KEY = \"statusline\";\nconst GIT_STATUS_REFRESH_INTERVAL_MS = 30_000;\nconst GIT_STATUS_EVENT_DEBOUNCE_MS = 250;\nconst EMPTY_EXTENSION_STATUS_ICON_ALIASES: ExtensionStatusIconAliasMap = new Map();\n\ntype StatuslineCommands = typeof import(\"./commands.js\");\nlet statuslineCommandsPromise: Promise<StatuslineCommands> | undefined;\n\nfunction loadStatuslineCommands(): Promise<StatuslineCommands> {\n\tif (!statuslineCommandsPromise) {\n\t\tstatuslineCommandsPromise = import(\"./commands.js\").catch((error) => {\n\t\t\tstatuslineCommandsPromise = undefined;\n\t\t\tthrow error;\n\t\t});\n\t}\n\treturn statuslineCommandsPromise;\n}\n\nexport default function statusline(pi: ExtensionAPI) {\n\tlet loaded: LoadedStatuslineSettings | undefined;\n\tlet previewPalettePreset: PalettePreset | undefined;\n\tlet activeSessionManager: ExtensionContext[\"sessionManager\"] | undefined;\n\tconst runtime: RuntimeState = {\n\t\tturnCount: 0,\n\t\tactiveTools: new Map(),\n\t\tisStreaming: false,\n\t\tthinkingLevel: \"off\",\n\t\tduplicateExtensions: [],\n\t\textensionStatusIconAliases: EMPTY_EXTENSION_STATUS_ICON_ALIASES,\n\t};\n\n\tlet sessionGeneration = 0;\n\tlet menuController = new AbortController();\n\tlet gitStatusRequestId = 0;\n\tlet activeGitStatusTarget: { cwd: string; generation: number } | undefined;\n\tlet gitStatusRefreshInFlight = false;\n\tlet gitStatusAbortController: AbortController | undefined;\n\tlet gitStatusDebounceTimer: ReturnType<typeof setTimeout> | undefined;\n\tlet pendingGitStatusRefresh: { cwd: string; generation: number; requestId: number } | undefined;\n\n\tconst refresh = () => runtime.requestRender?.();\n\tconst ownsRuntime = (ctx: ExtensionContext) => ctx.sessionManager === activeSessionManager;\n\n\tconst setGitStatus = (summary: GitStatusSummary | undefined) => {\n\t\tif (gitStatusSummaryEqual(runtime.gitStatus, summary)) return;\n\t\truntime.gitStatus = summary;\n\t\trefresh();\n\t};\n\n\tconst clearGitStatusDebounce = () => {\n\t\tif (!gitStatusDebounceTimer) return;\n\t\tclearTimeout(gitStatusDebounceTimer);\n\t\tgitStatusDebounceTimer = undefined;\n\t};\n\n\tconst abortGitStatusRefresh = (reason: string) => {\n\t\tgitStatusAbortController?.abort(new DOMException(reason, \"AbortError\"));\n\t};\n\n\tconst isActiveGitStatusTarget = (cwd: string, generation: number) =>\n\t\tactiveGitStatusTarget?.cwd === cwd &&\n\t\tactiveGitStatusTarget.generation === generation &&\n\t\tgeneration === sessionGeneration;\n\n\tconst isCurrentGitStatusRequest = (cwd: string, generation: number, requestId: number) =>\n\t\tisActiveGitStatusTarget(cwd, generation) && requestId === gitStatusRequestId;\n\n\tconst runGitStatusRefresh = (cwd: string, generation: number, requestId: number) => {\n\t\tif (!isCurrentGitStatusRequest(cwd, generation, requestId)) return;\n\t\tif (gitStatusRefreshInFlight) {\n\t\t\tpendingGitStatusRefresh = { cwd, generation, requestId };\n\t\t\treturn;\n\t\t}\n\n\t\tgitStatusRefreshInFlight = true;\n\t\tconst abortController = new AbortController();\n\t\tgitStatusAbortController = abortController;\n\t\tvoid (async () => {\n\t\t\ttry {\n\t\t\t\tconst summary = await readGitStatus(pi, cwd, abortController.signal);\n\t\t\t\tif (isCurrentGitStatusRequest(cwd, generation, requestId)) setGitStatus(summary);\n\t\t\t} catch {\n\t\t\t\tif (isCurrentGitStatusRequest(cwd, generation, requestId)) setGitStatus(undefined);\n\t\t\t} finally {\n\t\t\t\tgitStatusRefreshInFlight = false;\n\t\t\t\tif (gitStatusAbortController === abortController) gitStatusAbortController = undefined;\n\t\t\t\tconst pending = pendingGitStatusRefresh;\n\t\t\t\tpendingGitStatusRefresh = undefined;\n\t\t\t\tif (pending) runGitStatusRefresh(pending.cwd, pending.generation, pending.requestId);\n\t\t\t}\n\t\t})();\n\t};\n\n\tconst refreshGitStatus = (cwd: string, generation = sessionGeneration) => {\n\t\tif (!isActiveGitStatusTarget(cwd, generation)) return;\n\t\trunGitStatusRefresh(cwd, generation, ++gitStatusRequestId);\n\t};\n\n\tconst scheduleGitStatusRefresh = (cwd: string, generation = sessionGeneration) => {\n\t\tif (!isActiveGitStatusTarget(cwd, generation)) return;\n\t\tconst requestId = ++gitStatusRequestId;\n\t\tclearGitStatusDebounce();\n\t\tgitStatusDebounceTimer = setTimeout(() => {\n\t\t\tgitStatusDebounceTimer = undefined;\n\t\t\trunGitStatusRefresh(cwd, generation, requestId);\n\t\t}, GIT_STATUS_EVENT_DEBOUNCE_MS);\n\t};\n\n\tconst scheduleGitStatusRefreshForContext = (ctx: ExtensionContext) => {\n\t\tif (!activeGitStatusTarget || activeGitStatusTarget.cwd !== ctx.cwd) return;\n\t\tscheduleGitStatusRefresh(activeGitStatusTarget.cwd, activeGitStatusTarget.generation);\n\t};\n\n\tconst installFooter = (ctx: ExtensionContext) => {\n\t\tconst generation = ++sessionGeneration;\n\t\tmenuController.abort(new DOMException(\"Statusline session context replaced\", \"AbortError\"));\n\t\tmenuController = new AbortController();\n\t\tconst cwd = ctx.cwd;\n\t\tactiveSessionManager = ctx.sessionManager;\n\t\truntime.homeDir = homedir();\n\t\tpreviewPalettePreset = undefined;\n\t\tabortGitStatusRefresh(\"Statusline session context replaced\");\n\t\tclearGitStatusDebounce();\n\t\tactiveGitStatusTarget = ctx.mode === \"tui\" ? { cwd, generation } : undefined;\n\t\truntime.gitStatus = undefined;\n\t\truntime.duplicateExtensions = [];\n\t\truntime.extensionStatusIconAliases = EMPTY_EXTENSION_STATUS_ICON_ALIASES;\n\t\tctx.ui.setStatus(STATUSLINE_KEY, undefined);\n\t\tif (!activeGitStatusTarget || !loaded) return;\n\t\tconst installedPackages = readInstalledExtensionPackages(cwd);\n\t\truntime.duplicateExtensions = findDuplicateExtensions(installedPackages);\n\t\truntime.extensionStatusIconAliases = buildExtensionStatusIconAliases(installedPackages);\n\t\tctx.ui.setFooter((tui, theme, footerData) => {\n\t\t\truntime.requestRender = () => tui.requestRender();\n\n\t\t\tconst refreshFooterGitStatus = () => refreshGitStatus(cwd, generation);\n\t\t\tconst branchUnsubscribe = footerData.onBranchChange(() => {\n\t\t\t\truntime.gitStatus = undefined;\n\t\t\t\tabortGitStatusRefresh(\"Statusline Git branch changed\");\n\t\t\t\tclearGitStatusDebounce();\n\t\t\t\trefreshFooterGitStatus();\n\t\t\t\ttui.requestRender();\n\t\t\t});\n\t\t\tconst clock = setInterval(() => {\n\t\t\t\tclearGitStatusDebounce();\n\t\t\t\trefreshFooterGitStatus();\n\t\t\t\ttui.requestRender();\n\t\t\t}, GIT_STATUS_REFRESH_INTERVAL_MS);\n\n\t\t\treturn {\n\t\t\t\tdispose() {\n\t\t\t\t\tbranchUnsubscribe();\n\t\t\t\t\tclearInterval(clock);\n\t\t\t\t\tif (isActiveGitStatusTarget(cwd, generation)) {\n\t\t\t\t\t\tactiveGitStatusTarget = undefined;\n\t\t\t\t\t\tabortGitStatusRefresh(\"Statusline footer disposed\");\n\t\t\t\t\t\tclearGitStatusDebounce();\n\t\t\t\t\t\tpendingGitStatusRefresh = undefined;\n\t\t\t\t\t\truntime.gitStatus = undefined;\n\t\t\t\t\t\truntime.duplicateExtensions = [];\n\t\t\t\t\t\truntime.extensionStatusIconAliases = EMPTY_EXTENSION_STATUS_ICON_ALIASES;\n\t\t\t\t\t\truntime.requestRender = undefined;\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tinvalidate() {},\n\t\t\t\trender(width: number): string[] {\n\t\t\t\t\tif (!loaded) return [];\n\t\t\t\t\tconst config = previewPalettePreset\n\t\t\t\t\t\t? { ...loaded.config, palettePreset: previewPalettePreset }\n\t\t\t\t\t\t: loaded.config;\n\t\t\t\t\tconst trueColor = getCapabilities().trueColor;\n\t\t\t\t\tconst mainLine = renderStatusline(\n\t\t\t\t\t\twidth,\n\t\t\t\t\t\tctx,\n\t\t\t\t\t\tfooterData,\n\t\t\t\t\t\ttheme,\n\t\t\t\t\t\tconfig,\n\t\t\t\t\t\truntime,\n\t\t\t\t\t\ttrueColor,\n\t\t\t\t\t);\n\t\t\t\t\tconst lines = mainLine ? mainLine.split(\"\\n\") : [];\n\t\t\t\t\tlines.push(\n\t\t\t\t\t\t...renderExtensionStatusline(\n\t\t\t\t\t\t\twidth,\n\t\t\t\t\t\t\tfooterData,\n\t\t\t\t\t\t\ttheme,\n\t\t\t\t\t\t\tconfig,\n\t\t\t\t\t\t\truntime,\n\t\t\t\t\t\t\tmainLine,\n\t\t\t\t\t\t\ttrueColor,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t\treturn lines;\n\t\t\t\t},\n\t\t\t};\n\t\t});\n\t\trefreshGitStatus(cwd, generation);\n\t};\n\n\tconst agentDir = getAgentDir();\n\tconst configPath = settingsFilePath(agentDir);\n\tconst commandOptions: StatuslineCommandOptions = {\n\t\tsettingsPath: configPath,\n\t\tgetLoaded: () => loaded ?? loadStatuslineSettings(configPath),\n\t\tgetMenuOwner: () => {\n\t\t\tconst generation = sessionGeneration;\n\t\t\treturn {\n\t\t\t\tsignal: menuController.signal,\n\t\t\t\tisCurrent: () => generation === sessionGeneration && !menuController.signal.aborted,\n\t\t\t};\n\t\t},\n\t\tapply(next, ctx) {\n\t\t\tif (ctx.sessionManager !== activeSessionManager) return;\n\t\t\tpreviewPalettePreset = undefined;\n\t\t\tloaded = next;\n\t\t\trefresh();\n\t\t},\n\t\tpreview(palettePreset, ctx) {\n\t\t\tif (ctx.sessionManager !== activeSessionManager) return;\n\t\t\tpreviewPalettePreset = palettePreset;\n\t\t\trefresh();\n\t\t},\n\t};\n\tpi.registerCommand(\"statusline\", {\n\t\tdescription: \"Open or inspect the statusline settings\",\n\t\tgetArgumentCompletions: completeStatuslineArguments,\n\t\thandler: async (args, ctx) => {\n\t\t\tconst commands = await loadStatuslineCommands();\n\t\t\tif (ctx.sessionManager !== activeSessionManager) return;\n\t\t\tawait commands.handleStatuslineCommand(args, ctx, commandOptions);\n\t\t},\n\t});\n\n\tpi.on(\"session_start\", (_event, ctx) => {\n\t\truntime.turnCount = 0;\n\t\truntime.activeTools.clear();\n\t\truntime.isStreaming = false;\n\t\truntime.uiPrompt = undefined;\n\t\tloaded = loadStatuslineSettingsForAgent(agentDir);\n\t\tconst settingsNotice = consumeStatuslineSettingsNotice();\n\t\tif (settingsNotice) ctx.ui.notify(settingsNotice, \"warning\");\n\t\tif (loaded.diagnostics.length > 0) {\n\t\t\tctx.ui.notify(formatSettingsDiagnostics(loaded), \"warning\");\n\t\t}\n\t\truntime.thinkingLevel = pi.getThinkingLevel();\n\t\tinstallFooter(ctx);\n\t});\n\n\tpi.on(\"session_tree\", (_event, ctx) => {\n\t\tinstallFooter(ctx);\n\t\trefresh();\n\t});\n\n\tpi.on(\"session_shutdown\", (_event, ctx) => {\n\t\tif (!ownsRuntime(ctx)) return;\n\t\tsessionGeneration += 1;\n\t\tmenuController.abort(new DOMException(\"Statusline session shut down\", \"AbortError\"));\n\t\tactiveSessionManager = undefined;\n\t\tpreviewPalettePreset = undefined;\n\t\tactiveGitStatusTarget = undefined;\n\t\tabortGitStatusRefresh(\"Statusline session shut down\");\n\t\tclearGitStatusDebounce();\n\t\tpendingGitStatusRefresh = undefined;\n\t\truntime.gitStatus = undefined;\n\t\truntime.activeTools.clear();\n\t\truntime.isStreaming = false;\n\t\truntime.uiPrompt = undefined;\n\t\truntime.duplicateExtensions = [];\n\t\truntime.extensionStatusIconAliases = EMPTY_EXTENSION_STATUS_ICON_ALIASES;\n\t\tctx.ui.setFooter(undefined);\n\t\tctx.ui.setStatus(STATUSLINE_KEY, undefined);\n\t\truntime.requestRender = undefined;\n\t});\n\n\tpi.on(\"model_select\", () => refresh());\n\n\tpi.on(\"thinking_level_select\", (event) => {\n\t\truntime.thinkingLevel = event.level;\n\t\trefresh();\n\t});\n\n\tpi.on(\"agent_start\", (_event, ctx) => {\n\t\tif (!ownsRuntime(ctx)) return;\n\t\truntime.isStreaming = true;\n\t\trefresh();\n\t});\n\n\tpi.on(\"agent_end\", (_event, ctx) => {\n\t\tif (!ownsRuntime(ctx)) return;\n\t\truntime.activeTools.clear();\n\t\tscheduleGitStatusRefreshForContext(ctx);\n\t\trefresh();\n\t});\n\n\tpi.on(\"agent_settled\", (_event, ctx) => {\n\t\tif (!ownsRuntime(ctx)) return;\n\t\truntime.isStreaming = false;\n\t\truntime.activeTools.clear();\n\t\trefresh();\n\t});\n\n\tpi.on(\"ui_prompt_start\", (event, ctx) => {\n\t\tif (!ownsRuntime(ctx)) return;\n\t\truntime.uiPrompt = { kind: event.kind, title: event.title };\n\t\trefresh();\n\t});\n\n\tpi.on(\"ui_prompt_end\", (_event, ctx) => {\n\t\tif (!ownsRuntime(ctx)) return;\n\t\truntime.uiPrompt = undefined;\n\t\trefresh();\n\t});\n\n\tpi.on(\"turn_start\", (_event, ctx) => {\n\t\tif (!ownsRuntime(ctx)) return;\n\t\truntime.turnCount += 1;\n\t\truntime.isStreaming = true;\n\t\trefresh();\n\t});\n\n\tpi.on(\"turn_end\", (_event, ctx) => {\n\t\tif (!ownsRuntime(ctx)) return;\n\t\tscheduleGitStatusRefreshForContext(ctx);\n\t\trefresh();\n\t});\n\n\tpi.on(\"tool_execution_start\", (event, ctx) => {\n\t\tif (!ownsRuntime(ctx)) return;\n\t\tconst currentCount = runtime.activeTools.get(event.toolName) ?? 0;\n\t\truntime.activeTools.set(event.toolName, currentCount + 1);\n\t\trefresh();\n\t});\n\n\tpi.on(\"tool_execution_end\", (event, ctx) => {\n\t\tif (!ownsRuntime(ctx)) return;\n\t\tconst currentCount = runtime.activeTools.get(event.toolName) ?? 0;\n\t\tif (currentCount <= 1) runtime.activeTools.delete(event.toolName);\n\t\telse runtime.activeTools.set(event.toolName, currentCount - 1);\n\n\t\tscheduleGitStatusRefreshForContext(ctx);\n\t\trefresh();\n\t});\n}\n\nfunction formatSettingsDiagnostics(loaded: LoadedStatuslineSettings): string {\n\tconst details = loaded.diagnostics.slice(0, 5).map((item) => item.message);\n\tconst remaining = loaded.diagnostics.length - details.length;\n\treturn [\n\t\t`pi-statusline settings: ${details.join(\"; \")}`,\n\t\t...(remaining > 0 ? [`+${remaining} more`] : []),\n\t].join(\" \");\n}\n\nexport {\n\tbuildExtensionStatusIconAliases,\n\ttype ExtensionStatusIconAliasMap,\n\textensionColor,\n\tformatExtensionStatus,\n\tnpmPackageName,\n\tsimplifyExtensionStatusText,\n\tsplitExtensionStatusIcon,\n\tstripExtensionStatusPrefix,\n\twrapExtensionStatusline,\n} from \"./extension-status.js\";\nexport {\n\tformatGitBranchText,\n\tformatGitBranchValue,\n\tformatGitStatusSummary,\n\ttype GitStatusSummary,\n\tparseGitRoot,\n\tparseGitStatusPorcelain,\n\treadGitStatus,\n} from \"./git-status.js\";\nexport {\n\tcontextColor,\n\tformatCount,\n\tformatToolActivity,\n\tprContextFromStatuses,\n\tprLinkFromStatuses,\n\tshortenModel,\n} from \"./render.js\";\nexport { normalizeStatuslineSettings, readStatuslineSettings } from \"./settings.js\";\n", "import { existsSync, readFileSync } from \"node:fs\";\nimport { dirname, isAbsolute, join, resolve } from \"node:path\";\nimport { getAgentDir, type Theme, type ThemeColor } from \"@earendil-works/pi-coding-agent\";\nimport { wrapTextWithAnsi } from \"@earendil-works/pi-tui\";\nimport { powerlineExtensionSeparator } from \"./powerline.js\";\nimport { DEFAULT_EXTENSION_STATUS_ICONS } from \"./settings.js\";\nimport type { StatuslineConfig } from \"./types.js\";\n\nexport type ExtensionStatusIconAliasMap = ReadonlyMap<string, readonly string[]>;\nexport interface ExtensionStatusRuntime {\n\tduplicateExtensions: string[];\n\textensionStatusIconAliases: ExtensionStatusIconAliasMap;\n}\n\nconst STATUSLINE_KEY = \"statusline\";\nconst COMPATIBLE_STATUS_ICON_KEYS: Readonly<Record<string, string>> = {\n\tretry: \"unknown-error-retry\",\n\tsync: \"pisync\",\n\t\"unknown-error-retry\": \"retry\",\n\tpisync: \"sync\",\n};\nconst EMPTY_EXTENSION_STATUS_ICON_ALIASES: ExtensionStatusIconAliasMap = new Map();\nfunction extensionStatusSeparator(\n\tconfig: StatuslineConfig,\n\ttheme: Theme,\n\ttrueColor: boolean,\n): string {\n\treturn powerlineExtensionSeparator(theme, config.palettePreset, trueColor);\n}\n\nexport function formatExtensionStatuses(\n\tstatuses: ReadonlyMap<string, string>,\n\ttheme: Theme,\n\tconfig: StatuslineConfig,\n\truntime: ExtensionStatusRuntime,\n\thiddenKeys: ReadonlySet<string> = new Set(),\n\ttrueColor = true,\n): string {\n\tconst separator = extensionStatusSeparator(config, theme, trueColor);\n\tconst visibleStatuses = [\n\t\t...formatDuplicateExtensionStatus(runtime, theme),\n\t\t...[...statuses.entries()]\n\t\t\t.filter(\n\t\t\t\t([key, value]) => key !== STATUSLINE_KEY && !hiddenKeys.has(key) && value.trim().length > 0,\n\t\t\t)\n\t\t\t.map(([key, value]) =>\n\t\t\t\tformatExtensionStatus(key, value, theme, config, runtime.extensionStatusIconAliases),\n\t\t\t),\n\t].slice(0, 5);\n\n\treturn visibleStatuses.join(separator);\n}\n\nexport function formatExtensionStatus(\n\tkey: string,\n\tvalue: string,\n\ttheme: Theme,\n\tconfig: Pick<StatuslineConfig, \"extensionStatusIcons\">,\n\textensionStatusIconAliases: ExtensionStatusIconAliasMap = EMPTY_EXTENSION_STATUS_ICON_ALIASES,\n): string {\n\tconst status = splitExtensionStatusIcon(stripExtensionStatusPrefix(key, value));\n\tconst text = simplifyExtensionStatusText(status.text);\n\tconst color = extensionColor(key, value);\n\tconst textColor = color === \"warning\" ? \"warning\" : \"muted\";\n\tconst icon = extensionStatusIcon(\n\t\tkey,\n\t\tstatus.icon,\n\t\tconfig.extensionStatusIcons,\n\t\textensionStatusIconAliases,\n\t);\n\tconst renderedText = theme.fg(textColor, text);\n\treturn icon ? `${theme.fg(color, icon)} ${renderedText}` : renderedText;\n}\n\nfunction extensionStatusIcon(\n\tkey: string,\n\tleadingIcon: string | undefined,\n\tconfiguredIcons: Record<string, string>,\n\textensionStatusIconAliases: ExtensionStatusIconAliasMap,\n) {\n\tif (Object.hasOwn(configuredIcons, key)) return configuredIcons[key];\n\tconst namespaceIcon = configuredNamespaceIcon(key, configuredIcons);\n\tif (namespaceIcon !== undefined) return namespaceIcon;\n\tconst compatibleKey = COMPATIBLE_STATUS_ICON_KEYS[key];\n\tif (compatibleKey && Object.hasOwn(configuredIcons, compatibleKey)) {\n\t\treturn configuredIcons[compatibleKey];\n\t}\n\tfor (const alias of extensionStatusAliasesForKey(key, extensionStatusIconAliases)) {\n\t\tif (Object.hasOwn(configuredIcons, alias)) return configuredIcons[alias];\n\t}\n\treturn leadingIcon ?? DEFAULT_EXTENSION_STATUS_ICONS[key] ?? \"\uD83D\uDD0C\";\n}\n\nfunction configuredNamespaceIcon(\n\tkey: string,\n\tconfiguredIcons: Readonly<Record<string, string>>,\n): string | undefined {\n\tlet match: { baseLength: number; icon: string } | undefined;\n\tfor (const [selector, icon] of Object.entries(configuredIcons)) {\n\t\tif (!selector.endsWith(\":*\")) continue;\n\t\tconst base = selector.slice(0, -2);\n\t\tif (!base || !key.startsWith(`${base}:`)) continue;\n\t\tif (!match || base.length > match.baseLength) match = { baseLength: base.length, icon };\n\t}\n\treturn match?.icon;\n}\n\nfunction extensionStatusAliasesForKey(\n\tkey: string,\n\textensionStatusIconAliases: ExtensionStatusIconAliasMap,\n): readonly string[] {\n\tfor (const [statusBase, aliases] of extensionStatusIconAliases) {\n\t\tif (statusKeyMatchesStatusBase(key, statusBase)) return aliases;\n\t}\n\treturn [];\n}\n\nfunction statusKeyMatchesStatusBase(key: string, statusBase: string): boolean {\n\treturn key === statusBase || key.startsWith(`${statusBase}:`) || key.startsWith(`${statusBase}/`);\n}\n\nexport function wrapExtensionStatusline(status: string, width: number): string[] {\n\tif (!status || width <= 0) return [];\n\treturn wrapTextWithAnsi(status, width);\n}\n\nfunction formatDuplicateExtensionStatus(runtime: ExtensionStatusRuntime, theme: Theme): string[] {\n\tif (runtime.duplicateExtensions.length === 0) return [];\n\tconst names = runtime.duplicateExtensions.slice(0, 2).join(\", \");\n\tconst suffix =\n\t\truntime.duplicateExtensions.length > 2 ? ` +${runtime.duplicateExtensions.length - 2}` : \"\";\n\treturn [`${theme.fg(\"warning\", \"\u26A0\uFE0F\")} ${theme.fg(\"warning\", `dup ${names}${suffix}`)}`];\n}\n\nexport function splitExtensionStatusIcon(value: string): { icon?: string; text: string } {\n\tconst trimmed = value.trim();\n\tconst [firstToken, ...restTokens] = trimmed.split(/\\s+/);\n\tif (firstToken && isEmojiOnlyToken(firstToken)) {\n\t\treturn { icon: firstToken, text: restTokens.join(\" \") };\n\t}\n\treturn { text: trimmed };\n}\n\nfunction isEmojiOnlyToken(value: string): boolean {\n\treturn /^(?=.*(?:\\p{Extended_Pictographic}|\\p{Regional_Indicator}|[0-9#*]\\ufe0f?\\u20e3))(?:\\p{Extended_Pictographic}|\\p{Emoji_Modifier}|\\p{Regional_Indicator}|\\u200d|\\ufe0f|[0-9#*]\\ufe0f?\\u20e3)+$/u.test(\n\t\tvalue,\n\t);\n}\n\nexport function extensionColor(key: string, value: string): ThemeColor {\n\tconst normalized = `${key} ${value}`.toLowerCase();\n\tif (/missing|error|fail|conflict|duplicate|unavailable/.test(normalized)) return \"warning\";\n\tif (normalized.includes(\"codex\")) return \"accent\";\n\tif (/ready|active|running|enabled|awake|ok/.test(normalized)) return \"success\";\n\treturn \"muted\";\n}\n\nexport function stripExtensionStatusPrefix(key: string, value: string): string {\n\treturn value.trim().replace(new RegExp(`^${escapeRegExp(key)}\\\\s*:\\\\s*`, \"iu\"), \"\");\n}\n\nexport function simplifyExtensionStatusText(value: string): string {\n\treturn value\n\t\t.trim()\n\t\t.replace(/\\bready\\b/giu, \"\u2713\")\n\t\t.replace(/\\bmissing\\b/giu, \"\u2717\")\n\t\t.replace(/,\\s*/g, \" \")\n\t\t.replace(/\\s+\\([^)]*\\)\\s*$/, \"\")\n\t\t.replace(/\\s+/g, \" \");\n}\n\nfunction escapeRegExp(value: string): string {\n\treturn value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\ninterface InstalledExtensionPackage {\n\tpackageName: string;\n\tsource: string;\n\tidentity: string;\n}\n\nexport function readInstalledExtensionPackages(cwd: string): InstalledExtensionPackage[] {\n\tconst packages: InstalledExtensionPackage[] = [];\n\tconst settingsFiles = extensionSettingsFiles(cwd);\n\n\tfor (const settingsFile of settingsFiles) {\n\t\tconst baseDirectory = dirname(settingsFile);\n\t\tfor (const rawSource of readPackageSources(settingsFile)) {\n\t\t\tconst source = rawSource.trim();\n\t\t\tif (!source) continue;\n\t\t\tconst packageName = packageNameForSource(source, baseDirectory);\n\t\t\tif (!packageName) continue;\n\t\t\tpackages.push({ packageName, source, identity: sourceIdentity(source, baseDirectory) });\n\t\t}\n\t}\n\n\treturn packages;\n}\n\nfunction extensionSettingsFiles(cwd: string): string[] {\n\treturn [join(getAgentDir(), \"settings.json\"), join(cwd, \".pi\", \"settings.json\")].filter((file) =>\n\t\texistsSync(file),\n\t);\n}\n\nexport function findDuplicateExtensions(\n\tinstalledPackages: readonly InstalledExtensionPackage[],\n): string[] {\n\tconst sourcesByPackage = new Map<string, Set<string>>();\n\n\tfor (const extensionPackage of installedPackages) {\n\t\tconst sources = sourcesByPackage.get(extensionPackage.packageName) ?? new Set<string>();\n\t\tsources.add(extensionPackage.identity);\n\t\tsourcesByPackage.set(extensionPackage.packageName, sources);\n\t}\n\n\treturn [...sourcesByPackage.entries()]\n\t\t.filter(([, sources]) => sources.size > 1)\n\t\t.map(([packageName]) => packageName.replace(/^@[^/]+\\//, \"\").replace(/^pi-/, \"\"));\n}\n\nexport function buildExtensionStatusIconAliases(\n\tinstalledPackages: readonly { packageName: string; source?: string }[],\n): Map<string, string[]> {\n\tconst packageAliasesByStatusBase = new Map<string, Map<string, string[]>>();\n\n\tfor (const extensionPackage of installedPackages) {\n\t\tconst candidate = extensionStatusIconAliasCandidate(\n\t\t\textensionPackage.packageName,\n\t\t\textensionPackage.source,\n\t\t);\n\t\tif (!candidate) continue;\n\t\tconst aliasesByPackage =\n\t\t\tpackageAliasesByStatusBase.get(candidate.statusBase) ?? new Map<string, string[]>();\n\t\tconst existingAliases = aliasesByPackage.get(extensionPackage.packageName) ?? [];\n\t\taliasesByPackage.set(\n\t\t\textensionPackage.packageName,\n\t\t\tuniqueStrings([...existingAliases, ...candidate.aliases]),\n\t\t);\n\t\tpackageAliasesByStatusBase.set(candidate.statusBase, aliasesByPackage);\n\t}\n\n\tconst aliases = new Map<string, string[]>();\n\tfor (const [statusBase, aliasesByPackage] of packageAliasesByStatusBase) {\n\t\tif (aliasesByPackage.size === 1)\n\t\t\taliases.set(statusBase, [...aliasesByPackage.values()][0] ?? []);\n\t}\n\treturn aliases;\n}\n\nfunction extensionStatusIconAliasCandidate(\n\tpackageName: string,\n\tsource?: string,\n): { statusBase: string; aliases: string[] } | undefined {\n\tconst packageBase = packageBaseName(packageName);\n\tconst statusBase = statusBaseFromPackageBase(packageBase);\n\tif (!statusBase) return undefined;\n\n\tconst sourceAliases = source?.startsWith(\"npm:\") ? [source, `npm:${npmPackageName(source)}`] : [];\n\treturn {\n\t\tstatusBase,\n\t\taliases: uniqueStrings([...sourceAliases, packageName, packageBase, statusBase]),\n\t};\n}\n\nfunction packageBaseName(packageName: string): string {\n\tconst slashIndex = packageName.lastIndexOf(\"/\");\n\treturn slashIndex === -1 ? packageName : packageName.slice(slashIndex + 1);\n}\n\nfunction statusBaseFromPackageBase(packageBase: string): string {\n\treturn packageBase.startsWith(\"pi-\") && packageBase.length > \"pi-\".length\n\t\t? packageBase.slice(\"pi-\".length)\n\t\t: packageBase;\n}\n\nfunction uniqueStrings(values: readonly string[]): string[] {\n\treturn [...new Set(values.filter((value) => value.length > 0))];\n}\n\nfunction readPackageSources(settingsFile: string): string[] {\n\ttry {\n\t\tconst settings = JSON.parse(readFileSync(settingsFile, \"utf8\")) as { packages?: unknown[] };\n\t\treturn (settings.packages ?? [])\n\t\t\t.map((entry) => {\n\t\t\t\tif (typeof entry === \"string\") return entry;\n\t\t\t\tif (\n\t\t\t\t\tentry &&\n\t\t\t\t\ttypeof entry === \"object\" &&\n\t\t\t\t\ttypeof (entry as { source?: unknown }).source === \"string\"\n\t\t\t\t) {\n\t\t\t\t\treturn (entry as { source: string }).source;\n\t\t\t\t}\n\t\t\t\treturn undefined;\n\t\t\t})\n\t\t\t.filter((source): source is string => source !== undefined);\n\t} catch {\n\t\treturn [];\n\t}\n}\n\nfunction packageNameForSource(source: string, baseDirectory: string): string | undefined {\n\tif (source.startsWith(\"npm:\")) return npmPackageName(source);\n\tconst packageJson = join(resolveSourcePath(source, baseDirectory), \"package.json\");\n\ttry {\n\t\tconst packageData = JSON.parse(readFileSync(packageJson, \"utf8\")) as { name?: unknown };\n\t\treturn typeof packageData.name === \"string\" ? packageData.name : undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nexport function npmPackageName(source: string): string {\n\tconst spec = source.slice(\"npm:\".length);\n\tif (spec.startsWith(\"@\")) return spec.split(\"@\").slice(0, 2).join(\"@\");\n\treturn spec.split(\"@\")[0] ?? spec;\n}\n\nfunction sourceIdentity(source: string, baseDirectory: string): string {\n\tif (source.startsWith(\"npm:\")) return `npm:${npmPackageName(source)}`;\n\treturn resolveSourcePath(source, baseDirectory);\n}\n\nfunction resolveSourcePath(source: string, baseDirectory: string): string {\n\treturn isAbsolute(source) ? source : resolve(baseDirectory, source);\n}\n", "import type { Theme } from \"@earendil-works/pi-coding-agent\";\nimport { visibleWidth } from \"@earendil-works/pi-tui\";\nimport { ansiStyle } from \"./ansi.js\";\nimport { resolvePreset } from \"./presets/index.js\";\nimport type { BlockColors, PowerlinePreset } from \"./presets/types.js\";\nimport {\n\tLINE_BREAK_SEGMENT_NAME,\n\ttype PalettePreset,\n\ttype PowerlineBlockName,\n\ttype RenderItem,\n\ttype RenderSegment,\n\ttype SegmentPalette,\n\ttype SeparatorName,\n\ttype StatuslineConfig,\n} from \"./types.js\";\n\ninterface PowerlineBlock {\n\tbaseBlock: PowerlineBlockName;\n\tcolors: BlockColors;\n\tsegments: RenderSegment[];\n}\n\nexport function renderPowerlineStatusline(\n\twidth: number,\n\titems: RenderItem[],\n\tconfig: Pick<StatuslineConfig, \"palettePreset\" | \"palette\" | \"density\" | \"separator\">,\n\ttrueColor = true,\n): string {\n\tif (items.length === 0 || width <= 0) return \"\";\n\treturn splitLines(items)\n\t\t.map((segments) => fitPowerlineSegments(segments, width, config, trueColor))\n\t\t.join(\"\\n\");\n}\n\nfunction splitLines(items: RenderItem[]): RenderSegment[][] {\n\tconst lines: RenderSegment[][] = [[]];\n\tfor (const item of items) {\n\t\tif (item.name === LINE_BREAK_SEGMENT_NAME) lines.push([]);\n\t\telse lines.at(-1)?.push(item);\n\t}\n\treturn lines;\n}\n\nconst SEGMENT_RETENTION_PRIORITY: Readonly<Record<RenderSegment[\"name\"], number>> = {\n\tcontext: 120,\n\tmodel: 110,\n\tbranch: 100,\n\ttools: 90,\n\tcwd: 80,\n\tthinking: 70,\n\tcost: 60,\n\tprovider: 50,\n\tcache: 45,\n\ttokens: 40,\n\ttime: 30,\n\tturn: 20,\n\tbrand: 10,\n};\n\nfunction fitPowerlineSegments(\n\tsegments: readonly RenderSegment[],\n\twidth: number,\n\tconfig: Pick<StatuslineConfig, \"palettePreset\" | \"palette\" | \"density\" | \"separator\">,\n\ttrueColor: boolean,\n): string {\n\tif (segments.length === 0) return \"\";\n\tconst fitted = [...segments];\n\twhile (fitted.length > 1) {\n\t\tconst rendered = joinPowerlineSegments(fitted, config, trueColor);\n\t\tif (visibleWidth(rendered) <= width) return rendered;\n\t\tlet removalIndex = 0;\n\t\tfor (let index = 1; index < fitted.length; index += 1) {\n\t\t\tconst candidate = fitted[index];\n\t\t\tconst current = fitted[removalIndex];\n\t\t\tif (\n\t\t\t\tcandidate &&\n\t\t\t\tcurrent &&\n\t\t\t\tSEGMENT_RETENTION_PRIORITY[candidate.name] < SEGMENT_RETENTION_PRIORITY[current.name]\n\t\t\t) {\n\t\t\t\tremovalIndex = index;\n\t\t\t}\n\t\t}\n\t\tfitted.splice(removalIndex, 1);\n\t}\n\tconst rendered = joinPowerlineSegments(fitted, config, trueColor);\n\treturn visibleWidth(rendered) <= width ? rendered : \"\";\n}\n\nexport function powerlineExtensionSeparator(\n\t_theme: Theme,\n\tpalettePreset: PalettePreset = \"tokyo-night\",\n\ttrueColor = true,\n): string {\n\treturn ansiStyle(\" \u2022 \", { fg: resolvePreset(palettePreset).extensionSeparator }, trueColor);\n}\n\nfunction joinPowerlineSegments(\n\tsegments: RenderSegment[],\n\tconfig: Pick<StatuslineConfig, \"palettePreset\" | \"palette\" | \"density\" | \"separator\">,\n\ttrueColor: boolean,\n): string {\n\tconst preset = resolvePreset(config.palettePreset);\n\tconst blocks = contiguousBlocks(segments, preset, config.palettePreset, config.palette);\n\tlet line = ansiStyle(\"\u2591\u2592\u2593\", { fg: preset.lead }, trueColor);\n\n\tfor (const [index, block] of blocks.entries()) {\n\t\tconst previous = index === 0 ? undefined : blocks[index - 1]?.colors;\n\t\tif (previous) {\n\t\t\tline += ansiStyle(\"\uE0B4\", { fg: previous.bg, bg: block.colors.bg }, trueColor);\n\t\t}\n\t\tline += ansiStyle(formatBlockText(block, config), block.colors, trueColor);\n\t}\n\n\tconst lastBlock = blocks.at(-1);\n\tif (lastBlock) line += ansiStyle(\"\uE0B4\", { fg: lastBlock.colors.bg }, trueColor);\n\treturn line;\n}\n\nfunction contiguousBlocks(\n\tsegments: RenderSegment[],\n\tpreset: PowerlinePreset,\n\tpalettePreset: PalettePreset,\n\tconfiguredPalette: SegmentPalette,\n): PowerlineBlock[] {\n\tconst blocks: PowerlineBlock[] = [];\n\tconst usesConfiguredColors = palettePreset === \"custom\";\n\tfor (const segment of segments) {\n\t\tconst colors = usesConfiguredColors\n\t\t\t? (configuredPalette[segment.name] ?? {})\n\t\t\t: preset.blocks[segment.block];\n\t\tconst previous = blocks.at(-1);\n\t\tconst matchesPrevious =\n\t\t\tprevious !== undefined &&\n\t\t\t(usesConfiguredColors\n\t\t\t\t? colorsEqual(previous.colors, colors)\n\t\t\t\t: previous.baseBlock === segment.block);\n\t\tif (matchesPrevious) previous.segments.push(segment);\n\t\telse blocks.push({ baseBlock: segment.block, colors, segments: [segment] });\n\t}\n\treturn blocks;\n}\n\nfunction colorsEqual(left: BlockColors, right: BlockColors): boolean {\n\treturn left.fg === right.fg && left.bg === right.bg;\n}\n\nfunction formatBlockText(\n\tblock: PowerlineBlock,\n\tconfig: Pick<StatuslineConfig, \"density\" | \"separator\">,\n): string {\n\tconst texts = block.segments.map(formatSegmentText);\n\tconst separator = separatorText(config.separator, config.density === \"cozy\");\n\tconst leading = config.density === \"cozy\" ? \" \" : \" \";\n\tconst trailing = config.density === \"cozy\" ? \" \" : \"\";\n\treturn `${leading}${texts.join(separator)}${trailing}`;\n}\n\nfunction formatSegmentText(segment: RenderSegment): string {\n\treturn segment.emphasis ? `\\u001b[1m${segment.text}\\u001b[22m` : segment.text;\n}\n\nfunction separatorText(separator: SeparatorName, cozy: boolean): string {\n\tconst padding = cozy ? \" \" : \" \";\n\tswitch (separator) {\n\t\tcase \"dot\":\n\t\t\treturn `${padding}\u2022${padding}`;\n\t\tcase \"bar\":\n\t\t\treturn `${padding}\u2502${padding}`;\n\t\tcase \"powerline\":\n\t\t\treturn `${padding}\uE0B1${padding}`;\n\t\tcase \"round\":\n\t\t\treturn `${padding}\u276F${padding}`;\n\t\tcase \"none\":\n\t\t\treturn padding;\n\t}\n}\n", "export function ansiStyle(\n\ttext: string,\n\tcolors: { fg?: string; bg?: string },\n\ttrueColor = true,\n): string {\n\tconst codes = [\n\t\tcolors.fg ? colorCode(\"38\", colors.fg, trueColor) : undefined,\n\t\tcolors.bg ? colorCode(\"48\", colors.bg, trueColor) : undefined,\n\t].filter((code): code is string => code !== undefined);\n\tif (codes.length === 0) return text;\n\treturn `\\u001b[${codes.join(\";\")}m${text}\\u001b[0m`;\n}\n\nexport function ansiFg(hex: string, text: string, trueColor = true): string {\n\treturn ansiStyle(text, { fg: hex }, trueColor);\n}\n\nfunction colorCode(prefix: \"38\" | \"48\", hex: string, trueColor: boolean): string {\n\tconst { red, green, blue } = hexToRgb(hex);\n\treturn trueColor\n\t\t? `${prefix};2;${red};${green};${blue}`\n\t\t: `${prefix};5;${rgbToAnsi256(red, green, blue)}`;\n}\n\nfunction rgbToAnsi256(red: number, green: number, blue: number): number {\n\tconst channels = [red, green, blue].map((value) => Math.round((value / 255) * 5));\n\treturn 16 + 36 * (channels[0] ?? 0) + 6 * (channels[1] ?? 0) + (channels[2] ?? 0);\n}\n\nfunction hexToRgb(hex: string): { red: number; green: number; blue: number } {\n\tconst normalized = hex.replace(/^#/, \"\");\n\treturn {\n\t\tred: Number.parseInt(normalized.slice(0, 2), 16),\n\t\tgreen: Number.parseInt(normalized.slice(2, 4), 16),\n\t\tblue: Number.parseInt(normalized.slice(4, 6), 16),\n\t};\n}\n", "import { isAbsolute } from \"node:path\";\nimport type { ExtensionAPI } from \"@earendil-works/pi-coding-agent\";\n\nconst GIT_STATUS_TIMEOUT_MS = 3_000;\n\nexport interface GitStatusSummary {\n\troot?: string;\n\tahead: number;\n\tbehind: number;\n\tstaged: number;\n\tmodified: number;\n\tuntracked: number;\n\tconflicts: number;\n}\n\nexport async function readGitStatus(\n\tpi: ExtensionAPI,\n\tcwd: string,\n\tsignal?: AbortSignal,\n): Promise<GitStatusSummary | undefined> {\n\tconst [statusResult, rootResult] = await Promise.all([\n\t\tpi.exec(\n\t\t\t\"git\",\n\t\t\t[\"--no-optional-locks\", \"status\", \"--porcelain=v1\", \"--branch\", \"--untracked-files=normal\"],\n\t\t\t{ cwd, timeout: GIT_STATUS_TIMEOUT_MS, signal },\n\t\t),\n\t\tpi\n\t\t\t.exec(\"git\", [\"rev-parse\", \"--path-format=absolute\", \"--show-toplevel\"], {\n\t\t\t\tcwd,\n\t\t\t\ttimeout: GIT_STATUS_TIMEOUT_MS,\n\t\t\t\tsignal,\n\t\t\t})\n\t\t\t.catch(() => undefined),\n\t]);\n\tif (statusResult.code !== 0 || statusResult.killed) return undefined;\n\tconst summary = parseGitStatusPorcelain(statusResult.stdout);\n\tif (rootResult && rootResult.code === 0 && !rootResult.killed) {\n\t\tconst root = parseGitRoot(rootResult.stdout);\n\t\tif (root) summary.root = root;\n\t}\n\treturn summary;\n}\n\nexport function parseGitStatusPorcelain(output: string): GitStatusSummary {\n\tconst summary: GitStatusSummary = {\n\t\tahead: 0,\n\t\tbehind: 0,\n\t\tstaged: 0,\n\t\tmodified: 0,\n\t\tuntracked: 0,\n\t\tconflicts: 0,\n\t};\n\tfor (const line of output.split(/\\r?\\n/)) {\n\t\tif (!line) continue;\n\t\tif (line.startsWith(\"## \")) {\n\t\t\tconst ahead = line.match(/\\bahead (\\d+)/u);\n\t\t\tconst behind = line.match(/\\bbehind (\\d+)/u);\n\t\t\tsummary.ahead = ahead ? Number(ahead[1]) : 0;\n\t\t\tsummary.behind = behind ? Number(behind[1]) : 0;\n\t\t\tcontinue;\n\t\t}\n\t\tconst indexStatus = line[0] ?? \" \";\n\t\tconst worktreeStatus = line[1] ?? \" \";\n\t\tif (indexStatus === \"?\" && worktreeStatus === \"?\") {\n\t\t\tsummary.untracked += 1;\n\t\t\tcontinue;\n\t\t}\n\t\tif (isConflictStatus(indexStatus, worktreeStatus)) {\n\t\t\tsummary.conflicts += 1;\n\t\t\tcontinue;\n\t\t}\n\t\tif (isChangedStatus(indexStatus)) summary.staged += 1;\n\t\tif (isChangedStatus(worktreeStatus)) summary.modified += 1;\n\t}\n\treturn summary;\n}\n\nfunction isConflictStatus(indexStatus: string, worktreeStatus: string): boolean {\n\treturn (\n\t\t(indexStatus === \"D\" && worktreeStatus === \"D\") ||\n\t\t(indexStatus === \"A\" && worktreeStatus === \"A\") ||\n\t\tindexStatus === \"U\" ||\n\t\tworktreeStatus === \"U\"\n\t);\n}\n\nfunction isChangedStatus(status: string): boolean {\n\treturn status !== \" \" && status !== \"?\" && status !== \"!\";\n}\n\nexport function parseGitRoot(output: string): string | undefined {\n\tconst root = output.split(/\\r?\\n/u)[0]?.trim();\n\treturn root && isAbsolute(root) ? root : undefined;\n}\n\nexport function formatGitStatusSummary(summary: GitStatusSummary | undefined): string {\n\tif (!summary) return \"\";\n\tconst tokens = [\n\t\t[\"\u21E1\", summary.ahead],\n\t\t[\"\u21E3\", summary.behind],\n\t\t[\"+\", summary.staged],\n\t\t[\"~\", summary.modified],\n\t\t[\"?\", summary.untracked],\n\t\t[\"!\", summary.conflicts],\n\t] as const;\n\treturn tokens\n\t\t.filter(([, count]) => count > 0)\n\t\t.map(([prefix, count]) => `${prefix}${formatCount(count)}`)\n\t\t.join(\" \");\n}\n\nexport function formatGitBranchValue(\n\tbranch: string | null,\n\tstatus: GitStatusSummary | undefined,\n\tpr?: string,\n): string {\n\tif (!branch) return \"no-git\";\n\tconst suffixes = [formatGitStatusSummary(status), pr ? `(${pr})` : \"\"].filter(Boolean);\n\treturn suffixes.length > 0 ? `${branch} ${suffixes.join(\" \")}` : branch;\n}\n\nexport function formatGitBranchText(\n\tbranch: string | null,\n\tstatus: GitStatusSummary | undefined,\n\tpr?: string,\n): string {\n\treturn `\uD83C\uDF3F ${formatGitBranchValue(branch, status, pr)}`;\n}\n\nexport function gitStatusSummaryEqual(\n\tleft: GitStatusSummary | undefined,\n\tright: GitStatusSummary | undefined,\n): boolean {\n\tif (!left || !right) return left === right;\n\treturn (\n\t\tleft.root === right.root &&\n\t\tleft.ahead === right.ahead &&\n\t\tleft.behind === right.behind &&\n\t\tleft.staged === right.staged &&\n\t\tleft.modified === right.modified &&\n\t\tleft.untracked === right.untracked &&\n\t\tleft.conflicts === right.conflicts\n\t);\n}\n\nfunction formatCount(value: number): string {\n\treturn Intl.NumberFormat(\"en\", { notation: \"compact\", maximumFractionDigits: 1 }).format(value);\n}\n", "import type {\n\tExtensionAPI,\n\tExtensionContext,\n\tReadonlyFooterDataProvider,\n\tTheme,\n\tThemeColor,\n\tUIPromptKind,\n} from \"@earendil-works/pi-coding-agent\";\nimport { sliceByColumn, visibleWidth } from \"@earendil-works/pi-tui\";\nimport { sanitizeTerminalText } from \"@narumitw/pi-tui-kit/terminal-text\";\nimport { formatDirectoryPath } from \"./directory.js\";\nimport {\n\ttype ExtensionStatusRuntime,\n\tformatExtensionStatuses,\n\twrapExtensionStatusline,\n} from \"./extension-status.js\";\nimport { formatGitBranchValue, type GitStatusSummary } from \"./git-status.js\";\nimport { renderPowerlineStatusline } from \"./powerline.js\";\nimport {\n\tLINE_BREAK_SEGMENT_NAME,\n\ttype PowerlineBlockName,\n\ttype RenderItem,\n\ttype RenderSegment,\n\ttype SegmentName,\n\ttype StatuslineConfig,\n\ttype TruncationDirection,\n} from \"./types.js\";\nimport { type FooterUsageSummary, summarizeFooterUsage } from \"./usage.js\";\n\ntype ThinkingLevel = ReturnType<ExtensionAPI[\"getThinkingLevel\"]>;\nexport interface RuntimeState extends ExtensionStatusRuntime {\n\thomeDir?: string;\n\tturnCount: number;\n\tactiveTools: Map<string, number>;\n\tisStreaming: boolean;\n\tuiPrompt?: { kind: UIPromptKind; title?: string };\n\tthinkingLevel: ThinkingLevel;\n\tgitStatus?: GitStatusSummary;\n\trequestRender?: () => void;\n}\nconst GITHUB_PR_KEY = \"github-pr\";\nconst GITHUB_PR_STATUS_KEYS = new Set([GITHUB_PR_KEY]);\nexport function renderStatusline(\n\twidth: number,\n\tctx: ExtensionContext,\n\tfooterData: ReadonlyFooterDataProvider,\n\t_theme: Theme,\n\tconfig: StatuslineConfig,\n\truntime: RuntimeState,\n\ttrueColor = true,\n): string {\n\tif (width <= 0) return \"\";\n\n\tconst usageSummary = summarizeFooterUsage(ctx.sessionManager.getEntries());\n\tconst rows: Array<{ configuredSegments: number; segments: RenderSegment[] }> = [\n\t\t{ configuredSegments: 0, segments: [] },\n\t];\n\tfor (const name of config.segments) {\n\t\tif (name === LINE_BREAK_SEGMENT_NAME) {\n\t\t\trows.push({ configuredSegments: 0, segments: [] });\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst row = rows.at(-1);\n\t\tif (!row) continue;\n\t\trow.configuredSegments += 1;\n\t\tconst rendered = buildSegment(name, ctx, footerData, config, runtime, usageSummary);\n\t\tif (rendered && rendered.text.length > 0) row.segments.push(rendered);\n\t}\n\n\tconst segments: RenderItem[] = [];\n\tconst renderedRows = rows.filter(\n\t\t(row) => row.configuredSegments === 0 || row.segments.length > 0,\n\t);\n\tfor (const [index, row] of renderedRows.entries()) {\n\t\tif (index > 0) segments.push({ name: LINE_BREAK_SEGMENT_NAME });\n\t\tsegments.push(...row.segments);\n\t}\n\n\treturn renderPowerlineStatusline(width, segments, config, trueColor);\n}\n\nexport function renderExtensionStatusline(\n\twidth: number,\n\tfooterData: ReadonlyFooterDataProvider,\n\ttheme: Theme,\n\tconfig: StatuslineConfig,\n\truntime: RuntimeState,\n\tmainLine: string,\n\ttrueColor = true,\n): string[] {\n\tconst statuses = footerData.getExtensionStatuses();\n\tconst prContext = prContextFromStatuses(statuses);\n\tconst rendersPrInline = prContext !== undefined && mainLine.includes(prContext);\n\tconst status = formatExtensionStatuses(\n\t\tstatuses,\n\t\ttheme,\n\t\tconfig,\n\t\truntime,\n\t\trendersPrInline ? GITHUB_PR_STATUS_KEYS : undefined,\n\t\ttrueColor,\n\t);\n\treturn wrapExtensionStatusline(status, width);\n}\n\nfunction buildSegment(\n\tname: SegmentName,\n\tctx: ExtensionContext,\n\tfooterData: ReadonlyFooterDataProvider,\n\tconfig: StatuslineConfig,\n\truntime: RuntimeState,\n\tusageSummary: FooterUsageSummary,\n): RenderSegment | undefined {\n\tswitch (name) {\n\t\tcase \"brand\":\n\t\t\treturn segment(name, \"\u03C0\", config, \"accent\", \"header\", true);\n\t\tcase \"provider\":\n\t\t\treturn segment(name, ctx.model?.provider ?? \"no-provider\", config, \"accent\", \"header\");\n\t\tcase \"model\": {\n\t\t\tconst presentation = config.segmentText.model;\n\t\t\tconst model = truncateModel(\n\t\t\t\tshortenModel(ctx.model?.id ?? \"no-model\"),\n\t\t\t\tpresentation.truncationLength,\n\t\t\t\tpresentation.truncationSymbol,\n\t\t\t\tpresentation.truncationDirection,\n\t\t\t);\n\t\t\treturn segment(name, model, config, \"accent\", \"header\");\n\t\t}\n\t\tcase \"thinking\":\n\t\t\treturn segment(\n\t\t\t\tname,\n\t\t\t\truntime.thinkingLevel,\n\t\t\t\tconfig,\n\t\t\t\tthinkingColor(runtime.thinkingLevel),\n\t\t\t\t\"header\",\n\t\t\t);\n\t\tcase \"branch\": {\n\t\t\tconst branch = footerData.getGitBranch();\n\t\t\tconst pr = branch ? prContextFromStatuses(footerData.getExtensionStatuses()) : undefined;\n\t\t\treturn segment(\n\t\t\t\tname,\n\t\t\t\tformatGitBranchValue(branch, runtime.gitStatus, pr),\n\t\t\t\tconfig,\n\t\t\t\t\"accent\",\n\t\t\t\t\"git\",\n\t\t\t);\n\t\t}\n\t\tcase \"cwd\":\n\t\t\treturn segment(\n\t\t\t\tname,\n\t\t\t\tformatDirectoryPath(ctx.cwd, runtime.homeDir, runtime.gitStatus?.root),\n\t\t\t\tconfig,\n\t\t\t\t\"accent\",\n\t\t\t\t\"directory\",\n\t\t\t);\n\t\tcase \"tools\": {\n\t\t\tconst activity = formatToolActivity(runtime);\n\t\t\treturn activity ? segment(name, activity, config, \"accent\", \"runtime\") : undefined;\n\t\t}\n\t\tcase \"context\": {\n\t\t\tconst usage = ctx.getContextUsage();\n\t\t\tconst percentage =\n\t\t\t\tusage?.percent === null || usage?.percent === undefined\n\t\t\t\t\t? \"?\"\n\t\t\t\t\t: `${usage.percent.toFixed(1)}%`;\n\t\t\tconst contextWindow = usage?.contextWindow ?? ctx.model?.contextWindow ?? 0;\n\t\t\treturn segment(\n\t\t\t\tname,\n\t\t\t\t`${percentage}/${formatCount(contextWindow)}`,\n\t\t\t\tconfig,\n\t\t\t\tcontextColor(usage?.percent),\n\t\t\t\t\"runtime\",\n\t\t\t);\n\t\t}\n\t\tcase \"tokens\": {\n\t\t\tconst value =\n\t\t\t\tusageSummary.input === 0 && usageSummary.output === 0\n\t\t\t\t\t? \"tok 0\"\n\t\t\t\t\t: `\u2191${formatCount(usageSummary.input)} \u2193${formatCount(usageSummary.output)}`;\n\t\t\treturn segment(name, value, config, \"accent\", \"runtime\");\n\t\t}\n\t\tcase \"cache\": {\n\t\t\tif (usageSummary.cacheRead === 0 && usageSummary.cacheWrite === 0) return undefined;\n\t\t\tconst values: string[] = [];\n\t\t\tif (usageSummary.cacheRead > 0) values.push(`R${formatCount(usageSummary.cacheRead)}`);\n\t\t\tif (usageSummary.cacheWrite > 0) values.push(`W${formatCount(usageSummary.cacheWrite)}`);\n\t\t\tif (usageSummary.latestCacheHitRate !== undefined) {\n\t\t\t\tvalues.push(`CH${usageSummary.latestCacheHitRate.toFixed(1)}%`);\n\t\t\t}\n\t\t\treturn segment(name, values.join(\" \"), config, \"accent\", \"runtime\");\n\t\t}\n\t\tcase \"cost\": {\n\t\t\tconst subscription = isSubscriptionBacked(ctx) ? \" (sub)\" : \"\";\n\t\t\treturn segment(\n\t\t\t\tname,\n\t\t\t\t`${usageSummary.cost.toFixed(usageSummary.cost >= 1 ? 2 : 3)}${subscription}`,\n\t\t\t\tconfig,\n\t\t\t\t\"accent\",\n\t\t\t\t\"meter\",\n\t\t\t);\n\t\t}\n\t\tcase \"time\":\n\t\t\treturn segment(name, formatTime(), config, \"accent\", \"meter\");\n\t\tcase \"turn\":\n\t\t\treturn segment(name, `${runtime.turnCount}`, config, \"accent\", \"meter\");\n\t}\n}\n\nfunction segment(\n\tname: SegmentName,\n\tvalue: string,\n\tconfig: StatuslineConfig,\n\tcolor: RenderSegment[\"color\"],\n\tblock: PowerlineBlockName,\n\temphasis = false,\n): RenderSegment {\n\treturn { name, text: formatConfiguredSegment(name, value, config), color, block, emphasis };\n}\n\nexport function formatConfiguredSegment(\n\tname: SegmentName,\n\tvalue: string,\n\tconfig: Pick<StatuslineConfig, \"segmentText\">,\n): string {\n\tconst presentation = config.segmentText[name];\n\treturn `${presentation.prefix}${value}${presentation.suffix}`;\n}\n\nfunction thinkingColor(level: ThinkingLevel): ThemeColor {\n\tswitch (level as string) {\n\t\tcase \"off\":\n\t\t\treturn \"dim\";\n\t\tcase \"minimal\":\n\t\t\treturn \"thinkingMinimal\";\n\t\tcase \"low\":\n\t\t\treturn \"thinkingLow\";\n\t\tcase \"medium\":\n\t\t\treturn \"thinkingMedium\";\n\t\tcase \"high\":\n\t\t\treturn \"thinkingHigh\";\n\t\tcase \"xhigh\":\n\t\t\treturn \"thinkingXhigh\";\n\t\tcase \"max\":\n\t\t\treturn \"thinkingMax\" as ThemeColor;\n\t\tdefault:\n\t\t\treturn \"dim\";\n\t}\n}\n\nexport function contextColor(percent: number | null | undefined): ThemeColor {\n\tif (percent === null || percent === undefined) return \"dim\";\n\tif (percent >= 90) return \"error\";\n\tif (percent >= 70) return \"warning\";\n\treturn \"success\";\n}\n\nconst MAX_UI_PROMPT_TITLE_CODE_POINTS = 256;\nconst MAX_UI_PROMPT_TITLE_WIDTH = 40;\n\nfunction boundUIPromptTitleLength(title: string): string {\n\tlet end = 0;\n\tlet ellipsisEnd = 0;\n\tlet codePoints = 0;\n\twhile (end < title.length && codePoints < MAX_UI_PROMPT_TITLE_CODE_POINTS) {\n\t\tconst codePoint = title.codePointAt(end) ?? 0;\n\t\tend += codePoint > 0xffff ? 2 : 1;\n\t\tcodePoints += 1;\n\t\tif (codePoints < MAX_UI_PROMPT_TITLE_CODE_POINTS) ellipsisEnd = end;\n\t}\n\treturn end < title.length ? `${title.slice(0, ellipsisEnd)}\u2026` : title;\n}\n\nfunction formatUIPromptTitle(title: string | undefined): string {\n\tconst safeTitle = title ? sanitizeTerminalText(title).trim() : \"\";\n\tconst boundedTitle = boundUIPromptTitleLength(safeTitle);\n\tif (visibleWidth(boundedTitle) <= MAX_UI_PROMPT_TITLE_WIDTH) return boundedTitle;\n\treturn `${sliceByColumn(boundedTitle, 0, MAX_UI_PROMPT_TITLE_WIDTH - 1, true)}\u2026`;\n}\n\nexport function formatToolActivity(runtime: RuntimeState): string | undefined {\n\tif (runtime.uiPrompt) {\n\t\tconst title = formatUIPromptTitle(runtime.uiPrompt.title);\n\t\treturn `\u2328 waiting for ${runtime.uiPrompt.kind}${title ? ` \u00B7 ${title}` : \"\"}`;\n\t}\n\n\tconst active = [...runtime.activeTools.entries()];\n\tif (active.length > 0) {\n\t\tconst [name, count] = active[0] ?? [\"tool\", 1];\n\t\tconst suffix = count > 1 ? `\u00D7${count}` : active.length > 1 ? `+${active.length - 1}` : \"\";\n\t\treturn `\u2699\uFE0F ${name}${suffix}`;\n\t}\n\n\treturn runtime.isStreaming ? \"\uD83D\uDCAD thinking\" : undefined;\n}\n\nexport function prLinkFromStatuses(statuses: ReadonlyMap<string, string>): string | undefined {\n\tconst value = statuses.get(GITHUB_PR_KEY);\n\tif (!value) return undefined;\n\t// Extract the OSC 8 hyperlink span (the clickable \"#123\"); skip non-PR states\n\t// like \"PR gh missing\" that carry no link. github-pr emits exactly one link, so the\n\t// first OSC 8 span is the PR number.\n\tconst open = value.indexOf(\"\\x1b]8;;\");\n\tif (open === -1) return undefined;\n\tconst closeMarker = \"\\x1b]8;;\\x07\";\n\tconst close = value.indexOf(closeMarker, open + 1);\n\treturn close === -1 ? undefined : value.slice(open, close + closeMarker.length);\n}\n\nexport function prContextFromStatuses(statuses: ReadonlyMap<string, string>): string | undefined {\n\tconst value = statuses.get(GITHUB_PR_KEY);\n\tif (!value) return undefined;\n\tconst link = prLinkFromStatuses(statuses);\n\tconst reference = link ?? plainPrReference(value);\n\tif (!reference) return undefined;\n\n\tconst state = compactPrState(link ? value.replace(link, \"\") : value);\n\treturn state ? `${reference} \u00B7 ${state}` : undefined;\n}\n\nfunction plainPrReference(value: string): string | undefined {\n\treturn /^PR\\s+(#\\d+):/u.exec(value)?.[1];\n}\n\nfunction compactPrState(value: string): string | undefined {\n\tif (/:\\s*merged\\s*$/.test(value)) return \"merged\";\n\tif (/:\\s*closed\\s*$/.test(value)) return \"closed\";\n\tif (/\\bdraft\\b/.test(value)) return \"draft\";\n\n\tconst failing = /\\bchecks failing \\((\\d+)\\)/.exec(value);\n\tif (failing) return `${failing[1]} failing`;\n\tif (/\\bchanges requested\\b/.test(value)) return \"changes requested\";\n\n\tconst pending = /\\bchecks pending \\((\\d+)\\)/.exec(value);\n\tif (pending) return `${pending[1]} pending`;\n\tif (/\\bapproved\\b/.test(value)) return \"approved\";\n\tif (/\\breview required\\b/.test(value)) return \"review required\";\n\tif (/\\bchecks passing\\b/.test(value)) return \"checks passing\";\n\tif (/\\bno checks\\b/.test(value)) return \"no checks\";\n\treturn undefined;\n}\n\nfunction isSubscriptionBacked(ctx: ExtensionContext): boolean {\n\tconst model = ctx.model;\n\treturn (\n\t\tmodel !== undefined &&\n\t\t(model.provider === \"kimi-coding\" || ctx.modelRegistry.isUsingOAuth(model))\n\t);\n}\n\nexport function formatCount(value: number): string {\n\tif (value < 1000) return `${value}`;\n\tif (value < 1_000_000) return `${(value / 1000).toFixed(value < 10_000 ? 1 : 0)}k`;\n\treturn `${(value / 1_000_000).toFixed(1)}m`;\n}\n\nfunction formatTime(): string {\n\tconst now = new Date();\n\tconst hours = now.getHours().toString().padStart(2, \"0\");\n\tconst minutes = now.getMinutes().toString().padStart(2, \"0\");\n\treturn `${hours}:${minutes}`;\n}\n\nconst graphemeSegmenter = new Intl.Segmenter(undefined, { granularity: \"grapheme\" });\n\nexport function truncateModel(\n\tmodel: string,\n\tlength: number,\n\tsymbol: string,\n\tdirection: TruncationDirection,\n): string {\n\tconst safeModel = sanitizeTerminalText(model);\n\tif (length === 0) return safeModel;\n\tconst graphemes = [...graphemeSegmenter.segment(safeModel)].map(({ segment }) => segment);\n\tif (graphemes.length <= length) return safeModel;\n\tconst safeSymbol = sanitizeTerminalText(symbol);\n\n\tswitch (direction) {\n\t\tcase \"start\":\n\t\t\treturn `${safeSymbol}${graphemes.slice(-length).join(\"\")}`;\n\t\tcase \"middle\": {\n\t\t\tconst headLength = Math.ceil(length / 2);\n\t\t\tconst tailLength = Math.floor(length / 2);\n\t\t\tconst tail = tailLength > 0 ? graphemes.slice(-tailLength).join(\"\") : \"\";\n\t\t\treturn `${graphemes.slice(0, headLength).join(\"\")}${safeSymbol}${tail}`;\n\t\t}\n\t\tcase \"end\":\n\t\t\treturn `${graphemes.slice(0, length).join(\"\")}${safeSymbol}`;\n\t}\n}\n\nexport function shortenModel(model: string): string {\n\treturn model\n\t\t.replace(/^claude-/, \"\")\n\t\t.replace(/^gpt-/, \"gpt \")\n\t\t.replace(/-20\\d{6}$/, \"\")\n\t\t.replace(/-latest$/, \"\");\n}\n", "import { basename, isAbsolute, relative, sep } from \"node:path\";\nimport { sanitizeTerminalText } from \"@narumitw/pi-tui-kit/terminal-text\";\n\nconst DEFAULT_TRUNCATION_LENGTH = 3;\nconst DEFAULT_HOME_SYMBOL = \"~\";\n\n/** Apply Starship's default directory presentation without exposing a format language. */\nexport function formatDirectoryPath(\n\tcwd: string,\n\thomeDir: string | undefined,\n\tgitRoot: string | undefined,\n): string {\n\tconst contracted =\n\t\tgitRoot && (!homeDir || !samePath(gitRoot, homeDir))\n\t\t\t? (contractRepositoryPath(cwd, gitRoot) ?? contractPath(cwd, homeDir, DEFAULT_HOME_SYMBOL))\n\t\t\t: contractPath(cwd, homeDir, DEFAULT_HOME_SYMBOL);\n\tconst safeContracted = sanitizeTerminalText(contracted);\n\tconst components = safeContracted.split(\"/\").filter((component) => component.length > 0);\n\tconst displayed =\n\t\tcomponents.length > DEFAULT_TRUNCATION_LENGTH\n\t\t\t? components.slice(-DEFAULT_TRUNCATION_LENGTH).join(\"/\")\n\t\t\t: safeContracted;\n\tconst native = sep === \"/\" ? displayed : displayed.replaceAll(\"/\", sep);\n\treturn sanitizeTerminalText(native || basename(cwd) || cwd);\n}\n\nfunction toSlashPath(value: string): string {\n\treturn sep === \"\\\\\" ? value.replaceAll(\"\\\\\", \"/\") : value;\n}\n\nfunction contractPath(path: string, root: string | undefined, replacement: string): string {\n\tif (!root) return toSlashPath(path);\n\tconst child = relativeWithin(path, root);\n\tif (child === undefined) return toSlashPath(path);\n\treturn child ? `${replacement}/${child}` : replacement;\n}\n\nfunction contractRepositoryPath(path: string, root: string): string | undefined {\n\tconst child = relativeWithin(path, root);\n\tif (child === undefined) return undefined;\n\tconst name = basename(root) || toSlashPath(root);\n\treturn child ? `${name}/${child}` : name;\n}\n\nfunction relativeWithin(path: string, root: string): string | undefined {\n\tconst child = relative(root, path);\n\tif (child === \"\") return \"\";\n\tif (child === \"..\" || child.startsWith(`..${sep}`) || isAbsolute(child)) return undefined;\n\treturn toSlashPath(child);\n}\n\nfunction samePath(left: string, right: string): boolean {\n\treturn relative(left, right) === \"\";\n}\n", "import type { SessionEntry } from \"@earendil-works/pi-coding-agent\";\n\ninterface UsageLike {\n\tinput?: number;\n\toutput?: number;\n\tcacheRead?: number;\n\tcacheWrite?: number;\n\tcost?: { total?: number };\n}\n\nexport interface FooterUsageSummary {\n\tinput: number;\n\toutput: number;\n\tcacheRead: number;\n\tcacheWrite: number;\n\tcost: number;\n\tlatestCacheHitRate?: number;\n}\n\nexport function summarizeFooterUsage(entries: readonly SessionEntry[]): FooterUsageSummary {\n\tconst totals: FooterUsageSummary = {\n\t\tinput: 0,\n\t\toutput: 0,\n\t\tcacheRead: 0,\n\t\tcacheWrite: 0,\n\t\tcost: 0,\n\t};\n\n\tfor (const entry of entries) {\n\t\tlet usage: UsageLike | undefined;\n\t\tif (entry.type === \"message\" && entry.message.role === \"assistant\") {\n\t\t\tusage = entry.message.usage;\n\t\t\tconst input = usage.input ?? 0;\n\t\t\tconst cacheRead = usage.cacheRead ?? 0;\n\t\t\tconst cacheWrite = usage.cacheWrite ?? 0;\n\t\t\tconst promptTokens = input + cacheRead + cacheWrite;\n\t\t\ttotals.latestCacheHitRate = promptTokens > 0 ? (cacheRead / promptTokens) * 100 : undefined;\n\t\t} else if (entry.type === \"message\" && entry.message.role === \"toolResult\") {\n\t\t\tusage = entry.message.usage;\n\t\t} else if (entry.type === \"compaction\" || entry.type === \"branch_summary\") {\n\t\t\tusage = entry.usage;\n\t\t}\n\t\tif (!usage) continue;\n\n\t\ttotals.input += usage.input ?? 0;\n\t\ttotals.output += usage.output ?? 0;\n\t\ttotals.cacheRead += usage.cacheRead ?? 0;\n\t\ttotals.cacheWrite += usage.cacheWrite ?? 0;\n\t\ttotals.cost += usage.cost?.total ?? 0;\n\t}\n\n\treturn totals;\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import { homedir } from \"node:os\";\nimport { type ExtensionAPI, type ExtensionContext, getAgentDir } from \"@earendil-works/pi-coding-agent\";\nimport { getCapabilities } from \"@earendil-works/pi-tui\";\nimport { completeStatuslineArguments } from \"./command-contract.js\";\nimport type { StatuslineCommandOptions } from \"./commands.js\";\nimport {\n buildExtensionStatusIconAliases,\n type ExtensionStatusIconAliasMap,\n findDuplicateExtensions,\n readInstalledExtensionPackages,\n} from \"./extension-status.js\";\nimport { type GitStatusSummary, gitStatusSummaryEqual, readGitStatus } from \"./git-status.js\";\nimport { type RuntimeState, renderExtensionStatusline, renderStatusline } from \"./render.js\";\nimport {\n consumeStatuslineSettingsNotice,\n type LoadedStatuslineSettings,\n loadStatuslineSettings,\n loadStatuslineSettingsForAgent,\n settingsFilePath,\n} from \"./settings.js\";\nimport type { PalettePreset } from \"./types.js\";\n\nconst STATUSLINE_KEY = \"statusline\";\nconst GIT_STATUS_REFRESH_INTERVAL_MS = 30_000;\nconst GIT_STATUS_EVENT_DEBOUNCE_MS = 250;\nconst EMPTY_EXTENSION_STATUS_ICON_ALIASES: ExtensionStatusIconAliasMap = new Map();\n\ntype StatuslineCommands = typeof import(\"./commands.js\");\nlet statuslineCommandsPromise: Promise<StatuslineCommands> | undefined;\n\nfunction loadStatuslineCommands(): Promise<StatuslineCommands> {\n if (!statuslineCommandsPromise) {\n statuslineCommandsPromise = import(\"./commands.js\").catch((error) => {\n statuslineCommandsPromise = undefined;\n throw error;\n });\n }\n return statuslineCommandsPromise;\n}\n\nexport default function statusline(pi: ExtensionAPI) {\n let loaded: LoadedStatuslineSettings | undefined;\n let previewPalettePreset: PalettePreset | undefined;\n let activeSessionManager: ExtensionContext[\"sessionManager\"] | undefined;\n const runtime: RuntimeState = {\n turnCount: 0,\n activeTools: new Map(),\n isStreaming: false,\n thinkingLevel: \"off\",\n duplicateExtensions: [],\n extensionStatusIconAliases: EMPTY_EXTENSION_STATUS_ICON_ALIASES,\n };\n\n let sessionGeneration = 0;\n let menuController = new AbortController();\n let gitStatusRequestId = 0;\n let activeGitStatusTarget: { cwd: string; generation: number } | undefined;\n let gitStatusRefreshInFlight = false;\n let gitStatusAbortController: AbortController | undefined;\n let gitStatusDebounceTimer: ReturnType<typeof setTimeout> | undefined;\n let pendingGitStatusRefresh: { cwd: string; generation: number; requestId: number } | undefined;\n\n const refresh = () => runtime.requestRender?.();\n const ownsRuntime = (ctx: ExtensionContext) => ctx.sessionManager === activeSessionManager;\n\n const setGitStatus = (summary: GitStatusSummary | undefined) => {\n if (gitStatusSummaryEqual(runtime.gitStatus, summary)) return;\n runtime.gitStatus = summary;\n refresh();\n };\n\n const clearGitStatusDebounce = () => {\n if (!gitStatusDebounceTimer) return;\n clearTimeout(gitStatusDebounceTimer);\n gitStatusDebounceTimer = undefined;\n };\n\n const abortGitStatusRefresh = (reason: string) => {\n gitStatusAbortController?.abort(new DOMException(reason, \"AbortError\"));\n };\n\n const isActiveGitStatusTarget = (cwd: string, generation: number) =>\n activeGitStatusTarget?.cwd === cwd &&\n activeGitStatusTarget.generation === generation &&\n generation === sessionGeneration;\n\n const isCurrentGitStatusRequest = (cwd: string, generation: number, requestId: number) =>\n isActiveGitStatusTarget(cwd, generation) && requestId === gitStatusRequestId;\n\n const runGitStatusRefresh = (cwd: string, generation: number, requestId: number) => {\n if (!isCurrentGitStatusRequest(cwd, generation, requestId)) return;\n if (gitStatusRefreshInFlight) {\n pendingGitStatusRefresh = { cwd, generation, requestId };\n return;\n }\n\n gitStatusRefreshInFlight = true;\n const abortController = new AbortController();\n gitStatusAbortController = abortController;\n void (async () => {\n try {\n const summary = await readGitStatus(pi, cwd, abortController.signal);\n if (isCurrentGitStatusRequest(cwd, generation, requestId)) setGitStatus(summary);\n } catch {\n if (isCurrentGitStatusRequest(cwd, generation, requestId)) setGitStatus(undefined);\n } finally {\n gitStatusRefreshInFlight = false;\n if (gitStatusAbortController === abortController) gitStatusAbortController = undefined;\n const pending = pendingGitStatusRefresh;\n pendingGitStatusRefresh = undefined;\n if (pending) runGitStatusRefresh(pending.cwd, pending.generation, pending.requestId);\n }\n })();\n };\n\n const refreshGitStatus = (cwd: string, generation = sessionGeneration) => {\n if (!isActiveGitStatusTarget(cwd, generation)) return;\n runGitStatusRefresh(cwd, generation, ++gitStatusRequestId);\n };\n\n const scheduleGitStatusRefresh = (cwd: string, generation = sessionGeneration) => {\n if (!isActiveGitStatusTarget(cwd, generation)) return;\n const requestId = ++gitStatusRequestId;\n clearGitStatusDebounce();\n gitStatusDebounceTimer = setTimeout(() => {\n gitStatusDebounceTimer = undefined;\n runGitStatusRefresh(cwd, generation, requestId);\n }, GIT_STATUS_EVENT_DEBOUNCE_MS);\n };\n\n const scheduleGitStatusRefreshForContext = (ctx: ExtensionContext) => {\n if (!activeGitStatusTarget || activeGitStatusTarget.cwd !== ctx.cwd) return;\n scheduleGitStatusRefresh(activeGitStatusTarget.cwd, activeGitStatusTarget.generation);\n };\n\n const installFooter = (ctx: ExtensionContext) => {\n const generation = ++sessionGeneration;\n menuController.abort(new DOMException(\"Statusline session context replaced\", \"AbortError\"));\n menuController = new AbortController();\n const cwd = ctx.cwd;\n activeSessionManager = ctx.sessionManager;\n runtime.homeDir = homedir();\n previewPalettePreset = undefined;\n abortGitStatusRefresh(\"Statusline session context replaced\");\n clearGitStatusDebounce();\n activeGitStatusTarget = ctx.mode === \"tui\" ? { cwd, generation } : undefined;\n runtime.gitStatus = undefined;\n runtime.duplicateExtensions = [];\n runtime.extensionStatusIconAliases = EMPTY_EXTENSION_STATUS_ICON_ALIASES;\n ctx.ui.setStatus(STATUSLINE_KEY, undefined);\n if (!activeGitStatusTarget || !loaded) return;\n const installedPackages = readInstalledExtensionPackages(cwd);\n runtime.duplicateExtensions = findDuplicateExtensions(installedPackages);\n runtime.extensionStatusIconAliases = buildExtensionStatusIconAliases(installedPackages);\n ctx.ui.setFooter((tui, theme, footerData) => {\n runtime.requestRender = () => tui.requestRender();\n\n const refreshFooterGitStatus = () => refreshGitStatus(cwd, generation);\n const branchUnsubscribe = footerData.onBranchChange(() => {\n runtime.gitStatus = undefined;\n abortGitStatusRefresh(\"Statusline Git branch changed\");\n clearGitStatusDebounce();\n refreshFooterGitStatus();\n tui.requestRender();\n });\n const clock = setInterval(() => {\n clearGitStatusDebounce();\n refreshFooterGitStatus();\n tui.requestRender();\n }, GIT_STATUS_REFRESH_INTERVAL_MS);\n\n return {\n dispose() {\n branchUnsubscribe();\n clearInterval(clock);\n if (isActiveGitStatusTarget(cwd, generation)) {\n activeGitStatusTarget = undefined;\n abortGitStatusRefresh(\"Statusline footer disposed\");\n clearGitStatusDebounce();\n pendingGitStatusRefresh = undefined;\n runtime.gitStatus = undefined;\n runtime.duplicateExtensions = [];\n runtime.extensionStatusIconAliases = EMPTY_EXTENSION_STATUS_ICON_ALIASES;\n runtime.requestRender = undefined;\n }\n },\n invalidate() {},\n render(width: number): string[] {\n if (!loaded) return [];\n const config = previewPalettePreset\n ? { ...loaded.config, palettePreset: previewPalettePreset }\n : loaded.config;\n const trueColor = getCapabilities().trueColor;\n const mainLine = renderStatusline(width, ctx, footerData, theme, config, runtime, trueColor);\n const lines = mainLine ? mainLine.split(\"\\n\") : [];\n lines.push(...renderExtensionStatusline(width, footerData, theme, config, runtime, mainLine, trueColor));\n return lines;\n },\n };\n });\n refreshGitStatus(cwd, generation);\n };\n\n const agentDir = getAgentDir();\n const configPath = settingsFilePath(agentDir);\n const commandOptions: StatuslineCommandOptions = {\n settingsPath: configPath,\n getLoaded: () => loaded ?? loadStatuslineSettings(configPath),\n getMenuOwner: () => {\n const generation = sessionGeneration;\n return {\n signal: menuController.signal,\n isCurrent: () => generation === sessionGeneration && !menuController.signal.aborted,\n };\n },\n apply(next, ctx) {\n if (ctx.sessionManager !== activeSessionManager) return;\n previewPalettePreset = undefined;\n loaded = next;\n refresh();\n },\n preview(palettePreset, ctx) {\n if (ctx.sessionManager !== activeSessionManager) return;\n previewPalettePreset = palettePreset;\n refresh();\n },\n };\n pi.registerCommand(\"statusline\", {\n description: \"Open or inspect the statusline settings\",\n getArgumentCompletions: completeStatuslineArguments,\n handler: async (args, ctx) => {\n const commands = await loadStatuslineCommands();\n if (ctx.sessionManager !== activeSessionManager) return;\n await commands.handleStatuslineCommand(args, ctx, commandOptions);\n },\n });\n\n pi.on(\"session_start\", (_event, ctx) => {\n runtime.turnCount = 0;\n runtime.activeTools.clear();\n runtime.isStreaming = false;\n runtime.uiPrompt = undefined;\n loaded = loadStatuslineSettingsForAgent(agentDir);\n const settingsNotice = consumeStatuslineSettingsNotice();\n if (settingsNotice) ctx.ui.notify(settingsNotice, \"warning\");\n if (loaded.diagnostics.length > 0) {\n ctx.ui.notify(formatSettingsDiagnostics(loaded), \"warning\");\n }\n runtime.thinkingLevel = pi.getThinkingLevel();\n installFooter(ctx);\n });\n\n pi.on(\"session_tree\", (_event, ctx) => {\n installFooter(ctx);\n refresh();\n });\n\n pi.on(\"session_shutdown\", (_event, ctx) => {\n if (!ownsRuntime(ctx)) return;\n sessionGeneration += 1;\n menuController.abort(new DOMException(\"Statusline session shut down\", \"AbortError\"));\n activeSessionManager = undefined;\n previewPalettePreset = undefined;\n activeGitStatusTarget = undefined;\n abortGitStatusRefresh(\"Statusline session shut down\");\n clearGitStatusDebounce();\n pendingGitStatusRefresh = undefined;\n runtime.gitStatus = undefined;\n runtime.activeTools.clear();\n runtime.isStreaming = false;\n runtime.uiPrompt = undefined;\n runtime.duplicateExtensions = [];\n runtime.extensionStatusIconAliases = EMPTY_EXTENSION_STATUS_ICON_ALIASES;\n ctx.ui.setFooter(undefined);\n ctx.ui.setStatus(STATUSLINE_KEY, undefined);\n runtime.requestRender = undefined;\n });\n\n pi.on(\"model_select\", () => refresh());\n\n pi.on(\"thinking_level_select\", (event) => {\n runtime.thinkingLevel = event.level;\n refresh();\n });\n\n pi.on(\"agent_start\", (_event, ctx) => {\n if (!ownsRuntime(ctx)) return;\n runtime.isStreaming = true;\n refresh();\n });\n\n pi.on(\"agent_end\", (_event, ctx) => {\n if (!ownsRuntime(ctx)) return;\n runtime.activeTools.clear();\n scheduleGitStatusRefreshForContext(ctx);\n refresh();\n });\n\n pi.on(\"agent_settled\", (_event, ctx) => {\n if (!ownsRuntime(ctx)) return;\n runtime.isStreaming = false;\n runtime.activeTools.clear();\n refresh();\n });\n\n pi.on(\"ui_prompt_start\", (event, ctx) => {\n if (!ownsRuntime(ctx)) return;\n runtime.uiPrompt = { kind: event.kind, title: event.title };\n refresh();\n });\n\n pi.on(\"ui_prompt_end\", (_event, ctx) => {\n if (!ownsRuntime(ctx)) return;\n runtime.uiPrompt = undefined;\n refresh();\n });\n\n pi.on(\"turn_start\", (_event, ctx) => {\n if (!ownsRuntime(ctx)) return;\n runtime.turnCount += 1;\n runtime.isStreaming = true;\n refresh();\n });\n\n pi.on(\"turn_end\", (_event, ctx) => {\n if (!ownsRuntime(ctx)) return;\n scheduleGitStatusRefreshForContext(ctx);\n refresh();\n });\n\n pi.on(\"tool_execution_start\", (event, ctx) => {\n if (!ownsRuntime(ctx)) return;\n const currentCount = runtime.activeTools.get(event.toolName) ?? 0;\n runtime.activeTools.set(event.toolName, currentCount + 1);\n refresh();\n });\n\n pi.on(\"tool_execution_end\", (event, ctx) => {\n if (!ownsRuntime(ctx)) return;\n const currentCount = runtime.activeTools.get(event.toolName) ?? 0;\n if (currentCount <= 1) runtime.activeTools.delete(event.toolName);\n else runtime.activeTools.set(event.toolName, currentCount - 1);\n\n scheduleGitStatusRefreshForContext(ctx);\n refresh();\n });\n}\n\nfunction formatSettingsDiagnostics(loaded: LoadedStatuslineSettings): string {\n const details = loaded.diagnostics.slice(0, 5).map((item) => item.message);\n const remaining = loaded.diagnostics.length - details.length;\n return [`pi-statusline settings: ${details.join(\"; \")}`, ...(remaining > 0 ? [`+${remaining} more`] : [])].join(\" \");\n}\n\nexport {\n buildExtensionStatusIconAliases,\n type ExtensionStatusIconAliasMap,\n extensionColor,\n formatExtensionStatus,\n npmPackageName,\n simplifyExtensionStatusText,\n splitExtensionStatusIcon,\n stripExtensionStatusPrefix,\n wrapExtensionStatusline,\n} from \"./extension-status.js\";\nexport {\n formatGitBranchText,\n formatGitBranchValue,\n formatGitStatusSummary,\n type GitStatusSummary,\n parseGitRoot,\n parseGitStatusPorcelain,\n readGitStatus,\n} from \"./git-status.js\";\nexport {\n contextColor,\n formatCount,\n formatToolActivity,\n prContextFromStatuses,\n prLinkFromStatuses,\n shortenModel,\n} from \"./render.js\";\nexport { normalizeStatuslineSettings, readStatuslineSettings } from \"./settings.js\";\n", "import { existsSync, readFileSync } from \"node:fs\";\nimport { dirname, isAbsolute, join, resolve } from \"node:path\";\nimport { getAgentDir, type Theme, type ThemeColor } from \"@earendil-works/pi-coding-agent\";\nimport { wrapTextWithAnsi } from \"@earendil-works/pi-tui\";\nimport { powerlineExtensionSeparator } from \"./powerline.js\";\nimport { DEFAULT_EXTENSION_STATUS_ICONS } from \"./settings.js\";\nimport type { StatuslineConfig } from \"./types.js\";\n\nexport type ExtensionStatusIconAliasMap = ReadonlyMap<string, readonly string[]>;\nexport interface ExtensionStatusRuntime {\n duplicateExtensions: string[];\n extensionStatusIconAliases: ExtensionStatusIconAliasMap;\n}\n\nconst STATUSLINE_KEY = \"statusline\";\nconst COMPATIBLE_STATUS_ICON_KEYS: Readonly<Record<string, string>> = {\n retry: \"unknown-error-retry\",\n sync: \"pisync\",\n \"unknown-error-retry\": \"retry\",\n pisync: \"sync\",\n};\nconst EMPTY_EXTENSION_STATUS_ICON_ALIASES: ExtensionStatusIconAliasMap = new Map();\nfunction extensionStatusSeparator(config: StatuslineConfig, theme: Theme, trueColor: boolean): string {\n return powerlineExtensionSeparator(theme, config.palettePreset, trueColor);\n}\n\nexport function formatExtensionStatuses(\n statuses: ReadonlyMap<string, string>,\n theme: Theme,\n config: StatuslineConfig,\n runtime: ExtensionStatusRuntime,\n hiddenKeys: ReadonlySet<string> = new Set(),\n trueColor = true,\n): string {\n const separator = extensionStatusSeparator(config, theme, trueColor);\n const visibleStatuses = [\n ...formatDuplicateExtensionStatus(runtime, theme),\n ...[...statuses.entries()]\n .filter(([key, value]) => key !== STATUSLINE_KEY && !hiddenKeys.has(key) && value.trim().length > 0)\n .map(([key, value]) => formatExtensionStatus(key, value, theme, config, runtime.extensionStatusIconAliases)),\n ].slice(0, 5);\n\n return visibleStatuses.join(separator);\n}\n\nexport function formatExtensionStatus(\n key: string,\n value: string,\n theme: Theme,\n config: Pick<StatuslineConfig, \"extensionStatusIcons\">,\n extensionStatusIconAliases: ExtensionStatusIconAliasMap = EMPTY_EXTENSION_STATUS_ICON_ALIASES,\n): string {\n const status = splitExtensionStatusIcon(stripExtensionStatusPrefix(key, value));\n const text = simplifyExtensionStatusText(status.text);\n const color = extensionColor(key, value);\n const textColor = color === \"warning\" ? \"warning\" : \"muted\";\n const icon = extensionStatusIcon(key, status.icon, config.extensionStatusIcons, extensionStatusIconAliases);\n const renderedText = theme.fg(textColor, text);\n return icon ? `${theme.fg(color, icon)} ${renderedText}` : renderedText;\n}\n\nfunction extensionStatusIcon(\n key: string,\n leadingIcon: string | undefined,\n configuredIcons: Record<string, string>,\n extensionStatusIconAliases: ExtensionStatusIconAliasMap,\n) {\n if (Object.hasOwn(configuredIcons, key)) return configuredIcons[key];\n const namespaceIcon = configuredNamespaceIcon(key, configuredIcons);\n if (namespaceIcon !== undefined) return namespaceIcon;\n const compatibleKey = COMPATIBLE_STATUS_ICON_KEYS[key];\n if (compatibleKey && Object.hasOwn(configuredIcons, compatibleKey)) {\n return configuredIcons[compatibleKey];\n }\n for (const alias of extensionStatusAliasesForKey(key, extensionStatusIconAliases)) {\n if (Object.hasOwn(configuredIcons, alias)) return configuredIcons[alias];\n }\n return leadingIcon ?? DEFAULT_EXTENSION_STATUS_ICONS[key] ?? \"\uD83D\uDD0C\";\n}\n\nfunction configuredNamespaceIcon(key: string, configuredIcons: Readonly<Record<string, string>>): string | undefined {\n let match: { baseLength: number; icon: string } | undefined;\n for (const [selector, icon] of Object.entries(configuredIcons)) {\n if (!selector.endsWith(\":*\")) continue;\n const base = selector.slice(0, -2);\n if (!base || !key.startsWith(`${base}:`)) continue;\n if (!match || base.length > match.baseLength) match = { baseLength: base.length, icon };\n }\n return match?.icon;\n}\n\nfunction extensionStatusAliasesForKey(\n key: string,\n extensionStatusIconAliases: ExtensionStatusIconAliasMap,\n): readonly string[] {\n for (const [statusBase, aliases] of extensionStatusIconAliases) {\n if (statusKeyMatchesStatusBase(key, statusBase)) return aliases;\n }\n return [];\n}\n\nfunction statusKeyMatchesStatusBase(key: string, statusBase: string): boolean {\n return key === statusBase || key.startsWith(`${statusBase}:`) || key.startsWith(`${statusBase}/`);\n}\n\nexport function wrapExtensionStatusline(status: string, width: number): string[] {\n if (!status || width <= 0) return [];\n return wrapTextWithAnsi(status, width);\n}\n\nfunction formatDuplicateExtensionStatus(runtime: ExtensionStatusRuntime, theme: Theme): string[] {\n if (runtime.duplicateExtensions.length === 0) return [];\n const names = runtime.duplicateExtensions.slice(0, 2).join(\", \");\n const suffix = runtime.duplicateExtensions.length > 2 ? ` +${runtime.duplicateExtensions.length - 2}` : \"\";\n return [`${theme.fg(\"warning\", \"\u26A0\uFE0F\")} ${theme.fg(\"warning\", `dup ${names}${suffix}`)}`];\n}\n\nexport function splitExtensionStatusIcon(value: string): { icon?: string; text: string } {\n const trimmed = value.trim();\n const [firstToken, ...restTokens] = trimmed.split(/\\s+/);\n if (firstToken && isEmojiOnlyToken(firstToken)) {\n return { icon: firstToken, text: restTokens.join(\" \") };\n }\n return { text: trimmed };\n}\n\nfunction isEmojiOnlyToken(value: string): boolean {\n return /^(?=.*(?:\\p{Extended_Pictographic}|\\p{Regional_Indicator}|[0-9#*]\\ufe0f?\\u20e3))(?:\\p{Extended_Pictographic}|\\p{Emoji_Modifier}|\\p{Regional_Indicator}|\\u200d|\\ufe0f|[0-9#*]\\ufe0f?\\u20e3)+$/u.test(\n value,\n );\n}\n\nexport function extensionColor(key: string, value: string): ThemeColor {\n const normalized = `${key} ${value}`.toLowerCase();\n if (/missing|error|fail|conflict|duplicate|unavailable/.test(normalized)) return \"warning\";\n if (normalized.includes(\"codex\")) return \"accent\";\n if (/ready|active|running|enabled|awake|ok/.test(normalized)) return \"success\";\n return \"muted\";\n}\n\nexport function stripExtensionStatusPrefix(key: string, value: string): string {\n return value.trim().replace(new RegExp(`^${escapeRegExp(key)}\\\\s*:\\\\s*`, \"iu\"), \"\");\n}\n\nexport function simplifyExtensionStatusText(value: string): string {\n return value\n .trim()\n .replace(/\\bready\\b/giu, \"\u2713\")\n .replace(/\\bmissing\\b/giu, \"\u2717\")\n .replace(/,\\s*/g, \" \")\n .replace(/\\s+\\([^)]*\\)\\s*$/, \"\")\n .replace(/\\s+/g, \" \");\n}\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\ninterface InstalledExtensionPackage {\n packageName: string;\n source: string;\n identity: string;\n}\n\nexport function readInstalledExtensionPackages(cwd: string): InstalledExtensionPackage[] {\n const packages: InstalledExtensionPackage[] = [];\n const settingsFiles = extensionSettingsFiles(cwd);\n\n for (const settingsFile of settingsFiles) {\n const baseDirectory = dirname(settingsFile);\n for (const rawSource of readPackageSources(settingsFile)) {\n const source = rawSource.trim();\n if (!source) continue;\n const packageName = packageNameForSource(source, baseDirectory);\n if (!packageName) continue;\n packages.push({ packageName, source, identity: sourceIdentity(source, baseDirectory) });\n }\n }\n\n return packages;\n}\n\nfunction extensionSettingsFiles(cwd: string): string[] {\n return [join(getAgentDir(), \"settings.json\"), join(cwd, \".pi\", \"settings.json\")].filter((file) => existsSync(file));\n}\n\nexport function findDuplicateExtensions(installedPackages: readonly InstalledExtensionPackage[]): string[] {\n const sourcesByPackage = new Map<string, Set<string>>();\n\n for (const extensionPackage of installedPackages) {\n const sources = sourcesByPackage.get(extensionPackage.packageName) ?? new Set<string>();\n sources.add(extensionPackage.identity);\n sourcesByPackage.set(extensionPackage.packageName, sources);\n }\n\n return [...sourcesByPackage.entries()]\n .filter(([, sources]) => sources.size > 1)\n .map(([packageName]) => packageName.replace(/^@[^/]+\\//, \"\").replace(/^pi-/, \"\"));\n}\n\nexport function buildExtensionStatusIconAliases(\n installedPackages: readonly { packageName: string; source?: string }[],\n): Map<string, string[]> {\n const packageAliasesByStatusBase = new Map<string, Map<string, string[]>>();\n\n for (const extensionPackage of installedPackages) {\n const candidate = extensionStatusIconAliasCandidate(extensionPackage.packageName, extensionPackage.source);\n if (!candidate) continue;\n const aliasesByPackage = packageAliasesByStatusBase.get(candidate.statusBase) ?? new Map<string, string[]>();\n const existingAliases = aliasesByPackage.get(extensionPackage.packageName) ?? [];\n aliasesByPackage.set(extensionPackage.packageName, uniqueStrings([...existingAliases, ...candidate.aliases]));\n packageAliasesByStatusBase.set(candidate.statusBase, aliasesByPackage);\n }\n\n const aliases = new Map<string, string[]>();\n for (const [statusBase, aliasesByPackage] of packageAliasesByStatusBase) {\n if (aliasesByPackage.size === 1) aliases.set(statusBase, [...aliasesByPackage.values()][0] ?? []);\n }\n return aliases;\n}\n\nfunction extensionStatusIconAliasCandidate(\n packageName: string,\n source?: string,\n): { statusBase: string; aliases: string[] } | undefined {\n const packageBase = packageBaseName(packageName);\n const statusBase = statusBaseFromPackageBase(packageBase);\n if (!statusBase) return undefined;\n\n const sourceAliases = source?.startsWith(\"npm:\") ? [source, `npm:${npmPackageName(source)}`] : [];\n return {\n statusBase,\n aliases: uniqueStrings([...sourceAliases, packageName, packageBase, statusBase]),\n };\n}\n\nfunction packageBaseName(packageName: string): string {\n const slashIndex = packageName.lastIndexOf(\"/\");\n return slashIndex === -1 ? packageName : packageName.slice(slashIndex + 1);\n}\n\nfunction statusBaseFromPackageBase(packageBase: string): string {\n return packageBase.startsWith(\"pi-\") && packageBase.length > \"pi-\".length\n ? packageBase.slice(\"pi-\".length)\n : packageBase;\n}\n\nfunction uniqueStrings(values: readonly string[]): string[] {\n return [...new Set(values.filter((value) => value.length > 0))];\n}\n\nfunction readPackageSources(settingsFile: string): string[] {\n try {\n const settings = JSON.parse(readFileSync(settingsFile, \"utf8\")) as { packages?: unknown[] };\n return (settings.packages ?? [])\n .map((entry) => {\n if (typeof entry === \"string\") return entry;\n if (entry && typeof entry === \"object\" && typeof (entry as { source?: unknown }).source === \"string\") {\n return (entry as { source: string }).source;\n }\n return undefined;\n })\n .filter((source): source is string => source !== undefined);\n } catch {\n return [];\n }\n}\n\nfunction packageNameForSource(source: string, baseDirectory: string): string | undefined {\n if (source.startsWith(\"npm:\")) return npmPackageName(source);\n const packageJson = join(resolveSourcePath(source, baseDirectory), \"package.json\");\n try {\n const packageData = JSON.parse(readFileSync(packageJson, \"utf8\")) as { name?: unknown };\n return typeof packageData.name === \"string\" ? packageData.name : undefined;\n } catch {\n return undefined;\n }\n}\n\nexport function npmPackageName(source: string): string {\n const spec = source.slice(\"npm:\".length);\n if (spec.startsWith(\"@\")) return spec.split(\"@\").slice(0, 2).join(\"@\");\n return spec.split(\"@\")[0] ?? spec;\n}\n\nfunction sourceIdentity(source: string, baseDirectory: string): string {\n if (source.startsWith(\"npm:\")) return `npm:${npmPackageName(source)}`;\n return resolveSourcePath(source, baseDirectory);\n}\n\nfunction resolveSourcePath(source: string, baseDirectory: string): string {\n return isAbsolute(source) ? source : resolve(baseDirectory, source);\n}\n", "import type { Theme } from \"@earendil-works/pi-coding-agent\";\nimport { visibleWidth } from \"@earendil-works/pi-tui\";\nimport { ansiStyle } from \"./ansi.js\";\nimport { resolvePreset } from \"./presets/index.js\";\nimport type { BlockColors, PowerlinePreset } from \"./presets/types.js\";\nimport {\n LINE_BREAK_SEGMENT_NAME,\n type PalettePreset,\n type PowerlineBlockName,\n type RenderItem,\n type RenderSegment,\n type SegmentPalette,\n type SeparatorName,\n type StatuslineConfig,\n} from \"./types.js\";\n\ninterface PowerlineBlock {\n baseBlock: PowerlineBlockName;\n colors: BlockColors;\n segments: RenderSegment[];\n}\n\nexport function renderPowerlineStatusline(\n width: number,\n items: RenderItem[],\n config: Pick<StatuslineConfig, \"palettePreset\" | \"palette\" | \"density\" | \"separator\">,\n trueColor = true,\n): string {\n if (items.length === 0 || width <= 0) return \"\";\n return splitLines(items)\n .map((segments) => fitPowerlineSegments(segments, width, config, trueColor))\n .join(\"\\n\");\n}\n\nfunction splitLines(items: RenderItem[]): RenderSegment[][] {\n const lines: RenderSegment[][] = [[]];\n for (const item of items) {\n if (item.name === LINE_BREAK_SEGMENT_NAME) lines.push([]);\n else lines.at(-1)?.push(item);\n }\n return lines;\n}\n\nconst SEGMENT_RETENTION_PRIORITY: Readonly<Record<RenderSegment[\"name\"], number>> = {\n context: 120,\n model: 110,\n branch: 100,\n tools: 90,\n cwd: 80,\n thinking: 70,\n cost: 60,\n provider: 50,\n cache: 45,\n tokens: 40,\n time: 30,\n turn: 20,\n brand: 10,\n};\n\nfunction fitPowerlineSegments(\n segments: readonly RenderSegment[],\n width: number,\n config: Pick<StatuslineConfig, \"palettePreset\" | \"palette\" | \"density\" | \"separator\">,\n trueColor: boolean,\n): string {\n if (segments.length === 0) return \"\";\n const fitted = [...segments];\n while (fitted.length > 1) {\n const rendered = joinPowerlineSegments(fitted, config, trueColor);\n if (visibleWidth(rendered) <= width) return rendered;\n let removalIndex = 0;\n for (let index = 1; index < fitted.length; index += 1) {\n const candidate = fitted[index];\n const current = fitted[removalIndex];\n if (\n candidate &&\n current &&\n SEGMENT_RETENTION_PRIORITY[candidate.name] < SEGMENT_RETENTION_PRIORITY[current.name]\n ) {\n removalIndex = index;\n }\n }\n fitted.splice(removalIndex, 1);\n }\n const rendered = joinPowerlineSegments(fitted, config, trueColor);\n return visibleWidth(rendered) <= width ? rendered : \"\";\n}\n\nexport function powerlineExtensionSeparator(\n _theme: Theme,\n palettePreset: PalettePreset = \"tokyo-night\",\n trueColor = true,\n): string {\n return ansiStyle(\" \u2022 \", { fg: resolvePreset(palettePreset).extensionSeparator }, trueColor);\n}\n\nfunction joinPowerlineSegments(\n segments: RenderSegment[],\n config: Pick<StatuslineConfig, \"palettePreset\" | \"palette\" | \"density\" | \"separator\">,\n trueColor: boolean,\n): string {\n const preset = resolvePreset(config.palettePreset);\n const blocks = contiguousBlocks(segments, preset, config.palettePreset, config.palette);\n let line = ansiStyle(\"\u2591\u2592\u2593\", { fg: preset.lead }, trueColor);\n\n for (const [index, block] of blocks.entries()) {\n const previous = index === 0 ? undefined : blocks[index - 1]?.colors;\n if (previous) {\n line += ansiStyle(\"\uE0B4\", { fg: previous.bg, bg: block.colors.bg }, trueColor);\n }\n line += ansiStyle(formatBlockText(block, config), block.colors, trueColor);\n }\n\n const lastBlock = blocks.at(-1);\n if (lastBlock) line += ansiStyle(\"\uE0B4\", { fg: lastBlock.colors.bg }, trueColor);\n return line;\n}\n\nfunction contiguousBlocks(\n segments: RenderSegment[],\n preset: PowerlinePreset,\n palettePreset: PalettePreset,\n configuredPalette: SegmentPalette,\n): PowerlineBlock[] {\n const blocks: PowerlineBlock[] = [];\n const usesConfiguredColors = palettePreset === \"custom\";\n for (const segment of segments) {\n const colors = usesConfiguredColors ? (configuredPalette[segment.name] ?? {}) : preset.blocks[segment.block];\n const previous = blocks.at(-1);\n const matchesPrevious =\n previous !== undefined &&\n (usesConfiguredColors ? colorsEqual(previous.colors, colors) : previous.baseBlock === segment.block);\n if (matchesPrevious) previous.segments.push(segment);\n else blocks.push({ baseBlock: segment.block, colors, segments: [segment] });\n }\n return blocks;\n}\n\nfunction colorsEqual(left: BlockColors, right: BlockColors): boolean {\n return left.fg === right.fg && left.bg === right.bg;\n}\n\nfunction formatBlockText(block: PowerlineBlock, config: Pick<StatuslineConfig, \"density\" | \"separator\">): string {\n const texts = block.segments.map(formatSegmentText);\n const separator = separatorText(config.separator, config.density === \"cozy\");\n const leading = config.density === \"cozy\" ? \" \" : \" \";\n const trailing = config.density === \"cozy\" ? \" \" : \"\";\n return `${leading}${texts.join(separator)}${trailing}`;\n}\n\nfunction formatSegmentText(segment: RenderSegment): string {\n return segment.emphasis ? `\\u001b[1m${segment.text}\\u001b[22m` : segment.text;\n}\n\nfunction separatorText(separator: SeparatorName, cozy: boolean): string {\n const padding = cozy ? \" \" : \" \";\n switch (separator) {\n case \"dot\":\n return `${padding}\u2022${padding}`;\n case \"bar\":\n return `${padding}\u2502${padding}`;\n case \"powerline\":\n return `${padding}\uE0B1${padding}`;\n case \"round\":\n return `${padding}\u276F${padding}`;\n case \"none\":\n return padding;\n }\n}\n", "export function ansiStyle(text: string, colors: { fg?: string; bg?: string }, trueColor = true): string {\n const codes = [\n colors.fg ? colorCode(\"38\", colors.fg, trueColor) : undefined,\n colors.bg ? colorCode(\"48\", colors.bg, trueColor) : undefined,\n ].filter((code): code is string => code !== undefined);\n if (codes.length === 0) return text;\n return `\\u001b[${codes.join(\";\")}m${text}\\u001b[0m`;\n}\n\nexport function ansiFg(hex: string, text: string, trueColor = true): string {\n return ansiStyle(text, { fg: hex }, trueColor);\n}\n\nfunction colorCode(prefix: \"38\" | \"48\", hex: string, trueColor: boolean): string {\n const { red, green, blue } = hexToRgb(hex);\n return trueColor ? `${prefix};2;${red};${green};${blue}` : `${prefix};5;${rgbToAnsi256(red, green, blue)}`;\n}\n\nfunction rgbToAnsi256(red: number, green: number, blue: number): number {\n const channels = [red, green, blue].map((value) => Math.round((value / 255) * 5));\n return 16 + 36 * (channels[0] ?? 0) + 6 * (channels[1] ?? 0) + (channels[2] ?? 0);\n}\n\nfunction hexToRgb(hex: string): { red: number; green: number; blue: number } {\n const normalized = hex.replace(/^#/, \"\");\n return {\n red: Number.parseInt(normalized.slice(0, 2), 16),\n green: Number.parseInt(normalized.slice(2, 4), 16),\n blue: Number.parseInt(normalized.slice(4, 6), 16),\n };\n}\n", "import { isAbsolute } from \"node:path\";\nimport type { ExtensionAPI } from \"@earendil-works/pi-coding-agent\";\n\nconst GIT_STATUS_TIMEOUT_MS = 3_000;\n\nexport interface GitStatusSummary {\n root?: string;\n ahead: number;\n behind: number;\n staged: number;\n modified: number;\n untracked: number;\n conflicts: number;\n}\n\nexport async function readGitStatus(\n pi: ExtensionAPI,\n cwd: string,\n signal?: AbortSignal,\n): Promise<GitStatusSummary | undefined> {\n const [statusResult, rootResult] = await Promise.all([\n pi.exec(\"git\", [\"--no-optional-locks\", \"status\", \"--porcelain=v1\", \"--branch\", \"--untracked-files=normal\"], {\n cwd,\n timeout: GIT_STATUS_TIMEOUT_MS,\n signal,\n }),\n pi\n .exec(\"git\", [\"rev-parse\", \"--path-format=absolute\", \"--show-toplevel\"], {\n cwd,\n timeout: GIT_STATUS_TIMEOUT_MS,\n signal,\n })\n .catch(() => undefined),\n ]);\n if (statusResult.code !== 0 || statusResult.killed) return undefined;\n const summary = parseGitStatusPorcelain(statusResult.stdout);\n if (rootResult && rootResult.code === 0 && !rootResult.killed) {\n const root = parseGitRoot(rootResult.stdout);\n if (root) summary.root = root;\n }\n return summary;\n}\n\nexport function parseGitStatusPorcelain(output: string): GitStatusSummary {\n const summary: GitStatusSummary = {\n ahead: 0,\n behind: 0,\n staged: 0,\n modified: 0,\n untracked: 0,\n conflicts: 0,\n };\n for (const line of output.split(/\\r?\\n/)) {\n if (!line) continue;\n if (line.startsWith(\"## \")) {\n const ahead = line.match(/\\bahead (\\d+)/u);\n const behind = line.match(/\\bbehind (\\d+)/u);\n summary.ahead = ahead ? Number(ahead[1]) : 0;\n summary.behind = behind ? Number(behind[1]) : 0;\n continue;\n }\n const indexStatus = line[0] ?? \" \";\n const worktreeStatus = line[1] ?? \" \";\n if (indexStatus === \"?\" && worktreeStatus === \"?\") {\n summary.untracked += 1;\n continue;\n }\n if (isConflictStatus(indexStatus, worktreeStatus)) {\n summary.conflicts += 1;\n continue;\n }\n if (isChangedStatus(indexStatus)) summary.staged += 1;\n if (isChangedStatus(worktreeStatus)) summary.modified += 1;\n }\n return summary;\n}\n\nfunction isConflictStatus(indexStatus: string, worktreeStatus: string): boolean {\n return (\n (indexStatus === \"D\" && worktreeStatus === \"D\") ||\n (indexStatus === \"A\" && worktreeStatus === \"A\") ||\n indexStatus === \"U\" ||\n worktreeStatus === \"U\"\n );\n}\n\nfunction isChangedStatus(status: string): boolean {\n return status !== \" \" && status !== \"?\" && status !== \"!\";\n}\n\nexport function parseGitRoot(output: string): string | undefined {\n const root = output.split(/\\r?\\n/u)[0]?.trim();\n return root && isAbsolute(root) ? root : undefined;\n}\n\nexport function formatGitStatusSummary(summary: GitStatusSummary | undefined): string {\n if (!summary) return \"\";\n const tokens = [\n [\"\u21E1\", summary.ahead],\n [\"\u21E3\", summary.behind],\n [\"+\", summary.staged],\n [\"~\", summary.modified],\n [\"?\", summary.untracked],\n [\"!\", summary.conflicts],\n ] as const;\n return tokens\n .filter(([, count]) => count > 0)\n .map(([prefix, count]) => `${prefix}${formatCount(count)}`)\n .join(\" \");\n}\n\nexport function formatGitBranchValue(branch: string | null, status: GitStatusSummary | undefined, pr?: string): string {\n if (!branch) return \"no-git\";\n const suffixes = [formatGitStatusSummary(status), pr ? `(${pr})` : \"\"].filter(Boolean);\n return suffixes.length > 0 ? `${branch} ${suffixes.join(\" \")}` : branch;\n}\n\nexport function formatGitBranchText(branch: string | null, status: GitStatusSummary | undefined, pr?: string): string {\n return `\uD83C\uDF3F ${formatGitBranchValue(branch, status, pr)}`;\n}\n\nexport function gitStatusSummaryEqual(\n left: GitStatusSummary | undefined,\n right: GitStatusSummary | undefined,\n): boolean {\n if (!left || !right) return left === right;\n return (\n left.root === right.root &&\n left.ahead === right.ahead &&\n left.behind === right.behind &&\n left.staged === right.staged &&\n left.modified === right.modified &&\n left.untracked === right.untracked &&\n left.conflicts === right.conflicts\n );\n}\n\nfunction formatCount(value: number): string {\n return Intl.NumberFormat(\"en\", { notation: \"compact\", maximumFractionDigits: 1 }).format(value);\n}\n", "import type {\n ExtensionAPI,\n ExtensionContext,\n ReadonlyFooterDataProvider,\n Theme,\n ThemeColor,\n UIPromptKind,\n} from \"@earendil-works/pi-coding-agent\";\nimport { sliceByColumn, visibleWidth } from \"@earendil-works/pi-tui\";\nimport { sanitizeTerminalText } from \"@narumitw/pi-tui-kit/terminal-text\";\nimport { formatDirectoryPath } from \"./directory.js\";\nimport { type ExtensionStatusRuntime, formatExtensionStatuses, wrapExtensionStatusline } from \"./extension-status.js\";\nimport { formatGitBranchValue, type GitStatusSummary } from \"./git-status.js\";\nimport { renderPowerlineStatusline } from \"./powerline.js\";\nimport {\n LINE_BREAK_SEGMENT_NAME,\n type PowerlineBlockName,\n type RenderItem,\n type RenderSegment,\n type SegmentName,\n type StatuslineConfig,\n type TruncationDirection,\n} from \"./types.js\";\nimport { type FooterUsageSummary, summarizeFooterUsage } from \"./usage.js\";\n\ntype ThinkingLevel = ReturnType<ExtensionAPI[\"getThinkingLevel\"]>;\nexport interface RuntimeState extends ExtensionStatusRuntime {\n homeDir?: string;\n turnCount: number;\n activeTools: Map<string, number>;\n isStreaming: boolean;\n uiPrompt?: { kind: UIPromptKind; title?: string };\n thinkingLevel: ThinkingLevel;\n gitStatus?: GitStatusSummary;\n requestRender?: () => void;\n}\nconst GITHUB_PR_KEY = \"github-pr\";\nconst GITHUB_PR_STATUS_KEYS = new Set([GITHUB_PR_KEY]);\nexport function renderStatusline(\n width: number,\n ctx: ExtensionContext,\n footerData: ReadonlyFooterDataProvider,\n _theme: Theme,\n config: StatuslineConfig,\n runtime: RuntimeState,\n trueColor = true,\n): string {\n if (width <= 0) return \"\";\n\n const usageSummary = summarizeFooterUsage(ctx.sessionManager.getEntries());\n const rows: Array<{ configuredSegments: number; segments: RenderSegment[] }> = [\n { configuredSegments: 0, segments: [] },\n ];\n for (const name of config.segments) {\n if (name === LINE_BREAK_SEGMENT_NAME) {\n rows.push({ configuredSegments: 0, segments: [] });\n continue;\n }\n\n const row = rows.at(-1);\n if (!row) continue;\n row.configuredSegments += 1;\n const rendered = buildSegment(name, ctx, footerData, config, runtime, usageSummary);\n if (rendered && rendered.text.length > 0) row.segments.push(rendered);\n }\n\n const segments: RenderItem[] = [];\n const renderedRows = rows.filter((row) => row.configuredSegments === 0 || row.segments.length > 0);\n for (const [index, row] of renderedRows.entries()) {\n if (index > 0) segments.push({ name: LINE_BREAK_SEGMENT_NAME });\n segments.push(...row.segments);\n }\n\n return renderPowerlineStatusline(width, segments, config, trueColor);\n}\n\nexport function renderExtensionStatusline(\n width: number,\n footerData: ReadonlyFooterDataProvider,\n theme: Theme,\n config: StatuslineConfig,\n runtime: RuntimeState,\n mainLine: string,\n trueColor = true,\n): string[] {\n const statuses = footerData.getExtensionStatuses();\n const prContext = prContextFromStatuses(statuses);\n const rendersPrInline = prContext !== undefined && mainLine.includes(prContext);\n const status = formatExtensionStatuses(\n statuses,\n theme,\n config,\n runtime,\n rendersPrInline ? GITHUB_PR_STATUS_KEYS : undefined,\n trueColor,\n );\n return wrapExtensionStatusline(status, width);\n}\n\nfunction buildSegment(\n name: SegmentName,\n ctx: ExtensionContext,\n footerData: ReadonlyFooterDataProvider,\n config: StatuslineConfig,\n runtime: RuntimeState,\n usageSummary: FooterUsageSummary,\n): RenderSegment | undefined {\n switch (name) {\n case \"brand\":\n return segment(name, \"\u03C0\", config, \"accent\", \"header\", true);\n case \"provider\":\n return segment(name, ctx.model?.provider ?? \"no-provider\", config, \"accent\", \"header\");\n case \"model\": {\n const presentation = config.segmentText.model;\n const model = truncateModel(\n shortenModel(ctx.model?.id ?? \"no-model\"),\n presentation.truncationLength,\n presentation.truncationSymbol,\n presentation.truncationDirection,\n );\n return segment(name, model, config, \"accent\", \"header\");\n }\n case \"thinking\":\n return segment(name, runtime.thinkingLevel, config, thinkingColor(runtime.thinkingLevel), \"header\");\n case \"branch\": {\n const branch = footerData.getGitBranch();\n const pr = branch ? prContextFromStatuses(footerData.getExtensionStatuses()) : undefined;\n return segment(name, formatGitBranchValue(branch, runtime.gitStatus, pr), config, \"accent\", \"git\");\n }\n case \"cwd\":\n return segment(\n name,\n formatDirectoryPath(ctx.cwd, runtime.homeDir, runtime.gitStatus?.root),\n config,\n \"accent\",\n \"directory\",\n );\n case \"tools\": {\n const activity = formatToolActivity(runtime);\n return activity ? segment(name, activity, config, \"accent\", \"runtime\") : undefined;\n }\n case \"context\": {\n const usage = ctx.getContextUsage();\n const percentage = usage?.percent === null || usage?.percent === undefined ? \"?\" : `${usage.percent.toFixed(1)}%`;\n const contextWindow = usage?.contextWindow ?? ctx.model?.contextWindow ?? 0;\n return segment(\n name,\n `${percentage}/${formatCount(contextWindow)}`,\n config,\n contextColor(usage?.percent),\n \"runtime\",\n );\n }\n case \"tokens\": {\n const value =\n usageSummary.input === 0 && usageSummary.output === 0\n ? \"tok 0\"\n : `\u2191${formatCount(usageSummary.input)} \u2193${formatCount(usageSummary.output)}`;\n return segment(name, value, config, \"accent\", \"runtime\");\n }\n case \"cache\": {\n if (usageSummary.cacheRead === 0 && usageSummary.cacheWrite === 0) return undefined;\n const values: string[] = [];\n if (usageSummary.cacheRead > 0) values.push(`R${formatCount(usageSummary.cacheRead)}`);\n if (usageSummary.cacheWrite > 0) values.push(`W${formatCount(usageSummary.cacheWrite)}`);\n if (usageSummary.latestCacheHitRate !== undefined) {\n values.push(`CH${usageSummary.latestCacheHitRate.toFixed(1)}%`);\n }\n return segment(name, values.join(\" \"), config, \"accent\", \"runtime\");\n }\n case \"cost\": {\n const subscription = isSubscriptionBacked(ctx) ? \" (sub)\" : \"\";\n return segment(\n name,\n `${usageSummary.cost.toFixed(usageSummary.cost >= 1 ? 2 : 3)}${subscription}`,\n config,\n \"accent\",\n \"meter\",\n );\n }\n case \"time\":\n return segment(name, formatTime(), config, \"accent\", \"meter\");\n case \"turn\":\n return segment(name, `${runtime.turnCount}`, config, \"accent\", \"meter\");\n }\n}\n\nfunction segment(\n name: SegmentName,\n value: string,\n config: StatuslineConfig,\n color: RenderSegment[\"color\"],\n block: PowerlineBlockName,\n emphasis = false,\n): RenderSegment {\n return { name, text: formatConfiguredSegment(name, value, config), color, block, emphasis };\n}\n\nexport function formatConfiguredSegment(\n name: SegmentName,\n value: string,\n config: Pick<StatuslineConfig, \"segmentText\">,\n): string {\n const presentation = config.segmentText[name];\n return `${presentation.prefix}${value}${presentation.suffix}`;\n}\n\nfunction thinkingColor(level: ThinkingLevel): ThemeColor {\n switch (level as string) {\n case \"off\":\n return \"dim\";\n case \"minimal\":\n return \"thinkingMinimal\";\n case \"low\":\n return \"thinkingLow\";\n case \"medium\":\n return \"thinkingMedium\";\n case \"high\":\n return \"thinkingHigh\";\n case \"xhigh\":\n return \"thinkingXhigh\";\n case \"max\":\n return \"thinkingMax\" as ThemeColor;\n default:\n return \"dim\";\n }\n}\n\nexport function contextColor(percent: number | null | undefined): ThemeColor {\n if (percent === null || percent === undefined) return \"dim\";\n if (percent >= 90) return \"error\";\n if (percent >= 70) return \"warning\";\n return \"success\";\n}\n\nconst MAX_UI_PROMPT_TITLE_CODE_POINTS = 256;\nconst MAX_UI_PROMPT_TITLE_WIDTH = 40;\n\nfunction boundUIPromptTitleLength(title: string): string {\n let end = 0;\n let ellipsisEnd = 0;\n let codePoints = 0;\n while (end < title.length && codePoints < MAX_UI_PROMPT_TITLE_CODE_POINTS) {\n const codePoint = title.codePointAt(end) ?? 0;\n end += codePoint > 0xffff ? 2 : 1;\n codePoints += 1;\n if (codePoints < MAX_UI_PROMPT_TITLE_CODE_POINTS) ellipsisEnd = end;\n }\n return end < title.length ? `${title.slice(0, ellipsisEnd)}\u2026` : title;\n}\n\nfunction formatUIPromptTitle(title: string | undefined): string {\n const safeTitle = title ? sanitizeTerminalText(title).trim() : \"\";\n const boundedTitle = boundUIPromptTitleLength(safeTitle);\n if (visibleWidth(boundedTitle) <= MAX_UI_PROMPT_TITLE_WIDTH) return boundedTitle;\n return `${sliceByColumn(boundedTitle, 0, MAX_UI_PROMPT_TITLE_WIDTH - 1, true)}\u2026`;\n}\n\nexport function formatToolActivity(runtime: RuntimeState): string | undefined {\n if (runtime.uiPrompt) {\n const title = formatUIPromptTitle(runtime.uiPrompt.title);\n return `\u2328 waiting for ${runtime.uiPrompt.kind}${title ? ` \u00B7 ${title}` : \"\"}`;\n }\n\n const active = [...runtime.activeTools.entries()];\n if (active.length > 0) {\n const [name, count] = active[0] ?? [\"tool\", 1];\n const suffix = count > 1 ? `\u00D7${count}` : active.length > 1 ? `+${active.length - 1}` : \"\";\n return `\u2699\uFE0F ${name}${suffix}`;\n }\n\n return runtime.isStreaming ? \"\uD83D\uDCAD thinking\" : undefined;\n}\n\nexport function prLinkFromStatuses(statuses: ReadonlyMap<string, string>): string | undefined {\n const value = statuses.get(GITHUB_PR_KEY);\n if (!value) return undefined;\n // Extract the OSC 8 hyperlink span (the clickable \"#123\"); skip non-PR states\n // like \"PR gh missing\" that carry no link. github-pr emits exactly one link, so the\n // first OSC 8 span is the PR number.\n const open = value.indexOf(\"\\x1b]8;;\");\n if (open === -1) return undefined;\n const closeMarker = \"\\x1b]8;;\\x07\";\n const close = value.indexOf(closeMarker, open + 1);\n return close === -1 ? undefined : value.slice(open, close + closeMarker.length);\n}\n\nexport function prContextFromStatuses(statuses: ReadonlyMap<string, string>): string | undefined {\n const value = statuses.get(GITHUB_PR_KEY);\n if (!value) return undefined;\n const link = prLinkFromStatuses(statuses);\n const reference = link ?? plainPrReference(value);\n if (!reference) return undefined;\n\n const state = compactPrState(link ? value.replace(link, \"\") : value);\n return state ? `${reference} \u00B7 ${state}` : undefined;\n}\n\nfunction plainPrReference(value: string): string | undefined {\n return /^PR\\s+(#\\d+):/u.exec(value)?.[1];\n}\n\nfunction compactPrState(value: string): string | undefined {\n if (/:\\s*merged\\s*$/.test(value)) return \"merged\";\n if (/:\\s*closed\\s*$/.test(value)) return \"closed\";\n if (/\\bdraft\\b/.test(value)) return \"draft\";\n\n const failing = /\\bchecks failing \\((\\d+)\\)/.exec(value);\n if (failing) return `${failing[1]} failing`;\n if (/\\bchanges requested\\b/.test(value)) return \"changes requested\";\n\n const pending = /\\bchecks pending \\((\\d+)\\)/.exec(value);\n if (pending) return `${pending[1]} pending`;\n if (/\\bapproved\\b/.test(value)) return \"approved\";\n if (/\\breview required\\b/.test(value)) return \"review required\";\n if (/\\bchecks passing\\b/.test(value)) return \"checks passing\";\n if (/\\bno checks\\b/.test(value)) return \"no checks\";\n return undefined;\n}\n\nfunction isSubscriptionBacked(ctx: ExtensionContext): boolean {\n const model = ctx.model;\n return model !== undefined && (model.provider === \"kimi-coding\" || ctx.modelRegistry.isUsingOAuth(model));\n}\n\nexport function formatCount(value: number): string {\n if (value < 1000) return `${value}`;\n if (value < 1_000_000) return `${(value / 1000).toFixed(value < 10_000 ? 1 : 0)}k`;\n return `${(value / 1_000_000).toFixed(1)}m`;\n}\n\nfunction formatTime(): string {\n const now = new Date();\n const hours = now.getHours().toString().padStart(2, \"0\");\n const minutes = now.getMinutes().toString().padStart(2, \"0\");\n return `${hours}:${minutes}`;\n}\n\nconst graphemeSegmenter = new Intl.Segmenter(undefined, { granularity: \"grapheme\" });\n\nexport function truncateModel(model: string, length: number, symbol: string, direction: TruncationDirection): string {\n const safeModel = sanitizeTerminalText(model);\n if (length === 0) return safeModel;\n const graphemes = [...graphemeSegmenter.segment(safeModel)].map(({ segment }) => segment);\n if (graphemes.length <= length) return safeModel;\n const safeSymbol = sanitizeTerminalText(symbol);\n\n switch (direction) {\n case \"start\":\n return `${safeSymbol}${graphemes.slice(-length).join(\"\")}`;\n case \"middle\": {\n const headLength = Math.ceil(length / 2);\n const tailLength = Math.floor(length / 2);\n const tail = tailLength > 0 ? graphemes.slice(-tailLength).join(\"\") : \"\";\n return `${graphemes.slice(0, headLength).join(\"\")}${safeSymbol}${tail}`;\n }\n case \"end\":\n return `${graphemes.slice(0, length).join(\"\")}${safeSymbol}`;\n }\n}\n\nexport function shortenModel(model: string): string {\n return model\n .replace(/^claude-/, \"\")\n .replace(/^gpt-/, \"gpt \")\n .replace(/-20\\d{6}$/, \"\")\n .replace(/-latest$/, \"\");\n}\n", "import { basename, isAbsolute, relative, sep } from \"node:path\";\nimport { sanitizeTerminalText } from \"@narumitw/pi-tui-kit/terminal-text\";\n\nconst DEFAULT_TRUNCATION_LENGTH = 3;\nconst DEFAULT_HOME_SYMBOL = \"~\";\n\n/** Apply Starship's default directory presentation without exposing a format language. */\nexport function formatDirectoryPath(cwd: string, homeDir: string | undefined, gitRoot: string | undefined): string {\n const contracted =\n gitRoot && (!homeDir || !samePath(gitRoot, homeDir))\n ? (contractRepositoryPath(cwd, gitRoot) ?? contractPath(cwd, homeDir, DEFAULT_HOME_SYMBOL))\n : contractPath(cwd, homeDir, DEFAULT_HOME_SYMBOL);\n const safeContracted = sanitizeTerminalText(contracted);\n const components = safeContracted.split(\"/\").filter((component) => component.length > 0);\n const displayed =\n components.length > DEFAULT_TRUNCATION_LENGTH\n ? components.slice(-DEFAULT_TRUNCATION_LENGTH).join(\"/\")\n : safeContracted;\n const native = sep === \"/\" ? displayed : displayed.replaceAll(\"/\", sep);\n return sanitizeTerminalText(native || basename(cwd) || cwd);\n}\n\nfunction toSlashPath(value: string): string {\n return sep === \"\\\\\" ? value.replaceAll(\"\\\\\", \"/\") : value;\n}\n\nfunction contractPath(path: string, root: string | undefined, replacement: string): string {\n if (!root) return toSlashPath(path);\n const child = relativeWithin(path, root);\n if (child === undefined) return toSlashPath(path);\n return child ? `${replacement}/${child}` : replacement;\n}\n\nfunction contractRepositoryPath(path: string, root: string): string | undefined {\n const child = relativeWithin(path, root);\n if (child === undefined) return undefined;\n const name = basename(root) || toSlashPath(root);\n return child ? `${name}/${child}` : name;\n}\n\nfunction relativeWithin(path: string, root: string): string | undefined {\n const child = relative(root, path);\n if (child === \"\") return \"\";\n if (child === \"..\" || child.startsWith(`..${sep}`) || isAbsolute(child)) return undefined;\n return toSlashPath(child);\n}\n\nfunction samePath(left: string, right: string): boolean {\n return relative(left, right) === \"\";\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 };\n}\n\nexport interface FooterUsageSummary {\n input: number;\n output: number;\n cacheRead: number;\n cacheWrite: number;\n cost: number;\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 };\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 }\n\n return totals;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["getAgentDir", "rendered", "segment", "isAbsolute", "visibleWidth", "sanitizeTerminalText", "isAbsolute", "formatCount", "sanitizeTerminalText", "visibleWidth", "segment", "STATUSLINE_KEY", "EMPTY_EXTENSION_STATUS_ICON_ALIASES", "getAgentDir"]
|
|
7
7
|
}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
# Pi Statusline configuration reference
|
|
2
|
+
|
|
3
|
+
[Back to README](../README.md)
|
|
4
|
+
|
|
5
|
+
- [Settings fields](#settings-reference)
|
|
6
|
+
- [Appearance and palettes](#-appearance)
|
|
7
|
+
- [Model truncation](#model-truncation)
|
|
8
|
+
- [Advanced layout and controls](#-advanced-layout)
|
|
9
|
+
- [Extension statuses and icons](#-extension-statuses-and-icons)
|
|
10
|
+
|
|
11
|
+
## ⚙️ Settings
|
|
12
|
+
|
|
13
|
+
The extension uses one user-level file:
|
|
14
|
+
|
|
15
|
+
```text
|
|
16
|
+
<getAgentDir()>/pi-statusline.json
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
There are no project or environment overrides.
|
|
20
|
+
When the file is absent, pi-statusline uses built-in defaults without creating the file or its parent directory.
|
|
21
|
+
The first successful settings save creates a complete editable document atomically.
|
|
22
|
+
Malformed or unreadable settings are never overwritten.
|
|
23
|
+
Settings reload on startup, `/reload`, and session replacement.
|
|
24
|
+
|
|
25
|
+
A valid legacy `pi-statusline-settings.json` remains readable with a warning and is never modified automatically; rename it to `pi-statusline.json`.
|
|
26
|
+
If both files exist, `pi-statusline.json` wins.
|
|
27
|
+
|
|
28
|
+
### Settings reference
|
|
29
|
+
|
|
30
|
+
| Field | Accepted values | Purpose |
|
|
31
|
+
| --- | --- | --- |
|
|
32
|
+
| `palettePreset` | `tokyo-night`, `ocean`, `sunset`, `forest`, `candy`, `neon`, `mono`, `custom` | Select the active color preset |
|
|
33
|
+
| `palette` | Per-segment `fg`/`bg` `#RRGGBB` colors | Define colors used by `custom` |
|
|
34
|
+
| `density` | `compact`, `cozy` | Control horizontal padding |
|
|
35
|
+
| `separator` | `none`, `dot`, `bar`, `powerline`, `round` | Separate adjacent segments in one color block |
|
|
36
|
+
| `segments` | Ordered unique segment names and `line_break` | Control visibility, order, and rows |
|
|
37
|
+
| `segmentText` | Per-segment `prefix` and `suffix`; model truncation fields | Format Pi-owned dynamic values |
|
|
38
|
+
| `extensionStatusIcons` | Raw status key or `namespace:*` to icon string | Customize extension status icons |
|
|
39
|
+
|
|
40
|
+
All fields are optional in an existing document.
|
|
41
|
+
Missing fields use defaults.
|
|
42
|
+
Menu saves warn about and preserve unknown fields.
|
|
43
|
+
Invalid recognized values block saving and leave the file and live footer unchanged.
|
|
44
|
+
|
|
45
|
+
A compact customization example:
|
|
46
|
+
|
|
47
|
+
```json
|
|
48
|
+
{
|
|
49
|
+
"palettePreset": "ocean",
|
|
50
|
+
"density": "compact",
|
|
51
|
+
"separator": "dot",
|
|
52
|
+
"segments": ["model", "thinking", "cwd", "branch", "context", "cache", "cost"],
|
|
53
|
+
"segmentText": {
|
|
54
|
+
"model": {
|
|
55
|
+
"truncationLength": 40,
|
|
56
|
+
"truncationSymbol": "…",
|
|
57
|
+
"truncationDirection": "middle"
|
|
58
|
+
},
|
|
59
|
+
"context": { "prefix": "ctx ", "suffix": "" }
|
|
60
|
+
},
|
|
61
|
+
"extensionStatusIcons": {
|
|
62
|
+
"goal": "◎",
|
|
63
|
+
"foo:*": "🧪"
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Use **Advanced → Edit settings JSON** or `/statusline settings` to edit, validate, atomically save, and apply the file.
|
|
69
|
+
|
|
70
|
+
## 🎨 Appearance
|
|
71
|
+
|
|
72
|
+
Named palettes provide contrast-checked color ramps.
|
|
73
|
+
Appearance previews update while the picker moves, but save only when Enter is pressed; Escape restores the saved palette.
|
|
74
|
+
|
|
75
|
+
When `palettePreset` is `custom`, `palette` maps segment names to foreground/background colors:
|
|
76
|
+
|
|
77
|
+
```json
|
|
78
|
+
{
|
|
79
|
+
"palettePreset": "custom",
|
|
80
|
+
"palette": {
|
|
81
|
+
"model": { "fg": "#090c0c", "bg": "#a3aed2" },
|
|
82
|
+
"context": { "fg": "#c0caf5", "bg": "#1d2230" }
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
- Selecting `custom` without a palette copies the active named preset as a starting point.
|
|
88
|
+
- A manually authored `"palettePreset": "custom"` without `palette` uses Tokyo Night colors.
|
|
89
|
+
- Named presets ignore but preserve an existing custom palette.
|
|
90
|
+
- A `palette` object without `palettePreset` selects `custom`.
|
|
91
|
+
- Legacy string palettes such as `"palette": "ocean"` remain accepted.
|
|
92
|
+
- Missing custom colors remain unstyled instead of inheriting Tokyo Night.
|
|
93
|
+
- Adjacent segments with identical colors share one block; transitions use ``.
|
|
94
|
+
- Hex palette colors render as ANSI-256 when Pi's effective terminal capabilities disable true color.
|
|
95
|
+
|
|
96
|
+
`segmentText` values must be single-line text without terminal control characters.
|
|
97
|
+
Use `line_break` for another row rather than inserting a newline into a prefix or suffix.
|
|
98
|
+
|
|
99
|
+
### Model truncation
|
|
100
|
+
|
|
101
|
+
Long model IDs are truncated out of the box so the balanced footer can retain useful model context:
|
|
102
|
+
|
|
103
|
+
```json
|
|
104
|
+
{
|
|
105
|
+
"segmentText": {
|
|
106
|
+
"model": {
|
|
107
|
+
"truncationLength": 36,
|
|
108
|
+
"truncationSymbol": "…",
|
|
109
|
+
"truncationDirection": "start"
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
`truncationLength` counts model grapheme clusters retained before the symbol.
|
|
116
|
+
The built-in value is `36`; set it to `0` to display the complete ID.
|
|
117
|
+
The direction names the removed portion:
|
|
118
|
+
|
|
119
|
+
- `start` retains the suffix and is the default, which is useful for long llama.cpp paths and model variants.
|
|
120
|
+
- `middle` retains both ends.
|
|
121
|
+
- `end` retains the prefix.
|
|
122
|
+
|
|
123
|
+
Truncation runs after the built-in Claude/GPT shortening rules but before the configured model prefix and suffix.
|
|
124
|
+
It changes display only—the provider model ID is untouched.
|
|
125
|
+
Terminal control sequences in model IDs are removed at render time, and unsafe configured symbols are rejected.
|
|
126
|
+
An empty `truncationSymbol` truncates without a marker.
|
|
127
|
+
pi-statusline treats model IDs as opaque strings and does not parse paths, repositories, GGUF suffixes, or quantization names.
|
|
128
|
+
At very narrow widths, the existing responsive priorities may still omit the model rather than overflow the terminal.
|
|
129
|
+
|
|
130
|
+
## 🧩 Advanced layout
|
|
131
|
+
|
|
132
|
+
Open **Advanced → Custom layout** when the curated levels are not enough.
|
|
133
|
+
|
|
134
|
+
| Key | Action |
|
|
135
|
+
| --- | --- |
|
|
136
|
+
| Up/Down | Navigate |
|
|
137
|
+
| Page Up/Page Down | Move by one viewport |
|
|
138
|
+
| Enter/Space | Show or hide the selected segment |
|
|
139
|
+
| `M` | Enter or leave Move mode |
|
|
140
|
+
| Up/Down in Move mode | Reorder the selected visible segment |
|
|
141
|
+
| `Alt+Up` / `Alt+Down` | Reorder without entering Move mode |
|
|
142
|
+
| `B` | Add or remove a line break after the selected segment |
|
|
143
|
+
| Configured Back key (Escape by default) | Leave Move mode first, then close the screen |
|
|
144
|
+
| Ctrl+C | Close the screen immediately, including from Move mode |
|
|
145
|
+
|
|
146
|
+
The layout displays the effective Back key and keeps Ctrl+C available when Back is remapped.
|
|
147
|
+
Every successful change saves and applies immediately.
|
|
148
|
+
Closing the screen does not roll it back.
|
|
149
|
+
|
|
150
|
+
Available data segments:
|
|
151
|
+
|
|
152
|
+
```text
|
|
153
|
+
brand provider model thinking cwd branch tools context tokens cache cost time turn
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Data segments must be unique.
|
|
157
|
+
`line_break` may repeat when data segments separate occurrences, but consecutive breaks are invalid.
|
|
158
|
+
It has no `segmentText` entry.
|
|
159
|
+
The menu cleans up leading, trailing, and newly consecutive breaks after visibility changes.
|
|
160
|
+
Manually authored leading/trailing breaks represent empty rows.
|
|
161
|
+
|
|
162
|
+
```json
|
|
163
|
+
{
|
|
164
|
+
"segments": ["model", "line_break", "cwd", "branch", "context"]
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
An empty `segments` array hides the main powerline while extension statuses can still render.
|
|
169
|
+
|
|
170
|
+
## 🔌 Extension statuses and icons
|
|
171
|
+
|
|
172
|
+
Other extension statuses appear below the main powerline, wrap to terminal width, and are limited to five items.
|
|
173
|
+
Icons use this order:
|
|
174
|
+
|
|
175
|
+
1. Exact configured raw key, such as `goal` or `foo:server`.
|
|
176
|
+
2. Longest configured colon wildcard, such as `foo:*` or `foo:server:*`.
|
|
177
|
+
3. Unambiguous installed-package alias, such as `@vendor/pi-foo`, `pi-foo`, or `foo`.
|
|
178
|
+
4. Leading emoji supplied by the status text.
|
|
179
|
+
5. Built-in icon.
|
|
180
|
+
6. Generic `🔌` fallback.
|
|
181
|
+
|
|
182
|
+
Set an icon to `""` to hide only the icon.
|
|
183
|
+
Wildcards match colon namespaces, not slash-delimited keys.
|
|
184
|
+
Configure slash keys exactly.
|
|
185
|
+
Compatibility fallbacks retain `codex-usage`, `pisync`, and `unknown-error-retry`; an explicit canonical key wins.
|
|
186
|
+
|
|
187
|
+
For interoperable extensions, prefer one aggregated key or a stable coexistence slot:
|
|
188
|
+
|
|
189
|
+
```text
|
|
190
|
+
<extension-id>
|
|
191
|
+
<extension-id>:<stable-slot>
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Put transient activity in the value, and clear the exact key that was set.
|