oh-my-githubcopilot 1.8.1-alpha.c2814e2 → 1.8.1-alpha.ed20e27
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/AGENTS.md +5 -0
- package/README.md +5 -0
- package/bin/omp-statusline.mjs +5 -5
- package/bin/omp-statusline.mjs.map +2 -2
- package/bin/omp.mjs +70 -9
- package/bin/omp.mjs.map +4 -4
- package/dist/hooks/hud-emitter.mjs +5 -5
- package/dist/hooks/hud-emitter.mjs.map +2 -2
- package/package.json +1 -1
package/AGENTS.md
CHANGED
|
@@ -174,3 +174,8 @@ Before starting work on an issue:
|
|
|
174
174
|
3. Do not make a fourth attempt without human acknowledgement.
|
|
175
175
|
|
|
176
176
|
<!-- ai-sdlc-init:end -->
|
|
177
|
+
|
|
178
|
+
<!-- v3-ai-sdlc-init:start -->
|
|
179
|
+
## AI SDLC v3
|
|
180
|
+
This repo follows the v3 AI-SDLC layout. See `.ai/matrix.json`, `.memory/human-override/`, and `docs/architecture/adr/`. Modules at `r3dlex/skills/ai-sdlc-init/modules/`.
|
|
181
|
+
<!-- v3-ai-sdlc-init:end -->
|
package/README.md
CHANGED
|
@@ -138,3 +138,8 @@ omp is open source under the [Apache-2.0 License](LICENSE).
|
|
|
138
138
|
## Sponsors
|
|
139
139
|
|
|
140
140
|
If omp saves you time, consider [sponsoring the project](https://github.com/sponsors/r3dlex) ❤️
|
|
141
|
+
|
|
142
|
+
<!-- v3-ai-sdlc-init:start -->
|
|
143
|
+
## AI SDLC v3
|
|
144
|
+
This repo follows the v3 AI-SDLC layout. See `.ai/matrix.json`, `.memory/human-override/`, and `docs/architecture/adr/`. Modules at `r3dlex/skills/ai-sdlc-init/modules/`.
|
|
145
|
+
<!-- v3-ai-sdlc-init:end -->
|
package/bin/omp-statusline.mjs
CHANGED
|
@@ -149,17 +149,17 @@ function writeHudArtifacts(snapshot, paths = getStatuslinePaths()) {
|
|
|
149
149
|
return { line, state, paths };
|
|
150
150
|
}
|
|
151
151
|
function readStatusline(paths = getStatuslinePaths()) {
|
|
152
|
-
try {
|
|
153
|
-
const line = readFileSync(paths.displayPath, "utf-8").trim();
|
|
154
|
-
if (line) return line;
|
|
155
|
-
} catch {
|
|
156
|
-
}
|
|
157
152
|
try {
|
|
158
153
|
const parsed = JSON.parse(readFileSync(paths.statusJsonPath, "utf-8"));
|
|
159
154
|
const state = deserializeHudState(parsed);
|
|
160
155
|
if (state) return renderPlain(state);
|
|
161
156
|
} catch {
|
|
162
157
|
}
|
|
158
|
+
try {
|
|
159
|
+
const line = readFileSync(paths.displayPath, "utf-8").trim();
|
|
160
|
+
if (line) return line;
|
|
161
|
+
} catch {
|
|
162
|
+
}
|
|
163
163
|
try {
|
|
164
164
|
const line = readFileSync(paths.legacyLinePath, "utf-8").trim();
|
|
165
165
|
if (line) return line;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/hud/statusline.mts", "../src/hud/renderer.mts"],
|
|
4
|
-
"sourcesContent": ["/**\n * HUD statusline helpers and standalone entrypoint.\n *\n * Keeps HUD artifact generation in one place so hooks and shell wrappers\n * can share the same rendering and fallback behavior.\n */\n\nimport { mkdirSync, readFileSync, renameSync, writeFileSync } from \"fs\";\nimport { homedir } from \"os\";\nimport { dirname, join } from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { renderPlain, type HudState, type HudStatus } from \"./renderer.mts\";\n\nconst DEFAULT_VERSION = \"0.0.0\";\nconst DEFAULT_STATUSLINE = \"OMP | hud: no active session\";\nconst DEFAULT_TOKEN_BUDGET = 200_000;\nconst DEFAULT_PREMIUM_REQUESTS_TOTAL = 1500;\n\nexport interface StatuslinePaths {\n legacyLinePath: string;\n hudDir: string;\n statusJsonPath: string;\n displayPath: string;\n tmuxSegmentPath: string;\n}\n\nexport interface HudSnapshot {\n version?: string;\n session_id?: string;\n started_at?: number;\n updated_at?: number;\n model?: string;\n tokens_estimated?: number;\n token_budget?: number;\n context_pct?: number;\n tools_used?: string[];\n skills_used?: string[];\n agents_used?: string[];\n active_mode?: string | null;\n last_output?: string;\n task_progress?: number;\n status?: HudStatus;\n premium_requests?: number;\n premium_requests_total?: number;\n warning_active?: boolean;\n}\n\ninterface SerializedHudState extends Omit<HudState, \"toolsUsed\" | \"skillsUsed\"> {\n toolsUsed: string[];\n skillsUsed: string[];\n}\n\nexport function getStatuslinePaths(home = process.env[\"HOME\"] || homedir()): StatuslinePaths {\n const ompDir = join(home, \".omp\");\n const hudDir = join(ompDir, \"hud\");\n return {\n legacyLinePath: join(ompDir, \"hud.line\"),\n hudDir,\n statusJsonPath: join(hudDir, \"status.json\"),\n displayPath: join(hudDir, \"display.txt\"),\n tmuxSegmentPath: join(hudDir, \"tmux-segment.sh\"),\n };\n}\n\nfunction ensureParent(filePath: string): void {\n mkdirSync(dirname(filePath), { recursive: true });\n}\n\nfunction writeAtomic(filePath: string, content: string, mode?: number): void {\n ensureParent(filePath);\n const tempPath = `${filePath}.tmp`;\n writeFileSync(tempPath, content, mode === undefined ? \"utf-8\" : { encoding: \"utf-8\", mode });\n renameSync(tempPath, filePath);\n}\n\nfunction normalizeStringArray(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n return value.filter((item): item is string => typeof item === \"string\");\n}\n\nfunction serializeHudState(state: HudState): SerializedHudState {\n return {\n ...state,\n toolsUsed: Array.from(state.toolsUsed),\n skillsUsed: Array.from(state.skillsUsed),\n };\n}\n\nfunction deserializeHudState(raw: unknown): HudState | null {\n if (!raw || typeof raw !== \"object\") return null;\n const value = raw as Record<string, unknown>;\n const toolsUsed = new Set(normalizeStringArray(value.toolsUsed));\n const skillsUsed = new Set(normalizeStringArray(value.skillsUsed));\n const agentsActive = normalizeStringArray(value.agentsActive);\n const status = typeof value.status === \"string\" ? (value.status as HudStatus) : \"idle\";\n\n return {\n sessionId: typeof value.sessionId === \"string\" ? value.sessionId : \"default\",\n activeMode: typeof value.activeMode === \"string\" ? value.activeMode : null,\n activeModel: typeof value.activeModel === \"string\" ? value.activeModel : \"sonnet\",\n contextPct: typeof value.contextPct === \"number\" ? value.contextPct : 0,\n tokensUsed: typeof value.tokensUsed === \"number\" ? value.tokensUsed : 0,\n tokensTotal: typeof value.tokensTotal === \"number\" ? value.tokensTotal : DEFAULT_TOKEN_BUDGET,\n agentsActive,\n lastAgent: typeof value.lastAgent === \"string\" ? value.lastAgent : agentsActive.at(-1) ?? \"-\",\n lastOutput: typeof value.lastOutput === \"string\" ? value.lastOutput : \"\",\n taskProgress: typeof value.taskProgress === \"number\" ? value.taskProgress : 0,\n startedAt: typeof value.startedAt === \"number\" ? value.startedAt : Date.now(),\n updatedAt: typeof value.updatedAt === \"number\" ? value.updatedAt : Date.now(),\n version: typeof value.version === \"string\" ? value.version : DEFAULT_VERSION,\n status,\n sessionDurationMs: typeof value.sessionDurationMs === \"number\" ? value.sessionDurationMs : 0,\n cumulativeAgentsUsed: typeof value.cumulativeAgentsUsed === \"number\" ? value.cumulativeAgentsUsed : agentsActive.length,\n toolsUsed,\n skillsUsed,\n toolsTotal: typeof value.toolsTotal === \"number\" ? value.toolsTotal : 13,\n skillsTotal: typeof value.skillsTotal === \"number\" ? value.skillsTotal : 25,\n agentsTotal: typeof value.agentsTotal === \"number\" ? value.agentsTotal : 23,\n premiumRequests: typeof value.premiumRequests === \"number\" ? value.premiumRequests : 0,\n premiumRequestsTotal: typeof value.premiumRequestsTotal === \"number\" ? value.premiumRequestsTotal : DEFAULT_PREMIUM_REQUESTS_TOTAL,\n warningActive: typeof value.warningActive === \"boolean\" ? value.warningActive : false,\n };\n}\n\nexport function buildHudState(snapshot: HudSnapshot, now = Date.now()): HudState {\n const startedAt = snapshot.started_at ?? now;\n const updatedAt = snapshot.updated_at ?? now;\n const toolsUsed = new Set(normalizeStringArray(snapshot.tools_used));\n const skillsUsed = new Set(normalizeStringArray(snapshot.skills_used));\n const agentsActive = normalizeStringArray(snapshot.agents_used);\n\n return {\n sessionId: snapshot.session_id ?? \"default\",\n activeMode: snapshot.active_mode ?? null,\n activeModel: snapshot.model ?? \"sonnet\",\n contextPct: snapshot.context_pct ?? 0,\n tokensUsed: snapshot.tokens_estimated ?? 0,\n tokensTotal: snapshot.token_budget ?? DEFAULT_TOKEN_BUDGET,\n agentsActive,\n lastAgent: agentsActive.at(-1) ?? \"-\",\n lastOutput: snapshot.last_output ?? \"\",\n taskProgress: snapshot.task_progress ?? 0,\n startedAt,\n updatedAt,\n version: snapshot.version ?? DEFAULT_VERSION,\n status: snapshot.status ?? \"idle\",\n sessionDurationMs: Math.max(0, updatedAt - startedAt),\n cumulativeAgentsUsed: agentsActive.length,\n toolsUsed,\n skillsUsed,\n toolsTotal: 13,\n skillsTotal: 25,\n agentsTotal: 23,\n premiumRequests: snapshot.premium_requests ?? 0,\n premiumRequestsTotal: snapshot.premium_requests_total ?? DEFAULT_PREMIUM_REQUESTS_TOTAL,\n warningActive: snapshot.warning_active ?? false,\n };\n}\n\nexport function writeHudArtifacts(snapshot: HudSnapshot, paths = getStatuslinePaths()): { line: string; state: HudState; paths: StatuslinePaths } {\n const state = buildHudState(snapshot);\n const line = renderPlain(state);\n const serializedState = `${JSON.stringify(serializeHudState(state), null, 2)}\\n`;\n\n writeAtomic(paths.statusJsonPath, serializedState);\n writeAtomic(paths.displayPath, `${line}\\n`);\n writeAtomic(paths.tmuxSegmentPath, `${line}\\n`, 0o755);\n writeAtomic(paths.legacyLinePath, `${line}\\n`);\n\n return { line, state, paths };\n}\n\nexport function readStatusline(paths = getStatuslinePaths()): string {\n try {\n const line = readFileSync(paths.displayPath, \"utf-8\").trim();\n if (line) return line;\n } catch {\n // Fall through to other sources.\n }\n\n try {\n const parsed = JSON.parse(readFileSync(paths.statusJsonPath, \"utf-8\"));\n const state = deserializeHudState(parsed);\n if (state) return renderPlain(state);\n } catch {\n // Fall through to legacy file.\n }\n\n try {\n const line = readFileSync(paths.legacyLinePath, \"utf-8\").trim();\n if (line) return line;\n } catch {\n // No HUD artifacts yet.\n }\n\n return DEFAULT_STATUSLINE;\n}\n\nif (process.argv[1] === fileURLToPath(import.meta.url)) {\n console.log(readStatusline());\n}\n", "/**\n * HUD Renderer\n * Formats HudState into ANSI or plain text status lines.\n */\n\n\nexport interface HudState {\n sessionId: string;\n activeMode: string | null;\n activeModel: string;\n contextPct: number;\n tokensUsed: number;\n tokensTotal: number;\n agentsActive: string[];\n lastAgent: string;\n lastOutput: string;\n taskProgress: number;\n startedAt: number;\n updatedAt: number;\n version: string;\n status: HudStatus;\n sessionDurationMs: number;\n cumulativeAgentsUsed: number;\n toolsUsed: Set<string>;\n skillsUsed: Set<string>;\n toolsTotal: number;\n skillsTotal: number;\n agentsTotal: number;\n premiumRequests: number;\n premiumRequestsTotal: number;\n warningActive: boolean;\n}\n\nexport type HudStatus = \"idle\" | \"running\" | \"waiting\" | \"complete\" | \"error\" | \"eco\";\n\nconst STATUS_ICONS: Record<HudStatus, string> = {\n idle: \"\u25CB\",\n running: \"\u25CF\",\n waiting: \"\u25F7\",\n complete: \"\u2713\",\n error: \"\u2717\",\n eco: \"\u26A1\",\n};\n\nfunction formatAge(startedAt: number): string {\n const elapsed = Date.now() - startedAt;\n const mins = Math.floor(elapsed / 60000);\n if (mins < 60) return `${mins}m`;\n const hours = Math.floor(mins / 60);\n const remainingMins = mins % 60;\n return `${hours}h${remainingMins}m`;\n}\n\nfunction formatTokens(tokens: number): string {\n if (tokens >= 1_000_000) return `${(tokens / 1_000_000).toFixed(1)}M`;\n if (tokens >= 1_000) return `${(tokens / 1_000).toFixed(1)}k`;\n return `${tokens}`;\n}\n\nfunction ctxColor(pct: number): string {\n if (pct < 60) return \"\\x1b[32m\"; // green\n if (pct < 85) return \"\\x1b[33m\"; // yellow\n return \"\\x1b[31m\"; // red\n}\n\nfunction reset(): string {\n return \"\\x1b[0m\";\n}\n\n/**\n * Render HUD line with ANSI color codes.\n * Format: [OMP v1.0.0] mode | model | ctx:N% | tok:~Nk/Nk | Nm | tools:N/N | skills:N/N | agents:N/N | N% status\n */\nexport function renderAnsi(state: HudState): string {\n const age = formatAge(state.startedAt);\n const tokens = formatTokens(state.tokensUsed);\n const ctx = state.contextPct;\n const mode = state.activeMode || \"-\";\n const model = state.activeModel || \"sonnet\";\n const icon = STATUS_ICONS[state.status] || \"\u25CF\";\n\n const ctxClr = ctxColor(ctx);\n const ctxStr = `${ctxClr}ctx:${ctx}%${reset()}`;\n const tokenStr = `tok:~${tokens}/${state.tokensTotal}`;\n const modeStr = mode === \"-\" ? \"-\" : `\\x1b[36m${mode}${reset()}`; // cyan for active modes\n\n const reqWarning = state.warningActive ? \" !!\" : \"\";\n const reqStr = `req:${state.premiumRequests ?? 0}/${state.premiumRequestsTotal ?? 1500}${reqWarning}`;\n\n return `[OMP v${state.version}] ${modeStr} | ${model} | ${ctxStr} | ${tokenStr} | ${reqStr} | ${age} | tools:${state.toolsUsed?.size || 0}/${state.toolsTotal ?? 13} | skills:${state.skillsUsed?.size || 0}/${state.skillsTotal ?? 25} | agents:${state.cumulativeAgentsUsed}/${state.agentsTotal ?? 23} | ${icon} ${state.status}`;\n}\n\n/**\n * Render HUD line as plain text (no ANSI codes).\n * Format: [OMP v1.0.0] mode | model | ctx:N% | tok:~Nk/Nk | Nm | tools:N/N | skills:N/N | agents:N/N | N% status\n */\nexport function renderPlain(state: HudState): string {\n const age = formatAge(state.startedAt);\n const tokens = formatTokens(state.tokensUsed);\n const ctx = state.contextPct;\n const mode = state.activeMode || \"-\";\n const model = state.activeModel || \"sonnet\";\n\n const reqWarningPlain = state.warningActive ? \" !!\" : \"\";\n const reqStrPlain = `req:${state.premiumRequests ?? 0}/${state.premiumRequestsTotal ?? 1500}${reqWarningPlain}`;\n\n return `[OMP v${state.version}] ${mode} | ${model} | ctx:${ctx}% | tok:~${tokens}/${state.tokensTotal} | ${reqStrPlain} | ${age} | tools:${state.toolsUsed?.size || 0}/${state.toolsTotal ?? 13} | skills:${state.skillsUsed?.size || 0}/${state.skillsTotal ?? 25} | agents:${state.cumulativeAgentsUsed}/${state.agentsTotal ?? 23} | ${state.status}`;\n}\n"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["/**\n * HUD statusline helpers and standalone entrypoint.\n *\n * Keeps HUD artifact generation in one place so hooks and shell wrappers\n * can share the same rendering and fallback behavior.\n */\n\nimport { mkdirSync, readFileSync, renameSync, writeFileSync } from \"fs\";\nimport { homedir } from \"os\";\nimport { dirname, join } from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { renderPlain, type HudState, type HudStatus } from \"./renderer.mts\";\n\nconst DEFAULT_VERSION = \"0.0.0\";\nconst DEFAULT_STATUSLINE = \"OMP | hud: no active session\";\nconst DEFAULT_TOKEN_BUDGET = 200_000;\nconst DEFAULT_PREMIUM_REQUESTS_TOTAL = 1500;\n\nexport interface StatuslinePaths {\n legacyLinePath: string;\n hudDir: string;\n statusJsonPath: string;\n displayPath: string;\n tmuxSegmentPath: string;\n}\n\nexport interface HudSnapshot {\n version?: string;\n session_id?: string;\n started_at?: number;\n updated_at?: number;\n model?: string;\n tokens_estimated?: number;\n token_budget?: number;\n context_pct?: number;\n tools_used?: string[];\n skills_used?: string[];\n agents_used?: string[];\n active_mode?: string | null;\n last_output?: string;\n task_progress?: number;\n status?: HudStatus;\n premium_requests?: number;\n premium_requests_total?: number;\n warning_active?: boolean;\n}\n\ninterface SerializedHudState extends Omit<HudState, \"toolsUsed\" | \"skillsUsed\"> {\n toolsUsed: string[];\n skillsUsed: string[];\n}\n\nexport function getStatuslinePaths(home = process.env[\"HOME\"] || homedir()): StatuslinePaths {\n const ompDir = join(home, \".omp\");\n const hudDir = join(ompDir, \"hud\");\n return {\n legacyLinePath: join(ompDir, \"hud.line\"),\n hudDir,\n statusJsonPath: join(hudDir, \"status.json\"),\n displayPath: join(hudDir, \"display.txt\"),\n tmuxSegmentPath: join(hudDir, \"tmux-segment.sh\"),\n };\n}\n\nfunction ensureParent(filePath: string): void {\n mkdirSync(dirname(filePath), { recursive: true });\n}\n\nfunction writeAtomic(filePath: string, content: string, mode?: number): void {\n ensureParent(filePath);\n const tempPath = `${filePath}.tmp`;\n writeFileSync(tempPath, content, mode === undefined ? \"utf-8\" : { encoding: \"utf-8\", mode });\n renameSync(tempPath, filePath);\n}\n\nfunction normalizeStringArray(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n return value.filter((item): item is string => typeof item === \"string\");\n}\n\nfunction serializeHudState(state: HudState): SerializedHudState {\n return {\n ...state,\n toolsUsed: Array.from(state.toolsUsed),\n skillsUsed: Array.from(state.skillsUsed),\n };\n}\n\nfunction deserializeHudState(raw: unknown): HudState | null {\n if (!raw || typeof raw !== \"object\") return null;\n const value = raw as Record<string, unknown>;\n const toolsUsed = new Set(normalizeStringArray(value.toolsUsed));\n const skillsUsed = new Set(normalizeStringArray(value.skillsUsed));\n const agentsActive = normalizeStringArray(value.agentsActive);\n const status = typeof value.status === \"string\" ? (value.status as HudStatus) : \"idle\";\n\n return {\n sessionId: typeof value.sessionId === \"string\" ? value.sessionId : \"default\",\n activeMode: typeof value.activeMode === \"string\" ? value.activeMode : null,\n activeModel: typeof value.activeModel === \"string\" ? value.activeModel : \"sonnet\",\n contextPct: typeof value.contextPct === \"number\" ? value.contextPct : 0,\n tokensUsed: typeof value.tokensUsed === \"number\" ? value.tokensUsed : 0,\n tokensTotal: typeof value.tokensTotal === \"number\" ? value.tokensTotal : DEFAULT_TOKEN_BUDGET,\n agentsActive,\n lastAgent: typeof value.lastAgent === \"string\" ? value.lastAgent : agentsActive.at(-1) ?? \"-\",\n lastOutput: typeof value.lastOutput === \"string\" ? value.lastOutput : \"\",\n taskProgress: typeof value.taskProgress === \"number\" ? value.taskProgress : 0,\n startedAt: typeof value.startedAt === \"number\" ? value.startedAt : Date.now(),\n updatedAt: typeof value.updatedAt === \"number\" ? value.updatedAt : Date.now(),\n version: typeof value.version === \"string\" ? value.version : DEFAULT_VERSION,\n status,\n sessionDurationMs: typeof value.sessionDurationMs === \"number\" ? value.sessionDurationMs : 0,\n cumulativeAgentsUsed: typeof value.cumulativeAgentsUsed === \"number\" ? value.cumulativeAgentsUsed : agentsActive.length,\n toolsUsed,\n skillsUsed,\n toolsTotal: typeof value.toolsTotal === \"number\" ? value.toolsTotal : 13,\n skillsTotal: typeof value.skillsTotal === \"number\" ? value.skillsTotal : 25,\n agentsTotal: typeof value.agentsTotal === \"number\" ? value.agentsTotal : 23,\n premiumRequests: typeof value.premiumRequests === \"number\" ? value.premiumRequests : 0,\n premiumRequestsTotal: typeof value.premiumRequestsTotal === \"number\" ? value.premiumRequestsTotal : DEFAULT_PREMIUM_REQUESTS_TOTAL,\n warningActive: typeof value.warningActive === \"boolean\" ? value.warningActive : false,\n };\n}\n\nexport function buildHudState(snapshot: HudSnapshot, now = Date.now()): HudState {\n const startedAt = snapshot.started_at ?? now;\n const updatedAt = snapshot.updated_at ?? now;\n const toolsUsed = new Set(normalizeStringArray(snapshot.tools_used));\n const skillsUsed = new Set(normalizeStringArray(snapshot.skills_used));\n const agentsActive = normalizeStringArray(snapshot.agents_used);\n\n return {\n sessionId: snapshot.session_id ?? \"default\",\n activeMode: snapshot.active_mode ?? null,\n activeModel: snapshot.model ?? \"sonnet\",\n contextPct: snapshot.context_pct ?? 0,\n tokensUsed: snapshot.tokens_estimated ?? 0,\n tokensTotal: snapshot.token_budget ?? DEFAULT_TOKEN_BUDGET,\n agentsActive,\n lastAgent: agentsActive.at(-1) ?? \"-\",\n lastOutput: snapshot.last_output ?? \"\",\n taskProgress: snapshot.task_progress ?? 0,\n startedAt,\n updatedAt,\n version: snapshot.version ?? DEFAULT_VERSION,\n status: snapshot.status ?? \"idle\",\n sessionDurationMs: Math.max(0, updatedAt - startedAt),\n cumulativeAgentsUsed: agentsActive.length,\n toolsUsed,\n skillsUsed,\n toolsTotal: 13,\n skillsTotal: 25,\n agentsTotal: 23,\n premiumRequests: snapshot.premium_requests ?? 0,\n premiumRequestsTotal: snapshot.premium_requests_total ?? DEFAULT_PREMIUM_REQUESTS_TOTAL,\n warningActive: snapshot.warning_active ?? false,\n };\n}\n\nexport function writeHudArtifacts(snapshot: HudSnapshot, paths = getStatuslinePaths()): { line: string; state: HudState; paths: StatuslinePaths } {\n const state = buildHudState(snapshot);\n const line = renderPlain(state);\n const serializedState = `${JSON.stringify(serializeHudState(state), null, 2)}\\n`;\n\n writeAtomic(paths.statusJsonPath, serializedState);\n writeAtomic(paths.displayPath, `${line}\\n`);\n writeAtomic(paths.tmuxSegmentPath, `${line}\\n`, 0o755);\n writeAtomic(paths.legacyLinePath, `${line}\\n`);\n\n return { line, state, paths };\n}\n\nexport function readStatusline(paths = getStatuslinePaths()): string {\n // Try live render from status.json \u2014 formatAge runs at call time, not hook-fire time\n try {\n const parsed = JSON.parse(readFileSync(paths.statusJsonPath, \"utf-8\"));\n const state = deserializeHudState(parsed);\n if (state) return renderPlain(state);\n } catch {\n // Fall through to cached display string.\n }\n\n // Fallback: pre-rendered cached string (written by hud-emitter; used by tmux consumers)\n try {\n const line = readFileSync(paths.displayPath, \"utf-8\").trim();\n if (line) return line;\n } catch {\n // Fall through to legacy file.\n }\n\n try {\n const line = readFileSync(paths.legacyLinePath, \"utf-8\").trim();\n if (line) return line;\n } catch {}\n\n return DEFAULT_STATUSLINE;\n}\n\nif (process.argv[1] === fileURLToPath(import.meta.url)) {\n console.log(readStatusline());\n}\n", "/**\n * HUD Renderer\n * Formats HudState into ANSI or plain text status lines.\n */\n\n\nexport interface HudState {\n sessionId: string;\n activeMode: string | null;\n activeModel: string;\n contextPct: number;\n tokensUsed: number;\n tokensTotal: number;\n agentsActive: string[];\n lastAgent: string;\n lastOutput: string;\n taskProgress: number;\n startedAt: number;\n updatedAt: number;\n version: string;\n status: HudStatus;\n sessionDurationMs: number;\n cumulativeAgentsUsed: number;\n toolsUsed: Set<string>;\n skillsUsed: Set<string>;\n toolsTotal: number;\n skillsTotal: number;\n agentsTotal: number;\n premiumRequests: number;\n premiumRequestsTotal: number;\n warningActive: boolean;\n}\n\nexport type HudStatus = \"idle\" | \"running\" | \"waiting\" | \"complete\" | \"error\" | \"eco\";\n\nconst STATUS_ICONS: Record<HudStatus, string> = {\n idle: \"\u25CB\",\n running: \"\u25CF\",\n waiting: \"\u25F7\",\n complete: \"\u2713\",\n error: \"\u2717\",\n eco: \"\u26A1\",\n};\n\nfunction formatAge(startedAt: number): string {\n const elapsed = Date.now() - startedAt;\n const mins = Math.floor(elapsed / 60000);\n if (mins < 60) return `${mins}m`;\n const hours = Math.floor(mins / 60);\n const remainingMins = mins % 60;\n return `${hours}h${remainingMins}m`;\n}\n\nfunction formatTokens(tokens: number): string {\n if (tokens >= 1_000_000) return `${(tokens / 1_000_000).toFixed(1)}M`;\n if (tokens >= 1_000) return `${(tokens / 1_000).toFixed(1)}k`;\n return `${tokens}`;\n}\n\nfunction ctxColor(pct: number): string {\n if (pct < 60) return \"\\x1b[32m\"; // green\n if (pct < 85) return \"\\x1b[33m\"; // yellow\n return \"\\x1b[31m\"; // red\n}\n\nfunction reset(): string {\n return \"\\x1b[0m\";\n}\n\n/**\n * Render HUD line with ANSI color codes.\n * Format: [OMP v1.0.0] mode | model | ctx:N% | tok:~Nk/Nk | Nm | tools:N/N | skills:N/N | agents:N/N | N% status\n */\nexport function renderAnsi(state: HudState): string {\n const age = formatAge(state.startedAt);\n const tokens = formatTokens(state.tokensUsed);\n const ctx = state.contextPct;\n const mode = state.activeMode || \"-\";\n const model = state.activeModel || \"sonnet\";\n const icon = STATUS_ICONS[state.status] || \"\u25CF\";\n\n const ctxClr = ctxColor(ctx);\n const ctxStr = `${ctxClr}ctx:${ctx}%${reset()}`;\n const tokenStr = `tok:~${tokens}/${state.tokensTotal}`;\n const modeStr = mode === \"-\" ? \"-\" : `\\x1b[36m${mode}${reset()}`; // cyan for active modes\n\n const reqWarning = state.warningActive ? \" !!\" : \"\";\n const reqStr = `req:${state.premiumRequests ?? 0}/${state.premiumRequestsTotal ?? 1500}${reqWarning}`;\n\n return `[OMP v${state.version}] ${modeStr} | ${model} | ${ctxStr} | ${tokenStr} | ${reqStr} | ${age} | tools:${state.toolsUsed?.size || 0}/${state.toolsTotal ?? 13} | skills:${state.skillsUsed?.size || 0}/${state.skillsTotal ?? 25} | agents:${state.cumulativeAgentsUsed}/${state.agentsTotal ?? 23} | ${icon} ${state.status}`;\n}\n\n/**\n * Render HUD line as plain text (no ANSI codes).\n * Format: [OMP v1.0.0] mode | model | ctx:N% | tok:~Nk/Nk | Nm | tools:N/N | skills:N/N | agents:N/N | N% status\n */\nexport function renderPlain(state: HudState): string {\n const age = formatAge(state.startedAt);\n const tokens = formatTokens(state.tokensUsed);\n const ctx = state.contextPct;\n const mode = state.activeMode || \"-\";\n const model = state.activeModel || \"sonnet\";\n\n const reqWarningPlain = state.warningActive ? \" !!\" : \"\";\n const reqStrPlain = `req:${state.premiumRequests ?? 0}/${state.premiumRequestsTotal ?? 1500}${reqWarningPlain}`;\n\n return `[OMP v${state.version}] ${mode} | ${model} | ctx:${ctx}% | tok:~${tokens}/${state.tokensTotal} | ${reqStrPlain} | ${age} | tools:${state.toolsUsed?.size || 0}/${state.toolsTotal ?? 13} | skills:${state.skillsUsed?.size || 0}/${state.skillsTotal ?? 25} | agents:${state.cumulativeAgentsUsed}/${state.agentsTotal ?? 23} | ${state.status}`;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/bin/omp.mjs
CHANGED
|
@@ -189,17 +189,17 @@ function writeHudArtifacts(snapshot, paths = getStatuslinePaths()) {
|
|
|
189
189
|
return { line, state, paths };
|
|
190
190
|
}
|
|
191
191
|
function readStatusline(paths = getStatuslinePaths()) {
|
|
192
|
-
try {
|
|
193
|
-
const line = readFileSync(paths.displayPath, "utf-8").trim();
|
|
194
|
-
if (line) return line;
|
|
195
|
-
} catch {
|
|
196
|
-
}
|
|
197
192
|
try {
|
|
198
193
|
const parsed = JSON.parse(readFileSync(paths.statusJsonPath, "utf-8"));
|
|
199
194
|
const state = deserializeHudState(parsed);
|
|
200
195
|
if (state) return renderPlain(state);
|
|
201
196
|
} catch {
|
|
202
197
|
}
|
|
198
|
+
try {
|
|
199
|
+
const line = readFileSync(paths.displayPath, "utf-8").trim();
|
|
200
|
+
if (line) return line;
|
|
201
|
+
} catch {
|
|
202
|
+
}
|
|
203
203
|
try {
|
|
204
204
|
const line = readFileSync(paths.legacyLinePath, "utf-8").trim();
|
|
205
205
|
if (line) return line;
|
|
@@ -283,6 +283,62 @@ var init_watch = __esm({
|
|
|
283
283
|
}
|
|
284
284
|
});
|
|
285
285
|
|
|
286
|
+
// src/cli/install.mts
|
|
287
|
+
var install_exports = {};
|
|
288
|
+
__export(install_exports, {
|
|
289
|
+
runInstall: () => runInstall
|
|
290
|
+
});
|
|
291
|
+
import { mkdir as mkdir2, readFile as readFile2, rename, writeFile as writeFile2 } from "fs/promises";
|
|
292
|
+
import { homedir as homedir4 } from "os";
|
|
293
|
+
import { dirname as dirname3, join as join4 } from "path";
|
|
294
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
295
|
+
async function runInstall(settingsPath = join4(homedir4(), ".copilot", "settings.json")) {
|
|
296
|
+
const pkgRoot = join4(dirname3(fileURLToPath2(import.meta.url)), "..");
|
|
297
|
+
const statusLineCommand = join4(pkgRoot, "bin", "omp-statusline.sh");
|
|
298
|
+
const marketplacePath = pkgRoot;
|
|
299
|
+
let existing = {};
|
|
300
|
+
try {
|
|
301
|
+
const raw = await readFile2(settingsPath, "utf-8");
|
|
302
|
+
const parsed = JSON.parse(raw);
|
|
303
|
+
if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
304
|
+
existing = parsed;
|
|
305
|
+
}
|
|
306
|
+
} catch {
|
|
307
|
+
}
|
|
308
|
+
const existingPlugins = typeof existing.enabledPlugins === "object" && existing.enabledPlugins !== null && !Array.isArray(existing.enabledPlugins) ? existing.enabledPlugins : {};
|
|
309
|
+
const existingMarketplaces = typeof existing.extraKnownMarketplaces === "object" && existing.extraKnownMarketplaces !== null && !Array.isArray(existing.extraKnownMarketplaces) ? existing.extraKnownMarketplaces : {};
|
|
310
|
+
const merged = {
|
|
311
|
+
...existing,
|
|
312
|
+
enabledPlugins: {
|
|
313
|
+
...existingPlugins,
|
|
314
|
+
"oh-my-githubcopilot@oh-my-githubcopilot": true
|
|
315
|
+
},
|
|
316
|
+
experimental: true,
|
|
317
|
+
statusLine: { type: "command", command: statusLineCommand },
|
|
318
|
+
extraKnownMarketplaces: {
|
|
319
|
+
...existingMarketplaces,
|
|
320
|
+
"oh-my-githubcopilot": {
|
|
321
|
+
source: { source: "directory", path: marketplacePath }
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
};
|
|
325
|
+
const tmp = `${settingsPath}.tmp`;
|
|
326
|
+
await mkdir2(dirname3(settingsPath), { recursive: true });
|
|
327
|
+
await writeFile2(tmp, JSON.stringify(merged, null, 2) + "\n", "utf-8");
|
|
328
|
+
await rename(tmp, settingsPath);
|
|
329
|
+
console.log(`omp install: wrote ${settingsPath}`);
|
|
330
|
+
console.log(` statusLine.command: ${statusLineCommand}`);
|
|
331
|
+
console.log(` marketplace path: ${marketplacePath}`);
|
|
332
|
+
console.log(` plugin: oh-my-githubcopilot@oh-my-githubcopilot`);
|
|
333
|
+
console.log(`
|
|
334
|
+
Restart Copilot CLI to activate OMP.`);
|
|
335
|
+
}
|
|
336
|
+
var init_install = __esm({
|
|
337
|
+
"src/cli/install.mts"() {
|
|
338
|
+
"use strict";
|
|
339
|
+
}
|
|
340
|
+
});
|
|
341
|
+
|
|
286
342
|
// src/hooks/keyword-detector.mts
|
|
287
343
|
var keyword_detector_exports = {};
|
|
288
344
|
__export(keyword_detector_exports, {
|
|
@@ -698,6 +754,11 @@ async function main() {
|
|
|
698
754
|
case "hook":
|
|
699
755
|
await runHook(positionals.slice(1));
|
|
700
756
|
break;
|
|
757
|
+
case "install": {
|
|
758
|
+
const { runInstall: runInstall2 } = await Promise.resolve().then(() => (init_install(), install_exports));
|
|
759
|
+
await runInstall2();
|
|
760
|
+
break;
|
|
761
|
+
}
|
|
701
762
|
default:
|
|
702
763
|
console.error(`Unknown subcommand: ${resolvedSubcommand}`);
|
|
703
764
|
printUsage(true);
|
|
@@ -706,14 +767,14 @@ async function main() {
|
|
|
706
767
|
}
|
|
707
768
|
function printUsage(stderr = false) {
|
|
708
769
|
const output = stderr ? console.error : console.log;
|
|
709
|
-
output("Usage: omp [hud|version|psm|bench|hook] [--watch]");
|
|
770
|
+
output("Usage: omp [hud|install|version|psm|bench|hook] [--watch]");
|
|
710
771
|
}
|
|
711
772
|
async function printHud() {
|
|
712
773
|
try {
|
|
713
774
|
const { readFileSync: readFileSync3 } = await import("fs");
|
|
714
|
-
const { join:
|
|
715
|
-
const { homedir:
|
|
716
|
-
const hudPath =
|
|
775
|
+
const { join: join5 } = await import("path");
|
|
776
|
+
const { homedir: homedir5 } = await import("os");
|
|
777
|
+
const hudPath = join5(homedir5(), ".omp", "hud.line");
|
|
717
778
|
const line = readFileSync3(hudPath, "utf-8").trim();
|
|
718
779
|
console.log(line);
|
|
719
780
|
} catch {
|
package/bin/omp.mjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/hud/renderer.mts", "../src/hud/statusline.mts", "../src/hud/watch.mts", "../src/hooks/keyword-detector.mts", "../src/index.mts", "../src/cli/update.mts"],
|
|
4
|
-
"sourcesContent": ["/**\n * HUD Renderer\n * Formats HudState into ANSI or plain text status lines.\n */\n\n\nexport interface HudState {\n sessionId: string;\n activeMode: string | null;\n activeModel: string;\n contextPct: number;\n tokensUsed: number;\n tokensTotal: number;\n agentsActive: string[];\n lastAgent: string;\n lastOutput: string;\n taskProgress: number;\n startedAt: number;\n updatedAt: number;\n version: string;\n status: HudStatus;\n sessionDurationMs: number;\n cumulativeAgentsUsed: number;\n toolsUsed: Set<string>;\n skillsUsed: Set<string>;\n toolsTotal: number;\n skillsTotal: number;\n agentsTotal: number;\n premiumRequests: number;\n premiumRequestsTotal: number;\n warningActive: boolean;\n}\n\nexport type HudStatus = \"idle\" | \"running\" | \"waiting\" | \"complete\" | \"error\" | \"eco\";\n\nconst STATUS_ICONS: Record<HudStatus, string> = {\n idle: \"\u25CB\",\n running: \"\u25CF\",\n waiting: \"\u25F7\",\n complete: \"\u2713\",\n error: \"\u2717\",\n eco: \"\u26A1\",\n};\n\nfunction formatAge(startedAt: number): string {\n const elapsed = Date.now() - startedAt;\n const mins = Math.floor(elapsed / 60000);\n if (mins < 60) return `${mins}m`;\n const hours = Math.floor(mins / 60);\n const remainingMins = mins % 60;\n return `${hours}h${remainingMins}m`;\n}\n\nfunction formatTokens(tokens: number): string {\n if (tokens >= 1_000_000) return `${(tokens / 1_000_000).toFixed(1)}M`;\n if (tokens >= 1_000) return `${(tokens / 1_000).toFixed(1)}k`;\n return `${tokens}`;\n}\n\nfunction ctxColor(pct: number): string {\n if (pct < 60) return \"\\x1b[32m\"; // green\n if (pct < 85) return \"\\x1b[33m\"; // yellow\n return \"\\x1b[31m\"; // red\n}\n\nfunction reset(): string {\n return \"\\x1b[0m\";\n}\n\n/**\n * Render HUD line with ANSI color codes.\n * Format: [OMP v1.0.0] mode | model | ctx:N% | tok:~Nk/Nk | Nm | tools:N/N | skills:N/N | agents:N/N | N% status\n */\nexport function renderAnsi(state: HudState): string {\n const age = formatAge(state.startedAt);\n const tokens = formatTokens(state.tokensUsed);\n const ctx = state.contextPct;\n const mode = state.activeMode || \"-\";\n const model = state.activeModel || \"sonnet\";\n const icon = STATUS_ICONS[state.status] || \"\u25CF\";\n\n const ctxClr = ctxColor(ctx);\n const ctxStr = `${ctxClr}ctx:${ctx}%${reset()}`;\n const tokenStr = `tok:~${tokens}/${state.tokensTotal}`;\n const modeStr = mode === \"-\" ? \"-\" : `\\x1b[36m${mode}${reset()}`; // cyan for active modes\n\n const reqWarning = state.warningActive ? \" !!\" : \"\";\n const reqStr = `req:${state.premiumRequests ?? 0}/${state.premiumRequestsTotal ?? 1500}${reqWarning}`;\n\n return `[OMP v${state.version}] ${modeStr} | ${model} | ${ctxStr} | ${tokenStr} | ${reqStr} | ${age} | tools:${state.toolsUsed?.size || 0}/${state.toolsTotal ?? 13} | skills:${state.skillsUsed?.size || 0}/${state.skillsTotal ?? 25} | agents:${state.cumulativeAgentsUsed}/${state.agentsTotal ?? 23} | ${icon} ${state.status}`;\n}\n\n/**\n * Render HUD line as plain text (no ANSI codes).\n * Format: [OMP v1.0.0] mode | model | ctx:N% | tok:~Nk/Nk | Nm | tools:N/N | skills:N/N | agents:N/N | N% status\n */\nexport function renderPlain(state: HudState): string {\n const age = formatAge(state.startedAt);\n const tokens = formatTokens(state.tokensUsed);\n const ctx = state.contextPct;\n const mode = state.activeMode || \"-\";\n const model = state.activeModel || \"sonnet\";\n\n const reqWarningPlain = state.warningActive ? \" !!\" : \"\";\n const reqStrPlain = `req:${state.premiumRequests ?? 0}/${state.premiumRequestsTotal ?? 1500}${reqWarningPlain}`;\n\n return `[OMP v${state.version}] ${mode} | ${model} | ctx:${ctx}% | tok:~${tokens}/${state.tokensTotal} | ${reqStrPlain} | ${age} | tools:${state.toolsUsed?.size || 0}/${state.toolsTotal ?? 13} | skills:${state.skillsUsed?.size || 0}/${state.skillsTotal ?? 25} | agents:${state.cumulativeAgentsUsed}/${state.agentsTotal ?? 23} | ${state.status}`;\n}\n", "/**\n * HUD statusline helpers and standalone entrypoint.\n *\n * Keeps HUD artifact generation in one place so hooks and shell wrappers\n * can share the same rendering and fallback behavior.\n */\n\nimport { mkdirSync, readFileSync, renameSync, writeFileSync } from \"fs\";\nimport { homedir } from \"os\";\nimport { dirname, join } from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { renderPlain, type HudState, type HudStatus } from \"./renderer.mts\";\n\nconst DEFAULT_VERSION = \"0.0.0\";\nconst DEFAULT_STATUSLINE = \"OMP | hud: no active session\";\nconst DEFAULT_TOKEN_BUDGET = 200_000;\nconst DEFAULT_PREMIUM_REQUESTS_TOTAL = 1500;\n\nexport interface StatuslinePaths {\n legacyLinePath: string;\n hudDir: string;\n statusJsonPath: string;\n displayPath: string;\n tmuxSegmentPath: string;\n}\n\nexport interface HudSnapshot {\n version?: string;\n session_id?: string;\n started_at?: number;\n updated_at?: number;\n model?: string;\n tokens_estimated?: number;\n token_budget?: number;\n context_pct?: number;\n tools_used?: string[];\n skills_used?: string[];\n agents_used?: string[];\n active_mode?: string | null;\n last_output?: string;\n task_progress?: number;\n status?: HudStatus;\n premium_requests?: number;\n premium_requests_total?: number;\n warning_active?: boolean;\n}\n\ninterface SerializedHudState extends Omit<HudState, \"toolsUsed\" | \"skillsUsed\"> {\n toolsUsed: string[];\n skillsUsed: string[];\n}\n\nexport function getStatuslinePaths(home = process.env[\"HOME\"] || homedir()): StatuslinePaths {\n const ompDir = join(home, \".omp\");\n const hudDir = join(ompDir, \"hud\");\n return {\n legacyLinePath: join(ompDir, \"hud.line\"),\n hudDir,\n statusJsonPath: join(hudDir, \"status.json\"),\n displayPath: join(hudDir, \"display.txt\"),\n tmuxSegmentPath: join(hudDir, \"tmux-segment.sh\"),\n };\n}\n\nfunction ensureParent(filePath: string): void {\n mkdirSync(dirname(filePath), { recursive: true });\n}\n\nfunction writeAtomic(filePath: string, content: string, mode?: number): void {\n ensureParent(filePath);\n const tempPath = `${filePath}.tmp`;\n writeFileSync(tempPath, content, mode === undefined ? \"utf-8\" : { encoding: \"utf-8\", mode });\n renameSync(tempPath, filePath);\n}\n\nfunction normalizeStringArray(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n return value.filter((item): item is string => typeof item === \"string\");\n}\n\nfunction serializeHudState(state: HudState): SerializedHudState {\n return {\n ...state,\n toolsUsed: Array.from(state.toolsUsed),\n skillsUsed: Array.from(state.skillsUsed),\n };\n}\n\nfunction deserializeHudState(raw: unknown): HudState | null {\n if (!raw || typeof raw !== \"object\") return null;\n const value = raw as Record<string, unknown>;\n const toolsUsed = new Set(normalizeStringArray(value.toolsUsed));\n const skillsUsed = new Set(normalizeStringArray(value.skillsUsed));\n const agentsActive = normalizeStringArray(value.agentsActive);\n const status = typeof value.status === \"string\" ? (value.status as HudStatus) : \"idle\";\n\n return {\n sessionId: typeof value.sessionId === \"string\" ? value.sessionId : \"default\",\n activeMode: typeof value.activeMode === \"string\" ? value.activeMode : null,\n activeModel: typeof value.activeModel === \"string\" ? value.activeModel : \"sonnet\",\n contextPct: typeof value.contextPct === \"number\" ? value.contextPct : 0,\n tokensUsed: typeof value.tokensUsed === \"number\" ? value.tokensUsed : 0,\n tokensTotal: typeof value.tokensTotal === \"number\" ? value.tokensTotal : DEFAULT_TOKEN_BUDGET,\n agentsActive,\n lastAgent: typeof value.lastAgent === \"string\" ? value.lastAgent : agentsActive.at(-1) ?? \"-\",\n lastOutput: typeof value.lastOutput === \"string\" ? value.lastOutput : \"\",\n taskProgress: typeof value.taskProgress === \"number\" ? value.taskProgress : 0,\n startedAt: typeof value.startedAt === \"number\" ? value.startedAt : Date.now(),\n updatedAt: typeof value.updatedAt === \"number\" ? value.updatedAt : Date.now(),\n version: typeof value.version === \"string\" ? value.version : DEFAULT_VERSION,\n status,\n sessionDurationMs: typeof value.sessionDurationMs === \"number\" ? value.sessionDurationMs : 0,\n cumulativeAgentsUsed: typeof value.cumulativeAgentsUsed === \"number\" ? value.cumulativeAgentsUsed : agentsActive.length,\n toolsUsed,\n skillsUsed,\n toolsTotal: typeof value.toolsTotal === \"number\" ? value.toolsTotal : 13,\n skillsTotal: typeof value.skillsTotal === \"number\" ? value.skillsTotal : 25,\n agentsTotal: typeof value.agentsTotal === \"number\" ? value.agentsTotal : 23,\n premiumRequests: typeof value.premiumRequests === \"number\" ? value.premiumRequests : 0,\n premiumRequestsTotal: typeof value.premiumRequestsTotal === \"number\" ? value.premiumRequestsTotal : DEFAULT_PREMIUM_REQUESTS_TOTAL,\n warningActive: typeof value.warningActive === \"boolean\" ? value.warningActive : false,\n };\n}\n\nexport function buildHudState(snapshot: HudSnapshot, now = Date.now()): HudState {\n const startedAt = snapshot.started_at ?? now;\n const updatedAt = snapshot.updated_at ?? now;\n const toolsUsed = new Set(normalizeStringArray(snapshot.tools_used));\n const skillsUsed = new Set(normalizeStringArray(snapshot.skills_used));\n const agentsActive = normalizeStringArray(snapshot.agents_used);\n\n return {\n sessionId: snapshot.session_id ?? \"default\",\n activeMode: snapshot.active_mode ?? null,\n activeModel: snapshot.model ?? \"sonnet\",\n contextPct: snapshot.context_pct ?? 0,\n tokensUsed: snapshot.tokens_estimated ?? 0,\n tokensTotal: snapshot.token_budget ?? DEFAULT_TOKEN_BUDGET,\n agentsActive,\n lastAgent: agentsActive.at(-1) ?? \"-\",\n lastOutput: snapshot.last_output ?? \"\",\n taskProgress: snapshot.task_progress ?? 0,\n startedAt,\n updatedAt,\n version: snapshot.version ?? DEFAULT_VERSION,\n status: snapshot.status ?? \"idle\",\n sessionDurationMs: Math.max(0, updatedAt - startedAt),\n cumulativeAgentsUsed: agentsActive.length,\n toolsUsed,\n skillsUsed,\n toolsTotal: 13,\n skillsTotal: 25,\n agentsTotal: 23,\n premiumRequests: snapshot.premium_requests ?? 0,\n premiumRequestsTotal: snapshot.premium_requests_total ?? DEFAULT_PREMIUM_REQUESTS_TOTAL,\n warningActive: snapshot.warning_active ?? false,\n };\n}\n\nexport function writeHudArtifacts(snapshot: HudSnapshot, paths = getStatuslinePaths()): { line: string; state: HudState; paths: StatuslinePaths } {\n const state = buildHudState(snapshot);\n const line = renderPlain(state);\n const serializedState = `${JSON.stringify(serializeHudState(state), null, 2)}\\n`;\n\n writeAtomic(paths.statusJsonPath, serializedState);\n writeAtomic(paths.displayPath, `${line}\\n`);\n writeAtomic(paths.tmuxSegmentPath, `${line}\\n`, 0o755);\n writeAtomic(paths.legacyLinePath, `${line}\\n`);\n\n return { line, state, paths };\n}\n\nexport function readStatusline(paths = getStatuslinePaths()): string {\n try {\n const line = readFileSync(paths.displayPath, \"utf-8\").trim();\n if (line) return line;\n } catch {\n // Fall through to other sources.\n }\n\n try {\n const parsed = JSON.parse(readFileSync(paths.statusJsonPath, \"utf-8\"));\n const state = deserializeHudState(parsed);\n if (state) return renderPlain(state);\n } catch {\n // Fall through to legacy file.\n }\n\n try {\n const line = readFileSync(paths.legacyLinePath, \"utf-8\").trim();\n if (line) return line;\n } catch {\n // No HUD artifacts yet.\n }\n\n return DEFAULT_STATUSLINE;\n}\n\nif (process.argv[1] === fileURLToPath(import.meta.url)) {\n console.log(readStatusline());\n}\n", "/**\n * HUD watch daemon \u2014 polls session state and rewrites HUD artifacts on each tick.\n *\n * Usage:\n * omp hud --watch Poll every 2s (default)\n * OMP_HUD_INTERVAL=5000 omp hud --watch Override interval (ms)\n *\n * Each cycle:\n * readState() \u2192 buildHudState() \u2192 renderAnsi() \u2192 writeHudArtifacts()\n *\n * Elapsed time is always recomputed from startedAt so the display never goes stale\n * between hook firings.\n */\n\nimport { readFileSync } from \"fs\";\nimport { homedir } from \"os\";\nimport { join } from \"path\";\nimport {\n buildHudState,\n writeHudArtifacts,\n getStatuslinePaths,\n type HudSnapshot,\n} from \"./statusline.mts\";\nimport { renderAnsi } from \"./renderer.mts\";\n\nconst DEFAULT_INTERVAL_MS = 2_000;\nconst STATE_PATH = join(homedir(), \".omp\", \"state\", \"session.json\");\n\nfunction readSnapshot(): HudSnapshot | null {\n try {\n const raw = readFileSync(STATE_PATH, \"utf-8\");\n const parsed = JSON.parse(raw) as HudSnapshot;\n return parsed;\n } catch {\n return null;\n }\n}\n\nfunction tick(paths = getStatuslinePaths()): void {\n const snapshot = readSnapshot();\n if (!snapshot) return;\n\n // Pass current time so buildHudState recomputes sessionDurationMs from live clock.\n const now = Date.now();\n const state = buildHudState(snapshot, now);\n\n // Write all artifacts (display.txt, tmux-segment.sh, status.json, hud.line).\n writeHudArtifacts(snapshot, paths);\n\n // Render ANSI to stdout so a terminal running `omp hud --watch` shows live output.\n process.stdout.write(\"\\x1b[2J\\x1b[H\" + renderAnsi(state) + \"\\x1b[K\\n\\x1b[J\");\n}\n\n/**\n * Start the HUD watch daemon.\n *\n * Runs until SIGINT or SIGTERM. The interval is configurable via the\n * OMP_HUD_INTERVAL env var (milliseconds).\n */\nexport function runHudWatch(): void {\n const intervalMs = Math.max(\n 500,\n parseInt(process.env[\"OMP_HUD_INTERVAL\"] ?? \"\", 10) || DEFAULT_INTERVAL_MS,\n );\n\n const paths = getStatuslinePaths();\n\n // Hide cursor while watch loop is active.\n process.stdout.write(\"\\x1b[?25l\");\n\n // Initial render immediately.\n try {\n tick(paths);\n } catch {\n // Swallow first-tick errors \u2014 state may not exist yet.\n }\n\n const timer = setInterval(() => {\n try {\n tick(paths);\n } catch {\n // Swallow per-tick errors to keep the daemon alive.\n }\n }, intervalMs);\n\n const stop = () => {\n clearInterval(timer);\n // Restore cursor and clear screen before exit.\n process.stdout.write(\"\\x1b[?25h\\x1b[2J\\x1b[H\");\n process.exit(0);\n };\n\n process.on(\"SIGINT\", stop);\n process.on(\"SIGTERM\", stop);\n}\n", "/**\n * keyword-detector hook\n * Trigger: pre-cycle (UserPromptSubmitted equivalent)\n * Priority: 100 (runs first)\n *\n * Scans incoming prompts for magic keywords and rewrites them\n * to skill invocation slash commands.\n */\n\nexport interface KeywordMatch {\n keyword: string;\n skillId: string;\n position: number;\n}\n\nconst KEYWORD_MAP: Record<string, string> = {\n \"autopilot:\": \"autopilot\",\n \"/autopilot\": \"autopilot\",\n \"/omp:autopilot\": \"autopilot\",\n \"ralph:\": \"ralph\",\n \"/ralph\": \"ralph\",\n \"/omp:ralph\": \"ralph\",\n \"ulw:\": \"ultrawork\",\n \"ultrawork:\": \"ultrawork\",\n \"/ulw\": \"ultrawork\",\n \"/ultrawork\": \"ultrawork\",\n \"/omp:ulw\": \"ultrawork\",\n \"/omp:ultrawork\": \"ultrawork\",\n \"team:\": \"team\",\n \"/team\": \"team\",\n \"/omp:team\": \"team\",\n \"eco:\": \"ecomode\",\n \"ecomode:\": \"ecomode\",\n \"/eco\": \"ecomode\",\n \"/ecomode\": \"ecomode\",\n \"/omp:eco\": \"ecomode\",\n \"/omp:ecomode\": \"ecomode\",\n \"swarm:\": \"swarm\",\n \"/swarm\": \"swarm\",\n \"/omp:swarm\": \"swarm\",\n \"pipeline:\": \"pipeline\",\n \"/pipeline\": \"pipeline\",\n \"/omp:pipeline\": \"pipeline\",\n \"deep interview:\": \"deep-interview\",\n \"/deep-interview\": \"deep-interview\",\n \"/omp:deep-interview\": \"deep-interview\",\n \"plan:\": \"omp-plan\",\n \"/plan\": \"omp-plan\",\n \"/omp-plan\": \"omp-plan\",\n \"/omp:plan\": \"omp-plan\",\n \"setup:\": \"omp-setup\",\n \"/setup\": \"omp-setup\",\n \"/omp-setup\": \"omp-setup\",\n \"/omp:setup\": \"omp-setup\",\n \"mcp:\": \"mcp-setup\",\n \"mcp-setup:\": \"mcp-setup\",\n \"/mcp\": \"mcp-setup\",\n \"/mcp-setup\": \"mcp-setup\",\n \"/omp:mcp-setup\": \"mcp-setup\",\n \"/hud\": \"hud\",\n \"hud:\": \"hud\",\n \"/omp:hud\": \"hud\",\n \"/wiki\": \"wiki\",\n \"wiki:\": \"wiki\",\n \"/omp:wiki\": \"wiki\",\n \"/learner\": \"learner\",\n \"learner:\": \"learner\",\n \"/omp:learner\": \"learner\",\n \"/note\": \"note\",\n \"note:\": \"note\",\n \"/omp:note\": \"note\",\n \"/trace\": \"trace\",\n \"trace:\": \"trace\",\n \"/omp:trace\": \"trace\",\n \"/release\": \"release\",\n \"release:\": \"release\",\n \"/omp:release\": \"release\",\n \"/configure-notifications\": \"configure-notifications\",\n \"configure-notifications:\": \"configure-notifications\",\n \"/omp:configure-notifications\": \"configure-notifications\",\n \"/psm\": \"psm\",\n \"psm:\": \"psm\",\n \"/omp:psm\": \"psm\",\n \"/swe-bench\": \"swe-bench\",\n \"swe-bench:\": \"swe-bench\",\n \"/omp:swe-bench\": \"swe-bench\",\n \"graphify:\": \"graphify\",\n \"graph build\": \"graphify\",\n \"build graph\": \"graphify\",\n \"graphwiki:\": \"graphwiki\",\n \"graph:\": \"graph-provider\",\n \"spending:\": \"spending\",\n \"/graphify\": \"graphify\",\n \"/omp:graphify\": \"graphify\",\n \"/graphwiki\": \"graphwiki\",\n \"/omp:graphwiki\": \"graphwiki\",\n \"/graph-provider\": \"graph-provider\",\n \"/omp:graph-provider\": \"graph-provider\",\n \"/spending\": \"spending\",\n \"/omp:spending\": \"spending\",\n \"--consensus\": \"omp-plan\",\n \"/omp:omp-doctor\": \"omp-doctor\",\n \"/omp:ralplan\": \"ralplan\",\n \"/omp:research\": \"research\",\n \"doctor:\": \"doctor\",\n \"/doctor\": \"doctor\",\n \"/omp:doctor\": \"doctor\",\n \"interview:\": \"interview\",\n \"/interview\": \"interview\",\n \"/omp:interview\": \"interview\",\n \"notifications:\": \"notifications\",\n \"/notifications\": \"notifications\",\n \"/omp:notifications\": \"notifications\",\n \"session:\": \"session\",\n \"/session\": \"session\",\n \"/omp:session\": \"session\",\n};\n\nconst KEYWORD_ENTRIES = Object.entries(KEYWORD_MAP).sort(([a], [b]) => b.length - a.length);\nconst CANONICAL_COMMAND_MAP: Record<string, string> = {\n \"omp-plan\": \"/omp:plan\",\n \"omp-setup\": \"/setup\",\n \"mcp-setup\": \"/mcp\",\n};\n\nexport interface HookInput {\n hook_type: \"UserPromptSubmitted\";\n prompt: string;\n session_id?: string;\n}\n\nexport interface HookOutput {\n decision?: \"allow\";\n modifiedPrompt?: string;\n additionalContext?: string;\n status: \"ok\" | \"skip\" | \"error\";\n latencyMs: number;\n mutations: Array<{ type: \"set_mode\"; mode: string } | { type: \"log\"; level: \"info\"; message: string }>;\n log: string[];\n}\n\nfunction detectKeyword(prompt: string): KeywordMatch | null {\n const trimmed = prompt.trimStart();\n\n // Prefer the longest literal alias match first so /mcp-setup wins over /mcp.\n for (const [keyword, skillId] of KEYWORD_ENTRIES) {\n if (trimmed.startsWith(keyword)) {\n return {\n keyword,\n skillId,\n position: 0,\n };\n }\n }\n\n // Case-insensitive check for slash forms\n const slashPattern = /^\\/((?:omp:)?[a-zA-Z][a-zA-Z0-9-]*)\\b/;\n const slashMatch = trimmed.match(slashPattern);\n if (slashMatch) {\n const cmd = slashMatch[1].toLowerCase();\n const skillId = KEYWORD_MAP[`/${cmd}`] ?? KEYWORD_MAP[`${cmd}:`];\n if (skillId) {\n return {\n keyword: slashMatch[0],\n skillId,\n position: 0,\n };\n }\n }\n\n // Compatibility: support long namespace aliases like\n // \"oh-my-githubcopilot:ralph\" (or \"/oh-my-githubcopilot:ralph\")\n const longNamespacePattern = /^\\/?oh-my-githubcopilot:([a-zA-Z][a-zA-Z0-9-]*)\\b/i;\n const longNamespaceMatch = trimmed.match(longNamespacePattern);\n if (longNamespaceMatch) {\n const cmd = longNamespaceMatch[1].toLowerCase();\n const skillId =\n KEYWORD_MAP[`/omp:${cmd}`] ??\n KEYWORD_MAP[`/${cmd}`] ??\n KEYWORD_MAP[`${cmd}:`];\n if (skillId) {\n return {\n keyword: longNamespaceMatch[0],\n skillId,\n position: 0,\n };\n }\n }\n\n return null;\n}\n\nfunction getCanonicalCommand(skillId: string): string {\n return CANONICAL_COMMAND_MAP[skillId] ?? `/omp:${skillId}`;\n}\n\nexport function processHook(input: HookInput): HookOutput {\n const start = Date.now();\n const log: string[] = [];\n\n try {\n if (input.hook_type !== \"UserPromptSubmitted\") {\n return {\n status: \"skip\",\n latencyMs: Date.now() - start,\n mutations: [],\n log: [\"Not a UserPromptSubmitted hook\"],\n };\n }\n\n const match = detectKeyword(input.prompt);\n if (!match) {\n return {\n status: \"ok\",\n latencyMs: Date.now() - start,\n mutations: [],\n log: [],\n };\n }\n\n // Rewrite prompt to invoke the skill\n const taskPart = input.prompt.slice(match.position + match.keyword.length).trim();\n const rewritten = `${getCanonicalCommand(match.skillId)}${taskPart ? ` ${taskPart}` : \"\"}`;\n\n log.push(`Keyword detected: \"${match.keyword}\" \u2192 skill: ${match.skillId}`);\n log.push(`Rewritten: \"${rewritten}\"`);\n\n return {\n status: \"ok\",\n latencyMs: Date.now() - start,\n modifiedPrompt: rewritten,\n mutations: [\n { type: \"set_mode\", mode: match.skillId },\n { type: \"log\", level: \"info\", message: `Skill activated: ${match.skillId}` },\n ],\n log,\n };\n } catch (err) {\n return {\n status: \"error\",\n latencyMs: Date.now() - start,\n mutations: [],\n log: [`Error: ${err}`],\n };\n }\n}\n\n// Main entry point \u2014 only runs when executed directly (not imported).\n// The omp CLI imports processHook directly to avoid double-dispatch when bundled.\nif (process.argv[1]?.endsWith(\"keyword-detector.mjs\") || process.argv[1]?.endsWith(\"keyword-detector.mts\")) {\n const input: HookInput = JSON.parse(await readStdin());\n const output = processHook(input);\n console.log(JSON.stringify(output));\n}\n\nasync function readStdin(): Promise<string> {\n const chunks: string[] = [];\n for await (const chunk of process.stdin) {\n chunks.push(chunk);\n }\n return chunks.join(\"\");\n}\n", "/**\n * omp CLI companion tool\n * Entry point: bin/omp.mjs\n *\n * Subcommands:\n * omp hud \u2014 print current HUD line\n * omp version \u2014 show OMP version\n * omp psm \u2014 shorthand for PSM commands\n * omp bench \u2014 run SWE-bench suite\n * omp hook \u2014 execute a packaged hook from stdin\n */\n\nimport { parseArgs } from \"util\";\nimport { createRequire } from \"module\";\nimport { maybeCheckAndPromptUpdate } from \"./cli/update.mts\";\nconst _require = createRequire(import.meta.url);\nconst { version: PKG_VERSION, name: PKG_NAME } = _require(\"../package.json\") as { version: string; name: string };\n\nconst { positionals, values: flags } = parseArgs({\n args: process.argv.slice(2),\n options: {\n help: { type: \"boolean\", default: false },\n version: { type: \"boolean\", default: false },\n watch: { type: \"boolean\", default: false },\n },\n allowPositionals: true,\n});\n\nconst subcommand = positionals[0] || \"hud\";\nconst resolvedSubcommand = flags.version && !positionals[0] ? \"version\" : subcommand;\n\nasync function main() {\n if (flags.help) {\n printUsage();\n return;\n }\n\n await maybeCheckAndPromptUpdate({\n cwd: process.cwd(),\n packageName: PKG_NAME,\n currentVersion: PKG_VERSION,\n subcommand: resolvedSubcommand,\n flags: {\n help: flags.help,\n version: flags.version,\n },\n });\n\n switch (resolvedSubcommand) {\n case \"hud\":\n if (flags.watch) {\n const { runHudWatch } = await import(\"./hud/watch.mts\");\n runHudWatch();\n } else {\n await printHud();\n }\n break;\n case \"version\":\n console.log(`${PKG_NAME} v${PKG_VERSION}`);\n break;\n case \"psm\":\n await runPsm(positionals.slice(1));\n break;\n case \"bench\":\n await runBench(positionals.slice(1));\n break;\n case \"hook\":\n await runHook(positionals.slice(1));\n break;\n default:\n console.error(`Unknown subcommand: ${resolvedSubcommand}`);\n printUsage(true);\n process.exit(1);\n }\n}\n\nfunction printUsage(stderr = false) {\n const output = stderr ? console.error : console.log;\n output(\"Usage: omp [hud|version|psm|bench|hook] [--watch]\");\n}\n\nasync function printHud() {\n try {\n const { readFileSync } = await import(\"fs\");\n const { join } = await import(\"path\");\n const { homedir } = await import(\"os\");\n const hudPath = join(homedir(), \".omp\", \"hud.line\");\n const line = readFileSync(hudPath, \"utf-8\").trim();\n console.log(line);\n } catch {\n console.log(`OMP v${PKG_VERSION} | hud: no active session`);\n }\n}\n\nasync function runPsm(_args: string[]) {\n // Delegate to PSM skill \u2014 just print guidance\n console.log(\"PSM commands:\");\n console.log(\" /omp:psm create <name> Create isolated worktree session\");\n console.log(\" /omp:psm list List active sessions\");\n console.log(\" /omp:psm switch <name> Switch to session\");\n console.log(\" /omp:psm destroy <name> Destroy session\");\n}\n\nasync function runHook(args: string[]) {\n const hookId = args[0];\n if (hookId !== \"keyword-detector\") {\n console.error(\"Usage: omp hook keyword-detector\");\n process.exit(1);\n }\n\n const { processHook } = await import(\"./hooks/keyword-detector.mts\");\n const inputText = await readStdin();\n const input = JSON.parse(inputText || \"{}\");\n const output = processHook(input);\n console.log(JSON.stringify(output));\n}\n\nasync function readStdin(): Promise<string> {\n const chunks: string[] = [];\n for await (const chunk of process.stdin) {\n chunks.push(String(chunk));\n }\n return chunks.join(\"\");\n}\n\nasync function runBench(_args: string[]) {\n console.log(\"SWE-bench requires Node.js subprocess with Python evaluation harness.\");\n console.log(\"Usage: /omp:swe-bench --suite lite --compare baseline\");\n}\n\nmain().catch((err) => {\n console.error(err);\n process.exit(1);\n});\n", "/**\n * Launch-time update checks for the omp CLI companion.\n * Non-fatal, TTY-only, and throttled via ~/.omp/state/update-check.json.\n */\n\nimport { spawnSync } from \"child_process\";\nimport { mkdir, readFile, writeFile } from \"fs/promises\";\nimport { homedir } from \"os\";\nimport { dirname, join } from \"path\";\nimport { createInterface } from \"node:readline/promises\";\n\nexport interface UpdateState {\n last_checked_at: string;\n last_seen_latest?: string;\n}\n\nexport interface UpdateCheckFlags {\n help?: boolean;\n version?: boolean;\n}\n\nexport interface UpdateCheckContext {\n cwd: string;\n packageName: string;\n currentVersion: string;\n subcommand: string;\n flags?: UpdateCheckFlags;\n}\n\ninterface LatestPackageInfo {\n version?: string;\n}\n\ninterface ParsedSemver {\n major: number;\n minor: number;\n patch: number;\n prerelease: string | null;\n}\n\ninterface UpdateDependencies {\n nowMs: () => number;\n readUpdateState: (statePath: string) => Promise<UpdateState | null>;\n writeUpdateState: (statePath: string, state: UpdateState) => Promise<void>;\n fetchLatestVersion: (packageName: string) => Promise<string | null>;\n askYesNo: (question: string) => Promise<boolean>;\n runGlobalUpdate: (packageName: string, cwd: string) => { ok: boolean; stderr: string };\n}\n\nconst CHECK_INTERVAL_MS = 12 * 60 * 60 * 1000; // 12h\nconst PROMPTABLE_SUBCOMMANDS = new Set([\"hud\", \"psm\", \"bench\"]);\nconst DISABLED_AUTO_UPDATE_VALUES = new Set([\"0\", \"false\", \"no\", \"off\"]);\nconst ENABLED_DISABLE_FLAG_VALUES = new Set([\"1\", \"true\", \"yes\", \"on\"]);\n\nfunction parseSemver(version: string): ParsedSemver | null {\n const match = version.trim().match(/^v?(\\d+)\\.(\\d+)\\.(\\d+)(?:-([0-9A-Za-z.-]+))?$/);\n if (!match) return null;\n return {\n major: Number(match[1]),\n minor: Number(match[2]),\n patch: Number(match[3]),\n prerelease: match[4] ?? null,\n };\n}\n\nexport function isNewerVersion(current: string, latest: string): boolean {\n const currentVersion = parseSemver(current);\n const latestVersion = parseSemver(latest);\n if (!currentVersion || !latestVersion) return false;\n\n if (latestVersion.major !== currentVersion.major) return latestVersion.major > currentVersion.major;\n if (latestVersion.minor !== currentVersion.minor) return latestVersion.minor > currentVersion.minor;\n if (latestVersion.patch !== currentVersion.patch) return latestVersion.patch > currentVersion.patch;\n\n // Stable release of the same numeric version is newer than a prerelease.\n if (currentVersion.prerelease && !latestVersion.prerelease) return true;\n return false;\n}\n\nexport function shouldCheckForUpdates(\n nowMs: number,\n state: UpdateState | null,\n intervalMs = CHECK_INTERVAL_MS\n): boolean {\n if (!state?.last_checked_at) return true;\n const lastCheckedAt = Date.parse(state.last_checked_at);\n if (!Number.isFinite(lastCheckedAt)) return true;\n return nowMs - lastCheckedAt >= intervalMs;\n}\n\nexport function isAutoUpdateDisabled(env: NodeJS.ProcessEnv = process.env): boolean {\n const autoUpdate = env[\"OMP_AUTO_UPDATE\"]?.trim().toLowerCase();\n if (autoUpdate && DISABLED_AUTO_UPDATE_VALUES.has(autoUpdate)) return true;\n\n const disableCheck = env[\"OMP_DISABLE_UPDATE_CHECK\"]?.trim().toLowerCase();\n if (disableCheck && ENABLED_DISABLE_FLAG_VALUES.has(disableCheck)) return true;\n\n return false;\n}\n\nexport function shouldSkipUpdatePrompt(subcommand: string, flags: UpdateCheckFlags = {}): boolean {\n if (flags.help || flags.version) return true;\n return !PROMPTABLE_SUBCOMMANDS.has(subcommand);\n}\n\nfunction updateStatePath(homeDir: string): string {\n return join(homeDir, \".omp\", \"state\", \"update-check.json\");\n}\n\nasync function readCachedUpdateState(statePath: string): Promise<UpdateState | null> {\n try {\n const raw = await readFile(statePath, \"utf-8\");\n return JSON.parse(raw) as UpdateState;\n } catch {\n return null;\n }\n}\n\nasync function writeCachedUpdateState(statePath: string, state: UpdateState): Promise<void> {\n await mkdir(dirname(statePath), { recursive: true });\n await writeFile(statePath, JSON.stringify(state, null, 2), \"utf-8\");\n}\n\nasync function fetchLatestVersionFromNpm(packageName: string, timeoutMs = 3500): Promise<string | null> {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), timeoutMs);\n try {\n const url = `https://registry.npmjs.org/${encodeURIComponent(packageName)}/latest`;\n const response = await fetch(url, { signal: controller.signal });\n if (!response.ok) return null;\n const payload = (await response.json()) as LatestPackageInfo;\n return typeof payload.version === \"string\" ? payload.version : null;\n } catch {\n return null;\n } finally {\n clearTimeout(timeout);\n }\n}\n\nfunction runNpmGlobalUpdate(packageName: string, cwd: string): { ok: boolean; stderr: string } {\n const result = spawnSync(\"npm\", [\"install\", \"-g\", `${packageName}@latest`], {\n encoding: \"utf-8\",\n stdio: [\"ignore\", \"ignore\", \"pipe\"],\n timeout: 120000,\n windowsHide: true,\n cwd,\n });\n\n if (result.error) return { ok: false, stderr: result.error.message };\n if (result.status !== 0) {\n return { ok: false, stderr: (result.stderr || \"\").trim() || `npm exited ${result.status}` };\n }\n return { ok: true, stderr: \"\" };\n}\n\nasync function askYesNo(question: string): Promise<boolean> {\n if (!process.stdin.isTTY || !process.stdout.isTTY) return false;\n const readline = createInterface({ input: process.stdin, output: process.stdout });\n try {\n const answer = (await readline.question(question)).trim().toLowerCase();\n return answer === \"\" || answer === \"y\" || answer === \"yes\";\n } finally {\n readline.close();\n }\n}\n\nconst defaultDependencies: UpdateDependencies = {\n nowMs: () => Date.now(),\n readUpdateState: readCachedUpdateState,\n writeUpdateState: writeCachedUpdateState,\n fetchLatestVersion: fetchLatestVersionFromNpm,\n askYesNo,\n runGlobalUpdate: runNpmGlobalUpdate,\n};\n\nexport async function maybeCheckAndPromptUpdate(\n context: UpdateCheckContext,\n dependencies: Partial<UpdateDependencies> = {}\n): Promise<void> {\n const updateDependencies: UpdateDependencies = {\n ...defaultDependencies,\n ...dependencies,\n };\n\n try {\n if (isAutoUpdateDisabled()) return;\n if (!process.stdin.isTTY || !process.stdout.isTTY) return;\n if (shouldSkipUpdatePrompt(context.subcommand, context.flags)) return;\n\n const statePath = updateStatePath(process.env[\"HOME\"] || homedir());\n const now = updateDependencies.nowMs();\n const state = await updateDependencies.readUpdateState(statePath);\n\n if (!shouldCheckForUpdates(now, state)) return;\n\n const latestVersion = await updateDependencies.fetchLatestVersion(context.packageName);\n await updateDependencies.writeUpdateState(statePath, {\n last_checked_at: new Date(now).toISOString(),\n last_seen_latest: latestVersion || state?.last_seen_latest,\n });\n\n if (!latestVersion || !isNewerVersion(context.currentVersion, latestVersion)) return;\n\n const approved = await updateDependencies.askYesNo(\n `[omp] Update available: v${context.currentVersion} \u2192 v${latestVersion}. Update now? [Y/n] `\n );\n if (!approved) return;\n\n console.log(`[omp] Running: npm install -g ${context.packageName}@latest`);\n const result = updateDependencies.runGlobalUpdate(context.packageName, context.cwd);\n\n if (result.ok) {\n console.log(`[omp] Updated to v${latestVersion}. Restart this shell to load the new CLI.`);\n } else {\n console.log(`[omp] Update failed. Run manually: npm install -g ${context.packageName}@latest`);\n }\n } catch {\n // Update checks should never block normal CLI flows.\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["homedir", "dirname", "join", "readFileSync", "homedir", "join", "subcommand", "flags", "runHudWatch", "readFileSync", "join", "homedir", "processHook", "readStdin"]
|
|
3
|
+
"sources": ["../src/hud/renderer.mts", "../src/hud/statusline.mts", "../src/hud/watch.mts", "../src/cli/install.mts", "../src/hooks/keyword-detector.mts", "../src/index.mts", "../src/cli/update.mts"],
|
|
4
|
+
"sourcesContent": ["/**\n * HUD Renderer\n * Formats HudState into ANSI or plain text status lines.\n */\n\n\nexport interface HudState {\n sessionId: string;\n activeMode: string | null;\n activeModel: string;\n contextPct: number;\n tokensUsed: number;\n tokensTotal: number;\n agentsActive: string[];\n lastAgent: string;\n lastOutput: string;\n taskProgress: number;\n startedAt: number;\n updatedAt: number;\n version: string;\n status: HudStatus;\n sessionDurationMs: number;\n cumulativeAgentsUsed: number;\n toolsUsed: Set<string>;\n skillsUsed: Set<string>;\n toolsTotal: number;\n skillsTotal: number;\n agentsTotal: number;\n premiumRequests: number;\n premiumRequestsTotal: number;\n warningActive: boolean;\n}\n\nexport type HudStatus = \"idle\" | \"running\" | \"waiting\" | \"complete\" | \"error\" | \"eco\";\n\nconst STATUS_ICONS: Record<HudStatus, string> = {\n idle: \"\u25CB\",\n running: \"\u25CF\",\n waiting: \"\u25F7\",\n complete: \"\u2713\",\n error: \"\u2717\",\n eco: \"\u26A1\",\n};\n\nfunction formatAge(startedAt: number): string {\n const elapsed = Date.now() - startedAt;\n const mins = Math.floor(elapsed / 60000);\n if (mins < 60) return `${mins}m`;\n const hours = Math.floor(mins / 60);\n const remainingMins = mins % 60;\n return `${hours}h${remainingMins}m`;\n}\n\nfunction formatTokens(tokens: number): string {\n if (tokens >= 1_000_000) return `${(tokens / 1_000_000).toFixed(1)}M`;\n if (tokens >= 1_000) return `${(tokens / 1_000).toFixed(1)}k`;\n return `${tokens}`;\n}\n\nfunction ctxColor(pct: number): string {\n if (pct < 60) return \"\\x1b[32m\"; // green\n if (pct < 85) return \"\\x1b[33m\"; // yellow\n return \"\\x1b[31m\"; // red\n}\n\nfunction reset(): string {\n return \"\\x1b[0m\";\n}\n\n/**\n * Render HUD line with ANSI color codes.\n * Format: [OMP v1.0.0] mode | model | ctx:N% | tok:~Nk/Nk | Nm | tools:N/N | skills:N/N | agents:N/N | N% status\n */\nexport function renderAnsi(state: HudState): string {\n const age = formatAge(state.startedAt);\n const tokens = formatTokens(state.tokensUsed);\n const ctx = state.contextPct;\n const mode = state.activeMode || \"-\";\n const model = state.activeModel || \"sonnet\";\n const icon = STATUS_ICONS[state.status] || \"\u25CF\";\n\n const ctxClr = ctxColor(ctx);\n const ctxStr = `${ctxClr}ctx:${ctx}%${reset()}`;\n const tokenStr = `tok:~${tokens}/${state.tokensTotal}`;\n const modeStr = mode === \"-\" ? \"-\" : `\\x1b[36m${mode}${reset()}`; // cyan for active modes\n\n const reqWarning = state.warningActive ? \" !!\" : \"\";\n const reqStr = `req:${state.premiumRequests ?? 0}/${state.premiumRequestsTotal ?? 1500}${reqWarning}`;\n\n return `[OMP v${state.version}] ${modeStr} | ${model} | ${ctxStr} | ${tokenStr} | ${reqStr} | ${age} | tools:${state.toolsUsed?.size || 0}/${state.toolsTotal ?? 13} | skills:${state.skillsUsed?.size || 0}/${state.skillsTotal ?? 25} | agents:${state.cumulativeAgentsUsed}/${state.agentsTotal ?? 23} | ${icon} ${state.status}`;\n}\n\n/**\n * Render HUD line as plain text (no ANSI codes).\n * Format: [OMP v1.0.0] mode | model | ctx:N% | tok:~Nk/Nk | Nm | tools:N/N | skills:N/N | agents:N/N | N% status\n */\nexport function renderPlain(state: HudState): string {\n const age = formatAge(state.startedAt);\n const tokens = formatTokens(state.tokensUsed);\n const ctx = state.contextPct;\n const mode = state.activeMode || \"-\";\n const model = state.activeModel || \"sonnet\";\n\n const reqWarningPlain = state.warningActive ? \" !!\" : \"\";\n const reqStrPlain = `req:${state.premiumRequests ?? 0}/${state.premiumRequestsTotal ?? 1500}${reqWarningPlain}`;\n\n return `[OMP v${state.version}] ${mode} | ${model} | ctx:${ctx}% | tok:~${tokens}/${state.tokensTotal} | ${reqStrPlain} | ${age} | tools:${state.toolsUsed?.size || 0}/${state.toolsTotal ?? 13} | skills:${state.skillsUsed?.size || 0}/${state.skillsTotal ?? 25} | agents:${state.cumulativeAgentsUsed}/${state.agentsTotal ?? 23} | ${state.status}`;\n}\n", "/**\n * HUD statusline helpers and standalone entrypoint.\n *\n * Keeps HUD artifact generation in one place so hooks and shell wrappers\n * can share the same rendering and fallback behavior.\n */\n\nimport { mkdirSync, readFileSync, renameSync, writeFileSync } from \"fs\";\nimport { homedir } from \"os\";\nimport { dirname, join } from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { renderPlain, type HudState, type HudStatus } from \"./renderer.mts\";\n\nconst DEFAULT_VERSION = \"0.0.0\";\nconst DEFAULT_STATUSLINE = \"OMP | hud: no active session\";\nconst DEFAULT_TOKEN_BUDGET = 200_000;\nconst DEFAULT_PREMIUM_REQUESTS_TOTAL = 1500;\n\nexport interface StatuslinePaths {\n legacyLinePath: string;\n hudDir: string;\n statusJsonPath: string;\n displayPath: string;\n tmuxSegmentPath: string;\n}\n\nexport interface HudSnapshot {\n version?: string;\n session_id?: string;\n started_at?: number;\n updated_at?: number;\n model?: string;\n tokens_estimated?: number;\n token_budget?: number;\n context_pct?: number;\n tools_used?: string[];\n skills_used?: string[];\n agents_used?: string[];\n active_mode?: string | null;\n last_output?: string;\n task_progress?: number;\n status?: HudStatus;\n premium_requests?: number;\n premium_requests_total?: number;\n warning_active?: boolean;\n}\n\ninterface SerializedHudState extends Omit<HudState, \"toolsUsed\" | \"skillsUsed\"> {\n toolsUsed: string[];\n skillsUsed: string[];\n}\n\nexport function getStatuslinePaths(home = process.env[\"HOME\"] || homedir()): StatuslinePaths {\n const ompDir = join(home, \".omp\");\n const hudDir = join(ompDir, \"hud\");\n return {\n legacyLinePath: join(ompDir, \"hud.line\"),\n hudDir,\n statusJsonPath: join(hudDir, \"status.json\"),\n displayPath: join(hudDir, \"display.txt\"),\n tmuxSegmentPath: join(hudDir, \"tmux-segment.sh\"),\n };\n}\n\nfunction ensureParent(filePath: string): void {\n mkdirSync(dirname(filePath), { recursive: true });\n}\n\nfunction writeAtomic(filePath: string, content: string, mode?: number): void {\n ensureParent(filePath);\n const tempPath = `${filePath}.tmp`;\n writeFileSync(tempPath, content, mode === undefined ? \"utf-8\" : { encoding: \"utf-8\", mode });\n renameSync(tempPath, filePath);\n}\n\nfunction normalizeStringArray(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n return value.filter((item): item is string => typeof item === \"string\");\n}\n\nfunction serializeHudState(state: HudState): SerializedHudState {\n return {\n ...state,\n toolsUsed: Array.from(state.toolsUsed),\n skillsUsed: Array.from(state.skillsUsed),\n };\n}\n\nfunction deserializeHudState(raw: unknown): HudState | null {\n if (!raw || typeof raw !== \"object\") return null;\n const value = raw as Record<string, unknown>;\n const toolsUsed = new Set(normalizeStringArray(value.toolsUsed));\n const skillsUsed = new Set(normalizeStringArray(value.skillsUsed));\n const agentsActive = normalizeStringArray(value.agentsActive);\n const status = typeof value.status === \"string\" ? (value.status as HudStatus) : \"idle\";\n\n return {\n sessionId: typeof value.sessionId === \"string\" ? value.sessionId : \"default\",\n activeMode: typeof value.activeMode === \"string\" ? value.activeMode : null,\n activeModel: typeof value.activeModel === \"string\" ? value.activeModel : \"sonnet\",\n contextPct: typeof value.contextPct === \"number\" ? value.contextPct : 0,\n tokensUsed: typeof value.tokensUsed === \"number\" ? value.tokensUsed : 0,\n tokensTotal: typeof value.tokensTotal === \"number\" ? value.tokensTotal : DEFAULT_TOKEN_BUDGET,\n agentsActive,\n lastAgent: typeof value.lastAgent === \"string\" ? value.lastAgent : agentsActive.at(-1) ?? \"-\",\n lastOutput: typeof value.lastOutput === \"string\" ? value.lastOutput : \"\",\n taskProgress: typeof value.taskProgress === \"number\" ? value.taskProgress : 0,\n startedAt: typeof value.startedAt === \"number\" ? value.startedAt : Date.now(),\n updatedAt: typeof value.updatedAt === \"number\" ? value.updatedAt : Date.now(),\n version: typeof value.version === \"string\" ? value.version : DEFAULT_VERSION,\n status,\n sessionDurationMs: typeof value.sessionDurationMs === \"number\" ? value.sessionDurationMs : 0,\n cumulativeAgentsUsed: typeof value.cumulativeAgentsUsed === \"number\" ? value.cumulativeAgentsUsed : agentsActive.length,\n toolsUsed,\n skillsUsed,\n toolsTotal: typeof value.toolsTotal === \"number\" ? value.toolsTotal : 13,\n skillsTotal: typeof value.skillsTotal === \"number\" ? value.skillsTotal : 25,\n agentsTotal: typeof value.agentsTotal === \"number\" ? value.agentsTotal : 23,\n premiumRequests: typeof value.premiumRequests === \"number\" ? value.premiumRequests : 0,\n premiumRequestsTotal: typeof value.premiumRequestsTotal === \"number\" ? value.premiumRequestsTotal : DEFAULT_PREMIUM_REQUESTS_TOTAL,\n warningActive: typeof value.warningActive === \"boolean\" ? value.warningActive : false,\n };\n}\n\nexport function buildHudState(snapshot: HudSnapshot, now = Date.now()): HudState {\n const startedAt = snapshot.started_at ?? now;\n const updatedAt = snapshot.updated_at ?? now;\n const toolsUsed = new Set(normalizeStringArray(snapshot.tools_used));\n const skillsUsed = new Set(normalizeStringArray(snapshot.skills_used));\n const agentsActive = normalizeStringArray(snapshot.agents_used);\n\n return {\n sessionId: snapshot.session_id ?? \"default\",\n activeMode: snapshot.active_mode ?? null,\n activeModel: snapshot.model ?? \"sonnet\",\n contextPct: snapshot.context_pct ?? 0,\n tokensUsed: snapshot.tokens_estimated ?? 0,\n tokensTotal: snapshot.token_budget ?? DEFAULT_TOKEN_BUDGET,\n agentsActive,\n lastAgent: agentsActive.at(-1) ?? \"-\",\n lastOutput: snapshot.last_output ?? \"\",\n taskProgress: snapshot.task_progress ?? 0,\n startedAt,\n updatedAt,\n version: snapshot.version ?? DEFAULT_VERSION,\n status: snapshot.status ?? \"idle\",\n sessionDurationMs: Math.max(0, updatedAt - startedAt),\n cumulativeAgentsUsed: agentsActive.length,\n toolsUsed,\n skillsUsed,\n toolsTotal: 13,\n skillsTotal: 25,\n agentsTotal: 23,\n premiumRequests: snapshot.premium_requests ?? 0,\n premiumRequestsTotal: snapshot.premium_requests_total ?? DEFAULT_PREMIUM_REQUESTS_TOTAL,\n warningActive: snapshot.warning_active ?? false,\n };\n}\n\nexport function writeHudArtifacts(snapshot: HudSnapshot, paths = getStatuslinePaths()): { line: string; state: HudState; paths: StatuslinePaths } {\n const state = buildHudState(snapshot);\n const line = renderPlain(state);\n const serializedState = `${JSON.stringify(serializeHudState(state), null, 2)}\\n`;\n\n writeAtomic(paths.statusJsonPath, serializedState);\n writeAtomic(paths.displayPath, `${line}\\n`);\n writeAtomic(paths.tmuxSegmentPath, `${line}\\n`, 0o755);\n writeAtomic(paths.legacyLinePath, `${line}\\n`);\n\n return { line, state, paths };\n}\n\nexport function readStatusline(paths = getStatuslinePaths()): string {\n // Try live render from status.json \u2014 formatAge runs at call time, not hook-fire time\n try {\n const parsed = JSON.parse(readFileSync(paths.statusJsonPath, \"utf-8\"));\n const state = deserializeHudState(parsed);\n if (state) return renderPlain(state);\n } catch {\n // Fall through to cached display string.\n }\n\n // Fallback: pre-rendered cached string (written by hud-emitter; used by tmux consumers)\n try {\n const line = readFileSync(paths.displayPath, \"utf-8\").trim();\n if (line) return line;\n } catch {\n // Fall through to legacy file.\n }\n\n try {\n const line = readFileSync(paths.legacyLinePath, \"utf-8\").trim();\n if (line) return line;\n } catch {}\n\n return DEFAULT_STATUSLINE;\n}\n\nif (process.argv[1] === fileURLToPath(import.meta.url)) {\n console.log(readStatusline());\n}\n", "/**\n * HUD watch daemon \u2014 polls session state and rewrites HUD artifacts on each tick.\n *\n * Usage:\n * omp hud --watch Poll every 2s (default)\n * OMP_HUD_INTERVAL=5000 omp hud --watch Override interval (ms)\n *\n * Each cycle:\n * readState() \u2192 buildHudState() \u2192 renderAnsi() \u2192 writeHudArtifacts()\n *\n * Elapsed time is always recomputed from startedAt so the display never goes stale\n * between hook firings.\n */\n\nimport { readFileSync } from \"fs\";\nimport { homedir } from \"os\";\nimport { join } from \"path\";\nimport {\n buildHudState,\n writeHudArtifacts,\n getStatuslinePaths,\n type HudSnapshot,\n} from \"./statusline.mts\";\nimport { renderAnsi } from \"./renderer.mts\";\n\nconst DEFAULT_INTERVAL_MS = 2_000;\nconst STATE_PATH = join(homedir(), \".omp\", \"state\", \"session.json\");\n\nfunction readSnapshot(): HudSnapshot | null {\n try {\n const raw = readFileSync(STATE_PATH, \"utf-8\");\n const parsed = JSON.parse(raw) as HudSnapshot;\n return parsed;\n } catch {\n return null;\n }\n}\n\nfunction tick(paths = getStatuslinePaths()): void {\n const snapshot = readSnapshot();\n if (!snapshot) return;\n\n // Pass current time so buildHudState recomputes sessionDurationMs from live clock.\n const now = Date.now();\n const state = buildHudState(snapshot, now);\n\n // Write all artifacts (display.txt, tmux-segment.sh, status.json, hud.line).\n writeHudArtifacts(snapshot, paths);\n\n // Render ANSI to stdout so a terminal running `omp hud --watch` shows live output.\n process.stdout.write(\"\\x1b[2J\\x1b[H\" + renderAnsi(state) + \"\\x1b[K\\n\\x1b[J\");\n}\n\n/**\n * Start the HUD watch daemon.\n *\n * Runs until SIGINT or SIGTERM. The interval is configurable via the\n * OMP_HUD_INTERVAL env var (milliseconds).\n */\nexport function runHudWatch(): void {\n const intervalMs = Math.max(\n 500,\n parseInt(process.env[\"OMP_HUD_INTERVAL\"] ?? \"\", 10) || DEFAULT_INTERVAL_MS,\n );\n\n const paths = getStatuslinePaths();\n\n // Hide cursor while watch loop is active.\n process.stdout.write(\"\\x1b[?25l\");\n\n // Initial render immediately.\n try {\n tick(paths);\n } catch {\n // Swallow first-tick errors \u2014 state may not exist yet.\n }\n\n const timer = setInterval(() => {\n try {\n tick(paths);\n } catch {\n // Swallow per-tick errors to keep the daemon alive.\n }\n }, intervalMs);\n\n const stop = () => {\n clearInterval(timer);\n // Restore cursor and clear screen before exit.\n process.stdout.write(\"\\x1b[?25h\\x1b[2J\\x1b[H\");\n process.exit(0);\n };\n\n process.on(\"SIGINT\", stop);\n process.on(\"SIGTERM\", stop);\n}\n", "import { mkdir, readFile, rename, writeFile } from \"fs/promises\";\nimport { homedir } from \"os\";\nimport { dirname, join } from \"path\";\nimport { fileURLToPath } from \"url\";\n\nexport async function runInstall(\n settingsPath = join(homedir(), \".copilot\", \"settings.json\"),\n): Promise<void> {\n // dirname(import.meta.url) = <pkg>/bin, \"..\" = <pkg>\n const pkgRoot = join(dirname(fileURLToPath(import.meta.url)), \"..\");\n const statusLineCommand = join(pkgRoot, \"bin\", \"omp-statusline.sh\");\n const marketplacePath = pkgRoot;\n\n let existing: Record<string, unknown> = {};\n try {\n const raw = await readFile(settingsPath, \"utf-8\");\n const parsed: unknown = JSON.parse(raw);\n if (parsed !== null && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n existing = parsed as Record<string, unknown>;\n }\n } catch { /* missing or invalid \u2014 start fresh */ }\n\n const existingPlugins =\n typeof existing.enabledPlugins === \"object\" &&\n existing.enabledPlugins !== null &&\n !Array.isArray(existing.enabledPlugins)\n ? (existing.enabledPlugins as Record<string, unknown>)\n : {};\n\n const existingMarketplaces =\n typeof existing.extraKnownMarketplaces === \"object\" &&\n existing.extraKnownMarketplaces !== null &&\n !Array.isArray(existing.extraKnownMarketplaces)\n ? (existing.extraKnownMarketplaces as Record<string, unknown>)\n : {};\n\n const merged = {\n ...existing,\n enabledPlugins: {\n ...existingPlugins,\n \"oh-my-githubcopilot@oh-my-githubcopilot\": true,\n },\n experimental: true,\n statusLine: { type: \"command\", command: statusLineCommand },\n extraKnownMarketplaces: {\n ...existingMarketplaces,\n \"oh-my-githubcopilot\": {\n source: { source: \"directory\", path: marketplacePath },\n },\n },\n };\n\n // Atomic write: tmp \u2192 rename (prevents partial write on crash/disk-full)\n const tmp = `${settingsPath}.tmp`;\n await mkdir(dirname(settingsPath), { recursive: true });\n await writeFile(tmp, JSON.stringify(merged, null, 2) + \"\\n\", \"utf-8\");\n await rename(tmp, settingsPath);\n\n console.log(`omp install: wrote ${settingsPath}`);\n console.log(` statusLine.command: ${statusLineCommand}`);\n console.log(` marketplace path: ${marketplacePath}`);\n console.log(` plugin: oh-my-githubcopilot@oh-my-githubcopilot`);\n console.log(`\\nRestart Copilot CLI to activate OMP.`);\n}\n", "/**\n * keyword-detector hook\n * Trigger: pre-cycle (UserPromptSubmitted equivalent)\n * Priority: 100 (runs first)\n *\n * Scans incoming prompts for magic keywords and rewrites them\n * to skill invocation slash commands.\n */\n\nexport interface KeywordMatch {\n keyword: string;\n skillId: string;\n position: number;\n}\n\nconst KEYWORD_MAP: Record<string, string> = {\n \"autopilot:\": \"autopilot\",\n \"/autopilot\": \"autopilot\",\n \"/omp:autopilot\": \"autopilot\",\n \"ralph:\": \"ralph\",\n \"/ralph\": \"ralph\",\n \"/omp:ralph\": \"ralph\",\n \"ulw:\": \"ultrawork\",\n \"ultrawork:\": \"ultrawork\",\n \"/ulw\": \"ultrawork\",\n \"/ultrawork\": \"ultrawork\",\n \"/omp:ulw\": \"ultrawork\",\n \"/omp:ultrawork\": \"ultrawork\",\n \"team:\": \"team\",\n \"/team\": \"team\",\n \"/omp:team\": \"team\",\n \"eco:\": \"ecomode\",\n \"ecomode:\": \"ecomode\",\n \"/eco\": \"ecomode\",\n \"/ecomode\": \"ecomode\",\n \"/omp:eco\": \"ecomode\",\n \"/omp:ecomode\": \"ecomode\",\n \"swarm:\": \"swarm\",\n \"/swarm\": \"swarm\",\n \"/omp:swarm\": \"swarm\",\n \"pipeline:\": \"pipeline\",\n \"/pipeline\": \"pipeline\",\n \"/omp:pipeline\": \"pipeline\",\n \"deep interview:\": \"deep-interview\",\n \"/deep-interview\": \"deep-interview\",\n \"/omp:deep-interview\": \"deep-interview\",\n \"plan:\": \"omp-plan\",\n \"/plan\": \"omp-plan\",\n \"/omp-plan\": \"omp-plan\",\n \"/omp:plan\": \"omp-plan\",\n \"setup:\": \"omp-setup\",\n \"/setup\": \"omp-setup\",\n \"/omp-setup\": \"omp-setup\",\n \"/omp:setup\": \"omp-setup\",\n \"mcp:\": \"mcp-setup\",\n \"mcp-setup:\": \"mcp-setup\",\n \"/mcp\": \"mcp-setup\",\n \"/mcp-setup\": \"mcp-setup\",\n \"/omp:mcp-setup\": \"mcp-setup\",\n \"/hud\": \"hud\",\n \"hud:\": \"hud\",\n \"/omp:hud\": \"hud\",\n \"/wiki\": \"wiki\",\n \"wiki:\": \"wiki\",\n \"/omp:wiki\": \"wiki\",\n \"/learner\": \"learner\",\n \"learner:\": \"learner\",\n \"/omp:learner\": \"learner\",\n \"/note\": \"note\",\n \"note:\": \"note\",\n \"/omp:note\": \"note\",\n \"/trace\": \"trace\",\n \"trace:\": \"trace\",\n \"/omp:trace\": \"trace\",\n \"/release\": \"release\",\n \"release:\": \"release\",\n \"/omp:release\": \"release\",\n \"/configure-notifications\": \"configure-notifications\",\n \"configure-notifications:\": \"configure-notifications\",\n \"/omp:configure-notifications\": \"configure-notifications\",\n \"/psm\": \"psm\",\n \"psm:\": \"psm\",\n \"/omp:psm\": \"psm\",\n \"/swe-bench\": \"swe-bench\",\n \"swe-bench:\": \"swe-bench\",\n \"/omp:swe-bench\": \"swe-bench\",\n \"graphify:\": \"graphify\",\n \"graph build\": \"graphify\",\n \"build graph\": \"graphify\",\n \"graphwiki:\": \"graphwiki\",\n \"graph:\": \"graph-provider\",\n \"spending:\": \"spending\",\n \"/graphify\": \"graphify\",\n \"/omp:graphify\": \"graphify\",\n \"/graphwiki\": \"graphwiki\",\n \"/omp:graphwiki\": \"graphwiki\",\n \"/graph-provider\": \"graph-provider\",\n \"/omp:graph-provider\": \"graph-provider\",\n \"/spending\": \"spending\",\n \"/omp:spending\": \"spending\",\n \"--consensus\": \"omp-plan\",\n \"/omp:omp-doctor\": \"omp-doctor\",\n \"/omp:ralplan\": \"ralplan\",\n \"/omp:research\": \"research\",\n \"doctor:\": \"doctor\",\n \"/doctor\": \"doctor\",\n \"/omp:doctor\": \"doctor\",\n \"interview:\": \"interview\",\n \"/interview\": \"interview\",\n \"/omp:interview\": \"interview\",\n \"notifications:\": \"notifications\",\n \"/notifications\": \"notifications\",\n \"/omp:notifications\": \"notifications\",\n \"session:\": \"session\",\n \"/session\": \"session\",\n \"/omp:session\": \"session\",\n};\n\nconst KEYWORD_ENTRIES = Object.entries(KEYWORD_MAP).sort(([a], [b]) => b.length - a.length);\nconst CANONICAL_COMMAND_MAP: Record<string, string> = {\n \"omp-plan\": \"/omp:plan\",\n \"omp-setup\": \"/setup\",\n \"mcp-setup\": \"/mcp\",\n};\n\nexport interface HookInput {\n hook_type: \"UserPromptSubmitted\";\n prompt: string;\n session_id?: string;\n}\n\nexport interface HookOutput {\n decision?: \"allow\";\n modifiedPrompt?: string;\n additionalContext?: string;\n status: \"ok\" | \"skip\" | \"error\";\n latencyMs: number;\n mutations: Array<{ type: \"set_mode\"; mode: string } | { type: \"log\"; level: \"info\"; message: string }>;\n log: string[];\n}\n\nfunction detectKeyword(prompt: string): KeywordMatch | null {\n const trimmed = prompt.trimStart();\n\n // Prefer the longest literal alias match first so /mcp-setup wins over /mcp.\n for (const [keyword, skillId] of KEYWORD_ENTRIES) {\n if (trimmed.startsWith(keyword)) {\n return {\n keyword,\n skillId,\n position: 0,\n };\n }\n }\n\n // Case-insensitive check for slash forms\n const slashPattern = /^\\/((?:omp:)?[a-zA-Z][a-zA-Z0-9-]*)\\b/;\n const slashMatch = trimmed.match(slashPattern);\n if (slashMatch) {\n const cmd = slashMatch[1].toLowerCase();\n const skillId = KEYWORD_MAP[`/${cmd}`] ?? KEYWORD_MAP[`${cmd}:`];\n if (skillId) {\n return {\n keyword: slashMatch[0],\n skillId,\n position: 0,\n };\n }\n }\n\n // Compatibility: support long namespace aliases like\n // \"oh-my-githubcopilot:ralph\" (or \"/oh-my-githubcopilot:ralph\")\n const longNamespacePattern = /^\\/?oh-my-githubcopilot:([a-zA-Z][a-zA-Z0-9-]*)\\b/i;\n const longNamespaceMatch = trimmed.match(longNamespacePattern);\n if (longNamespaceMatch) {\n const cmd = longNamespaceMatch[1].toLowerCase();\n const skillId =\n KEYWORD_MAP[`/omp:${cmd}`] ??\n KEYWORD_MAP[`/${cmd}`] ??\n KEYWORD_MAP[`${cmd}:`];\n if (skillId) {\n return {\n keyword: longNamespaceMatch[0],\n skillId,\n position: 0,\n };\n }\n }\n\n return null;\n}\n\nfunction getCanonicalCommand(skillId: string): string {\n return CANONICAL_COMMAND_MAP[skillId] ?? `/omp:${skillId}`;\n}\n\nexport function processHook(input: HookInput): HookOutput {\n const start = Date.now();\n const log: string[] = [];\n\n try {\n if (input.hook_type !== \"UserPromptSubmitted\") {\n return {\n status: \"skip\",\n latencyMs: Date.now() - start,\n mutations: [],\n log: [\"Not a UserPromptSubmitted hook\"],\n };\n }\n\n const match = detectKeyword(input.prompt);\n if (!match) {\n return {\n status: \"ok\",\n latencyMs: Date.now() - start,\n mutations: [],\n log: [],\n };\n }\n\n // Rewrite prompt to invoke the skill\n const taskPart = input.prompt.slice(match.position + match.keyword.length).trim();\n const rewritten = `${getCanonicalCommand(match.skillId)}${taskPart ? ` ${taskPart}` : \"\"}`;\n\n log.push(`Keyword detected: \"${match.keyword}\" \u2192 skill: ${match.skillId}`);\n log.push(`Rewritten: \"${rewritten}\"`);\n\n return {\n status: \"ok\",\n latencyMs: Date.now() - start,\n modifiedPrompt: rewritten,\n mutations: [\n { type: \"set_mode\", mode: match.skillId },\n { type: \"log\", level: \"info\", message: `Skill activated: ${match.skillId}` },\n ],\n log,\n };\n } catch (err) {\n return {\n status: \"error\",\n latencyMs: Date.now() - start,\n mutations: [],\n log: [`Error: ${err}`],\n };\n }\n}\n\n// Main entry point \u2014 only runs when executed directly (not imported).\n// The omp CLI imports processHook directly to avoid double-dispatch when bundled.\nif (process.argv[1]?.endsWith(\"keyword-detector.mjs\") || process.argv[1]?.endsWith(\"keyword-detector.mts\")) {\n const input: HookInput = JSON.parse(await readStdin());\n const output = processHook(input);\n console.log(JSON.stringify(output));\n}\n\nasync function readStdin(): Promise<string> {\n const chunks: string[] = [];\n for await (const chunk of process.stdin) {\n chunks.push(chunk);\n }\n return chunks.join(\"\");\n}\n", "/**\n * omp CLI companion tool\n * Entry point: bin/omp.mjs\n *\n * Subcommands:\n * omp hud \u2014 print current HUD line\n * omp version \u2014 show OMP version\n * omp psm \u2014 shorthand for PSM commands\n * omp bench \u2014 run SWE-bench suite\n * omp hook \u2014 execute a packaged hook from stdin\n */\n\nimport { parseArgs } from \"util\";\nimport { createRequire } from \"module\";\nimport { maybeCheckAndPromptUpdate } from \"./cli/update.mts\";\nconst _require = createRequire(import.meta.url);\nconst { version: PKG_VERSION, name: PKG_NAME } = _require(\"../package.json\") as { version: string; name: string };\n\nconst { positionals, values: flags } = parseArgs({\n args: process.argv.slice(2),\n options: {\n help: { type: \"boolean\", default: false },\n version: { type: \"boolean\", default: false },\n watch: { type: \"boolean\", default: false },\n },\n allowPositionals: true,\n});\n\nconst subcommand = positionals[0] || \"hud\";\nconst resolvedSubcommand = flags.version && !positionals[0] ? \"version\" : subcommand;\n\nasync function main() {\n if (flags.help) {\n printUsage();\n return;\n }\n\n await maybeCheckAndPromptUpdate({\n cwd: process.cwd(),\n packageName: PKG_NAME,\n currentVersion: PKG_VERSION,\n subcommand: resolvedSubcommand,\n flags: {\n help: flags.help,\n version: flags.version,\n },\n });\n\n switch (resolvedSubcommand) {\n case \"hud\":\n if (flags.watch) {\n const { runHudWatch } = await import(\"./hud/watch.mts\");\n runHudWatch();\n } else {\n await printHud();\n }\n break;\n case \"version\":\n console.log(`${PKG_NAME} v${PKG_VERSION}`);\n break;\n case \"psm\":\n await runPsm(positionals.slice(1));\n break;\n case \"bench\":\n await runBench(positionals.slice(1));\n break;\n case \"hook\":\n await runHook(positionals.slice(1));\n break;\n case \"install\": {\n const { runInstall } = await import(\"./cli/install.mts\");\n await runInstall();\n break;\n }\n default:\n console.error(`Unknown subcommand: ${resolvedSubcommand}`);\n printUsage(true);\n process.exit(1);\n }\n}\n\nfunction printUsage(stderr = false) {\n const output = stderr ? console.error : console.log;\n output(\"Usage: omp [hud|install|version|psm|bench|hook] [--watch]\");\n}\n\nasync function printHud() {\n try {\n const { readFileSync } = await import(\"fs\");\n const { join } = await import(\"path\");\n const { homedir } = await import(\"os\");\n const hudPath = join(homedir(), \".omp\", \"hud.line\");\n const line = readFileSync(hudPath, \"utf-8\").trim();\n console.log(line);\n } catch {\n console.log(`OMP v${PKG_VERSION} | hud: no active session`);\n }\n}\n\nasync function runPsm(_args: string[]) {\n // Delegate to PSM skill \u2014 just print guidance\n console.log(\"PSM commands:\");\n console.log(\" /omp:psm create <name> Create isolated worktree session\");\n console.log(\" /omp:psm list List active sessions\");\n console.log(\" /omp:psm switch <name> Switch to session\");\n console.log(\" /omp:psm destroy <name> Destroy session\");\n}\n\nasync function runHook(args: string[]) {\n const hookId = args[0];\n if (hookId !== \"keyword-detector\") {\n console.error(\"Usage: omp hook keyword-detector\");\n process.exit(1);\n }\n\n const { processHook } = await import(\"./hooks/keyword-detector.mts\");\n const inputText = await readStdin();\n const input = JSON.parse(inputText || \"{}\");\n const output = processHook(input);\n console.log(JSON.stringify(output));\n}\n\nasync function readStdin(): Promise<string> {\n const chunks: string[] = [];\n for await (const chunk of process.stdin) {\n chunks.push(String(chunk));\n }\n return chunks.join(\"\");\n}\n\nasync function runBench(_args: string[]) {\n console.log(\"SWE-bench requires Node.js subprocess with Python evaluation harness.\");\n console.log(\"Usage: /omp:swe-bench --suite lite --compare baseline\");\n}\n\nmain().catch((err) => {\n console.error(err);\n process.exit(1);\n});\n", "/**\n * Launch-time update checks for the omp CLI companion.\n * Non-fatal, TTY-only, and throttled via ~/.omp/state/update-check.json.\n */\n\nimport { spawnSync } from \"child_process\";\nimport { mkdir, readFile, writeFile } from \"fs/promises\";\nimport { homedir } from \"os\";\nimport { dirname, join } from \"path\";\nimport { createInterface } from \"node:readline/promises\";\n\nexport interface UpdateState {\n last_checked_at: string;\n last_seen_latest?: string;\n}\n\nexport interface UpdateCheckFlags {\n help?: boolean;\n version?: boolean;\n}\n\nexport interface UpdateCheckContext {\n cwd: string;\n packageName: string;\n currentVersion: string;\n subcommand: string;\n flags?: UpdateCheckFlags;\n}\n\ninterface LatestPackageInfo {\n version?: string;\n}\n\ninterface ParsedSemver {\n major: number;\n minor: number;\n patch: number;\n prerelease: string | null;\n}\n\ninterface UpdateDependencies {\n nowMs: () => number;\n readUpdateState: (statePath: string) => Promise<UpdateState | null>;\n writeUpdateState: (statePath: string, state: UpdateState) => Promise<void>;\n fetchLatestVersion: (packageName: string) => Promise<string | null>;\n askYesNo: (question: string) => Promise<boolean>;\n runGlobalUpdate: (packageName: string, cwd: string) => { ok: boolean; stderr: string };\n}\n\nconst CHECK_INTERVAL_MS = 12 * 60 * 60 * 1000; // 12h\nconst PROMPTABLE_SUBCOMMANDS = new Set([\"hud\", \"psm\", \"bench\"]);\nconst DISABLED_AUTO_UPDATE_VALUES = new Set([\"0\", \"false\", \"no\", \"off\"]);\nconst ENABLED_DISABLE_FLAG_VALUES = new Set([\"1\", \"true\", \"yes\", \"on\"]);\n\nfunction parseSemver(version: string): ParsedSemver | null {\n const match = version.trim().match(/^v?(\\d+)\\.(\\d+)\\.(\\d+)(?:-([0-9A-Za-z.-]+))?$/);\n if (!match) return null;\n return {\n major: Number(match[1]),\n minor: Number(match[2]),\n patch: Number(match[3]),\n prerelease: match[4] ?? null,\n };\n}\n\nexport function isNewerVersion(current: string, latest: string): boolean {\n const currentVersion = parseSemver(current);\n const latestVersion = parseSemver(latest);\n if (!currentVersion || !latestVersion) return false;\n\n if (latestVersion.major !== currentVersion.major) return latestVersion.major > currentVersion.major;\n if (latestVersion.minor !== currentVersion.minor) return latestVersion.minor > currentVersion.minor;\n if (latestVersion.patch !== currentVersion.patch) return latestVersion.patch > currentVersion.patch;\n\n // Stable release of the same numeric version is newer than a prerelease.\n if (currentVersion.prerelease && !latestVersion.prerelease) return true;\n return false;\n}\n\nexport function shouldCheckForUpdates(\n nowMs: number,\n state: UpdateState | null,\n intervalMs = CHECK_INTERVAL_MS\n): boolean {\n if (!state?.last_checked_at) return true;\n const lastCheckedAt = Date.parse(state.last_checked_at);\n if (!Number.isFinite(lastCheckedAt)) return true;\n return nowMs - lastCheckedAt >= intervalMs;\n}\n\nexport function isAutoUpdateDisabled(env: NodeJS.ProcessEnv = process.env): boolean {\n const autoUpdate = env[\"OMP_AUTO_UPDATE\"]?.trim().toLowerCase();\n if (autoUpdate && DISABLED_AUTO_UPDATE_VALUES.has(autoUpdate)) return true;\n\n const disableCheck = env[\"OMP_DISABLE_UPDATE_CHECK\"]?.trim().toLowerCase();\n if (disableCheck && ENABLED_DISABLE_FLAG_VALUES.has(disableCheck)) return true;\n\n return false;\n}\n\nexport function shouldSkipUpdatePrompt(subcommand: string, flags: UpdateCheckFlags = {}): boolean {\n if (flags.help || flags.version) return true;\n return !PROMPTABLE_SUBCOMMANDS.has(subcommand);\n}\n\nfunction updateStatePath(homeDir: string): string {\n return join(homeDir, \".omp\", \"state\", \"update-check.json\");\n}\n\nasync function readCachedUpdateState(statePath: string): Promise<UpdateState | null> {\n try {\n const raw = await readFile(statePath, \"utf-8\");\n return JSON.parse(raw) as UpdateState;\n } catch {\n return null;\n }\n}\n\nasync function writeCachedUpdateState(statePath: string, state: UpdateState): Promise<void> {\n await mkdir(dirname(statePath), { recursive: true });\n await writeFile(statePath, JSON.stringify(state, null, 2), \"utf-8\");\n}\n\nasync function fetchLatestVersionFromNpm(packageName: string, timeoutMs = 3500): Promise<string | null> {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), timeoutMs);\n try {\n const url = `https://registry.npmjs.org/${encodeURIComponent(packageName)}/latest`;\n const response = await fetch(url, { signal: controller.signal });\n if (!response.ok) return null;\n const payload = (await response.json()) as LatestPackageInfo;\n return typeof payload.version === \"string\" ? payload.version : null;\n } catch {\n return null;\n } finally {\n clearTimeout(timeout);\n }\n}\n\nfunction runNpmGlobalUpdate(packageName: string, cwd: string): { ok: boolean; stderr: string } {\n const result = spawnSync(\"npm\", [\"install\", \"-g\", `${packageName}@latest`], {\n encoding: \"utf-8\",\n stdio: [\"ignore\", \"ignore\", \"pipe\"],\n timeout: 120000,\n windowsHide: true,\n cwd,\n });\n\n if (result.error) return { ok: false, stderr: result.error.message };\n if (result.status !== 0) {\n return { ok: false, stderr: (result.stderr || \"\").trim() || `npm exited ${result.status}` };\n }\n return { ok: true, stderr: \"\" };\n}\n\nasync function askYesNo(question: string): Promise<boolean> {\n if (!process.stdin.isTTY || !process.stdout.isTTY) return false;\n const readline = createInterface({ input: process.stdin, output: process.stdout });\n try {\n const answer = (await readline.question(question)).trim().toLowerCase();\n return answer === \"\" || answer === \"y\" || answer === \"yes\";\n } finally {\n readline.close();\n }\n}\n\nconst defaultDependencies: UpdateDependencies = {\n nowMs: () => Date.now(),\n readUpdateState: readCachedUpdateState,\n writeUpdateState: writeCachedUpdateState,\n fetchLatestVersion: fetchLatestVersionFromNpm,\n askYesNo,\n runGlobalUpdate: runNpmGlobalUpdate,\n};\n\nexport async function maybeCheckAndPromptUpdate(\n context: UpdateCheckContext,\n dependencies: Partial<UpdateDependencies> = {}\n): Promise<void> {\n const updateDependencies: UpdateDependencies = {\n ...defaultDependencies,\n ...dependencies,\n };\n\n try {\n if (isAutoUpdateDisabled()) return;\n if (!process.stdin.isTTY || !process.stdout.isTTY) return;\n if (shouldSkipUpdatePrompt(context.subcommand, context.flags)) return;\n\n const statePath = updateStatePath(process.env[\"HOME\"] || homedir());\n const now = updateDependencies.nowMs();\n const state = await updateDependencies.readUpdateState(statePath);\n\n if (!shouldCheckForUpdates(now, state)) return;\n\n const latestVersion = await updateDependencies.fetchLatestVersion(context.packageName);\n await updateDependencies.writeUpdateState(statePath, {\n last_checked_at: new Date(now).toISOString(),\n last_seen_latest: latestVersion || state?.last_seen_latest,\n });\n\n if (!latestVersion || !isNewerVersion(context.currentVersion, latestVersion)) return;\n\n const approved = await updateDependencies.askYesNo(\n `[omp] Update available: v${context.currentVersion} \u2192 v${latestVersion}. Update now? [Y/n] `\n );\n if (!approved) return;\n\n console.log(`[omp] Running: npm install -g ${context.packageName}@latest`);\n const result = updateDependencies.runGlobalUpdate(context.packageName, context.cwd);\n\n if (result.ok) {\n console.log(`[omp] Updated to v${latestVersion}. Restart this shell to load the new CLI.`);\n } else {\n console.log(`[omp] Update failed. Run manually: npm install -g ${context.packageName}@latest`);\n }\n } catch {\n // Update checks should never block normal CLI flows.\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["homedir", "dirname", "join", "readFileSync", "homedir", "join", "mkdir", "readFile", "writeFile", "homedir", "dirname", "join", "fileURLToPath", "subcommand", "flags", "runHudWatch", "runInstall", "readFileSync", "join", "homedir", "processHook", "readStdin"]
|
|
7
7
|
}
|
|
@@ -153,17 +153,17 @@ function writeHudArtifacts(snapshot, paths = getStatuslinePaths()) {
|
|
|
153
153
|
return { line, state, paths };
|
|
154
154
|
}
|
|
155
155
|
function readStatusline(paths = getStatuslinePaths()) {
|
|
156
|
-
try {
|
|
157
|
-
const line = readFileSync(paths.displayPath, "utf-8").trim();
|
|
158
|
-
if (line) return line;
|
|
159
|
-
} catch {
|
|
160
|
-
}
|
|
161
156
|
try {
|
|
162
157
|
const parsed = JSON.parse(readFileSync(paths.statusJsonPath, "utf-8"));
|
|
163
158
|
const state = deserializeHudState(parsed);
|
|
164
159
|
if (state) return renderPlain(state);
|
|
165
160
|
} catch {
|
|
166
161
|
}
|
|
162
|
+
try {
|
|
163
|
+
const line = readFileSync(paths.displayPath, "utf-8").trim();
|
|
164
|
+
if (line) return line;
|
|
165
|
+
} catch {
|
|
166
|
+
}
|
|
167
167
|
try {
|
|
168
168
|
const line = readFileSync(paths.legacyLinePath, "utf-8").trim();
|
|
169
169
|
if (line) return line;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/hooks/hud-emitter.mts", "../../src/hud/statusline.mts", "../../src/hud/renderer.mts"],
|
|
4
|
-
"sourcesContent": ["/**\n * hud-emitter hook\n * Trigger: post-cycle (PostToolUse + SessionStart)\n * Priority: 60\n *\n * Writes HUD artifacts after every tool call and initializes session state.\n */\n\nimport { mkdirSync, readFileSync, writeFileSync } from \"fs\";\nimport { createRequire } from \"module\";\nimport { homedir } from \"os\";\nimport { join } from \"path\";\nimport { writeHudArtifacts } from \"../hud/statusline.mts\";\n\nconst _require = createRequire(import.meta.url);\nconst { version: PKG_VERSION } = _require(\"../../package.json\") as { version: string };\n\nexport interface HookInput {\n hook_type: \"SessionStart\" | \"PostToolUse\";\n tool_name?: string;\n tool_input?: unknown;\n tool_output?: unknown;\n session_id?: string;\n model?: string;\n}\n\nexport interface HookOutput {\n status: \"ok\" | \"skip\" | \"error\";\n latencyMs: number;\n mutations: Array<{ type: \"emit_hud\"; hudEmit: HudEmit } | { type: \"log\"; level: \"info\"; message: string }>;\n log: string[];\n}\n\nexport interface HudEmit {\n sessionId: string;\n activeMode: string | null;\n contextPct: number;\n tokensUsed: number;\n tokensTotal: number;\n agentsActive: string[];\n lastAgent: string;\n lastOutput: string;\n taskProgress: number;\n}\n\ninterface SessionState {\n version: string;\n session_id: string;\n started_at: number;\n updated_at: number;\n model: string;\n tokens_estimated: number;\n token_budget: number;\n context_pct: number;\n tools_used: string[];\n skills_used: string[];\n agents_used: string[];\n active_mode: string | null;\n last_output: string;\n task_progress: number;\n status: \"idle\" | \"running\" | \"waiting\" | \"complete\" | \"error\" | \"eco\";\n premium_requests: number;\n premium_requests_total: number;\n warning_active: boolean;\n}\n\nfunction getStatePath(sessionId?: string): string {\n const base = join(process.env[\"HOME\"] || homedir(), \".omp\", \"state\");\n if (sessionId) {\n return join(base, \"sessions\", sessionId, \"session.json\");\n }\n return join(base, \"session.json\");\n}\n\nfunction ensureDir(path: string): void {\n mkdirSync(path.substring(0, path.lastIndexOf(\"/\")), { recursive: true });\n}\n\nfunction stringifyOutput(value: unknown): string {\n if (typeof value === \"string\") {\n return value.trim().slice(0, 200);\n }\n if (value === undefined || value === null) {\n return \"\";\n }\n try {\n return JSON.stringify(value).slice(0, 200);\n } catch {\n return String(value).slice(0, 200);\n }\n}\n\nfunction buildEmit(state: SessionState): HudEmit {\n return {\n sessionId: state.session_id,\n activeMode: state.active_mode,\n contextPct: state.context_pct,\n tokensUsed: state.tokens_estimated,\n tokensTotal: state.token_budget,\n agentsActive: state.agents_used,\n lastAgent: state.agents_used[state.agents_used.length - 1] || \"-\",\n lastOutput: state.last_output,\n taskProgress: state.task_progress,\n };\n}\n\nconst MODEL_CONTEXTS: Record<string, number> = {\n \"claude-sonnet-4.5\": 200_000,\n \"claude-sonnet-4\": 200_000,\n \"claude-sonnet-4.6\": 200_000,\n \"claude-opus-4.6\": 200_000,\n \"gpt-5\": 128_000,\n \"gpt-5.4-mini\": 128_000,\n \"gemini-3-pro\": 128_000,\n default: 200_000,\n};\n\nfunction resolveTokenBudget(model: string): number {\n return MODEL_CONTEXTS[model] ?? MODEL_CONTEXTS[\"default\"] ?? 200_000;\n}\n\nfunction resolvePremiumRequestsTotal(): number {\n const env = process.env[\"OMP_PREMIUM_REQUESTS_TOTAL\"];\n if (env) {\n const parsed = parseInt(env, 10);\n if (!isNaN(parsed) && parsed > 0) return parsed;\n }\n return 1500;\n}\n\nfunction processSessionStart(input: HookInput): HookOutput {\n const start = Date.now();\n const log: string[] = [];\n const sessionId = input.session_id || \"default\";\n const now = Date.now();\n const model = input.model || \"claude-sonnet-4.6\";\n\n const state: SessionState = {\n version: PKG_VERSION,\n session_id: sessionId,\n started_at: now,\n updated_at: now,\n model,\n tokens_estimated: 0,\n token_budget: resolveTokenBudget(model),\n context_pct: 0,\n tools_used: [],\n skills_used: [],\n agents_used: [],\n active_mode: null,\n last_output: \"\",\n task_progress: 0,\n status: \"idle\",\n premium_requests: 0,\n premium_requests_total: resolvePremiumRequestsTotal(),\n warning_active: false,\n };\n\n const statePath = getStatePath(sessionId);\n ensureDir(statePath);\n writeFileSync(statePath, JSON.stringify(state), \"utf-8\");\n log.push(`Session initialized: ${sessionId}`);\n\n const { line, state: hudState } = writeHudArtifacts(state);\n log.push(`HUD artifacts written: ${line}`);\n\n return {\n status: \"ok\",\n latencyMs: Date.now() - start,\n mutations: [{ type: \"emit_hud\", hudEmit: buildEmit(state) }],\n log: [...log, `HUD state version: ${hudState.version}`],\n };\n}\n\nfunction processPostToolUse(input: HookInput): HookOutput {\n const start = Date.now();\n const log: string[] = [];\n\n const statePath = getStatePath(input.session_id);\n let state: SessionState;\n\n try {\n const raw = JSON.parse(readFileSync(statePath, \"utf-8\"));\n state = {\n ...raw,\n version: typeof raw.version === \"string\" ? raw.version : PKG_VERSION,\n session_id: typeof raw.session_id === \"string\" ? raw.session_id : input.session_id || \"default\",\n started_at: typeof raw.started_at === \"number\" ? raw.started_at : Date.now(),\n updated_at: Date.now(),\n model: typeof raw.model === \"string\" ? raw.model : input.model || \"claude-sonnet-4.6\",\n tokens_estimated: typeof raw.tokens_estimated === \"number\" ? raw.tokens_estimated : 0,\n token_budget: typeof raw.token_budget === \"number\" ? raw.token_budget : resolveTokenBudget(typeof raw.model === \"string\" ? raw.model : input.model || \"claude-sonnet-4.6\"),\n context_pct: typeof raw.context_pct === \"number\" ? raw.context_pct : 0,\n tools_used: Array.isArray(raw.tools_used) ? raw.tools_used : [],\n skills_used: Array.isArray(raw.skills_used) ? raw.skills_used : [],\n agents_used: Array.isArray(raw.agents_used) ? raw.agents_used : [],\n active_mode: typeof raw.active_mode === \"string\" ? raw.active_mode : null,\n last_output: typeof raw.last_output === \"string\" ? raw.last_output : \"\",\n task_progress: typeof raw.task_progress === \"number\" ? raw.task_progress : 0,\n status: raw.status ?? \"running\",\n premium_requests: typeof raw.premium_requests === \"number\" ? raw.premium_requests : 0,\n premium_requests_total: typeof raw.premium_requests_total === \"number\" ? raw.premium_requests_total : resolvePremiumRequestsTotal(),\n warning_active: typeof raw.warning_active === \"boolean\" ? raw.warning_active : false,\n };\n } catch {\n return processSessionStart(input);\n }\n\n if (input.tool_name && !state.tools_used.includes(input.tool_name)) {\n state.tools_used.push(input.tool_name);\n }\n state.status = \"running\";\n state.last_output = stringifyOutput(input.tool_output);\n\n writeFileSync(statePath, JSON.stringify(state), \"utf-8\");\n const { line } = writeHudArtifacts(state);\n log.push(`HUD updated: ${line}`);\n\n return {\n status: \"ok\",\n latencyMs: Date.now() - start,\n mutations: [{ type: \"emit_hud\", hudEmit: buildEmit(state) }],\n log,\n };\n}\n\nexport function processHook(input: HookInput): HookOutput {\n if (input.hook_type === \"SessionStart\") {\n return processSessionStart(input);\n }\n if (input.hook_type === \"PostToolUse\") {\n return processPostToolUse(input);\n }\n return {\n status: \"skip\",\n latencyMs: 0,\n mutations: [],\n log: [\"Unknown hook type\"],\n };\n}\n\nimport { fileURLToPath } from \"url\";\n\nif (process.argv[1] === fileURLToPath(import.meta.url)) {\n const input: HookInput = JSON.parse(await readStdin());\n const output = processHook(input);\n console.log(JSON.stringify(output));\n}\n\nasync function readStdin(): Promise<string> {\n const chunks: string[] = [];\n for await (const chunk of process.stdin) {\n chunks.push(chunk);\n }\n return chunks.join(\"\");\n}\n", "/**\n * HUD statusline helpers and standalone entrypoint.\n *\n * Keeps HUD artifact generation in one place so hooks and shell wrappers\n * can share the same rendering and fallback behavior.\n */\n\nimport { mkdirSync, readFileSync, renameSync, writeFileSync } from \"fs\";\nimport { homedir } from \"os\";\nimport { dirname, join } from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { renderPlain, type HudState, type HudStatus } from \"./renderer.mts\";\n\nconst DEFAULT_VERSION = \"0.0.0\";\nconst DEFAULT_STATUSLINE = \"OMP | hud: no active session\";\nconst DEFAULT_TOKEN_BUDGET = 200_000;\nconst DEFAULT_PREMIUM_REQUESTS_TOTAL = 1500;\n\nexport interface StatuslinePaths {\n legacyLinePath: string;\n hudDir: string;\n statusJsonPath: string;\n displayPath: string;\n tmuxSegmentPath: string;\n}\n\nexport interface HudSnapshot {\n version?: string;\n session_id?: string;\n started_at?: number;\n updated_at?: number;\n model?: string;\n tokens_estimated?: number;\n token_budget?: number;\n context_pct?: number;\n tools_used?: string[];\n skills_used?: string[];\n agents_used?: string[];\n active_mode?: string | null;\n last_output?: string;\n task_progress?: number;\n status?: HudStatus;\n premium_requests?: number;\n premium_requests_total?: number;\n warning_active?: boolean;\n}\n\ninterface SerializedHudState extends Omit<HudState, \"toolsUsed\" | \"skillsUsed\"> {\n toolsUsed: string[];\n skillsUsed: string[];\n}\n\nexport function getStatuslinePaths(home = process.env[\"HOME\"] || homedir()): StatuslinePaths {\n const ompDir = join(home, \".omp\");\n const hudDir = join(ompDir, \"hud\");\n return {\n legacyLinePath: join(ompDir, \"hud.line\"),\n hudDir,\n statusJsonPath: join(hudDir, \"status.json\"),\n displayPath: join(hudDir, \"display.txt\"),\n tmuxSegmentPath: join(hudDir, \"tmux-segment.sh\"),\n };\n}\n\nfunction ensureParent(filePath: string): void {\n mkdirSync(dirname(filePath), { recursive: true });\n}\n\nfunction writeAtomic(filePath: string, content: string, mode?: number): void {\n ensureParent(filePath);\n const tempPath = `${filePath}.tmp`;\n writeFileSync(tempPath, content, mode === undefined ? \"utf-8\" : { encoding: \"utf-8\", mode });\n renameSync(tempPath, filePath);\n}\n\nfunction normalizeStringArray(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n return value.filter((item): item is string => typeof item === \"string\");\n}\n\nfunction serializeHudState(state: HudState): SerializedHudState {\n return {\n ...state,\n toolsUsed: Array.from(state.toolsUsed),\n skillsUsed: Array.from(state.skillsUsed),\n };\n}\n\nfunction deserializeHudState(raw: unknown): HudState | null {\n if (!raw || typeof raw !== \"object\") return null;\n const value = raw as Record<string, unknown>;\n const toolsUsed = new Set(normalizeStringArray(value.toolsUsed));\n const skillsUsed = new Set(normalizeStringArray(value.skillsUsed));\n const agentsActive = normalizeStringArray(value.agentsActive);\n const status = typeof value.status === \"string\" ? (value.status as HudStatus) : \"idle\";\n\n return {\n sessionId: typeof value.sessionId === \"string\" ? value.sessionId : \"default\",\n activeMode: typeof value.activeMode === \"string\" ? value.activeMode : null,\n activeModel: typeof value.activeModel === \"string\" ? value.activeModel : \"sonnet\",\n contextPct: typeof value.contextPct === \"number\" ? value.contextPct : 0,\n tokensUsed: typeof value.tokensUsed === \"number\" ? value.tokensUsed : 0,\n tokensTotal: typeof value.tokensTotal === \"number\" ? value.tokensTotal : DEFAULT_TOKEN_BUDGET,\n agentsActive,\n lastAgent: typeof value.lastAgent === \"string\" ? value.lastAgent : agentsActive.at(-1) ?? \"-\",\n lastOutput: typeof value.lastOutput === \"string\" ? value.lastOutput : \"\",\n taskProgress: typeof value.taskProgress === \"number\" ? value.taskProgress : 0,\n startedAt: typeof value.startedAt === \"number\" ? value.startedAt : Date.now(),\n updatedAt: typeof value.updatedAt === \"number\" ? value.updatedAt : Date.now(),\n version: typeof value.version === \"string\" ? value.version : DEFAULT_VERSION,\n status,\n sessionDurationMs: typeof value.sessionDurationMs === \"number\" ? value.sessionDurationMs : 0,\n cumulativeAgentsUsed: typeof value.cumulativeAgentsUsed === \"number\" ? value.cumulativeAgentsUsed : agentsActive.length,\n toolsUsed,\n skillsUsed,\n toolsTotal: typeof value.toolsTotal === \"number\" ? value.toolsTotal : 13,\n skillsTotal: typeof value.skillsTotal === \"number\" ? value.skillsTotal : 25,\n agentsTotal: typeof value.agentsTotal === \"number\" ? value.agentsTotal : 23,\n premiumRequests: typeof value.premiumRequests === \"number\" ? value.premiumRequests : 0,\n premiumRequestsTotal: typeof value.premiumRequestsTotal === \"number\" ? value.premiumRequestsTotal : DEFAULT_PREMIUM_REQUESTS_TOTAL,\n warningActive: typeof value.warningActive === \"boolean\" ? value.warningActive : false,\n };\n}\n\nexport function buildHudState(snapshot: HudSnapshot, now = Date.now()): HudState {\n const startedAt = snapshot.started_at ?? now;\n const updatedAt = snapshot.updated_at ?? now;\n const toolsUsed = new Set(normalizeStringArray(snapshot.tools_used));\n const skillsUsed = new Set(normalizeStringArray(snapshot.skills_used));\n const agentsActive = normalizeStringArray(snapshot.agents_used);\n\n return {\n sessionId: snapshot.session_id ?? \"default\",\n activeMode: snapshot.active_mode ?? null,\n activeModel: snapshot.model ?? \"sonnet\",\n contextPct: snapshot.context_pct ?? 0,\n tokensUsed: snapshot.tokens_estimated ?? 0,\n tokensTotal: snapshot.token_budget ?? DEFAULT_TOKEN_BUDGET,\n agentsActive,\n lastAgent: agentsActive.at(-1) ?? \"-\",\n lastOutput: snapshot.last_output ?? \"\",\n taskProgress: snapshot.task_progress ?? 0,\n startedAt,\n updatedAt,\n version: snapshot.version ?? DEFAULT_VERSION,\n status: snapshot.status ?? \"idle\",\n sessionDurationMs: Math.max(0, updatedAt - startedAt),\n cumulativeAgentsUsed: agentsActive.length,\n toolsUsed,\n skillsUsed,\n toolsTotal: 13,\n skillsTotal: 25,\n agentsTotal: 23,\n premiumRequests: snapshot.premium_requests ?? 0,\n premiumRequestsTotal: snapshot.premium_requests_total ?? DEFAULT_PREMIUM_REQUESTS_TOTAL,\n warningActive: snapshot.warning_active ?? false,\n };\n}\n\nexport function writeHudArtifacts(snapshot: HudSnapshot, paths = getStatuslinePaths()): { line: string; state: HudState; paths: StatuslinePaths } {\n const state = buildHudState(snapshot);\n const line = renderPlain(state);\n const serializedState = `${JSON.stringify(serializeHudState(state), null, 2)}\\n`;\n\n writeAtomic(paths.statusJsonPath, serializedState);\n writeAtomic(paths.displayPath, `${line}\\n`);\n writeAtomic(paths.tmuxSegmentPath, `${line}\\n`, 0o755);\n writeAtomic(paths.legacyLinePath, `${line}\\n`);\n\n return { line, state, paths };\n}\n\nexport function readStatusline(paths = getStatuslinePaths()): string {\n try {\n const line = readFileSync(paths.displayPath, \"utf-8\").trim();\n if (line) return line;\n } catch {\n // Fall through to other sources.\n }\n\n try {\n const parsed = JSON.parse(readFileSync(paths.statusJsonPath, \"utf-8\"));\n const state = deserializeHudState(parsed);\n if (state) return renderPlain(state);\n } catch {\n // Fall through to legacy file.\n }\n\n try {\n const line = readFileSync(paths.legacyLinePath, \"utf-8\").trim();\n if (line) return line;\n } catch {\n // No HUD artifacts yet.\n }\n\n return DEFAULT_STATUSLINE;\n}\n\nif (process.argv[1] === fileURLToPath(import.meta.url)) {\n console.log(readStatusline());\n}\n", "/**\n * HUD Renderer\n * Formats HudState into ANSI or plain text status lines.\n */\n\n\nexport interface HudState {\n sessionId: string;\n activeMode: string | null;\n activeModel: string;\n contextPct: number;\n tokensUsed: number;\n tokensTotal: number;\n agentsActive: string[];\n lastAgent: string;\n lastOutput: string;\n taskProgress: number;\n startedAt: number;\n updatedAt: number;\n version: string;\n status: HudStatus;\n sessionDurationMs: number;\n cumulativeAgentsUsed: number;\n toolsUsed: Set<string>;\n skillsUsed: Set<string>;\n toolsTotal: number;\n skillsTotal: number;\n agentsTotal: number;\n premiumRequests: number;\n premiumRequestsTotal: number;\n warningActive: boolean;\n}\n\nexport type HudStatus = \"idle\" | \"running\" | \"waiting\" | \"complete\" | \"error\" | \"eco\";\n\nconst STATUS_ICONS: Record<HudStatus, string> = {\n idle: \"\u25CB\",\n running: \"\u25CF\",\n waiting: \"\u25F7\",\n complete: \"\u2713\",\n error: \"\u2717\",\n eco: \"\u26A1\",\n};\n\nfunction formatAge(startedAt: number): string {\n const elapsed = Date.now() - startedAt;\n const mins = Math.floor(elapsed / 60000);\n if (mins < 60) return `${mins}m`;\n const hours = Math.floor(mins / 60);\n const remainingMins = mins % 60;\n return `${hours}h${remainingMins}m`;\n}\n\nfunction formatTokens(tokens: number): string {\n if (tokens >= 1_000_000) return `${(tokens / 1_000_000).toFixed(1)}M`;\n if (tokens >= 1_000) return `${(tokens / 1_000).toFixed(1)}k`;\n return `${tokens}`;\n}\n\nfunction ctxColor(pct: number): string {\n if (pct < 60) return \"\\x1b[32m\"; // green\n if (pct < 85) return \"\\x1b[33m\"; // yellow\n return \"\\x1b[31m\"; // red\n}\n\nfunction reset(): string {\n return \"\\x1b[0m\";\n}\n\n/**\n * Render HUD line with ANSI color codes.\n * Format: [OMP v1.0.0] mode | model | ctx:N% | tok:~Nk/Nk | Nm | tools:N/N | skills:N/N | agents:N/N | N% status\n */\nexport function renderAnsi(state: HudState): string {\n const age = formatAge(state.startedAt);\n const tokens = formatTokens(state.tokensUsed);\n const ctx = state.contextPct;\n const mode = state.activeMode || \"-\";\n const model = state.activeModel || \"sonnet\";\n const icon = STATUS_ICONS[state.status] || \"\u25CF\";\n\n const ctxClr = ctxColor(ctx);\n const ctxStr = `${ctxClr}ctx:${ctx}%${reset()}`;\n const tokenStr = `tok:~${tokens}/${state.tokensTotal}`;\n const modeStr = mode === \"-\" ? \"-\" : `\\x1b[36m${mode}${reset()}`; // cyan for active modes\n\n const reqWarning = state.warningActive ? \" !!\" : \"\";\n const reqStr = `req:${state.premiumRequests ?? 0}/${state.premiumRequestsTotal ?? 1500}${reqWarning}`;\n\n return `[OMP v${state.version}] ${modeStr} | ${model} | ${ctxStr} | ${tokenStr} | ${reqStr} | ${age} | tools:${state.toolsUsed?.size || 0}/${state.toolsTotal ?? 13} | skills:${state.skillsUsed?.size || 0}/${state.skillsTotal ?? 25} | agents:${state.cumulativeAgentsUsed}/${state.agentsTotal ?? 23} | ${icon} ${state.status}`;\n}\n\n/**\n * Render HUD line as plain text (no ANSI codes).\n * Format: [OMP v1.0.0] mode | model | ctx:N% | tok:~Nk/Nk | Nm | tools:N/N | skills:N/N | agents:N/N | N% status\n */\nexport function renderPlain(state: HudState): string {\n const age = formatAge(state.startedAt);\n const tokens = formatTokens(state.tokensUsed);\n const ctx = state.contextPct;\n const mode = state.activeMode || \"-\";\n const model = state.activeModel || \"sonnet\";\n\n const reqWarningPlain = state.warningActive ? \" !!\" : \"\";\n const reqStrPlain = `req:${state.premiumRequests ?? 0}/${state.premiumRequestsTotal ?? 1500}${reqWarningPlain}`;\n\n return `[OMP v${state.version}] ${mode} | ${model} | ctx:${ctx}% | tok:~${tokens}/${state.tokensTotal} | ${reqStrPlain} | ${age} | tools:${state.toolsUsed?.size || 0}/${state.toolsTotal ?? 13} | skills:${state.skillsUsed?.size || 0}/${state.skillsTotal ?? 25} | agents:${state.cumulativeAgentsUsed}/${state.agentsTotal ?? 23} | ${state.status}`;\n}\n"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["/**\n * hud-emitter hook\n * Trigger: post-cycle (PostToolUse + SessionStart)\n * Priority: 60\n *\n * Writes HUD artifacts after every tool call and initializes session state.\n */\n\nimport { mkdirSync, readFileSync, writeFileSync } from \"fs\";\nimport { createRequire } from \"module\";\nimport { homedir } from \"os\";\nimport { join } from \"path\";\nimport { writeHudArtifacts } from \"../hud/statusline.mts\";\n\nconst _require = createRequire(import.meta.url);\nconst { version: PKG_VERSION } = _require(\"../../package.json\") as { version: string };\n\nexport interface HookInput {\n hook_type: \"SessionStart\" | \"PostToolUse\";\n tool_name?: string;\n tool_input?: unknown;\n tool_output?: unknown;\n session_id?: string;\n model?: string;\n}\n\nexport interface HookOutput {\n status: \"ok\" | \"skip\" | \"error\";\n latencyMs: number;\n mutations: Array<{ type: \"emit_hud\"; hudEmit: HudEmit } | { type: \"log\"; level: \"info\"; message: string }>;\n log: string[];\n}\n\nexport interface HudEmit {\n sessionId: string;\n activeMode: string | null;\n contextPct: number;\n tokensUsed: number;\n tokensTotal: number;\n agentsActive: string[];\n lastAgent: string;\n lastOutput: string;\n taskProgress: number;\n}\n\ninterface SessionState {\n version: string;\n session_id: string;\n started_at: number;\n updated_at: number;\n model: string;\n tokens_estimated: number;\n token_budget: number;\n context_pct: number;\n tools_used: string[];\n skills_used: string[];\n agents_used: string[];\n active_mode: string | null;\n last_output: string;\n task_progress: number;\n status: \"idle\" | \"running\" | \"waiting\" | \"complete\" | \"error\" | \"eco\";\n premium_requests: number;\n premium_requests_total: number;\n warning_active: boolean;\n}\n\nfunction getStatePath(sessionId?: string): string {\n const base = join(process.env[\"HOME\"] || homedir(), \".omp\", \"state\");\n if (sessionId) {\n return join(base, \"sessions\", sessionId, \"session.json\");\n }\n return join(base, \"session.json\");\n}\n\nfunction ensureDir(path: string): void {\n mkdirSync(path.substring(0, path.lastIndexOf(\"/\")), { recursive: true });\n}\n\nfunction stringifyOutput(value: unknown): string {\n if (typeof value === \"string\") {\n return value.trim().slice(0, 200);\n }\n if (value === undefined || value === null) {\n return \"\";\n }\n try {\n return JSON.stringify(value).slice(0, 200);\n } catch {\n return String(value).slice(0, 200);\n }\n}\n\nfunction buildEmit(state: SessionState): HudEmit {\n return {\n sessionId: state.session_id,\n activeMode: state.active_mode,\n contextPct: state.context_pct,\n tokensUsed: state.tokens_estimated,\n tokensTotal: state.token_budget,\n agentsActive: state.agents_used,\n lastAgent: state.agents_used[state.agents_used.length - 1] || \"-\",\n lastOutput: state.last_output,\n taskProgress: state.task_progress,\n };\n}\n\nconst MODEL_CONTEXTS: Record<string, number> = {\n \"claude-sonnet-4.5\": 200_000,\n \"claude-sonnet-4\": 200_000,\n \"claude-sonnet-4.6\": 200_000,\n \"claude-opus-4.6\": 200_000,\n \"gpt-5\": 128_000,\n \"gpt-5.4-mini\": 128_000,\n \"gemini-3-pro\": 128_000,\n default: 200_000,\n};\n\nfunction resolveTokenBudget(model: string): number {\n return MODEL_CONTEXTS[model] ?? MODEL_CONTEXTS[\"default\"] ?? 200_000;\n}\n\nfunction resolvePremiumRequestsTotal(): number {\n const env = process.env[\"OMP_PREMIUM_REQUESTS_TOTAL\"];\n if (env) {\n const parsed = parseInt(env, 10);\n if (!isNaN(parsed) && parsed > 0) return parsed;\n }\n return 1500;\n}\n\nfunction processSessionStart(input: HookInput): HookOutput {\n const start = Date.now();\n const log: string[] = [];\n const sessionId = input.session_id || \"default\";\n const now = Date.now();\n const model = input.model || \"claude-sonnet-4.6\";\n\n const state: SessionState = {\n version: PKG_VERSION,\n session_id: sessionId,\n started_at: now,\n updated_at: now,\n model,\n tokens_estimated: 0,\n token_budget: resolveTokenBudget(model),\n context_pct: 0,\n tools_used: [],\n skills_used: [],\n agents_used: [],\n active_mode: null,\n last_output: \"\",\n task_progress: 0,\n status: \"idle\",\n premium_requests: 0,\n premium_requests_total: resolvePremiumRequestsTotal(),\n warning_active: false,\n };\n\n const statePath = getStatePath(sessionId);\n ensureDir(statePath);\n writeFileSync(statePath, JSON.stringify(state), \"utf-8\");\n log.push(`Session initialized: ${sessionId}`);\n\n const { line, state: hudState } = writeHudArtifacts(state);\n log.push(`HUD artifacts written: ${line}`);\n\n return {\n status: \"ok\",\n latencyMs: Date.now() - start,\n mutations: [{ type: \"emit_hud\", hudEmit: buildEmit(state) }],\n log: [...log, `HUD state version: ${hudState.version}`],\n };\n}\n\nfunction processPostToolUse(input: HookInput): HookOutput {\n const start = Date.now();\n const log: string[] = [];\n\n const statePath = getStatePath(input.session_id);\n let state: SessionState;\n\n try {\n const raw = JSON.parse(readFileSync(statePath, \"utf-8\"));\n state = {\n ...raw,\n version: typeof raw.version === \"string\" ? raw.version : PKG_VERSION,\n session_id: typeof raw.session_id === \"string\" ? raw.session_id : input.session_id || \"default\",\n started_at: typeof raw.started_at === \"number\" ? raw.started_at : Date.now(),\n updated_at: Date.now(),\n model: typeof raw.model === \"string\" ? raw.model : input.model || \"claude-sonnet-4.6\",\n tokens_estimated: typeof raw.tokens_estimated === \"number\" ? raw.tokens_estimated : 0,\n token_budget: typeof raw.token_budget === \"number\" ? raw.token_budget : resolveTokenBudget(typeof raw.model === \"string\" ? raw.model : input.model || \"claude-sonnet-4.6\"),\n context_pct: typeof raw.context_pct === \"number\" ? raw.context_pct : 0,\n tools_used: Array.isArray(raw.tools_used) ? raw.tools_used : [],\n skills_used: Array.isArray(raw.skills_used) ? raw.skills_used : [],\n agents_used: Array.isArray(raw.agents_used) ? raw.agents_used : [],\n active_mode: typeof raw.active_mode === \"string\" ? raw.active_mode : null,\n last_output: typeof raw.last_output === \"string\" ? raw.last_output : \"\",\n task_progress: typeof raw.task_progress === \"number\" ? raw.task_progress : 0,\n status: raw.status ?? \"running\",\n premium_requests: typeof raw.premium_requests === \"number\" ? raw.premium_requests : 0,\n premium_requests_total: typeof raw.premium_requests_total === \"number\" ? raw.premium_requests_total : resolvePremiumRequestsTotal(),\n warning_active: typeof raw.warning_active === \"boolean\" ? raw.warning_active : false,\n };\n } catch {\n return processSessionStart(input);\n }\n\n if (input.tool_name && !state.tools_used.includes(input.tool_name)) {\n state.tools_used.push(input.tool_name);\n }\n state.status = \"running\";\n state.last_output = stringifyOutput(input.tool_output);\n\n writeFileSync(statePath, JSON.stringify(state), \"utf-8\");\n const { line } = writeHudArtifacts(state);\n log.push(`HUD updated: ${line}`);\n\n return {\n status: \"ok\",\n latencyMs: Date.now() - start,\n mutations: [{ type: \"emit_hud\", hudEmit: buildEmit(state) }],\n log,\n };\n}\n\nexport function processHook(input: HookInput): HookOutput {\n if (input.hook_type === \"SessionStart\") {\n return processSessionStart(input);\n }\n if (input.hook_type === \"PostToolUse\") {\n return processPostToolUse(input);\n }\n return {\n status: \"skip\",\n latencyMs: 0,\n mutations: [],\n log: [\"Unknown hook type\"],\n };\n}\n\nimport { fileURLToPath } from \"url\";\n\nif (process.argv[1] === fileURLToPath(import.meta.url)) {\n const input: HookInput = JSON.parse(await readStdin());\n const output = processHook(input);\n console.log(JSON.stringify(output));\n}\n\nasync function readStdin(): Promise<string> {\n const chunks: string[] = [];\n for await (const chunk of process.stdin) {\n chunks.push(chunk);\n }\n return chunks.join(\"\");\n}\n", "/**\n * HUD statusline helpers and standalone entrypoint.\n *\n * Keeps HUD artifact generation in one place so hooks and shell wrappers\n * can share the same rendering and fallback behavior.\n */\n\nimport { mkdirSync, readFileSync, renameSync, writeFileSync } from \"fs\";\nimport { homedir } from \"os\";\nimport { dirname, join } from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { renderPlain, type HudState, type HudStatus } from \"./renderer.mts\";\n\nconst DEFAULT_VERSION = \"0.0.0\";\nconst DEFAULT_STATUSLINE = \"OMP | hud: no active session\";\nconst DEFAULT_TOKEN_BUDGET = 200_000;\nconst DEFAULT_PREMIUM_REQUESTS_TOTAL = 1500;\n\nexport interface StatuslinePaths {\n legacyLinePath: string;\n hudDir: string;\n statusJsonPath: string;\n displayPath: string;\n tmuxSegmentPath: string;\n}\n\nexport interface HudSnapshot {\n version?: string;\n session_id?: string;\n started_at?: number;\n updated_at?: number;\n model?: string;\n tokens_estimated?: number;\n token_budget?: number;\n context_pct?: number;\n tools_used?: string[];\n skills_used?: string[];\n agents_used?: string[];\n active_mode?: string | null;\n last_output?: string;\n task_progress?: number;\n status?: HudStatus;\n premium_requests?: number;\n premium_requests_total?: number;\n warning_active?: boolean;\n}\n\ninterface SerializedHudState extends Omit<HudState, \"toolsUsed\" | \"skillsUsed\"> {\n toolsUsed: string[];\n skillsUsed: string[];\n}\n\nexport function getStatuslinePaths(home = process.env[\"HOME\"] || homedir()): StatuslinePaths {\n const ompDir = join(home, \".omp\");\n const hudDir = join(ompDir, \"hud\");\n return {\n legacyLinePath: join(ompDir, \"hud.line\"),\n hudDir,\n statusJsonPath: join(hudDir, \"status.json\"),\n displayPath: join(hudDir, \"display.txt\"),\n tmuxSegmentPath: join(hudDir, \"tmux-segment.sh\"),\n };\n}\n\nfunction ensureParent(filePath: string): void {\n mkdirSync(dirname(filePath), { recursive: true });\n}\n\nfunction writeAtomic(filePath: string, content: string, mode?: number): void {\n ensureParent(filePath);\n const tempPath = `${filePath}.tmp`;\n writeFileSync(tempPath, content, mode === undefined ? \"utf-8\" : { encoding: \"utf-8\", mode });\n renameSync(tempPath, filePath);\n}\n\nfunction normalizeStringArray(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n return value.filter((item): item is string => typeof item === \"string\");\n}\n\nfunction serializeHudState(state: HudState): SerializedHudState {\n return {\n ...state,\n toolsUsed: Array.from(state.toolsUsed),\n skillsUsed: Array.from(state.skillsUsed),\n };\n}\n\nfunction deserializeHudState(raw: unknown): HudState | null {\n if (!raw || typeof raw !== \"object\") return null;\n const value = raw as Record<string, unknown>;\n const toolsUsed = new Set(normalizeStringArray(value.toolsUsed));\n const skillsUsed = new Set(normalizeStringArray(value.skillsUsed));\n const agentsActive = normalizeStringArray(value.agentsActive);\n const status = typeof value.status === \"string\" ? (value.status as HudStatus) : \"idle\";\n\n return {\n sessionId: typeof value.sessionId === \"string\" ? value.sessionId : \"default\",\n activeMode: typeof value.activeMode === \"string\" ? value.activeMode : null,\n activeModel: typeof value.activeModel === \"string\" ? value.activeModel : \"sonnet\",\n contextPct: typeof value.contextPct === \"number\" ? value.contextPct : 0,\n tokensUsed: typeof value.tokensUsed === \"number\" ? value.tokensUsed : 0,\n tokensTotal: typeof value.tokensTotal === \"number\" ? value.tokensTotal : DEFAULT_TOKEN_BUDGET,\n agentsActive,\n lastAgent: typeof value.lastAgent === \"string\" ? value.lastAgent : agentsActive.at(-1) ?? \"-\",\n lastOutput: typeof value.lastOutput === \"string\" ? value.lastOutput : \"\",\n taskProgress: typeof value.taskProgress === \"number\" ? value.taskProgress : 0,\n startedAt: typeof value.startedAt === \"number\" ? value.startedAt : Date.now(),\n updatedAt: typeof value.updatedAt === \"number\" ? value.updatedAt : Date.now(),\n version: typeof value.version === \"string\" ? value.version : DEFAULT_VERSION,\n status,\n sessionDurationMs: typeof value.sessionDurationMs === \"number\" ? value.sessionDurationMs : 0,\n cumulativeAgentsUsed: typeof value.cumulativeAgentsUsed === \"number\" ? value.cumulativeAgentsUsed : agentsActive.length,\n toolsUsed,\n skillsUsed,\n toolsTotal: typeof value.toolsTotal === \"number\" ? value.toolsTotal : 13,\n skillsTotal: typeof value.skillsTotal === \"number\" ? value.skillsTotal : 25,\n agentsTotal: typeof value.agentsTotal === \"number\" ? value.agentsTotal : 23,\n premiumRequests: typeof value.premiumRequests === \"number\" ? value.premiumRequests : 0,\n premiumRequestsTotal: typeof value.premiumRequestsTotal === \"number\" ? value.premiumRequestsTotal : DEFAULT_PREMIUM_REQUESTS_TOTAL,\n warningActive: typeof value.warningActive === \"boolean\" ? value.warningActive : false,\n };\n}\n\nexport function buildHudState(snapshot: HudSnapshot, now = Date.now()): HudState {\n const startedAt = snapshot.started_at ?? now;\n const updatedAt = snapshot.updated_at ?? now;\n const toolsUsed = new Set(normalizeStringArray(snapshot.tools_used));\n const skillsUsed = new Set(normalizeStringArray(snapshot.skills_used));\n const agentsActive = normalizeStringArray(snapshot.agents_used);\n\n return {\n sessionId: snapshot.session_id ?? \"default\",\n activeMode: snapshot.active_mode ?? null,\n activeModel: snapshot.model ?? \"sonnet\",\n contextPct: snapshot.context_pct ?? 0,\n tokensUsed: snapshot.tokens_estimated ?? 0,\n tokensTotal: snapshot.token_budget ?? DEFAULT_TOKEN_BUDGET,\n agentsActive,\n lastAgent: agentsActive.at(-1) ?? \"-\",\n lastOutput: snapshot.last_output ?? \"\",\n taskProgress: snapshot.task_progress ?? 0,\n startedAt,\n updatedAt,\n version: snapshot.version ?? DEFAULT_VERSION,\n status: snapshot.status ?? \"idle\",\n sessionDurationMs: Math.max(0, updatedAt - startedAt),\n cumulativeAgentsUsed: agentsActive.length,\n toolsUsed,\n skillsUsed,\n toolsTotal: 13,\n skillsTotal: 25,\n agentsTotal: 23,\n premiumRequests: snapshot.premium_requests ?? 0,\n premiumRequestsTotal: snapshot.premium_requests_total ?? DEFAULT_PREMIUM_REQUESTS_TOTAL,\n warningActive: snapshot.warning_active ?? false,\n };\n}\n\nexport function writeHudArtifacts(snapshot: HudSnapshot, paths = getStatuslinePaths()): { line: string; state: HudState; paths: StatuslinePaths } {\n const state = buildHudState(snapshot);\n const line = renderPlain(state);\n const serializedState = `${JSON.stringify(serializeHudState(state), null, 2)}\\n`;\n\n writeAtomic(paths.statusJsonPath, serializedState);\n writeAtomic(paths.displayPath, `${line}\\n`);\n writeAtomic(paths.tmuxSegmentPath, `${line}\\n`, 0o755);\n writeAtomic(paths.legacyLinePath, `${line}\\n`);\n\n return { line, state, paths };\n}\n\nexport function readStatusline(paths = getStatuslinePaths()): string {\n // Try live render from status.json \u2014 formatAge runs at call time, not hook-fire time\n try {\n const parsed = JSON.parse(readFileSync(paths.statusJsonPath, \"utf-8\"));\n const state = deserializeHudState(parsed);\n if (state) return renderPlain(state);\n } catch {\n // Fall through to cached display string.\n }\n\n // Fallback: pre-rendered cached string (written by hud-emitter; used by tmux consumers)\n try {\n const line = readFileSync(paths.displayPath, \"utf-8\").trim();\n if (line) return line;\n } catch {\n // Fall through to legacy file.\n }\n\n try {\n const line = readFileSync(paths.legacyLinePath, \"utf-8\").trim();\n if (line) return line;\n } catch {}\n\n return DEFAULT_STATUSLINE;\n}\n\nif (process.argv[1] === fileURLToPath(import.meta.url)) {\n console.log(readStatusline());\n}\n", "/**\n * HUD Renderer\n * Formats HudState into ANSI or plain text status lines.\n */\n\n\nexport interface HudState {\n sessionId: string;\n activeMode: string | null;\n activeModel: string;\n contextPct: number;\n tokensUsed: number;\n tokensTotal: number;\n agentsActive: string[];\n lastAgent: string;\n lastOutput: string;\n taskProgress: number;\n startedAt: number;\n updatedAt: number;\n version: string;\n status: HudStatus;\n sessionDurationMs: number;\n cumulativeAgentsUsed: number;\n toolsUsed: Set<string>;\n skillsUsed: Set<string>;\n toolsTotal: number;\n skillsTotal: number;\n agentsTotal: number;\n premiumRequests: number;\n premiumRequestsTotal: number;\n warningActive: boolean;\n}\n\nexport type HudStatus = \"idle\" | \"running\" | \"waiting\" | \"complete\" | \"error\" | \"eco\";\n\nconst STATUS_ICONS: Record<HudStatus, string> = {\n idle: \"\u25CB\",\n running: \"\u25CF\",\n waiting: \"\u25F7\",\n complete: \"\u2713\",\n error: \"\u2717\",\n eco: \"\u26A1\",\n};\n\nfunction formatAge(startedAt: number): string {\n const elapsed = Date.now() - startedAt;\n const mins = Math.floor(elapsed / 60000);\n if (mins < 60) return `${mins}m`;\n const hours = Math.floor(mins / 60);\n const remainingMins = mins % 60;\n return `${hours}h${remainingMins}m`;\n}\n\nfunction formatTokens(tokens: number): string {\n if (tokens >= 1_000_000) return `${(tokens / 1_000_000).toFixed(1)}M`;\n if (tokens >= 1_000) return `${(tokens / 1_000).toFixed(1)}k`;\n return `${tokens}`;\n}\n\nfunction ctxColor(pct: number): string {\n if (pct < 60) return \"\\x1b[32m\"; // green\n if (pct < 85) return \"\\x1b[33m\"; // yellow\n return \"\\x1b[31m\"; // red\n}\n\nfunction reset(): string {\n return \"\\x1b[0m\";\n}\n\n/**\n * Render HUD line with ANSI color codes.\n * Format: [OMP v1.0.0] mode | model | ctx:N% | tok:~Nk/Nk | Nm | tools:N/N | skills:N/N | agents:N/N | N% status\n */\nexport function renderAnsi(state: HudState): string {\n const age = formatAge(state.startedAt);\n const tokens = formatTokens(state.tokensUsed);\n const ctx = state.contextPct;\n const mode = state.activeMode || \"-\";\n const model = state.activeModel || \"sonnet\";\n const icon = STATUS_ICONS[state.status] || \"\u25CF\";\n\n const ctxClr = ctxColor(ctx);\n const ctxStr = `${ctxClr}ctx:${ctx}%${reset()}`;\n const tokenStr = `tok:~${tokens}/${state.tokensTotal}`;\n const modeStr = mode === \"-\" ? \"-\" : `\\x1b[36m${mode}${reset()}`; // cyan for active modes\n\n const reqWarning = state.warningActive ? \" !!\" : \"\";\n const reqStr = `req:${state.premiumRequests ?? 0}/${state.premiumRequestsTotal ?? 1500}${reqWarning}`;\n\n return `[OMP v${state.version}] ${modeStr} | ${model} | ${ctxStr} | ${tokenStr} | ${reqStr} | ${age} | tools:${state.toolsUsed?.size || 0}/${state.toolsTotal ?? 13} | skills:${state.skillsUsed?.size || 0}/${state.skillsTotal ?? 25} | agents:${state.cumulativeAgentsUsed}/${state.agentsTotal ?? 23} | ${icon} ${state.status}`;\n}\n\n/**\n * Render HUD line as plain text (no ANSI codes).\n * Format: [OMP v1.0.0] mode | model | ctx:N% | tok:~Nk/Nk | Nm | tools:N/N | skills:N/N | agents:N/N | N% status\n */\nexport function renderPlain(state: HudState): string {\n const age = formatAge(state.startedAt);\n const tokens = formatTokens(state.tokensUsed);\n const ctx = state.contextPct;\n const mode = state.activeMode || \"-\";\n const model = state.activeModel || \"sonnet\";\n\n const reqWarningPlain = state.warningActive ? \" !!\" : \"\";\n const reqStrPlain = `req:${state.premiumRequests ?? 0}/${state.premiumRequestsTotal ?? 1500}${reqWarningPlain}`;\n\n return `[OMP v${state.version}] ${mode} | ${model} | ctx:${ctx}% | tok:~${tokens}/${state.tokensTotal} | ${reqStrPlain} | ${age} | tools:${state.toolsUsed?.size || 0}/${state.toolsTotal ?? 13} | skills:${state.skillsUsed?.size || 0}/${state.skillsTotal ?? 25} | agents:${state.cumulativeAgentsUsed}/${state.agentsTotal ?? 23} | ${state.status}`;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["mkdirSync", "readFileSync", "writeFileSync", "homedir", "join", "fileURLToPath", "join", "homedir", "mkdirSync", "writeFileSync", "readFileSync"]
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "oh-my-githubcopilot",
|
|
3
|
-
"version": "1.8.1-alpha.
|
|
3
|
+
"version": "1.8.1-alpha.ed20e27",
|
|
4
4
|
"description": "Multi-agent orchestration for GitHub Copilot CLI. 23 agents, 39 skills, parallel execution, HUD, PSM, SWE-bench.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "r3dlex"
|