oh-my-githubcopilot 1.8.1 → 2.0.0-alpha.1cd01f4

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.
Files changed (60) hide show
  1. package/.claude-plugin/plugin.json +23 -3
  2. package/AGENTS.md +29 -25
  3. package/CHANGELOG.md +49 -336
  4. package/README.md +7 -2
  5. package/agents/code-reviewer.agent.md +5 -0
  6. package/agents/{simplifier.agent.md → code-simplifier.agent.md} +2 -2
  7. package/agents/debugger.agent.md +1 -1
  8. package/agents/document-specialist.agent.md +6 -1
  9. package/agents/{explorer.agent.md → explore.agent.md} +2 -2
  10. package/agents/security-reviewer.agent.md +1 -1
  11. package/agents/test-engineer.agent.md +3 -1
  12. package/bin/omp-statusline.mjs +12 -11
  13. package/bin/omp-statusline.mjs.map +2 -2
  14. package/bin/omp.mjs +885 -42
  15. package/bin/omp.mjs.map +4 -4
  16. package/dist/hooks/delegation-enforcer.mjs +65 -13
  17. package/dist/hooks/delegation-enforcer.mjs.map +4 -4
  18. package/dist/hooks/hud-emitter.mjs +80 -28
  19. package/dist/hooks/hud-emitter.mjs.map +4 -4
  20. package/dist/hooks/keyword-detector.mjs +117 -11
  21. package/dist/hooks/keyword-detector.mjs.map +4 -4
  22. package/dist/hooks/model-router.mjs +64 -12
  23. package/dist/hooks/model-router.mjs.map +4 -4
  24. package/dist/hooks/stop-continuation.mjs +66 -14
  25. package/dist/hooks/stop-continuation.mjs.map +4 -4
  26. package/dist/hooks/token-tracker.mjs +81 -19
  27. package/dist/hooks/token-tracker.mjs.map +4 -4
  28. package/dist/mcp/server.mjs +17 -16
  29. package/dist/mcp/server.mjs.map +2 -2
  30. package/extension/extension.mjs +659 -0
  31. package/hooks/hooks.json +6 -6
  32. package/package.json +3 -2
  33. package/plugin.json +23 -3
  34. package/skills/build-fix/SKILL.md +35 -0
  35. package/skills/cancel/SKILL.md +33 -0
  36. package/skills/ccg/SKILL.md +37 -0
  37. package/skills/code-review/SKILL.md +33 -0
  38. package/skills/deep-dive/SKILL.md +33 -0
  39. package/skills/deepinit/SKILL.md +33 -0
  40. package/skills/deepsearch/SKILL.md +33 -0
  41. package/skills/design/SKILL.md +37 -0
  42. package/skills/external-context/SKILL.md +33 -0
  43. package/skills/help/SKILL.md +33 -0
  44. package/skills/omp-doctor/SKILL.md +23 -1
  45. package/skills/omp-reference/SKILL.md +20 -24
  46. package/skills/remember/SKILL.md +39 -0
  47. package/skills/research/SKILL.md +1 -1
  48. package/skills/sciomc/SKILL.md +35 -0
  49. package/skills/security-review/SKILL.md +33 -0
  50. package/skills/self-improve/SKILL.md +35 -0
  51. package/skills/ultragoal/SKILL.md +33 -0
  52. package/skills/ultraqa/SKILL.md +33 -0
  53. package/skills/verify/SKILL.md +33 -0
  54. package/skills/visual-verdict/SKILL.md +35 -0
  55. package/skills/web-clone/SKILL.md +35 -0
  56. package/skills/writer-memory/SKILL.md +37 -0
  57. package/agents/orchestrator.agent.md +0 -26
  58. package/agents/researcher.agent.md +0 -18
  59. package/agents/reviewer.agent.md +0 -23
  60. package/agents/tester.agent.md +0 -20
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/cli/doctor.mts", "../src/hooks/runner.mts", "../src/hooks/keyword-detector.mts", "../src/extension/commands.mts", "../src/extension/registry.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 ?? 19} | ${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 ?? 19} | ${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\";\n/** Fallback line when no HUD artifacts exist. Mirrored in extension/extension.mjs. */\nexport const 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 : 59,\n agentsTotal: typeof value.agentsTotal === \"number\" ? value.agentsTotal : 19,\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: 59,\n agentsTotal: 19,\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 // Fall through to default statusline.\n }\n\n return DEFAULT_STATUSLINE;\n}\n\n// Only emit when executed as the statusline entry itself. The bundle-name\n// check prevents this from firing inside other bundles (e.g. hud-emitter.mjs)\n// that inline this module \u2014 hooks must emit exactly one JSON object on stdout.\nif (\n process.argv[1] === fileURLToPath(import.meta.url) &&\n (process.argv[1].endsWith(\"omp-statusline.mjs\") || process.argv[1].endsWith(\"statusline.mts\"))\n) {\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 1s (default)\n * OMP_HUD_POLL_MS=500 omp hud --watch Override interval (ms)\n * OMP_HUD_INTERVAL=5000 omp hud --watch Legacy alias, lower precedence\n *\n * Fallback renderer #3 (SPEC-omp-2.0 \u00A75): the canvas HUD (renderer #1) is\n * event-pushed; this daemon and the tmux statusline (#2) poll.\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 = 1_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_POLL_MS env var (milliseconds, default 1000); the legacy\n * OMP_HUD_INTERVAL alias is honored at lower precedence.\n */\nexport function runHudWatch(): void {\n const intervalMs = Math.max(\n 500,\n parseInt(process.env[\"OMP_HUD_POLL_MS\"] ?? \"\", 10) ||\n parseInt(process.env[\"OMP_HUD_INTERVAL\"] ?? \"\", 10) ||\n 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 * omp doctor \u2014 installation and migration diagnostics.\n *\n * OMP 2.0 agent-parity migration check: scans the project's config files\n * (.github/copilot-instructions.md, AGENTS.md, .omg/ state) for stale agent\n * IDs that were renamed or dropped in 2.0 and prints suggested replacements.\n */\n\nimport { existsSync, readFileSync, readdirSync, statSync } from \"fs\";\nimport { join, relative } from \"path\";\n\n/** Stale agent ID \u2192 suggested replacement (OMP 2.0 agent parity). */\nexport const AGENT_MIGRATIONS: Record<string, string> = {\n explorer: \"explore\",\n simplifier: \"code-simplifier\",\n researcher: \"document-specialist\",\n reviewer: \"code-reviewer\",\n tester: \"test-engineer\",\n orchestrator: \"top-level orchestration role (no longer a delegatable agent)\",\n};\n\nexport interface StaleAgentWarning {\n file: string;\n line: number;\n staleId: string;\n replacement: string;\n text: string;\n}\n\n// Matches @-mentions of stale agent IDs as whole words. The lookarounds keep\n// hyphenated IDs intact: \"@qa-tester\", \"@code-reviewer\", \"@security-reviewer\"\n// and \"@code-simplifier\" never match.\nconst STALE_AGENT_PATTERN = /(?<![\\w-])@(explorer|simplifier|researcher|reviewer|tester|orchestrator)(?![\\w-])/g;\n\n/** Files scanned relative to the project root. */\nconst SCAN_FILES = [\n \".github/copilot-instructions.md\",\n \".copilot/copilot-instructions.md\",\n \"AGENTS.md\",\n];\n\n/** Directories scanned recursively (state dirs) relative to the project root. */\nconst SCAN_DIRS = [\".omg\", \".omp\"];\n\nconst SCANNABLE_EXTENSIONS = [\".md\", \".json\", \".yml\", \".yaml\", \".txt\"];\nconst MAX_SCAN_DEPTH = 3;\n\n/** Scan a text blob for stale agent references. */\nexport function scanTextForStaleAgents(text: string, file: string): StaleAgentWarning[] {\n const warnings: StaleAgentWarning[] = [];\n const lines = text.split(\"\\n\");\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n for (const match of line.matchAll(STALE_AGENT_PATTERN)) {\n const staleId = match[1];\n warnings.push({\n file,\n line: i + 1,\n staleId: `@${staleId}`,\n replacement: AGENT_MIGRATIONS[staleId],\n text: line.trim(),\n });\n }\n }\n return warnings;\n}\n\nfunction collectDirFiles(dir: string, depth: number): string[] {\n if (depth > MAX_SCAN_DEPTH) return [];\n const files: string[] = [];\n let entries: string[];\n try {\n entries = readdirSync(dir);\n } catch {\n return [];\n }\n for (const entry of entries) {\n const fullPath = join(dir, entry);\n try {\n const stats = statSync(fullPath);\n if (stats.isDirectory()) {\n files.push(...collectDirFiles(fullPath, depth + 1));\n } else if (SCANNABLE_EXTENSIONS.some((ext) => entry.endsWith(ext))) {\n files.push(fullPath);\n }\n } catch {\n // Skip unreadable entries\n }\n }\n return files;\n}\n\n/** Scan the project's config files for stale agent IDs. */\nexport function scanProjectForStaleAgents(cwd: string): StaleAgentWarning[] {\n const targets: string[] = [];\n for (const file of SCAN_FILES) {\n const fullPath = join(cwd, file);\n if (existsSync(fullPath)) targets.push(fullPath);\n }\n for (const dir of SCAN_DIRS) {\n const fullPath = join(cwd, dir);\n if (existsSync(fullPath)) targets.push(...collectDirFiles(fullPath, 0));\n }\n\n const warnings: StaleAgentWarning[] = [];\n for (const target of targets) {\n try {\n const text = readFileSync(target, \"utf-8\");\n warnings.push(...scanTextForStaleAgents(text, relative(cwd, target)));\n } catch {\n // Skip unreadable files\n }\n }\n return warnings;\n}\n\n/** Run the doctor checks and print a report. Returns the number of warnings. */\nexport function runDoctor(cwd: string = process.cwd()): number {\n console.log(\"OMP Doctor \u2014 agent migration check (2.0)\");\n console.log(\"\");\n\n const warnings = scanProjectForStaleAgents(cwd);\n\n if (warnings.length === 0) {\n console.log(\"OK: no stale agent references found.\");\n return 0;\n }\n\n console.log(`WARN: found ${warnings.length} stale agent reference(s):`);\n console.log(\"\");\n for (const warning of warnings) {\n console.log(` ${warning.file}:${warning.line} \u2014 ${warning.staleId} \u2192 ${warning.replacement}`);\n console.log(` ${warning.text}`);\n }\n console.log(\"\");\n console.log(\"Suggested replacements (OMP 2.0 agent parity):\");\n for (const [staleId, replacement] of Object.entries(AGENT_MIGRATIONS)) {\n console.log(` @${staleId} \u2192 ${replacement}`);\n }\n return warnings.length;\n}\n", "/**\n * Shared hook entry-point runner.\n *\n * Hooks must be FAIL-OPEN: any failure (empty stdin, malformed JSON,\n * unexpected processing error) must still emit a valid HookOutput-shaped\n * JSON object on stdout and exit 0. A non-zero exit or non-JSON stdout\n * causes the Copilot CLI to treat the hook as errored, which denies the\n * tool call for PreToolUse hooks.\n *\n * Fail-open events are persisted (best-effort) as JSONL records to\n * ~/.omp/logs/hook-failures.jsonl and mirrored on stderr so failures\n * remain observable without ever touching the stdout JSON contract.\n */\n\nimport { appendFileSync, mkdirSync } from \"fs\";\nimport { homedir } from \"os\";\nimport { join } from \"path\";\n\nexport interface FailOpenOutput {\n decision?: \"allow\";\n status: \"error\";\n latencyMs: number;\n mutations: never[];\n log: string[];\n}\n\nexport interface RunHookOptions {\n /**\n * When true (hooks whose HookOutput supports a decision field), the\n * fail-open output includes `\"decision\": \"allow\"` so the tool call is\n * explicitly allowed.\n */\n failOpenDecision?: boolean;\n /** Hook id recorded in fail-open log entries (stderr + JSONL). */\n hookName?: string;\n}\n\nexport async function readStdin(): Promise<string> {\n const readStdinActual = async (): 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\n const stdinTimeout = new Promise<string>((resolve) =>\n setTimeout(\n () => resolve(\"\"),\n (parseInt(process.env.OMP_HOOK_STDIN_TIMEOUT_MS ?? \"500\") || 500)\n )\n );\n\n return Promise.race([readStdinActual(), stdinTimeout]);\n}\n\n/**\n * Best-effort persistence of a fail-open event. Wrapped in its own\n * try/catch: logging must NEVER break fail-open or the one-JSON-object\n * stdout contract. Writes to stderr and the JSONL log only \u2014 never stdout.\n */\nfunction logHookFailure(hook: string, reason: string): void {\n try {\n process.stderr.write(`[omp hook fail-open] ${hook}: ${reason}\\n`);\n } catch {\n // stderr unavailable \u2014 ignore\n }\n try {\n const logsDir = join(homedir(), \".omp\", \"logs\");\n mkdirSync(logsDir, { recursive: true });\n const record = JSON.stringify({ ts: new Date().toISOString(), hook, reason });\n appendFileSync(join(logsDir, \"hook-failures.jsonl\"), record + \"\\n\", \"utf-8\");\n } catch {\n // best-effort only \u2014 never let logging break fail-open\n }\n}\n\n/**\n * Reads HookInput JSON from stdin, runs the hook, and prints the\n * HookOutput JSON to stdout. Never throws, never exits non-zero,\n * never emits non-JSON to stdout.\n */\nexport async function runHookMain<TInput>(\n processHook: (input: TInput) => unknown,\n options: RunHookOptions = {}\n): Promise<void> {\n let outputJson: string;\n try {\n const input = JSON.parse(await readStdin()) as TInput;\n const serialized = JSON.stringify(processHook(input));\n if (typeof serialized !== \"string\") {\n throw new Error(\"hook produced no serializable output\");\n }\n outputJson = serialized;\n } catch (err) {\n const reason = err instanceof Error ? err.message : String(err);\n logHookFailure(options.hookName ?? \"unknown\", reason);\n const failOpen: FailOpenOutput = {\n ...(options.failOpenDecision ? { decision: \"allow\" as const } : {}),\n status: \"error\",\n latencyMs: 0,\n mutations: [],\n log: [`fail-open: ${reason}`],\n };\n outputJson = JSON.stringify(failOpen);\n }\n console.log(outputJson);\n process.exitCode = 0;\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 \"verify:\": \"verify\",\n \"/verify\": \"verify\",\n \"/omp:verify\": \"verify\",\n \"cancel:\": \"cancel\",\n \"/omp:cancel\": \"cancel\",\n \"help:\": \"help\",\n \"/omp:help\": \"help\",\n \"code-review:\": \"code-review\",\n \"/code-review\": \"code-review\",\n \"/omp:code-review\": \"code-review\",\n \"security-review:\": \"security-review\",\n \"/security-review\": \"security-review\",\n \"/omp:security-review\": \"security-review\",\n \"ultraqa:\": \"ultraqa\",\n \"/ultraqa\": \"ultraqa\",\n \"/omp:ultraqa\": \"ultraqa\",\n \"ultragoal:\": \"ultragoal\",\n \"/ultragoal\": \"ultragoal\",\n \"/omp:ultragoal\": \"ultragoal\",\n \"deep-dive:\": \"deep-dive\",\n \"/deep-dive\": \"deep-dive\",\n \"/omp:deep-dive\": \"deep-dive\",\n \"external-context:\": \"external-context\",\n \"/external-context\": \"external-context\",\n \"/omp:external-context\": \"external-context\",\n \"deepsearch:\": \"deepsearch\",\n \"/deepsearch\": \"deepsearch\",\n \"/omp:deepsearch\": \"deepsearch\",\n \"sciomc:\": \"sciomc\",\n \"/sciomc\": \"sciomc\",\n \"/omp:sciomc\": \"sciomc\",\n \"remember:\": \"remember\",\n \"/omp:remember\": \"remember\",\n \"writer-memory:\": \"writer-memory\",\n \"/writer-memory\": \"writer-memory\",\n \"/omp:writer-memory\": \"writer-memory\",\n \"deepinit:\": \"deepinit\",\n \"/deepinit\": \"deepinit\",\n \"/omp:deepinit\": \"deepinit\",\n \"self-improve:\": \"self-improve\",\n \"/self-improve\": \"self-improve\",\n \"/omp:self-improve\": \"self-improve\",\n \"visual-verdict:\": \"visual-verdict\",\n \"/visual-verdict\": \"visual-verdict\",\n \"/omp:visual-verdict\": \"visual-verdict\",\n \"ccg:\": \"ccg\",\n \"/ccg\": \"ccg\",\n \"/omp:ccg\": \"ccg\",\n \"build-fix:\": \"build-fix\",\n \"/build-fix\": \"build-fix\",\n \"/omp:build-fix\": \"build-fix\",\n \"design:\": \"design\",\n \"/omp:design\": \"design\",\n \"web-clone:\": \"web-clone\",\n \"/web-clone\": \"web-clone\",\n \"/omp:web-clone\": \"web-clone\",\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.\n// Fail-open: any stdin/parse/processing failure still emits valid JSON and exits 0.\nimport { runHookMain } from \"./runner.mts\";\n\nif (process.argv[1]?.endsWith(\"keyword-detector.mjs\") || process.argv[1]?.endsWith(\"keyword-detector.mts\")) {\n await runHookMain(processHook, { failOpenDecision: true, hookName: \"keyword-detector\" });\n}\n", "/**\n * Pure builder mapping the OMP skill registry to Copilot SDK\n * CommandDefinition-shaped objects (SPEC-omp-2.0 \u00A74, ADR-0002).\n *\n * The SDK types are declared structurally here on purpose:\n * `@github/copilot-sdk` is resolved by the Copilot CLI inside extension\n * processes only and is NOT a package.json dependency of this repo.\n * `extension/extension.mjs` mirrors this logic in a self-contained form.\n */\n\nimport type { SkillEntry } from \"./registry.mts\";\n\n/** Minimal structural shape of the Copilot SDK CommandDefinition. */\nexport interface CommandDefinitionLike {\n name: string;\n description: string;\n handler: (args: string) => string;\n}\n\n/**\n * Returns the instruction string a command handler hands back to the\n * agent. Command handlers run in the extension process, so they cannot\n * execute the skill directly \u2014 they instruct the agent to activate it.\n */\nexport function buildActivationInstruction(\n skillId: string,\n args: string,\n): string {\n const trimmed = args.trim();\n return `Activate the OMP skill \"${skillId}\" with args: ${trimmed.length > 0 ? trimmed : \"(none)\"}`;\n}\n\n/**\n * Expands the registry into one command per skill id plus one per alias.\n * Alias commands point at the canonical skill id in both their\n * description and activation instruction.\n */\nexport function buildCommands(registry: SkillEntry[]): CommandDefinitionLike[] {\n const commands: CommandDefinitionLike[] = [];\n for (const entry of registry) {\n commands.push({\n name: entry.id,\n description: entry.description,\n handler: (args: string) => buildActivationInstruction(entry.id, args),\n });\n for (const alias of entry.aliases ?? []) {\n commands.push({\n name: alias,\n description: `Alias for /${entry.id} \u2014 ${entry.description}`,\n handler: (args: string) => buildActivationInstruction(entry.id, args),\n });\n }\n }\n return commands;\n}\n", "/**\n * OMP skill registry \u2014 single source of truth for slash commands,\n * CLI verbs, and keyword triggers (SPEC-omp-2.0 \u00A74, ADR-0002).\n *\n * Each entry mirrors a `skills/<id>/SKILL.md` listed in plugin.json.\n * `extension/extension.mjs` carries a self-contained copy of this list\n * (it must run standalone in the Copilot extension process without tsx);\n * keep both in sync when adding skills.\n */\n\nimport { buildCommands, type CommandDefinitionLike } from \"./commands.mts\";\n\nexport interface SkillEntry {\n /** Canonical skill id == skills/<id> directory basename. */\n id: string;\n /** One-line description shown next to the slash command. */\n description: string;\n /** Short alternative slash-command names (e.g. ulw \u2192 ultrawork). */\n aliases?: string[];\n /** Legacy prose keyword triggers kept for backward compat during 2.x. */\n keywords?: string[];\n}\n\nexport const SKILL_REGISTRY: SkillEntry[] = [\n {\n id: \"autopilot\",\n description: \"Autonomous end-to-end execution from idea to working code\",\n keywords: [\"autopilot:\"],\n },\n {\n id: \"ralph\",\n description: \"Persistence loop with architect verification gate\",\n keywords: [\"ralph:\"],\n },\n {\n id: \"ultrawork\",\n description: \"Parallel multi-agent high-throughput implementation\",\n aliases: [\"ulw\"],\n keywords: [\"ulw:\", \"ultrawork:\"],\n },\n {\n id: \"team\",\n description: \"Coordinated N-agent team with staged pipeline\",\n keywords: [\"team:\"],\n },\n {\n id: \"ecomode\",\n description: \"Cost-optimized execution with low-cost model tier\",\n aliases: [\"eco\"],\n keywords: [\"eco:\", \"ecomode:\"],\n },\n {\n id: \"swarm\",\n description: \"Parallel agent swarm for independent subtasks\",\n keywords: [\"swarm:\"],\n },\n {\n id: \"pipeline\",\n description: \"Sequential stage-based execution pipeline\",\n keywords: [\"pipeline:\"],\n },\n {\n id: \"deep-interview\",\n description: \"Socratic deep requirements interview with ambiguity gating\",\n aliases: [\"di\"],\n keywords: [\"deep interview:\"],\n },\n {\n id: \"omp-plan\",\n description:\n \"Strategic planning with interview, direct, consensus, and review modes\",\n aliases: [\"plan\"],\n keywords: [\"plan:\"],\n },\n {\n id: \"omp-setup\",\n description: \"OMP onboarding and configuration wizard\",\n keywords: [\"setup:\"],\n },\n {\n id: \"hud\",\n description: \"Display current HUD session state\",\n keywords: [\"hud:\"],\n },\n {\n id: \"wiki\",\n description: \"Project wiki operations and management\",\n keywords: [\"wiki:\"],\n },\n {\n id: \"learner\",\n description: \"Structured learning and knowledge sessions\",\n keywords: [\"learner:\"],\n },\n {\n id: \"note\",\n description: \"Session notes and context management\",\n keywords: [\"note:\"],\n },\n {\n id: \"trace\",\n description: \"Execution tracing and debugging\",\n keywords: [\"trace:\"],\n },\n {\n id: \"release\",\n description: \"Guided release workflow and automation\",\n keywords: [\"release:\"],\n },\n {\n id: \"configure-notifications\",\n description: \"Configure session notification settings\",\n keywords: [\"configure-notifications:\"],\n },\n {\n id: \"psm\",\n description: \"Plugin State Manager operations\",\n keywords: [\"psm:\"],\n },\n {\n id: \"swe-bench\",\n description: \"SWE-bench evaluation harness runner\",\n keywords: [\"swe-bench:\"],\n },\n {\n id: \"mcp-setup\",\n description: \"MCP server configuration wizard\",\n keywords: [\"mcp:\", \"mcp-setup:\"],\n },\n {\n id: \"setup\",\n description: \"OMP setup and onboarding wizard\",\n },\n {\n id: \"graphify\",\n description: \"Convert any input to a knowledge graph\",\n keywords: [\"graphify:\"],\n },\n {\n id: \"graphwiki\",\n description: \"GraphWiki CLI operations: query, lint, build\",\n keywords: [\"graphwiki:\"],\n },\n {\n id: \"graph-provider\",\n description: \"Manage and configure the active graph provider\",\n keywords: [\"graph:\"],\n },\n {\n id: \"spending\",\n description: \"Track and reset premium request usage\",\n keywords: [\"spending:\"],\n },\n {\n id: \"ralplan\",\n description:\n \"Consensus planning gate for vague ralph/autopilot/team requests\",\n },\n {\n id: \"research\",\n description:\n \"Research and investigation workflows (investigate, deep dive)\",\n keywords: [\"autoresearch:\"],\n },\n {\n id: \"omp-doctor\",\n description: \"Diagnose and fix oh-my-githubcopilot installation issues\",\n },\n {\n id: \"omp-reference\",\n description:\n \"OMP agent catalog, tools, routing, commit protocol, and skills registry\",\n },\n {\n id: \"ai-slop-cleaner\",\n description:\n \"Clean AI-generated code slop with a regression-safe, deletion-first workflow\",\n keywords: [\"deslop\", \"anti-slop\"],\n },\n {\n id: \"tdd\",\n description: \"Test-Driven Development with Red-Green-Refactor cycle\",\n keywords: [\"tdd:\"],\n },\n {\n id: \"improve-codebase-architecture\",\n description:\n \"Deep exploration and architectural improvement via friction detection\",\n },\n {\n id: \"skillify\",\n description:\n \"Turn a repeatable session workflow into a reusable OMP skill draft\",\n },\n {\n id: \"interview\",\n description: \"Socratic interview and ambiguity scoring\",\n keywords: [\"interview:\"],\n },\n {\n id: \"graph-context\",\n description:\n \"Load codebase context from the knowledge graph instead of raw files\",\n },\n {\n id: \"interactive-menu\",\n description:\n \"Numbered-choice selection pattern for OMP's conversational TUI\",\n },\n {\n id: \"notifications\",\n description:\n \"Send and manage runtime notifications (Telegram, Discord, Slack, Email)\",\n keywords: [\"notifications:\"],\n },\n {\n id: \"doctor\",\n description: \"Diagnose and fix common issues\",\n keywords: [\"doctor:\"],\n },\n {\n id: \"session\",\n description: \"Worktree and tmux session management\",\n keywords: [\"session:\"],\n },\n {\n id: \"verify\",\n description: \"Evidence-based completion check via verifier agent\",\n keywords: [\"verify:\"],\n },\n {\n id: \"cancel\",\n description: \"Ends active execution modes and clears .omp/state/\",\n keywords: [\"cancel:\"],\n },\n {\n id: \"help\",\n description: \"Command and skill discovery; prints the full skill catalog\",\n keywords: [\"help:\"],\n },\n {\n id: \"code-review\",\n description: \"Trigger the code-reviewer agent lane for structured code review\",\n keywords: [\"code-review:\"],\n },\n {\n id: \"security-review\",\n description: \"Trigger the security-reviewer agent lane for security analysis\",\n keywords: [\"security-review:\"],\n },\n {\n id: \"ultraqa\",\n description: \"QA cycle loop with qa-tester agent; runs until all checks pass\",\n keywords: [\"ultraqa:\"],\n },\n {\n id: \"ultragoal\",\n description: \"Durable goal ledger in .omp/ultragoal/ with fail-closed checkpoints\",\n keywords: [\"ultragoal:\"],\n },\n {\n id: \"deep-dive\",\n description: \"Trace\u2192deep-interview pipeline for deep investigation\",\n keywords: [\"deep-dive:\"],\n },\n {\n id: \"external-context\",\n description: \"Load external docs/URLs into session context\",\n keywords: [\"external-context:\"],\n },\n {\n id: \"deepsearch\",\n description: \"Multi-source deep search across codebase and web\",\n keywords: [\"deepsearch:\"],\n },\n {\n id: \"sciomc\",\n description: \"Scientific/analytical reasoning workflow \u2014 hypothesis\u2192experiment\u2192conclusion\",\n keywords: [\"sciomc:\"],\n },\n {\n id: \"remember\",\n description: \"Persist key facts/decisions to .omp/memory/\",\n keywords: [\"remember:\"],\n },\n {\n id: \"writer-memory\",\n description: \"Writing style memory \u2014 stores voice/tone preferences\",\n keywords: [\"writer-memory:\"],\n },\n {\n id: \"deepinit\",\n description: \"Deep project initialization \u2014 full codebase onboarding\",\n keywords: [\"deepinit:\"],\n },\n {\n id: \"self-improve\",\n description: \"OMP self-improvement \u2014 analyse own skills/agents and propose improvements\",\n keywords: [\"self-improve:\"],\n },\n {\n id: \"visual-verdict\",\n description: \"Visual diff/screenshot comparison verdict\",\n keywords: [\"visual-verdict:\"],\n },\n {\n id: \"ccg\",\n description: \"Concurrent code generation via multi-model picker\",\n keywords: [\"ccg:\"],\n },\n {\n id: \"build-fix\",\n description: \"Diagnose and fix build/CI failures automatically\",\n keywords: [\"build-fix:\"],\n },\n {\n id: \"design\",\n description: \"UI/UX design and frontend component generation\",\n keywords: [\"design:\"],\n },\n {\n id: \"web-clone\",\n description: \"Clone and adapt a web page/design to the codebase\",\n keywords: [\"web-clone:\"],\n },\n];\n\n/**\n * Maps the registry to Copilot SDK CommandDefinition-shaped objects\n * (one per skill id plus one per alias).\n */\nexport function getCommandDefinitions(): CommandDefinitionLike[] {\n return buildCommands(SKILL_REGISTRY);\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 doctor \u2014 check installation and stale agent references\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 * omp verify \u2014 evidence-based completion check via verifier agent\n * omp cancel \u2014 end active execution modes and clear .omp/state/\n * omp help \u2014 print skill catalog and command discovery\n * omp code-review \u2014 trigger code-reviewer agent lane\n * omp security-review \u2014 trigger security-reviewer agent lane\n * omp ultraqa \u2014 QA cycle loop with qa-tester agent\n * omp ultragoal \u2014 manage durable goal ledger in .omp/ultragoal/\n * omp deep-dive \u2014 guidance: use /deep-dive in Copilot\n * omp external-context \u2014 load external URL/path into context (or print guidance)\n * omp deepsearch \u2014 guidance: use /deepsearch in Copilot\n * omp sciomc \u2014 guidance: use /sciomc in Copilot\n * omp remember \u2014 persist note to .omp/memory/ (or list memories)\n * omp writer-memory \u2014 manage .omp/writer-memory.md style notes\n * omp deepinit \u2014 guidance: use /deepinit in Copilot\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 case \"doctor\": {\n const { runDoctor } = await import(\"./cli/doctor.mts\");\n const warnings = runDoctor(process.cwd());\n process.exitCode = warnings > 0 ? 1 : 0;\n break;\n }\n case \"verify\":\n console.log(\"OMP verify: use /verify or /oh-my-githubcopilot:verify in GitHub Copilot CLI to trigger @verifier evidence-based completion check.\");\n break;\n case \"cancel\":\n await runCancel();\n break;\n case \"help\":\n await runHelp();\n break;\n case \"code-review\":\n console.log(\"OMP code-review: use /code-review or /oh-my-githubcopilot:code-review in GitHub Copilot CLI to trigger @code-reviewer agent.\");\n break;\n case \"security-review\":\n console.log(\"OMP security-review: use /security-review or /oh-my-githubcopilot:security-review in GitHub Copilot CLI to trigger @security-reviewer agent.\");\n break;\n case \"ultraqa\":\n console.log(\"OMP ultraqa: use /ultraqa or /oh-my-githubcopilot:ultraqa in GitHub Copilot CLI to start a QA cycle with @qa-tester agent.\");\n break;\n case \"ultragoal\":\n await runUltragoal(positionals.slice(1));\n break;\n case \"deep-dive\":\n console.log(\"OMP deep-dive: use /deep-dive or /oh-my-githubcopilot:deep-dive in GitHub Copilot CLI to run the trace\u2192deep-interview investigation pipeline.\");\n break;\n case \"external-context\":\n await runExternalContext(positionals.slice(1));\n break;\n case \"deepsearch\":\n console.log(\"OMP deepsearch: use /deepsearch or /oh-my-githubcopilot:deepsearch in GitHub Copilot CLI to run multi-source deep search.\");\n break;\n case \"sciomc\":\n console.log(\"OMP sciomc: use /sciomc or /oh-my-githubcopilot:sciomc in GitHub Copilot CLI to run the scientific hypothesis\u2192experiment\u2192conclusion reasoning workflow.\");\n break;\n case \"remember\":\n await runRemember(positionals.slice(1));\n break;\n case \"writer-memory\":\n await runWriterMemory(positionals.slice(1));\n break;\n case \"deepinit\":\n console.log(\"OMP deepinit: use /deepinit or /oh-my-githubcopilot:deepinit in GitHub Copilot CLI to run deep project initialization.\");\n break;\n case \"self-improve\":\n console.log(\"OMP self-improve: use /self-improve in Copilot CLI to analyse OMP skills/agents and propose improvements.\");\n break;\n case \"visual-verdict\":\n console.log(\"OMP visual-verdict: use /visual-verdict in Copilot CLI to compare visual diffs or screenshots.\");\n break;\n case \"ccg\":\n console.log(\"OMP ccg: use /ccg in Copilot CLI to run concurrent code generation via multi-model picker.\");\n break;\n case \"build-fix\":\n console.log(\"OMP build-fix: use /build-fix in Copilot CLI to diagnose and fix build/CI failures automatically.\");\n break;\n case \"design\":\n console.log(\"OMP design: use /omp:design in Copilot CLI to generate UI/UX designs and frontend components.\");\n break;\n case \"web-clone\":\n console.log(\"OMP web-clone: use /web-clone in Copilot CLI to clone and adapt a web page/design to your codebase.\");\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|install|doctor|version|psm|bench|hook|verify|cancel|help|code-review|security-review|ultraqa|ultragoal|deep-dive|external-context|deepsearch|sciomc|remember|writer-memory|deepinit|self-improve|visual-verdict|ccg|build-fix|design|web-clone] [--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 // Fail-open: any stdin/parse/processing failure still emits valid JSON and exits 0.\n const { processHook } = await import(\"./hooks/keyword-detector.mts\");\n const { runHookMain } = await import(\"./hooks/runner.mts\");\n await runHookMain(processHook, { failOpenDecision: true, hookName: \"keyword-detector\" });\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\nasync function runCancel() {\n try {\n const { rmSync, existsSync } = await import(\"fs\");\n const { join } = await import(\"path\");\n const statePath = join(process.cwd(), \".omp\", \"state\");\n if (existsSync(statePath)) {\n rmSync(statePath, { recursive: true, force: true });\n console.log(\"OMP: active session cancelled. .omp/state/ cleared.\");\n } else {\n console.log(\"OMP: no active session state found. Nothing to cancel.\");\n }\n } catch (err) {\n console.error(\"OMP cancel failed:\", err);\n process.exitCode = 1;\n }\n}\n\nasync function runHelp() {\n try {\n const { SKILL_REGISTRY } = await import(\"./extension/registry.mts\");\n console.log(\"OMP Skills Catalog\\n\");\n console.log(\" ID Description\");\n console.log(\" \" + \"-\".repeat(70));\n for (const skill of SKILL_REGISTRY) {\n const id = skill.id.padEnd(30);\n console.log(` ${id} ${skill.description}`);\n }\n console.log(`\\nTotal: ${SKILL_REGISTRY.length} skills`);\n console.log(\"\\nUsage: /omp:<skill-id> [args]\");\n } catch (err) {\n console.error(\"OMP help failed:\", err);\n process.exitCode = 1;\n }\n}\n\nasync function runUltragoal(args: string[]) {\n try {\n const { mkdirSync, readFileSync, writeFileSync, existsSync } = await import(\"fs\");\n const { join } = await import(\"path\");\n const goalDir = join(process.cwd(), \".omp\", \"ultragoal\");\n const goalsPath = join(goalDir, \"goals.json\");\n mkdirSync(goalDir, { recursive: true });\n let goals: Array<{ id: number; goal: string; status: string; createdAt: string }> = [];\n if (existsSync(goalsPath)) {\n const parsed: unknown = JSON.parse(readFileSync(goalsPath, \"utf-8\"));\n if (Array.isArray(parsed)) {\n goals = parsed;\n } else {\n console.error(\"OMP UltraGoal: goals.json is corrupted (not an array). Resetting to empty.\");\n goals = [];\n }\n }\n if (args.length > 0) {\n const nextId = goals.length === 0 ? 1 : Math.max(...goals.map((g) => g.id)) + 1;\n const newGoal = { id: nextId, goal: args.join(\" \"), status: \"active\", createdAt: new Date().toISOString() };\n goals.push(newGoal);\n const tmpPath = goalsPath + \".tmp\";\n writeFileSync(tmpPath, JSON.stringify(goals, null, 2));\n const { renameSync } = await import(\"fs\");\n renameSync(tmpPath, goalsPath);\n console.log(`OMP UltraGoal: added goal #${newGoal.id}: \"${newGoal.goal}\"`);\n } else {\n if (goals.length === 0) {\n console.log(\"OMP UltraGoal: no goals set. Use: omp ultragoal <goal description>\");\n } else {\n console.log(\"OMP UltraGoal \u2014 Current Goals:\\n\");\n for (const g of goals) {\n console.log(` #${g.id} [${g.status}] ${g.goal}`);\n }\n }\n }\n } catch (err) {\n console.error(\"OMP ultragoal failed:\", err);\n process.exitCode = 1;\n }\n}\n\nasync function runExternalContext(args: string[]) {\n if (args.length === 0) {\n console.log(\"OMP external-context: use /external-context <url-or-path> or /oh-my-githubcopilot:external-context in GitHub Copilot CLI to load external docs into session context.\");\n return;\n }\n const target = args.join(\" \");\n console.log(`External context loaded: ${target}. Use /external-context ${target} in Copilot CLI to load into session.`);\n}\n\nasync function runRemember(args: string[]) {\n try {\n const { mkdirSync, readdirSync, writeFileSync, existsSync } = await import(\"fs\");\n const { join } = await import(\"path\");\n const memoryDir = join(process.cwd(), \".omp\", \"memory\");\n mkdirSync(memoryDir, { recursive: true });\n\n if (args.length === 0) {\n // List existing memories\n if (!existsSync(memoryDir)) {\n console.log(\"OMP Remember: no memories found. Use: omp remember <text>\");\n return;\n }\n const files = readdirSync(memoryDir).filter((f) => f.endsWith(\".md\")).sort();\n if (files.length === 0) {\n console.log(\"OMP Remember: no memories found. Use: omp remember <text>\");\n } else {\n console.log(\"OMP Remember \u2014 Stored Memories:\\n\");\n for (const file of files) {\n console.log(` ${file}`);\n }\n console.log(`\\nTotal: ${files.length} memor${files.length === 1 ? \"y\" : \"ies\"}`);\n }\n return;\n }\n\n // Write new memory\n const text = args.join(\" \");\n const timestamp = new Date().toISOString().replace(/[:.]/g, \"-\");\n const fileName = `${timestamp}.md`;\n const filePath = join(memoryDir, fileName);\n const tmpPath = filePath + \".tmp\";\n const content = `# Memory: ${new Date().toISOString()}\\n\\n${text}\\n`;\n writeFileSync(tmpPath, content, \"utf-8\");\n const { renameSync } = await import(\"fs\");\n renameSync(tmpPath, filePath);\n console.log(`OMP Remember: saved memory to .omp/memory/${fileName}`);\n } catch (err) {\n console.error(\"OMP remember failed:\", err);\n process.exitCode = 1;\n }\n}\n\nasync function runWriterMemory(args: string[]) {\n try {\n const { mkdirSync, readFileSync, appendFileSync, existsSync } = await import(\"fs\");\n const { join, dirname } = await import(\"path\");\n const filePath = join(process.cwd(), \".omp\", \"writer-memory.md\");\n mkdirSync(dirname(filePath), { recursive: true });\n\n if (args.length === 0) {\n // Print current writer memory\n if (!existsSync(filePath)) {\n console.log(\"OMP Writer Memory: no style notes found. Use: omp writer-memory <style-note>\");\n return;\n }\n const content = readFileSync(filePath, \"utf-8\");\n console.log(content);\n return;\n }\n\n // Append new style note\n const note = args.join(\" \");\n const entry = `\\n## ${new Date().toISOString()}\\n\\n${note}\\n`;\n appendFileSync(filePath, entry, \"utf-8\");\n console.log(`OMP Writer Memory: appended style note to .omp/writer-memory.md`);\n } catch (err) {\n console.error(\"OMP writer-memory failed:\", err);\n process.exitCode = 1;\n }\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", "readFileSync", "join", "mkdirSync", "homedir", "join", "processHook", "subcommand", "flags", "runHudWatch", "runInstall", "runDoctor", "readFileSync", "join", "homedir", "processHook", "runHookMain", "existsSync", "SKILL_REGISTRY", "mkdirSync", "writeFileSync", "renameSync", "readdirSync", "appendFileSync", "dirname"]
7
7
  }
@@ -1,16 +1,77 @@
1
1
  // src/hooks/delegation-enforcer.mts
2
2
  import { readFileSync } from "fs";
3
+ import { homedir as homedir2 } from "os";
4
+ import { join as join2 } from "path";
5
+ import { fileURLToPath } from "url";
6
+
7
+ // src/hooks/runner.mts
8
+ import { appendFileSync, mkdirSync } from "fs";
3
9
  import { homedir } from "os";
4
10
  import { join } from "path";
5
- import { fileURLToPath } from "url";
11
+ async function readStdin() {
12
+ const readStdinActual = async () => {
13
+ const chunks = [];
14
+ for await (const chunk of process.stdin) {
15
+ chunks.push(String(chunk));
16
+ }
17
+ return chunks.join("");
18
+ };
19
+ const stdinTimeout = new Promise(
20
+ (resolve) => setTimeout(
21
+ () => resolve(""),
22
+ parseInt(process.env.OMP_HOOK_STDIN_TIMEOUT_MS ?? "500") || 500
23
+ )
24
+ );
25
+ return Promise.race([readStdinActual(), stdinTimeout]);
26
+ }
27
+ function logHookFailure(hook, reason) {
28
+ try {
29
+ process.stderr.write(`[omp hook fail-open] ${hook}: ${reason}
30
+ `);
31
+ } catch {
32
+ }
33
+ try {
34
+ const logsDir = join(homedir(), ".omp", "logs");
35
+ mkdirSync(logsDir, { recursive: true });
36
+ const record = JSON.stringify({ ts: (/* @__PURE__ */ new Date()).toISOString(), hook, reason });
37
+ appendFileSync(join(logsDir, "hook-failures.jsonl"), record + "\n", "utf-8");
38
+ } catch {
39
+ }
40
+ }
41
+ async function runHookMain(processHook2, options = {}) {
42
+ let outputJson;
43
+ try {
44
+ const input = JSON.parse(await readStdin());
45
+ const serialized = JSON.stringify(processHook2(input));
46
+ if (typeof serialized !== "string") {
47
+ throw new Error("hook produced no serializable output");
48
+ }
49
+ outputJson = serialized;
50
+ } catch (err) {
51
+ const reason = err instanceof Error ? err.message : String(err);
52
+ logHookFailure(options.hookName ?? "unknown", reason);
53
+ const failOpen = {
54
+ ...options.failOpenDecision ? { decision: "allow" } : {},
55
+ status: "error",
56
+ latencyMs: 0,
57
+ mutations: [],
58
+ log: [`fail-open: ${reason}`]
59
+ };
60
+ outputJson = JSON.stringify(failOpen);
61
+ }
62
+ console.log(outputJson);
63
+ process.exitCode = 0;
64
+ }
65
+
66
+ // src/hooks/delegation-enforcer.mts
6
67
  function getSessionStateDir() {
7
- const ompDir = join(homedir(), ".omp", "state");
68
+ const ompDir = join2(homedir2(), ".omp", "state");
8
69
  return ompDir;
9
70
  }
10
71
  function getCurrentAgent(sessionId) {
11
72
  try {
12
73
  const stateDir = getSessionStateDir();
13
- const sessionFile = sessionId ? join(stateDir, "sessions", sessionId, "session.json") : join(stateDir, "session.json");
74
+ const sessionFile = sessionId ? join2(stateDir, "sessions", sessionId, "session.json") : join2(stateDir, "session.json");
14
75
  const data = JSON.parse(readFileSync(sessionFile, "utf-8"));
15
76
  return data.activeAgent || null;
16
77
  } catch {
@@ -79,16 +140,7 @@ function processHook(input) {
79
140
  }
80
141
  }
81
142
  if (process.argv[1] === fileURLToPath(import.meta.url)) {
82
- const input = JSON.parse(await readStdin());
83
- const output = processHook(input);
84
- console.log(JSON.stringify(output));
85
- }
86
- async function readStdin() {
87
- const chunks = [];
88
- for await (const chunk of process.stdin) {
89
- chunks.push(chunk);
90
- }
91
- return chunks.join("");
143
+ await runHookMain(processHook, { failOpenDecision: true, hookName: "delegation-enforcer" });
92
144
  }
93
145
  export {
94
146
  processHook
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../src/hooks/delegation-enforcer.mts"],
4
- "sourcesContent": ["/**\n * delegation-enforcer hook\n * Trigger: pre-cycle (PreToolUse equivalent)\n * Priority: 90\n *\n * Blocks orchestrator from using Write/Edit \u2014 forces delegation.\n */\n\nimport { readFileSync } from \"fs\";\nimport { homedir } from \"os\";\nimport { join } from \"path\";\n\nexport interface HookInput {\n hook_type: \"PreToolUse\";\n tool_name?: string;\n tool_input?: unknown;\n agent_id?: string;\n session_id?: string;\n}\n\nexport interface HookOutput {\n decision?: \"allow\" | \"deny\";\n modifiedArgs?: Record<string, unknown>;\n status: \"ok\" | \"skip\" | \"error\";\n latencyMs: number;\n mutations: Array<{ type: \"reroute_tool\"; toolCall: unknown; toAgent: string } | { type: \"log\"; level: \"info\" | \"warn\"; message: string }>;\n log: string[];\n}\n\nfunction getSessionStateDir(): string {\n const ompDir = join(homedir(), \".omp\", \"state\");\n return ompDir;\n}\n\nfunction getCurrentAgent(sessionId?: string): string | null {\n try {\n const stateDir = getSessionStateDir();\n const sessionFile = sessionId\n ? join(stateDir, \"sessions\", sessionId, \"session.json\")\n : join(stateDir, \"session.json\");\n const data = JSON.parse(readFileSync(sessionFile, \"utf-8\"));\n return data.activeAgent || null;\n } catch {\n return null;\n }\n}\n\nconst BLOCKED_TOOLS = new Set([\"Write\", \"Edit\"]);\nconst BLOCKED_AGENT = \"orchestrator\";\n\nexport function processHook(input: HookInput): HookOutput {\n const start = Date.now();\n const log: string[] = [];\n\n try {\n if (input.hook_type !== \"PreToolUse\") {\n return {\n status: \"skip\",\n latencyMs: Date.now() - start,\n mutations: [],\n log: [\"Not a PreToolUse hook\"],\n };\n }\n\n const agentId = input.agent_id || getCurrentAgent(input.session_id);\n const toolName = input.tool_name;\n\n if (!agentId || !toolName) {\n return {\n status: \"ok\",\n latencyMs: Date.now() - start,\n mutations: [],\n log: [],\n };\n }\n\n if (agentId === BLOCKED_AGENT && BLOCKED_TOOLS.has(toolName)) {\n log.push(`ENFORCEMENT: ${agentId} attempted ${toolName} \u2014 blocked`);\n log.push(`Rerouting to appropriate specialist agent`);\n\n return {\n decision: \"deny\",\n status: \"ok\",\n latencyMs: Date.now() - start,\n mutations: [\n {\n type: \"reroute_tool\",\n toolCall: { tool: toolName, params: input.tool_input },\n toAgent: \"executor\",\n },\n {\n type: \"log\",\n level: \"warn\",\n message: `Delegation enforced: ${agentId} cannot use ${toolName}`,\n },\n ],\n log,\n };\n }\n\n return {\n status: \"ok\",\n latencyMs: Date.now() - start,\n mutations: [],\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)\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"],
5
- "mappings": ";AAQA,SAAS,oBAAoB;AAC7B,SAAS,eAAe;AACxB,SAAS,YAAY;AA2GrB,SAAS,qBAAqB;AAxF9B,SAAS,qBAA6B;AACpC,QAAM,SAAS,KAAK,QAAQ,GAAG,QAAQ,OAAO;AAC9C,SAAO;AACT;AAEA,SAAS,gBAAgB,WAAmC;AAC1D,MAAI;AACF,UAAM,WAAW,mBAAmB;AACpC,UAAM,cAAc,YAChB,KAAK,UAAU,YAAY,WAAW,cAAc,IACpD,KAAK,UAAU,cAAc;AACjC,UAAM,OAAO,KAAK,MAAM,aAAa,aAAa,OAAO,CAAC;AAC1D,WAAO,KAAK,eAAe;AAAA,EAC7B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,IAAM,gBAAgB,oBAAI,IAAI,CAAC,SAAS,MAAM,CAAC;AAC/C,IAAM,gBAAgB;AAEf,SAAS,YAAY,OAA8B;AACxD,QAAM,QAAQ,KAAK,IAAI;AACvB,QAAM,MAAgB,CAAC;AAEvB,MAAI;AACF,QAAI,MAAM,cAAc,cAAc;AACpC,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,WAAW,KAAK,IAAI,IAAI;AAAA,QACxB,WAAW,CAAC;AAAA,QACZ,KAAK,CAAC,uBAAuB;AAAA,MAC/B;AAAA,IACF;AAEA,UAAM,UAAU,MAAM,YAAY,gBAAgB,MAAM,UAAU;AAClE,UAAM,WAAW,MAAM;AAEvB,QAAI,CAAC,WAAW,CAAC,UAAU;AACzB,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,WAAW,KAAK,IAAI,IAAI;AAAA,QACxB,WAAW,CAAC;AAAA,QACZ,KAAK,CAAC;AAAA,MACR;AAAA,IACF;AAEA,QAAI,YAAY,iBAAiB,cAAc,IAAI,QAAQ,GAAG;AAC5D,UAAI,KAAK,gBAAgB,OAAO,cAAc,QAAQ,iBAAY;AAClE,UAAI,KAAK,2CAA2C;AAEpD,aAAO;AAAA,QACL,UAAU;AAAA,QACV,QAAQ;AAAA,QACR,WAAW,KAAK,IAAI,IAAI;AAAA,QACxB,WAAW;AAAA,UACT;AAAA,YACE,MAAM;AAAA,YACN,UAAU,EAAE,MAAM,UAAU,QAAQ,MAAM,WAAW;AAAA,YACrD,SAAS;AAAA,UACX;AAAA,UACA;AAAA,YACE,MAAM;AAAA,YACN,OAAO;AAAA,YACP,SAAS,wBAAwB,OAAO,eAAe,QAAQ;AAAA,UACjE;AAAA,QACF;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,WAAW,KAAK,IAAI,IAAI;AAAA,MACxB,WAAW,CAAC;AAAA,MACZ,KAAK,CAAC;AAAA,IACR;AAAA,EACF,SAAS,KAAK;AACZ,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,WAAW,KAAK,IAAI,IAAI;AAAA,MACxB,WAAW,CAAC;AAAA,MACZ,KAAK,CAAC,UAAU,GAAG,EAAE;AAAA,IACvB;AAAA,EACF;AACF;AAKA,IAAI,QAAQ,KAAK,CAAC,MAAM,cAAc,YAAY,GAAG,GAAG;AACtD,QAAM,QAAmB,KAAK,MAAM,MAAM,UAAU,CAAC;AACrD,QAAM,SAAS,YAAY,KAAK;AAChC,UAAQ,IAAI,KAAK,UAAU,MAAM,CAAC;AACpC;AAEA,eAAe,YAA6B;AAC1C,QAAM,SAAmB,CAAC;AAC1B,mBAAiB,SAAS,QAAQ,OAAO;AACvC,WAAO,KAAK,KAAK;AAAA,EACnB;AACA,SAAO,OAAO,KAAK,EAAE;AACvB;",
6
- "names": []
3
+ "sources": ["../../src/hooks/delegation-enforcer.mts", "../../src/hooks/runner.mts"],
4
+ "sourcesContent": ["/**\n * delegation-enforcer hook\n * Trigger: pre-cycle (PreToolUse equivalent)\n * Priority: 90\n *\n * Blocks the top-level coordinator (orchestrator role) from using Write/Edit \u2014 forces delegation.\n * Note: since OMP 2.0, \"orchestrator\" is the orchestration role of the main session,\n * not a delegatable agent.\n */\n\nimport { readFileSync } from \"fs\";\nimport { homedir } from \"os\";\nimport { join } from \"path\";\n\nexport interface HookInput {\n hook_type: \"PreToolUse\";\n tool_name?: string;\n tool_input?: unknown;\n agent_id?: string;\n session_id?: string;\n}\n\nexport interface HookOutput {\n decision?: \"allow\" | \"deny\";\n modifiedArgs?: Record<string, unknown>;\n status: \"ok\" | \"skip\" | \"error\";\n latencyMs: number;\n mutations: Array<{ type: \"reroute_tool\"; toolCall: unknown; toAgent: string } | { type: \"log\"; level: \"info\" | \"warn\"; message: string }>;\n log: string[];\n}\n\nfunction getSessionStateDir(): string {\n const ompDir = join(homedir(), \".omp\", \"state\");\n return ompDir;\n}\n\nfunction getCurrentAgent(sessionId?: string): string | null {\n try {\n const stateDir = getSessionStateDir();\n const sessionFile = sessionId\n ? join(stateDir, \"sessions\", sessionId, \"session.json\")\n : join(stateDir, \"session.json\");\n const data = JSON.parse(readFileSync(sessionFile, \"utf-8\"));\n return data.activeAgent || null;\n } catch {\n return null;\n }\n}\n\nconst BLOCKED_TOOLS = new Set([\"Write\", \"Edit\"]);\nconst BLOCKED_AGENT = \"orchestrator\";\n\nexport function processHook(input: HookInput): HookOutput {\n const start = Date.now();\n const log: string[] = [];\n\n try {\n if (input.hook_type !== \"PreToolUse\") {\n return {\n status: \"skip\",\n latencyMs: Date.now() - start,\n mutations: [],\n log: [\"Not a PreToolUse hook\"],\n };\n }\n\n const agentId = input.agent_id || getCurrentAgent(input.session_id);\n const toolName = input.tool_name;\n\n if (!agentId || !toolName) {\n return {\n status: \"ok\",\n latencyMs: Date.now() - start,\n mutations: [],\n log: [],\n };\n }\n\n if (agentId === BLOCKED_AGENT && BLOCKED_TOOLS.has(toolName)) {\n log.push(`ENFORCEMENT: ${agentId} attempted ${toolName} \u2014 blocked`);\n log.push(`Rerouting to appropriate specialist agent`);\n\n return {\n decision: \"deny\",\n status: \"ok\",\n latencyMs: Date.now() - start,\n mutations: [\n {\n type: \"reroute_tool\",\n toolCall: { tool: toolName, params: input.tool_input },\n toAgent: \"executor\",\n },\n {\n type: \"log\",\n level: \"warn\",\n message: `Delegation enforced: ${agentId} cannot use ${toolName}`,\n },\n ],\n log,\n };\n }\n\n return {\n status: \"ok\",\n latencyMs: Date.now() - start,\n mutations: [],\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// Fail-open: any stdin/parse/processing failure still emits valid JSON and exits 0.\nimport { fileURLToPath } from \"url\";\nimport { runHookMain } from \"./runner.mts\";\n\nif (process.argv[1] === fileURLToPath(import.meta.url)) {\n await runHookMain(processHook, { failOpenDecision: true, hookName: \"delegation-enforcer\" });\n}\n", "/**\n * Shared hook entry-point runner.\n *\n * Hooks must be FAIL-OPEN: any failure (empty stdin, malformed JSON,\n * unexpected processing error) must still emit a valid HookOutput-shaped\n * JSON object on stdout and exit 0. A non-zero exit or non-JSON stdout\n * causes the Copilot CLI to treat the hook as errored, which denies the\n * tool call for PreToolUse hooks.\n *\n * Fail-open events are persisted (best-effort) as JSONL records to\n * ~/.omp/logs/hook-failures.jsonl and mirrored on stderr so failures\n * remain observable without ever touching the stdout JSON contract.\n */\n\nimport { appendFileSync, mkdirSync } from \"fs\";\nimport { homedir } from \"os\";\nimport { join } from \"path\";\n\nexport interface FailOpenOutput {\n decision?: \"allow\";\n status: \"error\";\n latencyMs: number;\n mutations: never[];\n log: string[];\n}\n\nexport interface RunHookOptions {\n /**\n * When true (hooks whose HookOutput supports a decision field), the\n * fail-open output includes `\"decision\": \"allow\"` so the tool call is\n * explicitly allowed.\n */\n failOpenDecision?: boolean;\n /** Hook id recorded in fail-open log entries (stderr + JSONL). */\n hookName?: string;\n}\n\nexport async function readStdin(): Promise<string> {\n const readStdinActual = async (): 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\n const stdinTimeout = new Promise<string>((resolve) =>\n setTimeout(\n () => resolve(\"\"),\n (parseInt(process.env.OMP_HOOK_STDIN_TIMEOUT_MS ?? \"500\") || 500)\n )\n );\n\n return Promise.race([readStdinActual(), stdinTimeout]);\n}\n\n/**\n * Best-effort persistence of a fail-open event. Wrapped in its own\n * try/catch: logging must NEVER break fail-open or the one-JSON-object\n * stdout contract. Writes to stderr and the JSONL log only \u2014 never stdout.\n */\nfunction logHookFailure(hook: string, reason: string): void {\n try {\n process.stderr.write(`[omp hook fail-open] ${hook}: ${reason}\\n`);\n } catch {\n // stderr unavailable \u2014 ignore\n }\n try {\n const logsDir = join(homedir(), \".omp\", \"logs\");\n mkdirSync(logsDir, { recursive: true });\n const record = JSON.stringify({ ts: new Date().toISOString(), hook, reason });\n appendFileSync(join(logsDir, \"hook-failures.jsonl\"), record + \"\\n\", \"utf-8\");\n } catch {\n // best-effort only \u2014 never let logging break fail-open\n }\n}\n\n/**\n * Reads HookInput JSON from stdin, runs the hook, and prints the\n * HookOutput JSON to stdout. Never throws, never exits non-zero,\n * never emits non-JSON to stdout.\n */\nexport async function runHookMain<TInput>(\n processHook: (input: TInput) => unknown,\n options: RunHookOptions = {}\n): Promise<void> {\n let outputJson: string;\n try {\n const input = JSON.parse(await readStdin()) as TInput;\n const serialized = JSON.stringify(processHook(input));\n if (typeof serialized !== \"string\") {\n throw new Error(\"hook produced no serializable output\");\n }\n outputJson = serialized;\n } catch (err) {\n const reason = err instanceof Error ? err.message : String(err);\n logHookFailure(options.hookName ?? \"unknown\", reason);\n const failOpen: FailOpenOutput = {\n ...(options.failOpenDecision ? { decision: \"allow\" as const } : {}),\n status: \"error\",\n latencyMs: 0,\n mutations: [],\n log: [`fail-open: ${reason}`],\n };\n outputJson = JSON.stringify(failOpen);\n }\n console.log(outputJson);\n process.exitCode = 0;\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["homedir", "join", "processHook", "join", "homedir"]
7
7
  }