@izkac/forgekit 0.3.12 → 0.3.13

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 (116) hide show
  1. package/bin/forge.mjs +107 -107
  2. package/bin/forgekit.mjs +83 -83
  3. package/bin/review.mjs +81 -81
  4. package/package.json +1 -1
  5. package/scripts/prepack.mjs +78 -78
  6. package/scripts/run-tests.mjs +50 -50
  7. package/src/adr.mjs +236 -236
  8. package/src/adr.test.mjs +170 -170
  9. package/src/change.mjs +327 -234
  10. package/src/change.test.mjs +145 -83
  11. package/src/cleanup-sessions.mjs +84 -84
  12. package/src/config.mjs +103 -103
  13. package/src/defer.mjs +75 -75
  14. package/src/doctor.mjs +350 -341
  15. package/src/doctor.test.mjs +114 -114
  16. package/src/init.mjs +680 -621
  17. package/src/install.mjs +815 -815
  18. package/src/install.test.mjs +180 -180
  19. package/src/integrity-check.mjs +60 -60
  20. package/src/integrity.mjs +682 -682
  21. package/src/integrity.test.mjs +566 -566
  22. package/src/lib.mjs +143 -143
  23. package/src/models.defaults.json +41 -41
  24. package/src/new-session.mjs +99 -99
  25. package/src/openspec-overlays/README.md +19 -19
  26. package/src/openspec-overlays/openspec-apply-change-footer.md +14 -14
  27. package/src/openspec-overlays/opsx-apply-completion-step.md +1 -1
  28. package/src/openspec-overlays/opsx-apply-implement-step.md +11 -11
  29. package/src/paths.mjs +92 -92
  30. package/src/plan-engine.mjs +321 -278
  31. package/src/plan-engine.test.mjs +447 -283
  32. package/src/preferences.defaults.json +78 -78
  33. package/src/preferences.mjs +438 -438
  34. package/src/preferences.test.mjs +174 -174
  35. package/src/record-evidence.mjs +204 -204
  36. package/src/resolve-model.mjs +312 -312
  37. package/src/resolve-model.test.mjs +194 -194
  38. package/src/review/cli.test.mjs +117 -117
  39. package/src/review/export.mjs +172 -172
  40. package/src/review/export.test.mjs +197 -197
  41. package/src/review/fixtures/valid-review.json +42 -42
  42. package/src/review/lib.mjs +894 -894
  43. package/src/review/lib.test.mjs +266 -266
  44. package/src/review/schema.json +196 -196
  45. package/src/review/signals.test.mjs +62 -62
  46. package/src/score-cli.mjs +68 -68
  47. package/src/score.mjs +568 -568
  48. package/src/score.test.mjs +366 -366
  49. package/src/session-reminder.mjs +207 -207
  50. package/src/session-status.mjs +70 -70
  51. package/src/set-models.mjs +186 -186
  52. package/src/set-phase.mjs +205 -205
  53. package/src/set-prefs.mjs +294 -294
  54. package/src/specs-sync.mjs +234 -0
  55. package/src/specs-sync.test.mjs +114 -0
  56. package/src/spine.mjs +93 -93
  57. package/src/triage-prompt.mjs +175 -175
  58. package/src/triage-prompt.test.mjs +50 -50
  59. package/src/vendor-openspec-overlays.mjs +176 -176
  60. package/src/vendor-openspec-overlays.test.mjs +62 -62
  61. package/vendor/skills/archive-to-adr/SKILL.md +149 -149
  62. package/vendor/skills/forge/SKILL.md +136 -136
  63. package/vendor/skills/forge/docs/forge.md +650 -647
  64. package/vendor/skills/forge/phases/brainstorm.md +23 -23
  65. package/vendor/skills/forge/phases/finish.md +90 -87
  66. package/vendor/skills/forge/phases/implement.md +77 -77
  67. package/vendor/skills/forge/phases/plan-openspec.md +60 -60
  68. package/vendor/skills/forge/phases/plan-specs.md +163 -117
  69. package/vendor/skills/forge/phases/review.md +25 -25
  70. package/vendor/skills/forge/phases/verify.md +124 -124
  71. package/vendor/skills/forge/references/forge-layout.md +85 -85
  72. package/vendor/skills/forge/references/pace.md +115 -115
  73. package/vendor/skills/forge/references/plan-routing.md +52 -51
  74. package/vendor/skills/forge/references/runtime-integrity.md +232 -232
  75. package/vendor/skills/forge/references/substantial-work.md +37 -37
  76. package/vendor/skills/forge/references/test-evidence.md +30 -30
  77. package/vendor/skills/forge/references/test-strategy.md +68 -68
  78. package/vendor/skills/forge/skills/subagent-driven-development/SKILL.md +87 -87
  79. package/vendor/skills/forge/subagents/final-reviewer-prompt.md +56 -56
  80. package/vendor/skills/forge/subagents/implementer-prompt.md +38 -38
  81. package/vendor/skills/git-resolve-adr-conflict/SKILL.md +132 -132
  82. package/vendor/skills/thorough-code-review/SKILL.md +290 -290
  83. package/vendor/skills/thorough-code-review/examples.md +133 -133
  84. package/vendor/skills/thorough-code-review/reference/accepted-risks.md +26 -26
  85. package/vendor/skills/thorough-code-review/reference/lenses.md +96 -96
  86. package/vendor/skills/thorough-code-review/reference/phase1-scout.md +62 -62
  87. package/vendor/skills/thorough-code-review/reference/phase2-skeptic.md +105 -105
  88. package/vendor/skills/thorough-code-review/reference/report-schema.json +222 -222
  89. package/vendor/skills/thorough-code-review/reference/report-template.md +115 -115
  90. package/vendor/skills/thorough-code-review/reference/severity-rubric.md +49 -49
  91. package/vendor/skills/thorough-code-review/reference/signals-preflight.md +55 -55
  92. package/vendor/templates/adr/README.md +7 -7
  93. package/vendor/templates/adr/decisions.md +141 -141
  94. package/vendor/templates/adr/hooks/check-pending-adrs.mjs +74 -74
  95. package/vendor/templates/adr/hooks/check-pending-adrs.sh +3 -3
  96. package/vendor/templates/adr/hooks/openspec-archive-agent-message.mjs +52 -52
  97. package/vendor/templates/adr/hooks/openspec-archive-agent-message.sh +3 -3
  98. package/vendor/templates/project/claude/commands/forge-apply.md +75 -75
  99. package/vendor/templates/project/claude/commands/forge-brainstorm.md +7 -7
  100. package/vendor/templates/project/claude/commands/forge-build.md +17 -17
  101. package/vendor/templates/project/claude/commands/forge-plan.md +12 -12
  102. package/vendor/templates/project/claude/commands/forge-skip.md +14 -14
  103. package/vendor/templates/project/claude/commands/forge-status.md +16 -16
  104. package/vendor/templates/project/claude/commands/forge.md +16 -16
  105. package/vendor/templates/project/claude/hooks/forge-prompt-hook.mjs +73 -73
  106. package/vendor/templates/project/claude/hooks/forge-session-start.mjs +19 -19
  107. package/vendor/templates/project/claude/hooks/forge-triage-hook.mjs +77 -77
  108. package/vendor/templates/project/cursor/commands/forge-apply.md +75 -75
  109. package/vendor/templates/project/cursor/commands/forge-brainstorm.md +10 -10
  110. package/vendor/templates/project/cursor/commands/forge-build.md +17 -17
  111. package/vendor/templates/project/cursor/commands/forge-plan.md +15 -15
  112. package/vendor/templates/project/cursor/commands/forge-skip.md +14 -14
  113. package/vendor/templates/project/cursor/commands/forge-status.md +16 -16
  114. package/vendor/templates/project/cursor/commands/forge.md +16 -16
  115. package/vendor/templates/project/cursor/hooks/forge-session-start.mjs +30 -30
  116. package/vendor/templates/project/cursor/hooks/forge-session-start.sh +3 -3
@@ -1,141 +1,141 @@
1
- # Architecture decision records (ADRs)
2
-
3
- > How this project captures **architectural** decisions. ADRs live next to OpenSpec
4
- > archives. Scaffolded by Forgekit (`forge init --adr` / `forgekit install` with ADRs on).
5
-
6
- ADR directory for this project: **`{{ADR_DIR}}`** (configured in `.forge/config.json`).
7
-
8
- ---
9
-
10
- ## 1. Why ADRs *and* OpenSpec archives?
11
-
12
- They overlap in “why we did something,” but they serve different lookups:
13
-
14
- | OpenSpec archive (verbose) | ADR (short) |
15
- | -------------------------- | ----------- |
16
- | `proposal.md`, `design.md`, `tasks.md`, specs | One file, one sharpened decision |
17
- | “Replay the implementation story” | “Why is X shaped this way?” |
18
-
19
- ---
20
-
21
- ## 2. When to write an ADR
22
-
23
- | Write an ADR when the change … | Skip the ADR when … |
24
- | ------------------------------ | ------------------- |
25
- | Establishes or moves a boundary | Bug fix / copy / docs-only |
26
- | Chooses among real alternatives | Refactor that changes no decision |
27
- | Adds a constraint future code must follow | Chore rename without semantics |
28
- | Picks a costly-to-swap vendor or protocol | Narrow feature inside a prior ADR |
29
- | Codifies a convention across the repo | Noise would drown readers |
30
-
31
- If you’re listing code edits, that belongs in `design.md`—not an ADR.
32
-
33
- ---
34
-
35
- ## 3. Format (`{{ADR_DIR}}/NNNN-short-topic.md`)
36
-
37
- ```markdown
38
- # NNNN. <Short, decision-shaped title>
39
-
40
- - **Status**: Proposed | Accepted | Superseded by ADR-NNNN (…)
41
- - **Date**: YYYY-MM-DD
42
- - **Area**: <product or layer>
43
- - **Related**: openspec/changes/archive/<change>/, …
44
-
45
- ## Context
46
-
47
- One paragraph: pressure or constraint forcing a decision.
48
-
49
- ## Decision
50
-
51
- One imperative paragraph stating what this project commits to.
52
-
53
- ## Alternatives considered
54
-
55
- - **Option A** — rejected because …
56
- - **Chosen** — …
57
-
58
- ## Consequences
59
-
60
- ### Positive
61
- ### Negative
62
- ### Neutral
63
-
64
- ## References
65
-
66
- - Archive: openspec/changes/archive/<name>/
67
- ```
68
-
69
- Keep ADRs terse (roughly tens to low hundreds of lines each).
70
-
71
- ---
72
-
73
- ## 4. Numbering
74
-
75
- - Sequential `NNNN`; never recycle numbers—supersede with a **new** ADR.
76
- - Prefer decision-shaped filenames: `0004-outbox-only-on-critical-path.md` not `0004-add-worker.md`.
77
-
78
- All ADRs sit under **`{{ADR_DIR}}/`** even when scoped to one area—the decision
79
- usually crosses layers.
80
-
81
- ---
82
-
83
- ## 5. Status index (`{{ADR_DIR}}/README.md`)
84
-
85
- Maintain the table of `#`, Title, Status, Date. Leave placeholder rows until real ADRs land.
86
-
87
- ---
88
-
89
- ## 6. Cross-link OpenSpec ↔ ADRs
90
-
91
- ADR **References** should point at the dated archive folder.
92
-
93
- Archived `proposal.md` should gain:
94
-
95
- ```markdown
96
- ## Decision record
97
-
98
- This change is recorded as ADR-NNNN ({{ADR_DIR}}/NNNN-short-topic.md).
99
- ```
100
-
101
- Or, for non-architectural archives, the one-line stamp:
102
-
103
- ```text
104
- No ADR — non-architectural change
105
- ```
106
-
107
- Capability specs may cite ADRs as normative “why.”
108
-
109
- ---
110
-
111
- ## 7. ADRs in agent retrieval
112
-
113
- Short, focused ADRs embed well. **Do not** add `{{ADR_DIR}}/` to
114
- `.cursorindexignore` (or equivalent).
115
-
116
- ---
117
-
118
- ## 7a. Hooks: archive → ADR
119
-
120
- When ADR wiring is enabled, archive hooks remind agents to run **archive-to-adr**
121
- after `openspec archive` or a move into `openspec/changes/archive/YYYY-MM-DD-…`.
122
-
123
- Session-start backstops list archives whose `proposal.md` lacks `ADR-[0-9]` **and**
124
- lacks the `No ADR — non-architectural change` stamp.
125
-
126
- ---
127
-
128
- ## 8. Maintenance habit
129
-
130
- - On each meaningful archive: decide ADR vs stamp.
131
- - Periodically skim the index for stale status.
132
- - Supersede with new ADRs—don’t delete old ones.
133
-
134
- ---
135
-
136
- ## 9. TL;DR
137
-
138
- - ADRs **distill** decisions; OpenSpec archives keep the **full** story.
139
- - Use this file + `{{ADR_DIR}}/README.md` + `{{ADR_DIR}}/NNNN-*.md`.
140
- - Cross-link archives and ADRs both directions.
141
- - After archive: run **archive-to-adr** (or stamp “No ADR”).
1
+ # Architecture decision records (ADRs)
2
+
3
+ > How this project captures **architectural** decisions. ADRs live next to OpenSpec
4
+ > archives. Scaffolded by Forgekit (`forge init --adr` / `forgekit install` with ADRs on).
5
+
6
+ ADR directory for this project: **`{{ADR_DIR}}`** (configured in `.forge/config.json`).
7
+
8
+ ---
9
+
10
+ ## 1. Why ADRs *and* OpenSpec archives?
11
+
12
+ They overlap in “why we did something,” but they serve different lookups:
13
+
14
+ | OpenSpec archive (verbose) | ADR (short) |
15
+ | -------------------------- | ----------- |
16
+ | `proposal.md`, `design.md`, `tasks.md`, specs | One file, one sharpened decision |
17
+ | “Replay the implementation story” | “Why is X shaped this way?” |
18
+
19
+ ---
20
+
21
+ ## 2. When to write an ADR
22
+
23
+ | Write an ADR when the change … | Skip the ADR when … |
24
+ | ------------------------------ | ------------------- |
25
+ | Establishes or moves a boundary | Bug fix / copy / docs-only |
26
+ | Chooses among real alternatives | Refactor that changes no decision |
27
+ | Adds a constraint future code must follow | Chore rename without semantics |
28
+ | Picks a costly-to-swap vendor or protocol | Narrow feature inside a prior ADR |
29
+ | Codifies a convention across the repo | Noise would drown readers |
30
+
31
+ If you’re listing code edits, that belongs in `design.md`—not an ADR.
32
+
33
+ ---
34
+
35
+ ## 3. Format (`{{ADR_DIR}}/NNNN-short-topic.md`)
36
+
37
+ ```markdown
38
+ # NNNN. <Short, decision-shaped title>
39
+
40
+ - **Status**: Proposed | Accepted | Superseded by ADR-NNNN (…)
41
+ - **Date**: YYYY-MM-DD
42
+ - **Area**: <product or layer>
43
+ - **Related**: openspec/changes/archive/<change>/, …
44
+
45
+ ## Context
46
+
47
+ One paragraph: pressure or constraint forcing a decision.
48
+
49
+ ## Decision
50
+
51
+ One imperative paragraph stating what this project commits to.
52
+
53
+ ## Alternatives considered
54
+
55
+ - **Option A** — rejected because …
56
+ - **Chosen** — …
57
+
58
+ ## Consequences
59
+
60
+ ### Positive
61
+ ### Negative
62
+ ### Neutral
63
+
64
+ ## References
65
+
66
+ - Archive: openspec/changes/archive/<name>/
67
+ ```
68
+
69
+ Keep ADRs terse (roughly tens to low hundreds of lines each).
70
+
71
+ ---
72
+
73
+ ## 4. Numbering
74
+
75
+ - Sequential `NNNN`; never recycle numbers—supersede with a **new** ADR.
76
+ - Prefer decision-shaped filenames: `0004-outbox-only-on-critical-path.md` not `0004-add-worker.md`.
77
+
78
+ All ADRs sit under **`{{ADR_DIR}}/`** even when scoped to one area—the decision
79
+ usually crosses layers.
80
+
81
+ ---
82
+
83
+ ## 5. Status index (`{{ADR_DIR}}/README.md`)
84
+
85
+ Maintain the table of `#`, Title, Status, Date. Leave placeholder rows until real ADRs land.
86
+
87
+ ---
88
+
89
+ ## 6. Cross-link OpenSpec ↔ ADRs
90
+
91
+ ADR **References** should point at the dated archive folder.
92
+
93
+ Archived `proposal.md` should gain:
94
+
95
+ ```markdown
96
+ ## Decision record
97
+
98
+ This change is recorded as ADR-NNNN ({{ADR_DIR}}/NNNN-short-topic.md).
99
+ ```
100
+
101
+ Or, for non-architectural archives, the one-line stamp:
102
+
103
+ ```text
104
+ No ADR — non-architectural change
105
+ ```
106
+
107
+ Capability specs may cite ADRs as normative “why.”
108
+
109
+ ---
110
+
111
+ ## 7. ADRs in agent retrieval
112
+
113
+ Short, focused ADRs embed well. **Do not** add `{{ADR_DIR}}/` to
114
+ `.cursorindexignore` (or equivalent).
115
+
116
+ ---
117
+
118
+ ## 7a. Hooks: archive → ADR
119
+
120
+ When ADR wiring is enabled, archive hooks remind agents to run **archive-to-adr**
121
+ after `openspec archive` or a move into `openspec/changes/archive/YYYY-MM-DD-…`.
122
+
123
+ Session-start backstops list archives whose `proposal.md` lacks `ADR-[0-9]` **and**
124
+ lacks the `No ADR — non-architectural change` stamp.
125
+
126
+ ---
127
+
128
+ ## 8. Maintenance habit
129
+
130
+ - On each meaningful archive: decide ADR vs stamp.
131
+ - Periodically skim the index for stale status.
132
+ - Supersede with new ADRs—don’t delete old ones.
133
+
134
+ ---
135
+
136
+ ## 9. TL;DR
137
+
138
+ - ADRs **distill** decisions; OpenSpec archives keep the **full** story.
139
+ - Use this file + `{{ADR_DIR}}/README.md` + `{{ADR_DIR}}/NNNN-*.md`.
140
+ - Cross-link archives and ADRs both directions.
141
+ - After archive: run **archive-to-adr** (or stamp “No ADR”).
@@ -1,74 +1,74 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Pending-ADR backstop: list archived proposals missing ADR link and No-ADR stamp.
4
- * Honors .forge/config.json adr.enabled === false.
5
- *
6
- * Usage: node check-pending-adrs.mjs [repoRoot]
7
- */
8
-
9
- import fs from 'node:fs';
10
- import path from 'node:path';
11
- import { spawnSync } from 'node:child_process';
12
-
13
- function gitRoot() {
14
- const r = spawnSync('git', ['rev-parse', '--show-toplevel'], {
15
- encoding: 'utf8',
16
- shell: process.platform === 'win32',
17
- });
18
- if (r.status !== 0) return null;
19
- return String(r.stdout || '').trim() || null;
20
- }
21
-
22
- function loadConfig(cwd) {
23
- const p = path.join(cwd, '.forge', 'config.json');
24
- if (!fs.existsSync(p)) return {};
25
- try {
26
- return JSON.parse(fs.readFileSync(p, 'utf8'));
27
- } catch {
28
- return {};
29
- }
30
- }
31
-
32
- function listProposals(cwd, archiveRoot) {
33
- const dir = path.join(cwd, ...archiveRoot.split('/'));
34
- if (!fs.existsSync(dir)) return [];
35
- /** @type {string[]} */
36
- const out = [];
37
- for (const name of fs.readdirSync(dir)) {
38
- const proposal = path.join(dir, name, 'proposal.md');
39
- if (fs.existsSync(proposal)) out.push(proposal);
40
- }
41
- return out;
42
- }
43
-
44
- const cwd = process.argv[2] || gitRoot();
45
- if (!cwd) process.exit(0);
46
-
47
- const cfg = loadConfig(cwd);
48
- if (cfg.adr && cfg.adr.enabled === false) process.exit(0);
49
-
50
- const archives = [
51
- 'openspec/changes/archive',
52
- `${(cfg.plan && typeof cfg.plan === 'object' && cfg.plan.dir) || 'specs'}/changes/archive`,
53
- ];
54
- /** @type {string[]} */
55
- const pending = [];
56
- for (const root of archives) {
57
- for (const proposal of listProposals(cwd, root)) {
58
- const body = fs.readFileSync(proposal, 'utf8');
59
- if (/ADR-[0-9]/.test(body)) continue;
60
- if (body.includes('No ADR — non-architectural change')) continue;
61
- pending.push(path.relative(cwd, proposal).replace(/\\/g, '/'));
62
- }
63
- }
64
-
65
- if (pending.length === 0) process.exit(0);
66
-
67
- const shown = pending.slice(0, 10).join('\n');
68
- process.stdout.write(
69
- `Archived changes whose proposal.md does not reference an ADR yet:\n\n${shown}\n\n` +
70
- `If any had architectural impact, run the archive-to-adr skill.\n` +
71
- `Otherwise add a one-line stamp to each proposal.md:\n` +
72
- ` 'No ADR — non-architectural change'\n`,
73
- );
74
- process.exit(0);
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Pending-ADR backstop: list archived proposals missing ADR link and No-ADR stamp.
4
+ * Honors .forge/config.json adr.enabled === false.
5
+ *
6
+ * Usage: node check-pending-adrs.mjs [repoRoot]
7
+ */
8
+
9
+ import fs from 'node:fs';
10
+ import path from 'node:path';
11
+ import { spawnSync } from 'node:child_process';
12
+
13
+ function gitRoot() {
14
+ const r = spawnSync('git', ['rev-parse', '--show-toplevel'], {
15
+ encoding: 'utf8',
16
+ shell: process.platform === 'win32',
17
+ });
18
+ if (r.status !== 0) return null;
19
+ return String(r.stdout || '').trim() || null;
20
+ }
21
+
22
+ function loadConfig(cwd) {
23
+ const p = path.join(cwd, '.forge', 'config.json');
24
+ if (!fs.existsSync(p)) return {};
25
+ try {
26
+ return JSON.parse(fs.readFileSync(p, 'utf8'));
27
+ } catch {
28
+ return {};
29
+ }
30
+ }
31
+
32
+ function listProposals(cwd, archiveRoot) {
33
+ const dir = path.join(cwd, ...archiveRoot.split('/'));
34
+ if (!fs.existsSync(dir)) return [];
35
+ /** @type {string[]} */
36
+ const out = [];
37
+ for (const name of fs.readdirSync(dir)) {
38
+ const proposal = path.join(dir, name, 'proposal.md');
39
+ if (fs.existsSync(proposal)) out.push(proposal);
40
+ }
41
+ return out;
42
+ }
43
+
44
+ const cwd = process.argv[2] || gitRoot();
45
+ if (!cwd) process.exit(0);
46
+
47
+ const cfg = loadConfig(cwd);
48
+ if (cfg.adr && cfg.adr.enabled === false) process.exit(0);
49
+
50
+ const archives = [
51
+ 'openspec/changes/archive',
52
+ `${(cfg.plan && typeof cfg.plan === 'object' && cfg.plan.dir) || 'specs'}/changes/archive`,
53
+ ];
54
+ /** @type {string[]} */
55
+ const pending = [];
56
+ for (const root of archives) {
57
+ for (const proposal of listProposals(cwd, root)) {
58
+ const body = fs.readFileSync(proposal, 'utf8');
59
+ if (/ADR-[0-9]/.test(body)) continue;
60
+ if (body.includes('No ADR — non-architectural change')) continue;
61
+ pending.push(path.relative(cwd, proposal).replace(/\\/g, '/'));
62
+ }
63
+ }
64
+
65
+ if (pending.length === 0) process.exit(0);
66
+
67
+ const shown = pending.slice(0, 10).join('\n');
68
+ process.stdout.write(
69
+ `Archived changes whose proposal.md does not reference an ADR yet:\n\n${shown}\n\n` +
70
+ `If any had architectural impact, run the archive-to-adr skill.\n` +
71
+ `Otherwise add a one-line stamp to each proposal.md:\n` +
72
+ ` 'No ADR — non-architectural change'\n`,
73
+ );
74
+ process.exit(0);
@@ -1,3 +1,3 @@
1
- #!/usr/bin/env bash
2
- # Thin wrapper around the Node implementation.
3
- exec node "$(dirname "$0")/check-pending-adrs.mjs" "$@"
1
+ #!/usr/bin/env bash
2
+ # Thin wrapper around the Node implementation.
3
+ exec node "$(dirname "$0")/check-pending-adrs.mjs" "$@"
@@ -1,52 +1,52 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Agent reminder after a successful change archive (stdout only).
4
- * Usage: node openspec-archive-agent-message.mjs <change-slug>
5
- */
6
-
7
- import fs from 'node:fs';
8
- import path from 'node:path';
9
-
10
- const changeName = process.argv[2];
11
- if (!changeName) {
12
- process.stderr.write('Usage: openspec-archive-agent-message.mjs <change-slug>\n');
13
- process.exit(1);
14
- }
15
-
16
- let adrDir = 'docs/adr';
17
- let decisionsDoc = 'docs/decisions.md';
18
- let archiveRoot = 'openspec/changes/archive';
19
- let adrEnabled = true;
20
-
21
- const cfgPath = path.join(process.cwd(), '.forge', 'config.json');
22
- if (fs.existsSync(cfgPath)) {
23
- try {
24
- const c = JSON.parse(fs.readFileSync(cfgPath, 'utf8'));
25
- if (c.plan?.engine === 'specs') {
26
- archiveRoot = `${c.plan.dir || 'specs'}/changes/archive`;
27
- }
28
- if (c.adr?.enabled === false) adrEnabled = false;
29
- if (c.adr?.dir) adrDir = c.adr.dir;
30
- if (c.adr?.decisionsDoc) decisionsDoc = c.adr.decisionsDoc;
31
- } catch {
32
- // keep defaults
33
- }
34
- }
35
-
36
- if (!adrEnabled) {
37
- process.stdout.write(
38
- `Change '${changeName}' was archived. ADRs are disabled for this project\n` +
39
- `(\`.forge/config.json\` → adr.enabled: false). No archive-to-adr follow-up.\n\n` +
40
- `Suggested commit (display only — do NOT commit unless the user asks):\n\n` +
41
- `openspec: archive ${changeName}\n`,
42
- );
43
- process.exit(0);
44
- }
45
-
46
- process.stdout.write(
47
- `Change '${changeName}' was just archived.\n\n` +
48
- `1. archive-to-adr: locate ${archiveRoot}/YYYY-MM-DD-${changeName}/, open proposal.md, and evaluate an ADR (${decisionsDoc}). If yes: ${adrDir}/NNNN-<topic>.md, update ${adrDir}/README.md, add a ## Decision record to proposal.md. If no: add one line to proposal.md: No ADR — non-architectural change.\n\n` +
49
- `2. Suggested commit (display only — do NOT run git commit / push / gh pr create unless the user explicitly asks):\n\n` +
50
- `openspec: archive ${changeName}\n`,
51
- );
52
- process.exit(0);
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Agent reminder after a successful change archive (stdout only).
4
+ * Usage: node openspec-archive-agent-message.mjs <change-slug>
5
+ */
6
+
7
+ import fs from 'node:fs';
8
+ import path from 'node:path';
9
+
10
+ const changeName = process.argv[2];
11
+ if (!changeName) {
12
+ process.stderr.write('Usage: openspec-archive-agent-message.mjs <change-slug>\n');
13
+ process.exit(1);
14
+ }
15
+
16
+ let adrDir = 'docs/adr';
17
+ let decisionsDoc = 'docs/decisions.md';
18
+ let archiveRoot = 'openspec/changes/archive';
19
+ let adrEnabled = true;
20
+
21
+ const cfgPath = path.join(process.cwd(), '.forge', 'config.json');
22
+ if (fs.existsSync(cfgPath)) {
23
+ try {
24
+ const c = JSON.parse(fs.readFileSync(cfgPath, 'utf8'));
25
+ if (c.plan?.engine === 'specs') {
26
+ archiveRoot = `${c.plan.dir || 'specs'}/changes/archive`;
27
+ }
28
+ if (c.adr?.enabled === false) adrEnabled = false;
29
+ if (c.adr?.dir) adrDir = c.adr.dir;
30
+ if (c.adr?.decisionsDoc) decisionsDoc = c.adr.decisionsDoc;
31
+ } catch {
32
+ // keep defaults
33
+ }
34
+ }
35
+
36
+ if (!adrEnabled) {
37
+ process.stdout.write(
38
+ `Change '${changeName}' was archived. ADRs are disabled for this project\n` +
39
+ `(\`.forge/config.json\` → adr.enabled: false). No archive-to-adr follow-up.\n\n` +
40
+ `Suggested commit (display only — do NOT commit unless the user asks):\n\n` +
41
+ `openspec: archive ${changeName}\n`,
42
+ );
43
+ process.exit(0);
44
+ }
45
+
46
+ process.stdout.write(
47
+ `Change '${changeName}' was just archived.\n\n` +
48
+ `1. archive-to-adr: locate ${archiveRoot}/YYYY-MM-DD-${changeName}/, open proposal.md, and evaluate an ADR (${decisionsDoc}). If yes: ${adrDir}/NNNN-<topic>.md, update ${adrDir}/README.md, add a ## Decision record to proposal.md. If no: add one line to proposal.md: No ADR — non-architectural change.\n\n` +
49
+ `2. Suggested commit (display only — do NOT run git commit / push / gh pr create unless the user explicitly asks):\n\n` +
50
+ `openspec: archive ${changeName}\n`,
51
+ );
52
+ process.exit(0);
@@ -1,3 +1,3 @@
1
- #!/usr/bin/env bash
2
- # Thin wrapper around the Node implementation.
3
- exec node "$(dirname "$0")/openspec-archive-agent-message.mjs" "$@"
1
+ #!/usr/bin/env bash
2
+ # Thin wrapper around the Node implementation.
3
+ exec node "$(dirname "$0")/openspec-archive-agent-message.mjs" "$@"