@jiawang1209/codex-hud 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.codex-plugin/plugin.json +41 -0
- package/CHANGELOG.md +9 -0
- package/LICENSE +21 -0
- package/README.md +342 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +206 -0
- package/dist/cli.js.map +1 -0
- package/dist/codex-statusline.d.ts +9 -0
- package/dist/codex-statusline.js +96 -0
- package/dist/codex-statusline.js.map +1 -0
- package/dist/config.d.ts +62 -0
- package/dist/config.js +199 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/installer.d.ts +17 -0
- package/dist/installer.js +125 -0
- package/dist/installer.js.map +1 -0
- package/dist/native-runner.d.ts +28 -0
- package/dist/native-runner.js +122 -0
- package/dist/native-runner.js.map +1 -0
- package/dist/render.d.ts +11 -0
- package/dist/render.js +149 -0
- package/dist/render.js.map +1 -0
- package/dist/snapshot.d.ts +12 -0
- package/dist/snapshot.js +32 -0
- package/dist/snapshot.js.map +1 -0
- package/dist/sources/codex.d.ts +50 -0
- package/dist/sources/codex.js +182 -0
- package/dist/sources/codex.js.map +1 -0
- package/dist/sources/git.d.ts +2 -0
- package/dist/sources/git.js +37 -0
- package/dist/sources/git.js.map +1 -0
- package/dist/sources/session.d.ts +14 -0
- package/dist/sources/session.js +278 -0
- package/dist/sources/session.js.map +1 -0
- package/dist/tmux-runner.d.ts +26 -0
- package/dist/tmux-runner.js +203 -0
- package/dist/tmux-runner.js.map +1 -0
- package/dist/types.d.ts +42 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/docs/installation.md +42 -0
- package/docs/native-codex-cli-patch.md +55 -0
- package/docs/plugin-marketplace.md +42 -0
- package/docs/release.md +35 -0
- package/docs/superpowers/plans/2026-05-23-codex-hud-mvp.md +234 -0
- package/docs/superpowers/plans/2026-05-23-productized-native-bundle.md +431 -0
- package/docs/superpowers/specs/2026-05-23-codex-hud-design.md +197 -0
- package/docs/upstream/codex-command-backed-statusline.md +101 -0
- package/package.json +49 -0
- package/patches/codex-cli-command-statusline.patch +459 -0
- package/plugins/codex-hud/.codex-plugin/plugin.json +41 -0
- package/plugins/codex-hud/skills/codex-hud/SKILL.md +153 -0
- package/skills/codex-hud/SKILL.md +153 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ProgressSnapshot, TodoSnapshot, ToolActivity } from "../types.js";
|
|
2
|
+
export interface SessionSignals {
|
|
3
|
+
context?: ProgressSnapshot;
|
|
4
|
+
usage?: ProgressSnapshot;
|
|
5
|
+
weekly?: ProgressSnapshot;
|
|
6
|
+
tools: ToolActivity[];
|
|
7
|
+
todos: TodoSnapshot;
|
|
8
|
+
}
|
|
9
|
+
export interface ParseSessionOptions {
|
|
10
|
+
recentToolCallLimit?: number;
|
|
11
|
+
}
|
|
12
|
+
export declare function readLatestSessionSignals(codexHome: string, cwd?: string): Promise<SessionSignals>;
|
|
13
|
+
export declare function parseSessionJsonl(text: string, options?: ParseSessionOptions): SessionSignals;
|
|
14
|
+
export declare function findLatestSessionFile(sessionsDir: string, cwd?: string): Promise<string | undefined>;
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
import { readFile, readdir, stat } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
const DEFAULT_RECENT_TOOL_CALL_LIMIT = 12;
|
|
4
|
+
export async function readLatestSessionSignals(codexHome, cwd) {
|
|
5
|
+
const sessionsDir = path.join(codexHome, "sessions");
|
|
6
|
+
const latest = await findLatestSessionFile(sessionsDir, cwd);
|
|
7
|
+
if (!latest)
|
|
8
|
+
return emptySignals();
|
|
9
|
+
try {
|
|
10
|
+
return parseSessionJsonl(await readFile(latest, "utf8"));
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
return emptySignals();
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export function parseSessionJsonl(text, options = {}) {
|
|
17
|
+
const toolsByCall = new Map();
|
|
18
|
+
let context;
|
|
19
|
+
let usage;
|
|
20
|
+
let weekly;
|
|
21
|
+
let todos = { completed: 0, total: 0 };
|
|
22
|
+
let lineIndex = 0;
|
|
23
|
+
for (const line of text.split(/\r?\n/)) {
|
|
24
|
+
lineIndex += 1;
|
|
25
|
+
if (!line.trim())
|
|
26
|
+
continue;
|
|
27
|
+
let entry;
|
|
28
|
+
try {
|
|
29
|
+
entry = JSON.parse(line);
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
const payload = entry.payload;
|
|
35
|
+
if (!payload)
|
|
36
|
+
continue;
|
|
37
|
+
if (payload.type === "function_call" && payload.call_id && payload.name) {
|
|
38
|
+
toolsByCall.set(payload.call_id, {
|
|
39
|
+
name: displayToolName(payload.name),
|
|
40
|
+
status: "active",
|
|
41
|
+
lastIndex: lineIndex,
|
|
42
|
+
});
|
|
43
|
+
if (payload.name === "update_plan") {
|
|
44
|
+
todos = parseUpdatePlanTodos(payload.arguments) ?? todos;
|
|
45
|
+
}
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
if (isCompletionPayload(payload.type) && payload.call_id) {
|
|
49
|
+
const tool = toolsByCall.get(payload.call_id);
|
|
50
|
+
if (tool) {
|
|
51
|
+
tool.status = payload.type === "patch_apply_end" ? "completed" : "completed";
|
|
52
|
+
tool.lastIndex = lineIndex;
|
|
53
|
+
}
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
if (payload.type === "token_count") {
|
|
57
|
+
const totalTokens = payload.info?.last_token_usage?.total_tokens
|
|
58
|
+
?? payload.info?.total_token_usage?.total_tokens;
|
|
59
|
+
const contextWindow = payload.info?.model_context_window;
|
|
60
|
+
if (validPositiveNumber(totalTokens) && validPositiveNumber(contextWindow)) {
|
|
61
|
+
context = {
|
|
62
|
+
label: "Context",
|
|
63
|
+
percent: clampPercent(Math.round((totalTokens / contextWindow) * 100)),
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
const primary = payload.rate_limits?.primary;
|
|
67
|
+
if (validPercent(primary?.used_percent)) {
|
|
68
|
+
usage = {
|
|
69
|
+
label: formatRateLimitWindow(primary?.window_minutes),
|
|
70
|
+
percent: primary.used_percent,
|
|
71
|
+
windowMinutes: validPositiveNumber(primary?.window_minutes) ? primary.window_minutes : undefined,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
const secondary = payload.rate_limits?.secondary;
|
|
75
|
+
if (validPercent(secondary?.used_percent)) {
|
|
76
|
+
const windowMinutes = validPositiveNumber(secondary?.window_minutes)
|
|
77
|
+
? secondary.window_minutes
|
|
78
|
+
: undefined;
|
|
79
|
+
weekly = {
|
|
80
|
+
label: "Weekly",
|
|
81
|
+
percent: secondary.used_percent,
|
|
82
|
+
windowMinutes,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return {
|
|
88
|
+
context,
|
|
89
|
+
usage,
|
|
90
|
+
weekly,
|
|
91
|
+
tools: summarizeTools(toolsByCall, normalizeRecentLimit(options.recentToolCallLimit)),
|
|
92
|
+
todos,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
export async function findLatestSessionFile(sessionsDir, cwd) {
|
|
96
|
+
const files = await listJsonlFiles(sessionsDir);
|
|
97
|
+
if (files.length === 0)
|
|
98
|
+
return undefined;
|
|
99
|
+
const targetCwd = cwd ? normalizePath(cwd) : undefined;
|
|
100
|
+
let latest;
|
|
101
|
+
let latestMatching;
|
|
102
|
+
for (const file of files) {
|
|
103
|
+
try {
|
|
104
|
+
const info = await stat(file);
|
|
105
|
+
if (!latest || info.mtimeMs > latest.mtimeMs || (info.mtimeMs === latest.mtimeMs && file > latest.file)) {
|
|
106
|
+
latest = { file, mtimeMs: info.mtimeMs };
|
|
107
|
+
}
|
|
108
|
+
if (targetCwd && await sessionFileMatchesCwd(file, targetCwd)) {
|
|
109
|
+
if (!latestMatching
|
|
110
|
+
|| info.mtimeMs > latestMatching.mtimeMs
|
|
111
|
+
|| (info.mtimeMs === latestMatching.mtimeMs && file > latestMatching.file)) {
|
|
112
|
+
latestMatching = { file, mtimeMs: info.mtimeMs };
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return latestMatching?.file ?? latest?.file;
|
|
121
|
+
}
|
|
122
|
+
function emptySignals() {
|
|
123
|
+
return {
|
|
124
|
+
tools: [],
|
|
125
|
+
todos: { completed: 0, total: 0 },
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
async function listJsonlFiles(dir) {
|
|
129
|
+
let entries;
|
|
130
|
+
try {
|
|
131
|
+
entries = await readdir(dir, { withFileTypes: true });
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
return [];
|
|
135
|
+
}
|
|
136
|
+
const files = [];
|
|
137
|
+
for (const entry of entries) {
|
|
138
|
+
const fullPath = path.join(dir, entry.name);
|
|
139
|
+
if (entry.isDirectory()) {
|
|
140
|
+
files.push(...await listJsonlFiles(fullPath));
|
|
141
|
+
}
|
|
142
|
+
else if (entry.isFile() && entry.name.endsWith(".jsonl")) {
|
|
143
|
+
files.push(fullPath);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return files;
|
|
147
|
+
}
|
|
148
|
+
function isCompletionPayload(type) {
|
|
149
|
+
return type === "function_call_output"
|
|
150
|
+
|| type === "custom_tool_call_output"
|
|
151
|
+
|| type === "mcp_tool_call_end"
|
|
152
|
+
|| type === "patch_apply_end";
|
|
153
|
+
}
|
|
154
|
+
function summarizeTools(toolsByCall, recentToolCallLimit) {
|
|
155
|
+
const byName = new Map();
|
|
156
|
+
const recentTools = Array.from(toolsByCall.values())
|
|
157
|
+
.sort((a, b) => b.lastIndex - a.lastIndex)
|
|
158
|
+
.slice(0, recentToolCallLimit);
|
|
159
|
+
for (const tool of recentTools) {
|
|
160
|
+
const current = byName.get(tool.name) ?? { active: 0, completed: 0, lastIndex: 0 };
|
|
161
|
+
if (tool.status === "active")
|
|
162
|
+
current.active += 1;
|
|
163
|
+
else
|
|
164
|
+
current.completed += 1;
|
|
165
|
+
current.lastIndex = Math.max(current.lastIndex, tool.lastIndex);
|
|
166
|
+
byName.set(tool.name, current);
|
|
167
|
+
}
|
|
168
|
+
return Array.from(byName.entries())
|
|
169
|
+
.sort((a, b) => b[1].lastIndex - a[1].lastIndex)
|
|
170
|
+
.slice(0, 4)
|
|
171
|
+
.reverse()
|
|
172
|
+
.map(([name, counts]) => ({
|
|
173
|
+
name,
|
|
174
|
+
status: counts.active > 0 ? "active" : "completed",
|
|
175
|
+
count: counts.active + counts.completed,
|
|
176
|
+
}));
|
|
177
|
+
}
|
|
178
|
+
function normalizeRecentLimit(value) {
|
|
179
|
+
if (typeof value !== "number" || !Number.isInteger(value) || value <= 0) {
|
|
180
|
+
return DEFAULT_RECENT_TOOL_CALL_LIMIT;
|
|
181
|
+
}
|
|
182
|
+
return Math.min(value, 100);
|
|
183
|
+
}
|
|
184
|
+
function parseUpdatePlanTodos(argumentsJson) {
|
|
185
|
+
if (!argumentsJson)
|
|
186
|
+
return undefined;
|
|
187
|
+
try {
|
|
188
|
+
const parsed = JSON.parse(argumentsJson);
|
|
189
|
+
if (!Array.isArray(parsed.plan))
|
|
190
|
+
return undefined;
|
|
191
|
+
const total = parsed.plan.length;
|
|
192
|
+
const completed = parsed.plan.filter((item) => item.status === "completed").length;
|
|
193
|
+
const current = parsed.plan.find((item) => item.status === "in_progress")?.step;
|
|
194
|
+
return {
|
|
195
|
+
completed,
|
|
196
|
+
total,
|
|
197
|
+
current: typeof current === "string" ? current : undefined,
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
catch {
|
|
201
|
+
return undefined;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
function displayToolName(name) {
|
|
205
|
+
const normalized = name.split(".").pop() ?? name;
|
|
206
|
+
const known = {
|
|
207
|
+
exec_command: "Exec",
|
|
208
|
+
write_stdin: "Stdin",
|
|
209
|
+
update_plan: "Plan",
|
|
210
|
+
apply_patch: "Patch",
|
|
211
|
+
view_image: "Image",
|
|
212
|
+
js: "Node",
|
|
213
|
+
};
|
|
214
|
+
if (known[normalized])
|
|
215
|
+
return known[normalized];
|
|
216
|
+
return normalized
|
|
217
|
+
.replace(/[_-]+/g, " ")
|
|
218
|
+
.replace(/\b\w/g, (char) => char.toUpperCase())
|
|
219
|
+
.replace(/\s+/g, "");
|
|
220
|
+
}
|
|
221
|
+
function formatRateLimitWindow(windowMinutes) {
|
|
222
|
+
if (!validPositiveNumber(windowMinutes))
|
|
223
|
+
return "Usage";
|
|
224
|
+
if (windowMinutes % 1440 === 0)
|
|
225
|
+
return `${windowMinutes / 1440}d`;
|
|
226
|
+
if (windowMinutes % 60 === 0)
|
|
227
|
+
return `${windowMinutes / 60}h`;
|
|
228
|
+
return `${windowMinutes}m`;
|
|
229
|
+
}
|
|
230
|
+
function validPositiveNumber(value) {
|
|
231
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0;
|
|
232
|
+
}
|
|
233
|
+
function validPercent(value) {
|
|
234
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0 && value <= 100;
|
|
235
|
+
}
|
|
236
|
+
function clampPercent(value) {
|
|
237
|
+
return Math.min(100, Math.max(0, value));
|
|
238
|
+
}
|
|
239
|
+
async function sessionFileMatchesCwd(file, targetCwd) {
|
|
240
|
+
const sessionCwd = await readSessionCwd(file);
|
|
241
|
+
if (!sessionCwd)
|
|
242
|
+
return false;
|
|
243
|
+
return pathsOverlap(normalizePath(sessionCwd), targetCwd);
|
|
244
|
+
}
|
|
245
|
+
async function readSessionCwd(file) {
|
|
246
|
+
let text;
|
|
247
|
+
try {
|
|
248
|
+
text = await readFile(file, "utf8");
|
|
249
|
+
}
|
|
250
|
+
catch {
|
|
251
|
+
return undefined;
|
|
252
|
+
}
|
|
253
|
+
for (const line of text.split(/\r?\n/).slice(0, 80)) {
|
|
254
|
+
if (!line.trim())
|
|
255
|
+
continue;
|
|
256
|
+
try {
|
|
257
|
+
const entry = JSON.parse(line);
|
|
258
|
+
if ((entry.type === "session_meta" || entry.type === "turn_context") && typeof entry.payload?.cwd === "string") {
|
|
259
|
+
return entry.payload.cwd;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
catch {
|
|
263
|
+
continue;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
return undefined;
|
|
267
|
+
}
|
|
268
|
+
function normalizePath(value) {
|
|
269
|
+
return path.resolve(value);
|
|
270
|
+
}
|
|
271
|
+
function pathsOverlap(sessionCwd, targetCwd) {
|
|
272
|
+
return sessionCwd === targetCwd || isWithin(sessionCwd, targetCwd) || isWithin(targetCwd, sessionCwd);
|
|
273
|
+
}
|
|
274
|
+
function isWithin(candidate, parent) {
|
|
275
|
+
const relative = path.relative(parent, candidate);
|
|
276
|
+
return relative.length > 0 && !relative.startsWith("..") && !path.isAbsolute(relative);
|
|
277
|
+
}
|
|
278
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/sources/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,IAAI,MAAM,WAAW,CAAC;AAe7B,MAAM,8BAA8B,GAAG,EAAE,CAAC;AAqC1C,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,SAAiB,EAAE,GAAY;IAC5E,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;IACrD,MAAM,MAAM,GAAG,MAAM,qBAAqB,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;IAC7D,IAAI,CAAC,MAAM;QAAE,OAAO,YAAY,EAAE,CAAC;IAEnC,IAAI,CAAC;QACH,OAAO,iBAAiB,CAAC,MAAM,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC3D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,YAAY,EAAE,CAAC;IACxB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,IAAY,EAAE,UAA+B,EAAE;IAC/E,MAAM,WAAW,GAAG,IAAI,GAAG,EAAqB,CAAC;IACjD,IAAI,OAAqC,CAAC;IAC1C,IAAI,KAAmC,CAAC;IACxC,IAAI,MAAoC,CAAC;IACzC,IAAI,KAAK,GAAiB,EAAE,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;IACrD,IAAI,SAAS,GAAG,CAAC,CAAC;IAElB,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;QACvC,SAAS,IAAI,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;YAAE,SAAS;QAE3B,IAAI,KAAkB,CAAC;QACvB,IAAI,CAAC;YACH,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAgB,CAAC;QAC1C,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;QAED,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;QAC9B,IAAI,CAAC,OAAO;YAAE,SAAS;QAEvB,IAAI,OAAO,CAAC,IAAI,KAAK,eAAe,IAAI,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACxE,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE;gBAC/B,IAAI,EAAE,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC;gBACnC,MAAM,EAAE,QAAQ;gBAChB,SAAS,EAAE,SAAS;aACrB,CAAC,CAAC;YACH,IAAI,OAAO,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;gBACnC,KAAK,GAAG,oBAAoB,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC;YAC3D,CAAC;YACD,SAAS;QACX,CAAC;QAED,IAAI,mBAAmB,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YACzD,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YAC9C,IAAI,IAAI,EAAE,CAAC;gBACT,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,IAAI,KAAK,iBAAiB,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC;gBAC7E,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;YAC7B,CAAC;YACD,SAAS;QACX,CAAC;QAED,IAAI,OAAO,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;YACnC,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,EAAE,gBAAgB,EAAE,YAAY;mBAC3D,OAAO,CAAC,IAAI,EAAE,iBAAiB,EAAE,YAAY,CAAC;YACnD,MAAM,aAAa,GAAG,OAAO,CAAC,IAAI,EAAE,oBAAoB,CAAC;YACzD,IAAI,mBAAmB,CAAC,WAAW,CAAC,IAAI,mBAAmB,CAAC,aAAa,CAAC,EAAE,CAAC;gBAC3E,OAAO,GAAG;oBACR,KAAK,EAAE,SAAS;oBAChB,OAAO,EAAE,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,WAAW,GAAG,aAAa,CAAC,GAAG,GAAG,CAAC,CAAC;iBACvE,CAAC;YACJ,CAAC;YAED,MAAM,OAAO,GAAG,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC;YAC7C,IAAI,YAAY,CAAC,OAAO,EAAE,YAAY,CAAC,EAAE,CAAC;gBACxC,KAAK,GAAG;oBACN,KAAK,EAAE,qBAAqB,CAAC,OAAO,EAAE,cAAc,CAAC;oBACrD,OAAO,EAAE,OAAO,CAAC,YAAY;oBAC7B,aAAa,EAAE,mBAAmB,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,SAAS;iBACjG,CAAC;YACJ,CAAC;YAED,MAAM,SAAS,GAAG,OAAO,CAAC,WAAW,EAAE,SAAS,CAAC;YACjD,IAAI,YAAY,CAAC,SAAS,EAAE,YAAY,CAAC,EAAE,CAAC;gBAC1C,MAAM,aAAa,GAAG,mBAAmB,CAAC,SAAS,EAAE,cAAc,CAAC;oBAClE,CAAC,CAAC,SAAS,CAAC,cAAc;oBAC1B,CAAC,CAAC,SAAS,CAAC;gBACd,MAAM,GAAG;oBACP,KAAK,EAAE,QAAQ;oBACf,OAAO,EAAE,SAAS,CAAC,YAAY;oBAC/B,aAAa;iBACd,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO;QACL,OAAO;QACP,KAAK;QACL,MAAM;QACN,KAAK,EAAE,cAAc,CAAC,WAAW,EAAE,oBAAoB,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;QACrF,KAAK;KACN,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,WAAmB,EAAE,GAAY;IAC3E,MAAM,KAAK,GAAG,MAAM,cAAc,CAAC,WAAW,CAAC,CAAC;IAChD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAEzC,MAAM,SAAS,GAAG,GAAG,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACvD,IAAI,MAAqD,CAAC;IAC1D,IAAI,cAA6D,CAAC;IAClE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC;YAC9B,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,KAAK,MAAM,CAAC,OAAO,IAAI,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;gBACxG,MAAM,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC;YAC3C,CAAC;YACD,IAAI,SAAS,IAAI,MAAM,qBAAqB,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,CAAC;gBAC9D,IACE,CAAC,cAAc;uBACZ,IAAI,CAAC,OAAO,GAAG,cAAc,CAAC,OAAO;uBACrC,CAAC,IAAI,CAAC,OAAO,KAAK,cAAc,CAAC,OAAO,IAAI,IAAI,GAAG,cAAc,CAAC,IAAI,CAAC,EAC1E,CAAC;oBACD,cAAc,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC;gBACnD,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;IACH,CAAC;IACD,OAAO,cAAc,EAAE,IAAI,IAAI,MAAM,EAAE,IAAI,CAAC;AAC9C,CAAC;AAED,SAAS,YAAY;IACnB,OAAO;QACL,KAAK,EAAE,EAAE;QACT,KAAK,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE;KAClC,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,cAAc,CAAC,GAAW;IACvC,IAAI,OAAO,CAAC;IACZ,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IACxD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAC5C,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC;QAChD,CAAC;aAAM,IAAI,KAAK,CAAC,MAAM,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC3D,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,mBAAmB,CAAC,IAAwB;IACnD,OAAO,IAAI,KAAK,sBAAsB;WACjC,IAAI,KAAK,yBAAyB;WAClC,IAAI,KAAK,mBAAmB;WAC5B,IAAI,KAAK,iBAAiB,CAAC;AAClC,CAAC;AAED,SAAS,cAAc,CAAC,WAAmC,EAAE,mBAA2B;IACtF,MAAM,MAAM,GAAG,IAAI,GAAG,EAAoE,CAAC;IAC3F,MAAM,WAAW,GAAG,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC;SACjD,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,CAAC;SACzC,KAAK,CAAC,CAAC,EAAE,mBAAmB,CAAC,CAAC;IAEjC,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;QAC/B,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;QACnF,IAAI,IAAI,CAAC,MAAM,KAAK,QAAQ;YAAE,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC;;YAC7C,OAAO,CAAC,SAAS,IAAI,CAAC,CAAC;QAC5B,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QAChE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACjC,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;SAChC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;SAC/C,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;SACX,OAAO,EAAE;SACT,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC;QACxB,IAAI;QACJ,MAAM,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW;QAClD,KAAK,EAAE,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,SAAS;KACxC,CAAC,CAAC,CAAC;AACR,CAAC;AAED,SAAS,oBAAoB,CAAC,KAAyB;IACrD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;QACxE,OAAO,8BAA8B,CAAC;IACxC,CAAC;IACD,OAAO,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AAC9B,CAAC;AAED,SAAS,oBAAoB,CAAC,aAAiC;IAC7D,IAAI,CAAC,aAAa;QAAE,OAAO,SAAS,CAAC;IAErC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAA2D,CAAC;QACnG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC;YAAE,OAAO,SAAS,CAAC;QAClD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;QACjC,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,MAAM,CAAC;QACnF,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,aAAa,CAAC,EAAE,IAAI,CAAC;QAChF,OAAO;YACL,SAAS;YACT,KAAK;YACL,OAAO,EAAE,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS;SAC3D,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,IAAY;IACnC,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC;IACjD,MAAM,KAAK,GAA2B;QACpC,YAAY,EAAE,MAAM;QACpB,WAAW,EAAE,OAAO;QACpB,WAAW,EAAE,MAAM;QACnB,WAAW,EAAE,OAAO;QACpB,UAAU,EAAE,OAAO;QACnB,EAAE,EAAE,MAAM;KACX,CAAC;IACF,IAAI,KAAK,CAAC,UAAU,CAAC;QAAE,OAAO,KAAK,CAAC,UAAU,CAAC,CAAC;IAChD,OAAO,UAAU;SACd,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC;SACtB,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;SAC9C,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AACzB,CAAC;AAED,SAAS,qBAAqB,CAAC,aAAiC;IAC9D,IAAI,CAAC,mBAAmB,CAAC,aAAa,CAAC;QAAE,OAAO,OAAO,CAAC;IACxD,IAAI,aAAa,GAAG,IAAI,KAAK,CAAC;QAAE,OAAO,GAAG,aAAa,GAAG,IAAI,GAAG,CAAC;IAClE,IAAI,aAAa,GAAG,EAAE,KAAK,CAAC;QAAE,OAAO,GAAG,aAAa,GAAG,EAAE,GAAG,CAAC;IAC9D,OAAO,GAAG,aAAa,GAAG,CAAC;AAC7B,CAAC;AAED,SAAS,mBAAmB,CAAC,KAAc;IACzC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC;AAC1E,CAAC;AAED,SAAS,YAAY,CAAC,KAAc;IAClC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,KAAK,IAAI,GAAG,CAAC;AAC3F,CAAC;AAED,SAAS,YAAY,CAAC,KAAa;IACjC,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;AAC3C,CAAC;AAED,KAAK,UAAU,qBAAqB,CAAC,IAAY,EAAE,SAAiB;IAClE,MAAM,UAAU,GAAG,MAAM,cAAc,CAAC,IAAI,CAAC,CAAC;IAC9C,IAAI,CAAC,UAAU;QAAE,OAAO,KAAK,CAAC;IAC9B,OAAO,YAAY,CAAC,aAAa,CAAC,UAAU,CAAC,EAAE,SAAS,CAAC,CAAC;AAC5D,CAAC;AAED,KAAK,UAAU,cAAc,CAAC,IAAY;IACxC,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC;QACH,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;QACpD,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;YAAE,SAAS;QAC3B,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAmD,CAAC;YACjF,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,cAAc,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,CAAC,IAAI,OAAO,KAAK,CAAC,OAAO,EAAE,GAAG,KAAK,QAAQ,EAAE,CAAC;gBAC/G,OAAO,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;YAC3B,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,aAAa,CAAC,KAAa;IAClC,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC7B,CAAC;AAED,SAAS,YAAY,CAAC,UAAkB,EAAE,SAAiB;IACzD,OAAO,UAAU,KAAK,SAAS,IAAI,QAAQ,CAAC,UAAU,EAAE,SAAS,CAAC,IAAI,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;AACxG,CAAC;AAED,SAAS,QAAQ,CAAC,SAAiB,EAAE,MAAc;IACjD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAClD,OAAO,QAAQ,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;AACzF,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export type TerminalLauncher = "tmux" | "iterm" | "terminal";
|
|
2
|
+
export interface RunOptions {
|
|
3
|
+
codexArgs: string[];
|
|
4
|
+
dryRun: boolean;
|
|
5
|
+
height: number;
|
|
6
|
+
sessionName: string;
|
|
7
|
+
terminal: TerminalLauncher;
|
|
8
|
+
}
|
|
9
|
+
export interface TmuxCommandOptions {
|
|
10
|
+
cwd: string;
|
|
11
|
+
codexArgs?: string[];
|
|
12
|
+
height?: number;
|
|
13
|
+
sessionName: string;
|
|
14
|
+
}
|
|
15
|
+
export declare function parseRunArgs(args: string[]): RunOptions;
|
|
16
|
+
export declare function runCodexHudSession(options: RunOptions, cwd?: string): Promise<number>;
|
|
17
|
+
export declare function dryRunText(options: RunOptions, cwd: string): string;
|
|
18
|
+
export declare function tmuxLaunchCommands(options: RunOptions, cwd: string): string[][];
|
|
19
|
+
export declare function buildTmuxNewSessionArgs(options: TmuxCommandOptions): string[];
|
|
20
|
+
export declare function buildTmuxSplitArgs(options: TmuxCommandOptions & {
|
|
21
|
+
targetPane?: string;
|
|
22
|
+
}): string[];
|
|
23
|
+
export declare function buildTmuxAttachArgs(sessionName: string): string[];
|
|
24
|
+
export declare function buildITermAppleScript(options: TmuxCommandOptions): string;
|
|
25
|
+
export declare function buildMacTerminalAppleScript(options: TmuxCommandOptions): string;
|
|
26
|
+
export declare function shellQuote(value: string): string;
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import { spawn, spawnSync } from "node:child_process";
|
|
2
|
+
import process from "node:process";
|
|
3
|
+
const DEFAULT_HEIGHT = 4;
|
|
4
|
+
export function parseRunArgs(args) {
|
|
5
|
+
const separatorIndex = args.indexOf("--");
|
|
6
|
+
const wrapperArgs = separatorIndex === -1 ? args : args.slice(0, separatorIndex);
|
|
7
|
+
const codexArgs = separatorIndex === -1 ? [] : args.slice(separatorIndex + 1);
|
|
8
|
+
let dryRun = false;
|
|
9
|
+
let height = DEFAULT_HEIGHT;
|
|
10
|
+
let sessionName = `codex-hud-${Date.now()}`;
|
|
11
|
+
let terminal = "tmux";
|
|
12
|
+
for (let index = 0; index < wrapperArgs.length; index += 1) {
|
|
13
|
+
const arg = wrapperArgs[index];
|
|
14
|
+
if (arg === "--dry-run") {
|
|
15
|
+
dryRun = true;
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
if (arg === "--height" && wrapperArgs[index + 1]) {
|
|
19
|
+
height = normalizeHeight(Number(wrapperArgs[index + 1]));
|
|
20
|
+
index += 1;
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
if (arg === "--session" && wrapperArgs[index + 1]) {
|
|
24
|
+
sessionName = sanitizeSessionName(wrapperArgs[index + 1]);
|
|
25
|
+
index += 1;
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
if (arg === "--terminal" && wrapperArgs[index + 1]) {
|
|
29
|
+
terminal = parseTerminal(wrapperArgs[index + 1]);
|
|
30
|
+
index += 1;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return {
|
|
34
|
+
codexArgs,
|
|
35
|
+
dryRun,
|
|
36
|
+
height,
|
|
37
|
+
sessionName,
|
|
38
|
+
terminal,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
export async function runCodexHudSession(options, cwd = process.cwd()) {
|
|
42
|
+
if (options.dryRun) {
|
|
43
|
+
process.stdout.write(`${dryRunText(options, cwd)}\n`);
|
|
44
|
+
return 0;
|
|
45
|
+
}
|
|
46
|
+
if (options.terminal === "iterm") {
|
|
47
|
+
return await runAppleScript(buildITermAppleScript({ cwd, codexArgs: options.codexArgs, sessionName: options.sessionName }));
|
|
48
|
+
}
|
|
49
|
+
if (options.terminal === "terminal") {
|
|
50
|
+
return await runAppleScript(buildMacTerminalAppleScript({
|
|
51
|
+
cwd,
|
|
52
|
+
codexArgs: options.codexArgs,
|
|
53
|
+
sessionName: options.sessionName,
|
|
54
|
+
}));
|
|
55
|
+
}
|
|
56
|
+
if (!commandExists("tmux")) {
|
|
57
|
+
process.stderr.write("codex-hud: tmux is required for `codex-hud run`\n");
|
|
58
|
+
process.stderr.write("codex-hud: install tmux, or use `codex-hud status` and `codex` separately.\n");
|
|
59
|
+
return 1;
|
|
60
|
+
}
|
|
61
|
+
if (process.env.TMUX) {
|
|
62
|
+
await spawnInherited("tmux", buildTmuxSplitArgs({
|
|
63
|
+
cwd,
|
|
64
|
+
height: options.height,
|
|
65
|
+
sessionName: "",
|
|
66
|
+
targetPane: undefined,
|
|
67
|
+
}));
|
|
68
|
+
return await spawnInherited("codex", options.codexArgs);
|
|
69
|
+
}
|
|
70
|
+
for (const args of tmuxLaunchCommands(options, cwd)) {
|
|
71
|
+
const code = await spawnInherited("tmux", args);
|
|
72
|
+
if (code !== 0)
|
|
73
|
+
return code;
|
|
74
|
+
}
|
|
75
|
+
return 0;
|
|
76
|
+
}
|
|
77
|
+
export function dryRunText(options, cwd) {
|
|
78
|
+
if (options.terminal === "iterm") {
|
|
79
|
+
return `osascript <<'APPLESCRIPT'\n${buildITermAppleScript({
|
|
80
|
+
cwd,
|
|
81
|
+
codexArgs: options.codexArgs,
|
|
82
|
+
sessionName: options.sessionName,
|
|
83
|
+
})}\nAPPLESCRIPT`;
|
|
84
|
+
}
|
|
85
|
+
if (options.terminal === "terminal") {
|
|
86
|
+
return `osascript <<'APPLESCRIPT'\n${buildMacTerminalAppleScript({
|
|
87
|
+
cwd,
|
|
88
|
+
codexArgs: options.codexArgs,
|
|
89
|
+
sessionName: options.sessionName,
|
|
90
|
+
})}\nAPPLESCRIPT`;
|
|
91
|
+
}
|
|
92
|
+
const commands = tmuxLaunchCommands(options, cwd);
|
|
93
|
+
return commands.map((command) => `tmux ${command.map(shellQuote).join(" ")}`).join("\n");
|
|
94
|
+
}
|
|
95
|
+
export function tmuxLaunchCommands(options, cwd) {
|
|
96
|
+
return [
|
|
97
|
+
buildTmuxNewSessionArgs({ cwd, codexArgs: options.codexArgs, sessionName: options.sessionName }),
|
|
98
|
+
buildTmuxSplitArgs({ cwd, height: options.height, sessionName: options.sessionName }),
|
|
99
|
+
["select-pane", "-t", `${options.sessionName}:0.0`],
|
|
100
|
+
buildTmuxAttachArgs(options.sessionName),
|
|
101
|
+
];
|
|
102
|
+
}
|
|
103
|
+
export function buildTmuxNewSessionArgs(options) {
|
|
104
|
+
return [
|
|
105
|
+
"new-session",
|
|
106
|
+
"-d",
|
|
107
|
+
"-s",
|
|
108
|
+
options.sessionName,
|
|
109
|
+
"-c",
|
|
110
|
+
options.cwd,
|
|
111
|
+
["codex", ...(options.codexArgs ?? [])].map(shellQuote).join(" "),
|
|
112
|
+
];
|
|
113
|
+
}
|
|
114
|
+
export function buildTmuxSplitArgs(options) {
|
|
115
|
+
const args = [
|
|
116
|
+
"split-window",
|
|
117
|
+
"-v",
|
|
118
|
+
"-l",
|
|
119
|
+
String(options.height ?? DEFAULT_HEIGHT),
|
|
120
|
+
];
|
|
121
|
+
const target = options.targetPane ?? (options.sessionName ? `${options.sessionName}:0.0` : undefined);
|
|
122
|
+
if (target) {
|
|
123
|
+
args.push("-t", target);
|
|
124
|
+
}
|
|
125
|
+
args.push("-c", options.cwd, "codex-hud pane");
|
|
126
|
+
return args;
|
|
127
|
+
}
|
|
128
|
+
export function buildTmuxAttachArgs(sessionName) {
|
|
129
|
+
return ["attach-session", "-t", sessionName];
|
|
130
|
+
}
|
|
131
|
+
export function buildITermAppleScript(options) {
|
|
132
|
+
const codexCommand = shellCommand(options.cwd, ["codex", ...(options.codexArgs ?? [])]);
|
|
133
|
+
const hudCommand = shellCommand(options.cwd, ["codex-hud", "pane"]);
|
|
134
|
+
return [
|
|
135
|
+
'tell application "iTerm2"',
|
|
136
|
+
" activate",
|
|
137
|
+
" set newWindow to (create window with default profile)",
|
|
138
|
+
" tell current session of newWindow",
|
|
139
|
+
` write text ${appleScriptString(codexCommand)}`,
|
|
140
|
+
" set hudSession to (split horizontally with default profile)",
|
|
141
|
+
" end tell",
|
|
142
|
+
" tell hudSession",
|
|
143
|
+
` write text ${appleScriptString(hudCommand)}`,
|
|
144
|
+
" end tell",
|
|
145
|
+
"end tell",
|
|
146
|
+
].join("\n");
|
|
147
|
+
}
|
|
148
|
+
export function buildMacTerminalAppleScript(options) {
|
|
149
|
+
const codexCommand = shellCommand(options.cwd, ["codex", ...(options.codexArgs ?? [])]);
|
|
150
|
+
const hudCommand = shellCommand(options.cwd, ["codex-hud", "pane"]);
|
|
151
|
+
return [
|
|
152
|
+
'tell application "Terminal"',
|
|
153
|
+
" activate",
|
|
154
|
+
` do script ${appleScriptString(codexCommand)}`,
|
|
155
|
+
` do script ${appleScriptString(hudCommand)}`,
|
|
156
|
+
"end tell",
|
|
157
|
+
].join("\n");
|
|
158
|
+
}
|
|
159
|
+
export function shellQuote(value) {
|
|
160
|
+
if (/^[A-Za-z0-9_./:=@%+-]+$/.test(value))
|
|
161
|
+
return value;
|
|
162
|
+
return `'${value.replace(/'/g, "'\\''")}'`;
|
|
163
|
+
}
|
|
164
|
+
function commandExists(command) {
|
|
165
|
+
const result = spawnSync(command, ["-V"], { encoding: "utf8", stdio: "ignore" });
|
|
166
|
+
return result.status === 0;
|
|
167
|
+
}
|
|
168
|
+
function spawnInherited(command, args) {
|
|
169
|
+
return new Promise((resolve) => {
|
|
170
|
+
const child = spawn(command, args, { stdio: "inherit" });
|
|
171
|
+
child.on("error", () => resolve(1));
|
|
172
|
+
child.on("exit", (code) => resolve(code ?? 1));
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
function runAppleScript(script) {
|
|
176
|
+
return new Promise((resolve) => {
|
|
177
|
+
const child = spawn("osascript", [], { stdio: ["pipe", "inherit", "inherit"] });
|
|
178
|
+
child.stdin.end(script);
|
|
179
|
+
child.on("error", () => resolve(1));
|
|
180
|
+
child.on("exit", (code) => resolve(code ?? 1));
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
function normalizeHeight(value) {
|
|
184
|
+
if (!Number.isInteger(value) || value < 3)
|
|
185
|
+
return DEFAULT_HEIGHT;
|
|
186
|
+
return Math.min(value, 12);
|
|
187
|
+
}
|
|
188
|
+
function sanitizeSessionName(value) {
|
|
189
|
+
const sanitized = value.replace(/[^A-Za-z0-9_.-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
190
|
+
return sanitized || `codex-hud-${Date.now()}`;
|
|
191
|
+
}
|
|
192
|
+
function parseTerminal(value) {
|
|
193
|
+
if (value === "iterm" || value === "terminal" || value === "tmux")
|
|
194
|
+
return value;
|
|
195
|
+
return "tmux";
|
|
196
|
+
}
|
|
197
|
+
function shellCommand(cwd, command) {
|
|
198
|
+
return `cd ${shellQuote(cwd)} && ${command.map(shellQuote).join(" ")}`;
|
|
199
|
+
}
|
|
200
|
+
function appleScriptString(value) {
|
|
201
|
+
return `"${value.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
|
|
202
|
+
}
|
|
203
|
+
//# sourceMappingURL=tmux-runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tmux-runner.js","sourceRoot":"","sources":["../src/tmux-runner.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export interface ProgressSnapshot {
|
|
2
|
+
label: string;
|
|
3
|
+
percent: number;
|
|
4
|
+
windowMinutes?: number;
|
|
5
|
+
}
|
|
6
|
+
export interface GitSnapshot {
|
|
7
|
+
branch: string;
|
|
8
|
+
isDirty: boolean;
|
|
9
|
+
ahead: number;
|
|
10
|
+
behind: number;
|
|
11
|
+
}
|
|
12
|
+
export interface ToolActivity {
|
|
13
|
+
name: string;
|
|
14
|
+
status: "active" | "completed" | "error";
|
|
15
|
+
count?: number;
|
|
16
|
+
}
|
|
17
|
+
export interface TodoSnapshot {
|
|
18
|
+
completed: number;
|
|
19
|
+
total: number;
|
|
20
|
+
current?: string;
|
|
21
|
+
}
|
|
22
|
+
export interface SessionSnapshot {
|
|
23
|
+
name?: string;
|
|
24
|
+
duration?: string;
|
|
25
|
+
}
|
|
26
|
+
export interface HudWarning {
|
|
27
|
+
message: string;
|
|
28
|
+
}
|
|
29
|
+
export interface HudSnapshot {
|
|
30
|
+
model?: string;
|
|
31
|
+
reasoningEffort?: string;
|
|
32
|
+
cwd: string;
|
|
33
|
+
projectName: string;
|
|
34
|
+
git?: GitSnapshot;
|
|
35
|
+
context?: ProgressSnapshot;
|
|
36
|
+
usage?: ProgressSnapshot;
|
|
37
|
+
weekly?: ProgressSnapshot;
|
|
38
|
+
tools: ToolActivity[];
|
|
39
|
+
todos: TodoSnapshot;
|
|
40
|
+
session?: SessionSnapshot;
|
|
41
|
+
warnings: HudWarning[];
|
|
42
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Installation
|
|
2
|
+
|
|
3
|
+
## Recommended Native HUD
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npm install -g @jiawang1209/codex-hud
|
|
7
|
+
codex-hud install
|
|
8
|
+
codex
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
`codex-hud install` prepares the complete native bundle:
|
|
12
|
+
|
|
13
|
+
- downloads a clean Codex CLI source checkout under `~/.codex-hud/native/openai-codex`
|
|
14
|
+
- applies the bundled command-backed status-line patch
|
|
15
|
+
- builds the patched Codex binary
|
|
16
|
+
- installs a reversible `codex` shim in `~/.local/bin`
|
|
17
|
+
|
|
18
|
+
After that, users run `codex` normally and Codex HUD is injected into the native Codex footer.
|
|
19
|
+
|
|
20
|
+
## Verify
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
codex-hud doctor
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
The doctor output should report the `codex-hud` binary, `codex` shim, patched Codex binary, and native status command.
|
|
27
|
+
|
|
28
|
+
## Custom Paths
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
codex-hud install --codex-source ~/src/openai-codex --bin-dir ~/.local/bin
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Use this when you already keep a Codex source checkout somewhere else or need a custom shim directory.
|
|
35
|
+
|
|
36
|
+
## Fallback Without Native Adapter
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
codex-hud run
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
This opens Codex with an external HUD pane using tmux, iTerm2, or Terminal.app. It does not require the patched Codex native adapter.
|