botmux 2.52.0 → 2.53.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/README.en.md +22 -269
- package/README.md +21 -300
- package/dist/adapters/backend/session-backend-selector.d.ts +5 -1
- package/dist/adapters/backend/session-backend-selector.d.ts.map +1 -1
- package/dist/adapters/backend/session-backend-selector.js +15 -1
- package/dist/adapters/backend/session-backend-selector.js.map +1 -1
- package/dist/adapters/backend/tmux-backend.d.ts.map +1 -1
- package/dist/adapters/backend/tmux-backend.js +3 -0
- package/dist/adapters/backend/tmux-backend.js.map +1 -1
- package/dist/adapters/backend/types.d.ts +22 -0
- package/dist/adapters/backend/types.d.ts.map +1 -1
- package/dist/adapters/backend/types.js +7 -1
- package/dist/adapters/backend/types.js.map +1 -1
- package/dist/adapters/backend/zellij-backend.d.ts +132 -0
- package/dist/adapters/backend/zellij-backend.d.ts.map +1 -0
- package/dist/adapters/backend/zellij-backend.js +375 -0
- package/dist/adapters/backend/zellij-backend.js.map +1 -0
- package/dist/adapters/backend/zellij-observe-backend.d.ts +62 -0
- package/dist/adapters/backend/zellij-observe-backend.d.ts.map +1 -0
- package/dist/adapters/backend/zellij-observe-backend.js +218 -0
- package/dist/adapters/backend/zellij-observe-backend.js.map +1 -0
- package/dist/adapters/cli/claude-code.d.ts +39 -5
- package/dist/adapters/cli/claude-code.d.ts.map +1 -1
- package/dist/adapters/cli/claude-code.js +53 -31
- package/dist/adapters/cli/claude-code.js.map +1 -1
- package/dist/adapters/cli/registry.d.ts +2 -1
- package/dist/adapters/cli/registry.d.ts.map +1 -1
- package/dist/adapters/cli/registry.js +3 -1
- package/dist/adapters/cli/registry.js.map +1 -1
- package/dist/adapters/cli/seed.d.ts +29 -0
- package/dist/adapters/cli/seed.d.ts.map +1 -0
- package/dist/adapters/cli/seed.js +63 -0
- package/dist/adapters/cli/seed.js.map +1 -0
- package/dist/adapters/cli/types.d.ts +17 -1
- package/dist/adapters/cli/types.d.ts.map +1 -1
- package/dist/bot-registry.d.ts +1 -1
- package/dist/bot-registry.d.ts.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +37 -27
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +7 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +8 -0
- package/dist/config.js.map +1 -1
- package/dist/core/ask-hook/registry.d.ts.map +1 -1
- package/dist/core/ask-hook/registry.js +4 -0
- package/dist/core/ask-hook/registry.js.map +1 -1
- package/dist/core/command-handler.d.ts +4 -1
- package/dist/core/command-handler.d.ts.map +1 -1
- package/dist/core/command-handler.js +100 -8
- package/dist/core/command-handler.js.map +1 -1
- package/dist/core/dispatch.d.ts +33 -0
- package/dist/core/dispatch.d.ts.map +1 -1
- package/dist/core/dispatch.js +26 -0
- package/dist/core/dispatch.js.map +1 -1
- package/dist/core/session-discovery.d.ts +13 -4
- package/dist/core/session-discovery.d.ts.map +1 -1
- package/dist/core/session-discovery.js +5 -5
- package/dist/core/session-discovery.js.map +1 -1
- package/dist/core/session-manager.d.ts +10 -0
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +43 -18
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/types.d.ts +5 -2
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/core/worker-pool.d.ts +1 -1
- package/dist/core/worker-pool.d.ts.map +1 -1
- package/dist/core/worker-pool.js +22 -9
- package/dist/core/worker-pool.js.map +1 -1
- package/dist/core/zellij-adopt-discovery.d.ts +28 -0
- package/dist/core/zellij-adopt-discovery.d.ts.map +1 -0
- package/dist/core/zellij-adopt-discovery.js +255 -0
- package/dist/core/zellij-adopt-discovery.js.map +1 -0
- package/dist/core/zellij-session-discovery.d.ts +73 -0
- package/dist/core/zellij-session-discovery.d.ts.map +1 -0
- package/dist/core/zellij-session-discovery.js +259 -0
- package/dist/core/zellij-session-discovery.js.map +1 -0
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +7 -3
- package/dist/daemon.js.map +1 -1
- package/dist/dashboard/web/i18n.js +1 -1
- package/dist/dashboard/web/i18n.js.map +1 -1
- package/dist/dashboard/web/sessions.d.ts.map +1 -1
- package/dist/dashboard/web/sessions.js +1 -0
- package/dist/dashboard/web/sessions.js.map +1 -1
- package/dist/dashboard/web/workflows.js +1 -1
- package/dist/dashboard/web/workflows.js.map +1 -1
- package/dist/dashboard-web/app.js +3 -3
- package/dist/i18n/en.d.ts.map +1 -1
- package/dist/i18n/en.js +8 -0
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/zh.d.ts.map +1 -1
- package/dist/i18n/zh.js +9 -1
- package/dist/i18n/zh.js.map +1 -1
- package/dist/im/lark/card-builder.d.ts +4 -1
- package/dist/im/lark/card-builder.d.ts.map +1 -1
- package/dist/im/lark/card-builder.js +59 -2
- package/dist/im/lark/card-builder.js.map +1 -1
- package/dist/im/lark/card-handler.d.ts.map +1 -1
- package/dist/im/lark/card-handler.js +66 -6
- package/dist/im/lark/card-handler.js.map +1 -1
- package/dist/im/lark/grant-command.d.ts +13 -0
- package/dist/im/lark/grant-command.d.ts.map +1 -1
- package/dist/im/lark/grant-command.js +93 -0
- package/dist/im/lark/grant-command.js.map +1 -1
- package/dist/services/codex-app-threads.d.ts +20 -0
- package/dist/services/codex-app-threads.d.ts.map +1 -0
- package/dist/services/codex-app-threads.js +165 -0
- package/dist/services/codex-app-threads.js.map +1 -0
- package/dist/setup/bot-config-editor.d.ts +1 -1
- package/dist/setup/bot-config-editor.d.ts.map +1 -1
- package/dist/setup/bot-config-editor.js +5 -4
- package/dist/setup/bot-config-editor.js.map +1 -1
- package/dist/setup/ensure-zellij.d.ts +48 -0
- package/dist/setup/ensure-zellij.d.ts.map +1 -0
- package/dist/setup/ensure-zellij.js +93 -0
- package/dist/setup/ensure-zellij.js.map +1 -0
- package/dist/types.d.ts +9 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/anchor-serializer.d.ts +3 -2
- package/dist/utils/anchor-serializer.d.ts.map +1 -1
- package/dist/utils/anchor-serializer.js +20 -5
- package/dist/utils/anchor-serializer.js.map +1 -1
- package/dist/utils/transient-snapshot.js +2 -2
- package/dist/utils/transient-snapshot.js.map +1 -1
- package/dist/worker.js +124 -30
- package/dist/worker.js.map +1 -1
- package/dist/workflows/attempt-resume.d.ts +1 -1
- package/dist/workflows/attempt-resume.d.ts.map +1 -1
- package/dist/workflows/attempt-resume.js +1 -1
- package/dist/workflows/attempt-resume.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zellij adopt discovery — find CLIs running in a user's zellij sessions and
|
|
3
|
+
* resolve the (paneId, pid, cwd, cliSessionId) needed to adopt them.
|
|
4
|
+
*
|
|
5
|
+
* The per-pid resolution (CLI detection, cwd, CLI-native session id) is shared
|
|
6
|
+
* with the tmux path (session-discovery.ts) — multiplexer-agnostic. What's
|
|
7
|
+
* zellij-specific is pane enumeration (`dump-layout` for command/cwd +
|
|
8
|
+
* `list-panes` for the drive id) and the pane→pid join.
|
|
9
|
+
*
|
|
10
|
+
* pane→pid join: zellij exposes no pid in list-panes, so we enumerate the
|
|
11
|
+
* session server's descendant CLI processes and match each dump-layout pane by
|
|
12
|
+
* (cliId, cwd). cwd is a strong discriminator (each CLI usually in its own
|
|
13
|
+
* project dir). If a pane matches zero or >1 process, we REFUSE it (skip) —
|
|
14
|
+
* better no-adopt than adopting the wrong pane (Codex's guidance).
|
|
15
|
+
*/
|
|
16
|
+
import { realpathSync, readFileSync } from 'node:fs';
|
|
17
|
+
import { basename } from 'node:path';
|
|
18
|
+
import { cliIdForComm, readComm, readCwd, getChildPids, readClaudeSessionMeta, } from './session-discovery.js';
|
|
19
|
+
import { findCodexRolloutByPid } from '../services/codex-transcript.js';
|
|
20
|
+
import { findCocoSessionByPid } from '../services/coco-transcript.js';
|
|
21
|
+
import { findServerPid } from '../adapters/backend/zellij-backend.js';
|
|
22
|
+
import { listLiveSessions, parseDumpLayoutLeafPanes, parseListPanesJson, } from './zellij-session-discovery.js';
|
|
23
|
+
import { zellijEnv } from '../setup/ensure-zellij.js';
|
|
24
|
+
import { logger } from '../utils/logger.js';
|
|
25
|
+
import { execFileSync } from 'node:child_process';
|
|
26
|
+
/** Normalise a path for comparison (resolve symlinks + strip trailing slash). */
|
|
27
|
+
function canonPath(p) {
|
|
28
|
+
if (!p)
|
|
29
|
+
return undefined;
|
|
30
|
+
let out = p;
|
|
31
|
+
try {
|
|
32
|
+
out = realpathSync(p);
|
|
33
|
+
}
|
|
34
|
+
catch { /* keep raw */ }
|
|
35
|
+
return out.length > 1 && out.endsWith('/') ? out.slice(0, -1) : out;
|
|
36
|
+
}
|
|
37
|
+
/** Interpreters that launch a CLI as a script argument (fnm/npx shims, etc.),
|
|
38
|
+
* so the CLI identity lives in argv, not in comm. */
|
|
39
|
+
const INTERPRETERS = new Set(['node', 'nodejs', 'bun', 'deno', 'python', 'python2', 'python3', 'ruby', 'npx', 'tsx']);
|
|
40
|
+
/** /proc/<pid>/cmdline → argv (Linux fast path; ps fallback for macOS). */
|
|
41
|
+
function readCmdline(pid) {
|
|
42
|
+
try {
|
|
43
|
+
return readFileSync(`/proc/${pid}/cmdline`, 'utf-8').split('\0').filter(Boolean);
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
try {
|
|
47
|
+
const out = execFileSync('ps', ['-o', 'args=', '-p', String(pid)], { encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'] });
|
|
48
|
+
return out.trim().split(/\s+/).filter(Boolean);
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
return [];
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Resolve a CliId from a process's comm + argv (pure — unit testable). Checks
|
|
57
|
+
* comm first (renamed binary, e.g. `codex`/`claude`); if comm is a bare
|
|
58
|
+
* interpreter (e.g. an fnm shim launches `node …/bin/codex`, so /proc/comm is
|
|
59
|
+
* "node"), scan argv for the CLI script basename. Without this, node-wrapped
|
|
60
|
+
* CLIs are invisible to discovery.
|
|
61
|
+
*/
|
|
62
|
+
export function cliIdFromCommArgv(comm, argv, filterCliId) {
|
|
63
|
+
if (!comm)
|
|
64
|
+
return undefined;
|
|
65
|
+
// cliIdForComm only special-cases mtr/opencode for filterCliId; it does NOT
|
|
66
|
+
// otherwise filter — so apply the filter explicitly at the end.
|
|
67
|
+
let detected = cliIdForComm(comm, filterCliId);
|
|
68
|
+
if (!detected && INTERPRETERS.has(comm)) {
|
|
69
|
+
for (const arg of argv.slice(1)) {
|
|
70
|
+
if (arg.startsWith('-'))
|
|
71
|
+
continue; // skip flags
|
|
72
|
+
const id = cliIdForComm(basename(arg), filterCliId);
|
|
73
|
+
if (id) {
|
|
74
|
+
detected = id;
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
if (!detected)
|
|
80
|
+
return undefined;
|
|
81
|
+
if (filterCliId && detected !== filterCliId)
|
|
82
|
+
return undefined;
|
|
83
|
+
return detected;
|
|
84
|
+
}
|
|
85
|
+
function cliIdForProc(pid, filterCliId) {
|
|
86
|
+
return cliIdFromCommArgv(readComm(pid), readCmdline(pid), filterCliId);
|
|
87
|
+
}
|
|
88
|
+
/** BFS the process tree under rootPid collecting every known CLI process with
|
|
89
|
+
* its cwd, for matching against dump-layout panes. Interpreter-wrapper chains
|
|
90
|
+
* (e.g. an fnm shim `node …/bin/codex` whose child is the native `codex`
|
|
91
|
+
* binary) are collapsed to ONE entry — the deepest match — so a single CLI
|
|
92
|
+
* doesn't look like two same-cwd candidates (which would trip the ambiguity
|
|
93
|
+
* guard). The deepest process is also the one holding the transcript fds,
|
|
94
|
+
* matching tmux's findCliProcess. */
|
|
95
|
+
function findAllClisUnder(rootPid, maxDepth, filterCliId) {
|
|
96
|
+
const found = [];
|
|
97
|
+
const parentOf = new Map();
|
|
98
|
+
let current = [rootPid];
|
|
99
|
+
for (let depth = 0; depth <= maxDepth && current.length > 0; depth++) {
|
|
100
|
+
const next = [];
|
|
101
|
+
for (const pid of current) {
|
|
102
|
+
const cliId = cliIdForProc(pid, filterCliId);
|
|
103
|
+
if (cliId)
|
|
104
|
+
found.push({ pid, cliId, cwd: canonPath(readCwd(pid)) });
|
|
105
|
+
for (const ch of getChildPids(pid)) {
|
|
106
|
+
parentOf.set(ch, pid);
|
|
107
|
+
next.push(ch);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
current = next;
|
|
111
|
+
}
|
|
112
|
+
// Drop a match that is an ancestor of another same-cliId match (the wrapper);
|
|
113
|
+
// keep the deepest (native) process.
|
|
114
|
+
const isAncestor = (anc, desc) => {
|
|
115
|
+
let p = desc;
|
|
116
|
+
while (p !== undefined && parentOf.has(p)) {
|
|
117
|
+
p = parentOf.get(p);
|
|
118
|
+
if (p === anc)
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
121
|
+
return false;
|
|
122
|
+
};
|
|
123
|
+
return found.filter(m => !found.some(n => n.pid !== m.pid && n.cliId === m.cliId && isAncestor(m.pid, n.pid)));
|
|
124
|
+
}
|
|
125
|
+
/** Run a read-only `zellij --session S action …`, returning stdout or null. */
|
|
126
|
+
function zellijRead(session, args) {
|
|
127
|
+
try {
|
|
128
|
+
return execFileSync('zellij', ['--session', session, 'action', ...args], {
|
|
129
|
+
encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'], timeout: 4000, env: zellijEnv(),
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
/** Trailing integer of a "terminal_<n>" id, for stable sorting. */
|
|
137
|
+
function paneNum(paneId) {
|
|
138
|
+
const m = paneId.match(/(\d+)$/);
|
|
139
|
+
return m ? Number(m[1]) : 0;
|
|
140
|
+
}
|
|
141
|
+
/** Live pane dimensions (content area) for a paneId in a session. */
|
|
142
|
+
function paneDimensions(session, paneId) {
|
|
143
|
+
try {
|
|
144
|
+
const out = execFileSync('zellij', ['--session', session, 'action', 'list-panes', '--json'], {
|
|
145
|
+
encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'], timeout: 3000, env: zellijEnv(),
|
|
146
|
+
});
|
|
147
|
+
const arr = JSON.parse(out);
|
|
148
|
+
if (!Array.isArray(arr))
|
|
149
|
+
return undefined;
|
|
150
|
+
const pane = arr.find((p) => !p.is_plugin && `terminal_${p.id}` === paneId);
|
|
151
|
+
if (!pane)
|
|
152
|
+
return undefined;
|
|
153
|
+
const cols = Number(pane.pane_content_columns ?? pane.pane_columns);
|
|
154
|
+
const rows = Number(pane.pane_content_rows ?? pane.pane_rows);
|
|
155
|
+
if (!Number.isFinite(cols) || !Number.isFinite(rows))
|
|
156
|
+
return undefined;
|
|
157
|
+
return { cols, rows };
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
return undefined;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
function resolveSessionId(cliId, pid) {
|
|
164
|
+
if (cliId === 'claude-code') {
|
|
165
|
+
const meta = readClaudeSessionMeta(pid);
|
|
166
|
+
return { sessionId: meta?.sessionId, startedAt: meta?.startedAt };
|
|
167
|
+
}
|
|
168
|
+
if (cliId === 'codex') {
|
|
169
|
+
const rollout = findCodexRolloutByPid(pid);
|
|
170
|
+
return { sessionId: rollout?.cliSessionId };
|
|
171
|
+
}
|
|
172
|
+
if (cliId === 'coco') {
|
|
173
|
+
const coco = findCocoSessionByPid(pid);
|
|
174
|
+
return { sessionId: coco?.sessionId };
|
|
175
|
+
}
|
|
176
|
+
return {};
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Scan all live zellij sessions for adoptable CLIs. Skips bmx-* (botmux's own).
|
|
180
|
+
* @param filterCliId only return sessions matching this CLI type.
|
|
181
|
+
*/
|
|
182
|
+
export function discoverAdoptableZellijSessions(filterCliId) {
|
|
183
|
+
const results = [];
|
|
184
|
+
for (const session of listLiveSessions()) {
|
|
185
|
+
if (session.startsWith('bmx-'))
|
|
186
|
+
continue;
|
|
187
|
+
const layoutOut = zellijRead(session, ['dump-layout']);
|
|
188
|
+
const panesOut = zellijRead(session, ['list-panes', '--json']);
|
|
189
|
+
if (!layoutOut || !panesOut)
|
|
190
|
+
continue;
|
|
191
|
+
// Positional join: ALL leaf terminal panes (command + bare shell) in
|
|
192
|
+
// dump-layout document order vs non-plugin/non-floating terminals in
|
|
193
|
+
// list-panes sorted by id. Counts MUST match or the alignment is
|
|
194
|
+
// untrustworthy — refuse the whole session rather than bind the wrong pane.
|
|
195
|
+
const leaves = parseDumpLayoutLeafPanes(layoutOut);
|
|
196
|
+
const terminals = parseListPanesJson(panesOut)
|
|
197
|
+
.filter(p => !p.isPlugin && !p.isFloating)
|
|
198
|
+
.sort((a, b) => paneNum(a.paneId) - paneNum(b.paneId));
|
|
199
|
+
if (leaves.length === 0 || leaves.length !== terminals.length) {
|
|
200
|
+
if (leaves.length !== terminals.length) {
|
|
201
|
+
logger.debug(`[zellij-adopt] ${session}: leaf(${leaves.length})/terminal(${terminals.length}) count mismatch — refusing adopt`);
|
|
202
|
+
}
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
205
|
+
const serverPid = findServerPid(session);
|
|
206
|
+
if (!serverPid)
|
|
207
|
+
continue;
|
|
208
|
+
const clis = findAllClisUnder(serverPid, 4, filterCliId);
|
|
209
|
+
for (let i = 0; i < leaves.length; i++) {
|
|
210
|
+
const leaf = leaves[i];
|
|
211
|
+
const term = terminals[i];
|
|
212
|
+
if (!leaf.command)
|
|
213
|
+
continue; // bare shell pane — not adoptable
|
|
214
|
+
// The cliId comes from the actual PROCESS (cliIdForProc handles
|
|
215
|
+
// node-wrapped CLIs where dump-layout's command is just "node"); we only
|
|
216
|
+
// need leaf.command to know the pane is running something. Bind by cwd:
|
|
217
|
+
// each running pane's cwd should match exactly one process-tree CLI of
|
|
218
|
+
// the (already filtered) cliId. `clis` is pre-filtered by filterCliId.
|
|
219
|
+
const paneCwd = canonPath(leaf.cwd);
|
|
220
|
+
const matches = clis.filter(c => c.cwd && c.cwd === paneCwd);
|
|
221
|
+
// Refuse ambiguous (>1) or unresolved (0) — never adopt the wrong pane.
|
|
222
|
+
if (matches.length !== 1)
|
|
223
|
+
continue;
|
|
224
|
+
const cli = matches[0];
|
|
225
|
+
const dims = paneDimensions(session, term.paneId);
|
|
226
|
+
if (!dims)
|
|
227
|
+
continue;
|
|
228
|
+
const { sessionId, startedAt } = resolveSessionId(cli.cliId, cli.pid);
|
|
229
|
+
results.push({
|
|
230
|
+
zellijSession: session,
|
|
231
|
+
zellijPaneId: term.paneId,
|
|
232
|
+
cliPid: cli.pid,
|
|
233
|
+
cliId: cli.cliId,
|
|
234
|
+
sessionId,
|
|
235
|
+
cwd: cli.cwd ?? leaf.cwd ?? '',
|
|
236
|
+
startedAt,
|
|
237
|
+
paneCols: dims.cols,
|
|
238
|
+
paneRows: dims.rows,
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
return results;
|
|
243
|
+
}
|
|
244
|
+
/** Re-confirm a zellij pane still runs the expected CLI pid (pre-adopt guard). */
|
|
245
|
+
export function validateZellijAdoptTarget(session, paneId, expectedPid) {
|
|
246
|
+
const serverPid = findServerPid(session);
|
|
247
|
+
if (!serverPid)
|
|
248
|
+
return false;
|
|
249
|
+
const clis = findAllClisUnder(serverPid, 4);
|
|
250
|
+
if (!clis.some(c => c.pid === expectedPid))
|
|
251
|
+
return false;
|
|
252
|
+
// And the pane must still exist.
|
|
253
|
+
return paneDimensions(session, paneId) !== undefined;
|
|
254
|
+
}
|
|
255
|
+
//# sourceMappingURL=zellij-adopt-discovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zellij-adopt-discovery.js","sourceRoot":"","sources":["../../src/core/zellij-adopt-discovery.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAErC,OAAO,EACL,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,EAAE,qBAAqB,GACrE,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,uCAAuC,CAAC;AACtE,OAAO,EACL,gBAAgB,EAAE,wBAAwB,EAAE,kBAAkB,GAC/D,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAclD,iFAAiF;AACjF,SAAS,SAAS,CAAC,CAAqB;IACtC,IAAI,CAAC,CAAC;QAAE,OAAO,SAAS,CAAC;IACzB,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,IAAI,CAAC;QAAC,GAAG,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,cAAc,CAAC,CAAC;IACvD,OAAO,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;AACtE,CAAC;AAED;sDACsD;AACtD,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;AAEtH,2EAA2E;AAC3E,SAAS,WAAW,CAAC,GAAW;IAC9B,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,SAAS,GAAG,UAAU,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACnF,CAAC;IAAC,MAAM,CAAC;QACP,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;YAC/H,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACjD,CAAC;QAAC,MAAM,CAAC;YAAC,OAAO,EAAE,CAAC;QAAC,CAAC;IACxB,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAwB,EAAE,IAAc,EAAE,WAAmB;IAC7F,IAAI,CAAC,IAAI;QAAE,OAAO,SAAS,CAAC;IAC5B,4EAA4E;IAC5E,gEAAgE;IAChE,IAAI,QAAQ,GAAG,YAAY,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IAC/C,IAAI,CAAC,QAAQ,IAAI,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QACxC,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;YAChC,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC;gBAAE,SAAS,CAAC,aAAa;YAChD,MAAM,EAAE,GAAG,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,WAAW,CAAC,CAAC;YACpD,IAAI,EAAE,EAAE,CAAC;gBAAC,QAAQ,GAAG,EAAE,CAAC;gBAAC,MAAM;YAAC,CAAC;QACnC,CAAC;IACH,CAAC;IACD,IAAI,CAAC,QAAQ;QAAE,OAAO,SAAS,CAAC;IAChC,IAAI,WAAW,IAAI,QAAQ,KAAK,WAAW;QAAE,OAAO,SAAS,CAAC;IAC9D,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,YAAY,CAAC,GAAW,EAAE,WAAmB;IACpD,OAAO,iBAAiB,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,WAAW,CAAC,GAAG,CAAC,EAAE,WAAW,CAAC,CAAC;AACzE,CAAC;AAED;;;;;;sCAMsC;AACtC,SAAS,gBAAgB,CACvB,OAAe,EACf,QAAgB,EAChB,WAAmB;IAEnB,MAAM,KAAK,GAAuD,EAAE,CAAC;IACrE,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC3C,IAAI,OAAO,GAAG,CAAC,OAAO,CAAC,CAAC;IACxB,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,IAAI,QAAQ,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;QACrE,MAAM,IAAI,GAAa,EAAE,CAAC;QAC1B,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;YAC1B,MAAM,KAAK,GAAG,YAAY,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;YAC7C,IAAI,KAAK;gBAAE,KAAK,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;YACpE,KAAK,MAAM,EAAE,IAAI,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC;gBAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;gBAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAAC,CAAC;QAC/E,CAAC;QACD,OAAO,GAAG,IAAI,CAAC;IACjB,CAAC;IACD,8EAA8E;IAC9E,qCAAqC;IACrC,MAAM,UAAU,GAAG,CAAC,GAAW,EAAE,IAAY,EAAW,EAAE;QACxD,IAAI,CAAC,GAAuB,IAAI,CAAC;QACjC,OAAO,CAAC,KAAK,SAAS,IAAI,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YAAC,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YAAC,IAAI,CAAC,KAAK,GAAG;gBAAE,OAAO,IAAI,CAAC;QAAC,CAAC;QAC/F,OAAO,KAAK,CAAC;IACf,CAAC,CAAC;IACF,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,KAAK,IAAI,UAAU,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AACjH,CAAC;AAED,+EAA+E;AAC/E,SAAS,UAAU,CAAC,OAAe,EAAE,IAAc;IACjD,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,QAAQ,EAAE,CAAC,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,EAAE;YACvE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE;SACxF,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,mEAAmE;AACnE,SAAS,OAAO,CAAC,MAAc;IAC7B,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IACjC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9B,CAAC;AAED,qEAAqE;AACrE,SAAS,cAAc,CAAC,OAAe,EAAE,MAAc;IACrD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,QAAQ,EAAE,CAAC,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,QAAQ,CAAC,EAAE;YAC3F,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE;SACxF,CAAC,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;YAAE,OAAO,SAAS,CAAC;QAC1C,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,IAAI,YAAY,CAAC,CAAC,EAAE,EAAE,KAAK,MAAM,CAAC,CAAC;QACjF,IAAI,CAAC,IAAI;YAAE,OAAO,SAAS,CAAC;QAC5B,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,oBAAoB,IAAI,IAAI,CAAC,YAAY,CAAC,CAAC;QACpE,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,iBAAiB,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC;QAC9D,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,OAAO,SAAS,CAAC;QACvE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACxB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAY,EAAE,GAAW;IACjD,IAAI,KAAK,KAAK,aAAa,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,qBAAqB,CAAC,GAAG,CAAC,CAAC;QACxC,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IACpE,CAAC;IACD,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;QACtB,MAAM,OAAO,GAAG,qBAAqB,CAAC,GAAG,CAAC,CAAC;QAC3C,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC;IAC9C,CAAC;IACD,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;QACrB,MAAM,IAAI,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAC;QACvC,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IACxC,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,+BAA+B,CAAC,WAAmB;IACjE,MAAM,OAAO,GAA6B,EAAE,CAAC;IAE7C,KAAK,MAAM,OAAO,IAAI,gBAAgB,EAAE,EAAE,CAAC;QACzC,IAAI,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC;YAAE,SAAS;QAEzC,MAAM,SAAS,GAAG,UAAU,CAAC,OAAO,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC;QACvD,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,EAAE,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC,CAAC;QAC/D,IAAI,CAAC,SAAS,IAAI,CAAC,QAAQ;YAAE,SAAS;QAEtC,qEAAqE;QACrE,qEAAqE;QACrE,iEAAiE;QACjE,4EAA4E;QAC5E,MAAM,MAAM,GAAG,wBAAwB,CAAC,SAAS,CAAC,CAAC;QACnD,MAAM,SAAS,GAAG,kBAAkB,CAAC,QAAQ,CAAC;aAC3C,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC;aACzC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;QACzD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,CAAC,MAAM,EAAE,CAAC;YAC9D,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,CAAC,MAAM,EAAE,CAAC;gBACvC,MAAM,CAAC,KAAK,CAAC,kBAAkB,OAAO,UAAU,MAAM,CAAC,MAAM,cAAc,SAAS,CAAC,MAAM,mCAAmC,CAAC,CAAC;YAClI,CAAC;YACD,SAAS;QACX,CAAC;QAED,MAAM,SAAS,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;QACzC,IAAI,CAAC,SAAS;YAAE,SAAS;QACzB,MAAM,IAAI,GAAG,gBAAgB,CAAC,SAAS,EAAE,CAAC,EAAE,WAAW,CAAC,CAAC;QAEzD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACvC,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAE,CAAC;YACxB,MAAM,IAAI,GAAG,SAAS,CAAC,CAAC,CAAE,CAAC;YAC3B,IAAI,CAAC,IAAI,CAAC,OAAO;gBAAE,SAAS,CAAC,kCAAkC;YAE/D,gEAAgE;YAChE,yEAAyE;YACzE,wEAAwE;YACxE,uEAAuE;YACvE,uEAAuE;YACvE,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACpC,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,KAAK,OAAO,CAAC,CAAC;YAC7D,wEAAwE;YACxE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;gBAAE,SAAS;YACnC,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,CAAE,CAAC;YAExB,MAAM,IAAI,GAAG,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;YAClD,IAAI,CAAC,IAAI;gBAAE,SAAS;YAEpB,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,gBAAgB,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;YACtE,OAAO,CAAC,IAAI,CAAC;gBACX,aAAa,EAAE,OAAO;gBACtB,YAAY,EAAE,IAAI,CAAC,MAAM;gBACzB,MAAM,EAAE,GAAG,CAAC,GAAG;gBACf,KAAK,EAAE,GAAG,CAAC,KAAK;gBAChB,SAAS;gBACT,GAAG,EAAE,GAAG,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,IAAI,EAAE;gBAC9B,SAAS;gBACT,QAAQ,EAAE,IAAI,CAAC,IAAI;gBACnB,QAAQ,EAAE,IAAI,CAAC,IAAI;aACpB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,kFAAkF;AAClF,MAAM,UAAU,yBAAyB,CAAC,OAAe,EAAE,MAAc,EAAE,WAAmB;IAC5F,MAAM,SAAS,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IACzC,IAAI,CAAC,SAAS;QAAE,OAAO,KAAK,CAAC;IAC7B,MAAM,IAAI,GAAG,gBAAgB,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;IAC5C,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,WAAW,CAAC;QAAE,OAAO,KAAK,CAAC;IACzD,iCAAiC;IACjC,OAAO,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC,KAAK,SAAS,CAAC;AACvD,CAAC"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
export interface LayoutPane {
|
|
2
|
+
/** Foreground command (argv0) zellij introspected for this pane, e.g. "claude". */
|
|
3
|
+
command: string;
|
|
4
|
+
/** Explicit pane name if set (zellij `name=`), else undefined. */
|
|
5
|
+
name?: string;
|
|
6
|
+
/** Absolute cwd of the pane (layout base cwd joined with the pane's relative cwd). */
|
|
7
|
+
cwd?: string;
|
|
8
|
+
/** Command args, when present in the dump. */
|
|
9
|
+
args: string[];
|
|
10
|
+
}
|
|
11
|
+
export interface ListedPane {
|
|
12
|
+
/** "terminal_<n>" — the id used to target zellij `action` commands. */
|
|
13
|
+
paneId: string;
|
|
14
|
+
isPlugin: boolean;
|
|
15
|
+
isFloating: boolean;
|
|
16
|
+
title?: string;
|
|
17
|
+
terminalCommand?: string | null;
|
|
18
|
+
}
|
|
19
|
+
export interface DiscoveredCli {
|
|
20
|
+
session: string;
|
|
21
|
+
paneId: string;
|
|
22
|
+
command: string;
|
|
23
|
+
cwd?: string;
|
|
24
|
+
args: string[];
|
|
25
|
+
title?: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Parse `zellij action dump-layout` output, returning only the panes that have
|
|
29
|
+
* a foreground `command=` (i.e. real terminal panes running something) in
|
|
30
|
+
* document order. Template sections (new_tab_template / swap_*_layout) are cut
|
|
31
|
+
* off first — their bare `pane` nodes have no command and would otherwise add
|
|
32
|
+
* noise. Plugin panes (tab-bar / status-bar / about) have no command= and are
|
|
33
|
+
* naturally excluded.
|
|
34
|
+
*/
|
|
35
|
+
export declare function parseDumpLayoutPanes(kdl: string): LayoutPane[];
|
|
36
|
+
export interface LeafPane {
|
|
37
|
+
/** Foreground command (argv0) if the pane is running one; undefined for an
|
|
38
|
+
* idle shell pane (zellij emits a bare `pane` with no command=). */
|
|
39
|
+
command?: string;
|
|
40
|
+
name?: string;
|
|
41
|
+
cwd?: string;
|
|
42
|
+
args: string[];
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Parse `zellij action dump-layout` into the ordered list of LEAF terminal
|
|
46
|
+
* panes — both command-bearing panes AND idle bare shell panes — skipping
|
|
47
|
+
* plugin panes (tab-bar/status-bar/about), container panes (splits), and the
|
|
48
|
+
* floating subtree. Preserving bare panes is what makes a positional join to
|
|
49
|
+
* `list-panes` correct: a bare shell pane that sorts before the CLI pane would
|
|
50
|
+
* otherwise shift every command pane onto the wrong pane id (the bug Codex
|
|
51
|
+
* found). Templates (new_tab_template / swap_*) are cut off first.
|
|
52
|
+
*
|
|
53
|
+
* zellij always pretty-prints dump-layout one node per line, so a brace-stack
|
|
54
|
+
* line walk is reliable here.
|
|
55
|
+
*/
|
|
56
|
+
export declare function parseDumpLayoutLeafPanes(kdl: string): LeafPane[];
|
|
57
|
+
/** Parse `zellij action list-panes --json` into a flat list (document order). */
|
|
58
|
+
export declare function parseListPanesJson(json: string): ListedPane[];
|
|
59
|
+
/**
|
|
60
|
+
* Join dump-layout command panes with list-panes terminal panes by document
|
|
61
|
+
* order: the i-th command pane ↔ the i-th non-plugin terminal pane (sorted by
|
|
62
|
+
* id). zellij assigns pane ids in creation order and walks the tree in a stable
|
|
63
|
+
* order, so this aligns for normal layouts. Returns one DiscoveredCli per
|
|
64
|
+
* command pane that could be bound to an id.
|
|
65
|
+
*/
|
|
66
|
+
export declare function joinPanes(session: string, layoutPanes: LayoutPane[], listed: ListedPane[]): DiscoveredCli[];
|
|
67
|
+
/** Names of live (non-exited) zellij sessions. */
|
|
68
|
+
export declare function listLiveSessions(): string[];
|
|
69
|
+
/** Discover CLIs running in one session. */
|
|
70
|
+
export declare function discoverSessionClis(session: string): DiscoveredCli[];
|
|
71
|
+
/** Discover CLIs across every live zellij session. */
|
|
72
|
+
export declare function discoverAllClis(): DiscoveredCli[];
|
|
73
|
+
//# sourceMappingURL=zellij-session-discovery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zellij-session-discovery.d.ts","sourceRoot":"","sources":["../../src/core/zellij-session-discovery.ts"],"names":[],"mappings":"AA4BA,MAAM,WAAW,UAAU;IACzB,mFAAmF;IACnF,OAAO,EAAE,MAAM,CAAC;IAChB,kEAAkE;IAClE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,sFAAsF;IACtF,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,8CAA8C;IAC9C,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,MAAM,WAAW,UAAU;IACzB,uEAAuE;IACvE,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAID;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,EAAE,CA6C9D;AAED,MAAM,WAAW,QAAQ;IACvB;yEACqE;IACrE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ,EAAE,CAuDhE;AAED,iFAAiF;AACjF,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,EAAE,CAW7D;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,aAAa,EAAE,CAmB3G;AAID,kDAAkD;AAClD,wBAAgB,gBAAgB,IAAI,MAAM,EAAE,CAS3C;AAUD,4CAA4C;AAC5C,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,EAAE,CAKpE;AAED,sDAAsD;AACtD,wBAAgB,eAAe,IAAI,aAAa,EAAE,CAEjD"}
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zellij session discovery for /adopt — find CLIs already running inside a
|
|
3
|
+
* user's zellij sessions and the pane needed to drive them.
|
|
4
|
+
*
|
|
5
|
+
* Why this exists (and why it's not just `list-panes`): zellij's
|
|
6
|
+
* `list-panes --json` exposes pane ids + geometry but NOT the running command,
|
|
7
|
+
* cwd, or pid, and its `terminal_command` is null for anything the user started
|
|
8
|
+
* interactively (typed `claude` into a shell — the common case). The data we
|
|
9
|
+
* need is instead surfaced by zellij's **session-resurrection** machinery: to be
|
|
10
|
+
* able to restore a session after a reboot, zellij continuously introspects each
|
|
11
|
+
* pane's *foreground process command + cwd* and exposes it via
|
|
12
|
+
* `zellij action dump-layout`. That's where we read "what CLI is in this pane".
|
|
13
|
+
*
|
|
14
|
+
* Discovery pipeline:
|
|
15
|
+
* 1. dump-layout → per-pane { command, args, cwd } (detection)
|
|
16
|
+
* 2. list-panes --json → per-pane { id: terminal_<n> } (drive target)
|
|
17
|
+
* 3. order/geometry join → bind command ↔ pane id
|
|
18
|
+
* 4. (caller) /proc descent under the pane shell → pid → ~/.claude/sessions/<pid>.json
|
|
19
|
+
*
|
|
20
|
+
* Parsers here are pure (string in, struct out) so they unit-test without a
|
|
21
|
+
* live zellij. The order-join (step 3) is robust for normal single/few-pane
|
|
22
|
+
* layouts; exotic multi-tab/floating arrangements may need the geometry/proc
|
|
23
|
+
* cross-check the caller layers on top.
|
|
24
|
+
*/
|
|
25
|
+
import { execFileSync } from 'node:child_process';
|
|
26
|
+
import { isAbsolute, join as pathJoin } from 'node:path';
|
|
27
|
+
import { zellijEnv } from '../setup/ensure-zellij.js';
|
|
28
|
+
const TEMPLATE_MARKERS = /\b(new_tab_template|swap_tiled_layout|swap_floating_layout)\b/;
|
|
29
|
+
/**
|
|
30
|
+
* Parse `zellij action dump-layout` output, returning only the panes that have
|
|
31
|
+
* a foreground `command=` (i.e. real terminal panes running something) in
|
|
32
|
+
* document order. Template sections (new_tab_template / swap_*_layout) are cut
|
|
33
|
+
* off first — their bare `pane` nodes have no command and would otherwise add
|
|
34
|
+
* noise. Plugin panes (tab-bar / status-bar / about) have no command= and are
|
|
35
|
+
* naturally excluded.
|
|
36
|
+
*/
|
|
37
|
+
export function parseDumpLayoutPanes(kdl) {
|
|
38
|
+
// Drop the template tail so we only see live tab content.
|
|
39
|
+
const tmplIdx = kdl.search(TEMPLATE_MARKERS);
|
|
40
|
+
const body = tmplIdx >= 0 ? kdl.slice(0, tmplIdx) : kdl;
|
|
41
|
+
const lines = body.split('\n');
|
|
42
|
+
const panes = [];
|
|
43
|
+
// Layout base cwd is a NODE: `cwd "..."` (space). Pane cwd is an ATTRIBUTE:
|
|
44
|
+
// `cwd="..."` (equals). The first node-form cwd is the layout base.
|
|
45
|
+
let layoutCwd;
|
|
46
|
+
const baseCwdMatch = body.match(/^\s*cwd\s+"([^"]*)"/m);
|
|
47
|
+
if (baseCwdMatch)
|
|
48
|
+
layoutCwd = baseCwdMatch[1];
|
|
49
|
+
let pending = null;
|
|
50
|
+
const flush = () => { if (pending) {
|
|
51
|
+
panes.push(pending);
|
|
52
|
+
pending = null;
|
|
53
|
+
} };
|
|
54
|
+
for (const line of lines) {
|
|
55
|
+
const trimmed = line.trim();
|
|
56
|
+
// A pane that runs a command (attributes can appear in any order).
|
|
57
|
+
if (/^pane\b/.test(trimmed) && /\bcommand=/.test(trimmed)) {
|
|
58
|
+
flush();
|
|
59
|
+
const command = attr(trimmed, 'command');
|
|
60
|
+
const name = attr(trimmed, 'name');
|
|
61
|
+
const cwdAttr = attr(trimmed, 'cwd');
|
|
62
|
+
pending = {
|
|
63
|
+
command: command ?? '',
|
|
64
|
+
name: name ?? undefined,
|
|
65
|
+
cwd: resolveCwd(layoutCwd, cwdAttr),
|
|
66
|
+
args: [],
|
|
67
|
+
};
|
|
68
|
+
// Single-line pane (closed on same line, no block) — flush immediately.
|
|
69
|
+
if (trimmed.includes('}') && !trimmed.endsWith('{'))
|
|
70
|
+
flush();
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
// args node inside the current pane block: `args "a" "b" …`
|
|
74
|
+
if (pending && /^args\b/.test(trimmed)) {
|
|
75
|
+
pending.args = [...trimmed.matchAll(/"((?:[^"\\]|\\.)*)"/g)].map(m => unescapeKdl(m[1]));
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
// Next pane / tab / closing — a new `pane` (without command) ends the block.
|
|
79
|
+
if (pending && /^pane\b/.test(trimmed))
|
|
80
|
+
flush();
|
|
81
|
+
}
|
|
82
|
+
flush();
|
|
83
|
+
return panes;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Parse `zellij action dump-layout` into the ordered list of LEAF terminal
|
|
87
|
+
* panes — both command-bearing panes AND idle bare shell panes — skipping
|
|
88
|
+
* plugin panes (tab-bar/status-bar/about), container panes (splits), and the
|
|
89
|
+
* floating subtree. Preserving bare panes is what makes a positional join to
|
|
90
|
+
* `list-panes` correct: a bare shell pane that sorts before the CLI pane would
|
|
91
|
+
* otherwise shift every command pane onto the wrong pane id (the bug Codex
|
|
92
|
+
* found). Templates (new_tab_template / swap_*) are cut off first.
|
|
93
|
+
*
|
|
94
|
+
* zellij always pretty-prints dump-layout one node per line, so a brace-stack
|
|
95
|
+
* line walk is reliable here.
|
|
96
|
+
*/
|
|
97
|
+
export function parseDumpLayoutLeafPanes(kdl) {
|
|
98
|
+
const tmplIdx = kdl.search(TEMPLATE_MARKERS);
|
|
99
|
+
const body = tmplIdx >= 0 ? kdl.slice(0, tmplIdx) : kdl;
|
|
100
|
+
const baseCwdMatch = body.match(/^\s*cwd\s+"([^"]*)"/m);
|
|
101
|
+
const layoutCwd = baseCwdMatch ? baseCwdMatch[1] : undefined;
|
|
102
|
+
const stack = [];
|
|
103
|
+
const leaves = [];
|
|
104
|
+
const inFloating = () => stack.some(f => f.isFloating);
|
|
105
|
+
const emit = (command, name, cwdAttr, args) => {
|
|
106
|
+
if (inFloating())
|
|
107
|
+
return;
|
|
108
|
+
leaves.push({ command, name, cwd: resolveCwd(layoutCwd, cwdAttr), args });
|
|
109
|
+
};
|
|
110
|
+
for (const raw of body.split('\n')) {
|
|
111
|
+
const line = raw.trim();
|
|
112
|
+
if (!line)
|
|
113
|
+
continue;
|
|
114
|
+
if (line === '}') {
|
|
115
|
+
const f = stack.pop();
|
|
116
|
+
// A pane frame that contained neither a plugin nor child panes is a leaf
|
|
117
|
+
// terminal pane (its block held only props like args/start_suspended).
|
|
118
|
+
if (f?.isPane && !f.hasPlugin && !f.hasChildPane && !inFloating()) {
|
|
119
|
+
leaves.push({ command: f.command, name: f.name, cwd: resolveCwd(layoutCwd, f.cwdAttr), args: f.args });
|
|
120
|
+
}
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
const opensBlock = line.endsWith('{');
|
|
124
|
+
if (line.startsWith('plugin')) {
|
|
125
|
+
if (stack.length && stack[stack.length - 1].isPane)
|
|
126
|
+
stack[stack.length - 1].hasPlugin = true;
|
|
127
|
+
if (opensBlock)
|
|
128
|
+
stack.push({ isPane: false, isFloating: false, args: [], hasPlugin: false, hasChildPane: false });
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
if (line.startsWith('pane')) {
|
|
132
|
+
if (stack.length && stack[stack.length - 1].isPane)
|
|
133
|
+
stack[stack.length - 1].hasChildPane = true;
|
|
134
|
+
const command = attr(line, 'command');
|
|
135
|
+
const name = attr(line, 'name');
|
|
136
|
+
const cwdAttr = attr(line, 'cwd');
|
|
137
|
+
if (opensBlock) {
|
|
138
|
+
stack.push({ isPane: true, isFloating: false, command, name, cwdAttr, args: [], hasPlugin: false, hasChildPane: false });
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
emit(command, name, cwdAttr, []); // bare leaf, no block
|
|
142
|
+
}
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
if (opensBlock) {
|
|
146
|
+
// tab / floating_panes / swap_* / other container
|
|
147
|
+
stack.push({ isPane: false, isFloating: line.startsWith('floating_panes'), args: [], hasPlugin: false, hasChildPane: false });
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
if (line.startsWith('args') && stack.length && stack[stack.length - 1].isPane) {
|
|
151
|
+
stack[stack.length - 1].args = [...line.matchAll(/"((?:[^"\\]|\\.)*)"/g)].map(m => unescapeKdl(m[1]));
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return leaves;
|
|
155
|
+
}
|
|
156
|
+
/** Parse `zellij action list-panes --json` into a flat list (document order). */
|
|
157
|
+
export function parseListPanesJson(json) {
|
|
158
|
+
let arr;
|
|
159
|
+
try {
|
|
160
|
+
arr = JSON.parse(json);
|
|
161
|
+
}
|
|
162
|
+
catch {
|
|
163
|
+
return [];
|
|
164
|
+
}
|
|
165
|
+
if (!Array.isArray(arr))
|
|
166
|
+
return [];
|
|
167
|
+
return arr.map((p) => ({
|
|
168
|
+
paneId: `terminal_${p.id}`,
|
|
169
|
+
isPlugin: !!p.is_plugin,
|
|
170
|
+
isFloating: !!p.is_floating,
|
|
171
|
+
title: typeof p.title === 'string' ? p.title : undefined,
|
|
172
|
+
terminalCommand: p.terminal_command ?? null,
|
|
173
|
+
}));
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Join dump-layout command panes with list-panes terminal panes by document
|
|
177
|
+
* order: the i-th command pane ↔ the i-th non-plugin terminal pane (sorted by
|
|
178
|
+
* id). zellij assigns pane ids in creation order and walks the tree in a stable
|
|
179
|
+
* order, so this aligns for normal layouts. Returns one DiscoveredCli per
|
|
180
|
+
* command pane that could be bound to an id.
|
|
181
|
+
*/
|
|
182
|
+
export function joinPanes(session, layoutPanes, listed) {
|
|
183
|
+
const terminals = listed
|
|
184
|
+
.filter(p => !p.isPlugin)
|
|
185
|
+
.sort((a, b) => paneNum(a.paneId) - paneNum(b.paneId));
|
|
186
|
+
const out = [];
|
|
187
|
+
for (let i = 0; i < layoutPanes.length; i++) {
|
|
188
|
+
const lp = layoutPanes[i];
|
|
189
|
+
const tp = terminals[i];
|
|
190
|
+
if (!tp)
|
|
191
|
+
break;
|
|
192
|
+
out.push({
|
|
193
|
+
session,
|
|
194
|
+
paneId: tp.paneId,
|
|
195
|
+
command: lp.command,
|
|
196
|
+
cwd: lp.cwd,
|
|
197
|
+
args: lp.args,
|
|
198
|
+
title: tp.title,
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
return out;
|
|
202
|
+
}
|
|
203
|
+
// ─── Runtime (shells out to zellij) ─────────────────────────────────────────
|
|
204
|
+
/** Names of live (non-exited) zellij sessions. */
|
|
205
|
+
export function listLiveSessions() {
|
|
206
|
+
try {
|
|
207
|
+
const out = execFileSync('zellij', ['list-sessions', '--no-formatting'], {
|
|
208
|
+
encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'], timeout: 3000, env: zellijEnv(),
|
|
209
|
+
});
|
|
210
|
+
return out.split('\n').map(l => l.trim())
|
|
211
|
+
.filter(l => l.length > 0 && !/EXITED/i.test(l))
|
|
212
|
+
.map(l => l.split(/\s+/)[0]).filter(Boolean);
|
|
213
|
+
}
|
|
214
|
+
catch {
|
|
215
|
+
return [];
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
function zellijAction(session, args) {
|
|
219
|
+
try {
|
|
220
|
+
return execFileSync('zellij', ['--session', session, 'action', ...args], {
|
|
221
|
+
encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'], timeout: 4000, env: zellijEnv(),
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
catch {
|
|
225
|
+
return null;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
/** Discover CLIs running in one session. */
|
|
229
|
+
export function discoverSessionClis(session) {
|
|
230
|
+
const layout = zellijAction(session, ['dump-layout']);
|
|
231
|
+
const panesJson = zellijAction(session, ['list-panes', '--json']);
|
|
232
|
+
if (!layout || !panesJson)
|
|
233
|
+
return [];
|
|
234
|
+
return joinPanes(session, parseDumpLayoutPanes(layout), parseListPanesJson(panesJson));
|
|
235
|
+
}
|
|
236
|
+
/** Discover CLIs across every live zellij session. */
|
|
237
|
+
export function discoverAllClis() {
|
|
238
|
+
return listLiveSessions().flatMap(discoverSessionClis);
|
|
239
|
+
}
|
|
240
|
+
// ─── helpers ────────────────────────────────────────────────────────────────
|
|
241
|
+
function attr(line, key) {
|
|
242
|
+
const m = line.match(new RegExp(`\\b${key}="((?:[^"\\\\]|\\\\.)*)"`));
|
|
243
|
+
return m ? unescapeKdl(m[1]) : undefined;
|
|
244
|
+
}
|
|
245
|
+
function resolveCwd(base, paneCwd) {
|
|
246
|
+
if (!paneCwd)
|
|
247
|
+
return base;
|
|
248
|
+
if (isAbsolute(paneCwd))
|
|
249
|
+
return paneCwd;
|
|
250
|
+
return base ? pathJoin(base, paneCwd) : paneCwd;
|
|
251
|
+
}
|
|
252
|
+
function paneNum(paneId) {
|
|
253
|
+
const m = paneId.match(/(\d+)$/);
|
|
254
|
+
return m ? Number(m[1]) : 0;
|
|
255
|
+
}
|
|
256
|
+
function unescapeKdl(s) {
|
|
257
|
+
return s.replace(/\\(.)/g, '$1');
|
|
258
|
+
}
|
|
259
|
+
//# sourceMappingURL=zellij-session-discovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zellij-session-discovery.js","sourceRoot":"","sources":["../../src/core/zellij-session-discovery.ts"],"names":[],"mappings":"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"}
|
package/dist/daemon.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"AA0BA,YAAY,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAsErD,OAAO,EAAE,oBAAoB,EAA6B,MAAM,uBAAuB,CAAC;AACxF,OAAO,KAAK,EAAE,sBAAsB,EAAiB,MAAM,wBAAwB,CAAC;AAsQpF,wBAAsB,8BAA8B,CAClD,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,OAAO,CAAC,CA4ClB;AAED,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,GAAG,EAAE,MAAM,GACV,MAAM,GAAG,SAAS,CAIpB;AAED,wBAAgB,+BAA+B,CAC7C,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,GAAG,EAAE,MAAM,GACV,MAAM,GAAG,SAAS,CAGpB;AAyJD,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,sBAAsB,GAAG,oBAAoB,CA0C5G;AAkpED,wBAAsB,WAAW,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"AA0BA,YAAY,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAsErD,OAAO,EAAE,oBAAoB,EAA6B,MAAM,uBAAuB,CAAC;AACxF,OAAO,KAAK,EAAE,sBAAsB,EAAiB,MAAM,wBAAwB,CAAC;AAsQpF,wBAAsB,8BAA8B,CAClD,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,OAAO,CAAC,CA4ClB;AAED,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,GAAG,EAAE,MAAM,GACV,MAAM,GAAG,SAAS,CAIpB;AAED,wBAAgB,+BAA+B,CAC7C,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,GAAG,EAAE,MAAM,GACV,MAAM,GAAG,SAAS,CAGpB;AAyJD,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,sBAAsB,GAAG,oBAAoB,CA0C5G;AAkpED,wBAAsB,WAAW,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA6TlE"}
|
package/dist/daemon.js
CHANGED
|
@@ -2662,9 +2662,13 @@ export async function startDaemon(botIndex) {
|
|
|
2662
2662
|
const backendType = ds.larkAppId
|
|
2663
2663
|
? (getBot(ds.larkAppId).config.backendType ?? config.daemon.backendType)
|
|
2664
2664
|
: config.daemon.backendType;
|
|
2665
|
-
if (backendType === 'tmux') {
|
|
2666
|
-
//
|
|
2667
|
-
//
|
|
2665
|
+
if (backendType === 'tmux' || backendType === 'zellij') {
|
|
2666
|
+
// Persistent backends (tmux / zellij): just kill the worker process —
|
|
2667
|
+
// the multiplexer session survives for re-attach. The worker's SIGTERM
|
|
2668
|
+
// handler calls backend.kill(), which only DETACHES. Going through
|
|
2669
|
+
// killWorker() instead would send {type:'close'} → destroySession() →
|
|
2670
|
+
// `zellij delete-session -f`, permanently erasing the session and
|
|
2671
|
+
// breaking daemon-restart reattach (the blocker Codex flagged).
|
|
2668
2672
|
try {
|
|
2669
2673
|
w.kill('SIGTERM');
|
|
2670
2674
|
}
|