@selesai/code 0.13.12 → 0.13.14

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 (203) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/dist/extensions/pi-subagents/CHANGELOG.md +77 -1
  3. package/dist/extensions/pi-subagents/VISION.md +12 -1
  4. package/dist/extensions/pi-subagents/docs/agents.md +13 -6
  5. package/dist/extensions/pi-subagents/docs/configuration.md +35 -9
  6. package/dist/extensions/pi-subagents/docs/extension-api.md +1 -1
  7. package/dist/extensions/pi-subagents/docs/missions.md +1 -1
  8. package/dist/extensions/pi-subagents/docs/models.md +6 -6
  9. package/dist/extensions/pi-subagents/docs/observability.md +6 -3
  10. package/dist/extensions/pi-subagents/docs/tool-reference.md +3 -3
  11. package/dist/extensions/pi-subagents/docs/watchdog.md +92 -114
  12. package/dist/extensions/pi-subagents/docs/workflows.md +1 -1
  13. package/dist/extensions/pi-subagents/install.mjs +1 -2
  14. package/dist/extensions/pi-subagents/package.json +1 -1
  15. package/dist/extensions/pi-subagents/skills/pi-subagents/references/constraints-and-recipes.md +1 -1
  16. package/dist/extensions/pi-subagents/skills/pi-subagents/references/execution-controls.md +6 -6
  17. package/dist/extensions/pi-subagents/skills/pi-subagents/references/management-authoring-rpc.md +2 -2
  18. package/dist/extensions/pi-subagents/skills/pi-subagents/references/multi-lane-orchestration.md +1 -1
  19. package/dist/extensions/pi-subagents/skills/pi-subagents/references/prompting-and-roles.md +4 -4
  20. package/dist/extensions/pi-subagents/skills/pi-subagents/references/review-and-validation.md +1 -1
  21. package/dist/extensions/pi-subagents/src/agents/agent-management.ts +41 -4
  22. package/dist/extensions/pi-subagents/src/agents/agent-serializer.ts +3 -0
  23. package/dist/extensions/pi-subagents/src/agents/agents.ts +120 -124
  24. package/dist/extensions/pi-subagents/src/agents/runtime-agent-registry.ts +5 -1
  25. package/dist/extensions/pi-subagents/src/api/preflight.ts +4 -0
  26. package/dist/extensions/pi-subagents/src/api/shared-types.ts +3 -0
  27. package/dist/extensions/pi-subagents/src/extension/config.ts +20 -0
  28. package/dist/extensions/pi-subagents/src/extension/public-execution.ts +1 -0
  29. package/dist/extensions/pi-subagents/src/extension/schemas.ts +6 -2
  30. package/dist/extensions/pi-subagents/src/extension/tool-description.ts +1 -1
  31. package/dist/extensions/pi-subagents/src/inspectors/herdr/inspector-runner.ts +19 -13
  32. package/dist/extensions/pi-subagents/src/runs/background/active-async-capacity.ts +26 -8
  33. package/dist/extensions/pi-subagents/src/runs/background/async-execution.ts +103 -23
  34. package/dist/extensions/pi-subagents/src/runs/background/async-resume.ts +6 -2
  35. package/dist/extensions/pi-subagents/src/runs/background/async-status.ts +18 -2
  36. package/dist/extensions/pi-subagents/src/runs/background/notify.ts +54 -3
  37. package/dist/extensions/pi-subagents/src/runs/background/process-terminal.ts +16 -0
  38. package/dist/extensions/pi-subagents/src/runs/background/run-status.ts +22 -2
  39. package/dist/extensions/pi-subagents/src/runs/background/scheduled-runs.ts +63 -6
  40. package/dist/extensions/pi-subagents/src/runs/background/steering.ts +4 -1
  41. package/dist/extensions/pi-subagents/src/runs/background/subagent-runner.ts +69 -12
  42. package/dist/extensions/pi-subagents/src/runs/background/wait-completions.ts +13 -0
  43. package/dist/extensions/pi-subagents/src/runs/background/wait-tool.ts +3 -1
  44. package/dist/extensions/pi-subagents/src/runs/foreground/execution.ts +21 -8
  45. package/dist/extensions/pi-subagents/src/runs/foreground/subagent-executor.ts +59 -6
  46. package/dist/extensions/pi-subagents/src/runs/shared/acceptance.ts +95 -18
  47. package/dist/extensions/pi-subagents/src/runs/shared/async-status-projection.ts +11 -43
  48. package/dist/extensions/pi-subagents/src/runs/shared/capability-ceiling.ts +1 -0
  49. package/dist/extensions/pi-subagents/src/runs/shared/dynamic-fanout.ts +1 -1
  50. package/dist/extensions/pi-subagents/src/runs/shared/lane-metadata.ts +24 -3
  51. package/dist/extensions/pi-subagents/src/runs/shared/parallel-handoff.ts +4 -0
  52. package/dist/extensions/pi-subagents/src/runs/shared/parallel-utils.ts +2 -6
  53. package/dist/extensions/pi-subagents/src/runs/shared/permissions.ts +1 -0
  54. package/dist/extensions/pi-subagents/src/runs/shared/pi-args.ts +33 -18
  55. package/dist/extensions/pi-subagents/src/runs/shared/pi-spawn.ts +73 -37
  56. package/dist/extensions/pi-subagents/src/runs/shared/structured-output.ts +33 -6
  57. package/dist/extensions/pi-subagents/src/runs/shared/subagent-control.ts +4 -2
  58. package/dist/extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.ts +20 -3
  59. package/dist/extensions/pi-subagents/src/runs/shared/task-intent.ts +21 -7
  60. package/dist/extensions/pi-subagents/src/runs/shared/tool-timeout.ts +1 -1
  61. package/dist/extensions/pi-subagents/src/runs/shared/worktree.ts +467 -63
  62. package/dist/extensions/pi-subagents/src/shared/atomic-json.ts +3 -1
  63. package/dist/extensions/pi-subagents/src/shared/fork-context.ts +0 -12
  64. package/dist/extensions/pi-subagents/src/shared/fork-session-cwd.ts +27 -0
  65. package/dist/extensions/pi-subagents/src/shared/launch-contract.ts +3 -0
  66. package/dist/extensions/pi-subagents/src/shared/types.ts +42 -4
  67. package/dist/extensions/pi-subagents/src/shared/utils.ts +18 -7
  68. package/dist/extensions/pi-subagents/src/slash/slash-commands.ts +1 -1
  69. package/dist/extensions/pi-subagents/src/slash/subagents-admin.ts +26 -12
  70. package/dist/extensions/pi-subagents/src/tui/fleet-status.ts +61 -2
  71. package/dist/extensions/pi-subagents/src/tui/fleet.ts +12 -7
  72. package/dist/extensions/pi-subagents/src/tui/render.ts +227 -14
  73. package/dist/extensions/pi-subagents/src/watchdog/child-status.ts +56 -34
  74. package/dist/extensions/pi-subagents/src/watchdog/diff-tool.ts +77 -0
  75. package/dist/extensions/pi-subagents/src/watchdog/emission-guard.ts +5 -3
  76. package/dist/extensions/pi-subagents/src/watchdog/guidance.ts +20 -0
  77. package/dist/extensions/pi-subagents/src/watchdog/register-child.ts +16 -13
  78. package/dist/extensions/pi-subagents/src/watchdog/register-main.ts +10 -9
  79. package/dist/extensions/pi-subagents/src/watchdog/render.ts +4 -5
  80. package/dist/extensions/pi-subagents/src/watchdog/review.ts +15 -4
  81. package/dist/extensions/pi-subagents/src/watchdog/rules.ts +70 -0
  82. package/dist/extensions/pi-subagents/src/watchdog/runtime.ts +75 -92
  83. package/dist/extensions/pi-subagents/src/watchdog/scope.ts +2 -1
  84. package/dist/extensions/pi-subagents/src/watchdog/settings.ts +48 -104
  85. package/dist/extensions/pi-subagents/src/watchdog/types.ts +18 -32
  86. package/dist/extensions/pi-subagents/src/watchdog/warning-format.ts +0 -1
  87. package/dist/extensions/pi-subagents/src/workflows/chat-progress.ts +3 -2
  88. package/dist/extensions/pi-subagents/src/workflows/workflow-checklist.ts +439 -0
  89. package/dist/extensions/pi-subagents/src/workflows/workflow-preflight.ts +28 -1
  90. package/dist/extensions/pi-subagents/test/integration/async-execution.test.ts +335 -21
  91. package/dist/extensions/pi-subagents/test/integration/async-job-tracker.test.ts +4 -1
  92. package/dist/extensions/pi-subagents/test/integration/async-status.test.ts +1 -1
  93. package/dist/extensions/pi-subagents/test/integration/fork-context-execution.test.ts +22 -18
  94. package/dist/extensions/pi-subagents/test/integration/intercom-result-delivery.test.ts +0 -1
  95. package/dist/extensions/pi-subagents/test/integration/render-widget.test.ts +21 -18
  96. package/dist/extensions/pi-subagents/test/integration/single-execution.test.ts +307 -22
  97. package/dist/extensions/pi-subagents/test/integration/slash-commands.test.ts +1 -0
  98. package/dist/extensions/pi-subagents/test/support/helpers.ts +25 -0
  99. package/dist/extensions/pi-subagents/test/support/isolated-temp-root.mjs +15 -4
  100. package/dist/extensions/pi-subagents/test/support/mock-pi-script.mjs +17 -2
  101. package/dist/extensions/pi-subagents/test/unit/acceptance.test.ts +96 -15
  102. package/dist/extensions/pi-subagents/test/unit/active-async-capacity.test.ts +53 -5
  103. package/dist/extensions/pi-subagents/test/unit/agent-frontmatter.test.ts +20 -0
  104. package/dist/extensions/pi-subagents/test/unit/agent-management.test.ts +221 -8
  105. package/dist/extensions/pi-subagents/test/unit/agent-overrides.test.ts +45 -24
  106. package/dist/extensions/pi-subagents/test/unit/agent-scan-dirs.test.ts +133 -0
  107. package/dist/extensions/pi-subagents/test/unit/async-execution.test.ts +28 -2
  108. package/dist/extensions/pi-subagents/test/unit/async-interrupt-action.test.ts +1 -1
  109. package/dist/extensions/pi-subagents/test/unit/async-resume.test.ts +2 -0
  110. package/dist/extensions/pi-subagents/test/unit/async-retention.test.ts +4 -1
  111. package/dist/extensions/pi-subagents/test/unit/async-status-projection.test.ts +18 -4
  112. package/dist/extensions/pi-subagents/test/unit/atomic-json.test.ts +16 -0
  113. package/dist/extensions/pi-subagents/test/unit/completion-guard.test.ts +38 -0
  114. package/dist/extensions/pi-subagents/test/unit/default-extensions.test.ts +2 -2
  115. package/dist/extensions/pi-subagents/test/unit/fleet-status.test.ts +21 -0
  116. package/dist/extensions/pi-subagents/test/unit/fleet.test.ts +19 -6
  117. package/dist/extensions/pi-subagents/test/unit/get-final-output.test.ts +26 -0
  118. package/dist/extensions/pi-subagents/test/unit/herdr-inspector.test.ts +22 -1
  119. package/dist/extensions/pi-subagents/test/unit/index-child-registration.test.ts +2 -6
  120. package/dist/extensions/pi-subagents/test/unit/notify.test.ts +66 -1
  121. package/dist/extensions/pi-subagents/test/unit/pi-args-permission-system.test.ts +1 -1
  122. package/dist/extensions/pi-subagents/test/unit/pi-args.test.ts +116 -10
  123. package/dist/extensions/pi-subagents/test/unit/pi-spawn.test.ts +136 -18
  124. package/dist/extensions/pi-subagents/test/unit/preflight.test.ts +20 -0
  125. package/dist/extensions/pi-subagents/test/unit/process-terminal.test.ts +22 -0
  126. package/dist/extensions/pi-subagents/test/unit/profiles.test.ts +1 -0
  127. package/dist/extensions/pi-subagents/test/unit/project-panes-public-api.test.ts +8 -0
  128. package/dist/extensions/pi-subagents/test/unit/render-helpers.test.ts +127 -48
  129. package/dist/extensions/pi-subagents/test/unit/run-status.test.ts +68 -0
  130. package/dist/extensions/pi-subagents/test/unit/runtime-agent-registration.test.ts +17 -0
  131. package/dist/extensions/pi-subagents/test/unit/scheduled-runs.test.ts +88 -0
  132. package/dist/extensions/pi-subagents/test/unit/schemas.test.ts +4 -2
  133. package/dist/extensions/pi-subagents/test/unit/scripted-workflow.test.ts +9 -9
  134. package/dist/extensions/pi-subagents/test/unit/steering-action.test.ts +2 -2
  135. package/dist/extensions/pi-subagents/test/unit/steering.test.ts +9 -3
  136. package/dist/extensions/pi-subagents/test/unit/subagent-control.test.ts +22 -9
  137. package/dist/extensions/pi-subagents/test/unit/subagent-prompt-runtime.test.ts +91 -8
  138. package/dist/extensions/pi-subagents/test/unit/task-intent.test.ts +27 -0
  139. package/dist/extensions/pi-subagents/test/unit/temp-paths.test.ts +50 -0
  140. package/dist/extensions/pi-subagents/test/unit/tool-description.test.ts +0 -1
  141. package/dist/extensions/pi-subagents/test/unit/tool-timeout.test.ts +2 -2
  142. package/dist/extensions/pi-subagents/test/unit/wait-completions.test.ts +34 -0
  143. package/dist/extensions/pi-subagents/test/unit/wait-subscriptions.test.ts +1 -2
  144. package/dist/extensions/pi-subagents/test/unit/watchdog-child-status.test.ts +73 -13
  145. package/dist/extensions/pi-subagents/test/unit/watchdog-diff-tool.test.ts +79 -0
  146. package/dist/extensions/pi-subagents/test/unit/watchdog-permission-arbiter.test.ts +2 -4
  147. package/dist/extensions/pi-subagents/test/unit/watchdog-render.test.ts +7 -8
  148. package/dist/extensions/pi-subagents/test/unit/watchdog-review.test.ts +48 -3
  149. package/dist/extensions/pi-subagents/test/unit/watchdog-rules.test.ts +37 -0
  150. package/dist/extensions/pi-subagents/test/unit/watchdog-runtime.test.ts +36 -118
  151. package/dist/extensions/pi-subagents/test/unit/watchdog-scope.test.ts +1 -1
  152. package/dist/extensions/pi-subagents/test/unit/watchdog-settings.test.ts +37 -14
  153. package/dist/extensions/pi-subagents/test/unit/workflow-chat-progress.test.ts +45 -26
  154. package/dist/extensions/pi-subagents/test/unit/workflow-checklist.test.ts +223 -0
  155. package/dist/extensions/pi-subagents/test/unit/workflow-launch-params.test.ts +50 -1
  156. package/dist/extensions/pi-subagents/test/unit/workflow-preflight.test.ts +22 -0
  157. package/dist/extensions/pi-subagents/test/unit/worktree.test.ts +136 -4
  158. package/dist/extensions/pi-zentui/README.md +19 -5
  159. package/dist/extensions/pi-zentui/docs/configuration.md +37 -9
  160. package/dist/extensions/pi-zentui/extensions/zentui/config.ts +29 -0
  161. package/dist/extensions/pi-zentui/extensions/zentui/index.ts +31 -2
  162. package/dist/extensions/pi-zentui/extensions/zentui/prototype-patch-registry.ts +55 -11
  163. package/dist/extensions/pi-zentui/extensions/zentui/settings-command.ts +115 -3
  164. package/dist/extensions/pi-zentui/extensions/zentui/settings-previews.ts +119 -2
  165. package/dist/extensions/pi-zentui/extensions/zentui/thinking-experimental.ts +1768 -0
  166. package/dist/extensions/pi-zentui/extensions/zentui/thinking-status.ts +69 -0
  167. package/dist/extensions/pi-zentui/extensions/zentui/thinking-steps.ts +155 -0
  168. package/dist/extensions/pi-zentui/extensions/zentui/ui.ts +2 -1
  169. package/dist/extensions/pi-zentui/extensions/zentui/user-message-osc.ts +16 -2
  170. package/dist/extensions/pi-zentui/extensions/zentui/user-message-styles.ts +1 -1
  171. package/dist/extensions/pi-zentui/test/config-load-lifecycle.test.ts +124 -0
  172. package/dist/extensions/pi-zentui/test/config.test.ts +82 -2
  173. package/dist/extensions/pi-zentui/test/editor-viewport-indicators.test.ts +19 -4
  174. package/dist/extensions/pi-zentui/test/extension-compliance.test.ts +58 -9
  175. package/dist/extensions/pi-zentui/test/package-contents.mjs +33 -0
  176. package/dist/extensions/pi-zentui/test/prototype-patch-registry.test.ts +131 -0
  177. package/dist/extensions/pi-zentui/test/responsive-dependencies.test.ts +4 -4
  178. package/dist/extensions/pi-zentui/test/settings-command.test.ts +289 -7
  179. package/dist/extensions/pi-zentui/test/settings-previews.test.ts +106 -0
  180. package/dist/extensions/pi-zentui/test/thinking-experimental-docs.test.ts +51 -0
  181. package/dist/extensions/pi-zentui/test/thinking-experimental-loader-diagnostics.mjs +54 -0
  182. package/dist/extensions/pi-zentui/test/thinking-experimental-missing-export.test.ts +44 -0
  183. package/dist/extensions/pi-zentui/test/thinking-experimental-rows.test.ts +297 -0
  184. package/dist/extensions/pi-zentui/test/thinking-experimental-tui.mjs +2329 -0
  185. package/dist/extensions/pi-zentui/test/thinking-experimental.test.ts +1668 -0
  186. package/dist/extensions/pi-zentui/test/thinking-status.test.ts +85 -0
  187. package/dist/extensions/pi-zentui/test/thinking-steps.test.ts +122 -0
  188. package/dist/extensions/pi-zentui/test/user-message-osc.test.ts +58 -0
  189. package/dist/skills/brandkit/SKILL.md +0 -2
  190. package/dist/skills/{industrial-brutalist-ui → brutalist}/SKILL.md +1 -3
  191. package/dist/skills/gpt-taste/SKILL.md +0 -2
  192. package/dist/skills/image-to-code/SKILL.md +0 -2
  193. package/dist/skills/imagegen-frontend-mobile/SKILL.md +0 -2
  194. package/dist/skills/imagegen-frontend-web/SKILL.md +0 -2
  195. package/dist/skills/{minimalist-ui → minimalist}/SKILL.md +1 -3
  196. package/dist/skills/{full-output-enforcement → output}/SKILL.md +1 -3
  197. package/dist/skills/{redesign-existing-projects → redesign}/SKILL.md +1 -3
  198. package/dist/skills/{high-end-visual-design → soft}/SKILL.md +1 -3
  199. package/dist/skills/stitch/DESIGN.md +121 -0
  200. package/dist/skills/{stitch-design-taste → stitch}/SKILL.md +1 -3
  201. package/dist/skills/{design-taste-frontend → taste}/SKILL.md +1 -3
  202. package/dist/skills/{design-taste-frontend-v1 → taste-v1}/SKILL.md +2 -4
  203. package/package.json +1 -1
@@ -1,145 +1,142 @@
1
1
  # Watchdog and child permissions
2
2
 
3
- The watchdog is an opt-in adversarial reviewer for repo edits. This page covers what it reviews, how to pick its model, scope monitoring, LSP diagnostics, and the native child tool permission gate that uses the child watchdog as its arbiter.
3
+ The watchdog is an opt-in second model that reviews what the agent just did and pushes findings back into the transcript. It looks for missed constraints, correctness risks, test gaps, unsafe changes, loop risks, and scope drift, and says nothing when the turn is clean. It is not the `reviewer` subagent; `subagents.defaultModel` and `agentOverrides.reviewer` do not configure it.
4
4
 
5
- ## What the watchdog reviews
5
+ ## When it runs
6
6
 
7
- The watchdog is not the `reviewer` subagent. `subagents.defaultModel` and `subagents.agentOverrides.reviewer` do not configure it.
7
+ | Timing | Trigger | Gate | Delivery |
8
+ |---|---|---|---|
9
+ | Boundary review | `agent_end` of every main or child turn | Repo changed | Steered into the transcript; the agent gets one continuation, then that turn is reviewed again |
10
+ | Cadence review | Every `cadence.everyNTools` tool results, minimum 5 | Opt-in | Steered after the current tool, before the next step |
11
+ | LSP pre-pass | Before boundary review | Changed TypeScript/JavaScript files | Diagnostics become watchdog findings without a model call |
8
12
 
9
- It reviews repo edits, not ordinary conversation:
13
+ Boundary reviews coalesce a turn's edits into one final-state review. Unchanged or reverted diffs are skipped, as are `.pi-subagents/` and `tmp/` artifacts. In orchestrated runs, each writing child reviews its own worktree and the parent reviews the aggregate diff after child changes land. There is no timer or "every turn regardless of edits" mode; the closest is a low cadence such as `everyNTools: 5`. Cadence monitoring is inspired by [Scopey](https://github.com/ArchAstro/scopey).
10
14
 
11
- - It runs at the safe `agent_end` boundary, only when the current agent or child writer changed the final repo state since the start of that turn.
12
- - Multiple edits in one turn are coalesced into one review of the final changed state.
13
- - Unchanged/reverted diffs are skipped.
14
- - Generated `.pi-subagents/` or `tmp/` artifacts do not trigger review.
15
- - In orchestrated runs, each writing child can review its own edited worktree, and the parent can still review the aggregate repo diff after child changes are applied.
15
+ Children get the same boundary, cadence, and LSP behavior. Child cadence resolves from `children.overrides.<agent>.cadence`, then `children.cadence`, then top-level `cadence`:
16
16
 
17
- ## Choosing a model
17
+ ```json
18
+ {
19
+ "subagents": {
20
+ "watchdog": {
21
+ "enabled": true,
22
+ "cadence": { "everyNTools": 10 },
23
+ "children": {
24
+ "enabled": true,
25
+ "cadence": { "everyNTools": 20 },
26
+ "overrides": {
27
+ "worker": { "cadence": { "everyNTools": 5 } },
28
+ "reviewer": { "enabled": false }
29
+ }
30
+ }
31
+ }
32
+ }
33
+ }
34
+ ```
18
35
 
19
- Because the watchdog is an adversarial change reviewer, it should usually use a strong complementary model rather than a cheap/light one.
36
+ That means: main every 10 tools, worker every 5, other children every 20, reviewer never.
20
37
 
21
- Ask pi-subagents for the current strong pairing:
38
+ ## What you see
22
39
 
23
- ```text
24
- /subagents-watchdog recommend-model
25
- /subagents-watchdog session model recommended
26
- /subagents-watchdog model recommended
40
+ Every finding is an ordinary transcript message: expandable, scrollable, and persisted in session JSONL. A clean review shows nothing.
41
+
42
+ ```
43
+ you ─▶ agent turn ─▶ edits repo ─▶ agent_end ─▶ watchdog review
44
+ ├─ clean: turn ends
45
+ └─ warning: steered in; agent continues once
27
46
  ```
28
47
 
29
- The current recommendation policy is Opus 4.8 with thinking high or GPT 5.5 with thinking high. If your main session is using one, the watchdog should use the other when that model is authenticated.
48
+ Collapsed warnings show the title and evidence line. Expanded warnings show evidence, recommended action, category, and source:
30
49
 
31
- - `session model recommended` changes only the current Pi session.
32
- - `model recommended` saves the recommendation to `~/.selesai/agent/settings.json`. It does not turn the watchdog on; enable it separately with `/subagents-watchdog on`.
50
+ ```
51
+ ● Subagent watchdog Blocker (displayed): Claims tests passed without running them
52
+ Evidence: The transcript claims `npm test` passed but no test command appears in the tool log.
53
+ Recommended action: Run the focused test before finishing.
54
+ Category: Test Gap · Source: main
55
+ ```
33
56
 
34
- Or set the model explicitly:
57
+ When consecutive boundary reviews raise the same warning, the agent is not making progress. After `stalemateRepeats` identical warnings in a row (default 3), the warning is shown as `stalemate`, no continuation is triggered, and the turn ends. Your next prompt resets the count.
35
58
 
36
- ```text
37
- /subagents-watchdog model anthropic/claude-opus-4-8:high
38
- /subagents-watchdog model openai-codex/gpt-5.5:high
39
- /subagents-watchdog model inherit
40
- /subagents-watchdog check
41
- ```
59
+ Child watchdog findings are lifted into the parent in three ways:
42
60
 
43
- In settings files, use `subagents.watchdog.main.model` and `subagents.watchdog.main.thinking` for the main watchdog:
61
+ - The result envelope contains `watchdog.warnings` with severity, category, summary, evidence, recommended action, `addressed`, and `stalemate`, bounded to the last 20.
62
+ - The acceptance runtime check `watchdog-blocker` fails on blockers that are unaddressed or stalemate.
63
+ - Completion notices include `Watchdog blockers:` lines, and Fleet/status views show `wd:<n>` plus `resolve watchdog blockers`.
44
64
 
45
- - If `main.model` is omitted, the main watchdog uses the current session model and thinking level.
46
- - If `main.model` is set without a thinking suffix or `main.thinking`, it runs with thinking off. Prefer `:high` or `"thinking": "high"` for the strong-watchdog pairing.
65
+ `/subagents-watchdog status` shows setting sources, enabled state, runtime state, review trigger, scope, cadence, LSP status, selected model/thinking, child overrides, timeout, stalemate count, launch-rule count, review backend, last warning, changed paths, and config errors when present.
47
66
 
48
- Default strong-reviewer profile:
67
+ ## What the reviewer is given
49
68
 
50
- ```json
51
- {
52
- "subagents": {
53
- "watchdog": {
54
- "enabled": true,
55
- "main": {
56
- "model": "anthropic/claude-opus-4-8",
57
- "thinking": "high"
58
- }
59
- }
60
- }
61
- }
62
- ```
69
+ - **Turn delta** with changed repo paths. Over-long input keeps the first 6,000 characters and the tail.
70
+ - **Current scope** (`scope.enabled`, default on): bounded real user prompts, with newer prompts superseding older ones.
71
+ - **`watchdog_diff`** when inside git: diff since the session-start commit, including later commits, plus untracked paths to inspect with `read`; accepts `path` and `stat:true`.
72
+ - **`WATCHDOG.md`** standing instructions, read fresh on every review: `<project>/.selesai/WATCHDOG.md` first, then `~/.selesai/agent/WATCHDOG.md`, capped at 8,000 characters. Set `guidance.watchdogMd: false` to ignore them.
73
+ - **LSP diagnostics** from `typescript-language-server`, auto-detected in `node_modules/.bin` or `PATH`; it is never installed and never run over the whole workspace. Errors become blockers, warnings concerns, and info/hints stay in status.
63
74
 
64
- ## Scope monitoring
75
+ ## Choosing a model
65
76
 
66
- When enabled, the watchdog keeps a bounded in-memory current-scope artifact from real user prompts and prepends it to review input by default (`subagents.watchdog.scope.enabled`). Newer prompts supersede and mutate older prompts, so the reviewer can flag work that no longer serves the current scope as `scope-drift`. Watchdog auto-follow prompts are not recorded as scope.
77
+ One model setting serves both boundary and cadence reviews per endpoint. Use a strong complementary model for rare adversarial boundary reviews, or a cheap one for frequent cadence monitoring.
67
78
 
68
- You can opt into Scopey-style scope monitoring, inspired by [Scopey](https://github.com/ArchAstro/scopey), by setting `subagents.watchdog.cadence.everyNTools` to run additional non-blocking reviews every N tool results. Cadence warnings are transcript-visible and delivered with Pi's `steer` mode after the current tool boundary; they are never hidden. The same configured watchdog model is used for all checks, so choose a cheap model for frequent monitoring or a strong model for rarer adversarial review.
79
+ ```text
80
+ /subagents-watchdog recommend-model
81
+ /subagents-watchdog session model recommended
82
+ /subagents-watchdog model recommended
83
+ /subagents-watchdog model anthropic/claude-opus-4-8:high
84
+ /subagents-watchdog model openai-codex/gpt-5.5:high
85
+ /subagents-watchdog model inherit
86
+ /subagents-watchdog check
87
+ /subagents-watchdog on
88
+ ```
69
89
 
70
- Scopey-style profile:
90
+ The recommendation is Opus 4.8 or GPT 5.5 at thinking high, whichever your main session is not using and is authenticated. Saving a model does not enable the watchdog; use `on` separately.
71
91
 
72
92
  ```json
73
93
  {
74
94
  "subagents": {
75
95
  "watchdog": {
76
96
  "enabled": true,
77
- "main": {
78
- "model": "anthropic/claude-haiku-4-5",
79
- "thinking": "medium"
80
- },
97
+ "main": { "model": "anthropic/claude-opus-4-8", "thinking": "high" },
81
98
  "scope": { "enabled": true },
82
99
  "cadence": { "everyNTools": 10 },
83
- "autoFollow": {
84
- "blockers": true,
85
- "maxAttempts": 3,
86
- "stalemateRepeats": 3
87
- }
100
+ "stalemateRepeats": 3
88
101
  }
89
102
  }
90
103
  }
91
104
  ```
92
105
 
93
- ## Auto-follow
94
-
95
- When the watchdog displays a blocker at `agent_end`, the `subagents.watchdog.autoFollow` policy can queue a visible follow-up user message asking the agent to address it. Auto-follow only runs while the watchdog is enabled, respects `maxAttempts`, and stops on repeated identical blockers using `stalemateRepeats`.
96
-
97
- ## LSP diagnostics
98
-
99
- When the watchdog is enabled, it also checks changed TypeScript and JavaScript files for fresh language-server diagnostics before the model review.
106
+ Omit `main.model` to inherit the session model and thinking level. A `main.model` without a thinking suffix or `main.thinking` runs with thinking off, so prefer `:high` for the strong pairing.
100
107
 
101
- - It auto-detects `typescript-language-server` from the project `node_modules/.bin` or `PATH`. It never installs tools or scans the whole workspace.
102
- - LSP errors surface as watchdog blockers, warnings as concerns, and info/hints stay in status details.
103
- - Slow or missing servers are reported in `/subagents-watchdog status` without blocking the turn or emitting late mid-turn warnings.
104
- - Configure the bounds with `subagents.watchdog.lsp.enabled`, `timeoutMs`, `maxFiles`, and `maxDiagnostics`.
108
+ Agents can call `subagent({ action: "watchdog.recommend-model" })` and `subagent({ action: "watchdog.configure", model: "recommended", scope: "session" | "user" | "project" })`. They should use `scope: "session"` unless you ask for a lasting default.
105
109
 
106
110
  ## Child watchdogs
107
111
 
108
- For child subagent watchdogs, use `subagents.watchdog.children.model` as the default child watchdog model, or `subagents.watchdog.children.overrides.<agent>.model` for a specific child role.
109
-
110
- Child watchdogs are opt-in and follow the same edit-gated rule: read-only children do not trigger watchdog reviews, while writer children are reviewed at their own `agent_end` if their worktree changed.
111
-
112
- ## Agent-driven configuration
113
-
114
- Agents can configure the same values through the tool when you ask them to set up the watchdog:
115
-
116
- ```ts
117
- subagent({ action: "watchdog.recommend-model" })
118
- subagent({ action: "watchdog.configure", model: "recommended", scope: "session" })
119
- subagent({ action: "watchdog.configure", model: "recommended", scope: "project" })
120
- ```
121
-
122
- Persistent scopes (`user` or `project`) should only be used when you ask for a lasting default. Otherwise the agent should use `scope: "session"`.
112
+ Opt in under `subagents.watchdog.children`. `model` and `thinking` set the default child watchdog; `overrides.<agent>` can set `model`, `thinking`, `enabled`, or `cadence` per role.
123
113
 
124
- ## Native child tool permissions
114
+ ## Launch rules
125
115
 
126
- Native permissions are opt-in and apply only to Pi child runtimes. With no rules configured, every tool call passes through unchanged.
127
-
128
- Configure explicit non-bash rules globally in `~/.selesai/agent/extensions/subagent/config.json`:
116
+ `subagents.watchdog.rules` pins which models each role may run on. It runs before a child starts, needs no model call, and applies even when model review is off.
129
117
 
130
118
  ```json
131
119
  {
132
- "permissions": {
133
- "rules": {
134
- "read": "allow",
135
- "write": "ask",
136
- "edit": "deny"
120
+ "subagents": {
121
+ "watchdog": {
122
+ "rules": {
123
+ "action": "warn",
124
+ "roleModels": {
125
+ "scout": { "allow": ["openai-codex/gpt-5.6-luna:max"] },
126
+ "oracle": { "deny": ["*"], "note": "oracle is for hard questions only; ask before launching" },
127
+ "worker": { "deny": ["openai-codex/gpt-5.6-sol:high"] }
128
+ }
129
+ }
137
130
  }
138
131
  }
139
132
  }
140
133
  ```
141
134
 
142
- Custom agents can override matching global rules with a `permission:` or `permissions:` frontmatter block:
135
+ `action: "warn"` steers a concern into the orchestrator transcript and lets the launch proceed. `action: "block"` returns a tool error and starts nothing. `allow` and `deny` are anchored, case-sensitive globs (`*`, `?`) matched against `provider/id[:thinking]` and bare `provider/id`; `deny` wins. Rules apply to direct launches, workflow children, and chain/parallel steps using settings visible at the launch cwd.
136
+
137
+ ## Native child tool permissions
138
+
139
+ Opt-in, Pi child runtimes only. With no rules, every tool call passes through. Global non-bash rules live in `~/.selesai/agent/extensions/subagent/config.json`; agents override matching rules in `permission:` or `permissions:` frontmatter:
143
140
 
144
141
  ```yaml
145
142
  ---
@@ -150,27 +147,8 @@ permission:
150
147
  ---
151
148
  ```
152
149
 
153
- Rules support `allow`, `ask`, and `deny`:
154
-
155
- - Agent rules override matching global rules.
156
- - Omitted and unknown tools default to `allow`.
157
- - Explicit `allow` removes an inherited restriction.
158
- - The gate is not registered when the resolved policy has no `ask` or `deny` rules.
159
-
160
- ### How `ask` works
161
-
162
- An explicit `ask` pauses that exact tool call and sends a bounded, redacted preview to a one-call permission arbiter owned by the built-in child watchdog. The arbiter uses the configured child-watchdog model and returns only `approve` or `deny`; it does not notify the parent agent.
163
-
164
- Enable and configure `subagents.watchdog.children` before using `ask` rules. A disabled watchdog, missing model/auth, timeout, malformed response, or runtime error denies the call with a clear error.
165
-
166
- Asked requests and decisions are written to bounded audit JSONL, including `decisionSource: "watchdog"` and bounded failure reasons. Ordinary direction and clarification through `contact_supervisor` or the optional `pi-intercom` extension remain separate and are never permission-gated.
167
-
168
- ### Bash is out of scope
169
-
170
- `bash` is always passed through by pi-subagents. Bash rules are rejected rather than parsed, gated, denied, or audited. Install and configure `pi-guard` when command-level bash policy is needed.
171
-
172
- A pi-subagents child is headless, so a pi-guard rule that resolves to `ask` cannot request approval from the parent Pi UI. Native permissions do not forward pi-guard decisions; they only apply to the separate non-bash child permission gate. For child-specific policy, use `PI_GUARD` through a `SELESAI_SUBAGENT_PI_BINARY` wrapper or an equivalent launch wrapper, and configure explicit `allow` or `deny` rules. An `allow` rule grants execution; it is not approval forwarding, so retain explicit denies for commands the child must not run.
150
+ Values are `allow`, `ask`, and `deny`. Agent rules override global ones, omitted and unknown tools default to `allow`, an explicit `allow` removes an inherited restriction, and the gate is not registered when the resolved policy has no `ask` or `deny`.
173
151
 
174
- ### External CLI profiles
152
+ `ask` pauses that exact tool call and sends a bounded, redacted preview to a one-call arbiter owned by the child watchdog, using the configured child-watchdog model. The arbiter returns only `approve` or `deny` and does not notify the parent. A disabled watchdog, missing model/auth, timeout, malformed response, or runtime error denies the call with a clear error. Requests and decisions are written to bounded audit JSONL. `contact_supervisor` and the optional `pi-intercom` extension are never permission-gated.
175
153
 
176
- External CLI profiles are opaque processes, so native permissions cannot intercept their tools. A launch with effective `ask` or `deny` rules is rejected for an external CLI agent instead of claiming enforcement.
154
+ Bash is always passed through; bash rules are rejected. Use `pi-guard` for command-level policy. For child-specific command policy, run `PI_GUARD` through a `SELESAI_SUBAGENT_SELESAI_BINARY` wrapper with explicit `allow` or `deny` rules. External CLI profiles are opaque processes, so native permissions cannot intercept their tools; launches with effective `ask` or `deny` rules are rejected for external CLI agents.
@@ -472,4 +472,4 @@ Then run it through the native adapter:
472
472
 
473
473
  The adapter delegates to the named subagent, applies `model`, `skill`, `cwd`, and fork/fresh context metadata, and supports runtime overrides such as `--subagent reviewer`, `--fork`, `--fresh`, and `--bg`.
474
474
 
475
- Prompt templates with `chain:` frontmatter are translated into `workflowScript` and launched through `/prompt-workflow`; `/chain-prompts` is no longer registered.
475
+ Prompt templates with `chain:` frontmatter are translated into `workflowScript` and launched through `/prompt-workflow`; `/chain-prompts` is no longer registered.
@@ -88,7 +88,6 @@ console.log(`
88
88
  The extension is now available in Selesai. Tools added:
89
89
  • subagent - Delegate tasks to agents and inspect run status
90
90
  • bg_wait - Wait for background/provider/detached work without native completion notifications
91
- (subagent_wait remains a deprecated compatibility alias)
92
91
 
93
92
  Documentation: ${EXTENSION_DIR}/README.md
94
- `);
93
+ `);
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-subagents",
3
- "version": "0.61.0",
3
+ "version": "0.64.0",
4
4
  "description": "Selesai extension for single-agent delegation and scripted multi-agent workflows",
5
5
  "author": "Nico Bailon",
6
6
  "license": "MIT",
@@ -67,4 +67,4 @@ Choose the smallest recipe that fits:
67
67
  - **Intercom already waiting for a reply:** resolve the pending ask before starting another.
68
68
  - **Parallel output-path conflict:** give each task a distinct output path, or disable output where no artifact is needed.
69
69
  - **Worktree launch failure:** ensure the git tree is clean and task cwd overrides match the shared cwd.
70
- - **Child fails before starting:** inspect `subagent({ action: "status", id: "..." })`, artifact metadata, output logs, and `doctor`; loader errors usually appear in child logs.
70
+ - **Child fails before starting:** inspect `subagent({ action: "status", id: "..." })`, artifact metadata, output logs, and `doctor`; loader errors usually appear in child logs.
@@ -168,8 +168,7 @@ from disabling `waitTool`, which returns immediately without arming a future
168
168
  wake. If a foreground child detaches for supervisor coordination, reply first,
169
169
  then wait on its id; do not resume or launch a replacement while it remains
170
170
  detached. Headless sessions also auto-drain exact current-session work at
171
- `agent_end` as a final safeguard. `subagent_wait` remains available as a
172
- deprecated compatibility alias for `bg_wait`.
171
+ `agent_end` as a final safeguard. `subagent_wait` remains available as a deprecated compatibility alias for `bg_wait`.
173
172
 
174
173
  Providers are discovered through the `pi-subagents/background-work` registry and
175
174
  must expose a stable item id and owning session id. Load a provider through the
@@ -338,9 +337,10 @@ child changes land. Enabled watchdogs also run changed-file TypeScript/JavaScrip
338
337
  LSP diagnostics before the model pass when `typescript-language-server` is available.
339
338
  They keep bounded current-scope context from real user prompts (`watchdog.scope.enabled`)
340
339
  and can optionally run non-blocking Scopey-style cadence reviews every N tool results
341
- (`watchdog.cadence.everyNTools`). Cadence corrections and blocker auto-follow prompts
342
- are always transcript-visible; choose the watchdog model that matches the desired
343
- cheap-monitor vs strong-reviewer policy.
340
+ (`watchdog.cadence.everyNTools`). Cadence corrections and boundary warnings are always
341
+ transcript-visible; a boundary warning continues the run so the agent can act on it, and
342
+ repeated identical warnings stop after `watchdog.stalemateRepeats`. Choose the watchdog
343
+ model that matches the desired cheap-monitor vs strong-reviewer policy.
344
344
 
345
345
  Prefer a strong complementary model (for example Opus 4.8 high paired against a
346
346
  GPT 5.5 main session, or the reverse). Recommendation and configuration:
@@ -536,4 +536,4 @@ subagent_supervisor({ action: "pending" })
536
536
 
537
537
  Native supervisor coordination does not expose generic `intercom` as a fallback. Use `subagent_supervisor` for parent replies.
538
538
 
539
- If intercom messages do not show up, run `subagent({ action: "doctor" })` or `/subagents-doctor`.
539
+ If intercom messages do not show up, run `subagent({ action: "doctor" })` or `/subagents-doctor`.
@@ -85,7 +85,7 @@ subagent({ action: "reset", agent: "reviewer" })
85
85
  Use management actions when the system needs to create or edit subagents on
86
86
  demand without dropping into raw file editing.
87
87
 
88
- Management actions create or update user/project agent files. `config.name` is the local frontmatter name; optional `config.package` registers and looks up the runtime name as `{package}.{name}`. Use the dotted runtime name for `get`, `update`, `delete`, slash commands, and scripted workflow steps. For small builtin changes such as a model swap, prefer `subagents.agentOverrides` in settings. Durable `.chain.md` definitions are legacy records, not a current authoring target; use `workflowScript` or `/prompt-workflow` for repeatable orchestration.
88
+ Management actions create or update user/project agent files. `config.name` is the local frontmatter name; optional `config.package` registers and looks up the runtime name as `{package}.{name}`. Use the dotted runtime name for `get`, `update`, `delete`, slash commands, and scripted workflow steps. For small agent changes such as a model swap, prefer `subagents.agentOverrides` in settings. Durable `.chain.md` definitions are legacy records, not a current authoring target; use `workflowScript` or `/prompt-workflow` for repeatable orchestration.
89
89
 
90
90
  ## Creating and Editing Agents by File
91
91
 
@@ -158,4 +158,4 @@ Additional user prompt templates can delegate into `pi-subagents` through the na
158
158
 
159
159
  Other Pi extensions can call `pi-subagents` through the in-process event bus. The RPC channels are `subagents:rpc:v1:ready`, `subagents:rpc:v1:request`, and per-request replies at `subagents:rpc:v1:reply:<requestId>`. Envelopes use `{ version: 1, requestId, method, params }`, and replies use `{ version: 1, requestId, success, data | error }`. `ping` advertises the exact process-local async completion event as `events.asyncComplete` for RPC-spawn consumers.
160
160
 
161
- Methods: `ping`, `status`, `spawn`, `steer`, `interrupt`, `resume`, and `stop`. `ping` capability metadata advertises optional projections: `capabilities.fleetStatus: { version: 1 }` adds bounded current-session `data.fleet` records (opaque reconciliation `key`, resolved `agent`, optional `role`, `model`, `effort`, caller-facing `goal`, `startedAt`, split `{ input, output, total }` tokens, plus `totalActive`/`omitted` overflow counts) to successful `status` replies; `capabilities.launchResolvedExtensions` advertises parent-resolved opaque launch-extension identifiers in status details; `capabilities.runtimeAcknowledgedExtensions` advertises the best-effort child-runtime acknowledgement projection fed by cooperating extensions emitting `subagent:acknowledge-extension`. Foreground `details.results[]` rows carry a stable numeric `index`; correlate children by `(runId, index)` rather than row position. Consumers should read status/result artifacts and RPC projections instead of scraping terminal output and must ignore unknown fields. `spawn` requires `workflowScript`, is async-only, and rejects management actions, `async: false`, or `clarify: true`; it reuses the normal executor, so discovery, validation, session attribution, configured spawn caps, child-safety depth, artifacts, and async status are shared with the `subagent` tool. `status`, acknowledged async `steer`, and `interrupt` map to the normal control actions. RPC steer disables pause-and-revive recovery and advertises `capabilities.nonRecoveringSteer`, preserving the caller's authority over the exact spawned child. `resume` requires a target plus non-empty message and delegates to the package-owned revival path; it may set a caller-owned `file-only` output path but cannot override the persisted child model, tools, budgets, session ownership, or exclusive session lease. For retained-child workflows, list children first and resume only rows reported `resumable`; otherwise start a same-role fallback challenge and label it as fallback. `stop` targets running async runs through the existing timeout control channel. `pi.events` is process-local, so separate Pi processes and child subagents need lifecycle artifact files or `pi-intercom` instead.
161
+ Methods: `ping`, `status`, `spawn`, `steer`, `interrupt`, `resume`, and `stop`. `ping` capability metadata advertises optional projections: `capabilities.fleetStatus: { version: 1 }` adds bounded current-session `data.fleet` records (opaque reconciliation `key`, resolved `agent`, optional `role`, `model`, `effort`, caller-facing `goal`, `startedAt`, split `{ input, output, total }` tokens, plus `totalActive`/`omitted` overflow counts) to successful `status` replies; `capabilities.launchResolvedExtensions` advertises parent-resolved opaque launch-extension identifiers in status details; `capabilities.runtimeAcknowledgedExtensions` advertises the best-effort child-runtime acknowledgement projection fed by cooperating extensions emitting `subagent:acknowledge-extension`. Foreground `details.results[]` rows carry a stable numeric `index`; correlate children by `(runId, index)` rather than row position. Consumers should read status/result artifacts and RPC projections instead of scraping terminal output and must ignore unknown fields. `spawn` requires `workflowScript`, is async-only, and rejects management actions, `async: false`, or `clarify: true`; it reuses the normal executor, so discovery, validation, session attribution, configured spawn caps, child-safety depth, artifacts, and async status are shared with the `subagent` tool. `status`, acknowledged async `steer`, and `interrupt` map to the normal control actions. RPC steer disables pause-and-revive recovery and advertises `capabilities.nonRecoveringSteer`, preserving the caller's authority over the exact spawned child. `resume` requires a target plus non-empty message and delegates to the package-owned revival path; it may set a caller-owned `file-only` output path but cannot override the persisted child model, tools, budgets, session ownership, or exclusive session lease. For retained-child workflows, list children first and resume only rows reported `resumable`; otherwise start a same-role fallback challenge and label it as fallback. `stop` targets running async runs through the existing timeout control channel. `pi.events` is process-local, so separate Pi processes and child subagents need lifecycle artifact files or `pi-intercom` instead.
@@ -48,4 +48,4 @@ Use stable lane-qualified artifact paths for reports and review output. A handof
48
48
 
49
49
  Keep a worktree until its handoff is durable, no run owns it, and no later gate needs it. Clean up only inside the recorded authority boundary. If a run stops or needs attention, preserve its worktree and artifacts, record the last known state and recovery owner, then resume that run or create one replacement lane from the handoff. Do not start another writer while worktree ownership is uncertain.
50
50
 
51
- Before completion, inspect the board. Every lane must be terminal or blocked with a named next action. Confirm one writer per repo/cwd or worktree, required validation, required fresh read-only review, and a durable handoff. The parent reports outcomes, evidence, residual risks, and the next decision.
51
+ Before completion, inspect the board. Every lane must be terminal or blocked with a named next action. Confirm one writer per repo/cwd or worktree, required validation, required fresh read-only review, and a durable handoff. The parent reports outcomes, evidence, residual risks, and the next decision.
@@ -185,7 +185,7 @@ Builtin `worker` and `delegate` use strict tool allowlists and do not inherit am
185
185
 
186
186
  Builtin agents inherit the current Pi default model unless a run, user setting, project setting, or `subagents.defaultModel` overrides `model`. The table records recommended tier routing, not shipped hard defaults; explicit run, user, or project settings still win. Keep the parent/orchestrator on the ordinary strong default model unless parent/user policy says otherwise. Override builtin defaults before copying full agent files when a small tweak is enough.
187
187
 
188
- Set `subagents.defaultThinking` to apply a shared thinking level to builtin, package, user, and project agents whose frontmatter leaves `thinking` unset. Project settings win over user settings; explicit frontmatter (including `thinking: false`), `agentOverrides.<name>.thinking`, and per-run overrides remain more specific. This setting affects child agents only and does not change the parent session's default thinking level.
188
+ Set `subagents.defaultThinking` to apply a shared thinking level to builtin, package, user, and project agents whose frontmatter leaves `thinking` unset. Project settings win over user settings; matching `agentOverrides.<name>.thinking` and per-run overrides replace frontmatter, while an explicit frontmatter value remains in effect when no matching override is set. This setting affects child agents only and does not change the parent session's default thinking level.
189
189
 
190
190
  ```json
191
191
  {
@@ -288,8 +288,8 @@ Use `fallbackModels` when a tier has provider quota or availability risk. Prefer
288
288
  If a provider rejects model IDs with thinking suffixes, use
289
289
  `subagents.disableThinking: true` in user or project settings to clear bundled
290
290
  builtin thinking defaults globally. A higher-precedence per-agent `thinking`
291
- override can opt one builtin back in. Existing custom-agent frontmatter remains authoritative.
291
+ override can opt one builtin back in or replace custom-agent frontmatter thinking.
292
292
 
293
- Set `subagents.defaultExtensions` to give agents without an `extensions` field a shared child extension allowlist. Omit it to preserve ambient extension discovery, set it to `[]` to disable ambient extensions by default, or use `agentOverrides.<name>.extensions` for one agent. Explicit custom-agent frontmatter still wins.
293
+ Set `subagents.defaultExtensions` to give agents without an `extensions` field a shared child extension allowlist. Omit it to preserve ambient extension discovery, set it to `[]` to disable ambient extensions by default, or use `agentOverrides.<name>.extensions` for one agent. A matching override replaces custom-agent frontmatter for that field.
294
294
 
295
- Tool description modes live in `~/.selesai/agent/extensions/subagent/config.json`, not `subagents` settings. The default uses split prompt metadata: a short tool description plus active `promptSnippet` and `promptGuidelines`. Set `toolDescriptionMode` to `full` or `compact` to force one description string, or `custom` to read `subagent-tool-description.md` from the project config dir or agent dir; invalid custom files fall back to full mode and the safety guidance is still appended.
295
+ Tool description modes live in `~/.selesai/agent/extensions/subagent/config.json`, not `subagents` settings. The default is `full`: one complete tool description. Set `toolDescriptionMode` to `compact` for a shorter description, or `custom` to read `subagent-tool-description.md` from the project config dir or agent dir; invalid custom files fall back to full mode and the safety guidance is still appended.
@@ -70,4 +70,4 @@ Before reporting delegated work as done, verify the relevant subset:
70
70
 
71
71
  ## Public/private boundary
72
72
 
73
- For issue/PR backlogs, releases, merge queues, contributor credit, or repo-specific policy, load the matching user/project skill when available. Keep those rules out of this public package until intentionally released.
73
+ For issue/PR backlogs, releases, merge queues, contributor credit, or repo-specific policy, load the matching user/project skill when available. Keep those rules out of this public package until intentionally released.
@@ -250,13 +250,25 @@ function withDeclaredExtensionPaths(config: AgentConfig, filePath: string): Agen
250
250
  export function editableAgentConfig(agent: AgentConfig): AgentConfig {
251
251
  const { extensions: _extensions, ...withoutExtensions } = agent;
252
252
  const base = agent.override?.base;
253
+ const description = base?.description ?? agent.description;
254
+ const frontmatterFields = agent.source === "builtin" || agent.source === "runtime" ? undefined : readAgentFrontmatterFields(agent.filePath);
255
+ const hasDeclaredField = (...fields: string[]) => frontmatterFields === undefined || fields.some((field) => frontmatterFields.has(field));
256
+ const withoutSettingsDefaults = (config: AgentConfig): AgentConfig => {
257
+ if (!frontmatterFields) return config;
258
+ const next = { ...config };
259
+ if (!hasDeclaredField("model")) delete next.model;
260
+ if (!hasDeclaredField("thinking")) delete next.thinking;
261
+ return next;
262
+ };
253
263
  const {
254
264
  override: _override,
265
+ description: _description,
255
266
  output: _output,
256
267
  outputMode: _outputMode,
257
268
  defaultReads: _defaultReads,
258
269
  model: _model,
259
270
  fallbackModels: _fallbackModels,
271
+ fast: _fast,
260
272
  thinking: _thinking,
261
273
  systemPromptMode: _systemPromptMode,
262
274
  inheritProjectContext: _inheritProjectContext,
@@ -269,27 +281,32 @@ export function editableAgentConfig(agent: AgentConfig): AgentConfig {
269
281
  skills: _skills,
270
282
  skillPath: _skillPath,
271
283
  tools: _tools,
284
+ excludeTools: _excludeTools,
272
285
  mcpDirectTools: _mcpDirectTools,
286
+ allowNestedSubagents: _allowNestedSubagents,
273
287
  subagentOnlyExtensions: _subagentOnlyExtensions,
274
288
  mutationTools: _mutationTools,
275
289
  completionGuard: _completionGuard,
290
+ toolBudget: _toolBudget,
276
291
  ...editable
277
292
  } = withoutExtensions;
278
293
  if (!base) {
279
- return withDeclaredExtensionPaths({
294
+ return withDeclaredExtensionPaths(withoutSettingsDefaults({
280
295
  ...withoutExtensions,
281
296
  ...(agent.extensionsFromDefault ? {} : agent.extensions !== undefined ? { extensions: [...agent.extensions] } : {}),
282
- }, agent.filePath);
297
+ }), agent.filePath);
283
298
  }
284
299
 
285
300
  return withDeclaredExtensionPaths({
286
301
  ...editable,
302
+ description,
287
303
  ...(base.output !== undefined ? { output: base.output } : {}),
288
304
  ...(base.outputMode !== undefined ? { outputMode: base.outputMode } : {}),
289
305
  ...(base.defaultReads !== undefined ? { defaultReads: [...base.defaultReads] } : {}),
290
- ...(base.model !== undefined ? { model: base.model } : {}),
306
+ ...(base.model !== undefined && hasDeclaredField("model") ? { model: base.model } : {}),
291
307
  ...(base.fallbackModels !== undefined ? { fallbackModels: [...base.fallbackModels] } : {}),
292
- ...(base.thinking !== undefined ? { thinking: base.thinking } : {}),
308
+ ...(base.fast !== undefined ? { fast: base.fast } : {}),
309
+ ...(base.thinking !== undefined && hasDeclaredField("thinking") ? { thinking: base.thinking } : {}),
293
310
  systemPromptMode: base.systemPromptMode,
294
311
  inheritProjectContext: base.inheritProjectContext,
295
312
  inheritGlobalContext: base.inheritGlobalContext,
@@ -301,11 +318,14 @@ export function editableAgentConfig(agent: AgentConfig): AgentConfig {
301
318
  ...(base.skills !== undefined ? { skills: [...base.skills] } : {}),
302
319
  ...(base.skillPath !== undefined ? { skillPath: [...base.skillPath] } : {}),
303
320
  ...(base.tools !== undefined ? { tools: [...base.tools] } : {}),
321
+ ...(base.excludeTools !== undefined ? { excludeTools: [...base.excludeTools] } : {}),
304
322
  ...(base.mcpDirectTools !== undefined ? { mcpDirectTools: [...base.mcpDirectTools] } : {}),
323
+ ...(base.allowNestedSubagents !== undefined ? { allowNestedSubagents: base.allowNestedSubagents } : {}),
305
324
  ...(base.extensions !== undefined ? { extensions: [...base.extensions] } : {}),
306
325
  ...(base.subagentOnlyExtensions !== undefined ? { subagentOnlyExtensions: [...base.subagentOnlyExtensions] } : {}),
307
326
  ...(base.mutationTools !== undefined ? { mutationTools: [...base.mutationTools] } : {}),
308
327
  ...(base.completionGuard !== undefined ? { completionGuard: base.completionGuard } : {}),
328
+ ...(base.toolBudget !== undefined ? { toolBudget: base.toolBudget } : {}),
309
329
  }, agent.filePath);
310
330
  }
311
331
 
@@ -333,6 +353,7 @@ export function preservedAgentFrontmatterFields(agent: AgentConfig, cfg: Record<
333
353
  if (hasKey(cfg, "model")) changed("model");
334
354
  if (hasKey(cfg, "fallbackModels")) changed("fallbackModels");
335
355
  if (hasKey(cfg, "tools")) changed("tools");
356
+ if (hasKey(cfg, "excludeTools")) changed("excludeTools");
336
357
  if (hasKey(cfg, "skills")) changed("skill", "skills");
337
358
  if (hasKey(cfg, "skillPath")) changed("skillPath");
338
359
  if (hasKey(cfg, "extensions")) changed("extensions");
@@ -463,6 +484,18 @@ function applyAgentConfig(target: AgentConfig, cfg: Record<string, unknown>): st
463
484
  else delete target.mcpDirectTools;
464
485
  } else return "config.tools must be a comma-separated string or false when provided.";
465
486
  }
487
+ if (hasKey(cfg, "excludeTools")) {
488
+ if (cfg.excludeTools === false || cfg.excludeTools === "") delete target.excludeTools;
489
+ else if (typeof cfg.excludeTools === "string") {
490
+ const excludeTools = parseCsv(cfg.excludeTools);
491
+ if (excludeTools.length) target.excludeTools = [...new Set(excludeTools)];
492
+ else delete target.excludeTools;
493
+ } else if (Array.isArray(cfg.excludeTools) && cfg.excludeTools.every((entry) => typeof entry === "string")) {
494
+ const excludeTools = [...new Set(cfg.excludeTools.map((entry) => entry.trim()).filter(Boolean))];
495
+ if (excludeTools.length) target.excludeTools = excludeTools;
496
+ else delete target.excludeTools;
497
+ } else return "config.excludeTools must be a comma-separated string, string array, or false when provided.";
498
+ }
466
499
  if (hasKey(cfg, "skills")) {
467
500
  if (cfg.skills === false || cfg.skills === "") delete target.skills;
468
501
  else if (typeof cfg.skills === "string") {
@@ -595,6 +628,7 @@ function applyAgentConfig(target: AgentConfig, cfg: Record<string, unknown>): st
595
628
  if (target.runner?.type === "external-cli" || target.runner?.type === "external-job") {
596
629
  const unsupported = [
597
630
  target.tools?.length || target.mcpDirectTools?.length ? "tools" : undefined,
631
+ target.excludeTools?.length ? "excludeTools" : undefined,
598
632
  target.model ? "model" : undefined,
599
633
  target.fallbackModels?.length ? "fallbackModels" : undefined,
600
634
  target.thinking ? "thinking" : undefined,
@@ -701,6 +735,7 @@ function formatAgentCapabilitiesLine(agent: AgentConfig, providerNames: Set<stri
701
735
  } else if (declaredTools.length > 0) {
702
736
  tools = declaredTools.join(", ");
703
737
  }
738
+ if (agent.excludeTools?.length) tools = `${tools}; excludes: ${agent.excludeTools.join(", ")}`;
704
739
  let model = "inherits current session";
705
740
  if (agent.model !== undefined) {
706
741
  model = agent.model;
@@ -728,6 +763,7 @@ function agentCapabilityTools(agent: AgentConfig): AgentCapabilityRow["tools"] {
728
763
  return {
729
764
  ambient: agent.tools === undefined && agent.mcpDirectTools === undefined,
730
765
  names: listOrEmpty(agent.tools),
766
+ ...(agent.excludeTools !== undefined ? { excludeTools: [...agent.excludeTools] } : {}),
731
767
  mcpDirectTools: listOrEmpty(agent.mcpDirectTools),
732
768
  mutationTools: agent.mutationTools,
733
769
  };
@@ -846,6 +882,7 @@ function formatAgentDetail(agent: AgentConfig): string {
846
882
  if (agent.model) lines.push(`Model: ${agent.model}`);
847
883
  if (agent.fallbackModels?.length) lines.push(`Fallback models: ${agent.fallbackModels.join(", ")}`);
848
884
  if (tools.length) lines.push(`Tools: ${tools.join(", ")}`);
885
+ if (agent.excludeTools?.length) lines.push(`Excluded tools: ${agent.excludeTools.join(", ")}`);
849
886
  if (agent.skills?.length) lines.push(`Skills: ${agent.skills.join(", ")}`);
850
887
  if (agent.skillPath?.length) lines.push(`Skill paths: ${agent.skillPath.join(", ")}`);
851
888
  lines.push(`System prompt mode: ${agent.systemPromptMode}`);
@@ -9,6 +9,7 @@ export const KNOWN_FIELDS = new Set([
9
9
  "alias",
10
10
  "aliases",
11
11
  "tools",
12
+ "excludeTools",
12
13
  "allowNestedSubagents",
13
14
  "model",
14
15
  "fallbackModels",
@@ -70,6 +71,8 @@ export function serializeAgent(config: AgentConfig, options: SerializeAgentOptio
70
71
  ];
71
72
  const toolsValue = joinComma(tools);
72
73
  if (toolsValue || preserve("tools")) lines.push(`tools: ${toolsValue ?? ""}`);
74
+ const excludeToolsValue = joinComma(config.excludeTools);
75
+ if (excludeToolsValue || preserve("excludeTools")) lines.push(`excludeTools: ${excludeToolsValue ?? ""}`);
73
76
  if (config.allowNestedSubagents === true || preserve("allowNestedSubagents")) {
74
77
  lines.push(`allowNestedSubagents: ${config.allowNestedSubagents === undefined ? "" : config.allowNestedSubagents ? "true" : "false"}`);
75
78
  }