agentp 2.0.0 → 2.0.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.
@@ -80,6 +80,7 @@ Placed at the **project root** (found by upward search, git-like).
80
80
  | `session` | yes (written) | OpenCode session ID to target. May be absent until first `ocmux serve`/`agentp` run. |
81
81
  | `server` | no | Cached shared-server URL. **Not authoritative** — the global server state wins. Kept for self-containment/offline diagnostics. |
82
82
  | `annotations` | no | Map `sessionID → reminder text` (the picker's `R` key). Prepended by `agentp` to every prompt for that session. |
83
+ | `broadcast` | no | Multi-session target (the picker's `Space` key): array of session IDs. When ≥2, `agentp` sends the prompt to all of them (waiting for idle). |
83
84
 
84
85
  **Legacy tolerance (read):** old files `{url, logfile, window_index}` must still
85
86
  parse. On read:
@@ -165,10 +166,48 @@ Retained flags: `--git`, `--GIT`, `-l`, `--print-logs`, `--version`, `-h`.
165
166
  - `Enter`/`Space` switches to the row but **stays open**; `n` creates (name
166
167
  input, blank = auto-title); `r` renames; `R` (Shift+r) sets a reminder;
167
168
  `d` deletes (y/N); `a` switches agent; `m` switches model; `p` opens the
168
- project switcher; `h` toggles help; `q`/`Ctrl+C` quits
169
+ project switcher; `h` toggles help; `q` quits (only here — see below)
170
+ - **Menu exit rule**: `q`/`ESC` only *close the current menu and return to the
171
+ previous one* in every menu except the session picker itself; **`Ctrl+C`
172
+ fully exits `ocmux` from any menu** (help, input/confirm prompts, pickers,
173
+ broadcast).
174
+ - **`/` incremental search** (session picker, model/agent pickers and project
175
+ switcher): typing filters the list live (case-insensitive; whitespace
176
+ tokens are ANDed), the inverted bottom line shows `Search: <pattern>▏`, and
177
+ its right end shows `Enter: confirm · Esc: cancel`. `Enter` keeps the filter
178
+ and returns to normal navigation, `ESC` clears it, `/` resumes editing it,
179
+ arrows still move through the filtered view, and `Backspace` on an
180
+ already-empty search also exits it.
181
+ - **Broadcast (`Space`)**: only `Enter` switches. `Space` over a *different*
182
+ session enters broadcast mode: `Space` toggles each session (selection
183
+ persists to `.ocmux.json` `broadcast`), `Enter` keeps the selection and
184
+ switches to the cursor session, `ESC`/`q` cancels and returns to the
185
+ session list with the TUI back on the stored session. **Each newly selected
186
+ session is opened in the TUI window** (so you can inspect what is going on
187
+ in it before deciding); deselecting does not switch back — except
188
+ **deselecting down to a single session ends broadcast mode by selecting
189
+ that remaining session**.
190
+ `h` opens broadcast-specific help, `d` deletes the cursor session with
191
+ confirmation, and `m` applies a selected model to **all** broadcast
192
+ sessions. The footer shows only `Broadcast to sessions: <names>`
193
+ while selecting. `agentp` then sends the prompt to **all** selected
194
+ sessions,
195
+ waiting for each to become idle first; if the broadcast is cancelled before
196
+ every session answers, the received responses are printed plus a
197
+ detailed "not completed" list (session name/id, error, timestamp).
198
+ Deferred broadcast tickets carry `sessionIds` (not a misleading single
199
+ `sessionId`) and preserve the target list for the detached child even if
200
+ `.ocmux.json` changes later.
169
201
  - an **inverted footer** with the key hints, plus info lines about the
170
202
  selected session (title, location, and a responsive grid of model, agent,
171
203
  status + time in status, tokens, cost, context limit, outcome).
204
+ - only **main** sessions are listed — child/subagent sessions (`parentID`
205
+ set, e.g. old `@explore`/`@general` runs) are hidden: OpenCode's TUI
206
+ defaults those to a "Subagents" tab, so they are not offered as targets
207
+ (`ocmux session <id>` / `agentp --session` can still reach one explicitly).
208
+ - **new sessions inherit the model of the previously selected session**
209
+ (falling back to the server default) — API-created v2 sessions have no
210
+ model and won't run a prompt until one is set.
172
211
  5. If **not** a TTY: focus the window and print the selected session ID on
173
212
  stdout (non-interactive).
174
213
 
@@ -180,7 +219,9 @@ URL). `agentp` does not depend on this.
180
219
  - Lists every tmux window in the `Opencode` session that has a `.ocmux.json`
181
220
  (project windows), plus their selected session.
182
221
  - Highlights the tmux-active window (live `activeWindowIndex()`).
183
- - `Enter`/`Space` focuses a window and keeps the menu open; `q` quits.
222
+ - `Enter`/`Space` focuses a window and keeps the menu open; `/` searches
223
+ (same incremental filter as §4.2); `h` toggles help; `q` closes the switcher
224
+ and returns to the session picker; `Ctrl+C` fully exits.
184
225
  - **Must never write `.ocmux.json`.** The dead-TUI restart path may *read* the
185
226
  state file, but only to know which session to relaunch with.
186
227
 
@@ -60,6 +60,9 @@ function normalizeState(raw, statefile) {
60
60
  const annotations = state.annotations && typeof state.annotations === 'object' && !Array.isArray(state.annotations)
61
61
  ? state.annotations
62
62
  : {};
63
+ const broadcast = Array.isArray(state.broadcast)
64
+ ? state.broadcast.filter(x => typeof x === 'string' && x)
65
+ : null;
63
66
  return {
64
67
  file: statefile,
65
68
  version: typeof state.version === 'number' ? state.version : 1,
@@ -68,6 +71,7 @@ function normalizeState(raw, statefile) {
68
71
  server,
69
72
  status,
70
73
  annotations,
74
+ broadcast,
71
75
  };
72
76
  }
73
77
 
@@ -109,6 +113,10 @@ function writeProjectState(statefile, patch) {
109
113
  if (patch.session !== undefined) next.session = patch.session;
110
114
  if (patch.server !== undefined) next.server = patch.server;
111
115
  if (patch.status !== undefined) next.status = patch.status;
116
+ if (patch.broadcast !== undefined) {
117
+ if (Array.isArray(patch.broadcast) && patch.broadcast.length >= 2) next.broadcast = [...patch.broadcast];
118
+ else delete next.broadcast;
119
+ }
112
120
  const tmp = statefile + '.tmp';
113
121
  fs.writeFileSync(tmp, JSON.stringify(next) + '\n');
114
122
  fs.renameSync(tmp, statefile);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentp",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
4
4
  "description": "Pipe prompts into a running OpenCode TUI session and stream the final answer",
5
5
  "bin": {
6
6
  "agentp": "bin/agentp",