oh-my-githubcopilot 1.4.0 → 1.5.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +11 -3
- package/.mcp.json +17 -0
- package/CHANGELOG.md +132 -1
- package/README.md +162 -82
- package/agents/analyst.agent.md +27 -0
- package/agents/architect.agent.md +24 -0
- package/agents/code-reviewer.agent.md +24 -0
- package/agents/critic.agent.md +24 -0
- package/agents/debugger.agent.md +24 -0
- package/agents/designer.agent.md +24 -0
- package/agents/document-specialist.agent.md +24 -0
- package/agents/executor.agent.md +27 -0
- package/agents/explorer.agent.md +23 -0
- package/agents/git-master.agent.md +24 -0
- package/agents/orchestrator.agent.md +26 -0
- package/agents/planner.agent.md +24 -0
- package/agents/qa-tester.agent.md +24 -0
- package/agents/researcher.agent.md +18 -0
- package/agents/reviewer.agent.md +23 -0
- package/agents/scientist.agent.md +20 -0
- package/agents/security-reviewer.agent.md +20 -0
- package/agents/simplifier.agent.md +20 -0
- package/agents/test-engineer.agent.md +20 -0
- package/agents/tester.agent.md +20 -0
- package/agents/tracer.agent.md +24 -0
- package/agents/verifier.agent.md +19 -0
- package/agents/writer.agent.md +24 -0
- package/bin/omp-statusline.mjs +179 -0
- package/bin/omp-statusline.mjs.map +7 -0
- package/bin/omp-statusline.sh +21 -0
- package/bin/omp.mjs +309 -15
- package/bin/omp.mjs.map +4 -4
- package/dist/hooks/hud-emitter.mjs +268 -82
- package/dist/hooks/hud-emitter.mjs.map +4 -4
- package/dist/hooks/keyword-detector.mjs +83 -21
- package/dist/hooks/keyword-detector.mjs.map +2 -2
- package/dist/hooks/model-router.mjs +1 -1
- package/dist/hooks/model-router.mjs.map +1 -1
- package/dist/hooks/stop-continuation.mjs +1 -1
- package/dist/hooks/stop-continuation.mjs.map +1 -1
- package/dist/hooks/token-tracker.mjs +2 -1
- package/dist/hooks/token-tracker.mjs.map +2 -2
- package/dist/mcp/server.mjs +57 -41
- package/dist/mcp/server.mjs.map +4 -4
- package/dist/skills/setup.mjs +39 -27
- package/dist/skills/setup.mjs.map +4 -4
- package/hooks/hooks.json +39 -45
- package/package.json +7 -3
- package/plugin.json +49 -0
- package/skills/autopilot/SKILL.md +6 -0
- package/skills/configure-notifications/SKILL.md +6 -0
- package/skills/deep-interview/SKILL.md +6 -0
- package/skills/ecomode/SKILL.md +6 -0
- package/skills/graph-provider/SKILL.md +6 -0
- package/skills/graphify/SKILL.md +6 -0
- package/skills/graphwiki/SKILL.md +6 -0
- package/skills/hud/SKILL.md +6 -0
- package/skills/learner/SKILL.md +6 -0
- package/skills/mcp-setup/SKILL.md +6 -0
- package/skills/note/SKILL.md +6 -0
- package/skills/omp-plan/SKILL.md +6 -0
- package/skills/omp-setup/SKILL.md +15 -1
- package/skills/pipeline/SKILL.md +6 -0
- package/skills/psm/SKILL.md +6 -0
- package/skills/ralph/SKILL.md +6 -0
- package/skills/release/SKILL.md +6 -0
- package/skills/setup/SKILL.md +6 -0
- package/skills/spending/SKILL.md +6 -0
- package/skills/swarm/SKILL.md +6 -0
- package/skills/swe-bench/SKILL.md +6 -0
- package/skills/team/SKILL.md +6 -0
- package/skills/trace/SKILL.md +6 -0
- package/skills/ultrawork/SKILL.md +6 -0
- package/skills/wiki/SKILL.md +6 -0
- package/src/agents/analyst.md +0 -103
- package/src/agents/architect.md +0 -169
- package/src/agents/code-reviewer.md +0 -135
- package/src/agents/critic.md +0 -196
- package/src/agents/debugger.md +0 -132
- package/src/agents/designer.md +0 -103
- package/src/agents/document-specialist.md +0 -111
- package/src/agents/executor.md +0 -120
- package/src/agents/explorer.md +0 -98
- package/src/agents/git-master.md +0 -92
- package/src/agents/orchestrator.md +0 -125
- package/src/agents/planner.md +0 -106
- package/src/agents/qa-tester.md +0 -129
- package/src/agents/researcher.md +0 -102
- package/src/agents/reviewer.md +0 -100
- package/src/agents/scientist.md +0 -150
- package/src/agents/security-reviewer.md +0 -132
- package/src/agents/simplifier.md +0 -109
- package/src/agents/test-engineer.md +0 -124
- package/src/agents/tester.md +0 -102
- package/src/agents/tracer.md +0 -160
- package/src/agents/verifier.md +0 -100
- package/src/agents/writer.md +0 -96
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/hud/statusline.mts", "../src/hud/renderer.mts"],
|
|
4
|
+
"sourcesContent": ["/**\n * HUD statusline helpers and standalone entrypoint.\n *\n * Keeps HUD artifact generation in one place so hooks and shell wrappers\n * can share the same rendering and fallback behavior.\n */\n\nimport { mkdirSync, readFileSync, renameSync, writeFileSync } from \"fs\";\nimport { homedir } from \"os\";\nimport { dirname, join } from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { renderPlain, type HudState, type HudStatus } from \"./renderer.mts\";\n\nconst DEFAULT_VERSION = \"0.0.0\";\nconst DEFAULT_STATUSLINE = \"OMP | hud: no active session\";\nconst DEFAULT_TOKEN_BUDGET = 200_000;\nconst DEFAULT_PREMIUM_REQUESTS_TOTAL = 1500;\n\nexport interface StatuslinePaths {\n legacyLinePath: string;\n hudDir: string;\n statusJsonPath: string;\n displayPath: string;\n tmuxSegmentPath: string;\n}\n\nexport interface HudSnapshot {\n version?: string;\n session_id?: string;\n started_at?: number;\n updated_at?: number;\n model?: string;\n tokens_estimated?: number;\n token_budget?: number;\n context_pct?: number;\n tools_used?: string[];\n skills_used?: string[];\n agents_used?: string[];\n active_mode?: string | null;\n last_output?: string;\n task_progress?: number;\n status?: HudStatus;\n premium_requests?: number;\n premium_requests_total?: number;\n warning_active?: boolean;\n}\n\ninterface SerializedHudState extends Omit<HudState, \"toolsUsed\" | \"skillsUsed\"> {\n toolsUsed: string[];\n skillsUsed: string[];\n}\n\nexport function getStatuslinePaths(home = process.env[\"HOME\"] || homedir()): StatuslinePaths {\n const ompDir = join(home, \".omp\");\n const hudDir = join(ompDir, \"hud\");\n return {\n legacyLinePath: join(ompDir, \"hud.line\"),\n hudDir,\n statusJsonPath: join(hudDir, \"status.json\"),\n displayPath: join(hudDir, \"display.txt\"),\n tmuxSegmentPath: join(hudDir, \"tmux-segment.sh\"),\n };\n}\n\nfunction ensureParent(filePath: string): void {\n mkdirSync(dirname(filePath), { recursive: true });\n}\n\nfunction writeAtomic(filePath: string, content: string, mode?: number): void {\n ensureParent(filePath);\n const tempPath = `${filePath}.tmp`;\n writeFileSync(tempPath, content, mode === undefined ? \"utf-8\" : { encoding: \"utf-8\", mode });\n renameSync(tempPath, filePath);\n}\n\nfunction normalizeStringArray(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n return value.filter((item): item is string => typeof item === \"string\");\n}\n\nfunction serializeHudState(state: HudState): SerializedHudState {\n return {\n ...state,\n toolsUsed: Array.from(state.toolsUsed),\n skillsUsed: Array.from(state.skillsUsed),\n };\n}\n\nfunction deserializeHudState(raw: unknown): HudState | null {\n if (!raw || typeof raw !== \"object\") return null;\n const value = raw as Record<string, unknown>;\n const toolsUsed = new Set(normalizeStringArray(value.toolsUsed));\n const skillsUsed = new Set(normalizeStringArray(value.skillsUsed));\n const agentsActive = normalizeStringArray(value.agentsActive);\n const status = typeof value.status === \"string\" ? (value.status as HudStatus) : \"idle\";\n\n return {\n sessionId: typeof value.sessionId === \"string\" ? value.sessionId : \"default\",\n activeMode: typeof value.activeMode === \"string\" ? value.activeMode : null,\n activeModel: typeof value.activeModel === \"string\" ? value.activeModel : \"sonnet\",\n contextPct: typeof value.contextPct === \"number\" ? value.contextPct : 0,\n tokensUsed: typeof value.tokensUsed === \"number\" ? value.tokensUsed : 0,\n tokensTotal: typeof value.tokensTotal === \"number\" ? value.tokensTotal : DEFAULT_TOKEN_BUDGET,\n agentsActive,\n lastAgent: typeof value.lastAgent === \"string\" ? value.lastAgent : agentsActive.at(-1) ?? \"-\",\n lastOutput: typeof value.lastOutput === \"string\" ? value.lastOutput : \"\",\n taskProgress: typeof value.taskProgress === \"number\" ? value.taskProgress : 0,\n startedAt: typeof value.startedAt === \"number\" ? value.startedAt : Date.now(),\n updatedAt: typeof value.updatedAt === \"number\" ? value.updatedAt : Date.now(),\n version: typeof value.version === \"string\" ? value.version : DEFAULT_VERSION,\n status,\n sessionDurationMs: typeof value.sessionDurationMs === \"number\" ? value.sessionDurationMs : 0,\n cumulativeAgentsUsed: typeof value.cumulativeAgentsUsed === \"number\" ? value.cumulativeAgentsUsed : agentsActive.length,\n toolsUsed,\n skillsUsed,\n toolsTotal: typeof value.toolsTotal === \"number\" ? value.toolsTotal : 13,\n skillsTotal: typeof value.skillsTotal === \"number\" ? value.skillsTotal : 25,\n agentsTotal: typeof value.agentsTotal === \"number\" ? value.agentsTotal : 23,\n premiumRequests: typeof value.premiumRequests === \"number\" ? value.premiumRequests : 0,\n premiumRequestsTotal: typeof value.premiumRequestsTotal === \"number\" ? value.premiumRequestsTotal : DEFAULT_PREMIUM_REQUESTS_TOTAL,\n warningActive: typeof value.warningActive === \"boolean\" ? value.warningActive : false,\n };\n}\n\nexport function buildHudState(snapshot: HudSnapshot, now = Date.now()): HudState {\n const startedAt = snapshot.started_at ?? now;\n const updatedAt = snapshot.updated_at ?? now;\n const toolsUsed = new Set(normalizeStringArray(snapshot.tools_used));\n const skillsUsed = new Set(normalizeStringArray(snapshot.skills_used));\n const agentsActive = normalizeStringArray(snapshot.agents_used);\n\n return {\n sessionId: snapshot.session_id ?? \"default\",\n activeMode: snapshot.active_mode ?? null,\n activeModel: snapshot.model ?? \"sonnet\",\n contextPct: snapshot.context_pct ?? 0,\n tokensUsed: snapshot.tokens_estimated ?? 0,\n tokensTotal: snapshot.token_budget ?? DEFAULT_TOKEN_BUDGET,\n agentsActive,\n lastAgent: agentsActive.at(-1) ?? \"-\",\n lastOutput: snapshot.last_output ?? \"\",\n taskProgress: snapshot.task_progress ?? 0,\n startedAt,\n updatedAt,\n version: snapshot.version ?? DEFAULT_VERSION,\n status: snapshot.status ?? \"idle\",\n sessionDurationMs: Math.max(0, updatedAt - startedAt),\n cumulativeAgentsUsed: agentsActive.length,\n toolsUsed,\n skillsUsed,\n toolsTotal: 13,\n skillsTotal: 25,\n agentsTotal: 23,\n premiumRequests: snapshot.premium_requests ?? 0,\n premiumRequestsTotal: snapshot.premium_requests_total ?? DEFAULT_PREMIUM_REQUESTS_TOTAL,\n warningActive: snapshot.warning_active ?? false,\n };\n}\n\nexport function writeHudArtifacts(snapshot: HudSnapshot, paths = getStatuslinePaths()): { line: string; state: HudState; paths: StatuslinePaths } {\n const state = buildHudState(snapshot);\n const line = renderPlain(state);\n const serializedState = `${JSON.stringify(serializeHudState(state), null, 2)}\\n`;\n\n writeAtomic(paths.statusJsonPath, serializedState);\n writeAtomic(paths.displayPath, `${line}\\n`);\n writeAtomic(paths.tmuxSegmentPath, `${line}\\n`, 0o755);\n writeAtomic(paths.legacyLinePath, `${line}\\n`);\n\n return { line, state, paths };\n}\n\nexport function readStatusline(paths = getStatuslinePaths()): string {\n try {\n const line = readFileSync(paths.displayPath, \"utf-8\").trim();\n if (line) return line;\n } catch {\n // Fall through to other sources.\n }\n\n try {\n const parsed = JSON.parse(readFileSync(paths.statusJsonPath, \"utf-8\"));\n const state = deserializeHudState(parsed);\n if (state) return renderPlain(state);\n } catch {\n // Fall through to legacy file.\n }\n\n try {\n const line = readFileSync(paths.legacyLinePath, \"utf-8\").trim();\n if (line) return line;\n } catch {\n // No HUD artifacts yet.\n }\n\n return DEFAULT_STATUSLINE;\n}\n\nif (process.argv[1] === fileURLToPath(import.meta.url)) {\n console.log(readStatusline());\n}\n", "/**\n * HUD Renderer\n * Formats HudState into ANSI or plain text status lines.\n */\n\n\nexport interface HudState {\n sessionId: string;\n activeMode: string | null;\n activeModel: string;\n contextPct: number;\n tokensUsed: number;\n tokensTotal: number;\n agentsActive: string[];\n lastAgent: string;\n lastOutput: string;\n taskProgress: number;\n startedAt: number;\n updatedAt: number;\n version: string;\n status: HudStatus;\n sessionDurationMs: number;\n cumulativeAgentsUsed: number;\n toolsUsed: Set<string>;\n skillsUsed: Set<string>;\n toolsTotal: number;\n skillsTotal: number;\n agentsTotal: number;\n premiumRequests: number;\n premiumRequestsTotal: number;\n warningActive: boolean;\n}\n\nexport type HudStatus = \"idle\" | \"running\" | \"waiting\" | \"complete\" | \"error\" | \"eco\";\n\nconst STATUS_ICONS: Record<HudStatus, string> = {\n idle: \"\u25CB\",\n running: \"\u25CF\",\n waiting: \"\u25F7\",\n complete: \"\u2713\",\n error: \"\u2717\",\n eco: \"\u26A1\",\n};\n\nfunction formatAge(startedAt: number): string {\n const elapsed = Date.now() - startedAt;\n const mins = Math.floor(elapsed / 60000);\n if (mins < 60) return `${mins}m`;\n const hours = Math.floor(mins / 60);\n const remainingMins = mins % 60;\n return `${hours}h${remainingMins}m`;\n}\n\nfunction formatTokens(tokens: number): string {\n if (tokens >= 1_000_000) return `${(tokens / 1_000_000).toFixed(1)}M`;\n if (tokens >= 1_000) return `${(tokens / 1_000).toFixed(1)}k`;\n return `${tokens}`;\n}\n\nfunction ctxColor(pct: number): string {\n if (pct < 60) return \"\\x1b[32m\"; // green\n if (pct < 85) return \"\\x1b[33m\"; // yellow\n return \"\\x1b[31m\"; // red\n}\n\nfunction reset(): string {\n return \"\\x1b[0m\";\n}\n\n/**\n * Render HUD line with ANSI color codes.\n * Format: [OMP v1.0.0] mode | model | ctx:N% | tok:~Nk/Nk | Nm | tools:N/N | skills:N/N | agents:N/N | N% status\n */\nexport function renderAnsi(state: HudState): string {\n const age = formatAge(state.startedAt);\n const tokens = formatTokens(state.tokensUsed);\n const ctx = state.contextPct;\n const mode = state.activeMode || \"-\";\n const model = state.activeModel || \"sonnet\";\n const icon = STATUS_ICONS[state.status] || \"\u25CF\";\n\n const ctxClr = ctxColor(ctx);\n const ctxStr = `${ctxClr}ctx:${ctx}%${reset()}`;\n const tokenStr = `tok:~${tokens}/${state.tokensTotal}`;\n const modeStr = mode === \"-\" ? \"-\" : `\\x1b[36m${mode}${reset()}`; // cyan for active modes\n\n const reqWarning = state.warningActive ? \" !!\" : \"\";\n const reqStr = `req:${state.premiumRequests ?? 0}/${state.premiumRequestsTotal ?? 1500}${reqWarning}`;\n\n return `[OMP v${state.version}] ${modeStr} | ${model} | ${ctxStr} | ${tokenStr} | ${reqStr} | ${age} | tools:${state.toolsUsed?.size || 0}/${state.toolsTotal ?? 13} | skills:${state.skillsUsed?.size || 0}/${state.skillsTotal ?? 25} | agents:${state.cumulativeAgentsUsed}/${state.agentsTotal ?? 23} | ${icon} ${state.status}`;\n}\n\n/**\n * Render HUD line as plain text (no ANSI codes).\n * Format: [OMP v1.0.0] mode | model | ctx:N% | tok:~Nk/Nk | Nm | tools:N/N | skills:N/N | agents:N/N | N% status\n */\nexport function renderPlain(state: HudState): string {\n const age = formatAge(state.startedAt);\n const tokens = formatTokens(state.tokensUsed);\n const ctx = state.contextPct;\n const mode = state.activeMode || \"-\";\n const model = state.activeModel || \"sonnet\";\n\n const reqWarningPlain = state.warningActive ? \" !!\" : \"\";\n const reqStrPlain = `req:${state.premiumRequests ?? 0}/${state.premiumRequestsTotal ?? 1500}${reqWarningPlain}`;\n\n return `[OMP v${state.version}] ${mode} | ${model} | ctx:${ctx}% | tok:~${tokens}/${state.tokensTotal} | ${reqStrPlain} | ${age} | tools:${state.toolsUsed?.size || 0}/${state.toolsTotal ?? 13} | skills:${state.skillsUsed?.size || 0}/${state.skillsTotal ?? 25} | agents:${state.cumulativeAgentsUsed}/${state.agentsTotal ?? 23} | ${state.status}`;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
|
5
|
+
ENTRY="$SCRIPT_DIR/omp-statusline.mjs"
|
|
6
|
+
DISPLAY_PATH="${OMP_HUD_DISPLAY_PATH:-$HOME/.omp/hud/display.txt}"
|
|
7
|
+
LEGACY_PATH="${OMP_HUD_LEGACY_PATH:-$HOME/.omp/hud.line}"
|
|
8
|
+
|
|
9
|
+
if [[ -f "$ENTRY" ]]; then
|
|
10
|
+
exec node "$ENTRY" "$@"
|
|
11
|
+
fi
|
|
12
|
+
|
|
13
|
+
if [[ -r "$DISPLAY_PATH" ]]; then
|
|
14
|
+
exec cat "$DISPLAY_PATH"
|
|
15
|
+
fi
|
|
16
|
+
|
|
17
|
+
if [[ -r "$LEGACY_PATH" ]]; then
|
|
18
|
+
exec cat "$LEGACY_PATH"
|
|
19
|
+
fi
|
|
20
|
+
|
|
21
|
+
printf 'OMP | hud: no active session\n'
|
package/bin/omp.mjs
CHANGED
|
@@ -1,10 +1,299 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __esm = (fn, res) => function __init() {
|
|
5
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
6
|
+
};
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
// src/hud/renderer.mts
|
|
13
|
+
function formatAge(startedAt) {
|
|
14
|
+
const elapsed = Date.now() - startedAt;
|
|
15
|
+
const mins = Math.floor(elapsed / 6e4);
|
|
16
|
+
if (mins < 60) return `${mins}m`;
|
|
17
|
+
const hours = Math.floor(mins / 60);
|
|
18
|
+
const remainingMins = mins % 60;
|
|
19
|
+
return `${hours}h${remainingMins}m`;
|
|
20
|
+
}
|
|
21
|
+
function formatTokens(tokens) {
|
|
22
|
+
if (tokens >= 1e6) return `${(tokens / 1e6).toFixed(1)}M`;
|
|
23
|
+
if (tokens >= 1e3) return `${(tokens / 1e3).toFixed(1)}k`;
|
|
24
|
+
return `${tokens}`;
|
|
25
|
+
}
|
|
26
|
+
function ctxColor(pct) {
|
|
27
|
+
if (pct < 60) return "\x1B[32m";
|
|
28
|
+
if (pct < 85) return "\x1B[33m";
|
|
29
|
+
return "\x1B[31m";
|
|
30
|
+
}
|
|
31
|
+
function reset() {
|
|
32
|
+
return "\x1B[0m";
|
|
33
|
+
}
|
|
34
|
+
function renderAnsi(state) {
|
|
35
|
+
const age = formatAge(state.startedAt);
|
|
36
|
+
const tokens = formatTokens(state.tokensUsed);
|
|
37
|
+
const ctx = state.contextPct;
|
|
38
|
+
const mode = state.activeMode || "-";
|
|
39
|
+
const model = state.activeModel || "sonnet";
|
|
40
|
+
const icon = STATUS_ICONS[state.status] || "\u25CF";
|
|
41
|
+
const ctxClr = ctxColor(ctx);
|
|
42
|
+
const ctxStr = `${ctxClr}ctx:${ctx}%${reset()}`;
|
|
43
|
+
const tokenStr = `tok:~${tokens}/${state.tokensTotal}`;
|
|
44
|
+
const modeStr = mode === "-" ? "-" : `\x1B[36m${mode}${reset()}`;
|
|
45
|
+
const reqWarning = state.warningActive ? " !!" : "";
|
|
46
|
+
const reqStr = `req:${state.premiumRequests ?? 0}/${state.premiumRequestsTotal ?? 1500}${reqWarning}`;
|
|
47
|
+
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}`;
|
|
48
|
+
}
|
|
49
|
+
function renderPlain(state) {
|
|
50
|
+
const age = formatAge(state.startedAt);
|
|
51
|
+
const tokens = formatTokens(state.tokensUsed);
|
|
52
|
+
const ctx = state.contextPct;
|
|
53
|
+
const mode = state.activeMode || "-";
|
|
54
|
+
const model = state.activeModel || "sonnet";
|
|
55
|
+
const reqWarningPlain = state.warningActive ? " !!" : "";
|
|
56
|
+
const reqStrPlain = `req:${state.premiumRequests ?? 0}/${state.premiumRequestsTotal ?? 1500}${reqWarningPlain}`;
|
|
57
|
+
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}`;
|
|
58
|
+
}
|
|
59
|
+
var STATUS_ICONS;
|
|
60
|
+
var init_renderer = __esm({
|
|
61
|
+
"src/hud/renderer.mts"() {
|
|
62
|
+
"use strict";
|
|
63
|
+
STATUS_ICONS = {
|
|
64
|
+
idle: "\u25CB",
|
|
65
|
+
running: "\u25CF",
|
|
66
|
+
waiting: "\u25F7",
|
|
67
|
+
complete: "\u2713",
|
|
68
|
+
error: "\u2717",
|
|
69
|
+
eco: "\u26A1"
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// src/hud/statusline.mts
|
|
75
|
+
import { mkdirSync, readFileSync, renameSync, writeFileSync } from "fs";
|
|
76
|
+
import { homedir } from "os";
|
|
77
|
+
import { dirname, join } from "path";
|
|
78
|
+
import { fileURLToPath } from "url";
|
|
79
|
+
function getStatuslinePaths(home = process.env["HOME"] || homedir()) {
|
|
80
|
+
const ompDir = join(home, ".omp");
|
|
81
|
+
const hudDir = join(ompDir, "hud");
|
|
82
|
+
return {
|
|
83
|
+
legacyLinePath: join(ompDir, "hud.line"),
|
|
84
|
+
hudDir,
|
|
85
|
+
statusJsonPath: join(hudDir, "status.json"),
|
|
86
|
+
displayPath: join(hudDir, "display.txt"),
|
|
87
|
+
tmuxSegmentPath: join(hudDir, "tmux-segment.sh")
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
function ensureParent(filePath) {
|
|
91
|
+
mkdirSync(dirname(filePath), { recursive: true });
|
|
92
|
+
}
|
|
93
|
+
function writeAtomic(filePath, content, mode) {
|
|
94
|
+
ensureParent(filePath);
|
|
95
|
+
const tempPath = `${filePath}.tmp`;
|
|
96
|
+
writeFileSync(tempPath, content, mode === void 0 ? "utf-8" : { encoding: "utf-8", mode });
|
|
97
|
+
renameSync(tempPath, filePath);
|
|
98
|
+
}
|
|
99
|
+
function normalizeStringArray(value) {
|
|
100
|
+
if (!Array.isArray(value)) return [];
|
|
101
|
+
return value.filter((item) => typeof item === "string");
|
|
102
|
+
}
|
|
103
|
+
function serializeHudState(state) {
|
|
104
|
+
return {
|
|
105
|
+
...state,
|
|
106
|
+
toolsUsed: Array.from(state.toolsUsed),
|
|
107
|
+
skillsUsed: Array.from(state.skillsUsed)
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
function deserializeHudState(raw) {
|
|
111
|
+
if (!raw || typeof raw !== "object") return null;
|
|
112
|
+
const value = raw;
|
|
113
|
+
const toolsUsed = new Set(normalizeStringArray(value.toolsUsed));
|
|
114
|
+
const skillsUsed = new Set(normalizeStringArray(value.skillsUsed));
|
|
115
|
+
const agentsActive = normalizeStringArray(value.agentsActive);
|
|
116
|
+
const status = typeof value.status === "string" ? value.status : "idle";
|
|
117
|
+
return {
|
|
118
|
+
sessionId: typeof value.sessionId === "string" ? value.sessionId : "default",
|
|
119
|
+
activeMode: typeof value.activeMode === "string" ? value.activeMode : null,
|
|
120
|
+
activeModel: typeof value.activeModel === "string" ? value.activeModel : "sonnet",
|
|
121
|
+
contextPct: typeof value.contextPct === "number" ? value.contextPct : 0,
|
|
122
|
+
tokensUsed: typeof value.tokensUsed === "number" ? value.tokensUsed : 0,
|
|
123
|
+
tokensTotal: typeof value.tokensTotal === "number" ? value.tokensTotal : DEFAULT_TOKEN_BUDGET,
|
|
124
|
+
agentsActive,
|
|
125
|
+
lastAgent: typeof value.lastAgent === "string" ? value.lastAgent : agentsActive.at(-1) ?? "-",
|
|
126
|
+
lastOutput: typeof value.lastOutput === "string" ? value.lastOutput : "",
|
|
127
|
+
taskProgress: typeof value.taskProgress === "number" ? value.taskProgress : 0,
|
|
128
|
+
startedAt: typeof value.startedAt === "number" ? value.startedAt : Date.now(),
|
|
129
|
+
updatedAt: typeof value.updatedAt === "number" ? value.updatedAt : Date.now(),
|
|
130
|
+
version: typeof value.version === "string" ? value.version : DEFAULT_VERSION,
|
|
131
|
+
status,
|
|
132
|
+
sessionDurationMs: typeof value.sessionDurationMs === "number" ? value.sessionDurationMs : 0,
|
|
133
|
+
cumulativeAgentsUsed: typeof value.cumulativeAgentsUsed === "number" ? value.cumulativeAgentsUsed : agentsActive.length,
|
|
134
|
+
toolsUsed,
|
|
135
|
+
skillsUsed,
|
|
136
|
+
toolsTotal: typeof value.toolsTotal === "number" ? value.toolsTotal : 13,
|
|
137
|
+
skillsTotal: typeof value.skillsTotal === "number" ? value.skillsTotal : 25,
|
|
138
|
+
agentsTotal: typeof value.agentsTotal === "number" ? value.agentsTotal : 23,
|
|
139
|
+
premiumRequests: typeof value.premiumRequests === "number" ? value.premiumRequests : 0,
|
|
140
|
+
premiumRequestsTotal: typeof value.premiumRequestsTotal === "number" ? value.premiumRequestsTotal : DEFAULT_PREMIUM_REQUESTS_TOTAL,
|
|
141
|
+
warningActive: typeof value.warningActive === "boolean" ? value.warningActive : false
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
function buildHudState(snapshot, now = Date.now()) {
|
|
145
|
+
const startedAt = snapshot.started_at ?? now;
|
|
146
|
+
const updatedAt = snapshot.updated_at ?? now;
|
|
147
|
+
const toolsUsed = new Set(normalizeStringArray(snapshot.tools_used));
|
|
148
|
+
const skillsUsed = new Set(normalizeStringArray(snapshot.skills_used));
|
|
149
|
+
const agentsActive = normalizeStringArray(snapshot.agents_used);
|
|
150
|
+
return {
|
|
151
|
+
sessionId: snapshot.session_id ?? "default",
|
|
152
|
+
activeMode: snapshot.active_mode ?? null,
|
|
153
|
+
activeModel: snapshot.model ?? "sonnet",
|
|
154
|
+
contextPct: snapshot.context_pct ?? 0,
|
|
155
|
+
tokensUsed: snapshot.tokens_estimated ?? 0,
|
|
156
|
+
tokensTotal: snapshot.token_budget ?? DEFAULT_TOKEN_BUDGET,
|
|
157
|
+
agentsActive,
|
|
158
|
+
lastAgent: agentsActive.at(-1) ?? "-",
|
|
159
|
+
lastOutput: snapshot.last_output ?? "",
|
|
160
|
+
taskProgress: snapshot.task_progress ?? 0,
|
|
161
|
+
startedAt,
|
|
162
|
+
updatedAt,
|
|
163
|
+
version: snapshot.version ?? DEFAULT_VERSION,
|
|
164
|
+
status: snapshot.status ?? "idle",
|
|
165
|
+
sessionDurationMs: Math.max(0, updatedAt - startedAt),
|
|
166
|
+
cumulativeAgentsUsed: agentsActive.length,
|
|
167
|
+
toolsUsed,
|
|
168
|
+
skillsUsed,
|
|
169
|
+
toolsTotal: 13,
|
|
170
|
+
skillsTotal: 25,
|
|
171
|
+
agentsTotal: 23,
|
|
172
|
+
premiumRequests: snapshot.premium_requests ?? 0,
|
|
173
|
+
premiumRequestsTotal: snapshot.premium_requests_total ?? DEFAULT_PREMIUM_REQUESTS_TOTAL,
|
|
174
|
+
warningActive: snapshot.warning_active ?? false
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
function writeHudArtifacts(snapshot, paths = getStatuslinePaths()) {
|
|
178
|
+
const state = buildHudState(snapshot);
|
|
179
|
+
const line = renderPlain(state);
|
|
180
|
+
const serializedState = `${JSON.stringify(serializeHudState(state), null, 2)}
|
|
181
|
+
`;
|
|
182
|
+
writeAtomic(paths.statusJsonPath, serializedState);
|
|
183
|
+
writeAtomic(paths.displayPath, `${line}
|
|
184
|
+
`);
|
|
185
|
+
writeAtomic(paths.tmuxSegmentPath, `${line}
|
|
186
|
+
`, 493);
|
|
187
|
+
writeAtomic(paths.legacyLinePath, `${line}
|
|
188
|
+
`);
|
|
189
|
+
return { line, state, paths };
|
|
190
|
+
}
|
|
191
|
+
function readStatusline(paths = getStatuslinePaths()) {
|
|
192
|
+
try {
|
|
193
|
+
const line = readFileSync(paths.displayPath, "utf-8").trim();
|
|
194
|
+
if (line) return line;
|
|
195
|
+
} catch {
|
|
196
|
+
}
|
|
197
|
+
try {
|
|
198
|
+
const parsed = JSON.parse(readFileSync(paths.statusJsonPath, "utf-8"));
|
|
199
|
+
const state = deserializeHudState(parsed);
|
|
200
|
+
if (state) return renderPlain(state);
|
|
201
|
+
} catch {
|
|
202
|
+
}
|
|
203
|
+
try {
|
|
204
|
+
const line = readFileSync(paths.legacyLinePath, "utf-8").trim();
|
|
205
|
+
if (line) return line;
|
|
206
|
+
} catch {
|
|
207
|
+
}
|
|
208
|
+
return DEFAULT_STATUSLINE;
|
|
209
|
+
}
|
|
210
|
+
var DEFAULT_VERSION, DEFAULT_STATUSLINE, DEFAULT_TOKEN_BUDGET, DEFAULT_PREMIUM_REQUESTS_TOTAL;
|
|
211
|
+
var init_statusline = __esm({
|
|
212
|
+
"src/hud/statusline.mts"() {
|
|
213
|
+
"use strict";
|
|
214
|
+
init_renderer();
|
|
215
|
+
DEFAULT_VERSION = "0.0.0";
|
|
216
|
+
DEFAULT_STATUSLINE = "OMP | hud: no active session";
|
|
217
|
+
DEFAULT_TOKEN_BUDGET = 2e5;
|
|
218
|
+
DEFAULT_PREMIUM_REQUESTS_TOTAL = 1500;
|
|
219
|
+
if (process.argv[1] === fileURLToPath(import.meta.url)) {
|
|
220
|
+
console.log(readStatusline());
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
// src/hud/watch.mts
|
|
226
|
+
var watch_exports = {};
|
|
227
|
+
__export(watch_exports, {
|
|
228
|
+
runHudWatch: () => runHudWatch
|
|
229
|
+
});
|
|
230
|
+
import { readFileSync as readFileSync2 } from "fs";
|
|
231
|
+
import { homedir as homedir2 } from "os";
|
|
232
|
+
import { join as join2 } from "path";
|
|
233
|
+
function readSnapshot() {
|
|
234
|
+
try {
|
|
235
|
+
const raw = readFileSync2(STATE_PATH, "utf-8");
|
|
236
|
+
const parsed = JSON.parse(raw);
|
|
237
|
+
return parsed;
|
|
238
|
+
} catch {
|
|
239
|
+
return null;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
function tick(paths = getStatuslinePaths()) {
|
|
243
|
+
const snapshot = readSnapshot();
|
|
244
|
+
if (!snapshot) return;
|
|
245
|
+
const now = Date.now();
|
|
246
|
+
const state = buildHudState(snapshot, now);
|
|
247
|
+
writeHudArtifacts(snapshot, paths);
|
|
248
|
+
process.stdout.write("\x1B[2J\x1B[H" + renderAnsi(state) + "\x1B[K\n\x1B[J");
|
|
249
|
+
}
|
|
250
|
+
function runHudWatch() {
|
|
251
|
+
const intervalMs = Math.max(
|
|
252
|
+
500,
|
|
253
|
+
parseInt(process.env["OMP_HUD_INTERVAL"] ?? "", 10) || DEFAULT_INTERVAL_MS
|
|
254
|
+
);
|
|
255
|
+
const paths = getStatuslinePaths();
|
|
256
|
+
process.stdout.write("\x1B[?25l");
|
|
257
|
+
try {
|
|
258
|
+
tick(paths);
|
|
259
|
+
} catch {
|
|
260
|
+
}
|
|
261
|
+
const timer = setInterval(() => {
|
|
262
|
+
try {
|
|
263
|
+
tick(paths);
|
|
264
|
+
} catch {
|
|
265
|
+
}
|
|
266
|
+
}, intervalMs);
|
|
267
|
+
const stop = () => {
|
|
268
|
+
clearInterval(timer);
|
|
269
|
+
process.stdout.write("\x1B[?25h\x1B[2J\x1B[H");
|
|
270
|
+
process.exit(0);
|
|
271
|
+
};
|
|
272
|
+
process.on("SIGINT", stop);
|
|
273
|
+
process.on("SIGTERM", stop);
|
|
274
|
+
}
|
|
275
|
+
var DEFAULT_INTERVAL_MS, STATE_PATH;
|
|
276
|
+
var init_watch = __esm({
|
|
277
|
+
"src/hud/watch.mts"() {
|
|
278
|
+
"use strict";
|
|
279
|
+
init_statusline();
|
|
280
|
+
init_renderer();
|
|
281
|
+
DEFAULT_INTERVAL_MS = 2e3;
|
|
282
|
+
STATE_PATH = join2(homedir2(), ".omp", "state", "session.json");
|
|
283
|
+
}
|
|
284
|
+
});
|
|
285
|
+
|
|
1
286
|
// src/index.mts
|
|
2
287
|
import { parseArgs } from "util";
|
|
3
|
-
|
|
288
|
+
import { createRequire } from "module";
|
|
289
|
+
var _require = createRequire(import.meta.url);
|
|
290
|
+
var { version: PKG_VERSION, name: PKG_NAME } = _require("../package.json");
|
|
291
|
+
var { positionals, values: flags } = parseArgs({
|
|
4
292
|
args: process.argv.slice(2),
|
|
5
293
|
options: {
|
|
6
294
|
help: { type: "boolean", default: false },
|
|
7
|
-
version: { type: "boolean", default: false }
|
|
295
|
+
version: { type: "boolean", default: false },
|
|
296
|
+
watch: { type: "boolean", default: false }
|
|
8
297
|
},
|
|
9
298
|
allowPositionals: true
|
|
10
299
|
});
|
|
@@ -12,10 +301,15 @@ var subcommand = positionals[0] || "hud";
|
|
|
12
301
|
async function main() {
|
|
13
302
|
switch (subcommand) {
|
|
14
303
|
case "hud":
|
|
15
|
-
|
|
304
|
+
if (flags.watch) {
|
|
305
|
+
const { runHudWatch: runHudWatch2 } = await Promise.resolve().then(() => (init_watch(), watch_exports));
|
|
306
|
+
runHudWatch2();
|
|
307
|
+
} else {
|
|
308
|
+
await printHud();
|
|
309
|
+
}
|
|
16
310
|
break;
|
|
17
311
|
case "version":
|
|
18
|
-
console.log(
|
|
312
|
+
console.log(`${PKG_NAME} v${PKG_VERSION}`);
|
|
19
313
|
break;
|
|
20
314
|
case "psm":
|
|
21
315
|
await runPsm(positionals.slice(1));
|
|
@@ -31,26 +325,26 @@ async function main() {
|
|
|
31
325
|
}
|
|
32
326
|
async function printHud() {
|
|
33
327
|
try {
|
|
34
|
-
const { readFileSync } = await import("fs");
|
|
35
|
-
const { join } = await import("path");
|
|
36
|
-
const { homedir } = await import("os");
|
|
37
|
-
const hudPath =
|
|
38
|
-
const line =
|
|
328
|
+
const { readFileSync: readFileSync3 } = await import("fs");
|
|
329
|
+
const { join: join3 } = await import("path");
|
|
330
|
+
const { homedir: homedir3 } = await import("os");
|
|
331
|
+
const hudPath = join3(homedir3(), ".omp", "hud.line");
|
|
332
|
+
const line = readFileSync3(hudPath, "utf-8").trim();
|
|
39
333
|
console.log(line);
|
|
40
334
|
} catch {
|
|
41
|
-
console.log(
|
|
335
|
+
console.log(`OMP v${PKG_VERSION} | hud: no active session`);
|
|
42
336
|
}
|
|
43
337
|
}
|
|
44
338
|
async function runPsm(_args) {
|
|
45
339
|
console.log("PSM commands:");
|
|
46
|
-
console.log(" /
|
|
47
|
-
console.log(" /
|
|
48
|
-
console.log(" /
|
|
49
|
-
console.log(" /
|
|
340
|
+
console.log(" /omp:psm create <name> Create isolated worktree session");
|
|
341
|
+
console.log(" /omp:psm list List active sessions");
|
|
342
|
+
console.log(" /omp:psm switch <name> Switch to session");
|
|
343
|
+
console.log(" /omp:psm destroy <name> Destroy session");
|
|
50
344
|
}
|
|
51
345
|
async function runBench(_args) {
|
|
52
346
|
console.log("SWE-bench requires Node.js subprocess with Python evaluation harness.");
|
|
53
|
-
console.log("Usage: /
|
|
347
|
+
console.log("Usage: /omp:swe-bench --suite lite --compare baseline");
|
|
54
348
|
}
|
|
55
349
|
main().catch((err) => {
|
|
56
350
|
console.error(err);
|
package/bin/omp.mjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/index.mts"],
|
|
4
|
-
"sourcesContent": ["/**\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 */\n\nimport { parseArgs } from \"util\";\n\nconst { positionals } = parseArgs({\n args: process.argv.slice(2),\n options: {\n help: { type: \"boolean\", default: false },\n version: { type: \"boolean\", default: false },\n },\n allowPositionals: true,\n});\n\nconst subcommand = positionals[0] || \"hud\";\n\nasync function main() {\n switch (subcommand) {\n case \"hud\":\n await printHud();\n break;\n case \"version\":\n console.log(\"oh-my-githubcopilot v1.0.0\");\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 default:\n console.error(`Unknown subcommand: ${subcommand}`);\n console.error(\"Usage: omp [hud|version|psm|bench]\");\n process.exit(1);\n }\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 v1.0.0 | 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(\" /oh-my-githubcopilot:psm create <name> Create isolated worktree session\");\n console.log(\" /oh-my-githubcopilot:psm list List active sessions\");\n console.log(\" /oh-my-githubcopilot:psm switch <name> Switch to session\");\n console.log(\" /oh-my-githubcopilot:psm destroy <name> Destroy session\");\n}\n\nasync function runBench(_args: string[]) {\n console.log(\"SWE-bench requires Node.js subprocess with Python evaluation harness.\");\n console.log(\"Usage: /oh-my-githubcopilot:swe-bench --suite lite --compare baseline\");\n}\n\nmain().catch((err) => {\n console.error(err);\n process.exit(1);\n});\n"],
|
|
5
|
-
"mappings": ";
|
|
6
|
-
"names": []
|
|
3
|
+
"sources": ["../src/hud/renderer.mts", "../src/hud/statusline.mts", "../src/hud/watch.mts", "../src/index.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 * 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 */\n\nimport { parseArgs } from \"util\";\nimport { createRequire } from \"module\";\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\";\n\nasync function main() {\n switch (subcommand) {\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 default:\n console.error(`Unknown subcommand: ${subcommand}`);\n console.error(\"Usage: omp [hud|version|psm|bench]\");\n process.exit(1);\n }\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 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"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["readFileSync", "homedir", "join", "runHudWatch", "readFileSync", "join", "homedir"]
|
|
7
7
|
}
|