pi-squire 0.14.0 → 0.16.0

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 (62) hide show
  1. package/CHANGELOG.md +438 -1
  2. package/README.md +1062 -152
  3. package/package.json +4 -3
  4. package/src/agents.ts +395 -124
  5. package/src/child-tasks.ts +221 -0
  6. package/src/child.ts +107 -62
  7. package/src/completion-holds.ts +104 -0
  8. package/src/dashboard.ts +144 -0
  9. package/src/git.ts +6 -1
  10. package/src/identity.ts +152 -0
  11. package/src/index.ts +585 -107
  12. package/src/local-state.ts +21 -0
  13. package/src/navigator-view.ts +186 -0
  14. package/src/navigator.ts +152 -107
  15. package/src/new-delegate.ts +17 -8
  16. package/src/poll.ts +1 -0
  17. package/src/render.ts +4 -1
  18. package/src/result-close.ts +37 -0
  19. package/src/result-restore.ts +95 -0
  20. package/src/result-sessions.ts +39 -0
  21. package/src/result-types.ts +29 -1
  22. package/src/results-presentation.ts +47 -0
  23. package/src/results.ts +176 -108
  24. package/src/resume-checks.ts +59 -14
  25. package/src/resume-picker.ts +9 -2
  26. package/src/resume.ts +69 -15
  27. package/src/session-owner.ts +279 -0
  28. package/src/task-replies.ts +247 -0
  29. package/src/task-settlement.ts +81 -0
  30. package/src/task-store.ts +26 -0
  31. package/src/tmux.ts +134 -54
  32. package/src/tool-ceiling.ts +125 -0
  33. package/src/tracking.ts +72 -65
  34. package/src/tree-close.ts +236 -0
  35. package/src/tree-fence.ts +51 -0
  36. package/src/tree-lock.ts +77 -0
  37. package/src/tree-notice.ts +124 -0
  38. package/src/tree-registry.ts +365 -0
  39. package/src/tree-settings.ts +31 -0
  40. package/src/tree-types.ts +32 -0
  41. package/src/tree-view.ts +246 -0
  42. package/src/trust-control.ts +214 -0
  43. package/src/trust-prompt.ts +163 -0
  44. package/src/trust-wire.ts +203 -0
  45. package/src/widget-activity-join.ts +24 -0
  46. package/src/widget-activity-runtime.ts +104 -0
  47. package/src/widget-activity.ts +104 -0
  48. package/src/widget-ancestors.ts +142 -0
  49. package/src/widget-current.ts +41 -0
  50. package/src/widget-data.ts +147 -0
  51. package/src/widget-focus.ts +133 -0
  52. package/src/widget-live-process.ts +31 -0
  53. package/src/widget-live.ts +356 -0
  54. package/src/widget-render.ts +181 -0
  55. package/src/widget-selection.ts +58 -0
  56. package/src/widget-settings.ts +29 -0
  57. package/src/widget-summary.ts +51 -0
  58. package/src/widget-title-file.ts +127 -0
  59. package/src/widget-title.ts +118 -0
  60. package/src/widget.ts +272 -0
  61. package/src/window-placement.ts +30 -5
  62. package/src/workspace.ts +38 -90
package/CHANGELOG.md CHANGED
@@ -6,6 +6,429 @@ follows [Semantic Versioning](https://semver.org/).
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.16.0] - 2026-11-01
10
+
11
+ ### Breaking
12
+
13
+ - `delegation_close` now closes a persistent descendant subtree rather than one
14
+ local window. Its structured result adds `complete` and per-member outcomes;
15
+ partial failures return `isError:true` with details rather than discarding
16
+ successful members in a thrown tmux error. Close requires a readable shared
17
+ fence before kills. Old single-window wording/schema, direct-close-on-corrupt-
18
+ registry, panel/poll/placement text assertions deliberately change; local
19
+ genuine result publication remains warning-only. Unknown/foreign/obsolete
20
+ target ids refuse before effects. Canceling unfinished children now requires
21
+ direct-parent processing rather than silently releasing the task barrier.
22
+ - Delegations recorded without the required original-root placement identity
23
+ can no longer be resumed after this update, including pre-nesting and
24
+ identity-less records even when reopened by their original root. Resume tools,
25
+ commands and picker refuse before trust, mail, exited-window kill, reservation
26
+ or spawn effects. No legacy identity synthesis or migration is provided.
27
+ The subtree-close identity-less resume fixture now asserts this refusal when
28
+ composed with root placement; its earlier fallback expectation is superseded.
29
+
30
+ - Require pi-session-mail 0.6.0 or another provider of all four message hooks.
31
+ Upgrade mail and squire together: squire now owns delegate task settlement
32
+ through `message:reply`; mail no longer automatically answers task requests.
33
+
34
+ - Agent frontmatter now uses `auto_exit` (boolean, default true).
35
+ Old `auto-exit` and `extensions` fields are silently ignored, with no
36
+ warnings or validation. In particular, old `auto-exit: false` now leaves
37
+ auto-exit on unless `auto_exit` or a call override disables it.
38
+ Agent-specific extension path resolution and launch arguments are removed
39
+ for both launch and resume; normal Pi extension loading and `session:launch`
40
+ customization remain. CLI flags, commands, internal fields and environment
41
+ variables keep their names. Updated agent-file, auto-exit, delegate, real-Pi
42
+ tool-selection, resume and hook tests for this deliberate contract change.
43
+
44
+ ### Changed
45
+
46
+ - Complete branch-focused widget entry in the same dashboard: initial details
47
+ retain their Escape-to-compact-list behavior, while `b` opens only the selected
48
+ branch's descendant/resume history and worker details return to that list.
49
+ Overall `/delegates` stays scoped to the invoking session's whole subtree.
50
+ Root close-all remains explicitly all root subtrees, not only displayed rows.
51
+ - Dashboard switch/peek and `/delegate-open` now reuse positively verified
52
+ current pane/server/owner locators for reattached latest sessions, without
53
+ rewriting historical launch/result facts or changing close authority.
54
+ A lost or replaced current locator never falls back to an old still-open
55
+ window; peek captures the exact verified Pi pane. Details distinguish launch
56
+ and current windows and reflect native session titles and actual outcomes.
57
+ Verified live latest rows remain navigable even before historical disappearance
58
+ is polled. Closing live navigation rows confirms the separate durable control
59
+ scope; telemetry never retargets a kill, and reattached windows may remain open.
60
+ Post-switch ownership loss reports the completed switch honestly.
61
+ Add `test/navigator-current.test.ts`, extend `test/dashboard.test.ts` and
62
+ `test/widget-nesting-final.test.ts` for deliberate branch-list behavior,
63
+ current-window races, title composition and direct-parent resume refusal.
64
+ - Compose the shared widget/dashboard actions with context-aware subtree close:
65
+ selected close reports aggregate partial errors, and the root retains confirmed
66
+ `a` close-all from the same dashboard, including empty/history views. Keep
67
+ direct-widget activity/focus and direct-parent resume checks unchanged; no
68
+ second panel or row-by-row close authority. Add combined coverage in
69
+ `test/widget-nesting-final.test.ts` and root action intent coverage in
70
+ `test/dashboard.test.ts`; extend `test/dashboard-actions.test.ts` control stubs.
71
+ - Make the direct-delegate widget keyboard-navigable and reuse one dashboard for
72
+ widget Enter, `/delegates` and its shortcut. Down at an empty built-in prompt
73
+ selects children; stable selection scrolls through the cap. Enter opens details,
74
+ and Escape returns to list then prompt. Dashboard list Enter now opens details
75
+ before a second Enter switches (a deliberate navigation change); peek, close,
76
+ new and authorized resume remain behind existing action/ownership checks.
77
+ Custom editors, autocomplete, dialogs and unknown focus pass through unchanged.
78
+ The isolated Pi-internals adapter was tested with installed Pi 1.4.0 in both
79
+ regular and fullscreen modes; no Pi change or editor/footer replacement.
80
+ Protect the empty prompt while a widget-opened dashboard is loading or
81
+ re-listing between actions, without intercepting real dashboard/dialog input.
82
+ Update `test/navigator.test.ts` for the deliberate two-Enter details/switch
83
+ flow and `test/tree-restore.test.ts` to inspect metadata in details.
84
+ - The interactive direct-delegate overview deliberately replaces only Squire’s
85
+ running-count entry when its cap is positive, preserving custom footers/editors
86
+ and the own-delegate badge. Cap zero and non-TUI hosts retain the running count.
87
+
88
+ ### Added
89
+
90
+ - Nested delegate overview: root-to-parent ancestor rows with direct live-window
91
+ navigation, parent-first Down and cap-zero ancestor navigation plus the existing
92
+ direct-child count. Same-id reopens use owner-correlated current pane/server/
93
+ window metadata, independent of strict task activity launch correlation.
94
+ - All-depth descendant **task/launch-id** summaries beneath direct coordinator
95
+ rows, preserving failed/stopped/missing outcomes and failures across resumes.
96
+ Read-only semantic provenance and coverage keep registry accounting distinct
97
+ from actual replies; unknown/partial coverage is explicit. Summaries share one
98
+ secondary line with factual activity and take priority at narrow widths.
99
+ The former cap-zero empty-widget assertion deliberately changes for delegates;
100
+ async ancestor metadata tests now wait for the observable refreshed frame.
101
+ Corrupt descendant owner facts show unavailable counts without freezing fresh
102
+ ancestors/direct rows. Hidden/empty child views skip locator I/O, and unchanged
103
+ positive locator observations do not rewrite telemetry snapshots.
104
+ No task/control policy, result barrier, provider contract or second tree index.
105
+ - Factual live direct-delegate activity from actual concurrent/nested tool-call
106
+ ids and bounded assistant response text, propagated across Pi processes by
107
+ disposable owner-only snapshots. Launch correlation separates resumed tasks
108
+ from stable sessions; lifecycle cleanup and known task results/close clear
109
+ activity independently of task delivery. No thinking, tool results, inferred
110
+ intent/waits, extra model calls, counters or stale-state timer. Uncorrelated
111
+ manual reopen has no task-row activity. The common launcher now includes a
112
+ private stable-session/launch correlation environment value; launch-wire tests
113
+ deliberately account for this per-launch field.
114
+ - Live, passive direct-delegate overview in interactive Pi: running children
115
+ first, then finished-open children, newest within each group, with stable
116
+ session keys, mutable native titles and actual failure/stopped outcomes.
117
+ Native file-backed renames and unflushed title mirrors refresh without naming
118
+ tools or model calls. Responsive themed tree rows clamp narrow/wide text and
119
+ omit model then file-age metadata as space shrinks.
120
+ - `delegateWidgetPlacement` (above/below, default above) and
121
+ `delegateWidgetMaxEntries` (default three) in the existing Squire settings.
122
+ Independent observation continues after task completion and is cleaned up on
123
+ reload; no focus keys or tree accounting semantics change.
124
+
125
+ - Provider-neutral process-local completion holds: active exact-session Squire
126
+ runtimes advertise support in the versioned `pi.completion-holds.v1` data
127
+ table. External holds gate new final task replies, tree completion and
128
+ auto-exit until every current-session entry is ready. Host registrations are
129
+ runtime-owned and removed on every shutdown; provider holds survive reload
130
+ but are not durable across process restart.
131
+
132
+ - Synchronous `squire:identity` lifecycle notification with a frozen,
133
+ exact-session root/delegate/invalid observation, emitted after identity
134
+ restoration and persistence and before later asynchronous startup work.
135
+ Consumers can observe ordinary reopen and runtime replacement without
136
+ treating launch environment variables as identity authority.
137
+
138
+ - Explicit ancestor-scoped subtree close and root-only confirmed panel close-all.
139
+ Shared admission/own-entry dispatch fences precede effects, including root
140
+ reservations. Already-dispatched unknown creates remain charged/fenced and
141
+ partial; bounded explicit retries never guess no-start. Current verified
142
+ id+name locators include manually reattached same-id coordinators. Per-member
143
+ errors preserve successful closes; shared companions, branches and worktrees
144
+ are retained, and ordinary runtime exit never cascades.
145
+ - Confirmed closes are imported only by the direct-parent semantic owner as
146
+ durable canceled/missing child outcomes. Offline restoration and settlement
147
+ retain the processing barrier, root replay-stop behavior and genuine
148
+ mid-close/late worker replies. Completed fences allow a new authorized,
149
+ lifetime-counted direct-parent resume without reviving canceled descendants.
150
+ - Restore exact-session delegation trees without recreating live workers,
151
+ including offline child/coordinator replies, pending result processing and
152
+ concurrency for a manually reopened unfinished coordinator. Shared registry
153
+ ancestry drives descendant status/navigation; each direct parent's local
154
+ results/outcome inbox remains authoritative.
155
+ - Single Squire process owner per Pi identity, using the existing bakery lock.
156
+ Already-claimed Squire input is durably staged for the sole owner across
157
+ duplicate scans and delayed startup. Losing/stale runtimes cannot act or
158
+ clear a replacement token; ordinary parent exit never closes children.
159
+ - Bounded fresh-session notices explain reopening direct owners without
160
+ adoption: current agent/session directory, newest 64 registry files, at most
161
+ 10 owners, 1 MiB per tree, one 200 ms cooperative notice budget, and explicit
162
+ unavailable/truncated scope.
163
+ - Shared per-root tree registry and atomic cross-process launch reservations.
164
+ `maxConcurrentDelegates` and `maxDelegatesPerRoot` default to 16/64 with
165
+ maxDepth > 1, remain unlimited when absent at depth 1, and accept zero for
166
+ unlimited. Settings changes affect subsequent launches/resumes; refusals
167
+ report count/limit without queues or killing existing work. Resumes spend
168
+ new launches; completed open windows free concurrency, not lifetime count.
169
+ - Publish worker terminal accounting independently of the parent's process,
170
+ retaining 03's local result-processing authority and durable reply retries.
171
+ Preserve failed-versus-uncertain launch/resume handling, recover child window
172
+ locators after lost tmux responses, reconcile disappeared workers and retain
173
+ ambiguous reservations until positive evidence exists. Counts survive
174
+ ordinary root/coordinator restarts. Separate Node-process contention/crash
175
+ fixtures are reusable by the later subtree-close slice.
176
+
177
+ - Nested unresolved project trust goes directly to the attended root's squire,
178
+ outside model questions and task mail, with agent-chain, requester and
179
+ directory/source context. Root-local and remote prompts share a serialized
180
+ queue, including while the root is busy. Preserve scoped/source-worktree
181
+ resolution and explicit approval/denial flags on launch and resume.
182
+ - Bound ordinary trust requests to ten minutes including queue wait. Cancellation,
183
+ disconnect, expiry and either runtime's replacement stop the pending launch
184
+ and dismiss its question; late approvals and old requests after restart cannot
185
+ save trust or revive work. Persistent choices are saved only by a live
186
+ requester; launch-only choices remain unsaved. Unavailable/unattended roots
187
+ refuse without opening delegate UI. Squire uses owner-token loopback control,
188
+ without provider internals, permission inheritance or pending-request replay.
189
+ Deliberately replace the interim nested-trust refusal tests with root-choice
190
+ behavior, real-provider isolation and separate-process kill/restart coverage.
191
+ - Nested launch/resume tools are capped by the direct parent’s actually available
192
+ operations, including codemode/deferred and active model-only tools. Requested
193
+ patterns become exact registration grants after `session:launch` customization;
194
+ neither `delegateTools` nor hook-added extensions can widen them. Launch/resume
195
+ notices report removed tools and restricted patterns; top-level selection stays
196
+ unchanged. Real Pi 1.3 execution and isolated CLI launch/resume tests cover the
197
+ deliberate nested-only behavior.
198
+ - Complete nested-grant validation: false and empty lists grant none, malformed
199
+ values disable the agent, duplicates are removed, and unavailable child names
200
+ warn without disabling known entries. An agent with a permission map warns
201
+ when a listed child lacks one, including `true` grants over the current roster.
202
+ This heuristic does not compare policies or inherit permission authority;
203
+ tool restrictions and permission rules do not provide filesystem isolation.
204
+ - Unreleased nested-worker lifecycle: `maxDepth` (default 1), current-agent
205
+ `allow_nested_delegation` grants and bypass-resistant launch/resume admission,
206
+ including trusted project-agent shadowing. Coordinators get all four
207
+ delegation tools even with an explicit tools list; listing tools alone warns
208
+ and grants nothing. Nesting remains an incomplete integration milestone:
209
+ full integrated real-model and permission-forwarding validation remains required
210
+ before production use.
211
+ - Persist parent/root/depth/agent/chain identity and auto-exit state for manual
212
+ same-session reopening. Expose read-only parent/root/depth/frozen chain on
213
+ `session:launch`, alongside existing mutable args/env customization.
214
+ - Durable direct-child task completion and result-processing barrier. No
215
+ intermediate coordinator reply/exit while children run; out-of-order results
216
+ and rolling fan-out finish only after a later processing run settles. Results
217
+ arriving during final settlement force processing before completion.
218
+ Coordinators can recover after fallback exhaustion while workers run; their
219
+ final run determines success/failure. Confirmed disappearance produces the
220
+ existing missing-result outcome; unknown tmux state does not release work.
221
+ - Separate coordinator identity/auto-exit and running-child footer keys, retain
222
+ parent delegation guidance in coordinators, and keep trust questions out of
223
+ unattended UI. Update deliberate single-level-only
224
+ registration, hook shape, footer and persistence expectations in tests;
225
+ execute the expanded README hook example and real-mail multi-instance
226
+ lifecycle coverage.
227
+
228
+ ### Fixed
229
+
230
+ - Keep factual activity end/settlement observation live when Squire task-owner
231
+ processing fails or owner-record reads are unavailable, without granting action
232
+ authority. Check publication ownership only at startup, not on each text delta.
233
+ - Normalize process-start observation to C locale and UTC for live activity and
234
+ native-title mirrors, so differing parent/delegate time zones or locales do not
235
+ hide metadata or falsely delete a live activity snapshot.
236
+ - Preserve the original root project companion preference through nested
237
+ cross-project launches, same-id coordinator restarts without launch environment,
238
+ and direct-parent resumes while the root is absent. Save one `rootPlacement`
239
+ base in existing identity/local/shared tree records, keeping call-time
240
+ current/companion mode and marked/unmarked alternative selection separate.
241
+ Malformed or conflicting required placement identity fails closed; nested
242
+ parent-preference contradictions are refused before target trust resolution.
243
+ Identity-less resume refusal is declared above under Breaking; no relocation
244
+ or repair system is added.
245
+ Existing synthetic identity fixtures and full-identity assertions deliberately
246
+ include this required field. Add real-provider/Git cross-project coverage and
247
+ actual coordinator process shutdown/SIGKILL/reopen with root-absent resume.
248
+ - Incomplete transcript/child-identity restoration now fails closed for both
249
+ completion and admission, retains known own child obligations and refuses
250
+ incidental saves until repair/reopen. Foreign copied history stays excluded.
251
+ - Stage matching input atomically without waiting for a contended owner lock;
252
+ only the token owner drains, with callbacks outside that mutex. Preserve
253
+ timestamp/path order, avoid idle lock writes, and report unpersistable input
254
+ explicitly instead of silently falling through to plain mail. Ready owners
255
+ can use normal direct processing when staging alone is unwritable.
256
+ - Always run runtime shutdown cleanup after input/owner failures, closing old
257
+ trust controls/timers before replacement. Persist explicit root user stops
258
+ without automatic replay on reopen; fresh live results/gone outcomes still
259
+ wake normally and clear that replay hold. Ordinary crash recovery remains.
260
+ Root continuations use response wording rather than coordinator task reports.
261
+ - Ownership errors name the PID/file; discovery reports owner-read/tmux failures
262
+ once and shares one total latency budget. Document ordinary-mail/ask and
263
+ shared running-record consequences of duplicate provider processes.
264
+
265
+ - Restrict resume execution and picker authority to the original direct parent,
266
+ retaining root/depth, live-session/obsolete-chain protections and current
267
+ grants, caps, tool ceiling and trust resolver. Fork/clone copies are history,
268
+ not authority; inherited launch environment no longer assigns identity.
269
+ - Deliberately change the delegates panel to retain hierarchical history and
270
+ details rather than only open windows; only verified windows support
271
+ navigation. Descendant close stays with the separate explicit-close slice.
272
+ Reattachment tests now reopen the same id after shutdown rather than copying
273
+ starts into a fresh/live duplicate session. Root outcomes retain processing
274
+ durability with a non-displaying recovery wake instead of a repeated final.
275
+
276
+ - Keep durable local result/gone delivery, coordinator wakes and close tracking
277
+ working when shared fact publication fails; warn and reconcile those saved
278
+ facts at the next admission. Worker frozen-terminal publication remains
279
+ mandatory before transport. A confirmed window open stays successful and
280
+ locally tracked even if accounting publication fails, and refund failures
281
+ preserve the original tmux certainty/error. A refused concurrent resume no
282
+ longer releases another call\'s in-flight guard.
283
+ - Retain frozen answers when task context is unavailable rather than bypassing
284
+ terminal accounting, and skip failure-cleanup transactions after successful
285
+ resumes. Clarify malformed-settings behavior and unresolved-launch refusals.
286
+
287
+ - Refuse launches/resumes on malformed, unreadable or non-object shared squire
288
+ settings instead of silently losing configured cap limits. Deliberately
289
+ update window-placement/worktree-setting tests that previously allowed
290
+ inherited/cwd launches with an unreadable settings file; readable unrelated
291
+ creation settings still do not affect those launches.
292
+
293
+ - Preserve default leaf task guidance and takeover wording; only effective
294
+ coordinators receive child-first reporting instructions, including after a
295
+ current grant change. Refuse unhealthy durable child-task storage before
296
+ launch/resume effects rather than reporting failure after a child starts.
297
+ A task-wording lookup failure uses the original leaf wording before ownership
298
+ is recorded, so invalid depth configuration cannot strand an unprompted task;
299
+ launch admission still refuses invalid configuration.
300
+
301
+ - Persist owed delegate task answers and frozen reply retries across reload,
302
+ restart, resume and same-session manual reopening. Bounded startup retries
303
+ tolerate delayed mail initialization; remaining reply write failures are
304
+ visible and block auto-exit. Stops hold tasks through failed runs; successful
305
+ recovery, final failure, fallback and no-answer wording are preserved.
306
+ Updated `test/auto-exit.test.ts` for consumer-owned reply/exit behavior and
307
+ added real-provider task-reply and correlation regression coverage.
308
+ - Correlate every request id in a batched reply and suppress duplicate final
309
+ results even when a transport retry writes a fresh reply envelope.
310
+
311
+ ### Changed
312
+
313
+ - Default companion placement now groups delegate windows by the owning root
314
+ project's main-checkout basename (or root working-directory basename outside
315
+ Git), using `<project>-delegate-session`. Roots, same-named projects and
316
+ normalization collisions intentionally share managed companions without
317
+ sharing delegation ownership. Unmarked sessions are left untouched; numbered
318
+ alternatives are reused, including across parallel launches. Git inspection
319
+ failures report a basename fallback notice. Launch and resume use the root's
320
+ project even for cross-project tasks; `current` placement and delegate window
321
+ names are unchanged. Existing companions and live windows are not migrated.
322
+ Updated the tmux, window-placement, tools, navigator, delegate-render,
323
+ workspace, and worktree ticket 04/05 tests for the deliberate placement
324
+ behavior change; added project-companion and real-tmux regression coverage.
325
+ - Broken `.git` pointers now report Git state as unknown rather than as a
326
+ confirmed non-Git directory. This shared Git detection applies to workspace
327
+ records, status, snapshots and worktree-source errors, as well as companion
328
+ placement fallback notices.
329
+
330
+ ## [0.15.0] - 2026-10-30
331
+
332
+ ### Breaking
333
+
334
+ - Agents move to one file per agent in the agents folders Pi agent tooling
335
+ shares: `<agent dir>/agents/<name>.md` and, when the project is trusted,
336
+ `<cwd>/.pi/agents/<name>.md`, which replaces a global file of the same name.
337
+ `<agent dir>/squire/agents/<name>/AGENT.md` is no longer read; while that
338
+ folder exists, a warning says so. `squire/delegation_prompt.md` stays where
339
+ it is.
340
+ - The body is now wrapped in `<agent_instructions>` lines by default
341
+ (`prompt_mode: append`). `prompt_mode: replace` builds the delegate's prompt
342
+ exactly as before.
343
+ - `exclude-tools` is removed: a file that still has it gets a warning and the
344
+ field is ignored, so the delegate's tools follow the usual rules (its
345
+ `tools` line, or the parent session's active tools when there is none, plus
346
+ the `delegateTools` setting) with nothing taken off. List the delegate's
347
+ tools in `tools` instead.
348
+ - A `model` or `fallback` entry the model registry does not know is no longer
349
+ skipped for the next candidate: it goes to the child's `--model` unchanged,
350
+ and Pi reports it if it cannot resolve it.
351
+ - A delegate whose agent has no `tools` field now gets the parent session's
352
+ active tools when the launch or resume starts, passed as `--tools`, instead
353
+ of Pi's default tools. An empty `tools` field (`tools:` or `tools: []`) now
354
+ means no tools except the `delegateTools` setting, and `--no-tools` when that
355
+ is empty too; it used to mean the parent's tools.
356
+ - A delegate now gets exactly its selected tools, MCP tools included. Pi
357
+ kept every MCP tool registered, callable from `codemode` and loadable by
358
+ `tool_search`, unless a `--tools` entry started with `mcp__`; pi-squire now
359
+ adds the entry `mcp__`, which names no tool, to a list with no such entry,
360
+ so an MCP tool reaches a delegate only when its tools (or the parent's, for
361
+ an agent without `tools`) name or match it. Name a server's tools, such as
362
+ `mcp__docs__*`, to keep them. Tests changed with it: the argv tests in
363
+ `test/agent-files.test.ts`, `test/delegate.test.ts` and
364
+ `test/resume.test.ts` now expect the extra `mcp__` entry.
365
+ - Migration: move each `<agent dir>/squire/agents/<name>/AGENT.md` to
366
+ `<agent dir>/agents/<name>.md`; add `prompt_mode: replace` to keep today's
367
+ prompt; replace `exclude-tools: a, b` with a `tools` line naming the tools
368
+ the delegate should have.
369
+
370
+ ### Added
371
+
372
+ - An agent whose file is invalid is disabled: it is left out of the roster
373
+ and of the `delegate` tool's description, a warning names the file and the
374
+ reason when the session starts (and before a run, for a file that turns
375
+ invalid meanwhile), and a call or resume that names it is refused with that
376
+ reason instead of "no agent named".
377
+ - Every agent field is optional: `description` defaults to the name, an absent
378
+ `model` or `thinking` runs on the parent session's current model or level,
379
+ and an unknown `thinking` is dropped with a warning instead of leaving the
380
+ agent out. `model` and `fallback` entries may be aliases such as `sonnet`,
381
+ each resolving to one model; a `*` pattern makes the file invalid, so the
382
+ agent is disabled. A body may be empty.
383
+ - New agent fields: `display_name` (shown on the delegate card, in
384
+ `/delegates` and in the window title; it may hold only ASCII letters,
385
+ digits, `-` and `_`, and any other value, a space, `#`, `.`, a non-ASCII
386
+ letter or an empty value among them, makes the file invalid, so the agent is
387
+ disabled), `enabled: false` (leaves the agent
388
+ out; a project file hides a global agent of the same name), `locked` (`true`
389
+ or a list of `model` and `thinking`: a call or resume that passes a locked
390
+ field runs on the agent's value, and the result says which agent locked
391
+ which field; passing the agent's own value is the same as passing nothing,
392
+ so its fallbacks still apply; a resume runs a locked field on the file's
393
+ current value, not on what the delegate last ran on) and `prompt_mode`.
394
+ Keys pi-squire does not use, such as `max_turns` or another extension's
395
+ policy, are ignored without a warning.
396
+ - The `delegateTools` setting in `<agent dir>/squire/settings.json`: tool
397
+ names or `*` patterns added to every delegate's tools, from its agent's
398
+ `tools` or the parent's, for the tools a `message:*` provider gives a
399
+ delegate to reach its parent. Empty by default.
400
+ - A `tools` line of only `-name` entries (`tools: -bash, -write`) gives the
401
+ delegate the parent session's tools less those (a `-name` entry may be a `*`
402
+ pattern), then the `delegateTools` setting. A `+name` entry, or tool names
403
+ and `-name` entries mixed, make the agent file invalid, so the agent is
404
+ disabled. pi-squire always passes the child a plain `--tools` list.
405
+ - A `delegateTools` entry that starts with `+` or `-`, or holds a comma,
406
+ refuses every launch and resume with an error naming the settings file,
407
+ before the task is sent or a window opens.
408
+ - A `tools` or `fallback` YAML list entry holding a comma, such as
409
+ `tools: ["read,-bash"]`, makes the agent file invalid, so the agent is
410
+ disabled with a warning naming the file and the reason. A comma-separated
411
+ line (`tools: read, bash`) and a list of single names still work.
412
+ - A resume without `thinking`, for an agent that does not lock it, now runs
413
+ on the level the delegate last ran on, read from its session (the last
414
+ thinking-level change on the active branch, such as a change the user made
415
+ in the delegate's window or a clamp to a new model), instead of the level
416
+ recorded when the delegation started; the recorded level remains the
417
+ fallback when the session has none.
418
+ - A tool that only an agent's own `extensions` register reaches its delegate
419
+ only when the agent's `tools` list or the `delegateTools` setting names (or
420
+ matches) it. With no `tools` field, or only `-name` entries, the baseline
421
+ is the parent session's active tools alone; pi-squire never loads an
422
+ agent's extensions in the parent. (An unreleased change on this branch had
423
+ loaded them in the parent to add their tools to that baseline; its tests in
424
+ `test/agent-files.test.ts` and `test/pi-tools.test.ts` now pin this rule
425
+ instead.)
426
+ - A running delegate that hits a usage limit now resolves a `fallback` entry
427
+ that is an alias or bare id (such as `sonnet`) to one model with Pi's
428
+ `--model` resolver, in the listed order, instead of skipping every entry
429
+ that is not an exact `provider/id`. Each model is tried once, never the one
430
+ that just failed.
431
+
9
432
  ## [0.14.0] - 2026-10-27
10
433
 
11
434
  ### Removed
@@ -29,6 +452,18 @@ follows [Semantic Versioning](https://semver.org/).
29
452
  test that the poll runs only while a delegation does; `test/tmux.test.ts` no
30
453
  longer tests `popup` and `closePopup`, and `test/popup-parent.ts` and the
31
454
  fake's popup support are gone.
455
+ - Tests changed with the agent files: the harness writes `agents/<name>.md`
456
+ and the retired fixture to `squire/agents/<name>/AGENT.md`; prompt
457
+ assertions expect the `<agent_instructions>` wrapper; the roster, empty-roster
458
+ and malformed-file tests in `test/delegate.test.ts` and `test/tools.test.ts`
459
+ follow the optional fields and new location; the fallback render test skips
460
+ a model without credentials rather than an unknown one; the `display_name`
461
+ test names its agent `Code_Reviewer-2`, since a space is no longer accepted;
462
+ and `test/exclude-tools.test.ts` becomes `test/agent-files.test.ts`.
463
+ - Tests changed with tools inheritance: the test that pinned an empty `tools`
464
+ field as the parent's tools now pins it as no tools; the argv tests in
465
+ `test/delegate.test.ts` expect the parent's tools as `--tools`; and an
466
+ invalid `delegateTools` now refuses an agent without a `tools` field too.
32
467
 
33
468
  ## [0.13.1] - 2026-10-27
34
469
 
@@ -544,7 +979,9 @@ author's dotfiles; the changes below are against that copy.
544
979
 
545
980
  - The published file list includes `child.ts`, which `index.ts` imports.
546
981
 
547
- [Unreleased]: https://github.com/gvanderclay/pi-squire/compare/v0.14.0...HEAD
982
+ [Unreleased]: https://github.com/gvanderclay/pi-squire/compare/v0.16.0...HEAD
983
+ [0.16.0]: https://github.com/gvanderclay/pi-squire/compare/v0.15.0...v0.16.0
984
+ [0.15.0]: https://github.com/gvanderclay/pi-squire/compare/v0.14.0...v0.15.0
548
985
  [0.14.0]: https://github.com/gvanderclay/pi-squire/compare/v0.13.1...v0.14.0
549
986
  [0.13.1]: https://github.com/gvanderclay/pi-squire/compare/v0.13.0...v0.13.1
550
987
  [0.13.0]: https://github.com/gvanderclay/pi-squire/compare/v0.12.0...v0.13.0