@open-agent-toolkit/cli 0.3.8 → 0.3.10

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 (121) hide show
  1. package/README.md +3 -3
  2. package/assets/agents/oat-codebase-mapper.md +3 -2
  3. package/assets/agents/oat-reviewer.md +5 -13
  4. package/assets/agents/skeptical-evaluator.md +6 -2
  5. package/assets/bundle-metadata.json +1 -1
  6. package/assets/config/dispatch-matrix-recommendation.json +6 -6
  7. package/assets/docs/cli-utilities/backlog-lifecycle.md +3 -2
  8. package/assets/docs/cli-utilities/bootstrap.md +5 -2
  9. package/assets/docs/cli-utilities/config-and-local-state.md +13 -6
  10. package/assets/docs/cli-utilities/configuration.md +22 -17
  11. package/assets/docs/cli-utilities/tool-packs.md +60 -10
  12. package/assets/docs/cli-utilities/workflow-gates.md +1 -1
  13. package/assets/docs/contributing/code.md +9 -5
  14. package/assets/docs/contributing/updating-model-guidance.md +34 -6
  15. package/assets/docs/contributing/verifying-cursor-pins.md +38 -9
  16. package/assets/docs/provider-sync/commands.md +11 -8
  17. package/assets/docs/provider-sync/instruction-sync.md +241 -39
  18. package/assets/docs/provider-sync/providers.md +4 -4
  19. package/assets/docs/provider-sync/scope-and-surface.md +1 -1
  20. package/assets/docs/reference/cli-reference.md +2 -0
  21. package/assets/docs/reference/oat-directory-structure.md +12 -11
  22. package/assets/docs/reference/troubleshooting.md +19 -4
  23. package/assets/docs/workflows/projects/dispatch-ceiling.md +21 -14
  24. package/assets/docs/workflows/projects/implementation-execution.md +26 -9
  25. package/assets/docs/workflows/projects/lifecycle.md +4 -6
  26. package/assets/public-package-versions.json +4 -4
  27. package/assets/skills/oat-agent-instructions-analyze/SKILL.md +4 -4
  28. package/assets/skills/oat-agent-instructions-analyze/references/analysis-artifact-template.md +5 -5
  29. package/assets/skills/oat-agent-instructions-analyze/references/docs/rules-files.md +14 -11
  30. package/assets/skills/oat-agent-instructions-analyze/references/quality-checklist.md +2 -2
  31. package/assets/skills/oat-agent-instructions-analyze/scripts/resolve-instruction-files.sh +4 -3
  32. package/assets/skills/oat-agent-instructions-apply/SKILL.md +3 -3
  33. package/assets/skills/oat-agent-instructions-apply/references/docs/rules-files.md +14 -11
  34. package/assets/skills/oat-dispatch-subagents/SKILL.md +1 -1
  35. package/assets/skills/oat-dispatch-subagents/references/provider-cursor.md +5 -2
  36. package/assets/skills/oat-doctor/SKILL.md +17 -13
  37. package/assets/skills/oat-project-implement/SKILL.md +2 -2
  38. package/assets/skills/oat-project-implement/references/completion-and-closeout.md +33 -11
  39. package/assets/skills/oat-project-implement/references/dispatch-and-dry-run.md +1 -1
  40. package/assets/skills/oat-project-implement/references/phase-execution.md +109 -8
  41. package/assets/skills/oat-project-lite/SKILL.md +23 -1
  42. package/assets/skills/oat-project-next/SKILL.md +3 -3
  43. package/assets/skills/oat-project-plan-writing/SKILL.md +3 -3
  44. package/assets/skills/oat-project-progress/SKILL.md +2 -2
  45. package/assets/skills/subagent-orchestration/SKILL.md +1 -1
  46. package/assets/skills/subagent-orchestration/references/evidence-and-refresh.md +20 -8
  47. package/assets/skills/subagent-orchestration/references/provider-claude.md +25 -12
  48. package/assets/skills/subagent-orchestration/references/provider-codex.md +27 -18
  49. package/assets/skills/subagent-orchestration/references/provider-cursor.md +40 -10
  50. package/assets/templates/docs-app-mkdocs/docs/contributing.md +1 -3
  51. package/assets/templates/pjm-agents.md +7 -3
  52. package/assets/templates/state.md +2 -2
  53. package/dist/commands/backlog/archive.d.ts +10 -2
  54. package/dist/commands/backlog/archive.d.ts.map +1 -1
  55. package/dist/commands/backlog/archive.js +22 -6
  56. package/dist/commands/backlog/index.d.ts.map +1 -1
  57. package/dist/commands/backlog/index.js +5 -1
  58. package/dist/commands/backlog/rewrite-references.d.ts +41 -0
  59. package/dist/commands/backlog/rewrite-references.d.ts.map +1 -0
  60. package/dist/commands/backlog/rewrite-references.js +516 -0
  61. package/dist/commands/config/index.d.ts +1 -0
  62. package/dist/commands/config/index.d.ts.map +1 -1
  63. package/dist/commands/config/index.js +69 -34
  64. package/dist/commands/init/index.d.ts +6 -0
  65. package/dist/commands/init/index.d.ts.map +1 -1
  66. package/dist/commands/init/index.js +27 -4
  67. package/dist/commands/init/tools/index.d.ts +18 -1
  68. package/dist/commands/init/tools/index.d.ts.map +1 -1
  69. package/dist/commands/init/tools/index.js +84 -17
  70. package/dist/commands/init/tools/project-guidance.d.ts +19 -4
  71. package/dist/commands/init/tools/project-guidance.d.ts.map +1 -1
  72. package/dist/commands/init/tools/project-guidance.js +58 -15
  73. package/dist/commands/init/tools/workflows/index.d.ts.map +1 -1
  74. package/dist/commands/init/tools/workflows/index.js +5 -1
  75. package/dist/commands/instructions/instructions.types.d.ts +105 -4
  76. package/dist/commands/instructions/instructions.types.d.ts.map +1 -1
  77. package/dist/commands/instructions/instructions.types.js +4 -5
  78. package/dist/commands/instructions/instructions.utils.d.ts +161 -6
  79. package/dist/commands/instructions/instructions.utils.d.ts.map +1 -1
  80. package/dist/commands/instructions/instructions.utils.js +650 -12
  81. package/dist/commands/instructions/sync/sync.d.ts.map +1 -1
  82. package/dist/commands/instructions/sync/sync.js +256 -18
  83. package/dist/commands/instructions/validate/validate.d.ts.map +1 -1
  84. package/dist/commands/instructions/validate/validate.js +36 -8
  85. package/dist/commands/pjm/index.d.ts.map +1 -1
  86. package/dist/commands/pjm/index.js +19 -4
  87. package/dist/commands/pjm/init.d.ts +3 -0
  88. package/dist/commands/pjm/init.d.ts.map +1 -1
  89. package/dist/commands/pjm/init.js +23 -5
  90. package/dist/commands/shared/agents-md.d.ts +26 -5
  91. package/dist/commands/shared/agents-md.d.ts.map +1 -1
  92. package/dist/commands/shared/agents-md.js +182 -3
  93. package/dist/commands/tools/guidance/index.d.ts +15 -0
  94. package/dist/commands/tools/guidance/index.d.ts.map +1 -0
  95. package/dist/commands/tools/guidance/index.js +81 -0
  96. package/dist/commands/tools/index.d.ts.map +1 -1
  97. package/dist/commands/tools/index.js +2 -0
  98. package/dist/config/oat-config.d.ts +49 -3
  99. package/dist/config/oat-config.d.ts.map +1 -1
  100. package/dist/config/oat-config.js +107 -14
  101. package/dist/config/resolve.d.ts.map +1 -1
  102. package/dist/config/resolve.js +12 -2
  103. package/dist/providers/claude/dispatch-envelope.d.ts.map +1 -1
  104. package/dist/providers/claude/dispatch-envelope.js +1 -0
  105. package/dist/providers/claude/targets.d.ts +1 -0
  106. package/dist/providers/claude/targets.d.ts.map +1 -1
  107. package/dist/providers/claude/targets.js +3 -1
  108. package/dist/providers/codex/codec/shared.d.ts +3 -0
  109. package/dist/providers/codex/codec/shared.d.ts.map +1 -1
  110. package/dist/providers/codex/codec/shared.js +4 -0
  111. package/dist/providers/cursor/codec/catalog.d.ts +2 -2
  112. package/dist/providers/cursor/codec/catalog.d.ts.map +1 -1
  113. package/dist/providers/cursor/codec/catalog.js +45 -0
  114. package/dist/providers/cursor/codec/mapping-validation.d.ts +4 -0
  115. package/dist/providers/cursor/codec/mapping-validation.d.ts.map +1 -0
  116. package/dist/providers/cursor/codec/mapping-validation.js +25 -0
  117. package/dist/providers/cursor/codec/materialize.d.ts.map +1 -1
  118. package/dist/providers/cursor/codec/materialize.js +2 -11
  119. package/dist/providers/cursor/codec/sync-extension.d.ts.map +1 -1
  120. package/dist/providers/cursor/codec/sync-extension.js +2 -11
  121. package/package.json +2 -2
@@ -1,7 +1,7 @@
1
1
  ---
2
- guidance_version: 2026-09-24
3
- last_verified: 2026-09-24
4
- review_after: 2026-12-22
2
+ guidance_version: 2026-10-01
3
+ last_verified: 2026-10-01
4
+ review_after: 2026-12-30
5
5
  ---
6
6
 
7
7
  # Codex and OpenAI Model Selection
@@ -13,16 +13,19 @@ model examples below. Launch mechanics for OAT dispatch live in
13
13
 
14
14
  ## Current Families
15
15
 
16
- Use verified GPT-6 Sol/Luna model IDs for routine new Codex work. GPT-6 Astra
16
+ Use `gpt-6.1-sol` for new Sol routes and `gpt-6-luna` for bounded Luna work.
17
+ This Sol selector migration preserves the existing task-class effort guidance;
18
+ it does not claim a newly measured workload advantage. GPT-6 Astra
17
19
  is a supported Frontier candidate:
18
20
 
19
21
  - `gpt-6-astra`: Frontier candidate for especially demanding work; the bundled
20
22
  recommendation uses high and xhigh, while the supported catalogue also
21
23
  permits low, medium, and max;
22
- - `gpt-6-sol`: high-capability implementation and reasoning route;
24
+ - `gpt-6.1-sol`: high-capability implementation and reasoning route;
23
25
  - `gpt-6-luna`: cost-sensitive, bounded work.
24
26
 
25
- Public engineering benchmarks show task-dependent Astra gains over Sol, with
27
+ The earlier public engineering benchmarks show task-dependent Astra gains
28
+ over GPT-6 Sol, with
26
29
  cost and runtime tradeoffs; they do not establish a universal replacement. The
27
30
  September frontier-release comparison remains review-pending in the separate
28
31
  model-selection vault, and no matched OAT workload evaluation has qualified a
@@ -30,8 +33,8 @@ routine default change. Astra's Frontier inclusion is a user-directed
30
33
  preference. Keep the Sol task-class defaults below while that evidence is
31
34
  reconciled and local task fit is evaluated.
32
35
 
33
- The GPT-5.6 Sol/Luna/Terra targets remain supported for explicit configurations
34
- and established workloads. Re-evaluate economics and qualitative routing on
36
+ GPT-6 Sol (`gpt-6-sol`) and the GPT-5.6 Sol/Luna/Terra targets remain supported
37
+ for explicit configurations and established workloads. Re-evaluate economics and qualitative routing on
35
38
  representative work before carrying over GPT-5.6-specific comparisons.
36
39
 
37
40
  Direct API specialist routes:
@@ -48,18 +51,24 @@ name includes `codex`.
48
51
  ## Dated Task-Class Matrix
49
52
 
50
53
  These are current task-class starting points, not an evaluated ordering across
51
- providers or a promise about relative GPT-6 latency and price. All shown
54
+ providers or a promise about relative GPT-6 or GPT-6.1 latency and price. All shown
52
55
  model/effort pairs are in the local Codex catalogue.
53
56
 
54
- | Task class | Default | Escalation | Floor notes |
55
- | ------------------------ | ------------------------------------------ | --------------------------------------------------------------------- | ----------------------------------------------------------------------------- |
56
- | `mechanical-recon` | `gpt-6-luna`, high | `gpt-6-sol`, medium | Lower effort is suitable only when a miss is cheap and mechanically detected. |
57
- | `intelligent-recon` | `gpt-6-sol`, medium | Sol high | Preserve verification for silent-miss-prone reconnaissance. |
58
- | `default-implementation` | `gpt-6-sol`, medium | Sol high | Luna is for independently bounded, strongly verified work. |
59
- | `hard-reasoning` | `gpt-6-sol`, high | Sol xhigh | Narrow the problem before raising effort. |
60
- | `consequential` | `gpt-6-sol`, high, plus independent review | Sol xhigh for a reasoning-depth bottleneck; max only after evaluation | The root retains consequential authorization. |
61
-
62
- The bundled Frontier ladder ends with Astra xhigh after Sol xhigh and Astra
57
+ | Task class | Default | Escalation | Floor notes |
58
+ | ------------------------ | -------------------------------------------- | --------------------------------------------------------------------- | ----------------------------------------------------------------------------- |
59
+ | `mechanical-recon` | `gpt-6-luna`, high | `gpt-6.1-sol`, medium | Lower effort is suitable only when a miss is cheap and mechanically detected. |
60
+ | `intelligent-recon` | `gpt-6.1-sol`, medium | Sol high | Preserve verification for silent-miss-prone reconnaissance. |
61
+ | `default-implementation` | `gpt-6.1-sol`, medium | Sol high | Luna is for independently bounded, strongly verified work. |
62
+ | `hard-reasoning` | `gpt-6.1-sol`, high | Sol xhigh | Narrow the problem before raising effort. |
63
+ | `consequential` | `gpt-6.1-sol`, high, plus independent review | Sol xhigh for a reasoning-depth bottleneck; max only after evaluation | The root retains consequential authorization. |
64
+
65
+ [OpenAI's GPT-6.1 Sol model reference](https://developers.openai.com/api/docs/models/gpt-6.1-sol)
66
+ identifies `gpt-6.1-sol` and the supported efforts `low`, `medium`, `high`,
67
+ `xhigh`, and `max`. Do not emit `none` or `minimal` for this family. For direct
68
+ API tool calls, use the Responses API. Verify the launching Codex runtime
69
+ independently of API availability.
70
+
71
+ The bundled Frontier ladder ends with Astra xhigh after Sol 6.1 xhigh and Astra
63
72
  high. The supported Astra and Sol effort sets both end at max, so Sol max
64
73
  remains available for explicit configuration even though it is no longer in
65
74
  the bundled Frontier recommendation.
@@ -1,12 +1,14 @@
1
1
  ---
2
- guidance_version: 2026-09-25
3
- last_verified: 2026-09-25
4
- review_after: 2026-12-24
2
+ guidance_version: 2026-10-01
3
+ last_verified: 2026-10-01
4
+ review_after: 2026-12-30
5
5
  catalog_basis:
6
6
  Cursor desktop 3.21.18 resolved Grok 4.6 and Fable 5.1 effort selectors in
7
7
  native subagent hooks, and Grok 4.7 only as bare flat IDs; Cursor desktop
8
8
  3.20.14 resolved all five Opus 5.5 effort selectors; GPT-6 Sol/Luna were
9
- absent from the observed Cursor catalog
9
+ absent from the observed Cursor catalog; the 2026-10-01 CLI catalog lists
10
+ Sonnet 5.5 flat IDs; Cursor desktop 3.22.12 matched five exact-ID Sonnet
11
+ 5.5 pins while every bracket-form Sonnet 5.5 probe fell back
10
12
  ---
11
13
 
12
14
  # Cursor Model Selection
@@ -51,8 +53,8 @@ Cursor desktop 3.20.14 resolved all five `claude-opus-5-5[effort=...]`
51
53
  selectors to corresponding flat IDs in native hooks; on 2026-09-25, Cursor
52
54
  desktop 3.21.18 did the same for Grok 4.6 and Fable 5.1. See the
53
55
  probe records at `packages/cli/src/providers/cursor/codec/__fixtures__/README.md`.
54
- GPT-6 Sol/Luna were absent from the observed Cursor catalogue, so their Codex
55
- availability does not authorize Cursor routes.
56
+ GPT-6 Sol/Luna and GPT-6.1 Sol were absent from the 2026-10-01 Cursor CLI
57
+ catalogue, so their Codex availability does not authorize Cursor routes.
56
58
 
57
59
  | Task class | Default | Economy | Escalation | Floor notes |
58
60
  | ------------------------ | ------------------------------------------------------------------- | -------------------------------------------------- | ----------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
@@ -90,8 +92,34 @@ Grok 4.7 has no approved mapping. Every bracket spelling tried
90
92
  (`grok-4.7[effort=...]` with and without `fast`, `reasoning=`, and
91
93
  `grok-4-7[...]`) fell back to that same account default, which is easy to
92
94
  mistake for success because it is itself a Grok 4.7 model. Only bare flat IDs
93
- such as `grok-4.7-medium` resolved as requested, and the approved catalogue
94
- does not emit bare IDs. Do not pin Grok 4.7 until a mapping is approved.
95
+ such as `grok-4.7-medium` resolved as requested, but Grok 4.7 still lacks
96
+ its own approved registry entry and complete per-pin evidence. It stays outside
97
+ the shipped catalogue. This is a family-specific admission gap, not a blanket
98
+ prohibition of exact-ID pins.
99
+
100
+ ## Sonnet 5.5 Exact-ID Pin Evidence
101
+
102
+ The 2026-10-01 Cursor CLI catalogue lists
103
+ `claude-sonnet-5-5-low|medium|high|xhigh|max`. In Cursor desktop 3.22.12,
104
+ every `claude-sonnet-5-5[effort=...]` probe fell back to the account default,
105
+ `grok-4.7-high-fast`. Exact-ID pins
106
+ `claude-sonnet-5-5-low|medium|high|xhigh|max` instead matched their requested
107
+ rungs in `subagentStart`, Shell `preToolUse`, and `subagentStop`. The Opus 5.5
108
+ low positive control matched its established mapping; unknown-family and
109
+ Sonnet 5.5 `ultra` exact-ID controls both fell back to `grok-4.7-high-fast`.
110
+ Catalog visibility or a subagent self-report does not establish those results.
111
+ The 16 correlated summary rows and 64 native events from both rounds live in
112
+ `packages/cli/src/providers/cursor/codec/__fixtures__/cursor-pin-probe-2026-10-01.jsonl`
113
+ and `cursor-pin-probe-2026-10-01-events.jsonl`; the adjacent `README.md` records
114
+ provenance and excludes unrelated discovery calls.
115
+
116
+ Sonnet 5.5 mappings write the verified exact ID as frontmatter `model`.
117
+ Existing Sonnet 5, Opus, Fable, GPT, and Grok mappings retain their independently
118
+ verified selectors. Neither selector form is universally valid: every exact-ID
119
+ mapping requires native hook evidence, non-default-rung and invalid-selector
120
+ controls, and an explicit approved registry entry. There is no generic
121
+ pass-through of flat CLI IDs. See the
122
+ [probe runbook](../../../../apps/oat-docs/docs/contributing/verifying-cursor-pins.md).
95
123
 
96
124
  ## Historical Opus Cursor Probe Evidence (Retired)
97
125
 
@@ -177,8 +205,10 @@ and non-thinking variants.
177
205
  - `claude-fable-5-1-thinking-high`: eligible specialist for hard reasoning and
178
206
  the bundled Frontier terminal target; xhigh only for evaluated long-horizon
179
207
  work. Cursor lists Fable as "NO ZDR"; confirm retention eligibility.
180
- - `claude-sonnet-5-thinking-high`: strong provider-diversity alternative for
181
- normal implementation and agentic work when available.
208
+ - `claude-sonnet-5-5-high`: exact-ID provider-diversity option for normal
209
+ implementation and agentic work; qualify task performance separately.
210
+ - `claude-sonnet-5-thinking-high`: supported compatibility option for
211
+ established workflows.
182
212
  - `gpt-5.4-mini-medium`: economical general tool and coding worker.
183
213
  - `gpt-5.4-nano-medium`: strict extraction, classification, ranking, and simple
184
214
  read-only tool calls. Not a semantic repository worker.
@@ -102,9 +102,8 @@ Extends fenced code support and enables custom fences such as Mermaid:
102
102
  ```mermaid
103
103
  flowchart LR
104
104
  A[Read index.md] --> B[Generate nav]
105
- ````
106
-
107
105
  ```
106
+ ````
108
107
 
109
108
  ### `pymdownx.tabbed`
110
109
 
@@ -119,4 +118,3 @@ Adds table-of-contents anchors and permalinks for headings.
119
118
  - Treat `index.md` plus its `## Contents` section as the local discovery source of truth.
120
119
  - Prefer linking to source files and commands explicitly when documenting behavior.
121
120
  - When adding a new plugin or extension, update this guide with what it does and how to use it.
122
- ```
@@ -36,8 +36,10 @@ for abandoned work and `--summary "<text>"` to record the outcome. The command
36
36
  performs the whole close-out atomically: it flips `status` to the terminal
37
37
  value and bumps `updated`, appends the canonical `backlog/completed.md` entry
38
38
  (always for `closed`; for `wont_do` only when `--summary` is given), moves the
39
- item file from `backlog/items/` to `backlog/archived/`, and regenerates
40
- `backlog/index.md`. Stage the resulting changes with the shipping commit/PR.
39
+ item file from `backlog/items/` to `backlog/archived/`, rewrites inbound
40
+ `.oat/repo` links and path references to the moved file (reporting each
41
+ rewritten file), and regenerates `backlog/index.md`. Stage the resulting
42
+ changes with the shipping commit/PR.
41
43
 
42
44
  **Manual fallback.** These are the steps the command automates — follow them, in
43
45
  order, only when closing out by hand:
@@ -46,7 +48,9 @@ order, only when closing out by hand:
46
48
  2. Append a summary entry to `backlog/completed.md` (newest first; entry format
47
49
  is documented at the top of that file). Add the entry for a `wont_do` item
48
50
  only when the abandonment itself is worth recording (an explicit summary).
49
- 3. `git mv` the item file from `backlog/items/` to `backlog/archived/`.
51
+ 3. `git mv` the item file from `backlog/items/` to `backlog/archived/`, then
52
+ rewrite inbound `.oat/repo` links to `archived/` (plans, decision records,
53
+ other items, and repository-root paths such as `oat_external_plan_sources`).
50
54
  4. Run `oat backlog regenerate-index` and stage the regenerated
51
55
  `backlog/index.md`.
52
56
  5. If the completion changes the operating picture, refresh
@@ -50,8 +50,8 @@ oat_workflow_origin: native # native | imported
50
50
  # max_attempts: 2
51
51
  # attempts_completed: 0
52
52
  # reviewed_head: null
53
- # implementation_base_ref: null # exact logical base ref for effective-delta-v1
54
- # implementation_fingerprint: null # new generations use sha256:effective-delta-v1:<digest>
53
+ # implementation_base_ref: null # exact logical base ref for the qualified effective-delta fingerprint
54
+ # implementation_fingerprint: null # new generations use sha256:effective-delta-v2:<digest>; stored v1 values keep v1 semantics
55
55
  # freshness_head: null # rolling accepted tree checkpoint
56
56
  # freshness_fingerprint: null # full effective delta at freshness_head
57
57
  # launch_state: not_started # not_started | intent_persisted | accepted | result_persisted | not_accepted
@@ -7,6 +7,12 @@ export interface ArchiveBacklogItemResult {
7
7
  completedEntry: 'written' | 'scaffolded' | 'skipped';
8
8
  movedTo: string | null;
9
9
  indexRegenerated: boolean;
10
+ /**
11
+ * Markdown files under `.oat/repo/**` whose references to
12
+ * `items/<id>.md` were rewritten to `archived/<id>.md`, relative to the
13
+ * repository root.
14
+ */
15
+ rewrittenReferences: string[];
10
16
  warnings: string[];
11
17
  }
12
18
  export interface ArchiveBacklogItemOptions {
@@ -26,8 +32,10 @@ export declare class BacklogArchiveError extends Error {
26
32
  /**
27
33
  * Atomic backlog close-out. Validates the current status, sets the terminal
28
34
  * status and `updated`, records a canonical `completed.md` entry, moves the
29
- * item file into `archived/`, and regenerates the index. Idempotent when the
30
- * item is already archived.
35
+ * item file into `archived/`, rewrites inbound `.oat/repo` references to the
36
+ * moved file, and regenerates the index. Idempotent when the item is already
37
+ * archived: that path writes no status, completed-log, or move changes and only
38
+ * retries the reference rewrite and index regeneration.
31
39
  */
32
40
  export declare function archiveBacklogItem(backlogRoot: string, id: string, options?: ArchiveBacklogItemOptions): Promise<ArchiveBacklogItemResult>;
33
41
  //# sourceMappingURL=archive.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"archive.d.ts","sourceRoot":"","sources":["../../../src/commands/backlog/archive.ts"],"names":[],"mappings":"AASA,OAAO,EAEL,KAAK,iBAAiB,EAGvB,MAAM,sBAAsB,CAAC;AAmB9B,mDAAmD;AACnD,MAAM,WAAW,wBAAwB;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,UAAU,GAAG,MAAM,CAAC;IAC5B,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACjC,cAAc,EAAE,SAAS,GAAG,YAAY,GAAG,SAAS,CAAC;IACrD,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,yBAAyB;IACxC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,8EAA8E;IAC9E,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ;AAED;;;GAGG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,QAAQ,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,CAAC;IAEzB,YAAY,OAAO,EAAE,MAAM,EAAE,QAAQ,GAAE,CAAC,GAAG,CAAK,EAI/C;CACF;AAkID;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACtC,WAAW,EAAE,MAAM,EACnB,EAAE,EAAE,MAAM,EACV,OAAO,GAAE,yBAA8B,GACtC,OAAO,CAAC,wBAAwB,CAAC,CAqHnC"}
1
+ {"version":3,"file":"archive.d.ts","sourceRoot":"","sources":["../../../src/commands/backlog/archive.ts"],"names":[],"mappings":"AAUA,OAAO,EAEL,KAAK,iBAAiB,EAGvB,MAAM,sBAAsB,CAAC;AAmB9B,mDAAmD;AACnD,MAAM,WAAW,wBAAwB;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,UAAU,GAAG,MAAM,CAAC;IAC5B,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACjC,cAAc,EAAE,SAAS,GAAG,YAAY,GAAG,SAAS,CAAC;IACrD,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,gBAAgB,EAAE,OAAO,CAAC;IAC1B;;;;OAIG;IACH,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,yBAAyB;IACxC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,8EAA8E;IAC9E,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ;AAED;;;GAGG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,QAAQ,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,CAAC;IAEzB,YAAY,OAAO,EAAE,MAAM,EAAE,QAAQ,GAAE,CAAC,GAAG,CAAK,EAI/C;CACF;AAkID;;;;;;;GAOG;AACH,wBAAsB,kBAAkB,CACtC,WAAW,EAAE,MAAM,EACnB,EAAE,EAAE,MAAM,EACV,OAAO,GAAE,yBAA8B,GACtC,OAAO,CAAC,wBAAwB,CAAC,CA4InC"}
@@ -5,6 +5,7 @@ import { promisify } from 'node:util';
5
5
  import { getFrontmatterBlock } from '../shared/frontmatter.js';
6
6
  import YAML from 'yaml';
7
7
  import { regenerateBacklogIndex } from './regenerate-index.js';
8
+ import { rewriteInboundReferences } from './rewrite-references.js';
8
9
  import { BACKLOG_ITEM_STATUSES, extractBacklogStatus, isValidBacklogStatus, } from './shared/item-status.js';
9
10
  const execFileAsync = promisify(execFile);
10
11
  const COMPLETED_HEADING = '## Completed Items';
@@ -133,14 +134,17 @@ async function moveItemFile(backlogRoot, fromPath, toPath, warnings) {
133
134
  /**
134
135
  * Atomic backlog close-out. Validates the current status, sets the terminal
135
136
  * status and `updated`, records a canonical `completed.md` entry, moves the
136
- * item file into `archived/`, and regenerates the index. Idempotent when the
137
- * item is already archived.
137
+ * item file into `archived/`, rewrites inbound `.oat/repo` references to the
138
+ * moved file, and regenerates the index. Idempotent when the item is already
139
+ * archived: that path writes no status, completed-log, or move changes and only
140
+ * retries the reference rewrite and index regeneration.
138
141
  */
139
142
  export async function archiveBacklogItem(backlogRoot, id, options = {}) {
140
143
  const itemsPath = join(backlogRoot, 'items', `${id}.md`);
141
144
  const archivedPath = join(backlogRoot, 'archived', `${id}.md`);
142
145
  const warnings = [];
143
- // Idempotent no-op: already archived.
146
+ // Already archived: no status, completed-log, or move writes; only the
147
+ // idempotent reference rewrite and index regeneration are retried.
144
148
  if (await pathExists(archivedPath)) {
145
149
  // Conflicting duplicate: the same id lives in BOTH `items/` and
146
150
  // `archived/`. Treating this as a clean no-op would silently leave the live
@@ -157,14 +161,22 @@ export async function archiveBacklogItem(backlogRoot, id, options = {}) {
157
161
  catch {
158
162
  status = null;
159
163
  }
160
- warnings.push(`Backlog item ${id} is already archived at ${archivedPath}; nothing to do.`);
164
+ warnings.push(`Backlog item ${id} is already archived at ${archivedPath}; re-checked inbound references and regenerated the index.`);
165
+ // Retry the idempotent tail of a close-out: a run that failed during the
166
+ // reference rewrite (or an item archived before the rewrite existed)
167
+ // still gets its inbound links repointed and the index regenerated.
168
+ const references = await rewriteInboundReferences(backlogRoot, itemsPath, archivedPath, { rebaseMovedItem: false });
169
+ warnings.push(...references.warnings);
170
+ const regeneration = await regenerateBacklogIndex(backlogRoot);
171
+ warnings.push(...regeneration.warnings);
161
172
  return {
162
173
  id,
163
174
  result: 'noop',
164
175
  status,
165
176
  completedEntry: 'skipped',
166
177
  movedTo: archivedPath,
167
- indexRegenerated: false,
178
+ indexRegenerated: true,
179
+ rewrittenReferences: references.rewritten,
168
180
  warnings,
169
181
  };
170
182
  }
@@ -214,7 +226,10 @@ export async function archiveBacklogItem(backlogRoot, id, options = {}) {
214
226
  }
215
227
  // 6. Move items/<id>.md -> archived/<id>.md (git mv with rename fallback).
216
228
  await moveItemFile(backlogRoot, itemsPath, archivedPath, warnings);
217
- // 7. Regenerate the index via the exported core.
229
+ // 7. Rewrite inbound references so no `.oat/repo` link dangles at items/.
230
+ const references = await rewriteInboundReferences(backlogRoot, itemsPath, archivedPath);
231
+ warnings.push(...references.warnings);
232
+ // 8. Regenerate the index via the exported core.
218
233
  const regeneration = await regenerateBacklogIndex(backlogRoot);
219
234
  warnings.push(...regeneration.warnings);
220
235
  return {
@@ -224,6 +239,7 @@ export async function archiveBacklogItem(backlogRoot, id, options = {}) {
224
239
  completedEntry,
225
240
  movedTo: archivedPath,
226
241
  indexRegenerated: true,
242
+ rewrittenReferences: references.rewritten,
227
243
  warnings,
228
244
  };
229
245
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/backlog/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,mBAAmB,EAAuB,MAAM,sBAAsB,CAAC;AAChF,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAG5D,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,kBAAkB,EAAuB,MAAM,WAAW,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAC3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAC1C,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AA8B5D,UAAU,0BAA0B;IAClC,mBAAmB,EAAE,OAAO,mBAAmB,CAAC;IAChD,kBAAkB,EAAE,OAAO,kBAAkB,CAAC;IAC9C,iBAAiB,EAAE,OAAO,iBAAiB,CAAC;IAC5C,kBAAkB,EAAE,OAAO,kBAAkB,CAAC;IAC9C,iBAAiB,EAAE,OAAO,iBAAiB,CAAC;IAC5C,sBAAsB,EAAE,OAAO,sBAAsB,CAAC;IACtD,iBAAiB,EAAE,OAAO,iBAAiB,CAAC;IAC5C,kBAAkB,EAAE,OAAO,kBAAkB,CAAC;IAC9C,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CAChD;AA4ED,wBAAgB,oBAAoB,CAClC,SAAS,GAAE,OAAO,CAAC,0BAA0B,CAAM,GAClD,OAAO,CAyRT"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/backlog/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,mBAAmB,EAAuB,MAAM,sBAAsB,CAAC;AAChF,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAG5D,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,kBAAkB,EAAuB,MAAM,WAAW,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAC3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAC1C,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AA8B5D,UAAU,0BAA0B;IAClC,mBAAmB,EAAE,OAAO,mBAAmB,CAAC;IAChD,kBAAkB,EAAE,OAAO,kBAAkB,CAAC;IAC9C,iBAAiB,EAAE,OAAO,iBAAiB,CAAC;IAC5C,kBAAkB,EAAE,OAAO,kBAAkB,CAAC;IAC9C,iBAAiB,EAAE,OAAO,iBAAiB,CAAC;IAC5C,sBAAsB,EAAE,OAAO,sBAAsB,CAAC;IACtD,iBAAiB,EAAE,OAAO,iBAAiB,CAAC;IAC5C,kBAAkB,EAAE,OAAO,kBAAkB,CAAC;IAC9C,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CAChD;AA4ED,wBAAgB,oBAAoB,CAClC,SAAS,GAAE,OAAO,CAAC,0BAA0B,CAAM,GAClD,OAAO,CA6RT"}
@@ -179,7 +179,7 @@ export function createBacklogCommand(overrides = {}) {
179
179
  });
180
180
  cmd
181
181
  .command('archive')
182
- .description('Close out a backlog item: set a terminal status, record it in completed.md, move it to archived/, and regenerate the index')
182
+ .description('Close out a backlog item: set a terminal status, record it in completed.md, move it to archived/, rewrite inbound .oat/repo references to it, and regenerate the index')
183
183
  .argument('<id>', 'Backlog item id (`BL-YYMMDD-slug`)')
184
184
  .option('--wont-do', 'Close the item as `wont_do` instead of `closed`')
185
185
  .option('--summary <text>', 'One-line outcome summary for completed.md')
@@ -206,6 +206,10 @@ export function createBacklogCommand(overrides = {}) {
206
206
  else {
207
207
  context.logger.success(`Archived ${id} as ${result.status} (moved to ${result.movedTo}).`);
208
208
  }
209
+ // Both results can rewrite: a retry on an archived item re-runs it.
210
+ for (const path of result.rewrittenReferences) {
211
+ context.logger.info(`Rewrote references in ${path}`);
212
+ }
209
213
  }
210
214
  process.exitCode = 0;
211
215
  }
@@ -0,0 +1,41 @@
1
+ /** Result of {@link rewriteInboundReferences}. */
2
+ export interface RewriteInboundReferencesResult {
3
+ /** Files whose content was rewritten, relative to the repository root. */
4
+ rewritten: string[];
5
+ /** One warning per reference that names the item but cannot be resolved. */
6
+ warnings: string[];
7
+ }
8
+ /** Options for {@link rewriteInboundReferences}. */
9
+ export interface RewriteInboundReferencesOptions {
10
+ /**
11
+ * Rebase the moved item's own relative links from `items/` to `archived/`.
12
+ * Defaults to `true`; a retry on an already-archived item passes `false`
13
+ * because its links were rebased (or written) against `archived/` already.
14
+ */
15
+ rebaseMovedItem?: boolean;
16
+ }
17
+ /** A Markdown segment: prose, an inline code span, or a fenced code block. */
18
+ export interface MarkdownSegment {
19
+ kind: 'prose' | 'span' | 'fence';
20
+ text: string;
21
+ }
22
+ /**
23
+ * Split Markdown into prose, inline code spans, and fenced code blocks.
24
+ * Fences (``` or ~~~) close on a same-character run at least as long, or run
25
+ * to the end of the file. Inline code spans pair a backtick run with the next
26
+ * run of the same length inside one paragraph (a blank line ends it), so a
27
+ * stray backtick never swallows later paragraphs.
28
+ */
29
+ export declare function splitMarkdownCode(content: string): MarkdownSegment[];
30
+ /**
31
+ * After `items/<id>.md` moved to `archived/<id>.md`, rewrite every reference
32
+ * to the old path in Markdown under `.oat/repo/**` (links and repository-root
33
+ * path strings such as `oat_external_plan_sources` frontmatter). An inline code
34
+ * span is rewritten only when its whole content is a path to the item (the
35
+ * external-plan citation form); other spans and fenced code are left as
36
+ * written with a warning, so a recorded command keeps its meaning. References that name the item's `items/` path
37
+ * but cannot be resolved are reported as warnings and left untouched. The
38
+ * rewrite is idempotent, so a re-run on an already-archived item is safe.
39
+ */
40
+ export declare function rewriteInboundReferences(backlogRoot: string, itemsPath: string, archivedPath: string, options?: RewriteInboundReferencesOptions): Promise<RewriteInboundReferencesResult>;
41
+ //# sourceMappingURL=rewrite-references.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rewrite-references.d.ts","sourceRoot":"","sources":["../../../src/commands/backlog/rewrite-references.ts"],"names":[],"mappings":"AAsCA,kDAAkD;AAClD,MAAM,WAAW,8BAA8B;IAC7C,0EAA0E;IAC1E,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,4EAA4E;IAC5E,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,oDAAoD;AACpD,MAAM,WAAW,+BAA+B;IAC9C;;;;OAIG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AA0RD,8EAA8E;AAC9E,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC;IACjC,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,eAAe,EAAE,CA0EpE;AAmND;;;;;;;;;GASG;AACH,wBAAsB,wBAAwB,CAC5C,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE,+BAAoC,GAC5C,OAAO,CAAC,8BAA8B,CAAC,CAsCzC"}