@open-agent-toolkit/cli 0.2.35 → 0.2.37

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 (183) hide show
  1. package/assets/bundle-metadata.json +1 -1
  2. package/assets/docs/cli-utilities/backlog-lifecycle.md +18 -0
  3. package/assets/docs/cli-utilities/bootstrap.md +6 -3
  4. package/assets/docs/cli-utilities/config-and-local-state.md +26 -12
  5. package/assets/docs/cli-utilities/configuration.md +36 -13
  6. package/assets/docs/cli-utilities/tool-packs.md +423 -51
  7. package/assets/docs/provider-sync/scope-and-surface.md +4 -1
  8. package/assets/docs/reference/cli-reference.md +5 -3
  9. package/assets/docs/reference/file-locations.md +28 -4
  10. package/assets/docs/reference/troubleshooting.md +132 -2
  11. package/assets/docs/workflows/projects/lifecycle.md +21 -2
  12. package/assets/public-package-versions.json +4 -4
  13. package/assets/scripts/generate-oat-state.sh +441 -0
  14. package/assets/scripts/generate-thin-index.sh +200 -0
  15. package/assets/skills/oat-agent-instructions-analyze/SKILL.md +10 -5
  16. package/assets/skills/oat-agent-instructions-apply/SKILL.md +30 -5
  17. package/assets/skills/oat-brainstorm/SKILL.md +34 -8
  18. package/assets/skills/oat-brainstorm/references/destinations.md +6 -1
  19. package/assets/skills/oat-docs-analyze/SKILL.md +9 -4
  20. package/assets/skills/oat-docs-apply/SKILL.md +6 -3
  21. package/assets/skills/oat-pjm-add-backlog-item/SKILL.md +14 -1
  22. package/assets/skills/oat-pjm-decision/SKILL.md +22 -10
  23. package/assets/skills/oat-pjm-review-backlog/SKILL.md +20 -3
  24. package/assets/skills/oat-pjm-update-repo-reference/SKILL.md +20 -10
  25. package/assets/skills/oat-project-autonomous/references/gate-inventory.md +1 -1
  26. package/assets/skills/oat-project-document/SKILL.md +21 -3
  27. package/assets/skills/oat-project-document/references/docs/autonomy-contract.md +1 -1
  28. package/assets/skills/oat-project-implement/references/docs/autonomy-contract.md +1 -1
  29. package/assets/skills/oat-project-pr-final/references/docs/autonomy-contract.md +1 -1
  30. package/assets/skills/oat-project-quick-start/references/docs/autonomy-contract.md +1 -1
  31. package/assets/skills/oat-project-summary/SKILL.md +23 -11
  32. package/assets/skills/oat-repo-knowledge-index/SKILL.md +6 -3
  33. package/dist/commands/backlog/index.d.ts +2 -0
  34. package/dist/commands/backlog/index.d.ts.map +1 -1
  35. package/dist/commands/backlog/index.js +67 -23
  36. package/dist/commands/backlog/new.d.ts +3 -0
  37. package/dist/commands/backlog/new.d.ts.map +1 -1
  38. package/dist/commands/backlog/new.js +8 -21
  39. package/dist/commands/decision/agents-guidance.d.ts.map +1 -1
  40. package/dist/commands/decision/agents-guidance.js +2 -1
  41. package/dist/commands/decision/index.d.ts +2 -0
  42. package/dist/commands/decision/index.d.ts.map +1 -1
  43. package/dist/commands/decision/index.js +19 -3
  44. package/dist/commands/decision/new.d.ts +4 -0
  45. package/dist/commands/decision/new.d.ts.map +1 -1
  46. package/dist/commands/decision/new.js +11 -30
  47. package/dist/commands/doctor/index.d.ts +4 -0
  48. package/dist/commands/doctor/index.d.ts.map +1 -1
  49. package/dist/commands/doctor/index.js +254 -9
  50. package/dist/commands/init/tools/brainstorm/index.d.ts.map +1 -1
  51. package/dist/commands/init/tools/brainstorm/index.js +20 -6
  52. package/dist/commands/init/tools/docs/index.d.ts.map +1 -1
  53. package/dist/commands/init/tools/docs/index.js +4 -1
  54. package/dist/commands/init/tools/ideas/index.d.ts.map +1 -1
  55. package/dist/commands/init/tools/ideas/index.js +4 -1
  56. package/dist/commands/init/tools/index.d.ts +11 -2
  57. package/dist/commands/init/tools/index.d.ts.map +1 -1
  58. package/dist/commands/init/tools/index.js +459 -351
  59. package/dist/commands/init/tools/install-state.d.ts +2 -0
  60. package/dist/commands/init/tools/install-state.d.ts.map +1 -1
  61. package/dist/commands/init/tools/install-state.js +11 -0
  62. package/dist/commands/init/tools/project-management/agents-guidance.d.ts.map +1 -1
  63. package/dist/commands/init/tools/project-management/agents-guidance.js +3 -1
  64. package/dist/commands/init/tools/project-management/index.d.ts +1 -0
  65. package/dist/commands/init/tools/project-management/index.d.ts.map +1 -1
  66. package/dist/commands/init/tools/project-management/index.js +24 -55
  67. package/dist/commands/init/tools/project-management/install-project-management.d.ts +4 -0
  68. package/dist/commands/init/tools/project-management/install-project-management.d.ts.map +1 -1
  69. package/dist/commands/init/tools/project-management/install-project-management.js +4 -1
  70. package/dist/commands/init/tools/research/index.d.ts.map +1 -1
  71. package/dist/commands/init/tools/research/index.js +4 -1
  72. package/dist/commands/init/tools/shared/copy-helpers.d.ts.map +1 -1
  73. package/dist/commands/init/tools/shared/copy-helpers.js +10 -0
  74. package/dist/commands/init/tools/shared/skill-manifest.d.ts +15 -15
  75. package/dist/commands/init/tools/shared/skill-manifest.d.ts.map +1 -1
  76. package/dist/commands/init/tools/shared/skill-manifest.js +17 -122
  77. package/dist/commands/init/tools/utility/index.d.ts.map +1 -1
  78. package/dist/commands/init/tools/utility/index.js +4 -1
  79. package/dist/commands/init/tools/workflows/index.d.ts.map +1 -1
  80. package/dist/commands/init/tools/workflows/index.js +4 -1
  81. package/dist/commands/init/tools/workflows/install-workflows.d.ts.map +1 -1
  82. package/dist/commands/init/tools/workflows/install-workflows.js +2 -4
  83. package/dist/commands/pjm/adoption.d.ts +12 -0
  84. package/dist/commands/pjm/adoption.d.ts.map +1 -0
  85. package/dist/commands/pjm/adoption.js +47 -0
  86. package/dist/commands/pjm/doctor.d.ts +3 -2
  87. package/dist/commands/pjm/doctor.d.ts.map +1 -1
  88. package/dist/commands/pjm/doctor.js +28 -13
  89. package/dist/commands/pjm/index.d.ts +2 -0
  90. package/dist/commands/pjm/index.d.ts.map +1 -1
  91. package/dist/commands/pjm/index.js +11 -3
  92. package/dist/commands/pjm/init.d.ts +3 -0
  93. package/dist/commands/pjm/init.d.ts.map +1 -1
  94. package/dist/commands/pjm/init.js +37 -32
  95. package/dist/commands/pjm/migrate.d.ts +1 -0
  96. package/dist/commands/pjm/migrate.d.ts.map +1 -1
  97. package/dist/commands/pjm/migrate.js +1 -0
  98. package/dist/commands/pjm/template-source.d.ts +14 -0
  99. package/dist/commands/pjm/template-source.d.ts.map +1 -0
  100. package/dist/commands/pjm/template-source.js +56 -0
  101. package/dist/commands/remove/skills/remove-skills.d.ts.map +1 -1
  102. package/dist/commands/remove/skills/remove-skills.js +10 -19
  103. package/dist/commands/status/index.d.ts +5 -0
  104. package/dist/commands/status/index.d.ts.map +1 -1
  105. package/dist/commands/status/index.js +203 -2
  106. package/dist/commands/sync/index.d.ts.map +1 -1
  107. package/dist/commands/sync/index.js +40 -7
  108. package/dist/commands/sync/sync.types.d.ts +4 -0
  109. package/dist/commands/sync/sync.types.d.ts.map +1 -1
  110. package/dist/commands/tools/has/has-pack.d.ts +11 -2
  111. package/dist/commands/tools/has/has-pack.d.ts.map +1 -1
  112. package/dist/commands/tools/has/has-pack.js +33 -20
  113. package/dist/commands/tools/index.d.ts.map +1 -1
  114. package/dist/commands/tools/index.js +3 -1
  115. package/dist/commands/tools/info/info-tool.d.ts +3 -0
  116. package/dist/commands/tools/info/info-tool.d.ts.map +1 -1
  117. package/dist/commands/tools/info/info-tool.js +29 -4
  118. package/dist/commands/tools/list/list-tools.d.ts +3 -0
  119. package/dist/commands/tools/list/list-tools.d.ts.map +1 -1
  120. package/dist/commands/tools/list/list-tools.js +31 -4
  121. package/dist/commands/tools/migrate/index.d.ts +26 -0
  122. package/dist/commands/tools/migrate/index.d.ts.map +1 -0
  123. package/dist/commands/tools/migrate/index.js +312 -0
  124. package/dist/commands/tools/migrate/migrate-pack.d.ts +81 -0
  125. package/dist/commands/tools/migrate/migrate-pack.d.ts.map +1 -0
  126. package/dist/commands/tools/migrate/migrate-pack.js +324 -0
  127. package/dist/commands/tools/outdated/outdated-tools.d.ts +11 -0
  128. package/dist/commands/tools/outdated/outdated-tools.d.ts.map +1 -1
  129. package/dist/commands/tools/outdated/outdated-tools.js +33 -5
  130. package/dist/commands/tools/remove/index.d.ts.map +1 -1
  131. package/dist/commands/tools/remove/index.js +73 -20
  132. package/dist/commands/tools/remove/remove-tools.d.ts +28 -0
  133. package/dist/commands/tools/remove/remove-tools.d.ts.map +1 -1
  134. package/dist/commands/tools/remove/remove-tools.js +156 -26
  135. package/dist/commands/tools/shared/apply-pack-reconcile.d.ts +41 -0
  136. package/dist/commands/tools/shared/apply-pack-reconcile.d.ts.map +1 -0
  137. package/dist/commands/tools/shared/apply-pack-reconcile.js +126 -0
  138. package/dist/commands/tools/shared/auto-sync.d.ts +5 -2
  139. package/dist/commands/tools/shared/auto-sync.d.ts.map +1 -1
  140. package/dist/commands/tools/shared/auto-sync.js +1 -0
  141. package/dist/commands/tools/shared/content-digest.d.ts +3 -0
  142. package/dist/commands/tools/shared/content-digest.d.ts.map +1 -0
  143. package/dist/commands/tools/shared/content-digest.js +57 -0
  144. package/dist/commands/tools/shared/format-pack-inventory.d.ts +3 -0
  145. package/dist/commands/tools/shared/format-pack-inventory.d.ts.map +1 -0
  146. package/dist/commands/tools/shared/format-pack-inventory.js +21 -0
  147. package/dist/commands/tools/shared/install-sync-context.d.ts.map +1 -1
  148. package/dist/commands/tools/shared/install-sync-context.js +2 -25
  149. package/dist/commands/tools/shared/pack-inventory.d.ts +46 -0
  150. package/dist/commands/tools/shared/pack-inventory.d.ts.map +1 -0
  151. package/dist/commands/tools/shared/pack-inventory.js +207 -0
  152. package/dist/commands/tools/shared/pack-lifecycle.d.ts +34 -0
  153. package/dist/commands/tools/shared/pack-lifecycle.d.ts.map +1 -0
  154. package/dist/commands/tools/shared/pack-lifecycle.js +67 -0
  155. package/dist/commands/tools/shared/pack-manifest.d.ts +11 -0
  156. package/dist/commands/tools/shared/pack-manifest.d.ts.map +1 -0
  157. package/dist/commands/tools/shared/pack-manifest.js +384 -0
  158. package/dist/commands/tools/shared/pack-paths.d.ts +21 -0
  159. package/dist/commands/tools/shared/pack-paths.d.ts.map +1 -0
  160. package/dist/commands/tools/shared/pack-paths.js +35 -0
  161. package/dist/commands/tools/shared/pack-reconcile.d.ts +64 -0
  162. package/dist/commands/tools/shared/pack-reconcile.d.ts.map +1 -0
  163. package/dist/commands/tools/shared/pack-reconcile.js +158 -0
  164. package/dist/commands/tools/shared/project-tools-config.d.ts.map +1 -1
  165. package/dist/commands/tools/shared/project-tools-config.js +12 -38
  166. package/dist/commands/tools/shared/scan-tools.js +2 -2
  167. package/dist/commands/tools/shared/scoped-pack-intent.d.ts +34 -0
  168. package/dist/commands/tools/shared/scoped-pack-intent.d.ts.map +1 -0
  169. package/dist/commands/tools/shared/scoped-pack-intent.js +116 -0
  170. package/dist/commands/tools/shared/types.d.ts +22 -0
  171. package/dist/commands/tools/shared/types.d.ts.map +1 -1
  172. package/dist/commands/tools/update/index.d.ts.map +1 -1
  173. package/dist/commands/tools/update/index.js +30 -5
  174. package/dist/commands/tools/update/update-tools.d.ts +9 -1
  175. package/dist/commands/tools/update/update-tools.d.ts.map +1 -1
  176. package/dist/commands/tools/update/update-tools.js +176 -64
  177. package/dist/config/oat-config.d.ts +6 -0
  178. package/dist/config/oat-config.d.ts.map +1 -1
  179. package/dist/config/oat-config.js +49 -20
  180. package/dist/fs/paths.d.ts +12 -0
  181. package/dist/fs/paths.d.ts.map +1 -1
  182. package/dist/fs/paths.js +87 -1
  183. package/package.json +2 -2
@@ -11,18 +11,31 @@ This page covers CLI commands that manage bundled OAT tool packs and installed O
11
11
 
12
12
  - What it does: explains how bundled OAT packs are installed, updated, inspected, and removed.
13
13
  - When to use it: when you need to add capabilities to a repo, update installed skills, or understand which packs own which tools.
14
- - Primary commands: `oat tools list`, `oat tools has`, `oat tools install`, `oat tools update`, `oat tools remove`
14
+ - Primary commands: `oat tools list`, `oat tools has`, `oat tools install`, `oat tools update`, `oat tools remove`, `oat tools migrate`
15
+ - Coming from an earlier CLI: read [Upgrading from an earlier CLI](#upgrading-from-an-earlier-cli) for the changed install-scope default, PJM adoption gating, sparse `tools` config map, and per-pack `--json` shape
15
16
 
16
17
  ## Bundled packs at a glance
17
18
 
18
- - `core` - foundational diagnostics and docs access (`oat-doctor`, `oat-docs`)
19
- - `docs` - docs and agent-instructions governance workflows
20
- - `workflows` - project lifecycle skills, wave-program orchestration (`oat-wave-program`, `oat-wave-execute`), the project subagent-dispatch adapter, wrap-up reporting, reviewer agents, and core project templates
21
- - `ideas` - lightweight ideation and promotion flows
22
- - `utility` - review and repo-maintenance helpers plus portable subagent-selection guidance and the provider-neutral dispatch engine
23
- - `project-management` - file-backed backlog/reference skills plus backlog, roadmap, current-state, file-per-record decision, and AGENTS-guide templates
24
- - `research` - research, analysis, comparison, and synthesis skills
25
- - `brainstorm` - always-on brainstorming entry point with visual companion
19
+ | Pack | What it provides | Allowed scopes | Fresh-install default |
20
+ | -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | --------------------- |
21
+ | `core` | Foundational diagnostics and docs access (`oat-doctor`, `oat-docs`) plus the bundled documentation tree | user | user |
22
+ | `docs` | Docs and agent-instructions governance workflows, docs-app scaffold templates, and the shared tracking-resolution script | project, user | user |
23
+ | `workflows` | Project lifecycle skills, wave-program orchestration (`oat-wave-program`, `oat-wave-execute`), the project subagent-dispatch adapter, wrap-up reporting, reviewer agents, project templates, and helper scripts | project, user | user |
24
+ | `ideas` | Lightweight ideation and promotion flows plus idea templates | project, user | user |
25
+ | `utility` | Review and repo-maintenance helpers plus portable subagent-selection guidance and the provider-neutral dispatch engine | project, user | user |
26
+ | `project-management` | File-backed backlog/reference skills plus backlog, roadmap, current-state, file-per-record decision, and AGENTS-guide templates | project, user | user |
27
+ | `research` | Research, analysis, comparison, and synthesis skills plus the skeptical-evaluator agent | project, user | user |
28
+ | `brainstorm` | Always-on brainstorming entry point with visual companion | project, user | user |
29
+
30
+ Every reusable pack is a complete user-scope capability. On a **fresh** install
31
+ each pack lands at user scope by default, so capabilities follow you across
32
+ repositories. `core` is the one pack that is user-only: passing a conflicting
33
+ explicit `--scope project` is rejected rather than silently ignored.
34
+
35
+ On a **re-install**, existing placement wins. A pack already installed at
36
+ project scope stays at project scope; the fresh-install default never migrates
37
+ an existing install. Use [`oat tools migrate`](#oat-tools-migrate) when you
38
+ actually want to move one.
26
39
 
27
40
  ### Orchestration guidance and dispatch dependencies
28
41
 
@@ -94,6 +107,96 @@ It never falls back to a source checkout or copies core logic into the
94
107
  workflows pack. See [Explainer Kit](../workflows/skills/explainer-kit.md) for
95
108
  the usage and lifecycle contract.
96
109
 
110
+ ## Scope, intent, and inventory
111
+
112
+ Two independent facts describe a pack:
113
+
114
+ - **Intent** is what you asked for. It is stored per scope as
115
+ `tools.<pack>: true` in that scope's config file (`.oat/config.json` for
116
+ project scope, `~/.oat/config.json` for user scope). Intent is _true-or-absent_:
117
+ removing a pack deletes the key rather than writing `false`.
118
+ - **Inventory** is what is actually on disk right now: every managed asset the
119
+ release manifest declares for that pack and scope, its presence, and its
120
+ version or content digest.
121
+
122
+ Commands report both. `oat tools list` and `oat tools info` show placement,
123
+ intent source, and completeness. `oat status` and `oat doctor` report drift
124
+ between intent and inventory with a scoped recovery command.
125
+
126
+ A pack is **complete** at a scope when every managed asset the current release
127
+ declares for that scope is present, **partial** when only some are, and
128
+ **absent** when none are.
129
+
130
+ ### Where pack assets land
131
+
132
+ | Asset kind | Project scope | User scope | Ownership |
133
+ | ----------------- | ---------------------------------------------------------------------------------- | ---------------------------- | --------------------------------------------------- |
134
+ | Skill | `.agents/skills/<name>/` | `~/.agents/skills/<name>/` | Managed — updated and removed by OAT |
135
+ | Agent | `.agents/agents/<name>.md` | `~/.agents/agents/<name>.md` | Managed (see the user-scope agent limitation below) |
136
+ | Template | `.oat/templates/<name>` | `~/.oat/templates/<name>` | Seeded once at project scope; managed at user scope |
137
+ | Script | `.oat/scripts/<name>` | `~/.oat/scripts/<name>` | Managed, executable |
138
+ | Bundled docs tree | not applicable | `~/.oat/docs/` | Managed directory (core pack) |
139
+ | Seed file | `.oat/ideas/…`, `.oat/projects-root`, `.oat/config.json`, project `.gitkeep` files | `~/.oat/ideas/…` | Seeded once, then owned by you |
140
+
141
+ Seed files default to both scopes, so `oat tools install ideas --scope user`
142
+ creates `~/.oat/ideas/backlog.md` and `~/.oat/ideas/scratchpad.md`. Only the
143
+ `workflows` project-scaffold seeds — `.oat/projects-root`, `.oat/config.json`,
144
+ and the project `.gitkeep` files — are pinned to project scope.
145
+
146
+ #### User-scope agents reach no provider
147
+
148
+ Canonical **agents** are installed at either scope, but only project scope
149
+ materializes a provider view for them. At user scope the sync pipeline
150
+ enumerates skills only, and the sole user-scope agent materialization is the
151
+ bundled managed role file set (`oat-phase-implementer.md` and
152
+ `oat-reviewer.md`). A pack installed at user scope therefore writes its agents
153
+ to `~/.agents/agents/` where no provider can see them — for example
154
+ `oat tools install workflows --scope user` leaves `oat-codebase-mapper` without
155
+ a provider agent, and `oat tools install research --scope user` does the same
156
+ for `skeptical-evaluator`.
157
+
158
+ `oat status` and `oat doctor` name the affected agents with a
159
+ `user-agent-unmaterialized` finding rather than reporting the pack as complete
160
+ without qualification. Install the pack at **project scope** when you need its
161
+ agents; `oat tools update` cannot repair this, because it is a scope limitation
162
+ rather than drift.
163
+
164
+ Repository templates under `.oat/templates/` are **owner overrides**. Once a
165
+ project-scope template exists, OAT will not rewrite it: the managed default now
166
+ lives at user scope and in the bundle. Delete the repository copy to resume
167
+ managed-default behavior. `oat status` and `oat doctor` report retained
168
+ overrides so the divergence is visible rather than silent.
169
+
170
+ ### Evolving pack membership
171
+
172
+ Packs evolve between releases. A pack that is installed at a scope is
173
+ reconciled against the **current** release membership, not the membership it
174
+ had when you first installed it:
175
+
176
+ - `oat tools update --pack <pack>` and `oat tools update --all` add newly
177
+ bundled skills, agents, templates, and scripts to the scopes where the pack
178
+ is already installed.
179
+ - If every managed asset went missing but intent is still declared, update
180
+ repairs the pack from intent rather than treating it as uninstalled.
181
+ - Identical non-versioned assets are compared by content digest, so a refresh
182
+ that changes nothing performs no write.
183
+
184
+ ### Legacy `false` intent
185
+
186
+ Older repositories may still carry `tools.<pack>: false` in shared config.
187
+ That value is **not** authoritative and is never treated as an opt-out. When
188
+ managed assets exist alongside a legacy `false`, OAT reports a
189
+ `legacy-false-conflict` diagnostic and points at the scoped update command that
190
+ adopts the install. Removing the pack deletes the key entirely.
191
+
192
+ ### Duplicate cross-scope installs
193
+
194
+ A pack installed at both project and user scope is a legitimate state, not an
195
+ error. OAT reports it as a `duplicate-scope` diagnostic with the affected paths
196
+ and installed versions, and **does not infer provider precedence** — which copy
197
+ a given host loads is the host's behavior, not OAT's. Resolve it explicitly
198
+ with `oat tools migrate` when you want a single owner.
199
+
97
200
  ## `oat tools` command group
98
201
 
99
202
  The `oat tools` command group provides a unified interface for managing installed tools (skills and agents) across scopes.
@@ -119,12 +222,21 @@ Other eligible commands keep the passive update notice and never launch the inst
119
222
 
120
223
  ## Install vs. initialize
121
224
 
122
- The `project-management` pack has two lifecycle steps:
225
+ The `project-management` pack separates **capability** from **repository
226
+ adoption**, and the two are tracked independently:
123
227
 
124
- - **Install**: `oat tools install project-management` (or the legacy `oat init tools project-management`) copies project-management skills into `.agents/skills/` and template sources into `.oat/templates/`.
125
- - **Initialize**: `oat pjm init` instantiates the two-layer working repo-reference surface under `.oat/repo/`.
228
+ - **Install (capability)**: `oat tools install project-management` (or the
229
+ legacy `oat init tools project-management`) installs the PJM skills and
230
+ template sources. Like every other pack it defaults to **user** scope on a
231
+ fresh install, so `~/.agents/skills/` and `~/.oat/templates/` receive the
232
+ managed assets and no repository file is touched.
233
+ - **Initialize (adoption)**: `oat pjm init` instantiates the two-layer working
234
+ repo-reference surface under `.oat/repo/`, upserts the repository `AGENTS.md`
235
+ project-management guidance, and records explicit adoption in
236
+ `.oat/config.json` as `pjm.initialized: true` with a `pjm.schemaVersion`.
126
237
 
127
- Installing the pack makes the skills and templates available; it does not create the repo's working project-management reference docs. Run `oat pjm init` when you want to scaffold the canonical PJM surface for a repo:
238
+ Having the pack installed does **not** mean this repository uses PJM. Adoption
239
+ is a per-repository decision recorded by `oat pjm init`:
128
240
 
129
241
  ```bash
130
242
  oat pjm init
@@ -140,11 +252,68 @@ The canonical surface splits active operational state (under `pjm/`) from durabl
140
252
 
141
253
  Decisions are now file-per-record under `reference/decisions/` (created and indexed with the [`oat decision`](config-and-local-state.md#oat-decision-) command group), replacing the legacy single `decision-record.md`. Repos still on the old `reference/` layout can migrate with `oat pjm migrate`.
142
254
 
143
- For decision records without the broader PJM surface, run `oat decision init` directly. It creates only the decision directory, generated index, and decision-specific AGENTS guidance; it does not require the `project-management` pack or create current state, roadmap, and backlog artifacts. If the pack is installed later, its root guidance is maintained as a separate managed section so the decision instructions remain independently reusable.
255
+ > **Current migration prerequisite:** In CLI `0.2.37`, `oat pjm migrate` still
256
+ > requires project-scope `tools.project-management: true` in `.oat/config.json`;
257
+ > a user-only pack install does not satisfy that gate. In an adopted legacy
258
+ > repository, run `oat config set tools.project-management true` before the
259
+ > migration preview. Removing this temporary coupling is tracked by
260
+ > `BL-260827-correct-scope-and-adoption`.
261
+
262
+ Decision records still require repository PJM adoption. Run `oat pjm init` first: like every repository-mutating PJM command, `oat decision init` fails closed in an unadopted repository, writes nothing, and returns `oat pjm init` as the recovery. Once the repository is adopted, `oat decision init` scaffolds only the decision surface — the decision directory, generated index, and decision-specific AGENTS guidance — without touching current state, roadmap, or backlog artifacts. It does not require the `project-management` pack. If the pack is installed later, its root guidance is maintained as a separate managed section so the decision instructions remain independently reusable.
144
263
 
145
264
  `oat pjm init` is idempotent and non-destructive. Existing reference docs are skipped and left unchanged, so curated repo state is not overwritten on repeated runs.
146
265
 
147
- Run `oat pjm doctor` to check an existing surface after the `project-management` pack is enabled: it reports missing canonical files, leftover template frontmatter, and legacy/loose/second-roadmap drift, and accepts `--json` for machine-readable output. When the pack is disabled or not configured, doctor reports PJM as disabled and skips drift checks. The same gated checks also run under project-scope `oat doctor`.
266
+ ### Adoption state and the write guard
267
+
268
+ `resolvePjmAdoption()` resolves one of four repository states, and every
269
+ repository-mutating PJM command checks it before writing anything:
270
+
271
+ | State | Meaning | Recovery |
272
+ | ------------------------ | ----------------------------------------------------------------- | -------------- |
273
+ | `declared` | `pjm.initialized: true` is present in `.oat/config.json` | none needed |
274
+ | `inferred-legacy` | The full canonical scaffold exists without an explicit marker | none needed |
275
+ | `partial-initialization` | Some canonical scaffold files exist but the surface is incomplete | `oat pjm init` |
276
+ | `none` | The repository has not adopted PJM | `oat pjm init` |
277
+
278
+ `oat pjm`, `oat backlog`, and `oat decision` mutations **fail closed** for
279
+ `partial-initialization` and `none`. They write nothing and return an error
280
+ naming the repository path and `oat pjm init` as the recovery. `oat backlog
281
+ init` and `oat decision init` are no longer alternate adoption paths for the
282
+ full PJM surface.
283
+
284
+ Run `oat pjm doctor` to inspect an existing surface. It is read-only, reports
285
+ missing canonical files, leftover template frontmatter, and
286
+ legacy/loose/second-roadmap drift, and accepts `--json`. Its JSON result carries
287
+ an additive adoption object:
288
+
289
+ ```json
290
+ {
291
+ "adoption": {
292
+ "state": "declared",
293
+ "repoRoot": "/repo/.oat/repo",
294
+ "recovery": null
295
+ }
296
+ }
297
+ ```
298
+
299
+ Consumers that write repository PJM state branch on `adoption.state`, not on
300
+ pack presence. Project-scope `oat doctor` aggregates the same `pjm:*` checks and
301
+ keys them on adoption state rather than on `tools.project-management`, so a
302
+ repository that adopted PJM with a user-scope pack is diagnosed correctly.
303
+
304
+ ### Template precedence
305
+
306
+ PJM templates resolve through three tiers, first match wins:
307
+
308
+ 1. **Repository** — `.oat/templates/<name>` in this repo. An existing repository
309
+ template is an owner override and is never rewritten by pack updates.
310
+ 2. **User** — `~/.oat/templates/<name>`, the managed default that
311
+ `oat tools update --pack project-management --scope user` keeps current.
312
+ 3. **Bundle** — the templates shipped inside the installed CLI.
313
+
314
+ Delete a repository template to fall back to the managed user default. If a
315
+ template is missing from all three tiers, the command errors rather than
316
+ inventing content.
148
317
 
149
318
  Useful options:
150
319
 
@@ -163,6 +332,7 @@ Key behavior:
163
332
 
164
333
  - Scans installed skills and agents across project and user scopes
165
334
  - Displays version, pack (`core`, `docs`, `ideas`, `workflows`, `utility`, `project-management`, `research`, `brainstorm`, `custom`), and status (`current`, `outdated`, `newer`, `not-bundled`)
335
+ - Also reports per-pack placement (`project`, `user`, `both`, `unavailable`), intent source (`declared`, `inferred-legacy`, `none`), completeness, missing managed assets, and any inventory diagnostics
166
336
  - Supports `--scope` filtering and `--json` output
167
337
 
168
338
  ### `oat tools outdated`
@@ -174,6 +344,7 @@ Purpose:
174
344
  Key behavior:
175
345
 
176
346
  - Filters scan results to tools where the installed version is older than the bundled version
347
+ - Also reports non-versioned managed assets whose content has drifted from the bundle, and packs that are declared but absent, as repairable
177
348
  - Displays installed and available versions side by side
178
349
  - Supports `--scope` filtering and `--json` output
179
350
 
@@ -199,9 +370,42 @@ Key behavior:
199
370
 
200
371
  - Defaults to effective availability across project and user scopes
201
372
  - Accepts `--scope project`, `--scope user`, or `--scope all`
373
+ - **Availability is complete-only.** A scope counts as available only when every
374
+ managed asset the current release declares for that scope is present. A
375
+ partially installed pack reports `false` so callers never build on a
376
+ half-installed capability
202
377
  - Prints `true` or `false` in plain mode
203
- - With the global `--json` flag, emits `{ "pack": "<pack>", "available": <boolean>, "scopes": ["project", "user"] }`; `scopes` contains only locations where the pack is currently found
378
+ - With the global `--json` flag, emits the full availability record:
379
+
380
+ ```json
381
+ {
382
+ "pack": "docs",
383
+ "available": false,
384
+ "scopes": [],
385
+ "unavailableScopes": [],
386
+ "completeness": { "project": "partial", "user": "absent" },
387
+ "missing": [
388
+ {
389
+ "scope": "project",
390
+ "asset": "skill:oat-docs-apply",
391
+ "path": "/repo/.agents/skills/oat-docs-apply"
392
+ }
393
+ ]
394
+ }
395
+ ```
396
+
397
+ - `scopes` lists only the scopes where the pack is **complete**;
398
+ `unavailableScopes` lists requested scopes the pack could not be checked in —
399
+ either because the pack does not allow that scope at all (for example
400
+ `project` for `core`) or because the scope could not be resolved here;
401
+ `completeness` and `missing` explain a `false` result so it is actionable
402
+ - Outside a Git repository, the default `--scope all` query still answers from
403
+ user scope and lists `project` in `unavailableScopes` instead of failing. An
404
+ explicit `--scope project` outside a repository is still a hard failure
204
405
  - Exits `0` for every valid query, including an unavailable pack, `1` for an invalid pack or other actionable input error, and `2` for an unexpected scan or runtime failure
406
+ - `oat tools has <pack>` answers **capability availability**, not repository
407
+ adoption. For `project-management` specifically, use
408
+ `oat pjm doctor --json` to learn whether _this repository_ has adopted PJM
205
409
 
206
410
  Examples:
207
411
 
@@ -222,16 +426,18 @@ Key behavior:
222
426
  - Same pack selection and install flow as `oat init tools`
223
427
  - Pack-oriented install subcommands: `core`, `docs`, `ideas`, `workflows`, `utility`, `project-management`, `research`, `brainstorm`
224
428
  - Interactive installs show each pack's current install location in the picker so already-installed packs are visible before you submit
225
- - Installing is **additive**: choosing a scope for a pack never removes it from another scope. A user-eligible pack installed at user scope plus a project install ends up at `project + user`, not moved
226
- - For each user-eligible pack (`ideas`, `docs`, `workflows`, `utility`, `research`, `brainstorm`), the interactive flow offers a per-pack end-state selector (`project`, `user`, or `both`) defaulting to the pack's current placement; leaving the default makes no changes for that pack
429
+ - Installing is **additive**: choosing a scope for a pack never removes it from another scope. A pack installed at user scope plus a project install ends up at `project + user`, not moved
430
+ - For every pack that allows both scopes (`ideas`, `docs`, `workflows`, `utility`, `project-management`, `research`, `brainstorm`), the interactive flow offers a per-pack end-state selector (`project`, `user`, or `both`) defaulting to the pack's current placement; leaving the default makes no changes for that pack
431
+ - Fresh installs default to **user scope** for every pack; existing installs keep their current placement
227
432
  - `oat init --setup` uses this same additive scope resolver. In guided setup, choosing to customize scope reaches the per-pack selector; choosing the recommended defaults, or running non-interactively, applies additive per-pack defaults without removals
228
- - The `brainstorm` pack defaults to user scope on fresh installs (driven by `PACK_METADATA[brainstorm].defaultScope = 'user'`); existing installs keep their current placement on re-install, so a re-install never moves a pack between scopes
433
+ - Every pack's fresh-install default is user scope (`defaultScope` in the release manifest); existing installs keep their current placement on re-install, so a re-install never moves a pack between scopes or creates a second copy at the other one. This applies to the per-pack subcommands too: a bare `oat tools install docs` in a repository where `docs` is already at project scope stays at project scope, and only an explicit `--scope` overrides that
229
434
  - Removing a pack from a scope happens only when you explicitly choose a narrower end-state in the interactive flow (e.g. a pack at `both` set to `project` only). All staged removals are shown in a single change summary and applied only after one batch confirmation — declining makes no changes
230
435
  - Non-interactive installs (including `--scope project`, `--scope user`, and the default pack set) are strictly additive and never remove a pack from a scope. Removal is interactive-only
231
436
  - Tracks installed vs bundled skill versions and reports outdated skills
232
- - Reconciles shared repo config from project-scoped canonical assets only; a user-only install does not set `tools.<pack>: true`
233
- - Refreshes the managed `OAT tools` section in the repository-root `AGENTS.md`.
234
- - Installing the `project-management` pack—through either the aggregate picker or `oat tools install project-management`—also upserts a managed `OAT project-management` section. It points agents to `.oat/repo/AGENTS.md` for active PJM and durable-reference routing, summarizes when to consult it, and gives decision-specific guidance for reviewing and creating durable records without hand-editing the generated index.
437
+ - Writes pack intent into the config file for the scope you installed into: a project install sets `tools.<pack>: true` in `.oat/config.json`, and a user install sets it in `~/.oat/config.json`. A user-only install never writes repository config
438
+ - A user-only install needs no Git repository and performs no repository writes
439
+ - Refreshes the managed `OAT tools` section in the repository-root `AGENTS.md` **only for project-scope runs of the aggregate `oat tools install`**. The per-pack subcommands (`oat tools install workflows`, `oat tools install docs`, and the rest) never write `AGENTS.md`, at either scope
440
+ - Repository `AGENTS.md` guidance for project management is owned by adoption, not by pack placement. Installing the `project-management` pack no longer upserts a managed `OAT project-management` section; `oat pjm init` writes that repository guidance when the repository actually adopts PJM
235
441
  - Interactive runs can prompt to update selected outdated skills
236
442
  - Successful installs report the final scope chosen for each pack, including `project + user` when a pack is installed in both, and auto-sync only the scopes actually changed by the install so untouched scopes are never re-synced or pruned
237
443
  - Install-triggered auto-sync limits removal planning to the canonical entries from the pack that was just installed, so stale manifest drift in unrelated packs does not delete other provider views
@@ -248,9 +454,12 @@ Key behavior:
248
454
  - Accepts a tool name, `--pack <pack>`, or `--all` (mutually exclusive)
249
455
  - With no target, exits without mutation and suggests the explicit bulk command `oat tools update --all`; invalid packs and conflicting targets keep their own targeted diagnostics
250
456
  - Compares installed versions against bundled versions and copies updated assets
251
- - For `--pack <pack>` and `--all`, an already-installed pack is reconciled to include newly added bundled skills or agents in that same scope
252
- - Pack-targeted updates intentionally rewrite bundled template and script companions in place, even when the pack's installed skills are already current
253
- - For `--pack <pack>` and `--all`, shared repo config is also reconciled from a project-scoped installed-pack scan so `tools.*` reflects repository installation state and stale `true` flags are cleared
457
+ - For `--pack <pack>` and `--all`, an already-installed pack is reconciled to the **current** release membership in the scopes where it is installed, adding newly bundled skills, agents, templates, and scripts
458
+ - A pack whose managed assets are all missing but whose intent is still declared is repaired from intent rather than skipped
459
+ - Managed template and script companions are refreshed at **user** scope. A project-scope repository template is an owner override and is left alone
460
+ - Non-versioned assets are compared by content digest, so an identical refresh is a no-op instead of a rewrite
461
+ - Update persists inferred legacy intent only after a successful explicit mutation, so a read never rewrites your config
462
+ - `--scope all` outside a Git repository completes the user-scope work instead of failing. Unlike `oat status` and `oat doctor`, update skips project scope silently and does not name it in the result; an explicitly requested `--scope project` outside a repository is still a hard failure
254
463
  - Dry-run mode with `--dry-run`; auto-sync after mutations by default
255
464
  - Use `--no-sync` to skip auto-sync
256
465
  - Reports tools that are already current, newer than bundled, or not bundled (custom)
@@ -264,27 +473,94 @@ Purpose:
264
473
  Key behavior:
265
474
 
266
475
  - Accepts a tool name, `--pack <pack>`, or `--all` (mutually exclusive)
267
- - Removes skill directories and agent `.md` files from canonical locations
268
- - For `--pack <pack>` and `--all`, shared repo config is reconciled from a post-removal project scan; removing the last project copy clears project state even when a user copy remains
476
+ - Removal is planned from the release manifest, so it deletes **only** assets OAT manages for that pack and scope
477
+ - Retained by design: project-scope repository template overrides, mutable seed files (`.oat/ideas/…`, `.oat/projects-root`, project `.gitkeep` files), and shared scripts still owned by another installed pack. Retained owner data is reported rather than silently skipped
478
+ - Already-missing files are not an error
479
+ - On success the pack's intent key is deleted from that scope's config file. It is never rewritten as `false`. A failed removal retains the key
480
+ - A removal that finds no trace of a pack at a scope leaves that pack's intent alone. `No tools to remove.` means no durable state changed either, so `--all` in a repository whose packs are already gone will not quietly rewrite `.oat/config.json` or destroy the intent [`oat tools update`](#oat-tools-update) restores a fully-missing pack from
481
+ - In `--json` output, the additive `packOutcomes` array reports `pack`, `scope`,
482
+ and `removed` for each attempted pack/scope pair. Automation should use
483
+ `removed: true` as the evidence that removal acted on that pack and its scoped
484
+ intent was eligible to be cleared; `removed: false` is a no-op and preserves
485
+ intent.
486
+ - Removal-triggered sync prunes exactly the canonical provider views for the removed paths in that scope, leaving other scopes and packs untouched
269
487
  - Dry-run mode with `--dry-run`; auto-sync after mutations by default
270
488
  - Use `--no-sync` to skip auto-sync
271
489
 
272
- ## Shared config signal: `tools.*`
490
+ ### `oat tools migrate`
491
+
492
+ Purpose:
493
+
494
+ - Move one installed pack between scopes with a preview, a verified
495
+ destination, and an explicitly confirmed source removal
496
+
497
+ Key behavior:
498
+
499
+ - Requires `--pack <pack>`, `--from <scope>`, and `--to <scope>`; source and
500
+ destination must differ
501
+ - Always previews first. The preview lists additions, duplicates, conflicts,
502
+ planned source removals, retained owner data, and any inventory diagnostics
503
+ - `--dry-run` stops after the preview and exits `1` when the migration is
504
+ blocked by destination conflicts
505
+ - **Destination first, source second.** The destination is installed and
506
+ re-inventoried, and destination intent is written only after the pack is
507
+ verified complete there. Only then is source removal offered
508
+ - Source removal requires an interactive confirmation. Declining leaves the
509
+ pack installed at **both** scopes with the destination verified — a safe,
510
+ recoverable state, not a failure. Non-interactive runs stop at the same point
511
+ - If source removal or its sync fails partway, the destination is kept, source
512
+ intent is retained, and structured recovery instructions are printed. Rerun
513
+ the same command to finish
514
+ - There is no force flag: a blocked migration is resolved by fixing the
515
+ conflict, not by bypassing verification
516
+ - With `--json`, emits `{ "operation": "migrate", "dryRun": <boolean>, "preview": …, "status": …, "recovery": [...] }`.
517
+ `status` is one of `previewed`, `migrated`, `retained-both`, `blocked`,
518
+ `destination-sync-failed`, `source-removal-failed`, or `source-sync-failed`
519
+
520
+ ```bash
521
+ oat tools migrate --pack docs --from project --to user --dry-run
522
+ oat tools migrate --pack docs --from project --to user
523
+ ```
524
+
525
+ To roll a migration back, run it in the opposite direction. Because the
526
+ destination is always verified before the source is touched, a rollback is the
527
+ same safe two-phase operation.
528
+
529
+ ## Pack intent: `tools.<pack>`
273
530
 
274
- Tool-pack lifecycle commands maintain a project installation snapshot in shared repo config under `.oat/config.json`.
531
+ Pack intent is recorded per scope, in that scope's own config file:
275
532
 
276
- - Install, update, and remove reconcile the snapshot from project-scoped canonical assets only. User-only operations never set a shared `true` flag.
277
- - When at least one project pack is installed, reconciliation writes the complete eight-pack boolean map: `core`, `ideas`, `docs`, `workflows`, `utility`, `project-management`, `research`, and `brainstorm`.
278
- - When no project packs remain, reconciliation removes the entire `tools` map. It preserves unrelated shared keys, avoids creating a default-only config file, and skips unchanged writes.
533
+ | Scope | Config file | Key |
534
+ | ------- | -------------------- | -------------------- |
535
+ | project | `.oat/config.json` | `tools.<pack>: true` |
536
+ | user | `~/.oat/config.json` | `tools.<pack>: true` |
279
537
 
280
- Use `oat config get tools.<pack>` to inspect this project snapshot. A manual `oat config set tools.<pack> ...` value is a shared override that the next lifecycle reconciliation may replace.
538
+ - Intent is **true-or-absent**. Installing writes `true` for the scope you
539
+ installed into; removing deletes the key. OAT never writes `false`.
540
+ - A user-scope install never writes repository config, and a project-scope
541
+ install never writes user config.
542
+ - Intent for one pack is never derived from another pack's key, and no
543
+ command writes the full eight-pack map.
544
+ - `.oat/config.local.json` is not an intent surface; per-developer state stays
545
+ out of pack intent.
546
+ - A manual `oat config set tools.<pack> true` is an override that the next
547
+ lifecycle mutation for that scope may replace with the reconciled value.
281
548
 
282
- Use `oat tools has <pack>` when a workflow needs current effective availability from project or user scope. For example, `oat-project-document` checks `oat tools has project-management` before auto-running repo-reference refresh work.
549
+ Use `oat config get tools.<pack>` to inspect declared intent, and `oat tools
550
+ list`, `oat tools info <name>`, `oat status`, or `oat doctor` to inspect what is
551
+ actually installed.
552
+
553
+ Use `oat tools has <pack>` when a workflow needs current effective capability
554
+ availability across project and user scope. Availability is a capability
555
+ question; it is **not** evidence that the current repository adopted anything.
556
+ Workflows that write repository PJM state check `oat pjm doctor --json` for
557
+ adoption instead.
283
558
 
284
559
  ## Workflows pack
285
560
 
286
- The workflows pack is installable at project scope, user scope, or both. A
287
- user-scope install carries the complete versioned asset set:
561
+ The workflows pack is installable at project scope, user scope, or both, and
562
+ defaults to user scope on a fresh install. A user-scope install carries the
563
+ complete versioned asset set:
288
564
 
289
565
  - skills and agents → `~/.agents/skills/` and `~/.agents/agents/`;
290
566
  - templates → `~/.oat/templates/`;
@@ -305,8 +581,10 @@ retains its existing scaffolding and local-path setup.
305
581
  `oat tools update --pack workflows --scope user` refreshes all four asset
306
582
  classes in place, including newly bundled skills and agents. Pack removal and a
307
583
  confirmed aggregate scope reduction remove those same user-level assets.
308
- Companion template and script removal is user-scope-only; project-scope removal
309
- leaves repo-local `.oat/templates/` and `.oat/scripts/` assets intact.
584
+ Companion template removal is user-scope-only; project-scope removal leaves
585
+ repo-local `.oat/templates/` overrides and mutable project seeds intact. The
586
+ shared `resolve-tracking.sh` script is co-owned by the `docs` and `workflows`
587
+ packs and is retained while either pack still owns it in that scope.
310
588
 
311
589
  ## Core pack
312
590
 
@@ -317,7 +595,8 @@ The `core` pack contains foundational diagnostic and documentation skills:
317
595
 
318
596
  Key behavior:
319
597
 
320
- - Core pack always installs at **user scope** (`~/.agents/skills/`). It does not honor a different scope, and passing a conflicting explicit `--scope` (e.g. `oat init tools core --scope project`) is rejected with an error rather than silently ignored; omit `--scope` or pass `--scope user`. This ensures core skills are available in any directory.
598
+ - Core pack always installs at **user scope** (`~/.agents/skills/`). It is the only pack whose sole allowed scope is `user`, and passing a conflicting explicit `--scope` (e.g. `oat init tools core --scope project`) is rejected with an error rather than silently ignored; omit `--scope` or pass `--scope user`. This ensures core skills are available in any directory.
599
+ - `~/.oat/docs/` is a managed directory asset: its completeness and drift are compared as a whole tree, so a partially deleted docs tree is reported as a partial `core` install rather than passing silently.
321
600
  - Core is checked by default in the `oat init tools` guided setup.
322
601
  - Installation also bundles OAT documentation to `~/.oat/docs/` for the oat-docs skill.
323
602
  - `oat tools update --pack core` refreshes both skills and `~/.oat/docs/` documentation.
@@ -343,7 +622,8 @@ init`) with capability-gated post-patches, build verification, config
343
622
 
344
623
  Key behavior:
345
624
 
346
- - Docs pack installs at the selected scope, typically `project`.
625
+ - Docs pack installs at the selected scope and defaults to user scope on a
626
+ fresh install.
347
627
  - It complements the `core` pack: `oat-docs` answers questions from bundled
348
628
  docs, while the `docs` pack adds analyze/apply workflows.
349
629
  - `oat tools install docs` is the preferred install path; `oat init tools docs`
@@ -381,12 +661,10 @@ project-independent brainstorming conversations:
381
661
 
382
662
  Key behavior:
383
663
 
384
- - **Default user scope.** The `brainstorm` pack is user-eligible and defaults
385
- to user scope so the always-on trigger fires consistently across directories
386
- and machines. This is driven by the generalized pack-metadata mechanism
387
- (`PACK_METADATA[brainstorm].defaultScope = 'user'`); other user-eligible
388
- packs (`ideas`, `docs`, `utility`, `research`) still default to project scope
389
- unless their metadata is updated.
664
+ - **Default user scope.** The `brainstorm` pack defaults to user scope so the
665
+ always-on trigger fires consistently across directories and machines. Every
666
+ other reusable pack now shares that default; the per-pack `defaultScope` lives
667
+ in the release manifest.
390
668
  - **Existing-install precedence.** Re-running install on a pack that is
391
669
  already installed at project scope preserves that scope — `defaultScope` only
392
670
  applies to fresh installs. This protects users from unexpected scope
@@ -417,18 +695,111 @@ config get activeProject` lookup resolves active project state.
417
695
  consulted by the skill at destination-identification time.
418
696
  - **Pack lifecycle.** `oat tools install brainstorm`, `oat tools update --pack
419
697
  brainstorm`, and `oat tools remove --pack brainstorm` manage the skill plus
420
- visual-companion bundle as a unit. Project installs participate in the shared
421
- project snapshot; user-only installs remain available through `oat tools has
422
- brainstorm` without setting `tools.brainstorm` in shared config.
698
+ visual-companion bundle as a unit. A project install records
699
+ `tools.brainstorm: true` in `.oat/config.json`; a user install records it in
700
+ `~/.oat/config.json`. Either placement satisfies `oat tools has brainstorm`.
423
701
 
424
702
  ### Auto-sync behavior
425
703
 
426
- All mutation commands (`install`, `update`, `remove`) automatically run `oat sync --scope <scope>` after successful operations. This ensures provider views stay in sync with canonical assets without manual intervention.
704
+ All mutation commands (`install`, `update`, `remove`, `migrate`) automatically run `oat sync --scope <scope>` after successful operations. This ensures provider views stay in sync with canonical assets without manual intervention.
427
705
 
428
706
  Use `--no-sync` on any mutation command to skip this step.
429
707
 
430
708
  For `oat tools install`, the follow-up sync still refreshes provider views immediately, but its removal pass is scoped to the canonical entries that were just installed. This avoids deleting unrelated provider views when a worktree has stale manifest entries for packs whose canonical content is absent locally.
431
709
 
710
+ Removal and migration use the symmetric contract: the follow-up sync prunes exactly the provider views for the canonical paths that were removed, in that scope only, and only after the canonical source is confirmed absent.
711
+
712
+ ## Upgrading from an earlier CLI
713
+
714
+ User-scope tool packs and explicit PJM adoption changed several defaults and
715
+ exit codes. Nothing here is data-destructive, and legacy config keeps working —
716
+ `tools.<pack>: false` still parses, complete pre-adoption PJM scaffolds are
717
+ grandfathered as `inferred-legacy`, and no CLI flag was removed or renamed. But
718
+ several commands you already run behave differently.
719
+
720
+ ### Install scope defaults flipped to user
721
+
722
+ Every pack's fresh-install default is now **user** scope; it used to be project
723
+ scope. A fresh `oat tools install docs` in a repository therefore lands in
724
+ `~/.agents/` rather than the repository.
725
+
726
+ Existing installs are not moved: both the aggregate installer and the per-pack
727
+ subcommands resolve an already-installed pack to its current placement, so a
728
+ re-install neither migrates the pack nor creates a second copy at the other
729
+ scope. An explicit `--scope` still wins over that. Use
730
+ [`oat tools migrate`](#oat-tools-migrate) when you actually want to move a pack.
731
+
732
+ If you already have a pack at both scopes, `oat doctor` reports it as
733
+ [`duplicate-scope`](#duplicate-cross-scope-installs) and **exits 1**. That is a
734
+ new non-zero exit for a state the previous release did not diagnose; resolve it
735
+ with `oat tools migrate`, or treat the exit code accordingly in scripts.
736
+
737
+ ### PJM commands fail closed without adoption
738
+
739
+ Repository PJM state now requires explicit adoption via `oat pjm init`:
740
+
741
+ - `oat pjm doctor` **exits 1** in an unadopted repository. It previously
742
+ reported a passing `pjm:disabled` check.
743
+ - `oat backlog init`, `oat backlog new`, `oat backlog regenerate-index`,
744
+ `oat backlog archive`, `oat decision init`, `oat decision new`, and
745
+ `oat decision regenerate-index` **exit 1 and write nothing** in an unadopted
746
+ repository, naming `oat pjm init` as the recovery. Previously `init` was an
747
+ alternate adoption path and the other subcommands were ungated.
748
+
749
+ Installing the `project-management` pack does not adopt a repository. Run
750
+ `oat pjm init` once per repository that should carry PJM state.
751
+
752
+ ### The `tools` config map is now sparse
753
+
754
+ Pack intent is written as [true-or-absent](#pack-intent-toolspack). Earlier
755
+ releases wrote all eight pack keys as explicit `true`/`false` on reconcile;
756
+ current releases write `true` for installed packs and delete the key otherwise.
757
+
758
+ Scripts that read `tools.<pack> === false` now read `undefined` for a pack that
759
+ is not installed. Test for a truthy value instead. Legacy `false` values that
760
+ already exist in a config file are still read (see
761
+ [Legacy `false` intent](#legacy-false-intent)) — they are just never written.
762
+
763
+ ### Per-pack install `--json` changed shape
764
+
765
+ The per-pack subcommands (`oat tools install docs`, `oat tools install
766
+ workflows`, and the rest) now emit one multi-scope payload:
767
+
768
+ ```json
769
+ {
770
+ "status": "ok",
771
+ "pack": "docs",
772
+ "scopes": ["user"],
773
+ "results": [
774
+ { "request": { "pack": "docs", "scope": "user", "scopeRoot": "/home/you" } }
775
+ ]
776
+ }
777
+ ```
778
+
779
+ Each `results` entry is a full lifecycle result; only its `request` is shown
780
+ above. The previous single-scope payload's `scope`, `targetRoot`, `assetsRoot`,
781
+ `selectedSkills`, and `result` fields are **gone**, not renamed. A script
782
+ keying on them reads `undefined` rather than failing. Read `scopes` for the
783
+ scopes acted on, and `results[].request.scopeRoot` for the target root of each.
784
+
785
+ ### Other behavior changes worth knowing
786
+
787
+ - `oat tools remove --pack <pack>` deletes every managed asset the release
788
+ manifest declares for that pack and scope, including templates and scripts. It
789
+ previously removed only scanned skills and agents. Project-scope repository
790
+ template overrides and other owner data are still retained and reported.
791
+ - A removal that finds no trace of a pack leaves that pack's intent alone, so
792
+ `No tools to remove.` now means no durable state changed either.
793
+ - `oat tools info <packname>` exits `0` and prints a pack block. It previously
794
+ reported "not found" and exited 1 for a pack name.
795
+ - `oat tools list`, `oat tools outdated`, and `oat tools remove <name>` now see
796
+ user-scope **agents**, not just skills.
797
+ - `oat tools has <pack>` is complete-only: a partially installed pack answers
798
+ `false`. The exit code is unchanged at `0`.
799
+ - `oat tools has` and `oat tools update --scope all` no longer fail outside a
800
+ Git repository; see [`oat tools has`](#oat-tools-has-pack) and
801
+ [`oat tools update`](#oat-tools-update) for exactly what each reports.
802
+
432
803
  ## Legacy commands
433
804
 
434
805
  ### `oat init tools`
@@ -440,12 +811,13 @@ The `oat init tools` command remains available for backward compatibility. It ha
440
811
  The `oat remove` command group remains available for backward compatibility. It provides skill removal with dry-run/apply semantics and managed provider-view cleanup.
441
812
 
442
813
  - `oat remove skill <name>` — remove one installed skill by name
443
- - `oat remove skills --pack <pack>` — remove all installed skills from a bundled pack
814
+ - `oat remove skills --pack <pack>` — remove all installed skills from a bundled pack; pack membership is derived from the same release manifest the `oat tools` commands use
444
815
 
445
816
  These commands mutate by default; use `--dry-run` to preview deletions.
446
817
 
447
818
  Related docs:
448
819
 
820
+ - Diagnosing pack drift (`oat status`, `oat doctor`): `../reference/troubleshooting.md`
449
821
  - Bootstrap (`oat init`): `bootstrap.md`
450
822
  - Provider sync (`oat status`, `oat sync`, `oat providers ...`): `../provider-sync/index.md`
451
823
  - Diagnostics and local-state commands: `config-and-local-state.md`