iosm-cli 0.2.0 → 0.2.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.
Files changed (111) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/README.md +64 -52
  3. package/dist/core/agent-teams.d.ts.map +1 -1
  4. package/dist/core/agent-teams.js +38 -11
  5. package/dist/core/agent-teams.js.map +1 -1
  6. package/dist/core/failure-retrospective.d.ts +12 -0
  7. package/dist/core/failure-retrospective.d.ts.map +1 -0
  8. package/dist/core/failure-retrospective.js +115 -0
  9. package/dist/core/failure-retrospective.js.map +1 -0
  10. package/dist/core/model-registry.d.ts.map +1 -1
  11. package/dist/core/model-registry.js +2 -3
  12. package/dist/core/model-registry.js.map +1 -1
  13. package/dist/core/models-dev-provider-catalog.d.ts +30 -0
  14. package/dist/core/models-dev-provider-catalog.d.ts.map +1 -0
  15. package/dist/core/models-dev-provider-catalog.js +118 -0
  16. package/dist/core/models-dev-provider-catalog.js.map +1 -0
  17. package/dist/core/models-dev-providers.d.ts +12 -0
  18. package/dist/core/models-dev-providers.d.ts.map +1 -0
  19. package/dist/core/models-dev-providers.js +736 -0
  20. package/dist/core/models-dev-providers.js.map +1 -0
  21. package/dist/core/project-index/index.d.ts +17 -0
  22. package/dist/core/project-index/index.d.ts.map +1 -0
  23. package/dist/core/project-index/index.js +323 -0
  24. package/dist/core/project-index/index.js.map +1 -0
  25. package/dist/core/project-index/types.d.ts +34 -0
  26. package/dist/core/project-index/types.d.ts.map +1 -0
  27. package/dist/core/project-index/types.js +2 -0
  28. package/dist/core/project-index/types.js.map +1 -0
  29. package/dist/core/sdk.d.ts.map +1 -1
  30. package/dist/core/sdk.js +8 -0
  31. package/dist/core/sdk.js.map +1 -1
  32. package/dist/core/shared-memory.d.ts +46 -0
  33. package/dist/core/shared-memory.d.ts.map +1 -0
  34. package/dist/core/shared-memory.js +253 -0
  35. package/dist/core/shared-memory.js.map +1 -0
  36. package/dist/core/slash-commands.d.ts.map +1 -1
  37. package/dist/core/slash-commands.js +5 -1
  38. package/dist/core/slash-commands.js.map +1 -1
  39. package/dist/core/subagents.js +1 -1
  40. package/dist/core/subagents.js.map +1 -1
  41. package/dist/core/swarm/gates.d.ts +9 -0
  42. package/dist/core/swarm/gates.d.ts.map +1 -0
  43. package/dist/core/swarm/gates.js +65 -0
  44. package/dist/core/swarm/gates.js.map +1 -0
  45. package/dist/core/swarm/index.d.ts +9 -0
  46. package/dist/core/swarm/index.d.ts.map +1 -0
  47. package/dist/core/swarm/index.js +9 -0
  48. package/dist/core/swarm/index.js.map +1 -0
  49. package/dist/core/swarm/locks.d.ts +21 -0
  50. package/dist/core/swarm/locks.d.ts.map +1 -0
  51. package/dist/core/swarm/locks.js +93 -0
  52. package/dist/core/swarm/locks.js.map +1 -0
  53. package/dist/core/swarm/planner.d.ts +16 -0
  54. package/dist/core/swarm/planner.d.ts.map +1 -0
  55. package/dist/core/swarm/planner.js +137 -0
  56. package/dist/core/swarm/planner.js.map +1 -0
  57. package/dist/core/swarm/retry.d.ts +16 -0
  58. package/dist/core/swarm/retry.d.ts.map +1 -0
  59. package/dist/core/swarm/retry.js +32 -0
  60. package/dist/core/swarm/retry.js.map +1 -0
  61. package/dist/core/swarm/scheduler.d.ts +48 -0
  62. package/dist/core/swarm/scheduler.d.ts.map +1 -0
  63. package/dist/core/swarm/scheduler.js +554 -0
  64. package/dist/core/swarm/scheduler.js.map +1 -0
  65. package/dist/core/swarm/spawn.d.ts +16 -0
  66. package/dist/core/swarm/spawn.d.ts.map +1 -0
  67. package/dist/core/swarm/spawn.js +42 -0
  68. package/dist/core/swarm/spawn.js.map +1 -0
  69. package/dist/core/swarm/state-store.d.ts +35 -0
  70. package/dist/core/swarm/state-store.d.ts.map +1 -0
  71. package/dist/core/swarm/state-store.js +106 -0
  72. package/dist/core/swarm/state-store.js.map +1 -0
  73. package/dist/core/swarm/types.d.ts +116 -0
  74. package/dist/core/swarm/types.d.ts.map +1 -0
  75. package/dist/core/swarm/types.js +2 -0
  76. package/dist/core/swarm/types.js.map +1 -0
  77. package/dist/core/system-prompt.d.ts.map +1 -1
  78. package/dist/core/system-prompt.js +3 -2
  79. package/dist/core/system-prompt.js.map +1 -1
  80. package/dist/core/tools/shared-memory.d.ts +23 -0
  81. package/dist/core/tools/shared-memory.d.ts.map +1 -0
  82. package/dist/core/tools/shared-memory.js +134 -0
  83. package/dist/core/tools/shared-memory.js.map +1 -0
  84. package/dist/core/tools/task.d.ts +8 -1
  85. package/dist/core/tools/task.d.ts.map +1 -1
  86. package/dist/core/tools/task.js +664 -123
  87. package/dist/core/tools/task.js.map +1 -1
  88. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  89. package/dist/modes/interactive/components/footer.js +3 -11
  90. package/dist/modes/interactive/components/footer.js.map +1 -1
  91. package/dist/modes/interactive/components/login-dialog.d.ts +1 -0
  92. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  93. package/dist/modes/interactive/components/login-dialog.js +27 -4
  94. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  95. package/dist/modes/interactive/components/oauth-selector.d.ts +13 -1
  96. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  97. package/dist/modes/interactive/components/oauth-selector.js +89 -27
  98. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  99. package/dist/modes/interactive/components/subagent-message.d.ts.map +1 -1
  100. package/dist/modes/interactive/components/subagent-message.js +14 -0
  101. package/dist/modes/interactive/components/subagent-message.js.map +1 -1
  102. package/dist/modes/interactive/interactive-mode.d.ts +50 -0
  103. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  104. package/dist/modes/interactive/interactive-mode.js +1594 -51
  105. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  106. package/docs/cli-reference.md +11 -1
  107. package/docs/configuration.md +4 -1
  108. package/docs/getting-started.md +2 -2
  109. package/docs/interactive-mode.md +43 -4
  110. package/docs/orchestration-and-subagents.md +96 -169
  111. package/package.json +5 -4
package/CHANGELOG.md CHANGED
@@ -9,6 +9,59 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
9
9
 
10
10
  _No unreleased changes._
11
11
 
12
+ ## [0.2.2] - 2026-03-11
13
+
14
+ ### Added
15
+
16
+ - **Models.dev provider+model catalog runtime** — added full catalog parsing (providers + models metadata) with timeout/fallback behavior for interactive auth/model flows
17
+ - **Automatic provider model hydration after `/login`** — when a provider has credentials but no built-in model definitions, `iosm-cli` now registers models from `models.dev` so `/model` is immediately usable (including coding-plan providers such as `zai-coding-plan`)
18
+ - **Startup/on-demand auth model hydration** — `/model` now attempts to hydrate missing models for saved authenticated providers before rendering provider/model choices
19
+
20
+ ### Changed
21
+
22
+ - **Provider/model visibility in status line** — footer and model-switch status now display `provider/model` to make cross-provider switches explicit even when model IDs are identical
23
+ - **Auth UX feedback** — login flow now reports a clear warning when credentials are stored but no models can be loaded yet
24
+
25
+ ### Fixed
26
+
27
+ - **API-key login crash** — fixed unbound registry method usage that caused `TypeError: Cannot read properties of undefined (reading 'models')` in interactive login flows
28
+ - **Empty model selector after provider login** — fixed cases where `/model` stayed empty after successful API-key auth for providers not shipped in the built-in registry
29
+
30
+ ### Documentation
31
+
32
+ - Updated README and docs (`getting-started`, `interactive-mode`, `configuration`) to reflect full models.dev-backed provider/model availability via `/login` and `/model`
33
+
34
+ ## [0.2.1] - 2026-03-11
35
+
36
+ ### Added
37
+
38
+ - **Run/task shared memory runtime** — introduced `.iosm/subagents/shared-memory/*.json` state with versioned entries and history for cross-task coordination
39
+ - **Shared memory tools** — added `shared_memory_write` and `shared_memory_read` tools for subagent orchestration (`run` and `task` scopes, CAS support, append/set modes)
40
+ - **Canonical `/swarm` command surface** — added dedicated runtime commands: `/swarm run`, `/swarm from-singular`, `/swarm watch`, `/swarm retry`, `/swarm resume` (with bounded parallelism and budget controls)
41
+ - **Swarm scheduler reliability modules** — added dedicated scheduler/locks/gates/state-store/spawn/retry components for stable multi-task dispatch under contention
42
+ - **Swarm lock + gate execution model** — introduced hierarchical touch locks and contract-aware task/run gates for `Scopes -> Touches -> Locks -> Gates -> Done`
43
+ - **Swarm runtime artifacts** — added persisted run state in `.iosm/orchestrate/<run-id>/` (`run.json`, `dag.json`, `state.json`, `events.jsonl`, checkpoints, reports)
44
+ - **Swarm watch telemetry** — added runtime visibility for ready/running/blocked/done distribution, budget usage, lock snapshot, ETA/throughput, critical path, and theoretical speedup
45
+ - **Swarm spawn policy controls** — added high-risk spawn candidate classification with confirmation-gated fan-out behavior
46
+ - **Project index subsystem** — introduced repository indexing (`.iosm/project-index/index.json`) for scale-aware planning and targeted file selection
47
+ - **Failure retrospective engine** — added failure-cause classification and retry directive generation for smarter follow-up attempts
48
+
49
+ ### Changed
50
+
51
+ - **Swarm-first orchestration flow** — `/singular` execution handoff now supports `Start with Swarm (Recommended)` and routes selected options to `/swarm from-singular ...`
52
+ - **Command separation** — `/orchestrate --swarm` removed; `/swarm` is now the canonical gated runtime while `/orchestrate` remains manual legacy team splitting
53
+ - **Task orchestration contract** — `task` tool/runtime now carries richer run/task metadata and improved scheduling context for delegated execution
54
+ - **Interactive swarm observability** — expanded interactive mode status/watch output with deeper swarm runtime diagnostics and task progress details
55
+
56
+ ### Fixed
57
+
58
+ - **Swarm retry stability** — improved retry bucket handling (`permission`, `dependency/import`, `test`, `timeout`, `unknown`) to reduce noisy re-runs
59
+ - **Lock/contention handling** — improved execution behavior for conflicting touches and blocked tasks in DAG scheduling scenarios
60
+
61
+ ### Documentation
62
+
63
+ - Expanded README, CLI reference, interactive mode, and orchestration docs for swarm runtime semantics, shared-memory collaboration, and reliability controls
64
+
12
65
  ## [0.2.0] - 2026-03-11
13
66
 
14
67
  ### Added
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- <h1 align="center">IOSM CLI v0.2.0</h1>
1
+ <h1 align="center">IOSM CLI v0.2.2</h1>
2
2
 
3
3
  <p align="center">
4
4
  <strong>AI Engineering Runtime for Professional Developers</strong>
@@ -26,7 +26,7 @@
26
26
  It is a runtime for production codebases:
27
27
  - a terminal-native coding agent with direct filesystem and shell tooling
28
28
  - primary operating profiles: **full** (default) and **iosm** (advanced, methodology-driven engineering cycles)
29
- - smart orchestration for complex tasks: parallel/sequential agents, dependency ordering, lock coordination, and worktree isolation
29
+ - swarm-first orchestration for complex tasks: `Scopes -> Touches -> Locks -> Gates -> Done`, continuous dispatch, retries, checkpoints
30
30
  - built-in semantic embeddings search (`semantic_search` tool + `/semantic` + `iosm semantic`)
31
31
  - repeatable codebase improvement workflows via **IOSM** (Improve -> Optimize -> Shrink -> Modularize)
32
32
  - auditable artifact history for cycles, decisions, and metric evolution across runs
@@ -78,6 +78,7 @@ iosm --version
78
78
  Requirements:
79
79
  - Node.js `>=20.6.0`
80
80
  - provider auth (environment variable API key and/or `/login`)
81
+ - `/login` now includes the full `models.dev` provider catalog; `/model` loads available models for authenticated providers
81
82
 
82
83
  ### Recommended CLI Toolchain (for maximum efficiency)
83
84
 
@@ -118,8 +119,8 @@ iosm
118
119
 
119
120
  Inside the session (full profile):
120
121
  ```text
121
- /login # or /auth: configure credentials
122
- /model # select active model
122
+ /login # or /auth: configure credentials (OAuth + API key providers from models.dev)
123
+ /model # select active provider/model from currently authenticated providers
123
124
  <your task> # start working immediately
124
125
  ```
125
126
 
@@ -131,30 +132,28 @@ Shift+Tab # switch profile to iosm
131
132
  ```
132
133
 
133
134
  Core commands to unlock full runtime value:
134
- - `/orchestrate` run parallel/sequential subagents with dependencies, locks, and optional worktrees
135
+ - direct prompt to main agent default for simple tasks (single-agent flow)
136
+ - `/orchestrate` — manual legacy multi-agent orchestration (explicit team-run control)
137
+ - `/swarm` — recommended multi-agent orchestration runtime for complex/risky changes (`run`, `from-singular`, `watch`, `retry`, `resume`)
135
138
  - `/init` + `/iosm` — execute measurable IOSM cycles with artifacts and quality gates
136
139
  - `/mcp` — connect external tool ecosystems in interactive UI
137
140
  - `/semantic` — configure semantic provider, build/rebuild embeddings index, run meaning-based retrieval
138
141
  - `/memory` — persist project facts and constraints across sessions
139
142
 
140
- ## Real-World Example: Agent-Orchestrated IOSM Refactor
143
+ ## Real-World Example: Swarm-First IOSM Refactor
141
144
 
142
145
  ```console
143
146
  $ iosm
144
- IOSM CLI v0.2.0 [full]
147
+ IOSM CLI v0.2.2 [full]
145
148
 
146
- you> Refactor authentication module with parallel agents, then finalize in IOSM mode
147
- iosm> /orchestrate --parallel --agents 4 \
148
- --profiles iosm_analyst,explore,iosm_verifier,full \
149
- --depends 3>1,4>2 --locks schema,config --worktree \
150
- Refactor auth and reduce integration risk
151
- iosm> Team run started: #77
152
-
153
- iosm> agent[1] architecture map complete
154
- iosm> agent[2] implementation patch set prepared
155
- iosm> agent[3] verification suite and rollback checks ready
156
- iosm> agent[4] integration validation passed
157
- iosm> Consolidated patch plan generated
149
+ you> /singular Refactor auth and split session handling from token validation
150
+ iosm> Option 1 selected
151
+ iosm> Start with Swarm (Recommended)
152
+ iosm> /swarm from-singular 2026-03-10-210201 --option 1
153
+ iosm> Swarm run started: swarm_1741632000000_ab12cd
154
+ iosm> status: running (ready/running/blocked/done visible via /swarm watch)
155
+ iosm> Touches -> Locks -> Gates pipeline completed
156
+ iosm> integration report written to .iosm/orchestrate/swarm_1741632000000_ab12cd/reports/
158
157
 
159
158
  iosm> switch profile: iosm (Shift+Tab)
160
159
  iosm> /init
@@ -168,13 +167,10 @@ iosm> Result: simplicity +18%, modularity +11%, performance +6%
168
167
  iosm> Artifacts written to .iosm/cycles/2026-03-10-001/
169
168
  ```
170
169
 
171
- For broader tasks, delegate in parallel:
170
+ For plain-language execution without `/singular`:
172
171
 
173
172
  ```bash
174
- /orchestrate --parallel --agents 4 \
175
- --profiles iosm_analyst,explore,iosm_verifier,full \
176
- --depends 3>1,4>2 --locks schema,config --worktree \
177
- Refactor auth and reduce integration risk
173
+ /swarm run "Refactor auth and reduce integration risk" --max-parallel 3 --budget-usd 12
178
174
  ```
179
175
 
180
176
  ## Architecture Overview
@@ -182,7 +178,7 @@ For broader tasks, delegate in parallel:
182
178
  `IOSM CLI` is layered so execution stays controllable as task complexity grows:
183
179
 
184
180
  ```text
185
- Providers (OpenAI / Anthropic / OpenRouter / GitHub / Qwen)
181
+ Providers (built-ins + full models.dev catalog)
186
182
 
187
183
  Auth + Model Selection (/login, /model)
188
184
 
@@ -190,7 +186,7 @@ Agent Runtime (interactive + JSON + JSON-RPC + SDK)
190
186
 
191
187
  Tooling Layer (read/edit/bash + search/structural/data/security tools + MCP tools)
192
188
 
193
- Orchestration Engine (/orchestrate, subagents, dependencies, locks, worktrees)
189
+ Swarm Runtime (/swarm run|from-singular|watch|retry|resume)
194
190
 
195
191
  IOSM Layer (/init, /iosm cycles, metrics, governance)
196
192
 
@@ -199,8 +195,8 @@ Artifacts + Memory (.iosm/cycles/*, checkpoints, /memory state)
199
195
 
200
196
  ## Design Principles
201
197
 
202
- - **AI executes structured engineering loops, not ad hoc chats.** Core flow is orchestration + IOSM cycle execution (`/orchestrate` -> `/init` -> `/iosm`).
203
- - **Complex work needs orchestration.** Parallel agents, dependency ordering, locks, and optional worktree isolation reduce collision and blast radius.
198
+ - **AI executes structured engineering loops, not ad hoc chats.** Core flow for risky tasks is ` /singular -> /contract -> /swarm -> /iosm `.
199
+ - **Complex work needs controlled execution.** Swarm applies `Scopes -> Touches -> Locks -> Gates -> Done` with continuous dispatch and bounded retries.
204
200
  - **Refactoring must be measurable.** IOSM cycles capture baseline, hypotheses, and metric deltas instead of untracked edits.
205
201
  - **Every important run must be auditable.** Artifacts and memory preserve decisions and outcomes across sessions.
206
202
  - **Adoption should be progressive.** Start in `full` profile for speed; move to `iosm` profile for advanced cycles and governance when needed.
@@ -211,7 +207,7 @@ Artifacts + Memory (.iosm/cycles/*, checkpoints, /memory state)
211
207
 
212
208
  | Profile | Best For | What `/init` Does | Advanced Command |
213
209
  |------|----------|-------------------|------------------|
214
- | **full** (default) | Daily coding for any level | Generates/updates `AGENTS.md` from real repo scan and prepares `.iosm/agents/` | Use `/orchestrate` and built-in tools directly |
210
+ | **full** (default) | Daily coding for any level | Generates/updates `AGENTS.md` from real repo scan and prepares `.iosm/agents/` | Use `/swarm` (canonical) and built-in tools directly |
215
211
  | **iosm** (advanced) | High-risk refactors and system-level engineering loops | Bootstraps full IOSM workspace (`iosm.yaml`, `IOSM.md`, `.iosm/cycles/...`) with optional agent verification | `/iosm [target-index] [--max-iterations N] [--force-init]` |
216
212
 
217
213
  Typical advanced flow:
@@ -222,42 +218,57 @@ iosm --profile iosm
222
218
  /iosm 0.95 --max-iterations 5
223
219
  ```
224
220
 
225
- ## Smart Orchestration
226
-
227
- For complex work, use explicit multi-agent orchestration instead of one long monolithic prompt.
228
-
229
- `/orchestrate` supports:
230
- - parallel or sequential execution (`--parallel` / `--sequential`)
231
- - controlled concurrency (`--max-parallel`)
232
- - per-agent profiles and working directories (`--profiles`, `--cwd`)
233
- - dependency DAGs (`--depends 2>1,3>2`)
234
- - write safety (`--locks`) and optional git worktree isolation (`--worktree`)
221
+ ## Swarm-First Execution
222
+
223
+ For complex/risky work, use the canonical swarm runtime instead of one monolithic prompt.
224
+
225
+ Default routing rule:
226
+ - simple tasks -> direct prompt to one agent
227
+ - manual legacy multi-agent split -> `/orchestrate`
228
+ - complex/risky changes (multi-agent orchestration level) -> `/swarm`
229
+
230
+ `/swarm` supports:
231
+ - contract-bound execution (run blocks until effective `/contract` exists)
232
+ - run-level parallel workers via `--max-parallel` (1..20)
233
+ - continuous dispatch over DAG tasks (ready -> locks -> gates -> checkpoint)
234
+ - intra-task parallelism: one swarm task can fan out to delegated subagents (up to 10) when beneficial
235
+ - run-scoped shared memory (`shared_memory_write` / `shared_memory_read`) across tasks and delegates that share the same `run_id`
236
+ - standalone `task` executions auto-generate internal `run_id/task_id`, enabling shared memory for root + delegates without manual IDs
237
+ - hierarchical touches-based locking and lock downgrade
238
+ - task gates + run gates separation
239
+ - retries by taxonomy (`permission`, `dependency/import`, `test`, `timeout`, `unknown`)
240
+ - checkpoints/recovery (`/swarm resume`) and focused retries (`/swarm retry`)
241
+ - scheduler guards (`progress heuristic` + `conflict density guard`) for stable throughput under contention
242
+ - high-risk spawn candidates require explicit confirmation during run
235
243
 
236
244
  Example:
237
245
 
238
246
  ```bash
239
- /orchestrate --parallel --agents 4 \
240
- --profiles iosm_analyst,explore,iosm_verifier,full \
241
- --max-parallel 2 \
242
- --depends 3>1,4>2 \
243
- --locks schema,config \
244
- --worktree \
245
- Improve auth reliability and performance with verification gates
247
+ /swarm run "Improve auth reliability and performance with verification gates" \
248
+ --max-parallel 3 \
249
+ --budget-usd 15
246
250
  ```
247
251
 
248
- Track and resume delegated execution with `/subagent-runs`, `/subagent-resume`, `/team-runs`, and `/team-status`.
252
+ Bridge from decision mode:
253
+
254
+ ```bash
255
+ /singular "Refactor auth and split session handling from token validation"
256
+ # choose option -> Start with Swarm (Recommended)
257
+ ```
249
258
 
250
259
  ## Core Commands
251
260
 
252
261
  | Workflow Step | Command | Why It Matters |
253
262
  |------|---------|----------------|
254
263
  | Start clean context | `/new` or `/clear` | Reset session state before a new task or after context drift |
255
- | Configure auth | `/login` or `/auth` | Set provider credentials with guided flow |
256
- | Select active model | `/model` | Choose provider/model category for current workload |
257
- | Launch multi-agent execution | `/orchestrate ...` | Split complex tasks across agents with dependencies, locks, and optional worktrees |
264
+ | Configure auth | `/login` or `/auth` | Set OAuth/API key credentials with guided flow from full models.dev provider catalog |
265
+ | Select active model | `/model` | Choose provider/model from available authenticated providers |
266
+ | Launch controlled execution | `/swarm run ...` | Execute complex tasks with contract boundaries, locks, gates, retries, and checkpoints |
267
+ | Bridge decision to execution | `/swarm from-singular ...` | Apply selected `/singular` option under effective contract policy |
268
+ | Legacy orchestration | `/orchestrate --parallel ...` | Keep previous team-run flow when you explicitly need legacy semantics |
258
269
  | Initialize IOSM workspace | `/init` | Bootstrap/update IOSM files and cycle workspace |
259
270
  | Run IOSM cycle | `/iosm [target-index] [--max-iterations N]` | Execute measurable improve/verify loops with artifact output |
260
- | Track delegated runs | `/subagent-runs`, `/subagent-resume`, `/team-runs`, `/team-status` | Monitor and resume orchestration pipelines |
271
+ | Track swarm runs | `/swarm watch`, `/swarm resume`, `/swarm retry` | Observe state, resume checkpoints, and recover failed tasks |
261
272
  | Manage MCP servers | `/mcp` | Inspect/add/enable external tool servers interactively |
262
273
  | Manage semantic search | `/semantic` | Configure provider with auto model discovery (OpenRouter/Ollama), index codebase, query by intent/meaning |
263
274
  | Define engineering contract | `/contract` | Field-by-field interactive contract editor with auto-save and automatic JSON generation |
@@ -290,7 +301,8 @@ Key manager actions:
290
301
  - `Option 2`: alternative strategy with different trade-offs.
291
302
  - `Option 3`: defer/do-not-implement-now path.
292
303
  - Each option includes affected files, step-by-step plan, risks, and when-to-choose guidance.
293
- - User selects `1/2/3` (or exits) before coding starts.
304
+ - User selects `1/2/3`, then chooses `Start with Swarm` or `Continue without Swarm`.
305
+ - `Start with Swarm` executes selected option via `/swarm from-singular ...` under effective `/contract`.
294
306
 
295
307
  Legacy note:
296
308
  - `/blast` and `/shadow` are removed from active workflow.
@@ -1 +1 @@
1
- {"version":3,"file":"agent-teams.d.ts","sourceRoot":"","sources":["../../src/core/agent-teams.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,WAAW,CAAC;AAEpF,MAAM,WAAW,cAAc;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,EAAE,cAAc,CAAC;CACvB;AAED,MAAM,WAAW,aAAa;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,UAAU,GAAG,YAAY,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,cAAc,EAAE,CAAC;CACxB;AAUD,wBAAgB,aAAa,CAAC,KAAK,EAAE;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,UAAU,GAAG,YAAY,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;CAC5F,GAAG,aAAa,CA2BhB;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAQhF;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,aAAa,EAAE,CAkBrE;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE;IAC3C,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,cAAc,CAAC;CACvB,GAAG,aAAa,GAAG,SAAS,CAsB5B"}
1
+ {"version":3,"file":"agent-teams.d.ts","sourceRoot":"","sources":["../../src/core/agent-teams.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,WAAW,CAAC;AAEpF,MAAM,WAAW,cAAc;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,EAAE,cAAc,CAAC;CACvB;AAED,MAAM,WAAW,aAAa;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,UAAU,GAAG,YAAY,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,cAAc,EAAE,CAAC;CACxB;AAeD,wBAAgB,aAAa,CAAC,KAAK,EAAE;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,UAAU,GAAG,YAAY,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;CAC5F,GAAG,aAAa,CA2BhB;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAQhF;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,aAAa,EAAE,CAkBrE;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE;IAC3C,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,cAAc,CAAC;CACvB,GAAG,aAAa,GAAG,SAAS,CAwC5B"}
@@ -1,11 +1,16 @@
1
1
  import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from "node:fs";
2
2
  import { join } from "node:path";
3
+ import lockfile from "proper-lockfile";
3
4
  function getTeamsDir(cwd) {
4
5
  return join(cwd, ".iosm", "subagents", "teams");
5
6
  }
6
7
  function getTeamRunPath(cwd, runId) {
7
8
  return join(getTeamsDir(cwd), `${runId}.json`);
8
9
  }
10
+ function sleepSync(ms) {
11
+ const waiter = new Int32Array(new SharedArrayBuffer(4));
12
+ Atomics.wait(waiter, 0, 0, ms);
13
+ }
9
14
  export function createTeamRun(input) {
10
15
  const runId = `team_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`;
11
16
  const tasks = input.assignments.map((assignment, index) => {
@@ -67,24 +72,46 @@ export function listTeamRuns(cwd, limit = 20) {
67
72
  return runs;
68
73
  }
69
74
  export function updateTeamTaskStatus(input) {
70
- const existing = getTeamRun(input.cwd, input.runId);
71
- if (!existing)
72
- return undefined;
73
- const nextTasks = existing.tasks.map((task) => task.id === input.taskId ? { ...task, status: input.status } : task);
74
- if (!nextTasks.some((task) => task.id === input.taskId)) {
75
+ const runPath = getTeamRunPath(input.cwd, input.runId);
76
+ if (!existsSync(runPath))
75
77
  return undefined;
76
- }
77
- const next = {
78
- ...existing,
79
- tasks: nextTasks,
80
- };
78
+ let release;
81
79
  try {
82
80
  mkdirSync(getTeamsDir(input.cwd), { recursive: true });
83
- writeFileSync(getTeamRunPath(input.cwd, input.runId), JSON.stringify(next, null, 2), "utf8");
81
+ const maxLockAttempts = 12;
82
+ for (let attempt = 1; attempt <= maxLockAttempts; attempt += 1) {
83
+ try {
84
+ release = lockfile.lockSync(runPath, { realpath: false });
85
+ break;
86
+ }
87
+ catch (error) {
88
+ const code = error && typeof error === "object" && "code" in error ? String(error.code) : "";
89
+ if (code !== "ELOCKED" || attempt === maxLockAttempts) {
90
+ return undefined;
91
+ }
92
+ sleepSync(Math.min(120, 10 + attempt * 10));
93
+ }
94
+ }
95
+ if (!release)
96
+ return undefined;
97
+ const raw = readFileSync(runPath, "utf8");
98
+ const existing = JSON.parse(raw);
99
+ const nextTasks = existing.tasks.map((task) => task.id === input.taskId ? { ...task, status: input.status } : task);
100
+ if (!nextTasks.some((task) => task.id === input.taskId)) {
101
+ return undefined;
102
+ }
103
+ const next = {
104
+ ...existing,
105
+ tasks: nextTasks,
106
+ };
107
+ writeFileSync(runPath, JSON.stringify(next, null, 2), "utf8");
84
108
  return next;
85
109
  }
86
110
  catch {
87
111
  return undefined;
88
112
  }
113
+ finally {
114
+ release?.();
115
+ }
89
116
  }
90
117
  //# sourceMappingURL=agent-teams.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"agent-teams.js","sourceRoot":"","sources":["../../src/core/agent-teams.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nexport type TeamTaskStatus = \"pending\" | \"running\" | \"done\" | \"error\" | \"cancelled\";\n\nexport interface TeamTaskRecord {\n\tid: string;\n\tagentIndex: number;\n\tprofile: string;\n\tcwd: string;\n\tlockKey?: string;\n\tdependsOn: string[];\n\tstatus: TeamTaskStatus;\n}\n\nexport interface TeamRunRecord {\n\trunId: string;\n\tcreatedAt: string;\n\tmode: \"parallel\" | \"sequential\";\n\tagents: number;\n\tmaxParallel?: number;\n\ttask: string;\n\ttasks: TeamTaskRecord[];\n}\n\nfunction getTeamsDir(cwd: string): string {\n\treturn join(cwd, \".iosm\", \"subagents\", \"teams\");\n}\n\nfunction getTeamRunPath(cwd: string, runId: string): string {\n\treturn join(getTeamsDir(cwd), `${runId}.json`);\n}\n\nexport function createTeamRun(input: {\n\tcwd: string;\n\tmode: \"parallel\" | \"sequential\";\n\tagents: number;\n\tmaxParallel?: number;\n\ttask: string;\n\tassignments: Array<{ profile: string; cwd: string; lockKey?: string; dependsOn: number[] }>;\n}): TeamRunRecord {\n\tconst runId = `team_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`;\n\tconst tasks: TeamTaskRecord[] = input.assignments.map((assignment, index) => {\n\t\tconst id = `task_${index + 1}`;\n\t\tconst dependsOn = assignment.dependsOn.map((dep) => `task_${dep}`);\n\t\treturn {\n\t\t\tid,\n\t\t\tagentIndex: index + 1,\n\t\t\tprofile: assignment.profile,\n\t\t\tcwd: assignment.cwd,\n\t\t\tlockKey: assignment.lockKey,\n\t\t\tdependsOn,\n\t\t\tstatus: \"pending\",\n\t\t};\n\t});\n\tconst record: TeamRunRecord = {\n\t\trunId,\n\t\tcreatedAt: new Date().toISOString(),\n\t\tmode: input.mode,\n\t\tagents: input.agents,\n\t\tmaxParallel: input.maxParallel,\n\t\ttask: input.task,\n\t\ttasks,\n\t};\n\tmkdirSync(getTeamsDir(input.cwd), { recursive: true });\n\twriteFileSync(getTeamRunPath(input.cwd, runId), JSON.stringify(record, null, 2), \"utf8\");\n\treturn record;\n}\n\nexport function getTeamRun(cwd: string, runId: string): TeamRunRecord | undefined {\n\tconst path = getTeamRunPath(cwd, runId);\n\tif (!existsSync(path)) return undefined;\n\ttry {\n\t\treturn JSON.parse(readFileSync(path, \"utf8\")) as TeamRunRecord;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nexport function listTeamRuns(cwd: string, limit = 20): TeamRunRecord[] {\n\tconst dir = getTeamsDir(cwd);\n\tif (!existsSync(dir)) return [];\n\tconst names = readdirSync(dir)\n\t\t.filter((name) => name.toLowerCase().endsWith(\".json\"))\n\t\t.sort()\n\t\t.reverse()\n\t\t.slice(0, Math.max(1, limit));\n\tconst runs: TeamRunRecord[] = [];\n\tfor (const name of names) {\n\t\ttry {\n\t\t\tconst parsed = JSON.parse(readFileSync(join(dir, name), \"utf8\")) as TeamRunRecord;\n\t\t\truns.push(parsed);\n\t\t} catch {\n\t\t\t// ignore malformed files\n\t\t}\n\t}\n\treturn runs;\n}\n\nexport function updateTeamTaskStatus(input: {\n\tcwd: string;\n\trunId: string;\n\ttaskId: string;\n\tstatus: TeamTaskStatus;\n}): TeamRunRecord | undefined {\n\tconst existing = getTeamRun(input.cwd, input.runId);\n\tif (!existing) return undefined;\n\n\tconst nextTasks = existing.tasks.map((task) =>\n\t\ttask.id === input.taskId ? { ...task, status: input.status } : task,\n\t);\n\tif (!nextTasks.some((task) => task.id === input.taskId)) {\n\t\treturn undefined;\n\t}\n\n\tconst next: TeamRunRecord = {\n\t\t...existing,\n\t\ttasks: nextTasks,\n\t};\n\ttry {\n\t\tmkdirSync(getTeamsDir(input.cwd), { recursive: true });\n\t\twriteFileSync(getTeamRunPath(input.cwd, input.runId), JSON.stringify(next, null, 2), \"utf8\");\n\t\treturn next;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n"]}
1
+ {"version":3,"file":"agent-teams.js","sourceRoot":"","sources":["../../src/core/agent-teams.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport lockfile from \"proper-lockfile\";\n\nexport type TeamTaskStatus = \"pending\" | \"running\" | \"done\" | \"error\" | \"cancelled\";\n\nexport interface TeamTaskRecord {\n\tid: string;\n\tagentIndex: number;\n\tprofile: string;\n\tcwd: string;\n\tlockKey?: string;\n\tdependsOn: string[];\n\tstatus: TeamTaskStatus;\n}\n\nexport interface TeamRunRecord {\n\trunId: string;\n\tcreatedAt: string;\n\tmode: \"parallel\" | \"sequential\";\n\tagents: number;\n\tmaxParallel?: number;\n\ttask: string;\n\ttasks: TeamTaskRecord[];\n}\n\nfunction getTeamsDir(cwd: string): string {\n\treturn join(cwd, \".iosm\", \"subagents\", \"teams\");\n}\n\nfunction getTeamRunPath(cwd: string, runId: string): string {\n\treturn join(getTeamsDir(cwd), `${runId}.json`);\n}\n\nfunction sleepSync(ms: number): void {\n\tconst waiter = new Int32Array(new SharedArrayBuffer(4));\n\tAtomics.wait(waiter, 0, 0, ms);\n}\n\nexport function createTeamRun(input: {\n\tcwd: string;\n\tmode: \"parallel\" | \"sequential\";\n\tagents: number;\n\tmaxParallel?: number;\n\ttask: string;\n\tassignments: Array<{ profile: string; cwd: string; lockKey?: string; dependsOn: number[] }>;\n}): TeamRunRecord {\n\tconst runId = `team_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`;\n\tconst tasks: TeamTaskRecord[] = input.assignments.map((assignment, index) => {\n\t\tconst id = `task_${index + 1}`;\n\t\tconst dependsOn = assignment.dependsOn.map((dep) => `task_${dep}`);\n\t\treturn {\n\t\t\tid,\n\t\t\tagentIndex: index + 1,\n\t\t\tprofile: assignment.profile,\n\t\t\tcwd: assignment.cwd,\n\t\t\tlockKey: assignment.lockKey,\n\t\t\tdependsOn,\n\t\t\tstatus: \"pending\",\n\t\t};\n\t});\n\tconst record: TeamRunRecord = {\n\t\trunId,\n\t\tcreatedAt: new Date().toISOString(),\n\t\tmode: input.mode,\n\t\tagents: input.agents,\n\t\tmaxParallel: input.maxParallel,\n\t\ttask: input.task,\n\t\ttasks,\n\t};\n\tmkdirSync(getTeamsDir(input.cwd), { recursive: true });\n\twriteFileSync(getTeamRunPath(input.cwd, runId), JSON.stringify(record, null, 2), \"utf8\");\n\treturn record;\n}\n\nexport function getTeamRun(cwd: string, runId: string): TeamRunRecord | undefined {\n\tconst path = getTeamRunPath(cwd, runId);\n\tif (!existsSync(path)) return undefined;\n\ttry {\n\t\treturn JSON.parse(readFileSync(path, \"utf8\")) as TeamRunRecord;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nexport function listTeamRuns(cwd: string, limit = 20): TeamRunRecord[] {\n\tconst dir = getTeamsDir(cwd);\n\tif (!existsSync(dir)) return [];\n\tconst names = readdirSync(dir)\n\t\t.filter((name) => name.toLowerCase().endsWith(\".json\"))\n\t\t.sort()\n\t\t.reverse()\n\t\t.slice(0, Math.max(1, limit));\n\tconst runs: TeamRunRecord[] = [];\n\tfor (const name of names) {\n\t\ttry {\n\t\t\tconst parsed = JSON.parse(readFileSync(join(dir, name), \"utf8\")) as TeamRunRecord;\n\t\t\truns.push(parsed);\n\t\t} catch {\n\t\t\t// ignore malformed files\n\t\t}\n\t}\n\treturn runs;\n}\n\nexport function updateTeamTaskStatus(input: {\n\tcwd: string;\n\trunId: string;\n\ttaskId: string;\n\tstatus: TeamTaskStatus;\n}): TeamRunRecord | undefined {\n\tconst runPath = getTeamRunPath(input.cwd, input.runId);\n\tif (!existsSync(runPath)) return undefined;\n\tlet release: (() => void) | undefined;\n\ttry {\n\t\tmkdirSync(getTeamsDir(input.cwd), { recursive: true });\n\t\tconst maxLockAttempts = 12;\n\t\tfor (let attempt = 1; attempt <= maxLockAttempts; attempt += 1) {\n\t\t\ttry {\n\t\t\t\trelease = lockfile.lockSync(runPath, { realpath: false });\n\t\t\t\tbreak;\n\t\t\t} catch (error) {\n\t\t\t\tconst code = error && typeof error === \"object\" && \"code\" in error ? String(error.code) : \"\";\n\t\t\t\tif (code !== \"ELOCKED\" || attempt === maxLockAttempts) {\n\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\t\t\t\tsleepSync(Math.min(120, 10 + attempt * 10));\n\t\t\t}\n\t\t}\n\t\tif (!release) return undefined;\n\t\tconst raw = readFileSync(runPath, \"utf8\");\n\t\tconst existing = JSON.parse(raw) as TeamRunRecord;\n\t\tconst nextTasks = existing.tasks.map((task) =>\n\t\t\ttask.id === input.taskId ? { ...task, status: input.status } : task,\n\t\t);\n\t\tif (!nextTasks.some((task) => task.id === input.taskId)) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst next: TeamRunRecord = {\n\t\t\t...existing,\n\t\t\ttasks: nextTasks,\n\t\t};\n\t\twriteFileSync(runPath, JSON.stringify(next, null, 2), \"utf8\");\n\t\treturn next;\n\t} catch {\n\t\treturn undefined;\n\t} finally {\n\t\trelease?.();\n\t}\n}\n"]}
@@ -0,0 +1,12 @@
1
+ export type FailureCause = "token_limit" | "logic_error" | "aborted" | "timeout" | "dependency_env" | "empty_output" | "unknown";
2
+ export declare function classifyFailureCause(errorMessage: string): FailureCause;
3
+ export declare function isRetrospectiveRetryable(cause: FailureCause): boolean;
4
+ export declare function buildRetrospectiveDirective(input: {
5
+ cause: FailureCause;
6
+ errorMessage: string;
7
+ attempt: number;
8
+ target: "root" | "delegate";
9
+ }): string;
10
+ export declare function formatFailureCauseCounts(counts: Partial<Record<FailureCause, number>>): string;
11
+ export declare function dominantFailureCause(counts: Partial<Record<FailureCause, number>>): FailureCause | undefined;
12
+ //# sourceMappingURL=failure-retrospective.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"failure-retrospective.d.ts","sourceRoot":"","sources":["../../src/core/failure-retrospective.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GACrB,aAAa,GACb,aAAa,GACb,SAAS,GACT,SAAS,GACT,gBAAgB,GAChB,cAAc,GACd,SAAS,CAAC;AAYb,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG,YAAY,CAUvE;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAErE;AAgDD,wBAAgB,2BAA2B,CAAC,KAAK,EAAE;IAClD,KAAK,EAAE,YAAY,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,GAAG,UAAU,CAAC;CAC5B,GAAG,MAAM,CAYT;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,GAAG,MAAM,CAe9F;AAED,wBAAgB,oBAAoB,CACnC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,GAC3C,YAAY,GAAG,SAAS,CAY1B"}
@@ -0,0 +1,115 @@
1
+ const tokenLimitPattern = /(token limit|max(?:imum)? tokens?|too many tokens?|context length|context window|prompt is too long|input too long|length exceeded)/i;
2
+ const logicPattern = /(logic|invariant|assert(?:ion)?|expect\(|failed assumption|incorrect result|wrong output|invalid state|regression|failed dependency)/i;
3
+ const abortPattern = /(operation aborted|aborted|signal aborted)/i;
4
+ const timeoutPattern = /(timeout|timed out|deadline exceeded|took too long|hang(?:ing)?)/i;
5
+ const dependencyPattern = /(module not found|cannot find module|dependency|package|importerror|missing dependency|command not found|enoent|env(?:ironment)?)/i;
6
+ const emptyOutputPattern = /(empty output|no output|returned empty)/i;
7
+ export function classifyFailureCause(errorMessage) {
8
+ const message = errorMessage.trim();
9
+ if (!message)
10
+ return "unknown";
11
+ if (emptyOutputPattern.test(message))
12
+ return "empty_output";
13
+ if (tokenLimitPattern.test(message))
14
+ return "token_limit";
15
+ if (abortPattern.test(message))
16
+ return "aborted";
17
+ if (timeoutPattern.test(message))
18
+ return "timeout";
19
+ if (dependencyPattern.test(message))
20
+ return "dependency_env";
21
+ if (logicPattern.test(message))
22
+ return "logic_error";
23
+ return "unknown";
24
+ }
25
+ export function isRetrospectiveRetryable(cause) {
26
+ return cause !== "empty_output" && cause !== "aborted";
27
+ }
28
+ function guidanceForCause(cause) {
29
+ switch (cause) {
30
+ case "token_limit":
31
+ return [
32
+ "- Narrow scope to only the minimum files/commands needed.",
33
+ "- Produce concise output (bullet points + critical diffs only).",
34
+ "- Avoid broad scans and repeated large reads.",
35
+ ];
36
+ case "logic_error":
37
+ return [
38
+ "- Diagnose why the prior approach failed before changing code.",
39
+ "- Use an alternative strategy, not a repeat of the same path.",
40
+ "- Prefer smallest verifiable step and validate assumptions explicitly.",
41
+ ];
42
+ case "aborted":
43
+ return [
44
+ "- Stop retries for this task execution; cancellation came from an external signal.",
45
+ "- Report cancellation context (where it happened and what was in progress).",
46
+ "- Resume only via an explicit new task/run request.",
47
+ ];
48
+ case "timeout":
49
+ return [
50
+ "- Split work into smaller bounded steps.",
51
+ "- Reduce expensive commands and long-running checks.",
52
+ "- Prioritize fast targeted verification first.",
53
+ ];
54
+ case "dependency_env":
55
+ return [
56
+ "- Verify environment/dependency preconditions first.",
57
+ "- Prefer deterministic remediation steps and minimal commands.",
58
+ "- If blocked by environment, report exact missing prerequisite.",
59
+ ];
60
+ case "empty_output":
61
+ return [
62
+ "- Ensure the response includes a concrete result summary.",
63
+ "- If still impossible, return a clear blocked reason.",
64
+ ];
65
+ default:
66
+ return [
67
+ "- Re-evaluate assumptions and reduce scope.",
68
+ "- Try a different implementation approach.",
69
+ "- Produce a concise, verifiable outcome.",
70
+ ];
71
+ }
72
+ }
73
+ export function buildRetrospectiveDirective(input) {
74
+ const guidance = guidanceForCause(input.cause).join("\n");
75
+ return [
76
+ "[RETROSPECTIVE_RETRY]",
77
+ `target: ${input.target}`,
78
+ `attempt: ${input.attempt}`,
79
+ `cause: ${input.cause}`,
80
+ `previous_error: ${input.errorMessage.replace(/\s+/g, " ").trim()}`,
81
+ "retry_policy:",
82
+ guidance,
83
+ "[/RETROSPECTIVE_RETRY]",
84
+ ].join("\n");
85
+ }
86
+ export function formatFailureCauseCounts(counts) {
87
+ const ordered = [
88
+ "token_limit",
89
+ "logic_error",
90
+ "aborted",
91
+ "timeout",
92
+ "dependency_env",
93
+ "empty_output",
94
+ "unknown",
95
+ ];
96
+ const parts = ordered
97
+ .map((cause) => ({ cause, count: counts[cause] ?? 0 }))
98
+ .filter((item) => item.count > 0)
99
+ .map((item) => `${item.cause}=${item.count}`);
100
+ return parts.join(", ");
101
+ }
102
+ export function dominantFailureCause(counts) {
103
+ const entries = Object.entries(counts);
104
+ let best;
105
+ let bestCount = 0;
106
+ for (const [cause, count] of entries) {
107
+ const normalized = count ?? 0;
108
+ if (normalized > bestCount) {
109
+ best = cause;
110
+ bestCount = normalized;
111
+ }
112
+ }
113
+ return best;
114
+ }
115
+ //# sourceMappingURL=failure-retrospective.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"failure-retrospective.js","sourceRoot":"","sources":["../../src/core/failure-retrospective.ts"],"names":[],"mappings":"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","sourcesContent":["export type FailureCause =\n\t| \"token_limit\"\n\t| \"logic_error\"\n\t| \"aborted\"\n\t| \"timeout\"\n\t| \"dependency_env\"\n\t| \"empty_output\"\n\t| \"unknown\";\n\nconst tokenLimitPattern =\n\t/(token limit|max(?:imum)? tokens?|too many tokens?|context length|context window|prompt is too long|input too long|length exceeded)/i;\nconst logicPattern =\n\t/(logic|invariant|assert(?:ion)?|expect\\(|failed assumption|incorrect result|wrong output|invalid state|regression|failed dependency)/i;\nconst abortPattern = /(operation aborted|aborted|signal aborted)/i;\nconst timeoutPattern = /(timeout|timed out|deadline exceeded|took too long|hang(?:ing)?)/i;\nconst dependencyPattern =\n\t/(module not found|cannot find module|dependency|package|importerror|missing dependency|command not found|enoent|env(?:ironment)?)/i;\nconst emptyOutputPattern = /(empty output|no output|returned empty)/i;\n\nexport function classifyFailureCause(errorMessage: string): FailureCause {\n\tconst message = errorMessage.trim();\n\tif (!message) return \"unknown\";\n\tif (emptyOutputPattern.test(message)) return \"empty_output\";\n\tif (tokenLimitPattern.test(message)) return \"token_limit\";\n\tif (abortPattern.test(message)) return \"aborted\";\n\tif (timeoutPattern.test(message)) return \"timeout\";\n\tif (dependencyPattern.test(message)) return \"dependency_env\";\n\tif (logicPattern.test(message)) return \"logic_error\";\n\treturn \"unknown\";\n}\n\nexport function isRetrospectiveRetryable(cause: FailureCause): boolean {\n\treturn cause !== \"empty_output\" && cause !== \"aborted\";\n}\n\nfunction guidanceForCause(cause: FailureCause): string[] {\n\tswitch (cause) {\n\t\tcase \"token_limit\":\n\t\t\treturn [\n\t\t\t\t\"- Narrow scope to only the minimum files/commands needed.\",\n\t\t\t\t\"- Produce concise output (bullet points + critical diffs only).\",\n\t\t\t\t\"- Avoid broad scans and repeated large reads.\",\n\t\t\t];\n\t\tcase \"logic_error\":\n\t\t\treturn [\n\t\t\t\t\"- Diagnose why the prior approach failed before changing code.\",\n\t\t\t\t\"- Use an alternative strategy, not a repeat of the same path.\",\n\t\t\t\t\"- Prefer smallest verifiable step and validate assumptions explicitly.\",\n\t\t\t];\n\t\tcase \"aborted\":\n\t\t\treturn [\n\t\t\t\t\"- Stop retries for this task execution; cancellation came from an external signal.\",\n\t\t\t\t\"- Report cancellation context (where it happened and what was in progress).\",\n\t\t\t\t\"- Resume only via an explicit new task/run request.\",\n\t\t\t];\n\t\tcase \"timeout\":\n\t\t\treturn [\n\t\t\t\t\"- Split work into smaller bounded steps.\",\n\t\t\t\t\"- Reduce expensive commands and long-running checks.\",\n\t\t\t\t\"- Prioritize fast targeted verification first.\",\n\t\t\t];\n\t\tcase \"dependency_env\":\n\t\t\treturn [\n\t\t\t\t\"- Verify environment/dependency preconditions first.\",\n\t\t\t\t\"- Prefer deterministic remediation steps and minimal commands.\",\n\t\t\t\t\"- If blocked by environment, report exact missing prerequisite.\",\n\t\t\t];\n\t\tcase \"empty_output\":\n\t\t\treturn [\n\t\t\t\t\"- Ensure the response includes a concrete result summary.\",\n\t\t\t\t\"- If still impossible, return a clear blocked reason.\",\n\t\t\t];\n\t\tdefault:\n\t\t\treturn [\n\t\t\t\t\"- Re-evaluate assumptions and reduce scope.\",\n\t\t\t\t\"- Try a different implementation approach.\",\n\t\t\t\t\"- Produce a concise, verifiable outcome.\",\n\t\t\t];\n\t}\n}\n\nexport function buildRetrospectiveDirective(input: {\n\tcause: FailureCause;\n\terrorMessage: string;\n\tattempt: number;\n\ttarget: \"root\" | \"delegate\";\n}): string {\n\tconst guidance = guidanceForCause(input.cause).join(\"\\n\");\n\treturn [\n\t\t\"[RETROSPECTIVE_RETRY]\",\n\t\t`target: ${input.target}`,\n\t\t`attempt: ${input.attempt}`,\n\t\t`cause: ${input.cause}`,\n\t\t`previous_error: ${input.errorMessage.replace(/\\s+/g, \" \").trim()}`,\n\t\t\"retry_policy:\",\n\t\tguidance,\n\t\t\"[/RETROSPECTIVE_RETRY]\",\n\t].join(\"\\n\");\n}\n\nexport function formatFailureCauseCounts(counts: Partial<Record<FailureCause, number>>): string {\n\tconst ordered: FailureCause[] = [\n\t\t\"token_limit\",\n\t\t\"logic_error\",\n\t\t\"aborted\",\n\t\t\"timeout\",\n\t\t\"dependency_env\",\n\t\t\"empty_output\",\n\t\t\"unknown\",\n\t];\n\tconst parts = ordered\n\t\t.map((cause) => ({ cause, count: counts[cause] ?? 0 }))\n\t\t.filter((item) => item.count > 0)\n\t\t.map((item) => `${item.cause}=${item.count}`);\n\treturn parts.join(\", \");\n}\n\nexport function dominantFailureCause(\n\tcounts: Partial<Record<FailureCause, number>>,\n): FailureCause | undefined {\n\tconst entries = Object.entries(counts) as Array<[FailureCause, number | undefined]>;\n\tlet best: FailureCause | undefined;\n\tlet bestCount = 0;\n\tfor (const [cause, count] of entries) {\n\t\tconst normalized = count ?? 0;\n\t\tif (normalized > bestCount) {\n\t\t\tbest = cause;\n\t\t\tbestCount = normalized;\n\t\t}\n\t}\n\treturn best;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"model-registry.d.ts","sourceRoot":"","sources":["../../src/core/model-registry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"model-registry.d.ts","sourceRoot":"","sources":["../../src/core/model-registry.ts"],"names":[],"mappings":"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"}
@@ -488,9 +488,8 @@ export class ModelRegistry {
488
488
  if (!config.baseUrl) {
489
489
  throw new Error(`Provider ${providerName}: "baseUrl" is required when defining models.`);
490
490
  }
491
- if (!config.apiKey && !config.oauth) {
492
- throw new Error(`Provider ${providerName}: "apiKey" or "oauth" is required when defining models.`);
493
- }
491
+ // Runtime-registered providers may rely on AuthStorage credentials only.
492
+ // models.json validation still enforces apiKey for file-based custom models.
494
493
  // Parse and add new models
495
494
  for (const modelDef of config.models) {
496
495
  const api = modelDef.api || config.api;