@narumitw/pi-statusline 0.50.4 → 0.51.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.ts.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 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"],
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 gitStatusDebounceTimer.unref();\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 clock.unref();\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// Bound combined stdout/stderr while allowing large worktree listings and one absolute root path.\nconst GIT_STATUS_MAX_BUFFER = 1024 * 1024;\nconst GIT_ROOT_MAX_BUFFER = 16 * 1024;\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 maxBuffer: GIT_STATUS_MAX_BUFFER,\n signal,\n }),\n pi\n .exec(\"git\", [\"rev-parse\", \"--path-format=absolute\", \"--show-toplevel\"], {\n cwd,\n timeout: GIT_STATUS_TIMEOUT_MS,\n maxBuffer: GIT_ROOT_MAX_BUFFER,\n signal,\n })\n .catch(() => undefined),\n ]);\n if (statusResult.truncated || statusResult.code !== 0 || statusResult.killed) return undefined;\n const summary = parseGitStatusPorcelain(statusResult.stdout);\n if (rootResult && !rootResult.truncated && 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"],
5
- "mappings": "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",
6
- "names": ["getAgentDir", "rendered", "segment", "isAbsolute", "visibleWidth", "sanitizeTerminalText", "isAbsolute", "formatCount", "sanitizeTerminalText", "visibleWidth", "segment", "STATUSLINE_KEY", "EMPTY_EXTENSION_STATUS_ICON_ALIASES", "getAgentDir"]
3
+ "sources": ["../src/statusline.ts", "../src/extension-status.ts", "../src/powerline.ts", "../src/ansi.ts", "../src/extension-status-metadata.ts", "../src/git-status.ts", "../src/render.ts", "../src/directory.ts"],
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 { subscribeExtensionStatusMetadata } from \"./extension-status-metadata.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 let disposeFooter: (() => void) | 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 gitStatusDebounceTimer.unref();\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 disposeFooter?.();\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 runtime.extensionStatusMetadata = undefined;\n runtime.requestRender = undefined;\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 const sessionManager = ctx.sessionManager;\n const createFooter: NonNullable<Parameters<ExtensionContext[\"ui\"][\"setFooter\"]>[0]> = (tui, theme, footerData) => {\n if (generation !== sessionGeneration || sessionManager !== activeSessionManager) {\n return { render: () => [], invalidate() {} };\n }\n disposeFooter?.();\n activeGitStatusTarget = { cwd, generation };\n let disposed = false;\n let branchUnsubscribe: (() => void) | undefined;\n let clock: ReturnType<typeof setInterval> | undefined;\n let metadata: ReturnType<typeof subscribeExtensionStatusMetadata> | undefined;\n const isCurrentFooter = () =>\n !disposed && generation === sessionGeneration && sessionManager === activeSessionManager;\n const dispose = () => {\n if (disposed) return;\n disposed = true;\n try {\n metadata?.dispose();\n } finally {\n try {\n branchUnsubscribe?.();\n } finally {\n if (clock) clearInterval(clock);\n if (disposeFooter === dispose) {\n disposeFooter = undefined;\n runtime.extensionStatusMetadata = undefined;\n runtime.requestRender = undefined;\n }\n if (isActiveGitStatusTarget(cwd, generation)) {\n activeGitStatusTarget = undefined;\n abortGitStatusRefresh(\"Statusline footer disposed\");\n clearGitStatusDebounce();\n pendingGitStatusRefresh = undefined;\n runtime.gitStatus = undefined;\n }\n }\n }\n };\n disposeFooter = dispose;\n runtime.requestRender = () => {\n if (isCurrentFooter()) tui.requestRender();\n };\n\n try {\n const refreshFooterGitStatus = () => refreshGitStatus(cwd, generation);\n branchUnsubscribe = footerData.onBranchChange(() => {\n if (!isCurrentFooter()) return;\n runtime.gitStatus = undefined;\n abortGitStatusRefresh(\"Statusline Git branch changed\");\n clearGitStatusDebounce();\n refreshFooterGitStatus();\n refresh();\n });\n clock = setInterval(() => {\n if (!isCurrentFooter()) return;\n clearGitStatusDebounce();\n refreshFooterGitStatus();\n refresh();\n }, GIT_STATUS_REFRESH_INTERVAL_MS);\n clock.unref();\n metadata = subscribeExtensionStatusMetadata(\n pi.events,\n sessionManager,\n () => footerData.getExtensionStatuses(),\n () => {\n if (isCurrentFooter()) refresh();\n },\n );\n if (isCurrentFooter()) runtime.extensionStatusMetadata = metadata;\n else metadata.dispose();\n } catch (error) {\n dispose();\n throw error;\n }\n\n return {\n dispose,\n invalidate() {},\n render(width: number): string[] {\n if (!isCurrentFooter() || !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 try {\n ctx.ui.setFooter(createFooter);\n } catch (error) {\n disposeFooter?.();\n throw error;\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 try {\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 } catch (error) {\n disposeFooter?.();\n throw error;\n }\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 disposeFooter?.();\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 if (ctx.mode === \"tui\") 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 { truncateToWidth, visibleWidth, wrapTextWithAnsi } from \"@earendil-works/pi-tui\";\nimport { sanitizeTerminalText } from \"@narumitw/pi-tui-kit/terminal-text\";\nimport type { ExtensionStatusMetadata, ExtensionStatusPresentation } from \"./extension-status-metadata.js\";\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 extensionStatusMetadata?: ExtensionStatusMetadata;\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 runtime.extensionStatusMetadata?.reconcile(statuses);\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]) => {\n const presentation = runtime.extensionStatusMetadata?.get(key, value);\n return presentation\n ? formatCompactExtensionStatus(key, value, presentation, theme, config, runtime.extensionStatusIconAliases)\n : formatExtensionStatus(key, value, theme, config, runtime.extensionStatusIconAliases);\n })\n .filter((status) => status.length > 0),\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 formatCompactExtensionStatus(\n key: string,\n value: string,\n presentation: ExtensionStatusPresentation,\n theme: Theme,\n config: Pick<StatuslineConfig, \"extensionStatusIcons\">,\n aliases: ExtensionStatusIconAliasMap,\n): string {\n if (presentation.activity === \"idle\") return \"\";\n // Only the compact path strips terminal controls; raw statuses retain their existing PR links.\n const status = splitExtensionStatusIcon(\n stripExtensionStatusPrefix(sanitizeTerminalText(key), sanitizeTerminalText(value)),\n );\n const icon = sanitizeTerminalText(extensionStatusIcon(key, status.icon, config.extensionStatusIcons, aliases));\n const bodies = {\n checking: \"\u2026\",\n working: \"\u21BB\",\n pushing: \"\u2191\",\n pulling: \"\u2193\",\n resolving: \"AI\",\n retry: `retry: ${presentation.reason}`,\n blocked: `! ${presentation.reason}`,\n \"local-change\": \"\u21E1\",\n \"remote-change\": \"\u21E3\",\n review: \"\u21D5\",\n };\n const warning = presentation.activity === \"blocked\" || presentation.activity === \"retry\";\n const color = warning ? \"warning\" : extensionColor(key, value);\n const body = theme.fg(warning ? \"warning\" : \"muted\", bodies[presentation.activity]);\n return icon ? `${theme.fg(color, icon)} ${body}` : body;\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 = Object.hasOwn(COMPATIBLE_STATUS_ICON_KEYS, key) ? COMPATIBLE_STATUS_ICON_KEYS[key] : undefined;\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 (\n leadingIcon ?? (Object.hasOwn(DEFAULT_EXTENSION_STATUS_ICONS, key) ? DEFAULT_EXTENSION_STATUS_ICONS[key] : \"\uD83D\uDD0C\")\n );\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).map((line) =>\n visibleWidth(line) > width ? truncateToWidth(line, width, \"\") : line,\n );\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 type { ExtensionAPI } from \"@earendil-works/pi-coding-agent\";\n\nconst UPDATE_CHANNEL = \"extension-status:v1:update\";\nconst REQUEST_CHANNEL = \"extension-status:v1:request\";\nconst ACTIVITIES = new Set([\n \"idle\",\n \"checking\",\n \"working\",\n \"pushing\",\n \"pulling\",\n \"resolving\",\n \"retry\",\n \"blocked\",\n \"local-change\",\n \"remote-change\",\n \"review\",\n] as const);\n\nexport type ExtensionStatusActivity =\n | \"idle\"\n | \"checking\"\n | \"working\"\n | \"pushing\"\n | \"pulling\"\n | \"resolving\"\n | \"retry\"\n | \"blocked\"\n | \"local-change\"\n | \"remote-change\"\n | \"review\";\n\nexport interface ExtensionStatusPresentation {\n readonly value: string;\n readonly activity: ExtensionStatusActivity;\n readonly reason?: string;\n}\n\nexport interface ExtensionStatusMetadata {\n get(key: string, value: string): ExtensionStatusPresentation | undefined;\n reconcile(statuses: ReadonlyMap<string, string>): void;\n dispose(): void;\n}\n\nfunction parseMetadata(data: Record<string, unknown>): {\n presentation?: ExtensionStatusPresentation;\n withdrawal: boolean;\n} {\n if (Array.isArray(data)) return { withdrawal: false };\n // Capture fields once: accessors and proxy traps can synchronously replace the current state.\n const { version, value, activity, reason } = data;\n const hasValue = Object.hasOwn(data, \"value\");\n const hasActivity = \"activity\" in data;\n const hasReason = \"reason\" in data;\n const withdrawal = version === 1 && hasValue && value === undefined && !hasActivity && !hasReason;\n if (\n version !== 1 ||\n !hasValue ||\n typeof value !== \"string\" ||\n value.length === 0 ||\n !ACTIVITIES.has(activity as ExtensionStatusActivity)\n )\n return { withdrawal };\n if (activity === \"retry\" || activity === \"blocked\") {\n // JavaScript's $ also matches before a final newline; require the complete safe label.\n if (typeof reason !== \"string\" || /^[a-z][a-z0-9-]{0,31}$/.exec(reason)?.[0] !== reason) return { withdrawal };\n return { presentation: Object.freeze({ value, activity, reason }), withdrawal };\n }\n if (hasReason) return { withdrawal };\n return { presentation: Object.freeze({ value, activity: activity as ExtensionStatusActivity }), withdrawal };\n}\n\n/** Optional display metadata; the raw Pi status map remains authoritative. */\nexport function subscribeExtensionStatusMetadata(\n events: ExtensionAPI[\"events\"],\n sessionManager: object,\n getStatuses: () => ReadonlyMap<string, string>,\n requestRender: () => void,\n): ExtensionStatusMetadata {\n const records = new Map<string, ExtensionStatusPresentation>();\n const liveKeys = new Set<string>();\n const requestId = {};\n let observedStatuses = new Map<string, string>();\n try {\n observedStatuses = new Map(getStatuses());\n } catch {\n // A raw-map read failure must leave the ordinary footer available.\n }\n let disposed = false;\n let revision = 0;\n const keyRevisions = new Map<string, number>();\n const isCurrent = (key: string, owner: number) => !disposed && keyRevisions.get(key) === owner;\n let unsubscribe: (() => void) | undefined;\n\n const reconcile = (statuses: ReadonlyMap<string, string>, ownerKey?: string) => {\n if (disposed) return;\n const before = revision;\n const snapshot = new Map(statuses);\n if (disposed || revision !== before) return;\n for (const [key, value] of observedStatuses) {\n if (snapshot.get(key) === value) continue;\n records.delete(key);\n // An observed raw replacement must also fence off a delayed same-value snapshot.\n liveKeys.add(key);\n if (key !== ownerKey) keyRevisions.set(key, ++revision);\n }\n for (const key of snapshot.keys()) {\n if (observedStatuses.has(key)) continue;\n liveKeys.add(key);\n if (key !== ownerKey) keyRevisions.set(key, ++revision);\n }\n observedStatuses = snapshot;\n };\n\n const metadata: ExtensionStatusMetadata = {\n get(key, value) {\n const presentation = records.get(key);\n return presentation?.value === value ? presentation : undefined;\n },\n reconcile(statuses) {\n reconcile(statuses);\n },\n dispose() {\n if (disposed) return;\n disposed = true;\n revision++;\n keyRevisions.clear();\n records.clear();\n liveKeys.clear();\n observedStatuses.clear();\n try {\n unsubscribe?.();\n } catch {\n // Optional metadata cleanup must not prevent footer disposal.\n }\n unsubscribe = undefined;\n },\n };\n\n const receive = (payload: unknown) => {\n if (disposed || !payload || typeof payload !== \"object\") return;\n const entered = revision;\n let key: string;\n let snapshot: boolean;\n const data = payload as Record<string, unknown>;\n try {\n const rawKey = data.key;\n const manager = data.sessionManager;\n snapshot = \"requestId\" in data;\n const replyId = snapshot ? data.requestId : undefined;\n if (disposed || manager !== sessionManager || typeof rawKey !== \"string\" || !rawKey) return;\n key = rawKey;\n if ((keyRevisions.get(key) ?? 0) > entered) return;\n if (snapshot && (replyId !== requestId || liveKeys.has(key))) return;\n } catch {\n return;\n }\n\n // Only an accepted envelope for this key can supersede its in-flight update.\n const owner = ++revision;\n keyRevisions.set(key, owner);\n if (!snapshot) liveKeys.add(key);\n const previous = records.get(key);\n try {\n const { presentation, withdrawal } = parseMetadata(data);\n if (!isCurrent(key, owner)) return;\n // Read after payload accessors, and copy before touching the cache: either operation can reenter.\n const reading = revision;\n const statuses = new Map(getStatuses());\n if (!isCurrent(key, owner)) return;\n if (revision !== reading) {\n // An unstable read must not retain old hidden state or erase a newer sibling record.\n records.delete(key);\n } else {\n reconcile(statuses, key);\n if (!isCurrent(key, owner) || (snapshot && liveKeys.has(key))) return;\n if (presentation && statuses.get(key) === presentation.value) {\n records.set(key, presentation);\n } else if (!snapshot || withdrawal) {\n // Invalid live data and explicit withdrawals restore the existing raw-text path.\n records.delete(key);\n }\n }\n } catch {\n if (!isCurrent(key, owner)) return;\n if (!snapshot) records.delete(key);\n }\n if (isCurrent(key, owner) && previous !== records.get(key)) {\n try {\n requestRender();\n } catch {\n // A closed UI must not turn optional metadata delivery into an event-bus error.\n }\n }\n };\n\n try {\n unsubscribe = events.on(UPDATE_CHANNEL, receive);\n } catch {\n // Metadata support must not prevent the footer from loading.\n return metadata;\n }\n try {\n events.emit(REQUEST_CHANNEL, { version: 1, sessionManager, requestId });\n } catch {\n // Keep the live subscription usable when a snapshot request fails.\n }\n return metadata;\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// Bound combined stdout/stderr while allowing large worktree listings and one absolute root path.\nconst GIT_STATUS_MAX_BUFFER = 1024 * 1024;\nconst GIT_ROOT_MAX_BUFFER = 16 * 1024;\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 maxBuffer: GIT_STATUS_MAX_BUFFER,\n signal,\n }),\n pi\n .exec(\"git\", [\"rev-parse\", \"--path-format=absolute\", \"--show-toplevel\"], {\n cwd,\n timeout: GIT_STATUS_TIMEOUT_MS,\n maxBuffer: GIT_ROOT_MAX_BUFFER,\n signal,\n })\n .catch(() => undefined),\n ]);\n if (statusResult.truncated || statusResult.code !== 0 || statusResult.killed) return undefined;\n const summary = parseGitStatusPorcelain(statusResult.stdout);\n if (rootResult && !rootResult.truncated && 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 inlineStatuses = legacyInlineStatuses(footerData.getExtensionStatuses(), runtime);\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, inlineStatuses);\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(legacyInlineStatuses(statuses, runtime));\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 legacyInlineStatuses(\n statuses: ReadonlyMap<string, string>,\n runtime: ExtensionStatusRuntime,\n): ReadonlyMap<string, string> {\n const metadata = runtime.extensionStatusMetadata;\n if (!metadata) return statuses;\n metadata.reconcile(statuses);\n return new Map([...statuses].filter(([key, value]) => !metadata.get(key, value)));\n}\n\nfunction buildSegment(\n name: SegmentName,\n ctx: ExtensionContext,\n footerData: ReadonlyFooterDataProvider,\n config: StatuslineConfig,\n runtime: RuntimeState,\n usageSummary: FooterUsageSummary,\n inlineStatuses: ReadonlyMap<string, string>,\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(inlineStatuses) : 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"],
5
+ "mappings": "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",
6
+ "names": ["getAgentDir", "visibleWidth", "rendered", "segment", "visibleWidth", "isAbsolute", "visibleWidth", "sanitizeTerminalText", "isAbsolute", "sanitizeTerminalText", "formatCount", "sanitizeTerminalText", "visibleWidth", "segment", "STATUSLINE_KEY", "EMPTY_EXTENSION_STATUS_ICON_ALIASES", "getAgentDir"]
7
7
  }
@@ -192,3 +192,9 @@ For interoperable extensions, prefer one aggregated key or a stable coexistence
192
192
  ```
193
193
 
194
194
  Put transient activity in the value, and clear the exact key that was set.
195
+
196
+ ### Optional semantic activity
197
+
198
+ The [extension-neutral metadata v1 protocol](./extension-status-protocol.md) lets a publisher describe activity without supplying glyphs or relying on private message parsing. Valid participants use the quiet presentation: idle is hidden before the five-item limit, active work uses short static markers, and retries/blocked work retain a safe reason. No new setting is required; `extensionStatusIcons` keeps the precedence above.
199
+
200
+ Missing, invalid, stale, or unsupported metadata falls back to raw text, not hidden status. Snapshot refresh is read-only and does not start the publisher's work. Native Pi footers and RPC observers still receive the raw status value.
@@ -0,0 +1,92 @@
1
+ # Extension status metadata v1
2
+
3
+ This optional protocol supplies semantic activity for compact footer rendering. Publishers keep their readable `ctx.ui.setStatus(key, value)` output. Consumers choose presentation without parsing another extension's private messages. A missing publisher or consumer does not change extension behavior.
4
+
5
+ The protocol uses Pi's public `pi.events` bus. It does not authorize work, change settings, carry model context, or provide a security boundary between installed extensions.
6
+
7
+ ## Channels and payloads
8
+
9
+ `extension-status:v1:update` carries an update or withdrawal:
10
+
11
+ ```ts
12
+ interface StatusUpdateV1 {
13
+ version: 1;
14
+ sessionManager: object;
15
+ key: string;
16
+ value: string | undefined;
17
+ activity?:
18
+ | "idle"
19
+ | "checking"
20
+ | "working"
21
+ | "pushing"
22
+ | "pulling"
23
+ | "resolving"
24
+ | "retry"
25
+ | "blocked"
26
+ | "local-change"
27
+ | "remote-change"
28
+ | "review";
29
+ reason?: string;
30
+ requestId?: object;
31
+ }
32
+ ```
33
+
34
+ `sessionManager` is the public context's object identity, used only as a local session key. Do not inspect or serialize it. `key` is the exact nonempty raw status key, not an installed-package alias. For a presentation update, `value` is the exact nonempty raw value supplied to `setStatus()`. It must match the current raw status before the metadata is used.
35
+
36
+ The `value` property must be present. An explicit `undefined` withdraws metadata for the key; it does not clear or otherwise change Pi's raw status. A withdrawal omits `activity` and `reason`. A publisher clearing raw status must also withdraw its metadata. An unannotated raw value withdraws previous metadata rather than inheriting a previous activity.
37
+
38
+ An activity is required for a presentation update. `retry` and `blocked` also require the entire reason string to match `[a-z][a-z0-9-]{0,31}`. A trailing line terminator or any other control is invalid; a JavaScript `$` regex test alone is not a full-string check. Other activities omit a reason. Reasons are safe plain labels, not provider errors, file content, credentials, or free-form diagnostic messages. A consumer must not infer a diagnosis from unrecognized data.
39
+
40
+ `extension-status:v1:request` asks for a read-only snapshot:
41
+
42
+ ```ts
43
+ interface StatusRequestV1 {
44
+ version: 1;
45
+ sessionManager: object;
46
+ requestId: object;
47
+ }
48
+ ```
49
+
50
+ Top-level payloads must be non-array objects. An opaque identity must be a non-null value with `typeof value === "object"`; arrays and class instances are valid identities, while functions and primitives are not. The requester creates a new opaque `requestId` object for its current session/render generation. A publisher responds on the update channel with its current metadata or withdrawal and the same request object. Requests never start a transfer, inspection, model call, timer, or settings read. Publishers respond only for an identity-equal session manager they currently own.
51
+
52
+ Normal live updates omit `requestId`. Snapshot replies include it. A consumer accepts replies only for its current request object and rejects replies for a key that received a live update or withdrawal after the request. A delayed snapshot must not replace a newer activity, review, or clear even if the raw text happens to match.
53
+
54
+ ## Publication and lifecycle
55
+
56
+ Publish raw text first, then metadata. Use synchronous handlers without awaiting a response. Pi's public bus starts handlers synchronously, does not await asynchronous handlers, and returns an unsubscribe function from `on()`. Consumers cannot require a particular listener order.
57
+
58
+ Register session-owned listeners at session start or first use. Release or replace them on session replacement, shutdown, reload, and failed initialization. Scope resources by `sessionManager`, not `ctx.ui`; headless runners can share a no-op UI object. Do not retain a replaced context or create background work for metadata delivery.
59
+
60
+ Publishers keep only their current presentation and isolate metadata-delivery failures from domain work. Capture request fields once and revalidate ownership after validation. Reserve first-use binding before cleanup callbacks and revalidate ownership after every release callback. Retire local ownership before optional cleanup or withdrawal callbacks; only an explicit lifecycle start can reactivate a released publisher. An older activation must not replace a newer binding or receive its cleanup function. Show/hide preferences owned by a publisher apply to both raw publication and metadata. Re-enabling does not restore stale metadata before a new valid update.
61
+
62
+ Consumers request a snapshot after subscribing and use existing render invalidation for later updates. Clear consumer state on footer disposal or session replacement. Reconcile cached records against the current raw status map so cleared or replaced values cannot reuse stale metadata. Raw status-key collisions retain Pi's existing last-writer behavior; the protocol does not establish package ownership or authentication. Pi exposes no raw-status change hook: a nonparticipant's clear-and-replace with the same value between observations cannot be detected. Participating publishers must therefore send a withdrawal or new metadata for every raw change.
63
+
64
+ ## Validation and fallback
65
+
66
+ Accept only version 1, an identity-equal current session manager, an exact raw key, supported activity, valid reason, and a matching raw value. A reply must also pass current-request and newer-live-update checks. Check fields without mutating the supplied payload.
67
+
68
+ Field access and raw-map reads can run callbacks synchronously. Capture public fields once, then revalidate the current key's accepted update and disposal state before changing the cache. Read the current raw map after field validation. A newer same-key event, withdrawal, observed raw replacement, or disposal must prevent an older handler from setting or deleting records, including through error paths. Ignored packets and unrelated keys must not cancel a valid update. An unstable raw-map read must not retain an older hidden presentation or erase another key's metadata.
69
+
70
+ For a matching current-session key, invalid or unsupported live metadata withdraws a prior compact presentation so the raw value remains visible. Invalid snapshots must not erase a newer live presentation. Ignore data that cannot identify a current-session key. Unknown versions and absent participants use the existing raw-text path, not hidden status.
71
+
72
+ Sanitize terminal input at the display boundary without changing raw keys, values, or identity comparisons. Do not use metadata to invoke commands, write settings, or change model-visible state. Consumers must remain extension-neutral; no extension-name branches, private error imports, or private-message matching are permitted.
73
+
74
+ ## Quiet presentation
75
+
76
+ Pi Statusline applies these defaults to valid participants. The feature identifier uses the existing configured icon precedence, including an empty icon override. Activities are static markers; the protocol does not supply glyphs or hide instructions.
77
+
78
+ | Activity | Compact body |
79
+ | --- | --- |
80
+ | `idle` | Hidden |
81
+ | `checking` | `…` |
82
+ | `working` | `↻` |
83
+ | `pushing` / `pulling` | `↑` / `↓` |
84
+ | `resolving` | `AI` |
85
+ | `retry` | `retry: <reason>` |
86
+ | `blocked` | `! <reason>` |
87
+ | `local-change` / `remote-change` | `⇡` / `⇣` |
88
+ | `review` | `⇕` |
89
+
90
+ Filter hidden entries before applying the footer's visible-item limit and separators. Retrying and blocked activities retain their reason and an appropriate warning role. A compact view must not erase another current activity or review merely because a sibling publisher is idle.
91
+
92
+ Other footers and RPC observers continue to receive the readable raw value. This display protocol does not change retry policy, request limits, transfer authorization, or recovery requirements.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@narumitw/pi-statusline",
3
- "version": "0.50.4",
3
+ "version": "0.51.0",
4
4
  "description": "Pi extension that replaces the footer with an information-rich statusline.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -39,7 +39,7 @@
39
39
  "devDependencies": {
40
40
  "@earendil-works/pi-coding-agent": "1.5.0",
41
41
  "@earendil-works/pi-tui": "1.5.0",
42
- "@types/node": "26.6.5",
42
+ "@types/node": "26.6.6",
43
43
  "esbuild": "0.28.2",
44
44
  "typescript": "7.0.2"
45
45
  },