@zeph-to/cli 1.15.0 → 1.15.2
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/dist/agent-rules.default.d.ts.map +1 -1
- package/dist/agent-rules.default.js +30 -1
- package/dist/listener.d.ts +1 -0
- package/dist/listener.d.ts.map +1 -1
- package/dist/listener.js +8 -6
- package/dist/remote-agents.d.ts +21 -3
- package/dist/remote-agents.d.ts.map +1 -1
- package/dist/remote-agents.js +81 -2
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-rules.default.d.ts","sourceRoot":"","sources":["../src/agent-rules.default.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,EAAkB,KAAK,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE1E,eAAO,MAAM,gBAAgB,EAAE,
|
|
1
|
+
{"version":3,"file":"agent-rules.default.d.ts","sourceRoot":"","sources":["../src/agent-rules.default.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,EAAkB,KAAK,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE1E,eAAO,MAAM,gBAAgB,EAAE,iBA2F9B,CAAC"}
|
|
@@ -26,7 +26,7 @@ exports.DEFAULT_MANIFEST = void 0;
|
|
|
26
26
|
const agent_state_js_1 = require("./agent-state.js");
|
|
27
27
|
exports.DEFAULT_MANIFEST = {
|
|
28
28
|
engineVersion: agent_state_js_1.ENGINE_VERSION,
|
|
29
|
-
version: '2026.07.04.
|
|
29
|
+
version: '2026.07.04.3',
|
|
30
30
|
agents: {
|
|
31
31
|
claude: [
|
|
32
32
|
{
|
|
@@ -62,6 +62,35 @@ exports.DEFAULT_MANIFEST = {
|
|
|
62
62
|
priority: 800,
|
|
63
63
|
contains: ['esc to interrupt'],
|
|
64
64
|
},
|
|
65
|
+
{
|
|
66
|
+
// Newer CC skins drop the "esc to interrupt" hint; the
|
|
67
|
+
// live token counter on the spinner line
|
|
68
|
+
// ("✶ Churning… (1m 2s · ↓ 1.2k tokens)") only renders
|
|
69
|
+
// while the agent is actually running.
|
|
70
|
+
id: 'claude-working-token-counter',
|
|
71
|
+
state: 'working',
|
|
72
|
+
priority: 790,
|
|
73
|
+
regex: ['[↓↑]\\s?[\\d.,]+k? tokens'],
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
// Elapsed-time spinner suffix ("(12s · ..." / "(1m 2s ·")
|
|
77
|
+
// — second fallback for skins that hide the token counter
|
|
78
|
+
// early in a turn.
|
|
79
|
+
id: 'claude-working-elapsed-spinner',
|
|
80
|
+
state: 'working',
|
|
81
|
+
priority: 780,
|
|
82
|
+
regex: ['…\\s*\\((?:\\d+m )?\\d+s ·'],
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
// Compact pass ("✱ Compacting conversation… (51s)")
|
|
86
|
+
// renders neither the interrupt hint nor a token
|
|
87
|
+
// counter, but the session is busy and can't take
|
|
88
|
+
// input — without this it reads as idle.
|
|
89
|
+
id: 'claude-working-compacting',
|
|
90
|
+
state: 'working',
|
|
91
|
+
priority: 770,
|
|
92
|
+
contains: ['compacting conversation'],
|
|
93
|
+
},
|
|
65
94
|
{
|
|
66
95
|
// Idle prompt: `❯` at line start in the tail, with no
|
|
67
96
|
// dialog affordances around it.
|
package/dist/listener.d.ts
CHANGED
package/dist/listener.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"listener.d.ts","sourceRoot":"","sources":["../src/listener.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AASH,OAAO,EAA2B,KAAK,SAAS,EAAE,KAAK,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AACzG,OAAO,EAAiD,KAAK,UAAU,EAA4C,MAAM,kBAAkB,CAAC;AA4B5I,UAAU,YAAY;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,SAAS,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB;AAYD,eAAO,MAAM,kBAAkB,EAAE,WAAW,CAAC,MAAM,CAA+B,CAAC;AAenF,eAAO,MAAM,cAAc,GAAI,SAAS,MAAM,EAAE,MAAK,MAAmB,KAAG,OAgB1E,CAAC;AAEF,2EAA2E;AAC3E,eAAO,MAAM,kBAAkB,GAAI,SAAS,MAAM,KAAG,MAAM,GAAG,IAO7D,CAAC;AAiDF;;;;;;;GAOG;AACH,eAAO,MAAM,yBAAyB,QAAO,IAG5C,CAAC;AA8NF;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,GAAI,MAAM,MAAM,KAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAAG,IAK3F,CAAC;AAEF,UAAU,QAAQ;IACd,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"listener.d.ts","sourceRoot":"","sources":["../src/listener.ts"],"names":[],"mappings":"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"}
|
package/dist/listener.js
CHANGED
|
@@ -412,20 +412,22 @@ exports.parseSessionName = parseSessionName;
|
|
|
412
412
|
const FIELD_SEP = '␟';
|
|
413
413
|
const readPaneInfo = (session) => {
|
|
414
414
|
const r = (0, child_process_1.spawnSync)('tmux', tmuxArgs(['display-message', '-p', '-t', session,
|
|
415
|
-
`#{pane_current_command}${FIELD_SEP}#{pane_start_command}${FIELD_SEP}#{pane_current_path}`]), {
|
|
415
|
+
`#{pane_current_command}${FIELD_SEP}#{pane_start_command}${FIELD_SEP}#{pane_current_path}${FIELD_SEP}#{pane_pid}`]), {
|
|
416
416
|
encoding: 'utf-8',
|
|
417
417
|
stdio: ['ignore', 'pipe', 'ignore'],
|
|
418
418
|
});
|
|
419
419
|
if (r.status !== 0)
|
|
420
|
-
return { currentCommand: null, startCommand: null, currentPath: null };
|
|
420
|
+
return { currentCommand: null, startCommand: null, currentPath: null, panePid: null };
|
|
421
421
|
const parts = (r.stdout ?? '').trim().split(FIELD_SEP);
|
|
422
|
-
if (parts.length !==
|
|
423
|
-
return { currentCommand: null, startCommand: null, currentPath: null };
|
|
424
|
-
const [current, start, path] = parts;
|
|
422
|
+
if (parts.length !== 4)
|
|
423
|
+
return { currentCommand: null, startCommand: null, currentPath: null, panePid: null };
|
|
424
|
+
const [current, start, path, pid] = parts;
|
|
425
|
+
const parsedPid = Number(pid);
|
|
425
426
|
return {
|
|
426
427
|
currentCommand: current || null,
|
|
427
428
|
startCommand: start || null,
|
|
428
429
|
currentPath: path || null,
|
|
430
|
+
panePid: Number.isInteger(parsedPid) && parsedPid > 0 ? parsedPid : null,
|
|
429
431
|
};
|
|
430
432
|
};
|
|
431
433
|
/**
|
|
@@ -681,7 +683,7 @@ const collectSessionsVerbose = () => {
|
|
|
681
683
|
continue;
|
|
682
684
|
}
|
|
683
685
|
const agentSessionId = info.currentPath
|
|
684
|
-
? (agent.resolveSessionId?.(info.currentPath) ?? null)
|
|
686
|
+
? (agent.resolveSessionId?.(info.currentPath, info.panePid ?? undefined) ?? null)
|
|
685
687
|
: null;
|
|
686
688
|
sessions.push({
|
|
687
689
|
name,
|
package/dist/remote-agents.d.ts
CHANGED
|
@@ -10,11 +10,12 @@ export interface RemoteAgent {
|
|
|
10
10
|
/** Extra pane_command basenames accepted as this agent (beyond binary). */
|
|
11
11
|
paneMatchAliases?: readonly string[];
|
|
12
12
|
/**
|
|
13
|
-
* Resolve the agent's own session id from the pane's cwd
|
|
13
|
+
* Resolve the agent's own session id from the pane's cwd (+ pane pid
|
|
14
|
+
* when the caller knows it — enables exact process-tree matching).
|
|
14
15
|
* EXTENSION POINT: omitted for codex/gemini until their session-file
|
|
15
16
|
* formats are confirmed — the listener then reports agentSessionId: null.
|
|
16
17
|
*/
|
|
17
|
-
resolveSessionId?: (paneCwd: string) => string | null;
|
|
18
|
+
resolveSessionId?: (paneCwd: string, panePid?: number) => string | null;
|
|
18
19
|
}
|
|
19
20
|
/**
|
|
20
21
|
* Locate the most recent Claude Code session UUID for the working
|
|
@@ -25,12 +26,29 @@ export interface RemoteAgent {
|
|
|
25
26
|
* claudeSessionCache.
|
|
26
27
|
*/
|
|
27
28
|
export declare const detectClaudeSessionId: (cwd: string) => string | null;
|
|
29
|
+
interface PidSessionRecord {
|
|
30
|
+
pid: number;
|
|
31
|
+
sessionId: string;
|
|
32
|
+
cwd: string;
|
|
33
|
+
}
|
|
34
|
+
/** Test seam for the pid-based resolver. */
|
|
35
|
+
export interface PidResolveDeps {
|
|
36
|
+
records?: PidSessionRecord[];
|
|
37
|
+
descendants?: Set<number>;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Exact resolution: the session record whose pid lives in the pane's
|
|
41
|
+
* process tree AND whose cwd matches (guards against OS pid reuse
|
|
42
|
+
* leaving a stale record pointing elsewhere). Null → caller falls back
|
|
43
|
+
* to the mtime heuristic.
|
|
44
|
+
*/
|
|
45
|
+
export declare const detectClaudeSessionIdByPid: (panePid: number, paneCwd: string | null, deps?: PidResolveDeps) => string | null;
|
|
28
46
|
declare const REMOTE_AGENT_TABLE: readonly [{
|
|
29
47
|
readonly kind: "claude";
|
|
30
48
|
readonly displayName: "Claude Code";
|
|
31
49
|
readonly binary: "claude";
|
|
32
50
|
readonly subcommands: readonly ["cc", "claude"];
|
|
33
|
-
readonly resolveSessionId: (
|
|
51
|
+
readonly resolveSessionId: (paneCwd: string, panePid: number | undefined) => string | null;
|
|
34
52
|
}, {
|
|
35
53
|
readonly kind: "codex";
|
|
36
54
|
readonly displayName: "Codex CLI";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remote-agents.d.ts","sourceRoot":"","sources":["../src/remote-agents.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"remote-agents.d.ts","sourceRoot":"","sources":["../src/remote-agents.ts"],"names":[],"mappings":"AAkBA,MAAM,WAAW,WAAW;IACxB,qEAAqE;IACrE,IAAI,EAAE,MAAM,CAAC;IACb,kCAAkC;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,2EAA2E;IAC3E,MAAM,EAAE,MAAM,CAAC;IACf,0DAA0D;IAC1D,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,2EAA2E;IAC3E,gBAAgB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;CAC3E;AAyCD;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,GAAI,KAAK,MAAM,KAAG,MAAM,GAAG,IAiB5D,CAAC;AAaF,UAAU,gBAAgB;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;CACf;AAkDD,4CAA4C;AAC5C,MAAM,WAAW,cAAc;IAC3B,OAAO,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC7B,WAAW,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CAC7B;AAED;;;;;GAKG;AACH,eAAO,MAAM,0BAA0B,GACnC,SAAS,MAAM,EACf,SAAS,MAAM,GAAG,IAAI,EACtB,OAAM,cAAmB,KAC1B,MAAM,GAAG,IAOX,CAAC;AAIF,QAAA,MAAM,kBAAkB;;;;;;;;;;;;;;;;EAwBmB,CAAC;AAE5C,uFAAuF;AACvF,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC;AAEpE,8FAA8F;AAC9F,MAAM,MAAM,qBAAqB,GAAG,WAAW,GAAG;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC;AAEtE,eAAO,MAAM,aAAa,EAAE,SAAS,qBAAqB,EAAuB,CAAC;AAElF,eAAO,MAAM,qBAAqB,GAAI,KAAK,MAAM,KAAG,qBAAqB,GAAG,SAClB,CAAC;AAE3D,eAAO,MAAM,uBAAuB,GAAI,MAAM,MAAM,KAAG,qBAAqB,GAAG,SAG9E,CAAC"}
|
package/dist/remote-agents.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.matchAgentByPaneCommand = exports.findAgentBySubcommand = exports.REMOTE_AGENTS = exports.detectClaudeSessionId = void 0;
|
|
3
|
+
exports.matchAgentByPaneCommand = exports.findAgentBySubcommand = exports.REMOTE_AGENTS = exports.detectClaudeSessionIdByPid = exports.detectClaudeSessionId = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Remote-control agent registry — the single table behind `zeph cc` /
|
|
6
6
|
* `zeph codex` / `zeph gemini`, the listener's pane matching, and the
|
|
@@ -17,6 +17,7 @@ exports.matchAgentByPaneCommand = exports.findAgentBySubcommand = exports.REMOTE
|
|
|
17
17
|
const fs_1 = require("fs");
|
|
18
18
|
const os_1 = require("os");
|
|
19
19
|
const path_1 = require("path");
|
|
20
|
+
const child_process_1 = require("child_process");
|
|
20
21
|
// ── Claude Code session resolver ─────────────────────────────────
|
|
21
22
|
const CLAUDE_PROJECTS_DIR = (0, path_1.join)((0, os_1.homedir)(), '.claude', 'projects');
|
|
22
23
|
/**
|
|
@@ -82,6 +83,81 @@ const detectClaudeSessionId = (cwd) => {
|
|
|
82
83
|
return sessionId;
|
|
83
84
|
};
|
|
84
85
|
exports.detectClaudeSessionId = detectClaudeSessionId;
|
|
86
|
+
// ── Claude Code pid → session resolver ───────────────────────────
|
|
87
|
+
//
|
|
88
|
+
// Claude Code maintains ~/.claude/sessions/<pid>.json with the exact
|
|
89
|
+
// {pid, sessionId, cwd} of every live session. Matching the tmux pane's
|
|
90
|
+
// process tree against these records identifies THE session running in
|
|
91
|
+
// that pane — immune to the identity theft the mtime heuristic suffers
|
|
92
|
+
// when a second `claude` opens in the same cwd (its transcript becomes
|
|
93
|
+
// the newest file and steals the tmux session's id).
|
|
94
|
+
const CLAUDE_SESSIONS_DIR = (0, path_1.join)((0, os_1.homedir)(), '.claude', 'sessions');
|
|
95
|
+
const readPidSessionRecords = () => {
|
|
96
|
+
try {
|
|
97
|
+
const out = [];
|
|
98
|
+
for (const entry of (0, fs_1.readdirSync)(CLAUDE_SESSIONS_DIR)) {
|
|
99
|
+
if (!/^\d+\.json$/.test(entry))
|
|
100
|
+
continue;
|
|
101
|
+
try {
|
|
102
|
+
const raw = JSON.parse((0, fs_1.readFileSync)((0, path_1.join)(CLAUDE_SESSIONS_DIR, entry), 'utf-8'));
|
|
103
|
+
if (typeof raw.pid === 'number' && typeof raw.sessionId === 'string' && typeof raw.cwd === 'string') {
|
|
104
|
+
out.push({ pid: raw.pid, sessionId: raw.sessionId, cwd: raw.cwd });
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
catch { /* partial write / corrupt — skip */ }
|
|
108
|
+
}
|
|
109
|
+
return out;
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
return []; // dir absent (older CC) — caller falls back to mtime
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
/** pid set of `rootPid` + all descendants, from one `ps` snapshot. */
|
|
116
|
+
const collectDescendantPids = (rootPid, psOutput) => {
|
|
117
|
+
let table = psOutput;
|
|
118
|
+
if (table === undefined) {
|
|
119
|
+
const r = (0, child_process_1.spawnSync)('ps', ['-axo', 'pid=,ppid='], { encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'] });
|
|
120
|
+
if (r.status !== 0)
|
|
121
|
+
return new Set([rootPid]);
|
|
122
|
+
table = r.stdout ?? '';
|
|
123
|
+
}
|
|
124
|
+
const children = new Map();
|
|
125
|
+
for (const line of table.split('\n')) {
|
|
126
|
+
const m = line.trim().match(/^(\d+)\s+(\d+)$/);
|
|
127
|
+
if (!m)
|
|
128
|
+
continue;
|
|
129
|
+
const [pid, ppid] = [Number(m[1]), Number(m[2])];
|
|
130
|
+
const list = children.get(ppid) ?? [];
|
|
131
|
+
list.push(pid);
|
|
132
|
+
children.set(ppid, list);
|
|
133
|
+
}
|
|
134
|
+
const found = new Set([rootPid]);
|
|
135
|
+
const queue = [rootPid];
|
|
136
|
+
while (queue.length > 0) {
|
|
137
|
+
for (const child of children.get(queue.shift()) ?? []) {
|
|
138
|
+
if (!found.has(child)) {
|
|
139
|
+
found.add(child);
|
|
140
|
+
queue.push(child);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return found;
|
|
145
|
+
};
|
|
146
|
+
/**
|
|
147
|
+
* Exact resolution: the session record whose pid lives in the pane's
|
|
148
|
+
* process tree AND whose cwd matches (guards against OS pid reuse
|
|
149
|
+
* leaving a stale record pointing elsewhere). Null → caller falls back
|
|
150
|
+
* to the mtime heuristic.
|
|
151
|
+
*/
|
|
152
|
+
const detectClaudeSessionIdByPid = (panePid, paneCwd, deps = {}) => {
|
|
153
|
+
const records = deps.records ?? readPidSessionRecords();
|
|
154
|
+
if (records.length === 0)
|
|
155
|
+
return null;
|
|
156
|
+
const descendants = deps.descendants ?? collectDescendantPids(panePid);
|
|
157
|
+
const match = records.find((r) => descendants.has(r.pid) && (paneCwd === null || r.cwd === paneCwd));
|
|
158
|
+
return match?.sessionId ?? null;
|
|
159
|
+
};
|
|
160
|
+
exports.detectClaudeSessionIdByPid = detectClaudeSessionIdByPid;
|
|
85
161
|
// ── The registry ─────────────────────────────────────────────────
|
|
86
162
|
const REMOTE_AGENT_TABLE = [
|
|
87
163
|
{
|
|
@@ -89,7 +165,10 @@ const REMOTE_AGENT_TABLE = [
|
|
|
89
165
|
displayName: 'Claude Code',
|
|
90
166
|
binary: 'claude',
|
|
91
167
|
subcommands: ['cc', 'claude'],
|
|
92
|
-
|
|
168
|
+
// Exact pid-tree match first; mtime heuristic only as fallback
|
|
169
|
+
// (older CC without ~/.claude/sessions, or ps failure).
|
|
170
|
+
resolveSessionId: (paneCwd, panePid) => (panePid !== undefined ? (0, exports.detectClaudeSessionIdByPid)(panePid, paneCwd) : null)
|
|
171
|
+
?? (0, exports.detectClaudeSessionId)(paneCwd),
|
|
93
172
|
},
|
|
94
173
|
{
|
|
95
174
|
kind: 'codex',
|