@entelligentsia/forgecli 0.10.1 → 0.11.2
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.
- package/CHANGELOG.md +78 -0
- package/README.md +21 -3
- package/dist/CHANGELOG-forge-plugin.md +22 -0
- package/dist/extensions/forgecli/add-pipeline.d.ts +19 -0
- package/dist/extensions/forgecli/add-pipeline.js +143 -0
- package/dist/extensions/forgecli/add-pipeline.js.map +1 -0
- package/dist/extensions/forgecli/add-task.d.ts +20 -0
- package/dist/extensions/forgecli/add-task.js +154 -0
- package/dist/extensions/forgecli/add-task.js.map +1 -0
- package/dist/extensions/forgecli/calibrate.d.ts +61 -0
- package/dist/extensions/forgecli/calibrate.js +488 -0
- package/dist/extensions/forgecli/calibrate.js.map +1 -0
- package/dist/extensions/forgecli/fix-bug.d.ts +9 -1
- package/dist/extensions/forgecli/fix-bug.js +70 -8
- package/dist/extensions/forgecli/fix-bug.js.map +1 -1
- package/dist/extensions/forgecli/forge-commands.js +15 -22
- package/dist/extensions/forgecli/forge-commands.js.map +1 -1
- package/dist/extensions/forgecli/forge-subagent.js +34 -7
- package/dist/extensions/forgecli/forge-subagent.js.map +1 -1
- package/dist/extensions/forgecli/forge-update-command.d.ts +9 -0
- package/dist/extensions/forgecli/forge-update-command.js +106 -7
- package/dist/extensions/forgecli/forge-update-command.js.map +1 -1
- package/dist/extensions/forgecli/health-check.d.ts +22 -1
- package/dist/extensions/forgecli/health-check.js +177 -4
- package/dist/extensions/forgecli/health-check.js.map +1 -1
- package/dist/extensions/forgecli/hook-dispatcher.d.ts +25 -1
- package/dist/extensions/forgecli/hook-dispatcher.js +104 -9
- package/dist/extensions/forgecli/hook-dispatcher.js.map +1 -1
- package/dist/extensions/forgecli/hooks/check-update.d.ts +81 -0
- package/dist/extensions/forgecli/hooks/check-update.js +308 -0
- package/dist/extensions/forgecli/hooks/check-update.js.map +1 -0
- package/dist/extensions/forgecli/hooks/forge-permissions.d.ts +32 -0
- package/dist/extensions/forgecli/hooks/forge-permissions.js +119 -0
- package/dist/extensions/forgecli/hooks/forge-permissions.js.map +1 -0
- package/dist/extensions/forgecli/hooks/triage-error.d.ts +23 -0
- package/dist/extensions/forgecli/hooks/triage-error.js +62 -0
- package/dist/extensions/forgecli/hooks/triage-error.js.map +1 -0
- package/dist/extensions/forgecli/hooks/write-guard.d.ts +28 -0
- package/dist/extensions/forgecli/hooks/write-guard.js +225 -0
- package/dist/extensions/forgecli/hooks/write-guard.js.map +1 -0
- package/dist/extensions/forgecli/index.js +60 -0
- package/dist/extensions/forgecli/index.js.map +1 -1
- package/dist/extensions/forgecli/init-context.d.ts +1 -1
- package/dist/extensions/forgecli/init-context.js +21 -6
- package/dist/extensions/forgecli/init-context.js.map +1 -1
- package/dist/extensions/forgecli/materialize.d.ts +16 -0
- package/dist/extensions/forgecli/materialize.js +195 -0
- package/dist/extensions/forgecli/materialize.js.map +1 -0
- package/dist/extensions/forgecli/migrate.d.ts +19 -0
- package/dist/extensions/forgecli/migrate.js +258 -0
- package/dist/extensions/forgecli/migrate.js.map +1 -0
- package/dist/extensions/forgecli/migration-engine.d.ts +111 -0
- package/dist/extensions/forgecli/migration-engine.js +533 -0
- package/dist/extensions/forgecli/migration-engine.js.map +1 -0
- package/dist/extensions/forgecli/quiz-agent.d.ts +17 -0
- package/dist/extensions/forgecli/quiz-agent.js +98 -0
- package/dist/extensions/forgecli/quiz-agent.js.map +1 -0
- package/dist/extensions/forgecli/remove-command.d.ts +17 -0
- package/dist/extensions/forgecli/remove-command.js +124 -0
- package/dist/extensions/forgecli/remove-command.js.map +1 -0
- package/dist/extensions/forgecli/report-bug.d.ts +25 -0
- package/dist/extensions/forgecli/report-bug.js +159 -0
- package/dist/extensions/forgecli/report-bug.js.map +1 -0
- package/dist/extensions/forgecli/retrospective.d.ts +19 -0
- package/dist/extensions/forgecli/retrospective.js +156 -0
- package/dist/extensions/forgecli/retrospective.js.map +1 -0
- package/dist/extensions/forgecli/run-sprint.js +34 -0
- package/dist/extensions/forgecli/run-sprint.js.map +1 -1
- package/dist/extensions/forgecli/run-task.d.ts +9 -1
- package/dist/extensions/forgecli/run-task.js +64 -10
- package/dist/extensions/forgecli/run-task.js.map +1 -1
- package/dist/extensions/forgecli/session-registry.d.ts +27 -2
- package/dist/extensions/forgecli/session-registry.js +52 -1
- package/dist/extensions/forgecli/session-registry.js.map +1 -1
- package/dist/extensions/forgecli/status-command.d.ts +19 -0
- package/dist/extensions/forgecli/status-command.js +140 -0
- package/dist/extensions/forgecli/status-command.js.map +1 -0
- package/dist/extensions/forgecli/store-query.d.ts +22 -0
- package/dist/extensions/forgecli/store-query.js +107 -0
- package/dist/extensions/forgecli/store-query.js.map +1 -0
- package/dist/extensions/forgecli/store-repair.d.ts +17 -0
- package/dist/extensions/forgecli/store-repair.js +123 -0
- package/dist/extensions/forgecli/store-repair.js.map +1 -0
- package/dist/extensions/forgecli/thread-switcher.js +213 -28
- package/dist/extensions/forgecli/thread-switcher.js.map +1 -1
- package/dist/extensions/forgecli/update-tools.d.ts +23 -0
- package/dist/extensions/forgecli/update-tools.js +136 -0
- package/dist/extensions/forgecli/update-tools.js.map +1 -0
- package/dist/extensions/forgecli/viewport-theme.js +4 -0
- package/dist/extensions/forgecli/viewport-theme.js.map +1 -1
- package/dist/forge-payload/.claude-plugin/plugin.json +1 -1
- package/dist/forge-payload/.schemas/config.schema.json +83 -0
- package/dist/forge-payload/.schemas/migrations.json +2049 -0
- package/dist/forge-payload/commands/regenerate.md +17 -1
- package/dist/forge-payload/meta/personas/README.md +16 -0
- package/dist/forge-payload/meta/personas/meta-architect.md +70 -0
- package/dist/forge-payload/meta/personas/meta-bug-fixer.md +73 -0
- package/dist/forge-payload/meta/personas/meta-collator.md +72 -0
- package/dist/forge-payload/meta/personas/meta-engineer.md +70 -0
- package/dist/forge-payload/meta/personas/meta-orchestrator.md +71 -0
- package/dist/forge-payload/meta/personas/meta-product-manager.md +82 -0
- package/dist/forge-payload/meta/personas/meta-qa-engineer.md +91 -0
- package/dist/forge-payload/meta/personas/meta-supervisor.md +92 -0
- package/dist/forge-payload/meta/skill-recommendations.md +154 -0
- package/dist/forge-payload/meta/skills/meta-architect-skills.md +43 -0
- package/dist/forge-payload/meta/skills/meta-bug-fixer-skills.md +43 -0
- package/dist/forge-payload/meta/skills/meta-collator-skills.md +41 -0
- package/dist/forge-payload/meta/skills/meta-engineer-skills.md +43 -0
- package/dist/forge-payload/meta/skills/meta-generic-skills.md +58 -0
- package/dist/forge-payload/meta/skills/meta-qa-engineer-skills.md +46 -0
- package/dist/forge-payload/meta/skills/meta-supervisor-skills.md +43 -0
- package/dist/forge-payload/meta/store-schema/bug.schema.md +71 -0
- package/dist/forge-payload/meta/store-schema/event.schema.md +76 -0
- package/dist/forge-payload/meta/store-schema/feature.schema.md +65 -0
- package/dist/forge-payload/meta/store-schema/sprint.schema.md +64 -0
- package/dist/forge-payload/meta/store-schema/task.schema.md +78 -0
- package/dist/forge-payload/meta/templates/meta-code-review.md +26 -0
- package/dist/forge-payload/meta/templates/meta-plan-review.md +28 -0
- package/dist/forge-payload/meta/templates/meta-plan.md +28 -0
- package/dist/forge-payload/meta/templates/meta-progress.md +25 -0
- package/dist/forge-payload/meta/templates/meta-retrospective.md +28 -0
- package/dist/forge-payload/meta/templates/meta-sprint-manifest.md +26 -0
- package/dist/forge-payload/meta/templates/meta-sprint-requirements.md +91 -0
- package/dist/forge-payload/meta/templates/meta-task-prompt.md +26 -0
- package/dist/forge-payload/meta/tool-specs/collate.spec.md +88 -0
- package/dist/forge-payload/meta/tool-specs/generation-manifest.spec.md +139 -0
- package/dist/forge-payload/meta/tool-specs/manage-config.spec.md +143 -0
- package/dist/forge-payload/meta/tool-specs/seed-store.spec.md +91 -0
- package/dist/forge-payload/meta/tool-specs/store-cli.spec.md +328 -0
- package/dist/forge-payload/meta/tool-specs/validate-store.spec.md +191 -0
- package/dist/forge-payload/meta/workflows/_fragments/context-injection.md +75 -0
- package/dist/forge-payload/meta/workflows/_fragments/event-emission-schema.md +73 -0
- package/dist/forge-payload/meta/workflows/_fragments/finalize.md +13 -0
- package/dist/forge-payload/meta/workflows/_fragments/friction-emit.md +73 -0
- package/dist/forge-payload/meta/workflows/_fragments/progress-reporting.md +38 -0
- package/dist/forge-payload/meta/workflows/_fragments/store-cli-verbs.md +39 -0
- package/dist/forge-payload/meta/workflows/meta-approve.md +119 -0
- package/dist/forge-payload/meta/workflows/meta-collate.md +89 -0
- package/dist/forge-payload/meta/workflows/meta-commit.md +93 -0
- package/dist/forge-payload/meta/workflows/meta-enhance.md +286 -0
- package/dist/forge-payload/meta/workflows/meta-fix-bug.md +501 -0
- package/dist/forge-payload/meta/workflows/meta-implement.md +132 -0
- package/dist/forge-payload/meta/workflows/meta-migrate.md +455 -0
- package/dist/forge-payload/meta/workflows/meta-orchestrate.md +993 -0
- package/dist/forge-payload/meta/workflows/meta-plan-task.md +133 -0
- package/dist/forge-payload/meta/workflows/meta-quiz-agent.md +135 -0
- package/dist/forge-payload/meta/workflows/meta-retrospective.md +65 -0
- package/dist/forge-payload/meta/workflows/meta-review-implementation.md +119 -0
- package/dist/forge-payload/meta/workflows/meta-review-plan.md +108 -0
- package/dist/forge-payload/meta/workflows/meta-review-sprint-completion.md +65 -0
- package/dist/forge-payload/meta/workflows/meta-sprint-intake.md +76 -0
- package/dist/forge-payload/meta/workflows/meta-sprint-plan.md +147 -0
- package/dist/forge-payload/meta/workflows/meta-update-implementation.md +76 -0
- package/dist/forge-payload/meta/workflows/meta-update-plan.md +76 -0
- package/dist/forge-payload/meta/workflows/meta-validate.md +111 -0
- package/dist/forge-payload/tools/check-structure.cjs +344 -0
- package/dist/forge-payload/tools/list-skills.js +76 -0
- package/dist/forge-payload/tools/store-cli.cjs +27 -1
- package/dist/forge-payload/tools/substitute-placeholders.cjs +60 -8
- package/dist/forge-payload/tools/verify-integrity.cjs +86 -0
- package/package.json +2 -2
|
@@ -0,0 +1,455 @@
|
|
|
1
|
+
---
|
|
2
|
+
requirements:
|
|
3
|
+
reasoning: High
|
|
4
|
+
context: High
|
|
5
|
+
speed: Low
|
|
6
|
+
audience: orchestrator-only
|
|
7
|
+
deps:
|
|
8
|
+
personas: [engineer]
|
|
9
|
+
skills: [engineer, generic]
|
|
10
|
+
templates: []
|
|
11
|
+
sub_workflows: []
|
|
12
|
+
kb_docs: []
|
|
13
|
+
config_fields: [paths.engineering]
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# Meta-Workflow: Structural Migration (v0.x → v0.40)
|
|
17
|
+
|
|
18
|
+
## Purpose
|
|
19
|
+
|
|
20
|
+
Translate a prose-heavy v0.x `.forge/` instance into the v0.40 format:
|
|
21
|
+
`project-context.json` (T02 schema) + clean base-pack substitution (T03) +
|
|
22
|
+
`structure-versions.json` snapshot tracking (T05). Every operation is
|
|
23
|
+
reversible, guarded by user confirmation, and idempotent on re-run.
|
|
24
|
+
|
|
25
|
+
**Trigger:** Invoked by `/forge:migrate` when the user passes `--structural`
|
|
26
|
+
or when `.forge/structure-versions.json` is absent (pre-T05 install detected).
|
|
27
|
+
|
|
28
|
+
**Scope:** v0.x → v0.40 only. Installs older than v0.x should use
|
|
29
|
+
`/forge:health` → `/forge:update` to reach a supported baseline first.
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Pre-conditions
|
|
34
|
+
|
|
35
|
+
- `/forge:init` has run: `.forge/config.json` exists and is readable.
|
|
36
|
+
- `.forge/structure-versions.json` is absent OR `--structural` was passed.
|
|
37
|
+
- The Forge plugin root is resolvable:
|
|
38
|
+
```sh
|
|
39
|
+
export FORGE_ROOT=$(node -e "console.log(require('./.forge/config.json').paths.forgeRoot)")
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Algorithm
|
|
45
|
+
|
|
46
|
+
### Phase 0 — Pre-flight
|
|
47
|
+
|
|
48
|
+
**0a. Verify init has completed.**
|
|
49
|
+
|
|
50
|
+
Check that `.forge/config.json` exists. If it does not, stop:
|
|
51
|
+
|
|
52
|
+
> "Forge has not been initialised in this project. Run `/forge:init` first."
|
|
53
|
+
|
|
54
|
+
Read `FORGE_ROOT` from `.forge/config.json`.
|
|
55
|
+
|
|
56
|
+
**0b. Detect install generation.**
|
|
57
|
+
|
|
58
|
+
```sh
|
|
59
|
+
ls .forge/structure-versions.json 2>/dev/null && echo "EXISTS" || echo "ABSENT"
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
- If `structure-versions.json` EXISTS: this is a post-T05 install. Warn the
|
|
63
|
+
user that structural migration is not needed and offer to run the standard
|
|
64
|
+
store-schema migration (Steps 1–7 of `/forge:migrate`) instead. Stop.
|
|
65
|
+
- If ABSENT: proceed (pre-T05 install confirmed).
|
|
66
|
+
|
|
67
|
+
**0c. Check for in-progress sentinel (idempotency).**
|
|
68
|
+
|
|
69
|
+
```sh
|
|
70
|
+
ls .forge/archive/pre-migration/.migration-in-progress 2>/dev/null && echo "FOUND" || echo "NOT_FOUND"
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
If FOUND:
|
|
74
|
+
|
|
75
|
+
- Check if a draft `project-context.json` already exists AND is valid JSON:
|
|
76
|
+
```sh
|
|
77
|
+
node -e "JSON.parse(require('fs').readFileSync('.forge/project-context.json','utf8')); console.log('VALID');" 2>/dev/null || echo "INVALID_OR_ABSENT"
|
|
78
|
+
```
|
|
79
|
+
- Resume heuristic: sentinel exists AND `.forge/project-context.json` exists AND
|
|
80
|
+
validates against the schema → offer resume (ask user: "A previous migration
|
|
81
|
+
was interrupted. A draft project-context.json already exists. Resume from
|
|
82
|
+
Phase 2 (confirm and write)? [Y/n/restart]"). If user chooses restart, remove
|
|
83
|
+
the sentinel file and continue as a fresh run.
|
|
84
|
+
- Otherwise (no valid draft): offer fresh restart.
|
|
85
|
+
|
|
86
|
+
**0d. Create sentinel directory FIRST, then write sentinel file.**
|
|
87
|
+
|
|
88
|
+
ORDER IS MANDATORY — writing the file before the directory fails:
|
|
89
|
+
|
|
90
|
+
```sh
|
|
91
|
+
mkdir -p .forge/archive/pre-migration/
|
|
92
|
+
echo "in-progress" > .forge/archive/pre-migration/.migration-in-progress
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Record the migration start timestamp:
|
|
96
|
+
```sh
|
|
97
|
+
MIGRATION_START=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
### Phase 1 — Read and Extract
|
|
103
|
+
|
|
104
|
+
Read all existing `.forge/` artifacts in five categories and extract
|
|
105
|
+
project-specific content. Generic boilerplate lines (role definitions,
|
|
106
|
+
algorithm steps, universal Iron Laws) are skipped.
|
|
107
|
+
|
|
108
|
+
**Security note:** All extracted strings are copied verbatim into
|
|
109
|
+
`project-context.json` field values. They are never executed or evaluated.
|
|
110
|
+
Downstream T03 substitution (`substitute-placeholders.cjs`) treats all values
|
|
111
|
+
as opaque text strings and only replaces the canonical `REQUIRED_KEYS` +
|
|
112
|
+
`RUNTIME_PASSTHROUGH_KEYS` placeholder set. No arbitrary code paths are opened
|
|
113
|
+
by the extracted content.
|
|
114
|
+
|
|
115
|
+
#### Extraction categories
|
|
116
|
+
|
|
117
|
+
| Category | Files | Extraction targets |
|
|
118
|
+
|---|---|---|
|
|
119
|
+
| Config | `.forge/config.json` | All fields — direct mapping (highest confidence) |
|
|
120
|
+
| Personas | `.forge/personas/*.md` | Project name, prefix, KB path, impact categories, entity refs, skill directives |
|
|
121
|
+
| Skills | `.forge/skills/*.md` (esp. engineer, architect) | Stack summary, key directories, commands, technical debt, verification commands |
|
|
122
|
+
| Workflows | `.forge/workflows/*.md` | Project prefix occurrences, task ID format, branching convention, deployment environments |
|
|
123
|
+
| Templates | `.forge/templates/*.md` | Hardcoded project-specific values (task ID format, prefix, paths) |
|
|
124
|
+
|
|
125
|
+
#### Extraction rules
|
|
126
|
+
|
|
127
|
+
- **Config fields** → direct mapping to `project-context.json` (highest confidence).
|
|
128
|
+
- **`PROJECT_NAME`, `PREFIX` patterns** in persona/skill files → extract by pattern.
|
|
129
|
+
- **`{{KEY}}` tokens that survived substitution** → attempt to fill from KB; if
|
|
130
|
+
not resolvable, flag for user review.
|
|
131
|
+
- **Specific project paths, entity names, stack references** → extract with moderate confidence.
|
|
132
|
+
- **Generic boilerplate** (role definitions, algorithm steps, universal rules) → skip.
|
|
133
|
+
|
|
134
|
+
#### Target `project-context.json` fields (19 string-leaf fields)
|
|
135
|
+
|
|
136
|
+
These are the 19 scalar string leaves of `project-context.schema.json` that
|
|
137
|
+
count toward the ≥80% (≥15 of 19) population threshold:
|
|
138
|
+
|
|
139
|
+
1. `project.name`
|
|
140
|
+
2. `project.prefix`
|
|
141
|
+
3. `project.description`
|
|
142
|
+
4. `project.commands.test`
|
|
143
|
+
5. `project.commands.build`
|
|
144
|
+
6. `project.commands.deploy`
|
|
145
|
+
7. `architecture.frameworks.backend`
|
|
146
|
+
8. `architecture.frameworks.frontend`
|
|
147
|
+
9. `architecture.frameworks.database`
|
|
148
|
+
10. `architecture.dataAccess`
|
|
149
|
+
11. `architecture.deployment`
|
|
150
|
+
12. `conventions.branching`
|
|
151
|
+
13. `conventions.taskIdFormat`
|
|
152
|
+
14. `deployment.impactNotes`
|
|
153
|
+
15. `verification.typeCheck`
|
|
154
|
+
16. `verification.lint`
|
|
155
|
+
17. `verification.test`
|
|
156
|
+
18. `verification.build`
|
|
157
|
+
19. `verification.infraBuild`
|
|
158
|
+
|
|
159
|
+
#### No-data-loss guarantee
|
|
160
|
+
|
|
161
|
+
Any project-specific fact that cannot be confidently mapped to a
|
|
162
|
+
`project-context.json` field MUST be written to
|
|
163
|
+
`.forge/archive/pre-migration/MIGRATION_NOTES.md` for manual review. It must
|
|
164
|
+
never be silently dropped.
|
|
165
|
+
|
|
166
|
+
Format for each item in `MIGRATION_NOTES.md`:
|
|
167
|
+
```
|
|
168
|
+
## Unresolved: <short description>
|
|
169
|
+
Source: <file>:<line range>
|
|
170
|
+
Extracted: <verbatim text>
|
|
171
|
+
Suggested mapping: <field name or "none — needs manual review">
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Also document in `MIGRATION_NOTES.md`:
|
|
175
|
+
- The old plugin version detection result: if a `version` field was found in any
|
|
176
|
+
`.forge/store/sprints/*.json` record, record it as
|
|
177
|
+
`"derived-from-sprint-updated-<date>"`. Otherwise record `"unknown-pre-v0.40"`.
|
|
178
|
+
This provides an audit trace for future reviews.
|
|
179
|
+
- Note: the plugin version in `$FORGE_ROOT/.claude-plugin/plugin.json` reflects
|
|
180
|
+
the *new* installed plugin version and is NOT used to determine the pre-migration
|
|
181
|
+
version.
|
|
182
|
+
|
|
183
|
+
Produce a draft `project-context.json` covering all extractable T02 fields.
|
|
184
|
+
Fields that cannot be confidently populated are left at their schema defaults.
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
### Phase 2 — Synthesise and Show (Confirmation Gate)
|
|
189
|
+
|
|
190
|
+
Display the synthesised `project-context.json` to the user. Show:
|
|
191
|
+
|
|
192
|
+
1. The full JSON content (or a diff from schema defaults if large).
|
|
193
|
+
2. A summary line:
|
|
194
|
+
```
|
|
195
|
+
String fields populated: N / 19
|
|
196
|
+
Items needing review: K (see MIGRATION_NOTES.md)
|
|
197
|
+
```
|
|
198
|
+
3. The archive plan:
|
|
199
|
+
```
|
|
200
|
+
Files to archive: N (to .forge/archive/pre-migration/)
|
|
201
|
+
```
|
|
202
|
+
4. The substitution plan:
|
|
203
|
+
```
|
|
204
|
+
Files to write: N (new .forge/personas/, .forge/skills/, .forge/workflows/, .forge/templates/)
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
Prompt for explicit confirmation:
|
|
208
|
+
```
|
|
209
|
+
Migration plan ready.
|
|
210
|
+
String fields populated: N / 19
|
|
211
|
+
Items needing review: K (see MIGRATION_NOTES.md)
|
|
212
|
+
Files to archive: N
|
|
213
|
+
Files to write: N
|
|
214
|
+
|
|
215
|
+
Proceed with migration? [Y/n]
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
**If user declines:**
|
|
219
|
+
```sh
|
|
220
|
+
rm .forge/archive/pre-migration/.migration-in-progress
|
|
221
|
+
# Remove sentinel dir only if it is now empty
|
|
222
|
+
rmdir .forge/archive/pre-migration/ 2>/dev/null || true
|
|
223
|
+
```
|
|
224
|
+
Exit cleanly with the message: "Migration cancelled. No changes made."
|
|
225
|
+
|
|
226
|
+
**If user accepts:** proceed to Phase 3.
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
### Phase 3 — Write (archive → substitute → register)
|
|
231
|
+
|
|
232
|
+
#### Step 3a — Archive
|
|
233
|
+
|
|
234
|
+
Note: `.forge/archive/pre-migration/` was already created in Phase 0 (sentinel
|
|
235
|
+
setup). The `mkdir -p` below is idempotent.
|
|
236
|
+
|
|
237
|
+
```sh
|
|
238
|
+
mkdir -p .forge/archive/pre-migration/
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
Copy every file from `.forge/` (excluding `.forge/store/` and `.forge/archive/`
|
|
242
|
+
themselves) to `.forge/archive/pre-migration/`. Preserve directory structure.
|
|
243
|
+
Example:
|
|
244
|
+
```sh
|
|
245
|
+
# List files to archive (excluding store/ and archive/ subtrees)
|
|
246
|
+
find .forge/ -not -path '.forge/store/*' -not -path '.forge/archive/*' -type f
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
For each file found, copy it to `.forge/archive/pre-migration/<relative-path>`,
|
|
250
|
+
creating intermediate directories as needed.
|
|
251
|
+
|
|
252
|
+
Write an md5 manifest:
|
|
253
|
+
```sh
|
|
254
|
+
find .forge/archive/pre-migration/ -not -name 'MANIFEST.md5' -not -name '.migration-in-progress' -type f \
|
|
255
|
+
| sort | xargs md5sum > .forge/archive/pre-migration/MANIFEST.md5
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
Verify manifest completeness: re-read the directory list and confirm every
|
|
259
|
+
archived file (excluding `MANIFEST.md5` itself and `.migration-in-progress`)
|
|
260
|
+
has an entry in `MANIFEST.md5`. If any file is missing, add it and report the
|
|
261
|
+
discrepancy to the user.
|
|
262
|
+
|
|
263
|
+
#### Step 3b — Write `project-context.json`
|
|
264
|
+
|
|
265
|
+
Write `.forge/project-context.json` with the synthesised content.
|
|
266
|
+
|
|
267
|
+
Validate via the store tool:
|
|
268
|
+
```sh
|
|
269
|
+
export FORGE_ROOT
|
|
270
|
+
node "$FORGE_ROOT/tools/validate-store.cjs" --dry-run
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
If this exits non-zero, report the validation errors to the user and HALT. Do
|
|
274
|
+
NOT remove the sentinel — the user can fix the issue and re-run.
|
|
275
|
+
|
|
276
|
+
#### Step 3c — Substitute (T03)
|
|
277
|
+
|
|
278
|
+
```sh
|
|
279
|
+
export FORGE_ROOT
|
|
280
|
+
node "$FORGE_ROOT/tools/substitute-placeholders.cjs" \
|
|
281
|
+
--forge-root "$FORGE_ROOT" \
|
|
282
|
+
--base-pack "$FORGE_ROOT/init/base-pack" \
|
|
283
|
+
--config ".forge/config.json" \
|
|
284
|
+
--context ".forge/project-context.json" \
|
|
285
|
+
--out "."
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
This overwrites `.forge/personas/`, `.forge/skills/`, `.forge/workflows/`,
|
|
289
|
+
`.forge/templates/`, and `.claude/commands/forge/` with the freshly substituted
|
|
290
|
+
base-pack.
|
|
291
|
+
|
|
292
|
+
If `substitute-placeholders.cjs` exits non-zero: halt, report the error to the
|
|
293
|
+
user. Do NOT remove the sentinel (preserves ability to re-run after fixing).
|
|
294
|
+
|
|
295
|
+
#### Step 3d — Register snapshot (T05)
|
|
296
|
+
|
|
297
|
+
```sh
|
|
298
|
+
export FORGE_ROOT
|
|
299
|
+
node "$FORGE_ROOT/tools/manage-versions.cjs" init
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
`manage-versions init` is idempotent. Since `.forge/structure-versions.json`
|
|
303
|
+
does not exist yet, this writes snapshot 0 with `source: "base-pack"` and
|
|
304
|
+
`createdAt` set to the current time.
|
|
305
|
+
|
|
306
|
+
After `init` completes, read the written file and patch snapshot 0:
|
|
307
|
+
|
|
308
|
+
1. Set `source` → `"migration-from-v{old}"` where `{old}` is the old plugin
|
|
309
|
+
version determined in Phase 1 (defaults to `"unknown-pre-v0.40"`).
|
|
310
|
+
The `source` field is `type: string` with no enum constraint — this free-form
|
|
311
|
+
value is valid per schema.
|
|
312
|
+
2. Set `createdAt` of snapshot 0 → `$MIGRATION_START` (the timestamp recorded in
|
|
313
|
+
Phase 0d). This ensures snapshot 0 reflects the conceptual moment of
|
|
314
|
+
migration, not the `manage-versions init` run time.
|
|
315
|
+
|
|
316
|
+
Example patch (using Node.js):
|
|
317
|
+
```sh
|
|
318
|
+
node -e "
|
|
319
|
+
const fs = require('fs');
|
|
320
|
+
const sv = JSON.parse(fs.readFileSync('.forge/structure-versions.json','utf8'));
|
|
321
|
+
if (sv.snapshots && sv.snapshots.length > 0) {
|
|
322
|
+
sv.snapshots[0].source = 'migration-from-v{old}';
|
|
323
|
+
sv.snapshots[0].createdAt = process.env.MIGRATION_START;
|
|
324
|
+
}
|
|
325
|
+
fs.writeFileSync('.forge/structure-versions.json', JSON.stringify(sv, null, 2) + '\n');
|
|
326
|
+
console.log('Patched snapshot 0');
|
|
327
|
+
" MIGRATION_START="$MIGRATION_START"
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
#### Step 3e — Cleanup sentinel
|
|
331
|
+
|
|
332
|
+
```sh
|
|
333
|
+
rm .forge/archive/pre-migration/.migration-in-progress
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
---
|
|
337
|
+
|
|
338
|
+
### Phase 4 — Verify and Emit
|
|
339
|
+
|
|
340
|
+
**Verification (CLI-accessible only — do NOT invoke `/forge:health` here):**
|
|
341
|
+
|
|
342
|
+
```sh
|
|
343
|
+
export FORGE_ROOT
|
|
344
|
+
# 1. Validate the store
|
|
345
|
+
node "$FORGE_ROOT/tools/validate-store.cjs" --dry-run
|
|
346
|
+
|
|
347
|
+
# 2. Verify substitution outputs are non-empty
|
|
348
|
+
ls .forge/personas/*.md .forge/skills/*.md .forge/workflows/*.md .forge/templates/*.md
|
|
349
|
+
|
|
350
|
+
# 3. Verify project-context.json exists and is valid JSON
|
|
351
|
+
node -e "JSON.parse(require('fs').readFileSync('.forge/project-context.json','utf8')); console.log('project-context.json OK');"
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
Report findings to the user.
|
|
355
|
+
|
|
356
|
+
Tell the user: "Run `/forge:health` after migration completes to check overall
|
|
357
|
+
knowledge base status."
|
|
358
|
+
|
|
359
|
+
**Event emission — canonical schema compliant:**
|
|
360
|
+
|
|
361
|
+
Determine the sprint ID for the event. Look up the first sprint record in the
|
|
362
|
+
store:
|
|
363
|
+
```sh
|
|
364
|
+
ls .forge/store/sprints/*.json 2>/dev/null | sort | head -n1
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
Read that file and extract the `sprintId` field. If no sprint files exist, use
|
|
368
|
+
`"migration"` as the `sprintId` placeholder.
|
|
369
|
+
|
|
370
|
+
```sh
|
|
371
|
+
export FORGE_ROOT
|
|
372
|
+
MIGRATION_END=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
|
373
|
+
node "$FORGE_ROOT/tools/store-cli.cjs" emit "{projectSprintId}" '{
|
|
374
|
+
"eventId": "migration-'"$(date -u +%Y%m%dT%H%M%SZ)"'",
|
|
375
|
+
"taskId": "migration",
|
|
376
|
+
"sprintId": "{projectSprintId}",
|
|
377
|
+
"role": "migration-agent",
|
|
378
|
+
"action": "migration-completed",
|
|
379
|
+
"phase": "write",
|
|
380
|
+
"iteration": 1,
|
|
381
|
+
"startTimestamp": "'"$MIGRATION_START"'",
|
|
382
|
+
"endTimestamp": "'"$MIGRATION_END"'",
|
|
383
|
+
"durationMinutes": {elapsed},
|
|
384
|
+
"model": "{current-model}",
|
|
385
|
+
"notes": "{\"source\":\"migration-from-v{old}\",\"archivePath\":\".forge/archive/pre-migration/\",\"projectContextPath\":\".forge/project-context.json\"}"
|
|
386
|
+
}'
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
If `store-cli.cjs emit` exits non-zero, report the error but do NOT block
|
|
390
|
+
migration completion — the event is diagnostic metadata, not a prerequisite for
|
|
391
|
+
a working `.forge/` install.
|
|
392
|
+
|
|
393
|
+
**Report completion summary:**
|
|
394
|
+
|
|
395
|
+
```
|
|
396
|
+
Structural migration complete.
|
|
397
|
+
|
|
398
|
+
project-context.json: .forge/project-context.json (N / 19 string fields populated)
|
|
399
|
+
Archive: .forge/archive/pre-migration/ (N files, MANIFEST.md5 included)
|
|
400
|
+
Structure snapshot: .forge/structure-versions.json (source: migration-from-v{old})
|
|
401
|
+
Review items: K items in .forge/archive/pre-migration/MIGRATION_NOTES.md
|
|
402
|
+
|
|
403
|
+
Next steps:
|
|
404
|
+
1. Run /forge:health to verify the knowledge base.
|
|
405
|
+
2. Review MIGRATION_NOTES.md for any extractions requiring manual attention.
|
|
406
|
+
3. If something looks wrong, use the rollback procedure below.
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
---
|
|
410
|
+
|
|
411
|
+
## Rollback Procedure
|
|
412
|
+
|
|
413
|
+
The archive at `.forge/archive/pre-migration/` contains the complete pre-migration
|
|
414
|
+
state. To restore:
|
|
415
|
+
|
|
416
|
+
```sh
|
|
417
|
+
# Step 1 — Remove the migrated outputs
|
|
418
|
+
rm -rf .forge/personas .forge/skills .forge/workflows .forge/templates
|
|
419
|
+
rm -f .forge/project-context.json .forge/structure-versions.json
|
|
420
|
+
|
|
421
|
+
# Step 2 — Restore from archive
|
|
422
|
+
cp -r .forge/archive/pre-migration/personas .forge/personas 2>/dev/null || true
|
|
423
|
+
cp -r .forge/archive/pre-migration/skills .forge/skills 2>/dev/null || true
|
|
424
|
+
cp -r .forge/archive/pre-migration/workflows .forge/workflows 2>/dev/null || true
|
|
425
|
+
cp -r .forge/archive/pre-migration/templates .forge/templates 2>/dev/null || true
|
|
426
|
+
cp .forge/archive/pre-migration/project-context.json .forge/project-context.json 2>/dev/null || true
|
|
427
|
+
|
|
428
|
+
# Step 3 — Verify restoration
|
|
429
|
+
ls .forge/personas/*.md .forge/skills/*.md .forge/workflows/*.md .forge/templates/*.md
|
|
430
|
+
|
|
431
|
+
# Step 4 (optional) — Keep archive for audit, or remove it
|
|
432
|
+
# rm -rf .forge/archive/pre-migration/
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
To verify the restored files match the originals, compare against `MANIFEST.md5`:
|
|
436
|
+
```sh
|
|
437
|
+
cd .forge && md5sum -c archive/pre-migration/MANIFEST.md5 2>/dev/null | grep -v OK || echo "All files match"
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
---
|
|
441
|
+
|
|
442
|
+
## Error Handling
|
|
443
|
+
|
|
444
|
+
| Situation | Action |
|
|
445
|
+
|---|---|
|
|
446
|
+
| `.forge/config.json` missing | Stop. Tell user to run `/forge:init` first. |
|
|
447
|
+
| `structure-versions.json` already exists | Stop. Structural migration not needed for post-T05 installs. |
|
|
448
|
+
| Sentinel found + valid draft exists | Offer resume from Phase 2 or fresh restart. |
|
|
449
|
+
| Sentinel found + no valid draft | Offer fresh restart (remove sentinel and continue). |
|
|
450
|
+
| User declines confirmation | Remove sentinel, exit cleanly. No writes made. |
|
|
451
|
+
| `validate-store.cjs --dry-run` fails after writing `project-context.json` | Halt. Report errors. Do NOT remove sentinel. User fixes and re-runs. |
|
|
452
|
+
| `substitute-placeholders.cjs` exits non-zero | Halt. Report error. Do NOT remove sentinel. |
|
|
453
|
+
| `manage-versions.cjs init` exits non-zero | Halt. Report error. Archive is complete — rollback is available. |
|
|
454
|
+
| `store-cli.cjs emit` exits non-zero | Report error. Continue — event is diagnostic only. |
|
|
455
|
+
| Any unexpected error | Describe the error, point user to rollback procedure, suggest `/forge:report-bug`. |
|