@open-agent-toolkit/cli 0.1.30 → 0.1.32

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 (95) hide show
  1. package/assets/docs/cli-utilities/config-and-local-state.md +18 -5
  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/skills/deep-research/SKILL.md +2 -2
  9. package/assets/skills/oat-brainstorm/SKILL.md +3 -3
  10. package/assets/skills/oat-brainstorm/references/destinations.md +10 -2
  11. package/assets/skills/oat-brainstorm/references/dogfood-results.md +4 -4
  12. package/assets/skills/oat-pjm-add-backlog-item/SKILL.md +17 -20
  13. package/assets/skills/oat-pjm-decision/SKILL.md +129 -0
  14. package/assets/skills/oat-pjm-review-backlog/SKILL.md +17 -17
  15. package/assets/skills/oat-pjm-review-backlog/references/backlog-review-template.md +2 -2
  16. package/assets/skills/oat-pjm-review-backlog/references/priority-alignment-template.md +13 -13
  17. package/assets/skills/oat-pjm-update-repo-reference/SKILL.md +34 -25
  18. package/assets/skills/oat-project-complete/SKILL.md +2 -2
  19. package/assets/skills/oat-project-document/SKILL.md +4 -3
  20. package/assets/skills/oat-project-import-plan/SKILL.md +2 -2
  21. package/assets/skills/oat-project-summary/SKILL.md +76 -8
  22. package/assets/templates/backlog-item.md +1 -1
  23. package/assets/templates/current-state.md +11 -2
  24. package/assets/templates/decision.md +18 -0
  25. package/assets/templates/pjm-agents.md +13 -0
  26. package/assets/templates/reference-agents.md +14 -0
  27. package/assets/templates/repo-agents.md +13 -0
  28. package/assets/templates/roadmap.md +8 -3
  29. package/dist/commands/backlog/index.d.ts +1 -0
  30. package/dist/commands/backlog/index.d.ts.map +1 -1
  31. package/dist/commands/backlog/index.js +48 -11
  32. package/dist/commands/backlog/init.js +1 -1
  33. package/dist/commands/backlog/regenerate-index.d.ts.map +1 -1
  34. package/dist/commands/backlog/regenerate-index.js +24 -5
  35. package/dist/commands/backlog/shared/generate-id.d.ts +1 -3
  36. package/dist/commands/backlog/shared/generate-id.d.ts.map +1 -1
  37. package/dist/commands/backlog/shared/generate-id.js +4 -64
  38. package/dist/commands/cleanup/artifacts/artifacts.d.ts.map +1 -1
  39. package/dist/commands/cleanup/artifacts/artifacts.js +4 -1
  40. package/dist/commands/decision/index.d.ts +20 -0
  41. package/dist/commands/decision/index.d.ts.map +1 -0
  42. package/dist/commands/decision/index.js +177 -0
  43. package/dist/commands/decision/init.d.ts +7 -0
  44. package/dist/commands/decision/init.d.ts.map +1 -0
  45. package/dist/commands/decision/init.js +53 -0
  46. package/dist/commands/decision/migrate.d.ts +24 -0
  47. package/dist/commands/decision/migrate.d.ts.map +1 -0
  48. package/dist/commands/decision/migrate.js +270 -0
  49. package/dist/commands/decision/new.d.ts +16 -0
  50. package/dist/commands/decision/new.d.ts.map +1 -0
  51. package/dist/commands/decision/new.js +118 -0
  52. package/dist/commands/decision/regenerate-index.d.ts +14 -0
  53. package/dist/commands/decision/regenerate-index.d.ts.map +1 -0
  54. package/dist/commands/decision/regenerate-index.js +122 -0
  55. package/dist/commands/decision/shared/generate-id.d.ts +2 -0
  56. package/dist/commands/decision/shared/generate-id.d.ts.map +1 -0
  57. package/dist/commands/decision/shared/generate-id.js +5 -0
  58. package/dist/commands/doctor/index.d.ts +2 -0
  59. package/dist/commands/doctor/index.d.ts.map +1 -1
  60. package/dist/commands/doctor/index.js +6 -0
  61. package/dist/commands/index.d.ts.map +1 -1
  62. package/dist/commands/index.js +2 -0
  63. package/dist/commands/init/tools/shared/skill-manifest.d.ts +2 -2
  64. package/dist/commands/init/tools/shared/skill-manifest.d.ts.map +1 -1
  65. package/dist/commands/init/tools/shared/skill-manifest.js +5 -1
  66. package/dist/commands/pjm/doctor.d.ts +3 -0
  67. package/dist/commands/pjm/doctor.d.ts.map +1 -0
  68. package/dist/commands/pjm/doctor.js +238 -0
  69. package/dist/commands/pjm/index.d.ts +7 -0
  70. package/dist/commands/pjm/index.d.ts.map +1 -1
  71. package/dist/commands/pjm/index.js +132 -10
  72. package/dist/commands/pjm/init.d.ts +3 -2
  73. package/dist/commands/pjm/init.d.ts.map +1 -1
  74. package/dist/commands/pjm/init.js +42 -33
  75. package/dist/commands/pjm/migrate.d.ts +36 -0
  76. package/dist/commands/pjm/migrate.d.ts.map +1 -0
  77. package/dist/commands/pjm/migrate.js +393 -0
  78. package/dist/commands/shared/date-id.d.ts +2 -0
  79. package/dist/commands/shared/date-id.d.ts.map +1 -0
  80. package/dist/commands/shared/date-id.js +10 -0
  81. package/dist/commands/shared/managed-index.d.ts +22 -0
  82. package/dist/commands/shared/managed-index.d.ts.map +1 -0
  83. package/dist/commands/shared/managed-index.js +92 -0
  84. package/dist/commands/shared/slug.d.ts +2 -0
  85. package/dist/commands/shared/slug.d.ts.map +1 -0
  86. package/dist/commands/shared/slug.js +57 -0
  87. package/dist/commands/shared/strip-template-frontmatter.d.ts +2 -0
  88. package/dist/commands/shared/strip-template-frontmatter.d.ts.map +1 -0
  89. package/dist/commands/shared/strip-template-frontmatter.js +16 -0
  90. package/dist/engine/hook.d.ts.map +1 -1
  91. package/dist/engine/hook.js +13 -0
  92. package/dist/release/public-package-contract.d.ts.map +1 -1
  93. package/dist/release/public-package-contract.js +10 -1
  94. package/package.json +2 -2
  95. package/assets/templates/decision-record.md +0 -21
@@ -1,10 +1,10 @@
1
1
  ---
2
2
  name: oat-project-summary
3
- version: 1.1.2
3
+ version: 1.2.0
4
4
  description: Use when the user requests or confirms summarizing an active OAT project — e.g. "summarize the project", "generate the summary", "run oat-project-summary", or confirms a previously offered summary run. Do NOT auto-invoke when implementation completes. Generates summary.md from project artifacts as institutional memory.
5
5
  disable-model-invocation: false
6
6
  user-invocable: true
7
- allowed-tools: Read, Write, Bash(git:*), Glob, Grep, AskUserQuestion
7
+ allowed-tools: Read, Write, Bash(git:*), Bash(oat config:*), Bash(oat decision:*), Glob, Grep, AskUserQuestion
8
8
  ---
9
9
 
10
10
  # Project Summary
@@ -36,22 +36,25 @@ When executing this skill, provide lightweight progress feedback so the user can
36
36
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
37
37
 
38
38
  - Before multi-step work, print step indicators, e.g.:
39
- - `[1/4] Resolving project + reading artifacts…`
40
- - `[2/4] Checking for existing summary…`
41
- - `[3/4] Generating / updating summary sections…`
42
- - `[4/4] Committing…`
39
+ - `[1/5] Resolving project + reading artifacts…`
40
+ - `[2/5] Checking for existing summary…`
41
+ - `[3/5] Generating / updating summary sections…`
42
+ - `[4/5] Promoting key decisions to reference/decisions/ (if PJM installed)…`
43
+ - `[5/5] Committing…`
43
44
 
44
45
  **BLOCKED Activities:**
45
46
 
46
47
  - ❌ No implementation work
47
48
  - ❌ No changing project artifacts (other than summary.md)
48
49
  - ❌ No creating tasks or modifying plan
50
+ - ❌ No hand-authoring decision files or editing `reference/decisions/index.md` inside its managed markers
49
51
 
50
52
  **ALLOWED Activities:**
51
53
 
52
54
  - ✅ Reading all project artifacts
53
55
  - ✅ Creating or updating summary.md
54
56
  - ✅ Committing summary.md changes
57
+ - ✅ Promoting the summary's Key Decisions into canonical `reference/decisions/` records via `oat decision new` (Step 7), gated on the PJM tool pack being installed
55
58
 
56
59
  **Self-Correction Protocol:**
57
60
  If you catch yourself:
@@ -193,20 +196,82 @@ oat_summary_includes_revisions: [{ list of p-revN IDs reflected }]
193
196
  ---
194
197
  ```
195
198
 
196
- ### Step 6: Commit
199
+ ### Step 6: Promote Key Decisions to Canonical Decision Records
200
+
201
+ Run this step **after** `summary.md` (including its `## Key Decisions` section) has been written/refreshed and its frontmatter updated. It promotes the project's Key Decisions out of per-project prose and into the canonical, repo-wide `reference/decisions/` log so they stop being siloed in `summary.md`. This step is **additive and non-interactive** — it never prompts.
202
+
203
+ **6.1 — PJM gate (auto, no prompt).** Check whether the PJM tool pack is installed:
204
+
205
+ ```bash
206
+ PJM_ENABLED=$(oat config get tools.project-management 2>/dev/null || echo "")
207
+ ```
208
+
209
+ - If `PJM_ENABLED` is `true` → perform the promotion automatically. Do NOT ask the user.
210
+ - Otherwise (any other value, empty, or unset) → **skip this entire step silently.** Do not print a warning or prompt.
211
+
212
+ **6.2 — Skip if nothing to promote.** If `summary.md` has no `## Key Decisions` section, or that section has no decision content, skip the step. There is nothing to promote.
213
+
214
+ **6.3 — Ensure the decisions surface exists.** The canonical decisions root is `.oat/repo/reference/decisions` (the `oat decision` default; pass `--decisions-root <path>` only for an explicit override). If its managed index is missing — i.e. `.oat/repo/reference/decisions/index.md` does not exist — initialize it first so `oat decision new` can succeed:
215
+
216
+ ```bash
217
+ test -f .oat/repo/reference/decisions/index.md || oat decision init
218
+ ```
219
+
220
+ `oat decision init` is idempotent; running it when the scaffold already exists is harmless.
221
+
222
+ **6.4 — Idempotent, date-independent promotion (critical).** For each decision in `## Key Decisions`:
223
+
224
+ 1. **Derive title + rationale.** The decision's bold lead-in / first clause becomes the **title** (a short noun phrase). The remaining explanatory text becomes the **rationale**, passed verbatim as `--context`.
225
+ 2. **Compute the slug the CLI would use.** The CLI generates the record ID as `DR-<YYMMDD>-<slug>`, where `<slug>` is the lowercased, ASCII-folded, hyphen-collapsed form of the title, capped at 30 characters at the last whole-word boundary with trailing stop-words (`a, an, the, of, for, and, to, in, on, as, with`) trimmed (the same slug rule the CLI applies). Compute that `<slug>` for the title.
226
+ 3. **Dedup on the exact slug, ignoring only the date prefix.** A record ID is `DR-<YYMMDD>-<slug>`, where the date is exactly six digits. Check whether a record for this slug already exists by stripping that fixed `DR-<6 digits>-` prefix from existing record IDs and comparing the remaining slug for **exact equality**. Anchor the date to exactly six characters so the slug must match in full:
227
+
228
+ ```bash
229
+ # the six '?' pin the YYMMDD date, so <slug> must match exactly (not as a suffix)
230
+ ls .oat/repo/reference/decisions/DR-??????-"<slug>".md 2>/dev/null
231
+ ```
232
+
233
+ Do **not** use a loose `DR-*-<slug>.md` glob: the greedy `*` would let a short slug (e.g. `layers`) falsely match a longer record (`DR-260623-two-layers.md`) and wrongly skip it. (Equivalently, scan the `ID` column of `reference/decisions/index.md`, strip each `DR-<6 digits>-` prefix, and compare the slug exactly.) This date-independent, exact-slug match is essential: the `DR-YYMMDD-` date prefix changes across re-runs, so a naive full-ID `DR-YYMMDD-<slug>` check would never dedup, while a loose suffix match would over-dedup.
234
+
235
+ 4. **Skip or create.**
236
+ - If a matching record already exists (same slug) → **skip it.** It was already promoted on a prior run.
237
+ - Otherwise → create it:
238
+
239
+ ```bash
240
+ oat decision new "<title>" --status accepted --context "<rationale>"
241
+ ```
242
+
243
+ The command generates the deterministic `DR-YYMMDD-slug` ID, seeds the body from `.oat/templates/decision.md`, and regenerates the managed index automatically — do not hand-edit `index.md`. Optionally pass `--created-at "<project completion date>"` when a project completion date is available, so the record's date reflects when the decision was made.
244
+
245
+ Because of the date-independent slug dedup, this step is **safe to run every time `summary.md` is (re)generated** — including the pr-final refresh and revision re-runs — without ever creating duplicate decision records. Already-promoted decisions are skipped; only genuinely new Key Decisions become new records.
246
+
247
+ **Status value:** use `--status accepted`. The decision template's status field (`.oat/templates/decision.md`) is free-form, and the canonical accepted/decided value in the decision vocabulary (`proposed` → `accepted` → `superseded`) is `accepted`. A Key Decision in a completed project's summary represents a decision that was made and shipped, so `accepted` is the correct status.
248
+
249
+ **6.5 — Report, don't prompt.** After processing all Key Decisions, print a short informational summary, e.g.:
250
+
251
+ ```
252
+ Promoted N key decision(s) to reference/decisions/:
253
+ - created: DR-YYMMDD-<slug> ("<title>")
254
+ - skipped (already promoted): <slug>
255
+ ```
256
+
257
+ This is informational only. There is no interactive prompt anywhere in this step.
258
+
259
+ ### Step 7: Commit
197
260
 
198
261
  ```bash
199
262
  git add "$PROJECT_PATH/summary.md"
200
263
  git commit -m "docs: generate summary for {project-name}"
201
264
  ```
202
265
 
266
+ If decision records were promoted in Step 6, also stage `.oat/repo/reference/decisions/` so the new `DR-*.md` records and the regenerated `index.md` land with the summary.
267
+
203
268
  If this is a re-run (incremental update):
204
269
 
205
270
  ```bash
206
271
  git commit -m "docs: update summary for {project-name}"
207
272
  ```
208
273
 
209
- ### Step 7: Output Summary
274
+ ### Step 8: Output Summary
210
275
 
211
276
  ```
212
277
  Summary generated for {project-name}.
@@ -214,6 +279,7 @@ Summary generated for {project-name}.
214
279
  Sections: {list of non-empty sections included}
215
280
  Lines: {line count}
216
281
  Mode: {fresh | incremental update}
282
+ Decisions promoted: {N created, M skipped as already promoted | skipped (PJM not installed)}
217
283
 
218
284
  Summary tracks: last task {task_id}, {N} revision phases
219
285
  ```
@@ -227,3 +293,5 @@ Summary tracks: last task {task_id}, {N} revision phases
227
293
  - Summary is under 200 lines for typical projects
228
294
  - Re-run after revisions updates only affected sections
229
295
  - Re-run with no changes produces no modifications
296
+ - When the PJM tool pack is installed, each Key Decision is promoted to a canonical `reference/decisions/DR-YYMMDD-slug` record via `oat decision new` (status `accepted`), deduped on the date-independent slug so re-runs never create duplicate records
297
+ - When the PJM tool pack is not installed, decision promotion is skipped silently with no prompt
@@ -1,5 +1,5 @@
1
1
  ---
2
- id: bl-{hash}
2
+ id: BL-{YYMMDD-slug}
3
3
  title: '{title}'
4
4
  status: open # open | in_progress | closed | wont_do
5
5
  priority: medium # urgent | high | medium | low | none
@@ -5,9 +5,16 @@ oat_template_name: current-state
5
5
 
6
6
  # OAT Current State
7
7
 
8
+ This file is the active operating picture and lives under `pjm/` (the
9
+ operational layer), not `reference/`. To reduce cross-worktree conflicts, keep
10
+ edits append-mostly and scoped to the section you own; avoid rewriting whole
11
+ sections another branch may also touch.
12
+
8
13
  ## Canonical References
9
14
 
10
- <!-- List durable repo references, source-of-truth docs, dashboards, or processes here. -->
15
+ <!-- List durable repo references, source-of-truth docs, dashboards, or processes here.
16
+ Decisions live in reference/decisions/ (one file per record); link them rather than
17
+ copying their content here. -->
11
18
 
12
19
  ## What's Implemented
13
20
 
@@ -15,4 +22,6 @@ oat_template_name: current-state
15
22
 
16
23
  ## What's Next
17
24
 
18
- <!-- Track near-term follow-up work, known gaps, and active handoff context here. -->
25
+ <!-- Track near-term follow-up work, known gaps, and active handoff context here.
26
+ Track concrete items in pjm/backlog/ and sequencing in pjm/roadmap.md; keep this
27
+ section to a short narrative pointer. -->
@@ -0,0 +1,18 @@
1
+ ---
2
+ oat_template: true
3
+ oat_template_name: decision
4
+ ---
5
+
6
+ # {title}
7
+
8
+ ## Context
9
+
10
+ {context}
11
+
12
+ ## Decision
13
+
14
+ {decision}
15
+
16
+ ## Consequences
17
+
18
+ {consequences}
@@ -0,0 +1,13 @@
1
+ ---
2
+ oat_template: true
3
+ oat_template_name: pjm-agents
4
+ ---
5
+
6
+ # PJM Guidance
7
+
8
+ This directory owns active project-management state.
9
+
10
+ - `current-state.md` records the present operating picture.
11
+ - `roadmap.md` records prioritized direction and sequencing.
12
+ - `backlog/` stores file-per-record backlog items and generated indexes.
13
+ - Do not store durable research, brainstorms, imported plans, or decision history here.
@@ -0,0 +1,14 @@
1
+ ---
2
+ oat_template: true
3
+ oat_template_name: reference-agents
4
+ ---
5
+
6
+ # Durable Reference Guidance
7
+
8
+ This directory owns append-mostly reference material.
9
+
10
+ - `decisions/` stores file-per-record decisions and the generated decision index.
11
+ - `project-summaries/` stores archived project summaries.
12
+ - `external-plans/` stores imported provider or external plans.
13
+ - Create research, brainstorm, and deck folders on demand when a workflow needs them.
14
+ - Do not put active roadmap, current-state, or backlog records directly under `reference/`.
@@ -0,0 +1,13 @@
1
+ ---
2
+ oat_template: true
3
+ oat_template_name: repo-agents
4
+ ---
5
+
6
+ # Repo Reference Guidance
7
+
8
+ Use this directory as the canonical OAT repo-reference root.
9
+
10
+ - Active operational planning lives in `pjm/`.
11
+ - Durable append-mostly references live in `reference/`.
12
+ - Keep generated indexes inside their managed marker pairs.
13
+ - When an index conflicts, regenerate it with the owning OAT command and stage the result.
@@ -5,20 +5,25 @@ oat_template_name: roadmap
5
5
 
6
6
  # Roadmap
7
7
 
8
+ This file records prioritized direction and lives under `pjm/` (the operational
9
+ layer). To reduce cross-worktree conflicts, prefer adding or moving single
10
+ bullet lines over rewriting whole sections, and reference backlog records by ID
11
+ (`BL-YYMMDD-slug`) rather than restating their detail here.
12
+
8
13
  ## Now (Active / Committed)
9
14
 
10
15
  <!-- Add active work here. Format:
11
- - **bl-XXXX: {title}** — brief description. Project: {name} (if linked)
16
+ - **BL-YYMMDD-slug: {title}** — brief description. Project: {name} (if linked)
12
17
  -->
13
18
 
14
19
  ## Next (Planned)
15
20
 
16
21
  <!-- Add planned work here. Format:
17
- - **bl-XXXX: {title}** — brief description. Project: {name} (if linked)
22
+ - **BL-YYMMDD-slug: {title}** — brief description. Project: {name} (if linked)
18
23
  -->
19
24
 
20
25
  ## Later (Directional Intent)
21
26
 
22
27
  <!-- Add directional work here. Format:
23
- - **bl-XXXX: {title}** — brief description. Project: {name} (if linked)
28
+ - **BL-YYMMDD-slug: {title}** — brief description. Project: {name} (if linked)
24
29
  -->
@@ -8,6 +8,7 @@ interface BacklogCommandDependencies {
8
8
  resolveProjectRoot: typeof resolveProjectRoot;
9
9
  initializeBacklog: typeof initializeBacklog;
10
10
  regenerateBacklogIndex: typeof regenerateBacklogIndex;
11
+ pathExists: (path: string) => Promise<boolean>;
11
12
  }
12
13
  export declare function createBacklogCommand(overrides?: Partial<BacklogCommandDependencies>): Command;
13
14
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/backlog/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAuB,MAAM,sBAAsB,CAAC;AAEhF,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAC3C,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAkB5D,UAAU,0BAA0B;IAClC,mBAAmB,EAAE,OAAO,mBAAmB,CAAC;IAChD,kBAAkB,EAAE,OAAO,kBAAkB,CAAC;IAC9C,iBAAiB,EAAE,OAAO,iBAAiB,CAAC;IAC5C,sBAAsB,EAAE,OAAO,sBAAsB,CAAC;CACvD;AAsBD,wBAAgB,oBAAoB,CAClC,SAAS,GAAE,OAAO,CAAC,0BAA0B,CAAM,GAClD,OAAO,CAoGT"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/backlog/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,mBAAmB,EAAuB,MAAM,sBAAsB,CAAC;AAEhF,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAC3C,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAe5D,UAAU,0BAA0B;IAClC,mBAAmB,EAAE,OAAO,mBAAmB,CAAC;IAChD,kBAAkB,EAAE,OAAO,kBAAkB,CAAC;IAC9C,iBAAiB,EAAE,OAAO,iBAAiB,CAAC;IAC5C,sBAAsB,EAAE,OAAO,sBAAsB,CAAC;IACtD,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CAChD;AAyCD,wBAAgB,oBAAoB,CAClC,SAAS,GAAE,OAAO,CAAC,0BAA0B,CAAM,GAClD,OAAO,CAgIT"}
@@ -1,23 +1,40 @@
1
- import { resolve } from 'node:path';
1
+ import { access } from 'node:fs/promises';
2
+ import { join, resolve } from 'node:path';
2
3
  import { buildCommandContext } from '../../app/command-context.js';
3
4
  import { readGlobalOptions } from '../shared/shared.utils.js';
4
5
  import { resolveProjectRoot } from '../../fs/paths.js';
5
6
  import { Command } from 'commander';
6
7
  import { initializeBacklog } from './init.js';
7
8
  import { regenerateBacklogIndex } from './regenerate-index.js';
8
- import { generateUniqueBacklogId, readExistingBacklogIds, } from './shared/generate-id.js';
9
+ import { generateBacklogId } from './shared/generate-id.js';
10
+ async function pathExistsDefault(path) {
11
+ try {
12
+ await access(path);
13
+ return true;
14
+ }
15
+ catch (error) {
16
+ const code = error && typeof error === 'object' && 'code' in error
17
+ ? String(error.code)
18
+ : null;
19
+ if (code !== 'ENOENT') {
20
+ throw error;
21
+ }
22
+ return false;
23
+ }
24
+ }
9
25
  const DEFAULT_DEPENDENCIES = {
10
26
  buildCommandContext,
11
27
  resolveProjectRoot,
12
28
  initializeBacklog,
13
29
  regenerateBacklogIndex,
30
+ pathExists: pathExistsDefault,
14
31
  };
15
32
  async function resolveBacklogRoot(context, configuredRoot, dependencies = DEFAULT_DEPENDENCIES) {
16
33
  if (configuredRoot) {
17
34
  return resolve(context.cwd, configuredRoot);
18
35
  }
19
36
  const projectRoot = await dependencies.resolveProjectRoot(context.cwd);
20
- return resolve(projectRoot, '.oat', 'repo', 'reference', 'backlog');
37
+ return resolve(projectRoot, '.oat', 'repo', 'pjm', 'backlog');
21
38
  }
22
39
  export function createBacklogCommand(overrides = {}) {
23
40
  const dependencies = {
@@ -28,7 +45,7 @@ export function createBacklogCommand(overrides = {}) {
28
45
  cmd
29
46
  .command('init')
30
47
  .description('Scaffold the canonical backlog directory structure and starter files')
31
- .option('--backlog-root <path>', 'Backlog root directory (defaults to .oat/repo/reference/backlog)')
48
+ .option('--backlog-root <path>', 'Backlog root directory (defaults to .oat/repo/pjm/backlog)')
32
49
  .action(async (options, command) => {
33
50
  const context = dependencies.buildCommandContext(readGlobalOptions(command));
34
51
  const backlogRoot = await resolveBacklogRoot(context, options.backlogRoot, dependencies);
@@ -44,7 +61,7 @@ export function createBacklogCommand(overrides = {}) {
44
61
  cmd
45
62
  .command('regenerate-index')
46
63
  .description('Regenerate the managed backlog index table')
47
- .option('--backlog-root <path>', 'Backlog root directory (defaults to .oat/repo/reference/backlog)')
64
+ .option('--backlog-root <path>', 'Backlog root directory (defaults to .oat/repo/pjm/backlog)')
48
65
  .action(async (options, command) => {
49
66
  const context = dependencies.buildCommandContext(readGlobalOptions(command));
50
67
  const backlogRoot = await resolveBacklogRoot(context, options.backlogRoot, dependencies);
@@ -59,17 +76,37 @@ export function createBacklogCommand(overrides = {}) {
59
76
  });
60
77
  cmd
61
78
  .command('generate-id')
62
- .description('Generate a backlog item identifier from a filename seed')
63
- .argument('<filename>', 'Filename or slug seed for the backlog item')
79
+ .description('Generate a backlog item identifier (`BL-YYMMDD-slug`) from a title or slug')
80
+ .argument('<title-or-slug>', 'Title or slug seed for the backlog item')
64
81
  .option('--created-at <timestamp>', 'Creation timestamp seed for reproducible ID generation')
65
- .action(async (filename, options, command) => {
82
+ .action(async (titleOrSlug, options, command) => {
66
83
  const context = dependencies.buildCommandContext(readGlobalOptions(command));
67
84
  const backlogRoot = await resolveBacklogRoot(context, undefined, dependencies);
68
85
  const createdAt = options.createdAt ?? new Date().toISOString();
69
- const existingIds = await readExistingBacklogIds(backlogRoot);
70
- const id = generateUniqueBacklogId(filename, createdAt, existingIds);
86
+ const id = generateBacklogId(titleOrSlug, createdAt);
87
+ const candidatePaths = [
88
+ join(backlogRoot, 'items', `${id}.md`),
89
+ join(backlogRoot, 'archived', `${id}.md`),
90
+ ];
91
+ const collides = (await Promise.all(candidatePaths.map((candidatePath) => dependencies.pathExists(candidatePath)))).some(Boolean);
92
+ if (collides) {
93
+ const message = `Backlog item ${id} already exists. Use a more specific title or slug to disambiguate.`;
94
+ if (context.json) {
95
+ context.logger.json({ status: 'error', id, message });
96
+ }
97
+ else {
98
+ context.logger.error(message);
99
+ }
100
+ process.exitCode = 1;
101
+ return;
102
+ }
71
103
  if (context.json) {
72
- context.logger.json({ status: 'ok', id, filename, createdAt });
104
+ context.logger.json({
105
+ status: 'ok',
106
+ id,
107
+ titleOrSlug,
108
+ createdAt,
109
+ });
73
110
  }
74
111
  else {
75
112
  context.logger.info(id);
@@ -37,7 +37,7 @@ const STARTER_COMPLETED = [
37
37
  '',
38
38
  '## Entry Format',
39
39
  '',
40
- '- `YYYY-MM-DD — bl-XXXX — Title — one-line outcome summary`',
40
+ '- `YYYY-MM-DD — BL-YYMMDD-slug — Title — one-line outcome summary`',
41
41
  '',
42
42
  '## Completed Items',
43
43
  '',
@@ -1 +1 @@
1
- {"version":3,"file":"regenerate-index.d.ts","sourceRoot":"","sources":["../../../src/commands/backlog/regenerate-index.ts"],"names":[],"mappings":"AAkFA,wBAAsB,sBAAsB,CAC1C,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CAmCf"}
1
+ {"version":3,"file":"regenerate-index.d.ts","sourceRoot":"","sources":["../../../src/commands/backlog/regenerate-index.ts"],"names":[],"mappings":"AAmGA,wBAAsB,sBAAsB,CAC1C,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CA+Cf"}
@@ -1,6 +1,7 @@
1
1
  import { readdir, readFile, writeFile } from 'node:fs/promises';
2
2
  import { join } from 'node:path';
3
3
  import { getFrontmatterBlock } from '../shared/frontmatter.js';
4
+ import { computeManagedIndexUpdate } from '../shared/managed-index.js';
4
5
  import YAML from 'yaml';
5
6
  const INDEX_START = '<!-- OAT BACKLOG-INDEX -->';
6
7
  const INDEX_END = '<!-- END OAT BACKLOG-INDEX -->';
@@ -36,7 +37,19 @@ function compareItems(a, b) {
36
37
  if (priorityDiff !== 0) {
37
38
  return priorityDiff;
38
39
  }
39
- return a.title.localeCompare(b.title);
40
+ if (a.title < b.title) {
41
+ return -1;
42
+ }
43
+ if (a.title > b.title) {
44
+ return 1;
45
+ }
46
+ if (a.id < b.id) {
47
+ return -1;
48
+ }
49
+ if (a.id > b.id) {
50
+ return 1;
51
+ }
52
+ return 0;
40
53
  }
41
54
  function renderManagedSection(items) {
42
55
  const rows = items.length > 0
@@ -55,7 +68,8 @@ export async function regenerateBacklogIndex(backlogRoot) {
55
68
  const indexPath = join(backlogRoot, 'index.md');
56
69
  const entries = (await readdir(itemsDir, { withFileTypes: true }))
57
70
  .filter((entry) => entry.isFile() && entry.name.endsWith('.md'))
58
- .map((entry) => entry.name);
71
+ .map((entry) => entry.name)
72
+ .sort();
59
73
  const items = [];
60
74
  for (const entry of entries) {
61
75
  const filePath = join(itemsDir, entry);
@@ -71,8 +85,13 @@ export async function regenerateBacklogIndex(backlogRoot) {
71
85
  if (startIndex === -1 || endIndex === -1) {
72
86
  throw new Error(`Managed backlog index markers missing in ${indexPath}. Expected the exact marker pair:\n${INDEX_START}\n${INDEX_END}\nRun \`oat backlog init\` if the backlog scaffold is missing, or restore those exact markers in \`backlog/index.md\` before rerunning \`oat backlog regenerate-index\`.`);
73
87
  }
74
- const before = content.slice(0, startIndex);
75
- const after = content.slice(endIndex + INDEX_END.length);
76
- const updated = `${before}${renderManagedSection(items)}${after}`;
88
+ // Content-idempotent gate: when the on-disk managed block is logically equal
89
+ // to the freshly rendered block (cells equal after trimming, so external
90
+ // formatter padding is ignored), preserve the existing bytes and skip the
91
+ // write. Only rewrite on a genuine content change.
92
+ const { content: updated } = computeManagedIndexUpdate(content, startIndex, endIndex + INDEX_END.length, renderManagedSection(items));
93
+ if (updated === null) {
94
+ return;
95
+ }
77
96
  await writeFile(indexPath, updated, 'utf8');
78
97
  }
@@ -1,4 +1,2 @@
1
- export declare function generateBacklogId(filename: string, createdAt: string, nonce?: number): string;
2
- export declare function generateUniqueBacklogId(filename: string, createdAt: string, existingIds: Iterable<string>): string;
3
- export declare function readExistingBacklogIds(backlogRoot: string): Promise<Set<string>>;
1
+ export declare function generateBacklogId(titleOrSlug: string, createdAt: string): string;
4
2
  //# sourceMappingURL=generate-id.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"generate-id.d.ts","sourceRoot":"","sources":["../../../../src/commands/backlog/shared/generate-id.ts"],"names":[],"mappings":"AAeA,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,KAAK,SAAI,GACR,MAAM,CAQR;AAED,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,GAC5B,MAAM,CAWR;AAED,wBAAsB,sBAAsB,CAC1C,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAgDtB"}
1
+ {"version":3,"file":"generate-id.d.ts","sourceRoot":"","sources":["../../../../src/commands/backlog/shared/generate-id.ts"],"names":[],"mappings":"AAGA,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,GAChB,MAAM,CAER"}
@@ -1,65 +1,5 @@
1
- import { createHash } from 'node:crypto';
2
- import { readdir, readFile } from 'node:fs/promises';
3
- import { join } from 'node:path';
4
- import { getFrontmatterBlock } from '../../shared/frontmatter.js';
5
- import YAML from 'yaml';
6
- function buildBacklogHashInput(filename, createdAt, nonce) {
7
- return nonce === 0 ? filename : `${filename}#${nonce}`;
8
- }
9
- export function generateBacklogId(filename, createdAt, nonce = 0) {
10
- const hash = createHash('sha256')
11
- .update(buildBacklogHashInput(filename, createdAt, nonce))
12
- .update('\0')
13
- .update(createdAt)
14
- .digest('hex');
15
- return `bl-${hash.slice(0, 4)}`;
16
- }
17
- export function generateUniqueBacklogId(filename, createdAt, existingIds) {
18
- const ids = new Set(existingIds);
19
- for (let nonce = 0; nonce < Number.MAX_SAFE_INTEGER; nonce += 1) {
20
- const candidate = generateBacklogId(filename, createdAt, nonce);
21
- if (!ids.has(candidate)) {
22
- return candidate;
23
- }
24
- }
25
- throw new Error('Unable to generate a unique backlog ID.');
26
- }
27
- export async function readExistingBacklogIds(backlogRoot) {
28
- const ids = new Set();
29
- const sourceDirs = ['items', 'archived'];
30
- for (const dirName of sourceDirs) {
31
- const sourceDir = join(backlogRoot, dirName);
32
- try {
33
- const entries = await readdir(sourceDir, { withFileTypes: true });
34
- for (const entry of entries) {
35
- if (!entry.isFile() || !entry.name.endsWith('.md')) {
36
- continue;
37
- }
38
- const content = await readFile(join(sourceDir, entry.name), 'utf8');
39
- const rawFrontmatter = getFrontmatterBlock(content);
40
- if (!rawFrontmatter) {
41
- continue;
42
- }
43
- const parsed = YAML.parse(rawFrontmatter);
44
- if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
45
- continue;
46
- }
47
- const id = parsed.id;
48
- if (typeof id === 'string' && id.length > 0) {
49
- ids.add(id);
50
- }
51
- }
52
- continue;
53
- }
54
- catch (error) {
55
- const code = error && typeof error === 'object' && 'code' in error
56
- ? String(error.code)
57
- : null;
58
- if (code === 'ENOENT') {
59
- continue;
60
- }
61
- throw error;
62
- }
63
- }
64
- return ids;
1
+ import { yymmdd } from '../../shared/date-id.js';
2
+ import { slugify } from '../../shared/slug.js';
3
+ export function generateBacklogId(titleOrSlug, createdAt) {
4
+ return `BL-${yymmdd(createdAt)}-${slugify(titleOrSlug)}`;
65
5
  }
@@ -1 +1 @@
1
- {"version":3,"file":"artifacts.d.ts","sourceRoot":"","sources":["../../../../src/commands/cleanup/artifacts/artifacts.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"artifacts.d.ts","sourceRoot":"","sources":["../../../../src/commands/cleanup/artifacts/artifacts.ts"],"names":[],"mappings":"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"}
@@ -87,7 +87,10 @@ export async function discoverArtifactCandidates(repoRoot, excludedTargets = [])
87
87
  }
88
88
  async function collectReferenceContents(repoRoot) {
89
89
  const contents = [];
90
- const repoReferenceFiles = await collectMarkdownFiles(join(repoRoot, '.oat/repo/reference'));
90
+ const repoReferenceFiles = (await Promise.all([
91
+ join(repoRoot, '.oat/repo/pjm'),
92
+ join(repoRoot, '.oat/repo/reference'),
93
+ ].map((root) => collectMarkdownFiles(root)))).flat();
91
94
  let activeProjectFiles = [];
92
95
  try {
93
96
  const localConfig = await readOatLocalConfig(repoRoot);
@@ -0,0 +1,20 @@
1
+ import { buildCommandContext } from '../../app/command-context.js';
2
+ import { resolveAssetsRoot } from '../../fs/assets.js';
3
+ import { resolveProjectRoot } from '../../fs/paths.js';
4
+ import { Command } from 'commander';
5
+ import { initializeDecisionRecords } from './init.js';
6
+ import { migrateDecisionRecords } from './migrate.js';
7
+ import { createDecisionRecord } from './new.js';
8
+ import { regenerateDecisionIndex } from './regenerate-index.js';
9
+ interface DecisionCommandDependencies {
10
+ buildCommandContext: typeof buildCommandContext;
11
+ resolveProjectRoot: typeof resolveProjectRoot;
12
+ resolveAssetsRoot: typeof resolveAssetsRoot;
13
+ initializeDecisionRecords: typeof initializeDecisionRecords;
14
+ regenerateDecisionIndex: typeof regenerateDecisionIndex;
15
+ createDecisionRecord: typeof createDecisionRecord;
16
+ migrateDecisionRecords: typeof migrateDecisionRecords;
17
+ }
18
+ export declare function createDecisionCommand(overrides?: Partial<DecisionCommandDependencies>): Command;
19
+ export {};
20
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/decision/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAuB,MAAM,sBAAsB,CAAC;AAEhF,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,yBAAyB,EAAE,MAAM,QAAQ,CAAC;AACnD,OAAO,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAC7C,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAuB7D,UAAU,2BAA2B;IACnC,mBAAmB,EAAE,OAAO,mBAAmB,CAAC;IAChD,kBAAkB,EAAE,OAAO,kBAAkB,CAAC;IAC9C,iBAAiB,EAAE,OAAO,iBAAiB,CAAC;IAC5C,yBAAyB,EAAE,OAAO,yBAAyB,CAAC;IAC5D,uBAAuB,EAAE,OAAO,uBAAuB,CAAC;IACxD,oBAAoB,EAAE,OAAO,oBAAoB,CAAC;IAClD,sBAAsB,EAAE,OAAO,sBAAsB,CAAC;CACvD;AA8CD,wBAAgB,qBAAqB,CACnC,SAAS,GAAE,OAAO,CAAC,2BAA2B,CAAM,GACnD,OAAO,CA+LT"}