@open-agent-toolkit/cli 0.1.31 → 0.1.33

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 (98) hide show
  1. package/assets/docs/cli-utilities/config-and-local-state.md +19 -6
  2. package/assets/docs/cli-utilities/tool-packs.md +13 -8
  3. package/assets/docs/reference/cli-reference.md +14 -13
  4. package/assets/docs/reference/file-locations.md +2 -1
  5. package/assets/docs/reference/oat-directory-structure.md +35 -22
  6. package/assets/migration/pjm-restructure.md +500 -0
  7. package/assets/public-package-versions.json +4 -4
  8. package/assets/scripts/resolve-tracking.sh +52 -0
  9. package/assets/skills/deep-research/SKILL.md +2 -2
  10. package/assets/skills/oat-brainstorm/SKILL.md +3 -3
  11. package/assets/skills/oat-brainstorm/references/destinations.md +10 -2
  12. package/assets/skills/oat-brainstorm/references/dogfood-results.md +4 -4
  13. package/assets/skills/oat-pjm-add-backlog-item/SKILL.md +17 -20
  14. package/assets/skills/oat-pjm-decision/SKILL.md +129 -0
  15. package/assets/skills/oat-pjm-review-backlog/SKILL.md +17 -17
  16. package/assets/skills/oat-pjm-review-backlog/references/backlog-review-template.md +2 -2
  17. package/assets/skills/oat-pjm-review-backlog/references/priority-alignment-template.md +13 -13
  18. package/assets/skills/oat-pjm-update-repo-reference/SKILL.md +34 -25
  19. package/assets/skills/oat-project-complete/SKILL.md +2 -2
  20. package/assets/skills/oat-project-document/SKILL.md +4 -3
  21. package/assets/skills/oat-project-import-plan/SKILL.md +2 -2
  22. package/assets/skills/oat-project-summary/SKILL.md +76 -8
  23. package/assets/templates/backlog-item.md +1 -1
  24. package/assets/templates/current-state.md +11 -2
  25. package/assets/templates/decision.md +18 -0
  26. package/assets/templates/pjm-agents.md +13 -0
  27. package/assets/templates/reference-agents.md +14 -0
  28. package/assets/templates/repo-agents.md +13 -0
  29. package/assets/templates/roadmap.md +8 -3
  30. package/dist/commands/backlog/index.d.ts +1 -0
  31. package/dist/commands/backlog/index.d.ts.map +1 -1
  32. package/dist/commands/backlog/index.js +48 -11
  33. package/dist/commands/backlog/init.js +1 -1
  34. package/dist/commands/backlog/regenerate-index.d.ts.map +1 -1
  35. package/dist/commands/backlog/regenerate-index.js +24 -5
  36. package/dist/commands/backlog/shared/generate-id.d.ts +1 -3
  37. package/dist/commands/backlog/shared/generate-id.d.ts.map +1 -1
  38. package/dist/commands/backlog/shared/generate-id.js +4 -64
  39. package/dist/commands/cleanup/artifacts/artifacts.d.ts.map +1 -1
  40. package/dist/commands/cleanup/artifacts/artifacts.js +4 -1
  41. package/dist/commands/decision/index.d.ts +20 -0
  42. package/dist/commands/decision/index.d.ts.map +1 -0
  43. package/dist/commands/decision/index.js +177 -0
  44. package/dist/commands/decision/init.d.ts +7 -0
  45. package/dist/commands/decision/init.d.ts.map +1 -0
  46. package/dist/commands/decision/init.js +53 -0
  47. package/dist/commands/decision/migrate.d.ts +24 -0
  48. package/dist/commands/decision/migrate.d.ts.map +1 -0
  49. package/dist/commands/decision/migrate.js +270 -0
  50. package/dist/commands/decision/new.d.ts +16 -0
  51. package/dist/commands/decision/new.d.ts.map +1 -0
  52. package/dist/commands/decision/new.js +118 -0
  53. package/dist/commands/decision/regenerate-index.d.ts +14 -0
  54. package/dist/commands/decision/regenerate-index.d.ts.map +1 -0
  55. package/dist/commands/decision/regenerate-index.js +122 -0
  56. package/dist/commands/decision/shared/generate-id.d.ts +2 -0
  57. package/dist/commands/decision/shared/generate-id.d.ts.map +1 -0
  58. package/dist/commands/decision/shared/generate-id.js +5 -0
  59. package/dist/commands/doctor/index.d.ts +5 -0
  60. package/dist/commands/doctor/index.d.ts.map +1 -1
  61. package/dist/commands/doctor/index.js +15 -0
  62. package/dist/commands/index.d.ts.map +1 -1
  63. package/dist/commands/index.js +2 -0
  64. package/dist/commands/init/tools/shared/skill-manifest.d.ts +2 -2
  65. package/dist/commands/init/tools/shared/skill-manifest.d.ts.map +1 -1
  66. package/dist/commands/init/tools/shared/skill-manifest.js +5 -1
  67. package/dist/commands/pjm/doctor.d.ts +7 -0
  68. package/dist/commands/pjm/doctor.d.ts.map +1 -0
  69. package/dist/commands/pjm/doctor.js +250 -0
  70. package/dist/commands/pjm/index.d.ts +7 -0
  71. package/dist/commands/pjm/index.d.ts.map +1 -1
  72. package/dist/commands/pjm/index.js +135 -10
  73. package/dist/commands/pjm/init.d.ts +3 -2
  74. package/dist/commands/pjm/init.d.ts.map +1 -1
  75. package/dist/commands/pjm/init.js +42 -33
  76. package/dist/commands/pjm/migrate.d.ts +36 -0
  77. package/dist/commands/pjm/migrate.d.ts.map +1 -0
  78. package/dist/commands/pjm/migrate.js +393 -0
  79. package/dist/commands/shared/date-id.d.ts +2 -0
  80. package/dist/commands/shared/date-id.d.ts.map +1 -0
  81. package/dist/commands/shared/date-id.js +10 -0
  82. package/dist/commands/shared/managed-index.d.ts +22 -0
  83. package/dist/commands/shared/managed-index.d.ts.map +1 -0
  84. package/dist/commands/shared/managed-index.js +92 -0
  85. package/dist/commands/shared/slug.d.ts +2 -0
  86. package/dist/commands/shared/slug.d.ts.map +1 -0
  87. package/dist/commands/shared/slug.js +57 -0
  88. package/dist/commands/shared/strip-template-frontmatter.d.ts +2 -0
  89. package/dist/commands/shared/strip-template-frontmatter.d.ts.map +1 -0
  90. package/dist/commands/shared/strip-template-frontmatter.js +16 -0
  91. package/dist/commands/sync/apply.d.ts.map +1 -1
  92. package/dist/commands/sync/apply.js +6 -2
  93. package/dist/manifest/manager.d.ts.map +1 -1
  94. package/dist/manifest/manager.js +4 -1
  95. package/dist/release/public-package-contract.d.ts.map +1 -1
  96. package/dist/release/public-package-contract.js +10 -1
  97. package/package.json +2 -2
  98. package/assets/templates/decision-record.md +0 -21
@@ -0,0 +1,500 @@
1
+ # OAT PJM repo-reference migration — agent-runnable prompt
2
+
3
+ > **What this is:** a self-contained prompt you (an agent) run **inside a target git repo** to
4
+ > migrate its OAT project-management (PJM) reference layer from the OLD shape
5
+ > (`.oat/repo/reference/{current-state.md, roadmap.md, decision-record.md, backlog/}`) to the
6
+ > NEW LOCKED shape (`pjm/` active layer + `reference/` durable library + file-per-record
7
+ > decisions + date+slug IDs + committed generated indexes + master/scoped AGENTS.md).
8
+ >
9
+ > **How to invoke:** the user runs you in the target repo and says, e.g.,
10
+ > "Run the OAT PJM migration." Default to a **dry run**. Only mutate after the user types
11
+ > `apply` (or invokes you with `--apply`).
12
+ >
13
+ > **Preferred path — let the CLI do it end-to-end.** When the `oat` CLI has the PJM migration
14
+ > support (see the version gate in STEP 0), `oat pjm migrate --apply` performs the entire
15
+ > mechanical migration in **one atomic, preflight-guarded shot**: it moves the active layer
16
+ > into `pjm/`, re-ids and strips template frontmatter from backlog items, **splits the
17
+ > decisions into file-per-record AND removes the legacy `decision-record.md`**, and regenerates
18
+ > both committed indexes. Do **not** run a separate `oat decision migrate` / `--delete-legacy`
19
+ > afterward — the decision split and the legacy-file removal already happened inside
20
+ > `pjm migrate --apply`, so a follow-on `decision migrate` is redundant and fails with ENOENT
21
+ > (the legacy file is gone). The manual STEP 1-3 mechanics below are the **no-CLI fallback** for
22
+ > when the installed CLI lacks the support; the JUDGMENT gates (STEP 4-6) always need you.
23
+ >
24
+ > **Non-negotiable safety rules — read before doing anything:**
25
+ > 1. **Dry-run first, always.** Produce the full plan and the two judgment proposals BEFORE
26
+ > any write. Do not write/move/delete until the user explicitly approves.
27
+ > 2. **Idempotent.** If the repo is already in the new shape, report that and stop.
28
+ > 3. **Non-destructive.** Use `git mv` for every move (preserve history). Never `git rm` a
29
+ > file until its content is confirmed present in the new location.
30
+ > 4. **Preserve all content.** Re-id changes only the id/filename and adds `legacy_id`. Never
31
+ > rewrite a record's prose.
32
+ > 5. **Two judgment gates require human confirmation** (ad-hoc folder reconciliation; legacy
33
+ > file retirement / second-roadmap disposition). Mechanical steps run without asking.
34
+ > 6. **Stay in `.oat/`.** Touch only `.oat/repo/**` (+ project dirs under `.oat/projects/**`
35
+ > when the user confirms a project-scoped move) and `.oat/sync/manifest.json`.
36
+
37
+ ---
38
+
39
+ ## STEP 0 — Preconditions and dry-run inventory (READ-ONLY; no writes)
40
+
41
+ Run these and stop if a precondition fails.
42
+
43
+ ```bash
44
+ # 0a. Confirm we're in a git repo with an OAT install.
45
+ git rev-parse --show-toplevel
46
+ test -d .oat || { echo "No .oat/ directory — not an OAT repo. ABORT."; exit 1; }
47
+
48
+ # 0b. PJM must be enabled. If false, this repo has no reference layer by design.
49
+ node -e 'const c=require("./.oat/config.json"); process.exit(c.tools && c.tools["project-management"] ? 0 : 1)' \
50
+ || { echo "project-management pack is DISABLED in .oat/config.json — nothing to migrate. ABORT."; exit 1; }
51
+
52
+ # 0c. Clean working tree (or require explicit override from the user).
53
+ git status --porcelain | head
54
+ echo "HEAD: $(git rev-parse HEAD)" # record for rollback note
55
+
56
+ # 0d. Idempotency probe — already migrated?
57
+ test -d .oat/repo/pjm && test -d .oat/repo/reference/decisions \
58
+ && echo "ALREADY MIGRATED (pjm/ and reference/decisions/ exist). Stop unless user forces re-run."
59
+ ```
60
+
61
+ **0e. Version gate — use a CLI build that HAS the fixes (do NOT pin a stale SHA).** If you are
62
+ relying on the `oat` CLI (the preferred path) and especially if you are building it from source,
63
+ build from the **current branch tip**, never a pinned/stale commit SHA. Then verify the build
64
+ actually has the migration fixes BEFORE migrating, with a side-effect-free dry run:
65
+
66
+ ```bash
67
+ # Side-effect-free. Look at the proposed ids in the output.
68
+ oat decision migrate --dry-run # or: oat pjm migrate --dry-run
69
+ ```
70
+
71
+ The build is current **only if** the proposed ids are **uppercase** `DR-`/`BL-` with
72
+ **≤30-char** slugs (e.g. `DR-260130-make-oat-tools-install`). If you instead see lowercase
73
+ `dr-`/`bl-` ids, or 48-char (un-truncated) slugs, you are on a **pre-fix build** — **STOP**,
74
+ rebuild from the current tip, and re-check. (A dogfood run was burned by migrating with a CLI
75
+ built from a pre-fix commit.)
76
+
77
+ If `0b` fails (honeycomb/duet class): **abort with** "PJM is disabled; nothing to migrate."
78
+ If `0c` shows a dirty tree: ask the user to commit/stash or to confirm proceeding anyway.
79
+ If `0d` reports already-migrated: stop unless the user says re-run.
80
+ If `0e` shows lowercase ids or 48-char slugs: **stop** and rebuild from the current tip.
81
+
82
+ Now build the **inventory** (read-only) and print it:
83
+
84
+ ```bash
85
+ echo "=== reference root ==="; ls -la .oat/repo/reference/ 2>/dev/null
86
+ echo "=== canonical four ==="; for f in current-state.md roadmap.md decision-record.md; do
87
+ test -f ".oat/repo/reference/$f" && echo "present: $f" || echo "ABSENT: $f"; done
88
+ test -d .oat/repo/reference/backlog && echo "present: backlog/" || echo "ABSENT: backlog/"
89
+ echo "=== backlog items ==="; ls .oat/repo/reference/backlog/items/*.md 2>/dev/null | wc -l
90
+ echo "=== decision scheme ==="; grep -oE '^#{2,3} (ADR|DR)-[0-9]+' .oat/repo/reference/decision-record.md 2>/dev/null | sort -u | head
91
+ echo "=== legacy backlog files ==="; for f in backlog.md backlog-completed.md; do
92
+ test -f ".oat/repo/reference/$f" && echo "LEGACY present: $f"; done
93
+ echo "=== second roadmap ==="; ls .oat/repo/reference/*roadmap*.md 2>/dev/null | grep -v '/roadmap.md$'
94
+ echo "=== ad-hoc folder candidates ==="; for d in research planning brainstorms design product external-plans decks proposals operator-steps profile-baselines rollouts wrap-ups technical; do
95
+ test -d ".oat/repo/reference/$d" && echo "candidate dir: $d"; done
96
+ echo "=== loose reference-root *.md (non-canonical) ==="; ls .oat/repo/reference/*.md 2>/dev/null | grep -vE '/(current-state|roadmap|decision-record|backlog|backlog-completed)\.md$'
97
+ echo "=== version stamp ==="; node -e 'try{console.log("oatVersion:",require("./.oat/sync/manifest.json").oatVersion)}catch(e){console.log("no manifest")}'
98
+ oat --version 2>/dev/null || echo "oat CLI not on PATH"
99
+ ```
100
+
101
+ **Print the DRY-RUN PLAN** summarizing what each mechanical step will do, then present the
102
+ two judgment proposals (STEP 4 and STEP 5/6 tables) and ask:
103
+
104
+ > "This is the dry-run plan. Reply `apply` to execute mechanical steps 1-3, 7, 8, or confirm
105
+ > the proposal tables below first. Nothing has been changed."
106
+
107
+ Do not proceed past here without approval.
108
+
109
+ ---
110
+
111
+ > The mechanics in STEP 1-3 (and STEP 7-8) are exactly what `oat pjm migrate --apply` does in
112
+ > one atomic shot on a current CLI build. Run them by hand only on the **no-CLI fallback** path.
113
+
114
+ ## STEP 1 — Move active layer into `pjm/` (MECHANICAL)
115
+
116
+ ```bash
117
+ mkdir -p .oat/repo/pjm
118
+ # Move the three active surfaces (only if present).
119
+ for f in current-state.md roadmap.md; do
120
+ if [ -f ".oat/repo/reference/$f" ]; then git mv ".oat/repo/reference/$f" ".oat/repo/pjm/$f"; fi
121
+ done
122
+ if [ -d .oat/repo/reference/backlog ]; then git mv .oat/repo/reference/backlog .oat/repo/pjm/backlog; fi
123
+ ```
124
+
125
+ **Missing-file handling (sequence-class half-implemented repos):** for any of
126
+ `current-state.md` / `roadmap.md` that were ABSENT, instantiate from the repo template with
127
+ the `oat_template` frontmatter stripped, written directly under `pjm/`:
128
+
129
+ ```bash
130
+ # For each missing file <name>:
131
+ # - read .oat/templates/<name>.md
132
+ # - if it starts with a frontmatter block containing oat_template/oat_template_name, drop the
133
+ # entire leading "---\n...\n---\n" block (replicates pjm/init.ts stripTemplateFrontmatter)
134
+ # - write the remainder to .oat/repo/pjm/<name>
135
+ # - record "created from template — NEEDS BACKFILL" in the report
136
+ ```
137
+
138
+ If `backlog/` was absent but PJM is on, scaffold it at the new location:
139
+
140
+ ```bash
141
+ # Run the backlog scaffold against the new pjm/backlog path so the exact managed markers exist.
142
+ # (oat backlog init is idempotent; point it at the pjm backlog root per the repo's CLI support.)
143
+ oat backlog init
144
+ ```
145
+
146
+ ---
147
+
148
+ ## STEP 2 — Re-id backlog items to `BL-YYMMDD-slug` (MECHANICAL)
149
+
150
+ For every file in `.oat/repo/pjm/backlog/items/*.md` and `.oat/repo/pjm/backlog/archived/*.md`:
151
+
152
+ 1. Parse YAML frontmatter. Read `created` (ISO 8601, e.g. `2026-04-13T22:35:45Z`).
153
+ - Derive `YYMMDD` from `created` (→ `260413`).
154
+ - Fallback if `created` is missing: git first-commit date of the file
155
+ (`git log --diff-filter=A --format=%ad --date=short -1 -- <file>`), else file mtime.
156
+ Record any fallback in the report.
157
+ 2. Determine `slug` = the current filename stem if it is already kebab-case, else kebab-case
158
+ of `title`. The slug is **capped at 30 characters** at the last whole-word (`-`) boundary
159
+ with trailing stop-words (`a, an, the, of, for, and, to, in, on, as, with`) trimmed — so
160
+ prefer concise, meaningful titles that stay readable within 30 chars.
161
+ 3. Compute new id `BL-<YYMMDD>-<slug>` and new filename `<new-id>.md` (**id == stem**).
162
+ - On collision (same `BL-YYMMDD-slug` already produced), append `-2`, `-3`, … to the slug
163
+ and note it.
164
+ 4. Edit frontmatter **in place** before moving: set `id: BL-<YYMMDD>-<slug>` and **add**
165
+ `legacy_id: <old-id>` (keep the old value, e.g. `legacy_id: bl-c745`). If the legacy item
166
+ still carries `oat_template` / `oat_template_name` markers, **drop them** — a migrated record
167
+ is an instantiated item, never a raw template, and `pjm doctor` flags residual template
168
+ frontmatter. (On the preferred CLI path, `oat pjm migrate --apply` strips these markers from
169
+ every migrated record automatically; you only do this by hand on the no-CLI fallback.) Leave
170
+ `created`, `title`, every other field, and the body untouched.
171
+ 5. `git mv <old-file> .oat/repo/pjm/backlog/items/<new-id>.md`.
172
+
173
+ After all items are re-id'd, regenerate the committed index:
174
+
175
+ ```bash
176
+ oat backlog regenerate-index # rewrites only the <!-- OAT BACKLOG-INDEX --> managed table
177
+ ```
178
+
179
+ The index is **committed** (browsable). Its render is deterministic (priority-then-title), so
180
+ on a future merge conflict the resolver re-runs this command and `git add`s — see the AGENTS.md
181
+ note STEP 7 writes.
182
+
183
+ ---
184
+
185
+ ## STEP 3 — Split + re-id decisions to file-per-record (MECHANICAL)
186
+
187
+ > **On the preferred CLI path this whole step — the split, the index, AND the
188
+ > `git rm` of `decision-record.md` — is performed by `oat pjm migrate --apply` in one shot.**
189
+ > Do not run a separate `oat decision migrate` afterward: the legacy file is already gone, so a
190
+ > follow-on `decision migrate` is redundant and errors out (ENOENT). The manual mechanics below
191
+ > are the no-CLI fallback.
192
+
193
+ Source: `.oat/repo/reference/decision-record.md` (single file). Records use headings
194
+ `## ADR-NNN: Title` or `### ADR-NNN: Title` (or `DR-NNN`), each with a `- **Date:**
195
+ YYYY-MM-DD` and `- **Status:** …` line and a body. There is also a top **Decision Index**
196
+ table (`| ID | Date | Status | Title | …`).
197
+
198
+ If `decision-record.md` is absent (sequence): skip the split; just create the empty
199
+ `reference/decisions/` + generated `index.md` so the canonical surface exists. Note "no
200
+ decisions to migrate."
201
+
202
+ Otherwise:
203
+
204
+ ```bash
205
+ mkdir -p .oat/repo/reference/decisions
206
+ ```
207
+
208
+ Parse the file into records by splitting on `^#{2,3}\s+(ADR|DR)-(\d+):\s*(.+)$`. For each
209
+ record capture: original `ID` (e.g. `ADR-001`), `title`, and the `body` (everything from the
210
+ heading up to the next decision heading). Recover `Date`/`Status` from the record's inline
211
+ `- **Date:**` / `- **Status:**` lines; if absent, fall back to that ID's row in the Decision
212
+ Index table.
213
+
214
+ For each record write `.oat/repo/reference/decisions/<new-id>.md` where
215
+ `new-id = DR-<YYMMDD>-<slug>` (`YYMMDD` from the record's Date; `slug` = kebab-case of title,
216
+ **capped at 30 characters** at the last whole-word boundary with trailing stop-words
217
+ (`a, an, the, of, for, and, to, in, on, as, with`) trimmed — pick concise, meaningful titles
218
+ that stay readable within that 30-char budget):
219
+
220
+ ```markdown
221
+ ---
222
+ id: DR-<YYMMDD>-<slug>
223
+ legacy_id: ADR-001
224
+ title: '<original title>'
225
+ date: 'YYYY-MM-DD'
226
+ status: accepted
227
+ ---
228
+
229
+ <ORIGINAL BODY, PRESERVED VERBATIM — Drivers / Related / Context / Options Considered /
230
+ Decision / Consequences exactly as they appeared>
231
+ ```
232
+
233
+ Rules:
234
+ - **Preserve the body byte-for-byte** (minus the heading line, which becomes `title`/the
235
+ frontmatter). Do not summarize or reformat.
236
+ - `legacy_id` keeps the original `ADR-NNN`/`DR-NNN` so inbound references still resolve.
237
+ - Because the id carries the ORIGINAL date, records sort chronologically by filename and in
238
+ the index (ADR-001 @ 2026-01-30 → `DR-260130-…` sorts before a June decision). Gaps in the
239
+ old numbering (e.g. stoa DR-033/035 missing) are irrelevant — date+slug needs no contiguity.
240
+ - Collision (same `DR-YYMMDD-slug`): append `-2`/`-3` to the slug.
241
+
242
+ Generate the committed index:
243
+
244
+ ```bash
245
+ oat decision regenerate-index # builds reference/decisions/index.md managed table from the record files
246
+ ```
247
+
248
+ `reference/decisions/index.md` mirrors the backlog index: managed markers + a deterministic
249
+ table `| ID | Date | Status | Title | Legacy |` sorted by `date` then `id`. Committed;
250
+ regenerate-on-conflict.
251
+
252
+ **Verify before retiring the source:** count decision headings in the original file == count
253
+ of files in `reference/decisions/` (excluding `index.md`). Only when they match:
254
+
255
+ ```bash
256
+ git rm .oat/repo/reference/decision-record.md
257
+ ```
258
+
259
+ If counts mismatch, STOP and report the discrepancy — do not delete.
260
+
261
+ ---
262
+
263
+ ## STEP 4 — Reconcile ad-hoc folders (JUDGMENT — PROPOSE, then confirm each)
264
+
265
+ This step needs human judgment; do not move anything until the user confirms.
266
+
267
+ Detect (from STEP 0 inventory) folders/files under `.oat/repo/reference/` (and `.oat/repo/`)
268
+ in the set: `research, planning, brainstorms, design, product, external-plans, decks,
269
+ proposals, operator-steps, profile-baselines, rollouts, wrap-ups, technical`, plus any loose
270
+ non-canonical `*.md` in the reference root.
271
+
272
+ For each, infer a classification by skimming its contents:
273
+ - **Project-scoped** (content is about one specific project/feature) → propose moving into
274
+ that project's reference dir: `.oat/projects/<scope>/<project>/reference/`.
275
+ - **Repo-wide / durable** → propose the canonical destination:
276
+ - brainstorms → `reference/brainstorms/`
277
+ - research / deep-research → `reference/research/`
278
+ - external / imported plans → `reference/external-plans/`
279
+ - decks → `reference/decks/`
280
+ - loose reference-root `*.md` → `reference/research/` (or a `reference/<topic>/` you name)
281
+
282
+ **Emit a PROPOSAL TABLE** and ask the user to confirm or override each row:
283
+
284
+ ```
285
+ | # | Detected path | Inferred scope | Proposed destination | Confirm? |
286
+ |---|---|---|---|---|
287
+ | 1 | reference/brainstorms/ | repo-wide | reference/brainstorms/ (no move) | ? |
288
+ | 2 | reference/planning/mvp-screen-requirements/ | project-scoped (home-feed?) | .oat/projects/shared/<project>/reference/ | ? |
289
+ | 3 | reference/woz-oz-...-brief.md (loose) | repo-wide | reference/research/ | ? |
290
+ ...
291
+ ```
292
+
293
+ Rules:
294
+ - Ambiguous/unknown → default to **"leave in place, flag"**, never guess.
295
+ - After the user confirms, `git mv` each approved row. Skip rows the user rejects.
296
+ - Optional canonical folders (`research/`, `brainstorms/`, `external-plans/`, `decks/`) are
297
+ **created on demand** — only when a confirmed move needs them. Do not pre-create empties.
298
+
299
+ ---
300
+
301
+ ## STEP 4.5 — Stale top-level `.oat/repo/README.md` (EXPECTED — not an error)
302
+
303
+ A repo migrated from the old layout often has a top-level `.oat/repo/README.md` describing the
304
+ **old** structure. This is **benign and allowed**: `pjm doctor`'s top-level layout check
305
+ explicitly permits a top-level `README.md` (alongside `AGENTS.md`) — it does **not** fail the
306
+ layout check. Don't be surprised by it and don't treat it as drift to delete. Call it out in
307
+ the report and let the user pick one of:
308
+
309
+ - **Leave it** — fine; doctor passes either way.
310
+ - **Refresh it** — update its prose to describe the new two-layer (`pjm/` + `reference/`)
311
+ layout (the master `AGENTS.md` STEP 7 writes is the authoritative source to mirror).
312
+ - **Archive it** — `git mv .oat/repo/README.md .oat/repo/reference/archive/README.md` (create
313
+ `reference/archive/` on demand) if you want the old-layout prose retained for history but out
314
+ of the top level.
315
+
316
+ Default to **leave + flag**; only refresh/archive on explicit user confirmation.
317
+
318
+ ---
319
+
320
+ ## STEP 5 — Retire legacy backlog files (JUDGMENT — fold, then delete)
321
+
322
+ Targets if present: `.oat/repo/reference/backlog.md` (legacy flat) and
323
+ `.oat/repo/reference/backlog-completed.md` (parallel completion log).
324
+
325
+ 1. Read both. Diff their entries against the live `pjm/backlog/items/*.md` and
326
+ `pjm/backlog/completed.md`.
327
+ 2. **PROPOSE:** list entries present ONLY in the legacy files (would be lost on delete). For
328
+ each, propose either:
329
+ - fold into a new `pjm/backlog/items/<BL-YYMMDD-slug>.md` (re-id per STEP 2), or
330
+ - append to `pjm/backlog/completed.md` (for completion entries).
331
+ 3. After the user confirms the fold, write the folded items and then:
332
+ ```bash
333
+ git rm .oat/repo/reference/backlog.md .oat/repo/reference/backlog-completed.md
334
+ ```
335
+ 4. Stale-reference sweep (report dangling links; do not auto-edit other files):
336
+ ```bash
337
+ grep -rnE 'backlog\.md|backlog-completed\.md|deferred-phases\.md' \
338
+ .oat/repo AGENTS.md .agents/skills docs 2>/dev/null
339
+ grep -rnE '\.oat/repo/reference/(current-state|roadmap|decision-record|backlog)' \
340
+ .oat/repo AGENTS.md .agents/skills docs 2>/dev/null # old paths now under pjm/
341
+ ```
342
+
343
+ ---
344
+
345
+ ## STEP 6 — Archive or fold a second roadmap (JUDGMENT)
346
+
347
+ If STEP 0 found a `*roadmap*.md` other than the moved `pjm/roadmap.md` (e.g.
348
+ `milestone-roadmap.md`), **propose two options** and confirm:
349
+
350
+ - **Archive (default for "historical, do not use as active planning"):**
351
+ ```bash
352
+ mkdir -p .oat/repo/reference/archive
353
+ git mv .oat/repo/reference/milestone-roadmap.md .oat/repo/reference/archive/milestone-roadmap.md
354
+ ```
355
+ - **Fold:** merge still-relevant items into `pjm/roadmap.md` Later bucket, then
356
+ `git rm` the second file.
357
+
358
+ Confirm the choice before acting.
359
+
360
+ ---
361
+
362
+ ## STEP 7 — Write master + scoped AGENTS.md (MECHANICAL; OAT-managed docs)
363
+
364
+ Write (overwrite) these three OAT-managed docs.
365
+
366
+ **`.oat/repo/AGENTS.md`** (master):
367
+
368
+ ```markdown
369
+ # .oat/repo — OAT repo records (PJM restructure)
370
+
371
+ This describes the full proposed structure of `.oat/repo/`. **You may not have all of these** —
372
+ optional folders are created on demand, not pre-created.
373
+
374
+ ## Layout
375
+
376
+ - `pjm/` — ACTIVE operational layer (read at project start, written at completion):
377
+ - `current-state.md` (NON-NEGOTIABLE) — birdseye snapshot.
378
+ - `roadmap.md` (NON-NEGOTIABLE) — Now / Next / Later.
379
+ - `backlog/` (NON-NEGOTIABLE): `items/<BL-YYMMDD-slug>.md`, `index.md` (generated, COMMITTED),
380
+ `completed.md`, `archived/`.
381
+ - `reference/` — DURABLE refer-back library:
382
+ - `decisions/` (NON-NEGOTIABLE): `<DR-YYMMDD-slug>.md` file-per-record + `index.md`
383
+ (generated, COMMITTED).
384
+ - `project-summaries/<YYMMDD-slug>.md` (NON-NEGOTIABLE).
385
+ - `research/`, `brainstorms/`, `external-plans/`, `decks/` (RECOMMENDED — created on demand).
386
+ - `knowledge/`, `analysis/`, `reviews/` — generated/review surfaces (unchanged).
387
+ - Top-level `AGENTS.md` (this file) and an optional `README.md` are the only files allowed at
388
+ the `.oat/repo/` root; a leftover old-layout `README.md` is permitted by `pjm doctor` and may
389
+ be left, refreshed for the two-layer layout, or archived under `reference/archive/`.
390
+
391
+ ## IDs
392
+ - Decisions: `DR-YYMMDD-slug`. Backlog: `BL-YYMMDD-slug`. **ID == filename stem.** The `YYMMDD`
393
+ prefix gives chronological + file-explorer ordering. Allocator-free (no scan, no counter):
394
+ collision only on same-day + same-slug. Migrated records keep their original id in `legacy_id:`.
395
+ - Slugs are **capped at 30 characters** at the last whole-word boundary with trailing stop-words
396
+ (`a, an, the, of, for, and, to, in, on, as, with`) trimmed, so choose concise, meaningful titles.
397
+
398
+ ## Skill / content DESTINATIONS
399
+ - `oat-brainstorm` → `reference/brainstorms/`
400
+ - `oat project import-plan` → `reference/external-plans/` (already its target)
401
+ - research / deep-research → `reference/research/`
402
+
403
+ ## Generated indexes — regenerate on conflict
404
+ `pjm/backlog/index.md` and `reference/decisions/index.md` are generated and COMMITTED (not
405
+ gitignored, no merge driver). They render deterministically from the record files. On a merge
406
+ conflict: run the regenerate command, then `git add`:
407
+ - backlog: `oat backlog regenerate-index`
408
+ - decisions: `oat decision regenerate-index`
409
+
410
+ current-state.md and roadmap.md stay single narrative docs; minimize conflicts via stable
411
+ section order, one-item-per-line bullets, and the single managed `Last Updated:` line.
412
+ ```
413
+
414
+ **`.oat/repo/pjm/AGENTS.md`** (scoped):
415
+
416
+ ```markdown
417
+ # pjm/ — active operational layer
418
+
419
+ - `backlog/index.md` is GENERATED and COMMITTED. Do not hand-edit the
420
+ `<!-- OAT BACKLOG-INDEX -->` … `<!-- END OAT BACKLOG-INDEX -->` block. Only the
421
+ `## Curated Overview` section is hand-edited.
422
+ - On a merge conflict in `index.md`: run `oat backlog regenerate-index`, then `git add`.
423
+ - New backlog items: `BL-YYMMDD-slug`, one file per item under `backlog/items/`.
424
+ ```
425
+
426
+ **`.oat/repo/reference/AGENTS.md`** (scoped):
427
+
428
+ ```markdown
429
+ # reference/ — durable library
430
+
431
+ - `decisions/` is FILE-PER-RECORD (`DR-YYMMDD-slug.md`). New decisions: `oat decision new`.
432
+ - `decisions/index.md` is GENERATED and COMMITTED — do not hand-edit the managed block.
433
+ - On a merge conflict in `decisions/index.md`: run `oat decision regenerate-index`, then `git add`.
434
+ - Migrated decisions keep their old `ADR-NNN`/`DR-NNN` in `legacy_id:` frontmatter.
435
+ ```
436
+
437
+ ---
438
+
439
+ ## STEP 8 — Refresh the version stamp (MECHANICAL)
440
+
441
+ ```bash
442
+ # Set sync manifest oatVersion to the installed CLI version (fixes the stale 0.0.1 stamp),
443
+ # or just run sync which rewrites the manifest:
444
+ oat sync --scope project # idempotent; refreshes manifest incl. oatVersion
445
+ # If oat sync is not desired, set manifest .oatVersion to `oat --version` output directly.
446
+ ```
447
+
448
+ ---
449
+
450
+ ## STEP 9 — Verify and report (READ-ONLY)
451
+
452
+ ```bash
453
+ echo "=== target shape ==="
454
+ for p in pjm/current-state.md pjm/roadmap.md pjm/backlog/index.md \
455
+ reference/decisions/index.md AGENTS.md pjm/AGENTS.md reference/AGENTS.md; do
456
+ test -e ".oat/repo/$p" && echo "OK $p" || echo "MISS $p"; done
457
+ echo "=== no template frontmatter left ==="
458
+ grep -rl 'oat_template' .oat/repo/pjm .oat/repo/reference/decisions 2>/dev/null \
459
+ && echo "WARN: oat_template frontmatter remains (doctor FAIL)" || echo "OK: stripped"
460
+ echo "=== legacy files gone ==="
461
+ for f in reference/decision-record.md reference/backlog.md reference/backlog-completed.md; do
462
+ test -e ".oat/repo/$f" && echo "STILL PRESENT (folded?): $f" || echo "removed: $f"; done
463
+ echo "=== decision count parity ==="
464
+ ls .oat/repo/reference/decisions/*.md 2>/dev/null | grep -v '/index.md$' | wc -l
465
+ echo "=== top-level README (allowed; not a failure) ==="
466
+ test -f .oat/repo/README.md && echo "present: README.md (allowed by doctor; leave/refresh/archive per STEP 4.5)" || echo "absent: README.md"
467
+ ```
468
+
469
+ > A leftover top-level `.oat/repo/README.md` from the old layout is **not** a doctor failure
470
+ > (see STEP 4.5) — report it, don't flag it as broken.
471
+
472
+ **Print the final migration report** covering:
473
+ - files moved (old → new), backlog items re-id'd (old id → new id, any date fallback used),
474
+ - decisions split (old ADR/DR → new `DR-YYMMDD-slug`, count parity),
475
+ - ad-hoc folders reconciled (confirmed destinations),
476
+ - legacy files retired (with folded-in entries), second-roadmap disposition,
477
+ - version stamp before → after,
478
+ - any flagged follow-ups (e.g. sequence "current-state created from template — backfill",
479
+ dangling references found by the STEP 5 grep).
480
+
481
+ **Do NOT commit or push** unless the user asks. Leave the changes staged for their review.
482
+
483
+ ---
484
+
485
+ ## Notes for the running agent
486
+
487
+ - Run independent read-only inventory commands together; gate every mutation behind approval.
488
+ - **Prefer `oat pjm migrate --apply`** on a current CLI build (STEP 0e version gate): it runs
489
+ STEP 1-3 (+ 7-8) atomically — including splitting decisions and removing `decision-record.md`.
490
+ Never chase it with a standalone `oat decision migrate` / `--delete-legacy`; that legacy file
491
+ is already gone and the follow-on fails (ENOENT).
492
+ - If `oat decision new`/`regenerate-index` is not yet available in the installed CLI, perform
493
+ the decision split + index generation manually following STEP 3 (write the files; build the
494
+ `| ID | Date | Status | Title | Legacy |` table between
495
+ `<!-- OAT DECISION-INDEX -->` / `<!-- END OAT DECISION-INDEX -->` markers, sorted by date
496
+ then id) and say so in the report.
497
+ - Treat `.oat/projects/**` writes (project-scoped folder moves) as confirmed-only.
498
+ - This prompt is safe to re-run: STEP 0's idempotency probe short-circuits an
499
+ already-migrated repo.
500
+ ```
@@ -1,6 +1,6 @@
1
1
  {
2
- "cli": "0.1.31",
3
- "docs-config": "0.1.31",
4
- "docs-theme": "0.1.31",
5
- "docs-transforms": "0.1.31"
2
+ "cli": "0.1.33",
3
+ "docs-config": "0.1.33",
4
+ "docs-theme": "0.1.33",
5
+ "docs-transforms": "0.1.33"
6
6
  }
@@ -100,6 +100,41 @@ resolve_root_commit_hash() {
100
100
  git rev-parse HEAD
101
101
  }
102
102
 
103
+ is_agent_instructions_operation() {
104
+ local operation="${1:?Missing operation}"
105
+ [[ "$operation" == "agentInstructions" || "$operation" == "agentInstructionsApply" ]]
106
+ }
107
+
108
+ normalize_repo_relative_path() {
109
+ local path="${1:?Missing path}"
110
+
111
+ path="${path#./}"
112
+ if [[ "$path" == "$REPO_ROOT"/* ]]; then
113
+ path="${path#"$REPO_ROOT"/}"
114
+ fi
115
+
116
+ echo "$path"
117
+ }
118
+
119
+ artifact_path_is_tracked_and_present() {
120
+ local artifact_path="${1:?Missing artifact path}"
121
+ local relative_path absolute_path
122
+
123
+ relative_path="$(normalize_repo_relative_path "$artifact_path")"
124
+ absolute_path="${REPO_ROOT}/${relative_path}"
125
+
126
+ [[ -e "$absolute_path" ]] || return 1
127
+ git -C "$REPO_ROOT" ls-files --error-unmatch -- "$relative_path" >/dev/null 2>&1
128
+ }
129
+
130
+ remove_tracking_key() {
131
+ local operation="${1:?Missing operation}"
132
+ local existing="${2:?Missing existing tracking JSON}"
133
+
134
+ mkdir -p "$(dirname "$TRACKING_FILE")"
135
+ echo "$existing" | jq --arg op "$operation" 'del(.[$op])' > "$TRACKING_FILE"
136
+ }
137
+
103
138
  cmd_init() {
104
139
  mkdir -p "$(dirname "$TRACKING_FILE")"
105
140
  if [[ ! -f "$TRACKING_FILE" ]] || ! jq empty "$TRACKING_FILE" 2>/dev/null; then
@@ -118,6 +153,16 @@ cmd_read() {
118
153
  return 0
119
154
  fi
120
155
 
156
+ if is_agent_instructions_operation "$operation"; then
157
+ local artifact_path
158
+ artifact_path="$(jq -r --arg op "$operation" '.[$op].artifactPath // empty' "$TRACKING_FILE")"
159
+ if [[ -n "$artifact_path" ]] && ! artifact_path_is_tracked_and_present "$artifact_path"; then
160
+ remove_tracking_key "$operation" "$(cat "$TRACKING_FILE")"
161
+ echo "{}"
162
+ return 0
163
+ fi
164
+ fi
165
+
121
166
  jq -r --arg op "$operation" '.[$op] // empty' "$TRACKING_FILE"
122
167
  }
123
168
 
@@ -172,6 +217,13 @@ cmd_write() {
172
217
  existing='{"version":1}'
173
218
  fi
174
219
 
220
+ if is_agent_instructions_operation "$operation" && [[ -n "$artifact_path" ]] && ! artifact_path_is_tracked_and_present "$artifact_path"; then
221
+ remove_tracking_key "$operation" "$existing"
222
+ echo "Info: skipped $operation tracking because artifactPath is missing or untracked: $artifact_path" >&2
223
+ echo "Updated $TRACKING_FILE [$operation]"
224
+ return 0
225
+ fi
226
+
175
227
  if [[ -n "$artifact_path" ]]; then
176
228
  echo "$existing" | jq \
177
229
  --arg op "$operation" \
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: deep-research
3
- version: 0.1.0
3
+ version: 0.2.0
4
4
  description: Comprehensive research orchestrator that classifies topics, dispatches parallel research-angle workers, and produces structured artifacts using domain-specific schemas.
5
5
  argument-hint: 'topic [--depth surface|standard|exhaustive] [--focus angle] [--context path] [output-path]'
6
6
  user-invocable: true
@@ -239,7 +239,7 @@ If no competing options emerged, skip this step.
239
239
 
240
240
  **Otherwise**, determine a default suggestion using OAT-aware detection:
241
241
 
242
- 1. Check for `.oat/` at repo root (project-level OAT) → suggest `.oat/repo/research/`
242
+ 1. Check for `.oat/` at repo root (project-level OAT) → suggest `.oat/repo/reference/research/`
243
243
  2. Check for `~/.oat/` (user-level OAT) → suggest `~/.oat/research/`
244
244
  3. Fall back to current directory
245
245
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: oat-brainstorm
3
- version: 1.0.4
3
+ version: 1.1.0
4
4
  description: Use when the user explicitly invokes the `brainstorm` verb, including `/oat-brainstorm`, "let's brainstorm", "brainstorm this", "can we brainstorm X", or "help me brainstorm X". For ambiguous exploratory phrasing ("I've been thinking", "what if", "help me think through"), do NOT auto-enter; respond conversationally and offer mode only after ≥2 sustained exploratory turns. Do NOT use for review, debug, PR, status, implementation, or active-workflow questions.
5
5
  disable-model-invocation: false
6
6
  user-invocable: true
@@ -366,7 +366,7 @@ The payload is staged in memory only — it is not persisted between conversatio
366
366
  Scope: <xs|s|m|l|xl>
367
367
  Priority: <p0|p1|p2|p3>
368
368
 
369
- Confirm to write this to a new bl-XXXX file, or tell me what to change.
369
+ Confirm to write this to a new backlog item file, or tell me what to change.
370
370
  ```
371
371
 
372
372
  If the user requests changes, apply them to the in-memory payload and re-display the affected fields before continuing.
@@ -452,7 +452,7 @@ Read `.agents/skills/oat-pjm-add-backlog-item/SKILL.md` and execute its process
452
452
  - `Priority` → user-confirmed priority (p0 / p1 / p2 / p3).
453
453
  - Optional fields (related items, target release, owner) → only if surfaced during synthesis.
454
454
 
455
- The downstream `oat-pjm-add-backlog-item` owns ID generation, file writing under `.oat/repo/reference/backlog/items/`, and backlog-index regeneration. Do not duplicate that logic here.
455
+ The downstream `oat-pjm-add-backlog-item` owns ID generation, file writing under `.oat/repo/pjm/backlog/items/`, and backlog-index regeneration. Do not duplicate that logic here.
456
456
 
457
457
  End mode assertion when the backlog-add hands control back.
458
458
 
@@ -32,6 +32,14 @@ Per-destination lookup that `oat-brainstorm` consults at destination-identificat
32
32
  **Required template fields:** `title`, `summary`, `approachesConsidered`, `chosenDirection` (or explicit "no direction"), `transcriptSessionNote`. Template: `templates/brainstorm-doc.md` (in this skill).
33
33
  **Optional template fields:** `motivation`, `vision`, `openQuestions`, `nextSteps`.
34
34
  **Confirmation pattern:** `minimal` (path only)
35
+ **Default destination suggestion (OAT-aware):** When the user wants to save the doc into the repo but has not supplied an explicit path, suggest a durable default before prompting:
36
+
37
+ 1. Project-level OAT (`.oat/` at repo root) → suggest `.oat/repo/reference/brainstorms/<YYYY-MM-DD>-<topic>.md`. Create `reference/brainstorms/` on demand if it does not exist.
38
+ 2. User-level OAT (`~/.oat/`) → suggest `~/.oat/brainstorms/<YYYY-MM-DD>-<topic>.md`.
39
+ 3. Otherwise → fall back to the current directory.
40
+
41
+ Always honor an explicit user-supplied path over the suggestion. Brainstorm docs are durable reference material, so they belong under `reference/brainstorms/`, never under the active `pjm/` operational layer.
42
+
35
43
  **Handoff target:** no downstream skill. Skill validates path (file not dir; parent exists or offer to create — explicit confirmation if outside repo; file already exists → ask overwrite vs different name; unwritable → surface OS error), renders `templates/brainstorm-doc.md` with payload values, writes the file. Reports the absolute path written.
36
44
  **If user wants to keep brainstorming after this is offered:** return to flow with destination = doc-to-path. Skill notes the user-supplied path and may proactively probe for `motivation`, `vision`, or richer `chosenDirection` if those template sections feel sparse.
37
45
 
@@ -76,7 +84,7 @@ Per-destination lookup that `oat-brainstorm` consults at destination-identificat
76
84
  ### Destination: Scoped backlog item
77
85
 
78
86
  **Pack required:** `project-management` (i.e., `oat config get tools.project-management` returns `true`)
79
- **Trigger phrases:** "track this as a backlog item", "make a ticket", "log this", "open a backlog entry", "add this to the backlog", "create a bl-XXXX for this".
87
+ **Trigger phrases:** "track this as a backlog item", "make a ticket", "log this", "open a backlog entry", "add this to the backlog", "create a backlog item for this".
80
88
  **Required template fields:** `title` (1-line summary), `description` (problem + proposed approach), `acceptance criteria` (bullet list), `scope` (xs / s / m / l / xl), `priority` (p0 / p1 / p2 / p3). Template: `.oat/templates/backlog-item.md` (consumed via `oat-pjm-add-backlog-item`).
81
89
  **Optional template fields:** related items, target release, owner.
82
90
  **Confirmation pattern:** `full`
@@ -94,7 +102,7 @@ I have what I need to track this as a backlog item. Here is the proposed payload
94
102
  Scope: <xs|s|m|l|xl>
95
103
  Priority: <p0|p1|p2|p3>
96
104
 
97
- Confirm to write this to a new bl-XXXX file, or tell me what to change.
105
+ Confirm to write this to a new backlog item file, or tell me what to change.
98
106
  ```
99
107
 
100
108
  **Handoff target:** `oat-pjm-add-backlog-item` from its Step 1, with the confirmed payload pre-filling the early prompts. The downstream skill owns ID generation, file writing, and backlog-index regeneration.