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.
- package/README.md +33 -5
- package/bin/agentp +226 -47
- package/bin/ocmux +431 -76
- package/docs/specification_v2.md +43 -2
- package/lib/project-state.js +8 -0
- package/package.json +1 -1
package/docs/specification_v2.md
CHANGED
|
@@ -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
|
|
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;
|
|
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
|
|
package/lib/project-state.js
CHANGED
|
@@ -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);
|