@gigaflow/gmux 0.15.0 → 0.16.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/CHANGELOG.md +110 -80
- package/README.md +81 -57
- package/dist/adapters/claude-code.js +5 -2
- package/dist/adapters/claude-code.js.map +1 -1
- package/dist/adapters/codex.js +5 -2
- package/dist/adapters/codex.js.map +1 -1
- package/dist/cli/border-client.d.ts +1 -1
- package/dist/cli/border-client.js +1 -1
- package/dist/cli/commands/cockpit.d.ts +16 -6
- package/dist/cli/commands/cockpit.js +288 -20
- package/dist/cli/commands/cockpit.js.map +1 -1
- package/dist/cli/commands/daemon.d.ts +2 -19
- package/dist/cli/commands/daemon.js +39 -88
- package/dist/cli/commands/daemon.js.map +1 -1
- package/dist/cli/commands/doctor.js +24 -0
- package/dist/cli/commands/doctor.js.map +1 -1
- package/dist/cli/commands/organize.d.ts +18 -0
- package/dist/cli/commands/organize.js +94 -0
- package/dist/cli/commands/organize.js.map +1 -0
- package/dist/cli/commands/setup.js +13 -1
- package/dist/cli/commands/setup.js.map +1 -1
- package/dist/cli/commands/tmux.d.ts +56 -0
- package/dist/cli/commands/tmux.js +158 -28
- package/dist/cli/commands/tmux.js.map +1 -1
- package/dist/cli/gmux-render.d.ts +12 -1
- package/dist/cli/gmux-render.js +18 -11
- package/dist/cli/gmux-render.js.map +1 -1
- package/dist/cli/main.js +2 -0
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/organize-confirm.d.ts +45 -0
- package/dist/cli/organize-confirm.js +57 -0
- package/dist/cli/organize-confirm.js.map +1 -0
- package/dist/cli/overlay-ask.d.ts +3 -1
- package/dist/cli/overlay-ask.js +5 -3
- package/dist/cli/overlay-ask.js.map +1 -1
- package/dist/cli/tmux-label.d.ts +11 -4
- package/dist/cli/tmux-label.js +17 -6
- package/dist/cli/tmux-label.js.map +1 -1
- package/dist/cli/work-report.d.ts +18 -0
- package/dist/cli/work-report.js +50 -0
- package/dist/cli/work-report.js.map +1 -0
- package/dist/core/bytes.d.ts +6 -0
- package/dist/core/bytes.js +13 -0
- package/dist/core/bytes.js.map +1 -0
- package/dist/core/organize-types.d.ts +95 -0
- package/dist/core/organize-types.js +33 -0
- package/dist/core/organize-types.js.map +1 -0
- package/dist/core/paths.d.ts +13 -0
- package/dist/core/paths.js +20 -1
- package/dist/core/paths.js.map +1 -1
- package/dist/services/ask-router.d.ts +44 -0
- package/dist/services/ask-router.js +63 -0
- package/dist/services/ask-router.js.map +1 -0
- package/dist/services/daemon-lock.d.ts +31 -0
- package/dist/services/daemon-lock.js +77 -0
- package/dist/services/daemon-lock.js.map +1 -0
- package/dist/services/daemon.js +35 -6
- package/dist/services/daemon.js.map +1 -1
- package/dist/services/guardian.js +4 -4
- package/dist/services/guardian.js.map +1 -1
- package/dist/services/organize.d.ts +91 -0
- package/dist/services/organize.js +462 -0
- package/dist/services/organize.js.map +1 -0
- package/dist/services/tmux-gateway.d.ts +12 -0
- package/dist/services/tmux-gateway.js +7 -1
- package/dist/services/tmux-gateway.js.map +1 -1
- package/dist/services/tmux.d.ts +17 -1
- package/dist/services/tmux.js +34 -1
- package/dist/services/tmux.js.map +1 -1
- package/dist/services/work-view.d.ts +67 -0
- package/dist/services/work-view.js +155 -0
- package/dist/services/work-view.js.map +1 -0
- package/package.json +1 -1
|
@@ -1,51 +1,319 @@
|
|
|
1
|
+
import { basename } from "node:path";
|
|
2
|
+
import { writeFile } from "node:fs/promises";
|
|
3
|
+
import { workReportPath } from "../../core/paths.js";
|
|
4
|
+
import { buildAskContext, buildAskPrompt, defaultAskProvider } from "../../services/ask.js";
|
|
5
|
+
import { classifyIntent } from "../../services/ask-router.js";
|
|
6
|
+
import { mapLimit } from "../../services/concurrency.js";
|
|
1
7
|
import { readSnapshotFile, subscribe } from "../../services/daemon-client.js";
|
|
8
|
+
import { HeuristicOrganizePlanner, LlmOrganizePlanner, applyPlan } from "../../services/organize.js";
|
|
9
|
+
import { RealTmuxGateway } from "../../services/tmux-gateway.js";
|
|
10
|
+
import { attachSummaries, loadCachedRecords } from "../../services/views.js";
|
|
11
|
+
import { buildWorkViews, defaultWorkViewProvider } from "../../services/work-view.js";
|
|
2
12
|
import { renderCockpit } from "../gmux-render.js";
|
|
3
|
-
import {
|
|
13
|
+
import { confirmFrameLines, confirmKey, makeGeneration } from "../organize-confirm.js";
|
|
14
|
+
import { askBoxLines, askCursorColumn } from "../overlay-ask.js";
|
|
15
|
+
import { fromPaneEntry } from "./organize.js";
|
|
16
|
+
import { renderWorkReportHtml } from "../work-report.js";
|
|
17
|
+
const CLEAR = "\x1b[2J\x1b[H";
|
|
18
|
+
/** The cockpit prompt does both jobs; the box caption names both. */
|
|
19
|
+
const ASK_LABEL = "organize · ask · Enter · ^V report · ^G/Esc close";
|
|
20
|
+
/** One concise answer per session — asked in parallel, but bounded. */
|
|
21
|
+
const ASK_CONCURRENCY = 6;
|
|
4
22
|
/** Clear screen + home, then the cockpit grid — CRLF-joined for raw-mode stdout. */
|
|
5
23
|
export function buildFrame(snapshot, now, opts) {
|
|
6
|
-
return
|
|
24
|
+
return CLEAR + renderCockpit(snapshot, now, opts).join("\r\n");
|
|
25
|
+
}
|
|
26
|
+
/** Collapse an LLM answer to a single line — the cockpit renders answers terse. */
|
|
27
|
+
function oneLine(text) {
|
|
28
|
+
return text.replace(/\s+/g, " ").trim();
|
|
7
29
|
}
|
|
8
30
|
/**
|
|
9
|
-
* The
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
31
|
+
* The panes that have a resolvable session, paired with their record. Pure so
|
|
32
|
+
* the pairing is tested without a daemon: matches on `identity.sessionId`, skips
|
|
33
|
+
* session-less and unmatched panes, and dedupes a session claimed by two panes.
|
|
34
|
+
*/
|
|
35
|
+
export function sessionsForSnapshot(snapshot, records) {
|
|
36
|
+
const byId = new Map(records.map((r) => [r.sessionId, r]));
|
|
37
|
+
const seen = new Set();
|
|
38
|
+
const out = [];
|
|
39
|
+
for (const p of snapshot.panes) {
|
|
40
|
+
const sid = p.identity.sessionId;
|
|
41
|
+
if (!sid || seen.has(sid))
|
|
42
|
+
continue;
|
|
43
|
+
const record = byId.get(sid);
|
|
44
|
+
if (!record)
|
|
45
|
+
continue;
|
|
46
|
+
seen.add(sid);
|
|
47
|
+
out.push({ label: p.identity.cwd ? basename(p.identity.cwd) : p.identity.command, record });
|
|
48
|
+
}
|
|
49
|
+
return out;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* The whole-workspace cockpit: paint the last known snapshot immediately, then
|
|
53
|
+
* stay live off the daemon socket. A prompt line at the bottom takes free text;
|
|
54
|
+
* a quick classify routes it — a question broadcasts to every session and
|
|
55
|
+
* answers inline, a reorganization request is planned from the panes on screen
|
|
56
|
+
* and previewed for confirmation (never auto-applied). `ctrl-v` builds a
|
|
57
|
+
* per-session HTML work report and shows a file:// link in the status banner.
|
|
15
58
|
*/
|
|
16
59
|
export function registerCockpit(program) {
|
|
17
60
|
program
|
|
18
61
|
.command("cockpit")
|
|
19
62
|
.description("pull up the gmux workspace cockpit (used by the tmux ctrl-g binding)")
|
|
20
63
|
.action(async () => {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
64
|
+
let latest = null;
|
|
65
|
+
let stale = null;
|
|
66
|
+
let status = null;
|
|
67
|
+
let input = "";
|
|
68
|
+
let mode = "browse";
|
|
69
|
+
let plan = null;
|
|
70
|
+
let ask = null;
|
|
71
|
+
let busy = false; // a classify / plan / broadcast is in flight
|
|
72
|
+
let reportInFlight = null;
|
|
73
|
+
const gen = makeGeneration(); // invalidates an in-flight classify/plan/ask on cancel
|
|
74
|
+
const cols = () => process.stdout.columns || 120;
|
|
75
|
+
const askView = () => ask
|
|
76
|
+
? { question: ask.question, rows: ask.entries.map((e) => ({ label: e.label, answer: ask.answers.get(e.sessionId) ?? null })) }
|
|
77
|
+
: null;
|
|
78
|
+
const render = () => {
|
|
79
|
+
if (mode === "confirm" && plan) {
|
|
80
|
+
process.stdout.write(CLEAR + confirmFrameLines(plan).join("\r\n"));
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
if (!latest)
|
|
84
|
+
return;
|
|
85
|
+
const width = cols();
|
|
86
|
+
const grid = renderCockpit(latest, Date.now(), { width, stale, status, ask: askView() });
|
|
87
|
+
const box = askBoxLines(input, width, ASK_LABEL);
|
|
88
|
+
const frame = CLEAR + [...grid, ...box].join("\r\n");
|
|
89
|
+
const cursorRow = grid.length + 2; // the box's middle (input) line, 1-based
|
|
90
|
+
process.stdout.write(frame + `\x1b[${cursorRow};${askCursorColumn(input, width)}H`);
|
|
24
91
|
};
|
|
25
|
-
|
|
26
|
-
|
|
92
|
+
const initial = await readSnapshotFile();
|
|
93
|
+
if (initial) {
|
|
94
|
+
latest = initial.snapshot;
|
|
95
|
+
render();
|
|
96
|
+
}
|
|
97
|
+
const onSnapshot = (s) => { latest = s; stale = null; render(); };
|
|
27
98
|
const paintStale = () => {
|
|
28
99
|
readSnapshotFile()
|
|
29
|
-
.then((current) => {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
100
|
+
.then((current) => { if (current) {
|
|
101
|
+
latest = current.snapshot;
|
|
102
|
+
stale = { ageMs: current.ageMs };
|
|
103
|
+
render();
|
|
104
|
+
} })
|
|
33
105
|
.catch(() => { });
|
|
34
106
|
};
|
|
35
|
-
const stop = subscribe(
|
|
107
|
+
const stop = subscribe(onSnapshot, { onError: paintStale });
|
|
108
|
+
/** Build the per-session HTML work report and show its link (ctrl-v). */
|
|
109
|
+
const buildReport = async () => {
|
|
110
|
+
if (!latest)
|
|
111
|
+
return;
|
|
112
|
+
busy = true;
|
|
113
|
+
status = "⧗ building work report…";
|
|
114
|
+
render();
|
|
115
|
+
try {
|
|
116
|
+
const sessions = sessionsForSnapshot(latest, await loadCachedRecords());
|
|
117
|
+
if (sessions.length === 0) {
|
|
118
|
+
status = "no sessions to report";
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
const records = sessions.map((s) => s.record);
|
|
122
|
+
const provider = await defaultWorkViewProvider();
|
|
123
|
+
const built = provider ? await buildWorkViews(records, provider) : null;
|
|
124
|
+
const headlines = new Map((await attachSummaries(records)).map((v) => [v.record.sessionId, v.summary?.headline ?? null]));
|
|
125
|
+
const cards = sessions.map(({ label, record }) => {
|
|
126
|
+
const headline = headlines.get(record.sessionId) ?? null;
|
|
127
|
+
if (!built)
|
|
128
|
+
return { label, headline, html: null, note: "no model configured — run `gmux setup`" };
|
|
129
|
+
const view = built.views.get(record.sessionId);
|
|
130
|
+
if (view)
|
|
131
|
+
return { label, headline, html: view.html, note: null };
|
|
132
|
+
const reason = built.failed.find((f) => f.sessionId === record.sessionId)?.reason ?? "unknown";
|
|
133
|
+
return { label, headline, html: null, note: `generation failed: ${reason}` };
|
|
134
|
+
});
|
|
135
|
+
const path = workReportPath();
|
|
136
|
+
await writeFile(path, renderWorkReportHtml(cards, Date.now()), "utf8");
|
|
137
|
+
status = `✓ work report: file://${path}`;
|
|
138
|
+
}
|
|
139
|
+
catch (error) {
|
|
140
|
+
status = `⚠ ${error.message}`;
|
|
141
|
+
}
|
|
142
|
+
finally {
|
|
143
|
+
busy = false;
|
|
144
|
+
render();
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
/** Broadcast a question to every visible session, answering each inline. */
|
|
148
|
+
const broadcast = async (question, myGen) => {
|
|
149
|
+
const sessions = sessionsForSnapshot(latest, await loadCachedRecords());
|
|
150
|
+
if (!gen.isCurrent(myGen))
|
|
151
|
+
return;
|
|
152
|
+
if (sessions.length === 0) {
|
|
153
|
+
busy = false;
|
|
154
|
+
status = "no sessions to ask";
|
|
155
|
+
render();
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
const answers = new Map();
|
|
159
|
+
ask = { question, entries: sessions.map((s) => ({ label: s.label, sessionId: s.record.sessionId })), answers };
|
|
160
|
+
const provider = await defaultAskProvider();
|
|
161
|
+
if (!provider) {
|
|
162
|
+
for (const s of sessions)
|
|
163
|
+
answers.set(s.record.sessionId, "No model configured — run `gmux setup`.");
|
|
164
|
+
busy = false;
|
|
165
|
+
status = null;
|
|
166
|
+
render();
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
status = "⧗ asking…";
|
|
170
|
+
render();
|
|
171
|
+
const views = await attachSummaries(sessions.map((s) => s.record));
|
|
172
|
+
const byId = new Map(views.map((v) => [v.record.sessionId, v]));
|
|
173
|
+
await mapLimit(sessions, ASK_CONCURRENCY, async (s) => {
|
|
174
|
+
if (!gen.isCurrent(myGen))
|
|
175
|
+
return;
|
|
176
|
+
try {
|
|
177
|
+
const view = byId.get(s.record.sessionId);
|
|
178
|
+
const context = buildAskContext(view ? [view] : [], s.record.sessionId, 1);
|
|
179
|
+
answers.set(s.record.sessionId, oneLine(await provider.ask(buildAskPrompt(context, [], question))));
|
|
180
|
+
}
|
|
181
|
+
catch (error) {
|
|
182
|
+
answers.set(s.record.sessionId, `ask failed: ${error.message}`);
|
|
183
|
+
}
|
|
184
|
+
if (gen.isCurrent(myGen))
|
|
185
|
+
render();
|
|
186
|
+
});
|
|
187
|
+
if (!gen.isCurrent(myGen))
|
|
188
|
+
return;
|
|
189
|
+
busy = false;
|
|
190
|
+
status = null;
|
|
191
|
+
render();
|
|
192
|
+
};
|
|
193
|
+
/**
|
|
194
|
+
* Route a submitted prompt. A quick LLM classify decides: a question goes
|
|
195
|
+
* to the broadcast; a reorganization request is planned from the panes on
|
|
196
|
+
* screen and previewed for confirmation — never auto-applied. The
|
|
197
|
+
* classifier defaults to "ask" on any uncertainty, so a plain question is
|
|
198
|
+
* never mistaken for a reorg.
|
|
199
|
+
*/
|
|
200
|
+
const submit = async (prompt) => {
|
|
201
|
+
if (!latest)
|
|
202
|
+
return;
|
|
203
|
+
const myGen = gen.next();
|
|
204
|
+
busy = true;
|
|
205
|
+
status = "⧗ thinking…";
|
|
206
|
+
render();
|
|
207
|
+
const intent = await classifyIntent(prompt).catch(() => "ask");
|
|
208
|
+
if (!gen.isCurrent(myGen))
|
|
209
|
+
return;
|
|
210
|
+
if (intent === "ask") {
|
|
211
|
+
await broadcast(prompt, myGen);
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
status = "⧗ planning…";
|
|
215
|
+
render();
|
|
216
|
+
const panes = latest.panes.filter((p) => !p.gone).map(fromPaneEntry);
|
|
217
|
+
const built = await new LlmOrganizePlanner(new HeuristicOrganizePlanner()).plan(panes, prompt);
|
|
218
|
+
if (!gen.isCurrent(myGen))
|
|
219
|
+
return;
|
|
220
|
+
plan = built;
|
|
221
|
+
mode = "confirm";
|
|
222
|
+
busy = false;
|
|
223
|
+
status = null;
|
|
224
|
+
render();
|
|
225
|
+
};
|
|
36
226
|
const stdin = process.stdin;
|
|
37
227
|
if (stdin.isTTY)
|
|
38
228
|
stdin.setRawMode?.(true);
|
|
39
229
|
stdin.resume();
|
|
40
230
|
await new Promise((done) => {
|
|
41
231
|
stdin.on("data", (buf) => {
|
|
42
|
-
|
|
43
|
-
|
|
232
|
+
void (async () => {
|
|
233
|
+
const s = buf.toString();
|
|
234
|
+
// The confirm screen owns the keyboard: apply, cancel back to the
|
|
235
|
+
// grid, or hard-exit. Handled first so Esc cancels the plan rather
|
|
236
|
+
// than closing the cockpit.
|
|
237
|
+
if (mode === "confirm") {
|
|
238
|
+
switch (confirmKey(s)) {
|
|
239
|
+
case "apply":
|
|
240
|
+
// applyPlan skips (never throws on) a bad step, but a failure
|
|
241
|
+
// before its per-step loop — e.g. listPanes() — would escape;
|
|
242
|
+
// nothing was applied at that point, so a clean close is safe.
|
|
243
|
+
try {
|
|
244
|
+
if (plan)
|
|
245
|
+
await applyPlan(plan, new RealTmuxGateway());
|
|
246
|
+
}
|
|
247
|
+
catch (error) {
|
|
248
|
+
process.stderr.write(`gmux: organize apply failed — ${error.message}\n`);
|
|
249
|
+
}
|
|
250
|
+
return done();
|
|
251
|
+
case "exit":
|
|
252
|
+
return done();
|
|
253
|
+
case "cancel":
|
|
254
|
+
mode = "browse";
|
|
255
|
+
plan = null;
|
|
256
|
+
status = null;
|
|
257
|
+
render();
|
|
258
|
+
return;
|
|
259
|
+
default:
|
|
260
|
+
return; // ignore any other key while confirming
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
if (s === "\x03" || s === "\x04")
|
|
264
|
+
return done(); // ctrl-c / ctrl-d always exit
|
|
265
|
+
// While a classify / plan / broadcast / report is in flight, Esc or
|
|
266
|
+
// ctrl-g cancels it (a plan can take a while — no lockout); every
|
|
267
|
+
// other key is ignored. The generation guard drops the late result.
|
|
268
|
+
if (busy) {
|
|
269
|
+
if (s === "\x1b" || s === "\x07") {
|
|
270
|
+
gen.next();
|
|
271
|
+
busy = false;
|
|
272
|
+
status = null;
|
|
273
|
+
ask = null;
|
|
274
|
+
render();
|
|
275
|
+
}
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
if (s === "\x16") { // ctrl-v: work report (v itself types into the prompt)
|
|
279
|
+
if (!reportInFlight)
|
|
280
|
+
reportInFlight = buildReport().finally(() => { reportInFlight = null; });
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
if (s === "\x1b" || s === "\x07")
|
|
284
|
+
return done(); // Esc / ctrl-g close (idle)
|
|
285
|
+
if (s.startsWith("\x1b"))
|
|
286
|
+
return; // an arrow or other escape sequence — ignore
|
|
287
|
+
if (s === "\r" || s === "\n") {
|
|
288
|
+
const prompt = input.trim();
|
|
289
|
+
input = "";
|
|
290
|
+
if (!prompt) {
|
|
291
|
+
if (ask)
|
|
292
|
+
ask = null; // empty Enter clears the answers, back to the grid
|
|
293
|
+
render();
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
await submit(prompt);
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
if (s === "\x7f" || s === "\b") {
|
|
300
|
+
input = input.slice(0, -1);
|
|
301
|
+
render();
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
const printable = [...s].filter((c) => c >= " " && c <= "~").join("");
|
|
305
|
+
if (printable) {
|
|
306
|
+
input += printable;
|
|
307
|
+
render();
|
|
308
|
+
}
|
|
309
|
+
})().catch(() => { });
|
|
44
310
|
});
|
|
45
311
|
});
|
|
312
|
+
await reportInFlight;
|
|
46
313
|
stop();
|
|
47
314
|
if (stdin.isTTY)
|
|
48
315
|
stdin.setRawMode?.(false);
|
|
316
|
+
process.stdout.write(CLEAR);
|
|
49
317
|
process.exit(0);
|
|
50
318
|
});
|
|
51
319
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cockpit.js","sourceRoot":"","sources":["../../../src/cli/commands/cockpit.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AAC9E,OAAO,EAAE,aAAa,EAA6B,MAAM,mBAAmB,CAAC;AAC7E,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,oFAAoF;AACpF,MAAM,UAAU,UAAU,CAAC,QAA2B,EAAE,GAAW,EAAE,IAA2B;IAC9F,OAAO,eAAe,GAAG,aAAa,CAAC,QAAQ,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAC3E,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAAC,OAAgB;IAC9C,OAAO;SACJ,OAAO,CAAC,SAAS,CAAC;SAClB,WAAW,CAAC,sEAAsE,CAAC;SACnF,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,MAAM,OAAO,GAAG,MAAM,gBAAgB,EAAE,CAAC;QACzC,MAAM,KAAK,GAAG,CAAC,CAAoB,EAAQ,EAAE;YAC3C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QAClD,CAAC,CAAC;QACF,IAAI,OAAO;YAAE,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAErC,MAAM,UAAU,GAAG,GAAS,EAAE;YAC5B,gBAAgB,EAAE;iBACf,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE;gBAChB,IAAI,OAAO;oBAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC;YACnH,CAAC,CAAC;iBACD,KAAK,CAAC,GAAG,EAAE,GAAwC,CAAC,CAAC,CAAC;QAC3D,CAAC,CAAC;QAEF,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC;QAEvD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QAC5B,IAAI,KAAK,CAAC,KAAK;YAAE,KAAK,CAAC,UAAU,EAAE,CAAC,IAAI,CAAC,CAAC;QAC1C,KAAK,CAAC,MAAM,EAAE,CAAC;QAEf,MAAM,IAAI,OAAO,CAAO,CAAC,IAAI,EAAE,EAAE;YAC/B,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,GAAW,EAAE,EAAE;gBAC/B,IAAI,UAAU,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;oBAAE,IAAI,EAAE,CAAC;YACzC,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,IAAI,EAAE,CAAC;QACP,IAAI,KAAK,CAAC,KAAK;YAAE,KAAK,CAAC,UAAU,EAAE,CAAC,KAAK,CAAC,CAAC;QAC3C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
1
|
+
{"version":3,"file":"cockpit.js","sourceRoot":"","sources":["../../../src/cli/commands/cockpit.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
import type { Command } from "commander";
|
|
15
15
|
import type { GmuxConfig } from "../../core/gmux-types.js";
|
|
16
16
|
import { type DaemonDeps } from "../../services/daemon.js";
|
|
17
|
+
import { acquireDaemonLock, DAEMON_LOCK_STALE_MS, type DaemonLock, daemonLockPath, isDaemonLockStale, readDaemonLock, releaseDaemonLock } from "../../services/daemon-lock.js";
|
|
17
18
|
import { type LabelProvider } from "../../services/semantic.js";
|
|
18
19
|
import { type TmuxGateway } from "../../services/tmux-gateway.js";
|
|
19
20
|
import { WorkspaceModel } from "../../services/workspace.js";
|
|
@@ -53,23 +54,5 @@ export declare function runDaemonLoop(deps: DaemonDeps, opts: LoopOpts): Promise
|
|
|
53
54
|
* the production path; that override is a test-only seam.
|
|
54
55
|
*/
|
|
55
56
|
export declare function buildDaemonDeps(gateway: TmuxGateway, model: WorkspaceModel, gmuxCfg: GmuxConfig, provider: LabelProvider): DaemonDeps;
|
|
56
|
-
|
|
57
|
-
export declare const DAEMON_LOCK_STALE_MS: number;
|
|
58
|
-
export interface DaemonLock {
|
|
59
|
-
pid: number;
|
|
60
|
-
startedAt: string;
|
|
61
|
-
}
|
|
62
|
-
export declare function daemonLockPath(): string;
|
|
63
|
-
/** A lock is stale when its owner is gone, or when it is simply too old. */
|
|
64
|
-
export declare function isDaemonLockStale(lock: DaemonLock, now?: Date, staleMs?: number): boolean;
|
|
65
|
-
/** Corrupt or missing lock reads as "not running" — never throws. */
|
|
66
|
-
export declare function readDaemonLock(): Promise<DaemonLock | null>;
|
|
67
|
-
export declare function releaseDaemonLock(): Promise<void>;
|
|
68
|
-
/**
|
|
69
|
-
* Take the lock for this process, refusing if a live one already exists.
|
|
70
|
-
*
|
|
71
|
-
* Returns false — never throws — when another daemon is already running, so
|
|
72
|
-
* callers can print a clear message and exit rather than crash.
|
|
73
|
-
*/
|
|
74
|
-
export declare function acquireDaemonLock(now?: Date): Promise<boolean>;
|
|
57
|
+
export { acquireDaemonLock, DAEMON_LOCK_STALE_MS, type DaemonLock, daemonLockPath, isDaemonLockStale, readDaemonLock, releaseDaemonLock, };
|
|
75
58
|
export declare function registerDaemon(program: Command): void;
|
|
@@ -11,12 +11,10 @@
|
|
|
11
11
|
* It lives under `gmuxDir()` rather than `cacheDir()` directly because it is
|
|
12
12
|
* gmux-specific ephemeral state, not shared with the rest of gmux.
|
|
13
13
|
*/
|
|
14
|
-
import { mkdir, readFile, rm, writeFile } from "node:fs/promises";
|
|
15
|
-
import { join } from "node:path";
|
|
16
|
-
import { gmuxDir } from "../../core/paths.js";
|
|
17
14
|
import { readConfig, resolveGmuxConfig } from "../../services/config.js";
|
|
18
15
|
import { Daemon } from "../../services/daemon.js";
|
|
19
16
|
import { readSnapshotFile } from "../../services/daemon-client.js";
|
|
17
|
+
import { acquireDaemonLock, DAEMON_LOCK_STALE_MS, daemonLockPath, isDaemonLockStale, readDaemonLock, releaseDaemonLock, } from "../../services/daemon-lock.js";
|
|
20
18
|
import { ModelServer } from "../../services/daemon-socket.js";
|
|
21
19
|
import { Guardian } from "../../services/guardian.js";
|
|
22
20
|
import { ResourceMonitor } from "../../services/resources.js";
|
|
@@ -98,67 +96,12 @@ export function buildDaemonDeps(gateway, model, gmuxCfg, provider) {
|
|
|
98
96
|
return { gateway, model, now: () => Date.now(), semantic, resources, guardian };
|
|
99
97
|
}
|
|
100
98
|
// --- Lock -------------------------------------------------------------
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
if (pid <= 0)
|
|
108
|
-
return false;
|
|
109
|
-
try {
|
|
110
|
-
process.kill(pid, 0);
|
|
111
|
-
return true;
|
|
112
|
-
}
|
|
113
|
-
catch (error) {
|
|
114
|
-
// EPERM means the process exists but belongs to someone else — still alive.
|
|
115
|
-
return error.code === "EPERM";
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
/** A lock is stale when its owner is gone, or when it is simply too old. */
|
|
119
|
-
export function isDaemonLockStale(lock, now = new Date(), staleMs = DAEMON_LOCK_STALE_MS) {
|
|
120
|
-
const started = Date.parse(lock.startedAt);
|
|
121
|
-
if (Number.isNaN(started))
|
|
122
|
-
return true;
|
|
123
|
-
if (now.getTime() - started > staleMs)
|
|
124
|
-
return true;
|
|
125
|
-
return !processAlive(lock.pid);
|
|
126
|
-
}
|
|
127
|
-
/** Corrupt or missing lock reads as "not running" — never throws. */
|
|
128
|
-
export async function readDaemonLock() {
|
|
129
|
-
try {
|
|
130
|
-
const parsed = JSON.parse(await readFile(daemonLockPath(), "utf8"));
|
|
131
|
-
if (typeof parsed?.startedAt !== "string")
|
|
132
|
-
return null;
|
|
133
|
-
const pid = Number(parsed.pid);
|
|
134
|
-
if (!Number.isFinite(pid))
|
|
135
|
-
return null;
|
|
136
|
-
return { pid, startedAt: parsed.startedAt };
|
|
137
|
-
}
|
|
138
|
-
catch {
|
|
139
|
-
return null;
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
async function writeDaemonLock(lock) {
|
|
143
|
-
await mkdir(gmuxDir(), { recursive: true });
|
|
144
|
-
await writeFile(daemonLockPath(), JSON.stringify(lock), "utf8");
|
|
145
|
-
}
|
|
146
|
-
export async function releaseDaemonLock() {
|
|
147
|
-
await rm(daemonLockPath(), { force: true });
|
|
148
|
-
}
|
|
149
|
-
/**
|
|
150
|
-
* Take the lock for this process, refusing if a live one already exists.
|
|
151
|
-
*
|
|
152
|
-
* Returns false — never throws — when another daemon is already running, so
|
|
153
|
-
* callers can print a clear message and exit rather than crash.
|
|
154
|
-
*/
|
|
155
|
-
export async function acquireDaemonLock(now = new Date()) {
|
|
156
|
-
const existing = await readDaemonLock();
|
|
157
|
-
if (existing && !isDaemonLockStale(existing, now))
|
|
158
|
-
return false;
|
|
159
|
-
await writeDaemonLock({ pid: process.pid, startedAt: now.toISOString() });
|
|
160
|
-
return true;
|
|
161
|
-
}
|
|
99
|
+
// Re-exported so existing callers of this module (and its tests) keep
|
|
100
|
+
// working unchanged — the primitives themselves now live in
|
|
101
|
+
// `services/daemon-lock.ts`, a leaf module with no `cli/` dependents, so
|
|
102
|
+
// `cli/tmux-label.ts` can detect a live daemon without importing this file
|
|
103
|
+
// (which itself imports `cli/tmux-label.ts` for `enableBorder`).
|
|
104
|
+
export { acquireDaemonLock, DAEMON_LOCK_STALE_MS, daemonLockPath, isDaemonLockStale, readDaemonLock, releaseDaemonLock, };
|
|
162
105
|
// --- Command ------------------------------------------------------------
|
|
163
106
|
export function registerDaemon(program) {
|
|
164
107
|
const cmd = program.command("daemon").description("run and manage the gmux workspace daemon");
|
|
@@ -172,29 +115,35 @@ export function registerDaemon(program) {
|
|
|
172
115
|
process.exitCode = 1;
|
|
173
116
|
return;
|
|
174
117
|
}
|
|
175
|
-
// From here on the lock is held, so EVERYTHING —
|
|
176
|
-
// `start()`, the loop — must run inside this
|
|
177
|
-
// can throw (
|
|
178
|
-
//
|
|
179
|
-
//
|
|
180
|
-
//
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
const deps = buildDaemonDeps(gateway, model, gmuxCfg, provider);
|
|
187
|
-
const server = new ModelServer(model);
|
|
118
|
+
// From here on the lock is held, so EVERYTHING — config/dep assembly,
|
|
119
|
+
// server construction, `start()`, the loop — must run inside this
|
|
120
|
+
// `try`. Any of those can throw (a bad config file, a label provider
|
|
121
|
+
// that fails to initialize, the socket path being unwritable, a stale
|
|
122
|
+
// socket file that's somehow un-removable, ...); if any of it runs
|
|
123
|
+
// outside a `try/finally` the lock file is leaked forever and every
|
|
124
|
+
// future `gmux daemon run` refuses to start until someone manually
|
|
125
|
+
// deletes it.
|
|
126
|
+
let model;
|
|
127
|
+
let server;
|
|
128
|
+
let onChange;
|
|
188
129
|
const ac = new AbortController();
|
|
189
130
|
const stop = () => ac.abort();
|
|
190
|
-
// Repaints every pane's `@gm_label` on each model change — state only,
|
|
191
|
-
// zero sensing. Never lets a paint failure (e.g. a pane that vanished
|
|
192
|
-
// mid-write) propagate into the model's "change" emitter and take down
|
|
193
|
-
// the daemon loop.
|
|
194
|
-
const onChange = () => {
|
|
195
|
-
paintFromSnapshot(model.snapshot(), (id, text) => gateway.setOption(id, "@gm_label", text)).catch(() => { });
|
|
196
|
-
};
|
|
197
131
|
try {
|
|
132
|
+
const config = await readConfig();
|
|
133
|
+
const gmuxCfg = resolveGmuxConfig(config);
|
|
134
|
+
const provider = await defaultLabelProvider();
|
|
135
|
+
const gateway = new RealTmuxGateway();
|
|
136
|
+
model = new WorkspaceModel();
|
|
137
|
+
const deps = buildDaemonDeps(gateway, model, gmuxCfg, provider);
|
|
138
|
+
server = new ModelServer(model);
|
|
139
|
+
// Repaints every pane's `@gmux_label` on each model change — state
|
|
140
|
+
// only, zero sensing. Never lets a paint failure (e.g. a pane that
|
|
141
|
+
// vanished mid-write) propagate into the model's "change" emitter
|
|
142
|
+
// and take down the daemon loop.
|
|
143
|
+
const paneModel = model;
|
|
144
|
+
onChange = () => {
|
|
145
|
+
paintFromSnapshot(paneModel.snapshot(), (id, text) => gateway.setOption(id, "@gmux_label", text)).catch(() => { });
|
|
146
|
+
};
|
|
198
147
|
await server.start();
|
|
199
148
|
process.on("SIGINT", stop);
|
|
200
149
|
process.on("SIGTERM", stop);
|
|
@@ -204,14 +153,16 @@ export function registerDaemon(program) {
|
|
|
204
153
|
await runDaemonLoop(deps, { tickMs: gmuxCfg.tickMs, signal: ac.signal });
|
|
205
154
|
}
|
|
206
155
|
finally {
|
|
207
|
-
model
|
|
156
|
+
if (model && onChange)
|
|
157
|
+
model.off("change", onChange);
|
|
208
158
|
process.off("SIGINT", stop);
|
|
209
159
|
process.off("SIGTERM", stop);
|
|
210
|
-
// Safe even when `start()` itself threw
|
|
211
|
-
// server was
|
|
160
|
+
// Safe even when `start()` itself threw, or the throw happened
|
|
161
|
+
// before `server` was even assigned: `stop()` no-ops when the
|
|
162
|
+
// server was never started, and force-removes the socket path
|
|
212
163
|
// either way. Never let a cleanup failure hide the original error
|
|
213
164
|
// or, worse, skip releasing the lock below.
|
|
214
|
-
await server
|
|
165
|
+
await server?.stop().catch(() => { });
|
|
215
166
|
await releaseDaemonLock();
|
|
216
167
|
}
|
|
217
168
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"daemon.js","sourceRoot":"","sources":["../../../src/cli/commands/daemon.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;
|
|
1
|
+
{"version":3,"file":"daemon.js","sourceRoot":"","sources":["../../../src/cli/commands/daemon.ts"],"names":[],"mappings":"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"}
|