@bojackduy/opencode-loopd 1.10.5 → 1.12.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -6,6 +6,8 @@
6
6
 
7
7
  ### Added
8
8
 
9
+ - **Unified same-goal identity switching** — `switch_goal_identity` replaces the separate model/agent owner tools and control operations. Optional `model` and `agent` fields support one-field changes or a combined transaction; at least one is required. Combined assignments persist atomically, busy pairs defer together, and successful host changes roll back on partial failure. Dashboard `:model`/`:agent` dispatch the unified operation. The existing goal, worker session, transcript, progress, checks and budgets are preserved; there is no implicit interactive wake. Explicit resume requires a blocked goal (model-only still requires a provider-limit blocker).
10
+ - **Agent model discovery and same-goal recovery** — `loopd_list_models` exposes safe provider/model metadata, host capabilities, and owner-scoped goal identities; `switch_goal_identity` validates ownership/availability, defers busy workers, and preserves the existing worker session and budgets. Optional `fallbackModels` prepares ordered, one-shot alternatives only for observed provider quota/rate-limit errors; interactive goals never auto-wake. Remaining quota/reset information is **unknown/unsupported** in the inspected host APIs, never inferred from connected accounts or API keys. Covered by automated host/service/tool tests; no live provider-exhaustion or TUI proof claimed.
9
11
  - **M1 pty parity** — `env` (values to host, names-only persistence), `timeout_seconds` (in-memory deadline → terminate path, `endReason=timeout`, always notifies), `shell:true` (`/bin/sh -c`), `pattern`+`ignore_case` log read (ANSI-stripped match, ReDoS guard), `terminate remove:true`, `endReason` (`exit|terminate|timeout|until|missing`) on every terminal transition.
10
12
  - **M2 sentinel watcher engine** — `watch_filter`/`watch_until`/`watch_ignore_case`/`watch_until_action (stop|keep)` at start, `loopd_command_watch` on running commands; 2s coalescing (20 lines/4KB), 100-lines/sec flood-suspend (process keeps running), 30-push budget; `until:stop` terminates with `endReason=until` and exactly one owner message; `loopd_command_await until:` wakes a goal once on match without stopping.
11
13
  - **M3 surface** — watch badges + endReason in Commands tab, watch counters in detail panel, SKILL.md watching guide with pty + sentinel migration tables, de-polled `loopd_command_get` docs.
package/README.md CHANGED
@@ -21,6 +21,9 @@
21
21
  - **Safe by default** — per-goal artifact isolation (`.opencode/loopd/goals/<id>/`), `maxTurns`/`maxFailures`/`maxNoProgress`, force-finish → semantic `complete_goal` summary → parent notification via wake-up injection.
22
22
  - **Scheduled intervals** — `scheduleEveryMs`/`scheduleMaxRuns` auto-requeues the same goal every N ms (e.g., `10s` monitor, `1h` report) without manual `/goal` spam — `5s` poll, `skip-if-running`, `workspaceWrite` serialization, inbox `Scheduled tick N/M`.
23
23
  - **Modal TUI dashboard** — `<leader>o` or `/loop` opens a focused dialog (no leak to chat prompt). Vim-style navigation, live running indicator, per-status borders.
24
+ - **Command sessions, not blocked shells** — run installs, builds, dev servers, and REPLs as background OS processes with a fullscreen terminal, owner exit notifications, line-level `filter`/`until` watches, and timeouts — instead of freezing the agent turn in `bash`.
25
+ - **Switch identity mid-run** — `loopd_list_models` discovers models and agents; `switch_goal_identity` changes a goal's model, agent, or both on the *same* worker/session. Combined changes persist atomically and roll back on partial failure. Optional ordered `fallbackModels` switch automatically on 429s. Dashboard: `:model`/`:agent` and `:models`/`:agents`.
26
+ - **Manual mode for interactive work** — `interactive: true` (or `:interactive`) stops the engine from starting turns on its own; every turn comes from your `:send`/nudge. For tasks where the worker waits for input.
24
27
 
25
28
  Keywords: `opencode` `opencode-plugin` `background-agent` `autonomous` `subagent` `loop` `goal` `tui` `codex` `claude-code` `worker`
26
29
 
@@ -151,7 +154,9 @@ Dashboard (NORMAL / INSERT `:`) — shared Goals/Commands tabs:
151
154
  - `o` — goals: open child session (native OpenCode view) · commands: close
152
155
  popup, open fullscreen terminal page (route `opencode.loopd.terminal`)
153
156
  - `p/r/R/x` — pause / resume / retry / clear selected goal (Goals tab only)
154
- - Commands tab: `:new <command> [args...]` launch · `:interrupt` ·
157
+ - `c` — toggle finished on both tabs (completed goals · exited/terminated/missing commands)
158
+ - `:interactive` — toggle manual mode (engine never starts turns) · `:model <provider/model>` — switch goal's model · `:models` — provider/model inventory
159
+ - Commands tab: `X` force-kill · `R` restart · `x` remove finished · `:new <command> [args...]` launch · `:interrupt` ·
155
160
  `:terminate` · `:remove` · bare text + Enter writes stdin (owner-scoped)
156
161
  - `:` — insert mode → `:send <message>` to steer, `:force` / `:block` to finish manually
157
162
  - `?` — toggle help — help stays open while you type
@@ -174,6 +179,9 @@ inspect_background_goal() — full detail: objective, progress, blocker,
174
179
  read_goal_transcript() — last N worker messages (what it's doing)
175
180
  send_goal_input(goalID, msg) — steer: "skip appendix PDFs"
176
181
  pause_goal(goalID) / resume / clear
182
+ loopd_list_models() — providers/models, quota status (unknown where hosts can't report it)
183
+ switch_goal_identity({goal_id, model?, agent?}) — same goal, new identity (same worker/session; at least one field required)
184
+ loopd_command_start(...) — installs/builds/servers as background processes (never block the turn in bash)
177
185
  ```
178
186
 
179
187
  ### 4. Worker tools (child session)
@@ -260,6 +268,8 @@ Goals accept:
260
268
  | `checkCwd` | artifact directory | Directory where completion checks run; workspace writes default to project root |
261
269
  | `workspaceWrite` | `true` | Marks shared-workspace mutation; only one active workspace writer is allowed. Set `false` explicitly for artifact-only/read-only work |
262
270
  | `agent` | `defaultAgent` | Worker agent; goal creation fails if neither is configured nor supplied |
271
+ | `interactive` | `false` | Manual mode: engine never starts turns (`:send`/nudge only). For workers that wait for input |
272
+ | `fallbackModels` | `[]` | Ordered `provider/model` alternatives tried on quota/rate-limit errors only. Empty = no automatic switch |
263
273
  | `progressFile` | `<artifactDir>/progress.md` | Transaction state file |
264
274
  | `artifactDir` | `goals/<id>/` | Auto — override only if objective names another dir |
265
275
 
@@ -293,6 +303,19 @@ loopd_create_goal({
293
303
 
294
304
  Without schedule you’d send `/goal` 3× manually; with schedule one creation covers `monitor deploy`, `periodic tests`, `keep going until done`.
295
305
 
306
+ ## Switch models without losing the worker
307
+
308
+ When a provider hits quota or rate limits mid-run:
309
+
310
+ ```
311
+ loopd_list_models() — what's connected, quota status (or honestly unknown)
312
+ switch_goal_identity({goal_id, model:"other-provider/good-model"}) — same goal, same worker/session, transcript kept
313
+ ```
314
+
315
+ - Busy workers defer the switch to the next turn (`→ pending … applies next turn`); idle ones switch immediately. On v1 the new model takes effect from the next prompt (no mid-stream session switch API); v2 switches the live session where supported, else reports `unsupported` without touching anything.
316
+ - `fallbackModels: ["b/model", "c/model"]` at creation tries alternatives automatically — quota/429 errors only, each once, never looping. Interactive goals record the fallback but never auto-wake; you steer the next turn.
317
+ - Dashboard: `:model <provider/model>` and `:models` do the same for humans.
318
+
296
319
  ## Dashboard tips
297
320
 
298
321
  - Press `:` then type bare text → sent as `send_goal_input` to the selected goal.