oh-my-githubcopilot 1.4.1 → 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 +124 -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 +302 -13
- 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
|
@@ -1,21 +1,16 @@
|
|
|
1
1
|
// src/hooks/hud-emitter.mts
|
|
2
|
-
import { readFileSync, writeFileSync
|
|
2
|
+
import { mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
3
|
+
import { createRequire } from "module";
|
|
4
|
+
import { homedir as homedir2 } from "os";
|
|
5
|
+
import { join as join2 } from "path";
|
|
6
|
+
|
|
7
|
+
// src/hud/statusline.mts
|
|
8
|
+
import { mkdirSync, readFileSync, renameSync, writeFileSync } from "fs";
|
|
3
9
|
import { homedir } from "os";
|
|
4
|
-
import { join } from "path";
|
|
10
|
+
import { dirname, join } from "path";
|
|
5
11
|
import { fileURLToPath } from "url";
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
if (sessionId) {
|
|
9
|
-
return join(base, "sessions", sessionId, "session.json");
|
|
10
|
-
}
|
|
11
|
-
return join(base, "session.json");
|
|
12
|
-
}
|
|
13
|
-
function getHudLinePath() {
|
|
14
|
-
return join(homedir(), ".omp", "hud.line");
|
|
15
|
-
}
|
|
16
|
-
function ensureDir(path) {
|
|
17
|
-
mkdirSync(path.substring(0, path.lastIndexOf("/")), { recursive: true });
|
|
18
|
-
}
|
|
12
|
+
|
|
13
|
+
// src/hud/renderer.mts
|
|
19
14
|
function formatAge(startedAt) {
|
|
20
15
|
const elapsed = Date.now() - startedAt;
|
|
21
16
|
const mins = Math.floor(elapsed / 6e4);
|
|
@@ -25,67 +20,259 @@ function formatAge(startedAt) {
|
|
|
25
20
|
return `${hours}h${remainingMins}m`;
|
|
26
21
|
}
|
|
27
22
|
function formatTokens(tokens) {
|
|
28
|
-
if (tokens >= 1e6) return
|
|
29
|
-
if (tokens >= 1e3) return
|
|
30
|
-
return
|
|
31
|
-
}
|
|
32
|
-
function
|
|
33
|
-
const age = formatAge(state.
|
|
34
|
-
const tokens = formatTokens(state.
|
|
35
|
-
const ctx = state.
|
|
36
|
-
const
|
|
37
|
-
const
|
|
38
|
-
const
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
23
|
+
if (tokens >= 1e6) return `${(tokens / 1e6).toFixed(1)}M`;
|
|
24
|
+
if (tokens >= 1e3) return `${(tokens / 1e3).toFixed(1)}k`;
|
|
25
|
+
return `${tokens}`;
|
|
26
|
+
}
|
|
27
|
+
function renderPlain(state) {
|
|
28
|
+
const age = formatAge(state.startedAt);
|
|
29
|
+
const tokens = formatTokens(state.tokensUsed);
|
|
30
|
+
const ctx = state.contextPct;
|
|
31
|
+
const mode = state.activeMode || "-";
|
|
32
|
+
const model = state.activeModel || "sonnet";
|
|
33
|
+
const reqWarningPlain = state.warningActive ? " !!" : "";
|
|
34
|
+
const reqStrPlain = `req:${state.premiumRequests ?? 0}/${state.premiumRequestsTotal ?? 1500}${reqWarningPlain}`;
|
|
35
|
+
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}`;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// src/hud/statusline.mts
|
|
39
|
+
var DEFAULT_VERSION = "0.0.0";
|
|
40
|
+
var DEFAULT_STATUSLINE = "OMP | hud: no active session";
|
|
41
|
+
var DEFAULT_TOKEN_BUDGET = 2e5;
|
|
42
|
+
var DEFAULT_PREMIUM_REQUESTS_TOTAL = 1500;
|
|
43
|
+
function getStatuslinePaths(home = process.env["HOME"] || homedir()) {
|
|
44
|
+
const ompDir = join(home, ".omp");
|
|
45
|
+
const hudDir = join(ompDir, "hud");
|
|
46
|
+
return {
|
|
47
|
+
legacyLinePath: join(ompDir, "hud.line"),
|
|
48
|
+
hudDir,
|
|
49
|
+
statusJsonPath: join(hudDir, "status.json"),
|
|
50
|
+
displayPath: join(hudDir, "display.txt"),
|
|
51
|
+
tmuxSegmentPath: join(hudDir, "tmux-segment.sh")
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
function ensureParent(filePath) {
|
|
55
|
+
mkdirSync(dirname(filePath), { recursive: true });
|
|
56
|
+
}
|
|
57
|
+
function writeAtomic(filePath, content, mode) {
|
|
58
|
+
ensureParent(filePath);
|
|
59
|
+
const tempPath = `${filePath}.tmp`;
|
|
60
|
+
writeFileSync(tempPath, content, mode === void 0 ? "utf-8" : { encoding: "utf-8", mode });
|
|
61
|
+
renameSync(tempPath, filePath);
|
|
62
|
+
}
|
|
63
|
+
function normalizeStringArray(value) {
|
|
64
|
+
if (!Array.isArray(value)) return [];
|
|
65
|
+
return value.filter((item) => typeof item === "string");
|
|
66
|
+
}
|
|
67
|
+
function serializeHudState(state) {
|
|
68
|
+
return {
|
|
69
|
+
...state,
|
|
70
|
+
toolsUsed: Array.from(state.toolsUsed),
|
|
71
|
+
skillsUsed: Array.from(state.skillsUsed)
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
function deserializeHudState(raw) {
|
|
75
|
+
if (!raw || typeof raw !== "object") return null;
|
|
76
|
+
const value = raw;
|
|
77
|
+
const toolsUsed = new Set(normalizeStringArray(value.toolsUsed));
|
|
78
|
+
const skillsUsed = new Set(normalizeStringArray(value.skillsUsed));
|
|
79
|
+
const agentsActive = normalizeStringArray(value.agentsActive);
|
|
80
|
+
const status = typeof value.status === "string" ? value.status : "idle";
|
|
81
|
+
return {
|
|
82
|
+
sessionId: typeof value.sessionId === "string" ? value.sessionId : "default",
|
|
83
|
+
activeMode: typeof value.activeMode === "string" ? value.activeMode : null,
|
|
84
|
+
activeModel: typeof value.activeModel === "string" ? value.activeModel : "sonnet",
|
|
85
|
+
contextPct: typeof value.contextPct === "number" ? value.contextPct : 0,
|
|
86
|
+
tokensUsed: typeof value.tokensUsed === "number" ? value.tokensUsed : 0,
|
|
87
|
+
tokensTotal: typeof value.tokensTotal === "number" ? value.tokensTotal : DEFAULT_TOKEN_BUDGET,
|
|
88
|
+
agentsActive,
|
|
89
|
+
lastAgent: typeof value.lastAgent === "string" ? value.lastAgent : agentsActive.at(-1) ?? "-",
|
|
90
|
+
lastOutput: typeof value.lastOutput === "string" ? value.lastOutput : "",
|
|
91
|
+
taskProgress: typeof value.taskProgress === "number" ? value.taskProgress : 0,
|
|
92
|
+
startedAt: typeof value.startedAt === "number" ? value.startedAt : Date.now(),
|
|
93
|
+
updatedAt: typeof value.updatedAt === "number" ? value.updatedAt : Date.now(),
|
|
94
|
+
version: typeof value.version === "string" ? value.version : DEFAULT_VERSION,
|
|
95
|
+
status,
|
|
96
|
+
sessionDurationMs: typeof value.sessionDurationMs === "number" ? value.sessionDurationMs : 0,
|
|
97
|
+
cumulativeAgentsUsed: typeof value.cumulativeAgentsUsed === "number" ? value.cumulativeAgentsUsed : agentsActive.length,
|
|
98
|
+
toolsUsed,
|
|
99
|
+
skillsUsed,
|
|
100
|
+
toolsTotal: typeof value.toolsTotal === "number" ? value.toolsTotal : 13,
|
|
101
|
+
skillsTotal: typeof value.skillsTotal === "number" ? value.skillsTotal : 25,
|
|
102
|
+
agentsTotal: typeof value.agentsTotal === "number" ? value.agentsTotal : 23,
|
|
103
|
+
premiumRequests: typeof value.premiumRequests === "number" ? value.premiumRequests : 0,
|
|
104
|
+
premiumRequestsTotal: typeof value.premiumRequestsTotal === "number" ? value.premiumRequestsTotal : DEFAULT_PREMIUM_REQUESTS_TOTAL,
|
|
105
|
+
warningActive: typeof value.warningActive === "boolean" ? value.warningActive : false
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
function buildHudState(snapshot, now = Date.now()) {
|
|
109
|
+
const startedAt = snapshot.started_at ?? now;
|
|
110
|
+
const updatedAt = snapshot.updated_at ?? now;
|
|
111
|
+
const toolsUsed = new Set(normalizeStringArray(snapshot.tools_used));
|
|
112
|
+
const skillsUsed = new Set(normalizeStringArray(snapshot.skills_used));
|
|
113
|
+
const agentsActive = normalizeStringArray(snapshot.agents_used);
|
|
114
|
+
return {
|
|
115
|
+
sessionId: snapshot.session_id ?? "default",
|
|
116
|
+
activeMode: snapshot.active_mode ?? null,
|
|
117
|
+
activeModel: snapshot.model ?? "sonnet",
|
|
118
|
+
contextPct: snapshot.context_pct ?? 0,
|
|
119
|
+
tokensUsed: snapshot.tokens_estimated ?? 0,
|
|
120
|
+
tokensTotal: snapshot.token_budget ?? DEFAULT_TOKEN_BUDGET,
|
|
121
|
+
agentsActive,
|
|
122
|
+
lastAgent: agentsActive.at(-1) ?? "-",
|
|
123
|
+
lastOutput: snapshot.last_output ?? "",
|
|
124
|
+
taskProgress: snapshot.task_progress ?? 0,
|
|
125
|
+
startedAt,
|
|
126
|
+
updatedAt,
|
|
127
|
+
version: snapshot.version ?? DEFAULT_VERSION,
|
|
128
|
+
status: snapshot.status ?? "idle",
|
|
129
|
+
sessionDurationMs: Math.max(0, updatedAt - startedAt),
|
|
130
|
+
cumulativeAgentsUsed: agentsActive.length,
|
|
131
|
+
toolsUsed,
|
|
132
|
+
skillsUsed,
|
|
133
|
+
toolsTotal: 13,
|
|
134
|
+
skillsTotal: 25,
|
|
135
|
+
agentsTotal: 23,
|
|
136
|
+
premiumRequests: snapshot.premium_requests ?? 0,
|
|
137
|
+
premiumRequestsTotal: snapshot.premium_requests_total ?? DEFAULT_PREMIUM_REQUESTS_TOTAL,
|
|
138
|
+
warningActive: snapshot.warning_active ?? false
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
function writeHudArtifacts(snapshot, paths = getStatuslinePaths()) {
|
|
142
|
+
const state = buildHudState(snapshot);
|
|
143
|
+
const line = renderPlain(state);
|
|
144
|
+
const serializedState = `${JSON.stringify(serializeHudState(state), null, 2)}
|
|
145
|
+
`;
|
|
146
|
+
writeAtomic(paths.statusJsonPath, serializedState);
|
|
147
|
+
writeAtomic(paths.displayPath, `${line}
|
|
148
|
+
`);
|
|
149
|
+
writeAtomic(paths.tmuxSegmentPath, `${line}
|
|
150
|
+
`, 493);
|
|
151
|
+
writeAtomic(paths.legacyLinePath, `${line}
|
|
152
|
+
`);
|
|
153
|
+
return { line, state, paths };
|
|
154
|
+
}
|
|
155
|
+
function readStatusline(paths = getStatuslinePaths()) {
|
|
156
|
+
try {
|
|
157
|
+
const line = readFileSync(paths.displayPath, "utf-8").trim();
|
|
158
|
+
if (line) return line;
|
|
159
|
+
} catch {
|
|
160
|
+
}
|
|
161
|
+
try {
|
|
162
|
+
const parsed = JSON.parse(readFileSync(paths.statusJsonPath, "utf-8"));
|
|
163
|
+
const state = deserializeHudState(parsed);
|
|
164
|
+
if (state) return renderPlain(state);
|
|
165
|
+
} catch {
|
|
166
|
+
}
|
|
167
|
+
try {
|
|
168
|
+
const line = readFileSync(paths.legacyLinePath, "utf-8").trim();
|
|
169
|
+
if (line) return line;
|
|
170
|
+
} catch {
|
|
171
|
+
}
|
|
172
|
+
return DEFAULT_STATUSLINE;
|
|
173
|
+
}
|
|
174
|
+
if (process.argv[1] === fileURLToPath(import.meta.url)) {
|
|
175
|
+
console.log(readStatusline());
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// src/hooks/hud-emitter.mts
|
|
179
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
180
|
+
var _require = createRequire(import.meta.url);
|
|
181
|
+
var { version: PKG_VERSION } = _require("../../package.json");
|
|
182
|
+
function getStatePath(sessionId) {
|
|
183
|
+
const base = join2(process.env["HOME"] || homedir2(), ".omp", "state");
|
|
184
|
+
if (sessionId) {
|
|
185
|
+
return join2(base, "sessions", sessionId, "session.json");
|
|
186
|
+
}
|
|
187
|
+
return join2(base, "session.json");
|
|
188
|
+
}
|
|
189
|
+
function ensureDir(path) {
|
|
190
|
+
mkdirSync2(path.substring(0, path.lastIndexOf("/")), { recursive: true });
|
|
191
|
+
}
|
|
192
|
+
function stringifyOutput(value) {
|
|
193
|
+
if (typeof value === "string") {
|
|
194
|
+
return value.trim().slice(0, 200);
|
|
195
|
+
}
|
|
196
|
+
if (value === void 0 || value === null) {
|
|
197
|
+
return "";
|
|
198
|
+
}
|
|
199
|
+
try {
|
|
200
|
+
return JSON.stringify(value).slice(0, 200);
|
|
201
|
+
} catch {
|
|
202
|
+
return String(value).slice(0, 200);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
function buildEmit(state) {
|
|
206
|
+
return {
|
|
207
|
+
sessionId: state.session_id,
|
|
208
|
+
activeMode: state.active_mode,
|
|
209
|
+
contextPct: state.context_pct,
|
|
210
|
+
tokensUsed: state.tokens_estimated,
|
|
211
|
+
tokensTotal: state.token_budget,
|
|
212
|
+
agentsActive: state.agents_used,
|
|
213
|
+
lastAgent: state.agents_used[state.agents_used.length - 1] || "-",
|
|
214
|
+
lastOutput: state.last_output,
|
|
215
|
+
taskProgress: state.task_progress
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
var MODEL_CONTEXTS = {
|
|
219
|
+
"claude-sonnet-4.5": 2e5,
|
|
220
|
+
"claude-sonnet-4": 2e5,
|
|
221
|
+
"claude-sonnet-4.6": 2e5,
|
|
222
|
+
"claude-opus-4.6": 2e5,
|
|
223
|
+
"gpt-5": 128e3,
|
|
224
|
+
"gpt-5.4-mini": 128e3,
|
|
225
|
+
"gemini-3-pro": 128e3,
|
|
226
|
+
default: 2e5
|
|
227
|
+
};
|
|
228
|
+
function resolveTokenBudget(model) {
|
|
229
|
+
return MODEL_CONTEXTS[model] ?? MODEL_CONTEXTS["default"] ?? 2e5;
|
|
230
|
+
}
|
|
231
|
+
function resolvePremiumRequestsTotal() {
|
|
232
|
+
const env = process.env["OMP_PREMIUM_REQUESTS_TOTAL"];
|
|
233
|
+
if (env) {
|
|
234
|
+
const parsed = parseInt(env, 10);
|
|
235
|
+
if (!isNaN(parsed) && parsed > 0) return parsed;
|
|
236
|
+
}
|
|
237
|
+
return 1500;
|
|
42
238
|
}
|
|
43
239
|
function processSessionStart(input) {
|
|
44
240
|
const start = Date.now();
|
|
45
241
|
const log = [];
|
|
46
242
|
const sessionId = input.session_id || "default";
|
|
243
|
+
const now = Date.now();
|
|
244
|
+
const model = input.model || "claude-sonnet-4.6";
|
|
47
245
|
const state = {
|
|
48
|
-
version:
|
|
246
|
+
version: PKG_VERSION,
|
|
49
247
|
session_id: sessionId,
|
|
50
|
-
started_at:
|
|
51
|
-
|
|
248
|
+
started_at: now,
|
|
249
|
+
updated_at: now,
|
|
250
|
+
model,
|
|
52
251
|
tokens_estimated: 0,
|
|
53
|
-
token_budget:
|
|
252
|
+
token_budget: resolveTokenBudget(model),
|
|
54
253
|
context_pct: 0,
|
|
55
254
|
tools_used: [],
|
|
56
255
|
skills_used: [],
|
|
57
256
|
agents_used: [],
|
|
58
|
-
active_mode: null
|
|
257
|
+
active_mode: null,
|
|
258
|
+
last_output: "",
|
|
259
|
+
task_progress: 0,
|
|
260
|
+
status: "idle",
|
|
261
|
+
premium_requests: 0,
|
|
262
|
+
premium_requests_total: resolvePremiumRequestsTotal(),
|
|
263
|
+
warning_active: false
|
|
59
264
|
};
|
|
60
265
|
const statePath = getStatePath(sessionId);
|
|
61
266
|
ensureDir(statePath);
|
|
62
|
-
|
|
267
|
+
writeFileSync2(statePath, JSON.stringify(state), "utf-8");
|
|
63
268
|
log.push(`Session initialized: ${sessionId}`);
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
ensureDir(hudPath);
|
|
67
|
-
writeFileSync(hudPath, hudLine, "utf-8");
|
|
68
|
-
log.push(`HUD line written: ${hudLine}`);
|
|
269
|
+
const { line, state: hudState } = writeHudArtifacts(state);
|
|
270
|
+
log.push(`HUD artifacts written: ${line}`);
|
|
69
271
|
return {
|
|
70
272
|
status: "ok",
|
|
71
273
|
latencyMs: Date.now() - start,
|
|
72
|
-
mutations: [
|
|
73
|
-
|
|
74
|
-
type: "emit_hud",
|
|
75
|
-
hudEmit: {
|
|
76
|
-
sessionId,
|
|
77
|
-
activeMode: null,
|
|
78
|
-
contextPct: 0,
|
|
79
|
-
tokensUsed: 0,
|
|
80
|
-
tokensTotal: 2e5,
|
|
81
|
-
agentsActive: [],
|
|
82
|
-
lastAgent: "-",
|
|
83
|
-
lastOutput: "",
|
|
84
|
-
taskProgress: 0
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
],
|
|
88
|
-
log
|
|
274
|
+
mutations: [{ type: "emit_hud", hudEmit: buildEmit(state) }],
|
|
275
|
+
log: [...log, `HUD state version: ${hudState.version}`]
|
|
89
276
|
};
|
|
90
277
|
}
|
|
91
278
|
function processPostToolUse(input) {
|
|
@@ -94,12 +281,27 @@ function processPostToolUse(input) {
|
|
|
94
281
|
const statePath = getStatePath(input.session_id);
|
|
95
282
|
let state;
|
|
96
283
|
try {
|
|
97
|
-
const raw = JSON.parse(
|
|
284
|
+
const raw = JSON.parse(readFileSync2(statePath, "utf-8"));
|
|
98
285
|
state = {
|
|
99
286
|
...raw,
|
|
287
|
+
version: typeof raw.version === "string" ? raw.version : PKG_VERSION,
|
|
288
|
+
session_id: typeof raw.session_id === "string" ? raw.session_id : input.session_id || "default",
|
|
289
|
+
started_at: typeof raw.started_at === "number" ? raw.started_at : Date.now(),
|
|
290
|
+
updated_at: Date.now(),
|
|
291
|
+
model: typeof raw.model === "string" ? raw.model : input.model || "claude-sonnet-4.6",
|
|
292
|
+
tokens_estimated: typeof raw.tokens_estimated === "number" ? raw.tokens_estimated : 0,
|
|
293
|
+
token_budget: typeof raw.token_budget === "number" ? raw.token_budget : resolveTokenBudget(typeof raw.model === "string" ? raw.model : input.model || "claude-sonnet-4.6"),
|
|
294
|
+
context_pct: typeof raw.context_pct === "number" ? raw.context_pct : 0,
|
|
100
295
|
tools_used: Array.isArray(raw.tools_used) ? raw.tools_used : [],
|
|
101
296
|
skills_used: Array.isArray(raw.skills_used) ? raw.skills_used : [],
|
|
102
|
-
agents_used: Array.isArray(raw.agents_used) ? raw.agents_used : []
|
|
297
|
+
agents_used: Array.isArray(raw.agents_used) ? raw.agents_used : [],
|
|
298
|
+
active_mode: typeof raw.active_mode === "string" ? raw.active_mode : null,
|
|
299
|
+
last_output: typeof raw.last_output === "string" ? raw.last_output : "",
|
|
300
|
+
task_progress: typeof raw.task_progress === "number" ? raw.task_progress : 0,
|
|
301
|
+
status: raw.status ?? "running",
|
|
302
|
+
premium_requests: typeof raw.premium_requests === "number" ? raw.premium_requests : 0,
|
|
303
|
+
premium_requests_total: typeof raw.premium_requests_total === "number" ? raw.premium_requests_total : resolvePremiumRequestsTotal(),
|
|
304
|
+
warning_active: typeof raw.warning_active === "boolean" ? raw.warning_active : false
|
|
103
305
|
};
|
|
104
306
|
} catch {
|
|
105
307
|
return processSessionStart(input);
|
|
@@ -107,31 +309,15 @@ function processPostToolUse(input) {
|
|
|
107
309
|
if (input.tool_name && !state.tools_used.includes(input.tool_name)) {
|
|
108
310
|
state.tools_used.push(input.tool_name);
|
|
109
311
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
log.push(`HUD updated: ${
|
|
115
|
-
writeFileSync(statePath, JSON.stringify(state), "utf-8");
|
|
312
|
+
state.status = "running";
|
|
313
|
+
state.last_output = stringifyOutput(input.tool_output);
|
|
314
|
+
writeFileSync2(statePath, JSON.stringify(state), "utf-8");
|
|
315
|
+
const { line } = writeHudArtifacts(state);
|
|
316
|
+
log.push(`HUD updated: ${line}`);
|
|
116
317
|
return {
|
|
117
318
|
status: "ok",
|
|
118
319
|
latencyMs: Date.now() - start,
|
|
119
|
-
mutations: [
|
|
120
|
-
{
|
|
121
|
-
type: "emit_hud",
|
|
122
|
-
hudEmit: {
|
|
123
|
-
sessionId: state.session_id,
|
|
124
|
-
activeMode: state.active_mode,
|
|
125
|
-
contextPct: state.context_pct,
|
|
126
|
-
tokensUsed: state.tokens_estimated,
|
|
127
|
-
tokensTotal: state.token_budget,
|
|
128
|
-
agentsActive: state.agents_used,
|
|
129
|
-
lastAgent: state.agents_used[state.agents_used.length - 1] || "-",
|
|
130
|
-
lastOutput: "",
|
|
131
|
-
taskProgress: 0
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
],
|
|
320
|
+
mutations: [{ type: "emit_hud", hudEmit: buildEmit(state) }],
|
|
135
321
|
log
|
|
136
322
|
};
|
|
137
323
|
}
|
|
@@ -149,7 +335,7 @@ function processHook(input) {
|
|
|
149
335
|
log: ["Unknown hook type"]
|
|
150
336
|
};
|
|
151
337
|
}
|
|
152
|
-
if (process.argv[1] ===
|
|
338
|
+
if (process.argv[1] === fileURLToPath2(import.meta.url)) {
|
|
153
339
|
const input = JSON.parse(await readStdin());
|
|
154
340
|
const output = processHook(input);
|
|
155
341
|
console.log(JSON.stringify(output));
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../../src/hooks/hud-emitter.mts"],
|
|
4
|
-
"sourcesContent": ["/**\n * hud-emitter hook\n * Trigger: post-cycle (PostToolUse + SessionStart)\n * Priority: 60\n *\n * Writes HUD statusline to ~/.omp/hud.line after every tool call.\n * Initializes session state on SessionStart.\n */\n\nimport { readFileSync, writeFileSync, mkdirSync } from \"fs\";\nimport { homedir } from \"os\";\nimport { join } from \"path\";\n\nexport interface HookInput {\n hook_type: \"SessionStart\" | \"PostToolUse\";\n tool_name?: string;\n tool_input?: unknown;\n tool_output?: unknown;\n session_id?: string;\n model?: string;\n}\n\nexport interface HookOutput {\n status: \"ok\" | \"skip\" | \"error\";\n latencyMs: number;\n mutations: Array<{ type: \"emit_hud\"; hudEmit: HudEmit } | { type: \"log\"; level: \"info\"; message: string }>;\n log: string[];\n}\n\nexport interface HudEmit {\n sessionId: string;\n activeMode: string | null;\n contextPct: number;\n tokensUsed: number;\n tokensTotal: number;\n agentsActive: string[];\n lastAgent: string;\n lastOutput: string;\n taskProgress: number;\n}\n\ninterface SessionState {\n version: string;\n session_id: string;\n started_at: number;\n 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}\n\nfunction getStatePath(sessionId?: string): string {\n const base = join(homedir(), \".omp\", \"state\");\n if (sessionId) {\n return join(base, \"sessions\", sessionId, \"session.json\");\n }\n return join(base, \"session.json\");\n}\n\nfunction getHudLinePath(): string {\n return join(homedir(), \".omp\", \"hud.line\");\n}\n\nfunction ensureDir(path: string): void {\n mkdirSync(path.substring(0, path.lastIndexOf(\"/\")), { recursive: true });\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 buildHudLine(state: SessionState): string {\n const age = formatAge(state.started_at);\n const tokens = formatTokens(state.tokens_estimated);\n const ctx = state.context_pct;\n const tools = state.tools_used.length;\n const skills = state.skills_used.length;\n const agents = state.agents_used.length;\n const mode = state.active_mode || \"-\";\n const model = state.model || \"sonnet\";\n\n return `OMP v${state.version} | ${model} | tkn: ${tokens}/${state.token_budget} | ctx: ${ctx}% | session: ${age} | tools: ${tools} | skills: ${skills} | agents: ${agents} | mode: ${mode}`;\n}\n\nfunction processSessionStart(input: HookInput): HookOutput {\n const start = Date.now();\n const log: string[] = [];\n const sessionId = input.session_id || \"default\";\n\n const state: SessionState = {\n version: \"1.0.0\",\n session_id: sessionId,\n started_at: Date.now(),\n model: input.model || \"claude-sonnet-4.5\",\n tokens_estimated: 0,\n token_budget: 200_000,\n context_pct: 0,\n tools_used: [],\n skills_used: [],\n agents_used: [],\n active_mode: null,\n };\n\n const statePath = getStatePath(sessionId);\n ensureDir(statePath);\n writeFileSync(statePath, JSON.stringify(state), \"utf-8\");\n log.push(`Session initialized: ${sessionId}`);\n\n const hudLine = buildHudLine(state);\n const hudPath = getHudLinePath();\n ensureDir(hudPath);\n writeFileSync(hudPath, hudLine, \"utf-8\");\n log.push(`HUD line written: ${hudLine}`);\n\n return {\n status: \"ok\",\n latencyMs: Date.now() - start,\n mutations: [\n {\n type: \"emit_hud\",\n hudEmit: {\n sessionId,\n activeMode: null,\n contextPct: 0,\n tokensUsed: 0,\n tokensTotal: 200_000,\n agentsActive: [],\n lastAgent: \"-\",\n lastOutput: \"\",\n taskProgress: 0,\n },\n },\n ],\n log,\n };\n}\n\nfunction processPostToolUse(input: HookInput): HookOutput {\n const start = Date.now();\n const log: string[] = [];\n\n const statePath = getStatePath(input.session_id);\n let state: SessionState;\n\n try {\n const raw = JSON.parse(readFileSync(statePath, \"utf-8\"));\n state = {\n ...raw,\n tools_used: Array.isArray(raw.tools_used) ? raw.tools_used : [],\n skills_used: Array.isArray(raw.skills_used) ? raw.skills_used : [],\n agents_used: Array.isArray(raw.agents_used) ? raw.agents_used : [],\n };\n } catch {\n // Fall back to session start behavior if no state\n return processSessionStart(input);\n }\n\n // Update tools used\n if (input.tool_name && !state.tools_used.includes(input.tool_name)) {\n state.tools_used.push(input.tool_name);\n }\n\n // Recalculate HUD line\n const hudLine = buildHudLine(state);\n const hudPath = getHudLinePath();\n ensureDir(hudPath);\n writeFileSync(hudPath, hudLine, \"utf-8\");\n log.push(`HUD updated: ${hudLine}`);\n\n // Write updated state\n writeFileSync(statePath, JSON.stringify(state), \"utf-8\");\n\n return {\n status: \"ok\",\n latencyMs: Date.now() - start,\n mutations: [\n {\n type: \"emit_hud\",\n hudEmit: {\n sessionId: state.session_id,\n activeMode: state.active_mode,\n contextPct: state.context_pct,\n tokensUsed: state.tokens_estimated,\n tokensTotal: state.token_budget,\n agentsActive: state.agents_used,\n lastAgent: state.agents_used[state.agents_used.length - 1] || \"-\",\n lastOutput: \"\",\n taskProgress: 0,\n },\n },\n ],\n log,\n };\n}\n\nexport function processHook(input: HookInput): HookOutput {\n if (input.hook_type === \"SessionStart\") {\n return processSessionStart(input);\n }\n if (input.hook_type === \"PostToolUse\") {\n return processPostToolUse(input);\n }\n return {\n status: \"skip\",\n latencyMs: 0,\n mutations: [],\n log: [\"Unknown hook type\"],\n };\n}\n\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": ";
|
|
6
|
-
"names": []
|
|
3
|
+
"sources": ["../../src/hooks/hud-emitter.mts", "../../src/hud/statusline.mts", "../../src/hud/renderer.mts"],
|
|
4
|
+
"sourcesContent": ["/**\n * hud-emitter hook\n * Trigger: post-cycle (PostToolUse + SessionStart)\n * Priority: 60\n *\n * Writes HUD artifacts after every tool call and initializes session state.\n */\n\nimport { mkdirSync, readFileSync, writeFileSync } from \"fs\";\nimport { createRequire } from \"module\";\nimport { homedir } from \"os\";\nimport { join } from \"path\";\nimport { writeHudArtifacts } from \"../hud/statusline.mts\";\n\nconst _require = createRequire(import.meta.url);\nconst { version: PKG_VERSION } = _require(\"../../package.json\") as { version: string };\n\nexport interface HookInput {\n hook_type: \"SessionStart\" | \"PostToolUse\";\n tool_name?: string;\n tool_input?: unknown;\n tool_output?: unknown;\n session_id?: string;\n model?: string;\n}\n\nexport interface HookOutput {\n status: \"ok\" | \"skip\" | \"error\";\n latencyMs: number;\n mutations: Array<{ type: \"emit_hud\"; hudEmit: HudEmit } | { type: \"log\"; level: \"info\"; message: string }>;\n log: string[];\n}\n\nexport interface HudEmit {\n sessionId: string;\n activeMode: string | null;\n contextPct: number;\n tokensUsed: number;\n tokensTotal: number;\n agentsActive: string[];\n lastAgent: string;\n lastOutput: string;\n taskProgress: number;\n}\n\ninterface SessionState {\n version: string;\n session_id: string;\n started_at: number;\n updated_at: number;\n model: string;\n tokens_estimated: number;\n token_budget: number;\n context_pct: number;\n tools_used: string[];\n skills_used: string[];\n agents_used: string[];\n active_mode: string | null;\n last_output: string;\n task_progress: number;\n status: \"idle\" | \"running\" | \"waiting\" | \"complete\" | \"error\" | \"eco\";\n premium_requests: number;\n premium_requests_total: number;\n warning_active: boolean;\n}\n\nfunction getStatePath(sessionId?: string): string {\n const base = join(process.env[\"HOME\"] || homedir(), \".omp\", \"state\");\n if (sessionId) {\n return join(base, \"sessions\", sessionId, \"session.json\");\n }\n return join(base, \"session.json\");\n}\n\nfunction ensureDir(path: string): void {\n mkdirSync(path.substring(0, path.lastIndexOf(\"/\")), { recursive: true });\n}\n\nfunction stringifyOutput(value: unknown): string {\n if (typeof value === \"string\") {\n return value.trim().slice(0, 200);\n }\n if (value === undefined || value === null) {\n return \"\";\n }\n try {\n return JSON.stringify(value).slice(0, 200);\n } catch {\n return String(value).slice(0, 200);\n }\n}\n\nfunction buildEmit(state: SessionState): HudEmit {\n return {\n sessionId: state.session_id,\n activeMode: state.active_mode,\n contextPct: state.context_pct,\n tokensUsed: state.tokens_estimated,\n tokensTotal: state.token_budget,\n agentsActive: state.agents_used,\n lastAgent: state.agents_used[state.agents_used.length - 1] || \"-\",\n lastOutput: state.last_output,\n taskProgress: state.task_progress,\n };\n}\n\nconst MODEL_CONTEXTS: Record<string, number> = {\n \"claude-sonnet-4.5\": 200_000,\n \"claude-sonnet-4\": 200_000,\n \"claude-sonnet-4.6\": 200_000,\n \"claude-opus-4.6\": 200_000,\n \"gpt-5\": 128_000,\n \"gpt-5.4-mini\": 128_000,\n \"gemini-3-pro\": 128_000,\n default: 200_000,\n};\n\nfunction resolveTokenBudget(model: string): number {\n return MODEL_CONTEXTS[model] ?? MODEL_CONTEXTS[\"default\"] ?? 200_000;\n}\n\nfunction resolvePremiumRequestsTotal(): number {\n const env = process.env[\"OMP_PREMIUM_REQUESTS_TOTAL\"];\n if (env) {\n const parsed = parseInt(env, 10);\n if (!isNaN(parsed) && parsed > 0) return parsed;\n }\n return 1500;\n}\n\nfunction processSessionStart(input: HookInput): HookOutput {\n const start = Date.now();\n const log: string[] = [];\n const sessionId = input.session_id || \"default\";\n const now = Date.now();\n const model = input.model || \"claude-sonnet-4.6\";\n\n const state: SessionState = {\n version: PKG_VERSION,\n session_id: sessionId,\n started_at: now,\n updated_at: now,\n model,\n tokens_estimated: 0,\n token_budget: resolveTokenBudget(model),\n context_pct: 0,\n tools_used: [],\n skills_used: [],\n agents_used: [],\n active_mode: null,\n last_output: \"\",\n task_progress: 0,\n status: \"idle\",\n premium_requests: 0,\n premium_requests_total: resolvePremiumRequestsTotal(),\n warning_active: false,\n };\n\n const statePath = getStatePath(sessionId);\n ensureDir(statePath);\n writeFileSync(statePath, JSON.stringify(state), \"utf-8\");\n log.push(`Session initialized: ${sessionId}`);\n\n const { line, state: hudState } = writeHudArtifacts(state);\n log.push(`HUD artifacts written: ${line}`);\n\n return {\n status: \"ok\",\n latencyMs: Date.now() - start,\n mutations: [{ type: \"emit_hud\", hudEmit: buildEmit(state) }],\n log: [...log, `HUD state version: ${hudState.version}`],\n };\n}\n\nfunction processPostToolUse(input: HookInput): HookOutput {\n const start = Date.now();\n const log: string[] = [];\n\n const statePath = getStatePath(input.session_id);\n let state: SessionState;\n\n try {\n const raw = JSON.parse(readFileSync(statePath, \"utf-8\"));\n state = {\n ...raw,\n version: typeof raw.version === \"string\" ? raw.version : PKG_VERSION,\n session_id: typeof raw.session_id === \"string\" ? raw.session_id : input.session_id || \"default\",\n started_at: typeof raw.started_at === \"number\" ? raw.started_at : Date.now(),\n updated_at: Date.now(),\n model: typeof raw.model === \"string\" ? raw.model : input.model || \"claude-sonnet-4.6\",\n tokens_estimated: typeof raw.tokens_estimated === \"number\" ? raw.tokens_estimated : 0,\n token_budget: typeof raw.token_budget === \"number\" ? raw.token_budget : resolveTokenBudget(typeof raw.model === \"string\" ? raw.model : input.model || \"claude-sonnet-4.6\"),\n context_pct: typeof raw.context_pct === \"number\" ? raw.context_pct : 0,\n tools_used: Array.isArray(raw.tools_used) ? raw.tools_used : [],\n skills_used: Array.isArray(raw.skills_used) ? raw.skills_used : [],\n agents_used: Array.isArray(raw.agents_used) ? raw.agents_used : [],\n active_mode: typeof raw.active_mode === \"string\" ? raw.active_mode : null,\n last_output: typeof raw.last_output === \"string\" ? raw.last_output : \"\",\n task_progress: typeof raw.task_progress === \"number\" ? raw.task_progress : 0,\n status: raw.status ?? \"running\",\n premium_requests: typeof raw.premium_requests === \"number\" ? raw.premium_requests : 0,\n premium_requests_total: typeof raw.premium_requests_total === \"number\" ? raw.premium_requests_total : resolvePremiumRequestsTotal(),\n warning_active: typeof raw.warning_active === \"boolean\" ? raw.warning_active : false,\n };\n } catch {\n return processSessionStart(input);\n }\n\n if (input.tool_name && !state.tools_used.includes(input.tool_name)) {\n state.tools_used.push(input.tool_name);\n }\n state.status = \"running\";\n state.last_output = stringifyOutput(input.tool_output);\n\n writeFileSync(statePath, JSON.stringify(state), \"utf-8\");\n const { line } = writeHudArtifacts(state);\n log.push(`HUD updated: ${line}`);\n\n return {\n status: \"ok\",\n latencyMs: Date.now() - start,\n mutations: [{ type: \"emit_hud\", hudEmit: buildEmit(state) }],\n log,\n };\n}\n\nexport function processHook(input: HookInput): HookOutput {\n if (input.hook_type === \"SessionStart\") {\n return processSessionStart(input);\n }\n if (input.hook_type === \"PostToolUse\") {\n return processPostToolUse(input);\n }\n return {\n status: \"skip\",\n latencyMs: 0,\n mutations: [],\n log: [\"Unknown hook type\"],\n };\n}\n\nimport { fileURLToPath } from \"url\";\n\nif (process.argv[1] === fileURLToPath(import.meta.url)) {\n const input: HookInput = JSON.parse(await readStdin());\n const output = processHook(input);\n console.log(JSON.stringify(output));\n}\n\nasync function readStdin(): Promise<string> {\n const chunks: string[] = [];\n for await (const chunk of process.stdin) {\n chunks.push(chunk);\n }\n return chunks.join(\"\");\n}\n", "/**\n * HUD statusline helpers and standalone entrypoint.\n *\n * Keeps HUD artifact generation in one place so hooks and shell wrappers\n * can share the same rendering and fallback behavior.\n */\n\nimport { mkdirSync, readFileSync, renameSync, writeFileSync } from \"fs\";\nimport { homedir } from \"os\";\nimport { dirname, join } from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { renderPlain, type HudState, type HudStatus } from \"./renderer.mts\";\n\nconst DEFAULT_VERSION = \"0.0.0\";\nconst DEFAULT_STATUSLINE = \"OMP | hud: no active session\";\nconst DEFAULT_TOKEN_BUDGET = 200_000;\nconst DEFAULT_PREMIUM_REQUESTS_TOTAL = 1500;\n\nexport interface StatuslinePaths {\n legacyLinePath: string;\n hudDir: string;\n statusJsonPath: string;\n displayPath: string;\n tmuxSegmentPath: string;\n}\n\nexport interface HudSnapshot {\n version?: string;\n session_id?: string;\n started_at?: number;\n updated_at?: number;\n model?: string;\n tokens_estimated?: number;\n token_budget?: number;\n context_pct?: number;\n tools_used?: string[];\n skills_used?: string[];\n agents_used?: string[];\n active_mode?: string | null;\n last_output?: string;\n task_progress?: number;\n status?: HudStatus;\n premium_requests?: number;\n premium_requests_total?: number;\n warning_active?: boolean;\n}\n\ninterface SerializedHudState extends Omit<HudState, \"toolsUsed\" | \"skillsUsed\"> {\n toolsUsed: string[];\n skillsUsed: string[];\n}\n\nexport function getStatuslinePaths(home = process.env[\"HOME\"] || homedir()): StatuslinePaths {\n const ompDir = join(home, \".omp\");\n const hudDir = join(ompDir, \"hud\");\n return {\n legacyLinePath: join(ompDir, \"hud.line\"),\n hudDir,\n statusJsonPath: join(hudDir, \"status.json\"),\n displayPath: join(hudDir, \"display.txt\"),\n tmuxSegmentPath: join(hudDir, \"tmux-segment.sh\"),\n };\n}\n\nfunction ensureParent(filePath: string): void {\n mkdirSync(dirname(filePath), { recursive: true });\n}\n\nfunction writeAtomic(filePath: string, content: string, mode?: number): void {\n ensureParent(filePath);\n const tempPath = `${filePath}.tmp`;\n writeFileSync(tempPath, content, mode === undefined ? \"utf-8\" : { encoding: \"utf-8\", mode });\n renameSync(tempPath, filePath);\n}\n\nfunction normalizeStringArray(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n return value.filter((item): item is string => typeof item === \"string\");\n}\n\nfunction serializeHudState(state: HudState): SerializedHudState {\n return {\n ...state,\n toolsUsed: Array.from(state.toolsUsed),\n skillsUsed: Array.from(state.skillsUsed),\n };\n}\n\nfunction deserializeHudState(raw: unknown): HudState | null {\n if (!raw || typeof raw !== \"object\") return null;\n const value = raw as Record<string, unknown>;\n const toolsUsed = new Set(normalizeStringArray(value.toolsUsed));\n const skillsUsed = new Set(normalizeStringArray(value.skillsUsed));\n const agentsActive = normalizeStringArray(value.agentsActive);\n const status = typeof value.status === \"string\" ? (value.status as HudStatus) : \"idle\";\n\n return {\n sessionId: typeof value.sessionId === \"string\" ? value.sessionId : \"default\",\n activeMode: typeof value.activeMode === \"string\" ? value.activeMode : null,\n activeModel: typeof value.activeModel === \"string\" ? value.activeModel : \"sonnet\",\n contextPct: typeof value.contextPct === \"number\" ? value.contextPct : 0,\n tokensUsed: typeof value.tokensUsed === \"number\" ? value.tokensUsed : 0,\n tokensTotal: typeof value.tokensTotal === \"number\" ? value.tokensTotal : DEFAULT_TOKEN_BUDGET,\n agentsActive,\n lastAgent: typeof value.lastAgent === \"string\" ? value.lastAgent : agentsActive.at(-1) ?? \"-\",\n lastOutput: typeof value.lastOutput === \"string\" ? value.lastOutput : \"\",\n taskProgress: typeof value.taskProgress === \"number\" ? value.taskProgress : 0,\n startedAt: typeof value.startedAt === \"number\" ? value.startedAt : Date.now(),\n updatedAt: typeof value.updatedAt === \"number\" ? value.updatedAt : Date.now(),\n version: typeof value.version === \"string\" ? value.version : DEFAULT_VERSION,\n status,\n sessionDurationMs: typeof value.sessionDurationMs === \"number\" ? value.sessionDurationMs : 0,\n cumulativeAgentsUsed: typeof value.cumulativeAgentsUsed === \"number\" ? value.cumulativeAgentsUsed : agentsActive.length,\n toolsUsed,\n skillsUsed,\n toolsTotal: typeof value.toolsTotal === \"number\" ? value.toolsTotal : 13,\n skillsTotal: typeof value.skillsTotal === \"number\" ? value.skillsTotal : 25,\n agentsTotal: typeof value.agentsTotal === \"number\" ? value.agentsTotal : 23,\n premiumRequests: typeof value.premiumRequests === \"number\" ? value.premiumRequests : 0,\n premiumRequestsTotal: typeof value.premiumRequestsTotal === \"number\" ? value.premiumRequestsTotal : DEFAULT_PREMIUM_REQUESTS_TOTAL,\n warningActive: typeof value.warningActive === \"boolean\" ? value.warningActive : false,\n };\n}\n\nexport function buildHudState(snapshot: HudSnapshot, now = Date.now()): HudState {\n const startedAt = snapshot.started_at ?? now;\n const updatedAt = snapshot.updated_at ?? now;\n const toolsUsed = new Set(normalizeStringArray(snapshot.tools_used));\n const skillsUsed = new Set(normalizeStringArray(snapshot.skills_used));\n const agentsActive = normalizeStringArray(snapshot.agents_used);\n\n return {\n sessionId: snapshot.session_id ?? \"default\",\n activeMode: snapshot.active_mode ?? null,\n activeModel: snapshot.model ?? \"sonnet\",\n contextPct: snapshot.context_pct ?? 0,\n tokensUsed: snapshot.tokens_estimated ?? 0,\n tokensTotal: snapshot.token_budget ?? DEFAULT_TOKEN_BUDGET,\n agentsActive,\n lastAgent: agentsActive.at(-1) ?? \"-\",\n lastOutput: snapshot.last_output ?? \"\",\n taskProgress: snapshot.task_progress ?? 0,\n startedAt,\n updatedAt,\n version: snapshot.version ?? DEFAULT_VERSION,\n status: snapshot.status ?? \"idle\",\n sessionDurationMs: Math.max(0, updatedAt - startedAt),\n cumulativeAgentsUsed: agentsActive.length,\n toolsUsed,\n skillsUsed,\n toolsTotal: 13,\n skillsTotal: 25,\n agentsTotal: 23,\n premiumRequests: snapshot.premium_requests ?? 0,\n premiumRequestsTotal: snapshot.premium_requests_total ?? DEFAULT_PREMIUM_REQUESTS_TOTAL,\n warningActive: snapshot.warning_active ?? false,\n };\n}\n\nexport function writeHudArtifacts(snapshot: HudSnapshot, paths = getStatuslinePaths()): { line: string; state: HudState; paths: StatuslinePaths } {\n const state = buildHudState(snapshot);\n const line = renderPlain(state);\n const serializedState = `${JSON.stringify(serializeHudState(state), null, 2)}\\n`;\n\n writeAtomic(paths.statusJsonPath, serializedState);\n writeAtomic(paths.displayPath, `${line}\\n`);\n writeAtomic(paths.tmuxSegmentPath, `${line}\\n`, 0o755);\n writeAtomic(paths.legacyLinePath, `${line}\\n`);\n\n return { line, state, paths };\n}\n\nexport function readStatusline(paths = getStatuslinePaths()): string {\n try {\n const line = readFileSync(paths.displayPath, \"utf-8\").trim();\n if (line) return line;\n } catch {\n // Fall through to other sources.\n }\n\n try {\n const parsed = JSON.parse(readFileSync(paths.statusJsonPath, \"utf-8\"));\n const state = deserializeHudState(parsed);\n if (state) return renderPlain(state);\n } catch {\n // Fall through to legacy file.\n }\n\n try {\n const line = readFileSync(paths.legacyLinePath, \"utf-8\").trim();\n if (line) return line;\n } catch {\n // No HUD artifacts yet.\n }\n\n return DEFAULT_STATUSLINE;\n}\n\nif (process.argv[1] === fileURLToPath(import.meta.url)) {\n console.log(readStatusline());\n}\n", "/**\n * HUD Renderer\n * Formats HudState into ANSI or plain text status lines.\n */\n\n\nexport interface HudState {\n sessionId: string;\n activeMode: string | null;\n activeModel: string;\n contextPct: number;\n tokensUsed: number;\n tokensTotal: number;\n agentsActive: string[];\n lastAgent: string;\n lastOutput: string;\n taskProgress: number;\n startedAt: number;\n updatedAt: number;\n version: string;\n status: HudStatus;\n sessionDurationMs: number;\n cumulativeAgentsUsed: number;\n toolsUsed: Set<string>;\n skillsUsed: Set<string>;\n toolsTotal: number;\n skillsTotal: number;\n agentsTotal: number;\n premiumRequests: number;\n premiumRequestsTotal: number;\n warningActive: boolean;\n}\n\nexport type HudStatus = \"idle\" | \"running\" | \"waiting\" | \"complete\" | \"error\" | \"eco\";\n\nconst STATUS_ICONS: Record<HudStatus, string> = {\n idle: \"\u25CB\",\n running: \"\u25CF\",\n waiting: \"\u25F7\",\n complete: \"\u2713\",\n error: \"\u2717\",\n eco: \"\u26A1\",\n};\n\nfunction formatAge(startedAt: number): string {\n const elapsed = Date.now() - startedAt;\n const mins = Math.floor(elapsed / 60000);\n if (mins < 60) return `${mins}m`;\n const hours = Math.floor(mins / 60);\n const remainingMins = mins % 60;\n return `${hours}h${remainingMins}m`;\n}\n\nfunction formatTokens(tokens: number): string {\n if (tokens >= 1_000_000) return `${(tokens / 1_000_000).toFixed(1)}M`;\n if (tokens >= 1_000) return `${(tokens / 1_000).toFixed(1)}k`;\n return `${tokens}`;\n}\n\nfunction ctxColor(pct: number): string {\n if (pct < 60) return \"\\x1b[32m\"; // green\n if (pct < 85) return \"\\x1b[33m\"; // yellow\n return \"\\x1b[31m\"; // red\n}\n\nfunction reset(): string {\n return \"\\x1b[0m\";\n}\n\n/**\n * Render HUD line with ANSI color codes.\n * Format: [OMP v1.0.0] mode | model | ctx:N% | tok:~Nk/Nk | Nm | tools:N/N | skills:N/N | agents:N/N | N% status\n */\nexport function renderAnsi(state: HudState): string {\n const age = formatAge(state.startedAt);\n const tokens = formatTokens(state.tokensUsed);\n const ctx = state.contextPct;\n const mode = state.activeMode || \"-\";\n const model = state.activeModel || \"sonnet\";\n const icon = STATUS_ICONS[state.status] || \"\u25CF\";\n\n const ctxClr = ctxColor(ctx);\n const ctxStr = `${ctxClr}ctx:${ctx}%${reset()}`;\n const tokenStr = `tok:~${tokens}/${state.tokensTotal}`;\n const modeStr = mode === \"-\" ? \"-\" : `\\x1b[36m${mode}${reset()}`; // cyan for active modes\n\n const reqWarning = state.warningActive ? \" !!\" : \"\";\n const reqStr = `req:${state.premiumRequests ?? 0}/${state.premiumRequestsTotal ?? 1500}${reqWarning}`;\n\n return `[OMP v${state.version}] ${modeStr} | ${model} | ${ctxStr} | ${tokenStr} | ${reqStr} | ${age} | tools:${state.toolsUsed?.size || 0}/${state.toolsTotal ?? 13} | skills:${state.skillsUsed?.size || 0}/${state.skillsTotal ?? 25} | agents:${state.cumulativeAgentsUsed}/${state.agentsTotal ?? 23} | ${icon} ${state.status}`;\n}\n\n/**\n * Render HUD line as plain text (no ANSI codes).\n * Format: [OMP v1.0.0] mode | model | ctx:N% | tok:~Nk/Nk | Nm | tools:N/N | skills:N/N | agents:N/N | N% status\n */\nexport function renderPlain(state: HudState): string {\n const age = formatAge(state.startedAt);\n const tokens = formatTokens(state.tokensUsed);\n const ctx = state.contextPct;\n const mode = state.activeMode || \"-\";\n const model = state.activeModel || \"sonnet\";\n\n const reqWarningPlain = state.warningActive ? \" !!\" : \"\";\n const reqStrPlain = `req:${state.premiumRequests ?? 0}/${state.premiumRequestsTotal ?? 1500}${reqWarningPlain}`;\n\n return `[OMP v${state.version}] ${mode} | ${model} | ctx:${ctx}% | tok:~${tokens}/${state.tokensTotal} | ${reqStrPlain} | ${age} | tools:${state.toolsUsed?.size || 0}/${state.toolsTotal ?? 13} | skills:${state.skillsUsed?.size || 0}/${state.skillsTotal ?? 25} | agents:${state.cumulativeAgentsUsed}/${state.agentsTotal ?? 23} | ${state.status}`;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["mkdirSync", "readFileSync", "writeFileSync", "homedir", "join", "fileURLToPath", "join", "homedir", "mkdirSync", "writeFileSync", "readFileSync"]
|
|
7
7
|
}
|