@mentiko/pty-mgr 1.2.4 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,117 @@
1
+ # Changelog
2
+
3
+ ## 1.3.1 - 2026-07-02
4
+
5
+ ### Fixed
6
+
7
+ - macOS binaries are now compiled on a macOS runner and ad-hoc code-signed, so
8
+ they carry a valid signature and Apple Silicon (AMFI) no longer SIGKILLs them
9
+ on launch (`killed`). They were previously cross-compiled on Linux, whose
10
+ embedded linker signature is rejected by macOS. The `curl | sh` installer also
11
+ re-signs the binary on download as a fallback for older releases.
12
+
13
+ ## 1.3.0 - 2026-07-02
14
+
15
+ ### Added
16
+
17
+ - `p view <name1> <name2> [interval]` — live, read-only side-by-side session
18
+ viewer. Renders two sessions in split panes with a divider and name headers,
19
+ refreshes on an interval (default `500ms`), handles terminal resizes, and
20
+ exits cleanly on `q` / `Ctrl-C`. Requires at least 21 terminal columns.
21
+ - `p flow show <name>` — prints a single configured flow in detail: agents and
22
+ their adapter kinds, the start target, each turn's routing and steering text,
23
+ and cycle/interval/settle settings. Errors on unknown flow names.
24
+ - `p flow list --verbose` — shows each flow's agents, adapter kinds, start
25
+ target, and maxCycles alongside the flow name.
26
+ - `code-review` flow added to the shipped `pty-mgr.config.json`: Codex writes,
27
+ Claude reviews the actual `git diff` on disk, and Codex applies the fixes.
28
+
29
+ ### Fixed
30
+
31
+ - Flow prompt submission: sending a prompt to a freshly booted TUI could leave
32
+ the text typed but un-submitted (Enter races startup), so no transcript was
33
+ ever created and the flow waited out the full timeout with zero turns. Now
34
+ confirms the sent message appears in the agent's transcript and nudges with a
35
+ bare Enter if not; a stranded start fails fast with a clear reason.
36
+ - Waits for the agent CLI to boot before sending the first prompt.
37
+
38
+ ## 1.2.11 - 2026-06-06
39
+
40
+ ### Fixed
41
+
42
+ - Made the standalone `p demo` command exit explicitly after cleanup so
43
+ linux PTY handles cannot keep Bun alive after the demo prints complete.
44
+
45
+ ## 1.2.10 - 2026-06-06
46
+
47
+ ### Fixed
48
+
49
+ - Replaced the demo smoke test's interactive shell prompt dependency with a
50
+ deterministic scripted PTY shell reader.
51
+ - Added a CI timeout around the demo smoke step so future PTY hangs fail loudly
52
+ instead of parking the workflow.
53
+
54
+ ## 1.2.9 - 2026-06-06
55
+
56
+ ### Fixed
57
+
58
+ - Made `waitFor` poll the rendered screen while listening for data so fast
59
+ command output cannot be missed between spawn and listener timing.
60
+ - Made the demo smoke test exit its interactive shell cleanly and verify `kill`
61
+ with a separate disposable process so CI cannot hang on a lingering PTY.
62
+
63
+ ## 1.2.8 - 2026-06-06
64
+
65
+ ### Fixed
66
+
67
+ - Made the demo smoke test spawn `zsh -f` so CI cannot be blocked by user
68
+ startup files or compinit prompts.
69
+
70
+ ## 1.2.7 - 2026-06-06
71
+
72
+ ### Fixed
73
+
74
+ - Moved the demo smoke check out of the concurrent `bun test` suite; CI still
75
+ runs it as its own dedicated step.
76
+ - Made `waitForExit` tests use a self-exiting PTY command instead of sending
77
+ `exit` into an interactive shell before the prompt is ready.
78
+
79
+ ## 1.2.6 - 2026-06-06
80
+
81
+ ### Fixed
82
+
83
+ - Fixed a CI-only test race where delayed PTY test callbacks could fire after
84
+ test cleanup destroyed their sessions.
85
+ - Supersedes the v1.2.5 tag for the same agent-flow feature set with a stable
86
+ CI run.
87
+
88
+ ## 1.2.5 - 2026-06-06
89
+
90
+ ### Added
91
+
92
+ - Added `p flow list` and `p flow run <name> --task <text>` for configurable
93
+ multi-agent workflows.
94
+ - Added `pty-mgr.config.json` with Claude and Codex adapter examples plus
95
+ `spec-writer` and `review-loop` flow examples.
96
+ - Added config-driven transcript parsing for sent user messages and completed
97
+ assistant messages so flows can route between CLI tools without hardcoded
98
+ agent-specific logic.
99
+ - Added flow regression tests for competing transcripts, reused sessions, custom
100
+ adapters, steering templates, and CLI argument handling.
101
+
102
+ ### Changed
103
+
104
+ - Promoted the agent relay prototype into the main single-file implementation
105
+ under `lib/pty-manager.mjs`.
106
+ - Removed the old demo relay harness and standardized on `pty-mgr.config.json`.
107
+ - Improved setup wrappers, daemon argument parsing, wrap shell quoting, and
108
+ client-supplied environment filtering.
109
+
110
+ ### Fixed
111
+
112
+ - Fixed flow relay log binding so `p watch` completion cannot cause the relay to
113
+ grab another active agent's newer transcript.
114
+ - Fixed reused-session flow handling by binding to the sent prompt instead of
115
+ filtering only by transcript start time.
116
+ - Fixed `@...` payload handling so messages like `@everyone` are not mistaken
117
+ for daemon selectors after the command position.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Marco Almazan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -83,9 +83,18 @@ p send agent-1 "fix the login bug"
83
83
  # capture rendered screen (last 20 lines)
84
84
  p capture agent-1 20
85
85
 
86
+ # send raw text with no trailing enter
87
+ p send agent-1 --raw "partial input"
88
+
89
+ # poll whether a session is still working (diffs two captures)
90
+ p watch agent-1 4s
91
+
86
92
  # attach interactively (ctrl-] to detach)
87
93
  p attach agent-1
88
94
 
95
+ # watch two sessions side-by-side, live (q or Ctrl-C to exit)
96
+ p view agent-1 agent-2
97
+
89
98
  # rename a session
90
99
  p rename agent-1 agent-refactored
91
100
 
@@ -93,10 +102,164 @@ p rename agent-1 agent-refactored
93
102
  p capture all 50
94
103
  p kill refa*
95
104
 
105
+ # daemon status + config
106
+ p status
107
+
96
108
  # stop daemon
97
109
  p stop
98
110
  ```
99
111
 
112
+ ## Command Reference
113
+
114
+ Every command (`p --help`):
115
+
116
+ | Command | Description |
117
+ |---------|-------------|
118
+ | `p daemon` | Start daemon (forks to background) |
119
+ | `p daemon @myproject` | Named daemon (isolated sessions) |
120
+ | `p status` | Daemon info + config |
121
+ | `p config` | Show current config |
122
+ | `p config screen 100x50` | Set default terminal size |
123
+ | `p config cap-on-send on\|off` | Return a capture with every send |
124
+ | `p config send-delay <ms>` | Delay before enter (default 1000) |
125
+ | `p spawn <name> [cmd] [args...]` | Create session (default `zsh`) |
126
+ | `p wrap [cmd] [args...]` | Spawn with auto-incrementing cwd name |
127
+ | `p attach <name>` | Interactive mode (ctrl-] detach) |
128
+ | `p view <name1> <name2> [interval]` | Read-only split-pane live viewer |
129
+ | `p send <name> <text>` | Send text + enter |
130
+ | `p send <name> --raw <text>` | Send text as-is (no enter) |
131
+ | `p capture <name> [lines]` | Capture rendered screen |
132
+ | `p capture all [lines]` | Capture from all sessions |
133
+ | `p capture <glob*> [lines]` | Capture matching sessions |
134
+ | `p watch <name> [interval]` | Diff two bottom-100 captures → `done`/`working` |
135
+ | `p list` | List all sessions |
136
+ | `p alive <name>` | Check if a session is alive |
137
+ | `p info <name>` | Session details |
138
+ | `p kill <name>` | Kill session |
139
+ | `p kill all` | Kill all sessions |
140
+ | `p kill <glob*>` | Kill matching sessions |
141
+ | `p rename <old> <new>` | Rename a session |
142
+ | `p remove <name\|all\|glob*>` | Kill + remove |
143
+ | `p log <name> on [jsonl\|raw\|rendered]` | Start logging |
144
+ | `p log <name> off` | Stop logging |
145
+ | `p spawn <name> --log [cmd]` | Spawn with logging (jsonl) |
146
+ | `p stop` | Stop current daemon |
147
+ | `p stop all` | Stop all daemons |
148
+ | `p setup` | Wrap CLI tools (claude, etc.) |
149
+ | `p flow list [--verbose] [--config file]` | List configured agent workflows |
150
+ | `p flow show <name> [--config file]` | Show one configured agent workflow in detail |
151
+ | `p flow run <name> --task <text>` | Run a configured agent workflow |
152
+ | `p tg <message>` | Send a Telegram notification |
153
+ | `p tg <message> --reply [--timeout N]` | Send and block for a reply |
154
+ | `p demo` | Run self-test (no daemon needed) |
155
+
156
+ `p watch <name> [interval]` captures the bottom 100 lines, waits `interval`
157
+ (default `4s`; accepts `4s`, `1000ms`, or a bare millisecond value), captures
158
+ again, and prints `done` if the screen is unchanged or `working` if it moved —
159
+ a cheap idle check for polling long-running agents.
160
+
161
+ ## Side-by-Side Viewer
162
+
163
+ `p view <name1> <name2>` renders two sessions side-by-side in split panes with a
164
+ vertical divider and live refresh. It's read-only — great for watching two agents
165
+ work in parallel (e.g. a writer and a reviewer in a code-review flow) without
166
+ switching terminals.
167
+
168
+ ```
169
+ p daemon
170
+
171
+ # spawn two agents
172
+ p spawn writer claude
173
+ p spawn reviewer claude
174
+
175
+ # watch both live, side-by-side (refresh every 500ms by default)
176
+ p view writer reviewer
177
+
178
+ # custom refresh interval (4s, 1000ms, or bare milliseconds)
179
+ p view writer reviewer 1000ms
180
+
181
+ # "v" is an alias for "view"
182
+ p v writer reviewer
183
+ ```
184
+
185
+ The viewer enters the alternate screen, draws a header row with each session's
186
+ name, refreshes both panes on the interval you set, and handles terminal resizes.
187
+ Press `q` or `Ctrl-C` to exit. Requires at least 21 terminal columns.
188
+
189
+ ## Agent Flows
190
+
191
+ `p flow` runs configurable agent-collaboration workflows. The workflow lives in
192
+ `pty-mgr.config.json`; the binary provides the PTY/session/log plumbing.
193
+
194
+ ```
195
+ p daemon
196
+ p flow list # list configured flow names
197
+ p flow list --verbose # show each flow's agents + routing
198
+ p flow show code-review # full detail: agents, turns, settings
199
+ p flow run spec-writer --task "Create a spec for the auth rewrite."
200
+ p flow run review-loop --task "Review this repo." --max-cycles 2
201
+
202
+ # one agent implements, another reviews the real git diff, the first revises
203
+ p flow run code-review --task "Add rate limiting to the /login route" --cwd ~/dev/myapp
204
+ ```
205
+
206
+ Both agents in a flow launch in the same working directory (`--cwd`, or wherever
207
+ you run the command), so a reviewer agent can open the actual files the writer
208
+ produced — not just react to its chat summary.
209
+
210
+ A flow has:
211
+
212
+ - `adapters`: how to launch each CLI and parse sent user + assistant logs.
213
+ - `agents`: named participants in a workflow, each using an adapter kind.
214
+ - `start`: which agent receives the initial task.
215
+ - `turns`: routing and steering templates between agents.
216
+
217
+ Useful run flags:
218
+
219
+ - `--goal <text>`: separate long-running goal text from the initial task.
220
+ - `--max-cycles <n>`: override the workflow's configured cycle count.
221
+ - `--watch-interval <duration>`: compare bottom-100-line captures after this
222
+ interval to detect a stable screen (`4s`, `1000ms`, or a bare millisecond
223
+ value; default `10s`).
224
+ - `--interval-ms <n>`: poll cadence between stability checks (default `1000`).
225
+ - `--settle-ms <n>`: wait after a stable capture before reading the transcript.
226
+ - `--timeout-ms <n>`: return incomplete instead of waiting forever.
227
+
228
+ Example steering:
229
+
230
+ ```json
231
+ {
232
+ "from": "author",
233
+ "to": "reviewer",
234
+ "append": "Based on this, what gaps do you see and what should change next?"
235
+ }
236
+ ```
237
+
238
+ Supported template variables:
239
+
240
+ - `{task}`: the initial task passed on the CLI.
241
+ - `{goal}`: `--goal` if provided, otherwise the task.
242
+ - `{lastMessage}`: the completed assistant response being relayed.
243
+ - `{cycle}`: current cycle number.
244
+ - `{from}` / `{to}`: source and target agent names.
245
+
246
+ The shipped `pty-mgr.config.json` includes three examples for Claude/Codex:
247
+
248
+ - `spec-writer`: author drafts, reviewer critiques, author revises.
249
+ - `review-loop`: two agents trade a task back and forth.
250
+ - `code-review`: Codex implements the task, then Claude reviews the actual
251
+ `git diff` (correctness, edge cases, security) and Codex applies the fixes.
252
+ This is the "one agent writes code, another reviews it" workflow — run it
253
+ with `p flow run code-review --task "..." --cwd <repo>`.
254
+
255
+ Add new adapters for Gemini, OpenCode, or another CLI by defining where that
256
+ tool stores JSONL logs and how to extract the latest sent user message and
257
+ completed assistant message.
258
+
259
+ Flow transcript lookup is bound to the exact user prompt sent to the session,
260
+ then assistant extraction starts after that prompt. That prevents one active
261
+ agent from accidentally relaying another agent's newer log.
262
+
100
263
  ### CLI Aliases
101
264
 
102
265
  | Short | Full | Short | Full |
@@ -104,7 +267,7 @@ p stop
104
267
  | n/new | spawn | w/wrap | wrap |
105
268
  | s | send | k | kill |
106
269
  | c/cap | capture | l/ls | list |
107
- | a | attach | r/rm | remove |
270
+ | a | attach | v | view |
108
271
  | st | status | mv/ren | rename |
109
272
  | i | info | d | daemon |
110
273
  | cfg | config | x | stop |
@@ -167,6 +330,49 @@ for (const name of agents) {
167
330
  mgr.destroyAll();
168
331
  ```
169
332
 
333
+ ## Telegram Remote Control
334
+
335
+ Drive your sessions from Telegram — check on agents, capture output, send input,
336
+ and get notified when a task needs you, all from your phone.
337
+
338
+ Set two env vars before starting the daemon:
339
+
340
+ ```
341
+ export TELEGRAM_BOT_TOKEN=<token from @BotFather>
342
+ export TELEGRAM_CHAT_ID=<your chat id>
343
+ p daemon
344
+ ```
345
+
346
+ When `TELEGRAM_BOT_TOKEN` is set, the daemon starts a bot poller automatically.
347
+ Only messages from `TELEGRAM_CHAT_ID` are honored. Bot commands:
348
+
349
+ | Command | Description |
350
+ |---------|-------------|
351
+ | `/list` (`/ls`) | List sessions |
352
+ | `/capture <name> [lines]` (`/cap`, `/c`) | Capture output (defaults to last used session) |
353
+ | `/send <name> <text>` (`/s`) | Send text + enter, then auto-capture once the session settles |
354
+ | `/kill <name>` (`/k`) | Kill a session |
355
+ | `/spawn <name> [cmd]` (`/n`) | Spawn a session |
356
+ | `/status` | Daemon info |
357
+ | `/help` (`/start`) | List commands |
358
+
359
+ `/capture` and `/send` remember the last session you touched, so you can omit
360
+ the name on follow-ups.
361
+
362
+ From inside a session (or a script), push notifications the other direction with
363
+ the `tg` command:
364
+
365
+ ```
366
+ p tg "build finished, needs review" # fire-and-forget notification
367
+ p tg "approve deploy? (y/n)" --reply # block until you reply, print it
368
+ p tg "still there?" --reply --timeout 120 # wait up to 120s (default 60)
369
+ ```
370
+
371
+ `--reply` blocks the caller until you answer in Telegram and prints your reply to
372
+ stdout — useful for human-in-the-loop gates inside an agent flow. The `tg` sender
373
+ uses `PTY_MGR_SESSION` (set automatically in wrapped/managed sessions) to tag
374
+ which session is asking.
375
+
170
376
  ## Daemon Protocol
171
377
 
172
378
  The daemon listens on a Unix socket at `~/.pty-manager/<name>.sock`.
@@ -177,9 +383,17 @@ Communication is newline-delimited JSON:
177
383
  {"cmd": "wrap", "args": {"cmd": "zsh", "cwd": "/Users/you/dev/myproject"}}
178
384
  {"cmd": "send", "name": "agent-1", "args": {"text": "echo hi\r"}}
179
385
  {"cmd": "capture", "name": "agent-1", "args": {"lines": 20}}
386
+ {"cmd": "resize", "name": "agent-1", "args": {"cols": 120, "rows": 40}}
180
387
  {"cmd": "list"}
388
+ {"cmd": "info", "name": "agent-1"}
389
+ {"cmd": "alive", "name": "agent-1"}
390
+ {"cmd": "status"}
391
+ {"cmd": "config", "args": {"key": "screen", "value": "120x40"}}
392
+ {"cmd": "log", "name": "agent-1", "args": {"action": "on", "format": "jsonl"}}
181
393
  {"cmd": "kill", "name": "agent-1"}
394
+ {"cmd": "remove", "name": "agent-1"}
182
395
  {"cmd": "rename", "name": "agent-1", "args": {"newName": "agent-refactored"}}
396
+ {"cmd": "tg-send", "args": {"message": "done"}}
183
397
  {"cmd": "shutdown"}
184
398
  ```
185
399
 
@@ -189,10 +403,15 @@ interactive use.
189
403
  ## Configuration
190
404
 
191
405
  ```
406
+ p status # daemon info + current config
407
+ p config # show current config
192
408
  p config screen 120x40 # default terminal size for new sessions
193
409
  p config cap-on-send on # return capture with every send command
410
+ p config send-delay 500 # ms to wait before the trailing enter (default 1000)
194
411
  ```
195
412
 
413
+ Config persists in the daemon and applies to new sessions.
414
+
196
415
  ## Logging
197
416
 
198
417
  ```