@zeph-to/cli 2.18.0 → 2.19.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.md CHANGED
@@ -146,6 +146,14 @@ an answerable `zeph_ask`).
146
146
  | Pi | `before_agent_start` → `zeph remote-hook pi` (via extension) | `zeph setup` |
147
147
  | Cursor CLI | — none yet | — |
148
148
 
149
+ **Subagents (view-only).** A pi subagent spawned into an extra pane of the
150
+ same tmux window shows up on your phone as a child of its parent card, named
151
+ `<session>.<pane>` — its terminal mirror streams live, but input, keys, exit,
152
+ resume and forget are all refused: you watch from the phone and answer at the
153
+ terminal, where the parent owns the conversation. The pane is labelled from
154
+ `@zeph_pane_label` (the pi extension sets it from `PI_SUBAGENT_NAME`), and a
155
+ prompt push from a subagent names it and opens its stream directly.
156
+
149
157
  Detection is exact-match: a terminal keystroke racing a phone message
150
158
  can never false-flag. Muted projects are never flagged.
151
159
 
@@ -29,6 +29,11 @@ interface AgentSession {
29
29
  name: string;
30
30
  attached: boolean;
31
31
  agentKind: AgentKind;
32
+ /** Set when this session is a SUBAGENT — an extra pane of the parent
33
+ * session `parentName` (`zeph-zeph.48` belongs to `zeph-zeph`). Subagent
34
+ * sessions are view-only: input, keys, exit, resume and forget are
35
+ * refused, and the server never pushes agent.state transitions for them. */
36
+ parentName?: string;
32
37
  agentSessionId?: string | null;
33
38
  project: string;
34
39
  label?: string | null;
@@ -148,14 +153,27 @@ interface PaneInfo {
148
153
  currentPath: string | null;
149
154
  panePid: number | null;
150
155
  }
156
+ /**
157
+ * A subagent session name: `<session>.<pane id digits>` (`zeph-zeph.48`).
158
+ * tmux forbids `.` in session names, so the shape cannot collide; `#` would
159
+ * break the server's stream-sub keys and `:` is the web key separator.
160
+ */
161
+ export declare const isSubagentSessionName: (name: string) => boolean;
151
162
  /** Store the latest sweep's name → pane-id map (see `CollectResult.targets`). */
152
163
  export declare const recordTargets: (targets: Record<string, string> | null | undefined) => void;
153
164
  /**
154
165
  * The tmux target for a wire session name: its pinned pane id when the last
155
166
  * sweep saw the session, else the name itself (a session younger than one
156
167
  * sweep, or tmux unreachable at startup — today's resolution, active pane).
157
- */
158
- export declare const tmuxTargetFor: (name: string) => string;
168
+ *
169
+ * A SUBAGENT name is the one exception: it resolves ONLY through the map, and
170
+ * an unknown one is null — because tmux parses `zeph-zeph.48` as session
171
+ * `zeph-zeph`, pane INDEX 48, and silently falls back to the active pane when
172
+ * that index is missing (measured: `display -t zeph-zeph.99` → main pane,
173
+ * exit 0). Every caller treats null as "gone": no spawn, refusal, or capture
174
+ * failure — never a write to whichever pane happens to be focused.
175
+ */
176
+ export declare const tmuxTargetFor: (name: string) => string | null;
159
177
  /**
160
178
  * Identify the agent from the tmux pane. Prefer `pane_start_command`
161
179
  * because the foreground process is usually `node`/`python3` (the
@@ -1 +1 @@
1
- {"version":3,"file":"listener.d.ts","sourceRoot":"","sources":["../src/listener.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AA6BH,OAAO,EAA0C,KAAK,SAAS,EAAE,KAAK,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAUxH,OAAO,EAAiD,KAAK,UAAU,EAA4C,MAAM,kBAAkB,CAAC;AAG5I,OAAO,EAA4E,KAAK,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAGvI,OAAO,EAA6C,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAoCtG,eAAO,MAAM,2BAA2B,QAAS,CAAC;AAElD,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;;;;;;;;;;;;OAYG;IACH,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,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;AAED;;;;;;GAMG;AACH;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAE1C,MAAM,WAAW,oBAAoB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACtB;AAED,eAAO,MAAM,qBAAqB,GAC9B,MAAM,SAAS,YAAY,EAAE,EAC7B,MAAK,MAAmB,KACzB,oBAAoB,EAYtB,CAAC;AAEF,eAAO,MAAM,wBAAwB,GAAI,OAAO,oBAAoB,EAAE,KAAG,MACP,CAAC;AAEnE,eAAO,MAAM,mBAAmB,GAAI,UAAU,YAAY,EAAE,KAAG,MAS7C,CAAC;AAEnB;6BAC6B;AAC7B,eAAO,MAAM,iBAAiB,GAC1B,aAAa,MAAM,EACnB,qBAAqB,MAAM,GAAG,IAAI,EAClC,cAAc,MAAM,EACpB,OAAO,MAAM,KACd,OAEoD,CAAC;AAqBxD,eAAO,MAAM,kBAAkB,EAAE,WAAW,CAAC,MAAM,CAA+B,CAAC;AAenF,eAAO,MAAM,cAAc,GACvB,SAAS,MAAM,EACf,MAAK,MAAmB,EACxB,OAAM,MAAU,KACjB,OAgBF,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB,GAAI,SAAS,MAAM,KAAG,MAAM,GAAG,IAU7D,CAAC;AAgGF;;;;;GAKG;AACH,eAAO,MAAM,WAAW,GAAI,MAAM,MAAM,EAAE,KAAG,MAAM,EAAE,GAAG,IAQvD,CAAC;AA0CF;;;;;;;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;IAC3B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAsBD,iFAAiF;AACjF,eAAO,MAAM,aAAa,GAAI,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,GAAG,SAAS,KAAG,IAElF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,aAAa,GAAI,MAAM,MAAM,KAAG,MAA4C,CAAC;AAwC1F;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB,GAAI,MAAM,QAAQ,KAAG,qBAAqB,GAAG,IAGhE,CAAC;AA0BZ,iBAAiB;AACjB,eAAO,MAAM,kBAAkB,QAAO,IAErC,CAAC;AAWF;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB,GAC3B,MAAM,MAAM,EACZ,WAAW,SAAS,EACpB,UAAU,MAAM,GAAG,IAAI,EACvB,MAAK,MAAmB,KACzB,IAAI,CAAC,YAAY,EAAE,OAAO,GAAG,gBAAgB,GAAG,aAAa,CAmB/D,CAAC;AAWF,MAAM,WAAW,YAAY;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACnB;AASD,8EAA8E;AAC9E,eAAO,MAAM,iBAAiB,GAAI,KAAK,OAAO,KAAG,IAWhD,CAAC;AAEF,iBAAiB;AACjB,eAAO,MAAM,mBAAmB,QAAO,IAGtC,CAAC;AAEF,MAAM,WAAW,QAAQ;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,eAAO,MAAM,gBAAgB,GACzB,WAAW,WAAW,CAAC,MAAM,CAAC,EAC9B,UAAS,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,GAAG,IAAsB,KAC9D,QAAQ,EAgBV,CAAC;AAWF,MAAM,WAAW,aAAa;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC3B,OAAO,EAAE,uBAAuB,CAAC;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB,GAAI,KAAK,aAAa,KAAG,cAAc,GAAG,IAmBzE,CAAC;AAgBF;;kDAEkD;AAClD,eAAO,MAAM,mBAAmB,QAAY,CAAC;AAK7C,MAAM,WAAW,gBAAgB;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;4EACwE;IACxE,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,eAAgB,SAAQ,gBAAgB;IACrD;wEACoE;IACpE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;sCACkC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,4DAA4D;IAC5D,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACnB;AAsGD;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,GAC/B,KAAK,gBAAgB,EACrB,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,KAC9C,OA2CF,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,GAC9B,KAAK,eAAe,EACpB,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,KAC9C,OA+CF,CAAC;AAWF,MAAM,WAAW,oBAAoB;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,mBAAmB;IAChC,OAAO,EAAE,6BAA6B,CAAC;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,IAAI,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,0BAA0B,GACnC,KAAK,oBAAoB,EACzB,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,KAC9C,OAoDF,CAAC;AAEF,MAAM,WAAW,kBAAkB;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAC9B,OAAO,EAAE,2BAA2B,CAAC;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,IAAI,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;CACd;AA0BD,8DAA8D;AAC9D,eAAO,MAAM,oBAAoB,OAAQ,CAAC;AAI1C;;;;;;;;GAQG;AACH,eAAO,MAAM,wBAAwB,GACjC,KAAK,kBAAkB,EACvB,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,KAC9C,OA0DF,CAAC;AAEF,MAAM,WAAW,oBAAoB;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,mBAAmB;IAChC,OAAO,EAAE,6BAA6B,CAAC;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,IAAI,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,0BAA0B,GACnC,KAAK,oBAAoB,EACzB,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,KAC9C,OAqCF,CAAC;AAiBF;+EAC+E;AAC/E,eAAO,MAAM,wBAAwB,MAAM,CAAC;AAG5C,MAAM,WAAW,oBAAoB;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;;;;;OAUG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,qBAAqB;IAClC,OAAO,EAAE,+BAA+B,CAAC;IACzC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;sCACkC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;0EACsE;IACtE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uDAAuD;IACvD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;oEACgE;IAChE,SAAS,CAAC,EAAE,yBAAyB,CAAC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACtB;AA0CD;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,0BAA0B,GACnC,KAAK,oBAAoB,EACzB,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,KAC9C,OA8DF,CAAC;AAsEF,MAAM,WAAW,YAAY;IACzB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,MAAM,EAAE,MAAM,CAAC;IACf;;;oDAGgD;IAChD,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,iBAAiB,GAAI,KAAK,MAAM,KAAG,YAAY,GAAG,IAY9D,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,GACtB,SAAS,MAAM,EACf,QAAQ;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,KACjD;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,IAKlC,CAAC;AASF;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc,GAAI,SAAS,MAAM,EAAE,YAAY,MAAM,KAAG,MAClB,CAAC;AAUpD;;;;;;;;GAQG;AACH,eAAO,MAAM,uBAAuB,GAChC,aAAa,MAAM,EACnB,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,EAC7C,SAAQ,MAAM,EAA8B,KAC7C,IAuBF,CAAC;AAcF,MAAM,WAAW,aAAa;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6EAA6E;IAC7E,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;OAIG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;CACnB;AAQD,eAAO,MAAM,oBAAoB,MAAM,CAAC;AACxC,eAAO,MAAM,kBAAkB,MAAM,CAAC;AAKtC,eAAO,MAAM,iBAAiB,MAAM,CAAC;AACrC,eAAO,MAAM,eAAe,OAAQ,CAAC;AAOrC,eAAO,MAAM,kBAAkB,IAAI,CAAC;AAEpC;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,GAAI,aAAa,MAAM,GAAG,IAAI,EAAE,KAAK,MAAM,KAAG,MACgC,CAAC;AAEzG,0DAA0D;AAC1D,MAAM,WAAW,WAAW;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH;;gEAEgE;AAChE,eAAO,MAAM,cAAc,GAAI,QAAQ,WAAW,EAAE,KAAK,MAAM,KAAG,OAGxB,CAAC;AAE3C,eAAO,MAAM,cAAc,GAAI,QAAQ,WAAW,EAAE,KAAK,MAAM,KAAG,OAYjE,CAAC;AAqBF,eAAO,MAAM,eAAe,QAAS,CAAC;AAStC,eAAO,MAAM,qBAAqB,OAAQ,CAAC;AAM3C,eAAO,MAAM,sBAAsB,IAAI,CAAC;AA6IxC,eAAO,MAAM,UAAU,GAAI,aAAa,MAAM,KAAG,IAuBhD,CAAC;AAEF,eAAO,MAAM,cAAc,QAAO,IAGjC,CAAC;AAEF,oFAAoF;AACpF,MAAM,MAAM,kBAAkB,GAAG;IAC7B,OAAO,EAAE,oBAAoB,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,4EAA4E;IAC5E,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;mEAC+D;IAC/D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;;4EAMwE;IACxE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;0CAMsC;IACtC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;;;0CAOsC;IACtC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4DAA4D;IAC5D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+DAA+D;IAC/D,SAAS,CAAC,EAAE,yBAAyB,CAAC;CACzC,CAAC;AAEF;;;gDAGgD;AAChD,MAAM,MAAM,gBAAgB,GAAG;IAC3B,OAAO,EAAE,oBAAoB,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,iBAAiB,GAAG,kBAAkB,GAAG,gBAAgB,GAAG,cAAc,GAAG,aAAa,GAAG,gBAAgB,CAAC;IACrH;;+EAE2E;IAC3E,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;sEAEkE;IAClE,aAAa,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,GAAI,aAAa,MAAM,KAAG,OAChB,CAAC;AAsC1C;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,GACzB,UAAU;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,EACjD,aAAa,MAAM,EACnB,sBAAsB,MAAM,EAC5B,OAAO;IACH,MAAM,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC9C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB,KACF,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAmBnC,CAAC;AAEF;;;;GAIG;AASH,eAAO,MAAM,mBAAmB,GAC5B,KAAK,aAAa,EAClB,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,KAC9C,OAwQF,CAAC;AAWF;;;uBAGuB;AACvB,MAAM,WAAW,iBAAiB;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;+EAI2E;IAC3E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mFAAmF;IACnF,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,yEAAyE;IACzE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;;;;OAQG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wEAAwE;IACxE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;kFAK8E;IAC9E,SAAS,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;8DAE8D;AAC9D,eAAO,MAAM,cAAc,KAAK,CAAC;AACjC;;uDAEuD;AACvD,eAAO,MAAM,oBAAoB,OAAO,CAAC;AAEzC,kFAAkF;AAClF,KAAK,aAAa,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;AAE7D,+BAA+B;AAC/B,KAAK,cAAc,GAAG,cAAc,GAAG;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB;kEAC8D;IAC9D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mCAAmC;IACnC,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACxB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB;wEACoE;IACpE,MAAM,EAAE,OAAO,CAAC;CACnB,CAAC;AAOF,KAAK,UAAU,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,cAAc,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAuCtF;;;GAGG;AACH,eAAO,MAAM,oBAAoB,GAAI,KAAK,iBAAiB,KAAG,UAsC7D,CAAC;AAoBF;;;6DAG6D;AAC7D,eAAO,MAAM,eAAe,KAAK,CAAC;AA6ClC;;;;sDAIsD;AACtD,eAAO,MAAM,oBAAoB,KAAK,CAAC;AAEvC,2EAA2E;AAC3E,eAAO,MAAM,oBAAoB,QAAO,OAAO,CAAC,IAAI,CAAsB,CAAC;AA6G3E;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,GAC3B,KAAK,iBAAiB,EACtB,MAAM,aAAa,KACpB,OAqCF,CAAC;AAEF,MAAM,WAAW,aAAa;IAC1B,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,0EAA0E;IAC1E,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClD;;kEAE8D;IAC9D,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC;AAED;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,QAAO,aA0IzC,CAAC;AAwBF,eAAO,MAAM,eAAe,GAAI,UAAU,aAAa,CAAC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,IAAI,KAAG,IAElF,CAAC;AAsCF,eAAO,MAAM,kBAAkB,GAAI,UAAU,aAAa,CAAC,YAAY,CAAC,KAAG,IAoB1E,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,GAAI,aAAa,MAAM,KAAG,OAQnD,CAAC;AAIF;;;;;GAKG;AACH,UAAU,kBAAkB;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,UAAU,QAAQ;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,wEAAwE;IACxE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;sEACkE;IAClE,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB;sEACkE;IAClE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,uEAAuE;IACvE,KAAK,CAAC,EAAE,kBAAkB,EAAE,CAAC;CAChC;AAED,UAAU,cAAc;IACpB,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IACjD,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IACpD,0EAA0E;IAC1E,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IACxD,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC;IAC1D,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC;IACtE,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,oEAAoE;IACpE,mBAAmB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,EAAE,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACzF,+DAA+D;IAC/D,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IAC7C;sEACkE;IAClE,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9C;AA2BD;;;;;;;GAOG;AACH,eAAO,MAAM,iBAAiB,GAC1B,SAAS,MAAM,EACf,MAAM,MAAM,EACZ,MAAK,MAAM,MAAiB,KAC7B,OAUF,CAAC;AAyEF,eAAO,MAAM,oBAAoB,GAAI,KAAK;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,KAAG,IAE/E,CAAC;AA2FF;;;;GAIG;AACH,eAAO,MAAM,aAAa,GACtB,MAAK,MAAmB,EACxB,MAAK,MAAwB,EAC7B,MAAK,MAA0B,KAChC,MAaF,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,UAAU,GACnB,MAAM,QAAQ,EACd,OAAM,cAAmB,KAC1B,OAAO,CAAC,OAAO,CAgDjB,CAAC;AAcF,eAAO,MAAM,cAAc,GAAI,SAAS,MAAM,KAAG,MAIhD,CAAC;AA4DF,eAAO,MAAM,uBAAuB,GAAI,OAAO,MAAM,KAAG,MA2BvD,CAAC;AA0SF,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AA+H3C,eAAO,MAAM,cAAc,GAAU,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,KAAG,OAAO,CAAC,MAAM,CAoK3F,CAAC"}
1
+ {"version":3,"file":"listener.d.ts","sourceRoot":"","sources":["../src/listener.ts"],"names":[],"mappings":"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"}
package/dist/listener.js CHANGED
@@ -25,8 +25,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
25
25
  return (mod && mod.__esModule) ? mod : { "default": mod };
26
26
  };
27
27
  Object.defineProperty(exports, "__esModule", { value: true });
28
- exports.handleStreamControl = exports.buildStreamFrame = exports.isStreamCapReached = exports.stopAllStreams = exports.stopStream = exports.MAX_CONCURRENT_STREAMS = exports.STREAM_RENEW_FRESH_MS = exports.STREAM_LEASE_MS = exports.claimFrameSend = exports.hasFrameBudget = exports.streamCadence = exports.MAX_FRAMES_PER_SEC = exports.BURST_WINDOW_MS = exports.BURST_INTERVAL_MS = exports.STREAM_INTERVAL_MS = exports.STREAM_CAPTURE_LINES = exports.scheduleInjectSnapshots = exports.historyLinesIn = exports.cursorLineFor = exports.parsePaneGeometry = exports.handleScreenHistoryRequest = exports.SCREEN_HISTORY_MAX_LINES = exports.handleSessionForgetRequest = exports.handleSessionExitRequest = exports.SESSION_EXIT_STEP_MS = exports.handleSessionResumeRequest = exports.handleDiffFileRequest = exports.handleDiffFilesRequest = exports.DIFF_PAGE_MAX_BYTES = exports.handleScreenRequest = exports.collectWatchHits = exports.resetPatternWatches = exports.setPatternWatches = exports.deriveSessionState = exports.resetSessionStates = exports.detectRemoteAgent = exports.tmuxTargetFor = exports.recordTargets = exports.parseSessionName = exports.invalidateTmuxSocketCache = exports.resolveKeys = exports.paneCurrentCommand = exports.checkRateLimit = exports.AUTH_FAILURE_CODES = exports.sessionsReportDue = exports.sessionsFingerprint = exports.knownSessionsFingerprint = exports.knownSessionsToReport = exports.KNOWN_SESSIONS_REPORTED = exports.SESSION_REPORT_HEARTBEAT_MS = void 0;
29
- exports.handleListener = exports.resolveWsUrl = exports.computeListenerDeviceId = exports.computeBackoff = exports.handlePush = exports.gcAttachments = exports.setAttachmentContext = exports.writeRemoteMarker = exports.isInventoried = exports.syncTmuxAgentNames = exports.recordInventory = exports.collectSessionsVerbose = exports.handleCommandInput = exports.pendingInputDecrypts = exports.MAX_PENDING_DECRYPTS = exports.MAX_INPUT_LANES = exports.validateInputMessage = exports.MAX_INPUT_BODY_CHARS = exports.MAX_INPUT_KEYS = void 0;
28
+ exports.buildStreamFrame = exports.isStreamCapReached = exports.stopAllStreams = exports.stopStream = exports.MAX_CONCURRENT_STREAMS = exports.STREAM_RENEW_FRESH_MS = exports.STREAM_LEASE_MS = exports.claimFrameSend = exports.hasFrameBudget = exports.streamCadence = exports.MAX_FRAMES_PER_SEC = exports.BURST_WINDOW_MS = exports.BURST_INTERVAL_MS = exports.STREAM_INTERVAL_MS = exports.STREAM_CAPTURE_LINES = exports.scheduleInjectSnapshots = exports.historyLinesIn = exports.cursorLineFor = exports.parsePaneGeometry = exports.handleScreenHistoryRequest = exports.SCREEN_HISTORY_MAX_LINES = exports.handleSessionForgetRequest = exports.handleSessionExitRequest = exports.SESSION_EXIT_STEP_MS = exports.handleSessionResumeRequest = exports.handleDiffFileRequest = exports.handleDiffFilesRequest = exports.DIFF_PAGE_MAX_BYTES = exports.handleScreenRequest = exports.collectWatchHits = exports.resetPatternWatches = exports.setPatternWatches = exports.deriveSessionState = exports.resetSessionStates = exports.detectRemoteAgent = exports.tmuxTargetFor = exports.recordTargets = exports.isSubagentSessionName = exports.parseSessionName = exports.invalidateTmuxSocketCache = exports.resolveKeys = exports.paneCurrentCommand = exports.checkRateLimit = exports.AUTH_FAILURE_CODES = exports.sessionsReportDue = exports.sessionsFingerprint = exports.knownSessionsFingerprint = exports.knownSessionsToReport = exports.KNOWN_SESSIONS_REPORTED = exports.SESSION_REPORT_HEARTBEAT_MS = void 0;
29
+ exports.handleListener = exports.resolveWsUrl = exports.computeListenerDeviceId = exports.computeBackoff = exports.handlePush = exports.gcAttachments = exports.setAttachmentContext = exports.writeRemoteMarker = exports.isInventoried = exports.syncTmuxAgentNames = exports.recordInventory = exports.collectSessionsVerbose = exports.handleCommandInput = exports.pendingInputDecrypts = exports.MAX_PENDING_DECRYPTS = exports.MAX_INPUT_LANES = exports.validateInputMessage = exports.MAX_INPUT_BODY_CHARS = exports.MAX_INPUT_KEYS = exports.handleStreamControl = void 0;
30
30
  const child_process_1 = require("child_process");
31
31
  const crypto_1 = require("crypto");
32
32
  const fs_1 = require("fs");
@@ -195,7 +195,10 @@ exports.checkRateLimit = checkRateLimit;
195
195
  * session"), which refuses the inject until the next sweep re-pins.
196
196
  */
197
197
  const paneCurrentCommand = (session) => {
198
- const result = (0, child_process_1.spawnSync)('tmux', tmuxArgs(['display-message', '-p', '-t', (0, exports.tmuxTargetFor)(session),
198
+ const target = (0, exports.tmuxTargetFor)(session);
199
+ if (target === null)
200
+ return null; // unresolvable subagent — never spawn
201
+ const result = (0, child_process_1.spawnSync)('tmux', tmuxArgs(['display-message', '-p', '-t', target,
199
202
  `#{pane_current_command}${FIELD_SEP}#{session_name}`]), {
200
203
  encoding: 'utf-8',
201
204
  stdio: ['ignore', 'pipe', 'ignore'],
@@ -217,8 +220,13 @@ const isShellPane = (command) => {
217
220
  * so the user's own paste stack is never pushed onto, and `-d` drops it
218
221
  * again the moment it has been delivered. */
219
222
  const INJECT_BUFFER = 'zeph-inject';
220
- const sendLiteral = (session, text) => (0, child_process_1.spawnSync)('tmux', tmuxArgs(['send-keys', '-l', '-t', (0, exports.tmuxTargetFor)(session), text]), { stdio: ['ignore', 'ignore', 'pipe'] })
221
- .status === 0;
223
+ const sendLiteral = (session, text) => {
224
+ const target = (0, exports.tmuxTargetFor)(session);
225
+ if (target === null)
226
+ return false; // unresolvable subagent — never spawn
227
+ return (0, child_process_1.spawnSync)('tmux', tmuxArgs(['send-keys', '-l', '-t', target, text]), { stdio: ['ignore', 'ignore', 'pipe'] })
228
+ .status === 0;
229
+ };
222
230
  /**
223
231
  * Put the message in the pane as a PASTE rather than as typing.
224
232
  *
@@ -245,7 +253,10 @@ const pasteText = (session, text) => {
245
253
  const set = (0, child_process_1.spawnSync)('tmux', tmuxArgs(['set-buffer', '-b', INJECT_BUFFER, '--', text]), { stdio: ['ignore', 'ignore', 'pipe'] });
246
254
  if (set.status !== 0)
247
255
  return sendLiteral(session, text);
248
- const paste = (0, child_process_1.spawnSync)('tmux', tmuxArgs(['paste-buffer', '-d', '-p', '-b', INJECT_BUFFER, '-t', (0, exports.tmuxTargetFor)(session)]), { stdio: ['ignore', 'ignore', 'pipe'] });
256
+ const pasteTarget = (0, exports.tmuxTargetFor)(session);
257
+ if (pasteTarget === null)
258
+ return false; // unresolvable subagent — never spawn
259
+ const paste = (0, child_process_1.spawnSync)('tmux', tmuxArgs(['paste-buffer', '-d', '-p', '-b', INJECT_BUFFER, '-t', pasteTarget]), { stdio: ['ignore', 'ignore', 'pipe'] });
249
260
  if (paste.status === 0)
250
261
  return true;
251
262
  // `-d` never ran, so the buffer is still there holding the message.
@@ -264,7 +275,10 @@ const pasteText = (session, text) => {
264
275
  const injectKeys = (session, text) => {
265
276
  if (!pasteText(session, text))
266
277
  return false;
267
- const b = (0, child_process_1.spawnSync)('tmux', tmuxArgs(['send-keys', '-t', (0, exports.tmuxTargetFor)(session), 'Enter']), { stdio: ['ignore', 'ignore', 'pipe'] });
278
+ const enterTarget = (0, exports.tmuxTargetFor)(session);
279
+ if (enterTarget === null)
280
+ return false; // unresolvable subagent — never spawn
281
+ const b = (0, child_process_1.spawnSync)('tmux', tmuxArgs(['send-keys', '-t', enterTarget, 'Enter']), { stdio: ['ignore', 'ignore', 'pipe'] });
268
282
  return b.status === 0;
269
283
  };
270
284
  // Named keys the phone may inject to drive a full-screen Claude Code pane
@@ -322,7 +336,10 @@ exports.resolveKeys = resolveKeys;
322
336
  * whole sequence in order.
323
337
  */
324
338
  const injectNamedKeys = (session, tokens) => {
325
- const r = (0, child_process_1.spawnSync)('tmux', tmuxArgs(['send-keys', '-t', (0, exports.tmuxTargetFor)(session), ...tokens]), { stdio: ['ignore', 'ignore', 'pipe'] });
339
+ const target = (0, exports.tmuxTargetFor)(session);
340
+ if (target === null)
341
+ return false; // unresolvable subagent — never spawn
342
+ const r = (0, child_process_1.spawnSync)('tmux', tmuxArgs(['send-keys', '-t', target, ...tokens]), { stdio: ['ignore', 'ignore', 'pipe'] });
326
343
  return r.status === 0;
327
344
  };
328
345
  const stamp = () => new Date().toISOString().slice(11, 19);
@@ -624,6 +641,13 @@ const FIELD_SEP = '␟';
624
641
  // pinning cannot be bypassed by one call site forgetting it.
625
642
  /** Session name → pinned pane id, replaced wholesale by each inventory sweep. */
626
643
  let targetsBySession = new Map();
644
+ /**
645
+ * A subagent session name: `<session>.<pane id digits>` (`zeph-zeph.48`).
646
+ * tmux forbids `.` in session names, so the shape cannot collide; `#` would
647
+ * break the server's stream-sub keys and `:` is the web key separator.
648
+ */
649
+ const isSubagentSessionName = (name) => /^zeph-.+\.\d+$/.test(name);
650
+ exports.isSubagentSessionName = isSubagentSessionName;
627
651
  /** Store the latest sweep's name → pane-id map (see `CollectResult.targets`). */
628
652
  const recordTargets = (targets) => {
629
653
  targetsBySession = new Map(Object.entries(targets ?? {}));
@@ -633,11 +657,26 @@ exports.recordTargets = recordTargets;
633
657
  * The tmux target for a wire session name: its pinned pane id when the last
634
658
  * sweep saw the session, else the name itself (a session younger than one
635
659
  * sweep, or tmux unreachable at startup — today's resolution, active pane).
636
- */
637
- const tmuxTargetFor = (name) => targetsBySession.get(name) ?? name;
660
+ *
661
+ * A SUBAGENT name is the one exception: it resolves ONLY through the map, and
662
+ * an unknown one is null — because tmux parses `zeph-zeph.48` as session
663
+ * `zeph-zeph`, pane INDEX 48, and silently falls back to the active pane when
664
+ * that index is missing (measured: `display -t zeph-zeph.99` → main pane,
665
+ * exit 0). Every caller treats null as "gone": no spawn, refusal, or capture
666
+ * failure — never a write to whichever pane happens to be focused.
667
+ */
668
+ const tmuxTargetFor = (name) => {
669
+ const hit = targetsBySession.get(name);
670
+ if (hit !== undefined)
671
+ return hit;
672
+ return (0, exports.isSubagentSessionName)(name) ? null : name;
673
+ };
638
674
  exports.tmuxTargetFor = tmuxTargetFor;
639
675
  const readPaneInfo = (session) => {
640
- const r = (0, child_process_1.spawnSync)('tmux', tmuxArgs(['display-message', '-p', '-t', (0, exports.tmuxTargetFor)(session),
676
+ const target = (0, exports.tmuxTargetFor)(session);
677
+ if (target === null)
678
+ return { currentCommand: null, startCommand: null, currentPath: null, panePid: null };
679
+ const r = (0, child_process_1.spawnSync)('tmux', tmuxArgs(['display-message', '-p', '-t', target,
641
680
  `#{pane_current_command}${FIELD_SEP}#{pane_start_command}${FIELD_SEP}#{pane_current_path}${FIELD_SEP}#{pane_pid}`]), {
642
681
  encoding: 'utf-8',
643
682
  stdio: ['ignore', 'pipe', 'ignore'],
@@ -707,8 +746,13 @@ const resetSessionStates = () => {
707
746
  sessionStates.clear();
708
747
  };
709
748
  exports.resetSessionStates = resetSessionStates;
710
- const capturePaneText = (session) => {
711
- const r = (0, child_process_1.spawnSync)('tmux', tmuxArgs(['capture-pane', '-p', '-t', (0, exports.tmuxTargetFor)(session), '-S', `-${STATE_CAPTURE_LINES}`]), {
749
+ const capturePaneText = (session, target) => {
750
+ // Explicit target for the sweep (subagent rows aren't in the recorded
751
+ // target map yet); otherwise resolve through it.
752
+ const resolved = target ?? (0, exports.tmuxTargetFor)(session);
753
+ if (resolved === null)
754
+ return null; // unresolvable subagent — never spawn
755
+ const r = (0, child_process_1.spawnSync)('tmux', tmuxArgs(['capture-pane', '-p', '-t', resolved, '-S', `-${STATE_CAPTURE_LINES}`]), {
712
756
  encoding: 'utf-8',
713
757
  stdio: ['ignore', 'pipe', 'pipe'],
714
758
  });
@@ -1096,6 +1140,10 @@ const handleSessionResumeRequest = (req, send) => {
1096
1140
  send({ ...base, ...fields });
1097
1141
  return true;
1098
1142
  };
1143
+ // A subagent is a pane OF a live session, not a session to start — and
1144
+ // before the rate bucket, so refused subagent traffic costs nothing.
1145
+ if ((0, exports.isSubagentSessionName)(sessionName))
1146
+ return reply({ error: 'subagent_view_only' });
1099
1147
  // Charged like a submitted command, not like a keystroke: this starts a
1100
1148
  // process, and the two share one budget so a flood cannot be laundered
1101
1149
  // through whichever path is cheaper.
@@ -1187,6 +1235,11 @@ const handleSessionExitRequest = (req, send) => {
1187
1235
  // Same budget as resume and as a submitted command: ending a session is a
1188
1236
  // session-lifecycle action, and pricing it like a keystroke would let a
1189
1237
  // flood through the cheaper door.
1238
+ // Subagent refusal first, though — outside the bucket, like resume's:
1239
+ // ending a subagent pane is a kill(2) on the parent's child, not a
1240
+ // lifecycle action the phone is ever offered.
1241
+ if ((0, exports.isSubagentSessionName)(sessionName))
1242
+ return answer({ error: 'subagent_view_only' });
1190
1243
  if (!(0, exports.checkRateLimit)(sessionName, undefined, SUBMIT_COST))
1191
1244
  return answer({ error: 'rate_limited' });
1192
1245
  if (!sessionExists(sessionName))
@@ -1261,6 +1314,11 @@ const handleSessionForgetRequest = (req, send) => {
1261
1314
  };
1262
1315
  // Charged like a submitted command: it writes to disk and is irreversible,
1263
1316
  // so it shares the budget with the paths that start and stop processes.
1317
+ // Subagent refusal before the bucket: a subagent has no registry record
1318
+ // to forget (the sweep never remembers panes), so the honest answer is
1319
+ // the view-only one, not unknown_session.
1320
+ if ((0, exports.isSubagentSessionName)(sessionName))
1321
+ return reply({ error: 'subagent_view_only' });
1264
1322
  if (!(0, exports.checkRateLimit)(sessionName, undefined, SUBMIT_COST))
1265
1323
  return reply({ error: 'rate_limited' });
1266
1324
  if (sessionExists(sessionName))
@@ -1281,10 +1339,20 @@ const handleSessionForgetRequest = (req, send) => {
1281
1339
  return reply({ forgotten: true });
1282
1340
  };
1283
1341
  exports.handleSessionForgetRequest = handleSessionForgetRequest;
1284
- /** Whether tmux already holds a session by this name. */
1285
- const sessionExists = (name) => (0, child_process_1.spawnSync)('tmux', tmuxArgs(['has-session', '-t', name]), {
1286
- stdio: ['ignore', 'ignore', 'ignore'],
1287
- }).status === 0;
1342
+ /**
1343
+ * Whether this machine currently holds a session by this name. A subagent
1344
+ * pane cannot be asked with has-session: tmux would parse `zeph-x.48` as
1345
+ * session `zeph-x`, pane index 48 and answer for the WRONG thing (or exit 1
1346
+ * for a missing index) — so subs are answered from the sweep's target map,
1347
+ * which is exactly what "a pane we can address without ambiguity" means.
1348
+ */
1349
+ const sessionExists = (name) => {
1350
+ if ((0, exports.isSubagentSessionName)(name))
1351
+ return targetsBySession.has(name);
1352
+ return (0, child_process_1.spawnSync)('tmux', tmuxArgs(['has-session', '-t', name]), {
1353
+ stdio: ['ignore', 'ignore', 'ignore'],
1354
+ }).status === 0;
1355
+ };
1288
1356
  // ─── Deep pull: scrollback above the live window ───────────────────
1289
1357
  //
1290
1358
  // The live stream captures a fixed window and every frame is capped at
@@ -1303,7 +1371,10 @@ const isPageOffset = (v) => typeof v === 'number' && Number.isInteger(v) && v >=
1303
1371
  /** How many lines of scrollback the pane is holding, or null when tmux won't
1304
1372
  * say — which is also how a dead pane answers. */
1305
1373
  const paneHistorySize = (sessionName) => {
1306
- const r = (0, child_process_1.spawnSync)('tmux', tmuxArgs(['display-message', '-p', '-t', (0, exports.tmuxTargetFor)(sessionName), '#{history_size}']), { encoding: 'utf-8', stdio: ['ignore', 'pipe', 'pipe'] });
1374
+ const target = (0, exports.tmuxTargetFor)(sessionName);
1375
+ if (target === null)
1376
+ return null;
1377
+ const r = (0, child_process_1.spawnSync)('tmux', tmuxArgs(['display-message', '-p', '-t', target, '#{history_size}']), { encoding: 'utf-8', stdio: ['ignore', 'pipe', 'pipe'] });
1307
1378
  if (r.status !== 0)
1308
1379
  return null;
1309
1380
  const size = Number((r.stdout ?? '').trim());
@@ -1312,8 +1383,11 @@ const paneHistorySize = (sessionName) => {
1312
1383
  /** Capture one explicit range. tmux line 0 is the top of the visible pane and
1313
1384
  * negative numbers reach into the history, so both bounds are negative here. */
1314
1385
  const capturePaneRange = (sessionName, start, end) => {
1386
+ const target = (0, exports.tmuxTargetFor)(sessionName);
1387
+ if (target === null)
1388
+ return null;
1315
1389
  const r = (0, child_process_1.spawnSync)('tmux', tmuxArgs([
1316
- 'capture-pane', '-p', '-e', '-t', (0, exports.tmuxTargetFor)(sessionName),
1390
+ 'capture-pane', '-p', '-e', '-t', target,
1317
1391
  '-S', String(start), '-E', String(end),
1318
1392
  ]), { encoding: 'utf-8', stdio: ['ignore', 'pipe', 'pipe'] });
1319
1393
  if (r.status !== 0)
@@ -1425,9 +1499,12 @@ const capturePane = (sessionName, escapes = false, lines = SCREEN_PEEK_LINES) =>
1425
1499
  // `lines` sets how far back the capture reaches — the live stream grabs
1426
1500
  // more history so the mirror has room to scroll; SCREEN_PEEK_MAX_BYTES
1427
1501
  // still caps the payload below.
1502
+ const target = (0, exports.tmuxTargetFor)(sessionName);
1503
+ if (target === null)
1504
+ return null;
1428
1505
  const captureArgs = escapes
1429
- ? ['capture-pane', '-p', '-e', '-t', (0, exports.tmuxTargetFor)(sessionName), '-S', `-${lines}`]
1430
- : ['capture-pane', '-p', '-t', (0, exports.tmuxTargetFor)(sessionName), '-S', `-${lines}`];
1506
+ ? ['capture-pane', '-p', '-e', '-t', target, '-S', `-${lines}`]
1507
+ : ['capture-pane', '-p', '-t', target, '-S', `-${lines}`];
1431
1508
  const r = (0, child_process_1.spawnSync)('tmux', tmuxArgs(captureArgs), {
1432
1509
  encoding: 'utf-8',
1433
1510
  stdio: ['ignore', 'pipe', 'pipe'],
@@ -1452,8 +1529,11 @@ const capturePane = (sessionName, escapes = false, lines = SCREEN_PEEK_LINES) =>
1452
1529
  * spawn per SENT frame rather than per tick.
1453
1530
  */
1454
1531
  const capturePaneCursor = (sessionName) => {
1532
+ const target = (0, exports.tmuxTargetFor)(sessionName);
1533
+ if (target === null)
1534
+ return null;
1455
1535
  const r = (0, child_process_1.spawnSync)('tmux', tmuxArgs([
1456
- 'display-message', '-p', '-t', (0, exports.tmuxTargetFor)(sessionName),
1536
+ 'display-message', '-p', '-t', target,
1457
1537
  '#{cursor_x},#{cursor_y},#{pane_height},#{history_size}',
1458
1538
  ]), { encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'] });
1459
1539
  if (r.status !== 0)
@@ -2469,7 +2549,7 @@ const collectSessionsVerbose = () => {
2469
2549
  // per-session display-message) would multiply with split panes; the worker
2470
2550
  // thread keeps the one blocking sweep off the event loop.
2471
2551
  const list = (0, child_process_1.spawnSync)('tmux', tmuxArgs(['list-panes', '-a', '-F',
2472
- `#{session_name}${FIELD_SEP}#{session_attached}${FIELD_SEP}#{session_created}${FIELD_SEP}#{session_activity}${FIELD_SEP}#{window_index}${FIELD_SEP}#{pane_index}${FIELD_SEP}#{pane_id}${FIELD_SEP}#{pane_current_command}${FIELD_SEP}#{pane_start_command}${FIELD_SEP}#{pane_current_path}${FIELD_SEP}#{pane_pid}`]), {
2552
+ `#{session_name}${FIELD_SEP}#{session_attached}${FIELD_SEP}#{session_created}${FIELD_SEP}#{session_activity}${FIELD_SEP}#{window_index}${FIELD_SEP}#{pane_index}${FIELD_SEP}#{pane_id}${FIELD_SEP}#{pane_current_command}${FIELD_SEP}#{pane_start_command}${FIELD_SEP}#{pane_current_path}${FIELD_SEP}#{pane_pid}${FIELD_SEP}#{@zeph_pane_label}`]), {
2473
2553
  encoding: 'utf-8',
2474
2554
  stdio: ['ignore', 'pipe', 'pipe'],
2475
2555
  });
@@ -2495,9 +2575,9 @@ const collectSessionsVerbose = () => {
2495
2575
  }
2496
2576
  const sessions = [];
2497
2577
  const rejected = [];
2498
- /** 11 fields per row; a mismatch is the mangled-separator failure the
2578
+ /** 12 fields per row; a mismatch is the mangled-separator failure the
2499
2579
  * sanity log above exists for — skip the row loudly, never misparse it. */
2500
- const PANE_FIELDS = 11;
2580
+ const PANE_FIELDS = 12;
2501
2581
  const groups = new Map();
2502
2582
  let malformed = 0;
2503
2583
  for (const line of rawLines) {
@@ -2506,7 +2586,7 @@ const collectSessionsVerbose = () => {
2506
2586
  malformed += 1;
2507
2587
  continue;
2508
2588
  }
2509
- const [name, attached, created, activity, win, idx, paneId, current, start, path, pid] = f;
2589
+ const [name, attached, created, activity, win, idx, paneId, current, start, path, pid, label] = f;
2510
2590
  if (!(0, exports.parseSessionName)(name)) {
2511
2591
  // Not noisy enough to log every plain tmux session here —
2512
2592
  // would clutter the verbose output on machines with many
@@ -2521,6 +2601,7 @@ const collectSessionsVerbose = () => {
2521
2601
  paneId,
2522
2602
  win: numeric(win),
2523
2603
  idx: numeric(idx),
2604
+ label: label ?? '',
2524
2605
  info: {
2525
2606
  currentCommand: current || null,
2526
2607
  startCommand: start || null,
@@ -2586,15 +2667,56 @@ const collectSessionsVerbose = () => {
2586
2667
  providerSessionName,
2587
2668
  createdAt: epochToIso(group.created),
2588
2669
  lastActivityAt: epochToIso(group.activity),
2589
- ...(0, exports.deriveSessionState)(name, main.agent.kind, capturePaneText(main.row.paneId)),
2670
+ ...(0, exports.deriveSessionState)(name, main.agent.kind, capturePaneText(name, main.row.paneId)),
2590
2671
  });
2672
+ // Subagent panes: every OTHER pane of this session whose tty's
2673
+ // foreground process group runs a registered agent (measured:
2674
+ // pane_current_command alone says `bash` for a pi subagent — the
2675
+ // fg group's `comm` is what names it). View-only wire entities
2676
+ // named `<session>.<pane id digits>`; ordered by pane id so the
2677
+ // phone's switcher is stable across sweeps (tmux pane ids are
2678
+ // monotonic server-wide).
2679
+ const paneNum = (p) => Number(p.paneId.slice(1)) || 0;
2680
+ const extras = group.panes
2681
+ .filter((p) => p !== main.row)
2682
+ .sort((a, b) => paneNum(a) - paneNum(b));
2683
+ const fallbackCounts = new Map();
2684
+ for (const extra of extras) {
2685
+ const subAgent = (0, remote_agents_js_1.foregroundAgentFor)(extra.info.panePid ?? 0);
2686
+ if (!subAgent)
2687
+ continue; // a shell / non-agent pane — not reportable
2688
+ const subName = `${name}.${paneNum(extra)}`;
2689
+ targets[subName] = extra.paneId;
2690
+ const n = (fallbackCounts.get(subAgent.kind) ?? 0) + 1;
2691
+ fallbackCounts.set(subAgent.kind, n);
2692
+ sessions.push({
2693
+ name: subName,
2694
+ parentName: name,
2695
+ attached: group.attached,
2696
+ agentKind: subAgent.kind,
2697
+ agentSessionId: null,
2698
+ project: parsed.project,
2699
+ // The subagent names itself by setting @zeph_pane_label
2700
+ // (PI_EXTENSION); a manual `tmux set-option -p` works too.
2701
+ // Fallback names per agent kind so two subagents of the
2702
+ // same kind stay distinguishable.
2703
+ label: extra.label.trim() || `${subAgent.displayName} ${n}`,
2704
+ createdAt: epochToIso(group.created),
2705
+ lastActivityAt: epochToIso(group.activity),
2706
+ ...(0, exports.deriveSessionState)(subName, subAgent.kind, capturePaneText(subName, extra.paneId)),
2707
+ });
2708
+ }
2591
2709
  }
2592
2710
  pruneSessionStates(new Set(sessions.map((s) => s.name)));
2593
2711
  // Write down what each live session IS, while it still exists to be read.
2594
2712
  // tmux forgets a session the moment it ends, which is exactly when the
2595
2713
  // phone wants it back — and a resume must take its directory and its binary
2596
2714
  // from what this machine observed, never from the wire.
2597
- (0, session_registry_js_1.rememberSessions)(sessions.map((s) => ({
2715
+ (0, session_registry_js_1.rememberSessions)(
2716
+ // Subagents are view-only panes OF a session, not resumable ones:
2717
+ // the registry records what a session IS so exit/resume can act on
2718
+ // it, and neither is ever offered for a subagent.
2719
+ sessions.filter((s) => !s.parentName).map((s) => ({
2598
2720
  name: s.name,
2599
2721
  cwd: paneCwdOf.get(s.name) ?? null,
2600
2722
  agentKind: s.agentKind,
@@ -2667,6 +2789,12 @@ const publishedTmuxNames = new Map();
2667
2789
  const syncTmuxAgentNames = (sessions) => {
2668
2790
  const liveKeys = new Set();
2669
2791
  for (const s of sessions) {
2792
+ // Subagents are view-only panes of the parent; publishing a name
2793
+ // for them would run set-option against a `<session>.<pane>` name
2794
+ // that tmux parses as the PARENT session (pane index) — clobbering
2795
+ // the main pane's published name.
2796
+ if (s.parentName)
2797
+ continue;
2670
2798
  const key = `${s.name}\u241f${s.createdAt ?? ''}`;
2671
2799
  liveKeys.add(key);
2672
2800
  const value = s.providerSessionName ?? '';
@@ -2714,6 +2842,15 @@ exports.isInventoried = isInventoried;
2714
2842
  * prefix path route through here so the defense layers can't diverge.
2715
2843
  */
2716
2844
  const passesInjectGuards = (session, deps, cost = 1) => {
2845
+ // Subagent panes are view-only: the phone reads them but the agent
2846
+ // itself answers at the terminal. This sits above the rate bucket so a
2847
+ // flood of refused subagent writes costs nothing and spawns nothing —
2848
+ // with an unresolvable name every downstream tmux call is a no-op, but
2849
+ // the refusal must not depend on the pane still being mapped.
2850
+ if ((0, exports.isSubagentSessionName)(session)) {
2851
+ log(`! ${session}: subagent pane is view-only — drop`);
2852
+ return false;
2853
+ }
2717
2854
  // Rate bucket first: the pane probe below is a blocking tmux spawnSync,
2718
2855
  // and the sequencer can flush several held messages back-to-back — an
2719
2856
  // empty bucket must refuse before paying that probe N times, not after.
@@ -76,6 +76,15 @@ export interface ProcTable {
76
76
  children: Map<number, number[]>;
77
77
  /** pid → process start time in epoch ms. Only pids whose `lstart` parsed. */
78
78
  startTimes: Map<number, number>;
79
+ /** pid → its process group id. Absent when the row carried no pgid. */
80
+ pgidOf: Map<number, number>;
81
+ /** pid → the foreground process group of its controlling tty. A pane
82
+ * shell whose tpgid equals its own pgid IS the foreground — a plain
83
+ * prompt; anything else is running a foreground command. */
84
+ tpgidOf: Map<number, number>;
85
+ /** pid → its command name (`comm`), last column because it may contain
86
+ * spaces (`tmux: client`). Basename-matched against the agent registry. */
87
+ commOf: Map<number, string>;
79
88
  }
80
89
  /**
81
90
  * Parse `ps -axo pid=,ppid=,lstart=`. A row is `<pid> <ppid> [<lstart>]`, e.g.
@@ -92,7 +101,30 @@ export interface ProcTable {
92
101
  * allowed to go missing, and every consumer of `startTimes` treats an absent
93
102
  * entry as "no match" rather than guessing.
94
103
  */
104
+ /**
105
+ * Parse `ps -axo pid=,ppid=,pgid=,tpgid=,lstart=,comm=`. A row is
106
+ * `<pid> <ppid> <pgid> <tpgid> [<lstart>] [<comm>]`, e.g.
107
+ * ` 902 1 902 902 Fri Aug 7 11:12:59 2026 zsh` — note the two spaces
108
+ * before a single-digit day and the trailing padding.
109
+ *
110
+ * Token positions, not one regex: `lstart` is a fixed 5 tokens when present
111
+ * and `comm` is LAST because it may contain spaces. A row with fewer tokens
112
+ * simply contributes fewer maps — the shape is load-bearing rather than
113
+ * defensive: parent links must survive an unreadable timestamp (the reason
114
+ * `lstart` is optional), and the pgid/tpgid/comm columns are absent only when
115
+ * a caller fed the old narrower argv, which nothing in production does.
116
+ */
95
117
  export declare const parseProcTable: (table: string) => ProcTable;
118
+ /**
119
+ * The agent running in the FOREGROUND process group of the tty owned by a
120
+ * pane shell, or null. This is what separates a subagent pane from a plain
121
+ * prompt: the subagent pane reports `pane_current_command=bash` (a script
122
+ * execs pi), so the pane-level command identifies nothing — but the tty's
123
+ * foreground group is pi's, and `comm` names it. A pane sitting at its login
124
+ * shell has the shell's own group in the foreground (tpgid === pgid) and is
125
+ * not a subagent, no matter what the registry would match.
126
+ */
127
+ export declare const foregroundAgentFor: (panePid: number, table?: ProcTable | null) => RegisteredRemoteAgent | null;
96
128
  /** Start times for this cycle's snapshot. Empty when `ps` is unavailable. */
97
129
  export declare const psStartTimes: () => Map<number, number>;
98
130
  /** pid set of `rootPid` + all descendants, from one `ps` snapshot. */
@@ -1 +1 @@
1
- {"version":3,"file":"remote-agents.d.ts","sourceRoot":"","sources":["../src/remote-agents.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"remote-agents.d.ts","sourceRoot":"","sources":["../src/remote-agents.ts"],"names":[],"mappings":"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"}
@@ -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.detectCodexSessionName = exports.newestVersionedDb = exports.detectHermesSessionName = exports.sqliteJson = exports.pickRowByProcStart = exports.claudeTranscriptPath = exports.detectClaudeSessionNameByPid = exports.detectClaudeSessionIdByPid = exports.detectClaudeSessionByPid = exports.pidSessionRecordsExist = exports.collectDescendantPids = exports.psStartTimes = exports.parseProcTable = exports.detectClaudeSessionId = void 0;
3
+ exports.matchAgentByPaneCommand = exports.findAgentBySubcommand = exports.REMOTE_AGENTS = exports.detectCodexSessionName = exports.newestVersionedDb = exports.detectHermesSessionName = exports.sqliteJson = exports.pickRowByProcStart = exports.claudeTranscriptPath = exports.detectClaudeSessionNameByPid = exports.detectClaudeSessionIdByPid = exports.detectClaudeSessionByPid = exports.pidSessionRecordsExist = exports.collectDescendantPids = exports.psStartTimes = exports.foregroundAgentFor = exports.parseProcTable = exports.detectClaudeSessionId = void 0;
4
4
  /**
5
5
  * Remote-control agent registry — the single table behind every
6
6
  * `zeph <agent>` subcommand, the listener's pane matching, and the
@@ -178,24 +178,50 @@ const ttlMemo = (ttlMs, compute) => {
178
178
  * allowed to go missing, and every consumer of `startTimes` treats an absent
179
179
  * entry as "no match" rather than guessing.
180
180
  */
181
+ /**
182
+ * Parse `ps -axo pid=,ppid=,pgid=,tpgid=,lstart=,comm=`. A row is
183
+ * `<pid> <ppid> <pgid> <tpgid> [<lstart>] [<comm>]`, e.g.
184
+ * ` 902 1 902 902 Fri Aug 7 11:12:59 2026 zsh` — note the two spaces
185
+ * before a single-digit day and the trailing padding.
186
+ *
187
+ * Token positions, not one regex: `lstart` is a fixed 5 tokens when present
188
+ * and `comm` is LAST because it may contain spaces. A row with fewer tokens
189
+ * simply contributes fewer maps — the shape is load-bearing rather than
190
+ * defensive: parent links must survive an unreadable timestamp (the reason
191
+ * `lstart` is optional), and the pgid/tpgid/comm columns are absent only when
192
+ * a caller fed the old narrower argv, which nothing in production does.
193
+ */
181
194
  const parseProcTable = (table) => {
182
195
  const children = new Map();
183
196
  const startTimes = new Map();
197
+ const pgidOf = new Map();
198
+ const tpgidOf = new Map();
199
+ const commOf = new Map();
184
200
  for (const line of table.split('\n')) {
185
- const m = line.trim().match(/^(\d+)\s+(\d+)(?:\s+(.*))?$/);
186
- if (!m)
201
+ const tok = line.trim().split(/\s+/);
202
+ const pid = Number(tok[0]);
203
+ const ppid = Number(tok[1]);
204
+ if (!Number.isInteger(pid) || !Number.isInteger(ppid))
187
205
  continue;
188
- const [pid, ppid] = [Number(m[1]), Number(m[2])];
189
206
  const list = children.get(ppid) ?? [];
190
207
  list.push(pid);
191
208
  children.set(ppid, list);
192
- if (m[3] === undefined)
193
- continue;
194
- const started = Date.parse(m[3].trim());
195
- if (Number.isFinite(started))
196
- startTimes.set(pid, started);
209
+ let rest = tok.slice(2);
210
+ if (rest.length >= 2 && Number.isInteger(Number(rest[0]))) {
211
+ pgidOf.set(pid, Number(rest[0]));
212
+ tpgidOf.set(pid, Number(rest[1]));
213
+ rest = rest.slice(2);
214
+ }
215
+ if (rest.length >= 5) {
216
+ const started = Date.parse(rest.slice(0, 5).join(' '));
217
+ if (Number.isFinite(started))
218
+ startTimes.set(pid, started);
219
+ rest = rest.slice(5);
220
+ }
221
+ if (rest.length > 0)
222
+ commOf.set(pid, rest.join(' '));
197
223
  }
198
- return { children, startTimes };
224
+ return { children, startTimes, pgidOf, tpgidOf, commOf };
199
225
  };
200
226
  exports.parseProcTable = parseProcTable;
201
227
  /**
@@ -205,9 +231,38 @@ exports.parseProcTable = parseProcTable;
205
231
  * second `ps` spawn to learn that would undo what this memo is for.
206
232
  */
207
233
  const readPsSnapshot = ttlMemo(SNAPSHOT_TTL_MS, () => {
208
- const r = (0, child_process_1.spawnSync)('ps', ['-axo', 'pid=,ppid=,lstart='], { encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'] });
234
+ // pgid/tpgid/comm ride along for the subagent detection (foreground
235
+ // process group), so the extra panes cost zero new spawns — one `ps`
236
+ // per report cycle is still the whole table (KB precedent).
237
+ const r = (0, child_process_1.spawnSync)('ps', ['-axo', 'pid=,ppid=,pgid=,tpgid=,lstart=,comm='], { encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'] });
209
238
  return r.status === 0 ? (0, exports.parseProcTable)(r.stdout ?? '') : null;
210
239
  });
240
+ /**
241
+ * The agent running in the FOREGROUND process group of the tty owned by a
242
+ * pane shell, or null. This is what separates a subagent pane from a plain
243
+ * prompt: the subagent pane reports `pane_current_command=bash` (a script
244
+ * execs pi), so the pane-level command identifies nothing — but the tty's
245
+ * foreground group is pi's, and `comm` names it. A pane sitting at its login
246
+ * shell has the shell's own group in the foreground (tpgid === pgid) and is
247
+ * not a subagent, no matter what the registry would match.
248
+ */
249
+ const foregroundAgentFor = (panePid, table = readPsSnapshot()) => {
250
+ if (!Number.isInteger(panePid) || panePid <= 0 || !table)
251
+ return null;
252
+ const pgid = table.pgidOf.get(panePid);
253
+ const tpgid = table.tpgidOf.get(panePid);
254
+ if (pgid === undefined || tpgid === undefined || tpgid === pgid)
255
+ return null;
256
+ for (const [pid, pgrp] of table.pgidOf) {
257
+ if (pgrp !== tpgid)
258
+ continue;
259
+ const agent = (0, exports.matchAgentByPaneCommand)((0, path_1.basename)(table.commOf.get(pid) ?? ''));
260
+ if (agent)
261
+ return agent;
262
+ }
263
+ return null;
264
+ };
265
+ exports.foregroundAgentFor = foregroundAgentFor;
211
266
  /** Start times for this cycle's snapshot. Empty when `ps` is unavailable. */
212
267
  const psStartTimes = () => readPsSnapshot()?.startTimes ?? new Map();
213
268
  exports.psStartTimes = psStartTimes;
@@ -1 +1 @@
1
- {"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../src/templates.ts"],"names":[],"mappings":"AAwGA,oGAAoG;AACpG,eAAO,MAAM,kBAAkB,QAAS,CAAC;AA8IzC,6FAA6F;AAC7F,eAAO,MAAM,WAAW,QAKtB,CAAC;AAEH,6FAA6F;AAC7F,eAAO,MAAM,aAAa,QAIxB,CAAC;AAEH,+GAA+G;AAC/G,eAAO,MAAM,WAAW,QAAoE,CAAC;AAE7F,4GAA4G;AAC5G,eAAO,MAAM,UAAU,QAAoE,CAAC;AAE5F,oGAAoG;AACpG,eAAO,MAAM,YAAY,QAIvB,CAAC;AAEH,gFAAgF;AAChF,eAAO,MAAM,UAAU,QAIrB,CAAC;AAEH,sGAAsG;AACtG,eAAO,MAAM,UAAU,QAIrB,CAAC;AAEH,wJAAwJ;AACxJ,eAAO,MAAM,OAAO,QAKlB,CAAC;AAEH,2GAA2G;AAC3G,eAAO,MAAM,aAAa,QAIxB,CAAC;AAIH,eAAO,MAAM,YAAY,QAKd,CAAC;AAEZ,eAAO,MAAM,cAAc,QAOhB,CAAC;AAEZ,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;CAuBxB,CAAC;AAYF,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;CASvB,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,GAAI,OAAO,OAAO,KAAG,OAUhD,CAAC;AAEF,eAAO,MAAM,aAAa,QASf,CAAC;AAQZ,2FAA2F;AAC3F,eAAO,MAAM,YAAY,QAgJxB,CAAC;AAEF,kGAAkG;AAClG,eAAO,MAAM,eAAe,QAwG3B,CAAC;AASF,eAAO,MAAM,eAAe,oFAA+E,CAAC;AAC5G,eAAO,MAAM,aAAa,sBAAsB,CAAC;AAQjD;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,GAAI,UAAU,MAAM,EAAE,MAAM,MAAM,KAAG,MAWnE,CAAC;AAEF,uEAAuE;AACvE,eAAO,MAAM,kBAAkB,GAAI,UAAU,MAAM,KAAG,MAOrD,CAAC"}
1
+ {"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../src/templates.ts"],"names":[],"mappings":"AAwGA,oGAAoG;AACpG,eAAO,MAAM,kBAAkB,QAAS,CAAC;AA8IzC,6FAA6F;AAC7F,eAAO,MAAM,WAAW,QAKtB,CAAC;AAEH,6FAA6F;AAC7F,eAAO,MAAM,aAAa,QAIxB,CAAC;AAEH,+GAA+G;AAC/G,eAAO,MAAM,WAAW,QAAoE,CAAC;AAE7F,4GAA4G;AAC5G,eAAO,MAAM,UAAU,QAAoE,CAAC;AAE5F,oGAAoG;AACpG,eAAO,MAAM,YAAY,QAIvB,CAAC;AAEH,gFAAgF;AAChF,eAAO,MAAM,UAAU,QAIrB,CAAC;AAEH,sGAAsG;AACtG,eAAO,MAAM,UAAU,QAIrB,CAAC;AAEH,wJAAwJ;AACxJ,eAAO,MAAM,OAAO,QAKlB,CAAC;AAEH,2GAA2G;AAC3G,eAAO,MAAM,aAAa,QAIxB,CAAC;AAIH,eAAO,MAAM,YAAY,QAKd,CAAC;AAEZ,eAAO,MAAM,cAAc,QAOhB,CAAC;AAEZ,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;CAuBxB,CAAC;AAYF,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;CASvB,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,GAAI,OAAO,OAAO,KAAG,OAUhD,CAAC;AAEF,eAAO,MAAM,aAAa,QASf,CAAC;AAQZ,2FAA2F;AAC3F,eAAO,MAAM,YAAY,QAyKxB,CAAC;AAEF,kGAAkG;AAClG,eAAO,MAAM,eAAe,QAwG3B,CAAC;AASF,eAAO,MAAM,eAAe,oFAA+E,CAAC;AAC5G,eAAO,MAAM,aAAa,sBAAsB,CAAC;AAQjD;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,GAAI,UAAU,MAAM,EAAE,MAAM,MAAM,KAAG,MAWnE,CAAC;AAEF,uEAAuE;AACvE,eAAO,MAAM,kBAAkB,GAAI,UAAU,MAAM,KAAG,MAOrD,CAAC"}
package/dist/templates.js CHANGED
@@ -368,7 +368,7 @@ exports.COPILOT_HOOKS = JSON.stringify({
368
368
  // *_PLUGIN for the same quiet-default guard, at the string level.
369
369
  /** Pi extension source — written to ~/.pi/agent/extensions/zeph.ts (drop-in auto-load). */
370
370
  exports.PI_EXTENSION = `// Generated by @zeph-to/cli — reinstall overwrites; \`zeph uninstall\` removes.
371
- import { spawn } from "node:child_process";
371
+ import { spawn, execFileSync } from "node:child_process";
372
372
  import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
373
373
 
374
374
  const sh = (cmd: string, cwd: string, stdin?: string): Promise<string> =>
@@ -406,12 +406,32 @@ const pushHigh = (cwd: string, title: string, body: string): void => {
406
406
  ...process.env,
407
407
  ZEPH_PUSH_TITLE: title,
408
408
  ZEPH_PUSH_BODY: body.length > 200 ? body.slice(0, 199) + "…" : body,
409
+ ...(SUBAGENT_SESSION ? { ZEPH_AGENT_SESSION_NAME: SUBAGENT_SESSION } : {}),
409
410
  };
410
411
  const child = spawn("sh", ["-c", ${JSON.stringify(highNotifyCmd)}], { cwd, env, stdio: "ignore", detached: true });
411
412
  child.on("error", () => {});
412
413
  child.unref();
413
414
  };
414
415
 
416
+ // Subagent mode: pi spawned this process as a subagent (PI_SUBAGENT_NAME set
417
+ // by the spawner). Label this tmux pane so the listener's sweep picks the name
418
+ // up, and file pushes under the subagent's own session key
419
+ // (<parent session>.<pane id>) — the listener's naming — instead of the
420
+ // parent's, so a phone push opens the subagent's stream, not the parent's.
421
+ const SUBAGENT_NAME = process.env.PI_SUBAGENT_NAME || "";
422
+ const SUBAGENT_SESSION = (() => {
423
+ if (!SUBAGENT_NAME || !process.env.TMUX_PANE) return "";
424
+ try {
425
+ const pane = spawn("tmux", ["set-option", "-p", "-t", process.env.TMUX_PANE, "@zeph_pane_label", SUBAGENT_NAME], { stdio: "ignore", detached: true });
426
+ pane.on("error", () => {});
427
+ pane.unref();
428
+ // Targeted at this pane and bounded: this runs while pi loads, so a
429
+ // wedged tmux server must cost at most 2s, never the whole startup.
430
+ const s = execFileSync("tmux", ["display-message", "-p", "-t", process.env.TMUX_PANE, "#S"], { encoding: "utf8", timeout: 2000 }).trim();
431
+ return s ? s + "." + process.env.TMUX_PANE.slice(1) : "";
432
+ } catch { return ""; }
433
+ })();
434
+
415
435
  export default function (pi: ExtensionAPI) {
416
436
  // Turn facts for the push gate. One agent per process, so plain counters
417
437
  // suffice — no session keying.
@@ -467,7 +487,7 @@ export default function (pi: ExtensionAPI) {
467
487
  ?? (running ? running.toolName + " is waiting for your answer" : "Waiting for your input");
468
488
  promptTimer = setTimeout(() => {
469
489
  promptTimer = undefined;
470
- pushHigh(ctx.cwd, "pi asks: " + projectOf(ctx.cwd), body);
490
+ pushHigh(ctx.cwd, "pi asks: " + projectOf(ctx.cwd) + (SUBAGENT_NAME ? " · " + SUBAGENT_NAME : ""), body);
471
491
  }, PROMPT_GRACE_MS);
472
492
  promptTimer.unref?.();
473
493
  });
@@ -481,6 +501,11 @@ export default function (pi: ExtensionAPI) {
481
501
  agentRunning = false;
482
502
  clearTimeout(promptTimer);
483
503
  promptTimer = undefined;
504
+ // A subagent never pushes — not its completion, not its error. The parent
505
+ // settles on their results (4 parallel subagents would otherwise mean 4
506
+ // simultaneous pushes), and an error stays live in the subagent's own
507
+ // stream, which the phone is already mirroring.
508
+ if (SUBAGENT_NAME) return;
484
509
  // Esc (at the terminal, or a key sent from the phone): whoever stopped the
485
510
  // turn is already looking at it.
486
511
  if (stop?.reason === "aborted") return;
@@ -1 +1 @@
1
- {"version":3,"file":"zeph-hook.d.ts","sourceRoot":"","sources":["../src/zeph-hook.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,YAAY,EAAE,UAAU,EAAE,UAAU,EAAY,gBAAgB,EAAE,gBAAgB,EAAoB,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAoCxL,qBAAa,QAAQ;IACnB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IAEnC,OAAO,CAAC,iBAAiB,CAAS;gBAEtB,OAAO,EAAE,WAAW;IAShC;;;;;;;;OAQG;YACW,YAAY;IAyB1B;;;;;;;;;;;OAWG;IACG,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;YAgB7C,UAAU;YAyCV,cAAc;IA6DtB,aAAa,CAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAK7G,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAcrF,IAAI,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IAuB9C,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAKlD,UAAU,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAK7C;;;;OAIG;IACG,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;YASxF,OAAO;IAiCrB,OAAO,CAAC,UAAU;CASnB"}
1
+ {"version":3,"file":"zeph-hook.d.ts","sourceRoot":"","sources":["../src/zeph-hook.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,YAAY,EAAE,UAAU,EAAE,UAAU,EAAY,gBAAgB,EAAE,gBAAgB,EAAoB,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAyCxL,qBAAa,QAAQ;IACnB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IAEnC,OAAO,CAAC,iBAAiB,CAAS;gBAEtB,OAAO,EAAE,WAAW;IAShC;;;;;;;;OAQG;YACW,YAAY;IAyB1B;;;;;;;;;;;OAWG;IACG,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;YAgB7C,UAAU;YAyCV,cAAc;IA6DtB,aAAa,CAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAK7G,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAcrF,IAAI,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IAuB9C,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAKlD,UAAU,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAK7C;;;;OAIG;IACG,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;YASxF,OAAO;IAiCrB,OAAO,CAAC,UAAU;CASnB"}
package/dist/zeph-hook.js CHANGED
@@ -21,6 +21,12 @@ const PREVIEW_LENGTH = 200;
21
21
  const agentSessionContext = () => {
22
22
  if (!process.env.TMUX)
23
23
  return null;
24
+ // A pi subagent pane carries its own wire name (<#S>.<pane> — the
25
+ // listener's naming) in this env, set by the extension for its notify
26
+ // children. It wins over #S, which would file the push under the parent.
27
+ const fromEnv = process.env.ZEPH_AGENT_SESSION_NAME?.trim();
28
+ if (fromEnv)
29
+ return { agentDeviceId: (0, listener_device_id_js_1.listenerDeviceId)(), agentSessionName: fromEnv };
24
30
  let name;
25
31
  try {
26
32
  name = (0, node_child_process_1.execFileSync)('tmux', ['display-message', '-p', '#S'], { encoding: 'utf-8' }).trim();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zeph-to/cli",
3
- "version": "2.18.0",
3
+ "version": "2.19.0",
4
4
  "description": "Zeph CLI + push notification SDK for AI agents",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",