mindforge-cc 1.0.0

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 (324) hide show
  1. package/.agent/CLAUDE.md +462 -0
  2. package/.agent/forge/help.md +7 -0
  3. package/.agent/forge/init-project.md +32 -0
  4. package/.agent/forge/plan-phase.md +30 -0
  5. package/.agent/mindforge/approve.md +18 -0
  6. package/.agent/mindforge/audit.md +30 -0
  7. package/.agent/mindforge/benchmark.md +33 -0
  8. package/.agent/mindforge/complete-milestone.md +18 -0
  9. package/.agent/mindforge/debug.md +126 -0
  10. package/.agent/mindforge/discuss-phase.md +138 -0
  11. package/.agent/mindforge/execute-phase.md +165 -0
  12. package/.agent/mindforge/health.md +21 -0
  13. package/.agent/mindforge/help.md +23 -0
  14. package/.agent/mindforge/init-org.md +131 -0
  15. package/.agent/mindforge/init-project.md +155 -0
  16. package/.agent/mindforge/install-skill.md +15 -0
  17. package/.agent/mindforge/map-codebase.md +298 -0
  18. package/.agent/mindforge/metrics.md +22 -0
  19. package/.agent/mindforge/migrate.md +40 -0
  20. package/.agent/mindforge/milestone.md +12 -0
  21. package/.agent/mindforge/next.md +105 -0
  22. package/.agent/mindforge/plan-phase.md +125 -0
  23. package/.agent/mindforge/plugins.md +40 -0
  24. package/.agent/mindforge/pr-review.md +41 -0
  25. package/.agent/mindforge/profile-team.md +23 -0
  26. package/.agent/mindforge/publish-skill.md +19 -0
  27. package/.agent/mindforge/quick.md +135 -0
  28. package/.agent/mindforge/release.md +10 -0
  29. package/.agent/mindforge/retrospective.md +26 -0
  30. package/.agent/mindforge/review.md +157 -0
  31. package/.agent/mindforge/security-scan.md +233 -0
  32. package/.agent/mindforge/ship.md +100 -0
  33. package/.agent/mindforge/skills.md +141 -0
  34. package/.agent/mindforge/status.md +104 -0
  35. package/.agent/mindforge/sync-confluence.md +11 -0
  36. package/.agent/mindforge/sync-jira.md +12 -0
  37. package/.agent/mindforge/tokens.md +8 -0
  38. package/.agent/mindforge/update.md +42 -0
  39. package/.agent/mindforge/verify-phase.md +62 -0
  40. package/.agent/mindforge/workspace.md +29 -0
  41. package/.claude/CLAUDE.md +462 -0
  42. package/.claude/commands/forge/help.md +7 -0
  43. package/.claude/commands/forge/init-project.md +32 -0
  44. package/.claude/commands/forge/plan-phase.md +30 -0
  45. package/.claude/commands/mindforge/approve.md +18 -0
  46. package/.claude/commands/mindforge/audit.md +30 -0
  47. package/.claude/commands/mindforge/benchmark.md +33 -0
  48. package/.claude/commands/mindforge/complete-milestone.md +18 -0
  49. package/.claude/commands/mindforge/debug.md +126 -0
  50. package/.claude/commands/mindforge/discuss-phase.md +138 -0
  51. package/.claude/commands/mindforge/execute-phase.md +165 -0
  52. package/.claude/commands/mindforge/health.md +21 -0
  53. package/.claude/commands/mindforge/help.md +23 -0
  54. package/.claude/commands/mindforge/init-org.md +131 -0
  55. package/.claude/commands/mindforge/init-project.md +155 -0
  56. package/.claude/commands/mindforge/install-skill.md +15 -0
  57. package/.claude/commands/mindforge/map-codebase.md +298 -0
  58. package/.claude/commands/mindforge/metrics.md +22 -0
  59. package/.claude/commands/mindforge/migrate.md +40 -0
  60. package/.claude/commands/mindforge/milestone.md +12 -0
  61. package/.claude/commands/mindforge/next.md +105 -0
  62. package/.claude/commands/mindforge/plan-phase.md +125 -0
  63. package/.claude/commands/mindforge/plugins.md +40 -0
  64. package/.claude/commands/mindforge/pr-review.md +41 -0
  65. package/.claude/commands/mindforge/profile-team.md +23 -0
  66. package/.claude/commands/mindforge/publish-skill.md +19 -0
  67. package/.claude/commands/mindforge/quick.md +135 -0
  68. package/.claude/commands/mindforge/release.md +10 -0
  69. package/.claude/commands/mindforge/retrospective.md +26 -0
  70. package/.claude/commands/mindforge/review.md +157 -0
  71. package/.claude/commands/mindforge/security-scan.md +233 -0
  72. package/.claude/commands/mindforge/ship.md +100 -0
  73. package/.claude/commands/mindforge/skills.md +141 -0
  74. package/.claude/commands/mindforge/status.md +104 -0
  75. package/.claude/commands/mindforge/sync-confluence.md +11 -0
  76. package/.claude/commands/mindforge/sync-jira.md +12 -0
  77. package/.claude/commands/mindforge/tokens.md +8 -0
  78. package/.claude/commands/mindforge/update.md +42 -0
  79. package/.claude/commands/mindforge/verify-phase.md +62 -0
  80. package/.claude/commands/mindforge/workspace.md +29 -0
  81. package/.forge/org/CONVENTIONS.md +0 -0
  82. package/.forge/org/ORG.md +0 -0
  83. package/.forge/org/SECURITY.md +0 -0
  84. package/.forge/org/TOOLS.md +0 -0
  85. package/.forge/personas/analyst.md +0 -0
  86. package/.forge/personas/architect.md +0 -0
  87. package/.forge/personas/debug-specialist.md +0 -0
  88. package/.forge/personas/developer.md +26 -0
  89. package/.forge/personas/qa-engineer.md +0 -0
  90. package/.forge/personas/release-manager.md +0 -0
  91. package/.forge/personas/security-reviewer.md +33 -0
  92. package/.forge/personas/tech-writer.md +0 -0
  93. package/.forge/skills/api-design/SKILL.md +0 -0
  94. package/.forge/skills/code-quality/SKILL.md +0 -0
  95. package/.forge/skills/documentation/SKILL.md +0 -0
  96. package/.forge/skills/security-review/SKILL.md +23 -0
  97. package/.forge/skills/testing-standards/SKILL.md +27 -0
  98. package/.github/workflows/mindforge-ci.yml +224 -0
  99. package/.gitlab-ci-mindforge.yml +18 -0
  100. package/.mindforge/MINDFORGE-SCHEMA.json +165 -0
  101. package/.mindforge/audit/AUDIT-SCHEMA.md +451 -0
  102. package/.mindforge/ci/ci-config-schema.md +21 -0
  103. package/.mindforge/ci/ci-mode.md +179 -0
  104. package/.mindforge/ci/github-actions-adapter.md +224 -0
  105. package/.mindforge/ci/gitlab-ci-adapter.md +31 -0
  106. package/.mindforge/ci/jenkins-adapter.md +44 -0
  107. package/.mindforge/distribution/registry-client.md +166 -0
  108. package/.mindforge/distribution/registry-schema.md +96 -0
  109. package/.mindforge/distribution/skill-publisher.md +44 -0
  110. package/.mindforge/distribution/skill-validator.md +74 -0
  111. package/.mindforge/engine/compaction-protocol.md +182 -0
  112. package/.mindforge/engine/context-injector.md +128 -0
  113. package/.mindforge/engine/dependency-parser.md +113 -0
  114. package/.mindforge/engine/skills/conflict-resolver.md +69 -0
  115. package/.mindforge/engine/skills/loader.md +184 -0
  116. package/.mindforge/engine/skills/registry.md +98 -0
  117. package/.mindforge/engine/skills/versioning.md +75 -0
  118. package/.mindforge/engine/verification-pipeline.md +111 -0
  119. package/.mindforge/engine/wave-executor.md +235 -0
  120. package/.mindforge/governance/GOVERNANCE-CONFIG.md +17 -0
  121. package/.mindforge/governance/approval-workflow.md +37 -0
  122. package/.mindforge/governance/change-classifier.md +63 -0
  123. package/.mindforge/governance/compliance-gates.md +31 -0
  124. package/.mindforge/integrations/confluence.md +27 -0
  125. package/.mindforge/integrations/connection-manager.md +163 -0
  126. package/.mindforge/integrations/github.md +25 -0
  127. package/.mindforge/integrations/gitlab.md +13 -0
  128. package/.mindforge/integrations/jira.md +102 -0
  129. package/.mindforge/integrations/slack.md +41 -0
  130. package/.mindforge/intelligence/antipattern-detector.md +75 -0
  131. package/.mindforge/intelligence/difficulty-scorer.md +55 -0
  132. package/.mindforge/intelligence/health-engine.md +208 -0
  133. package/.mindforge/intelligence/skill-gap-analyser.md +40 -0
  134. package/.mindforge/intelligence/smart-compaction.md +71 -0
  135. package/.mindforge/metrics/METRICS-SCHEMA.md +42 -0
  136. package/.mindforge/metrics/quality-tracker.md +32 -0
  137. package/.mindforge/monorepo/cross-package-planner.md +114 -0
  138. package/.mindforge/monorepo/dependency-graph-builder.md +32 -0
  139. package/.mindforge/monorepo/workspace-detector.md +129 -0
  140. package/.mindforge/org/CONVENTIONS.md +62 -0
  141. package/.mindforge/org/ORG.md +51 -0
  142. package/.mindforge/org/SECURITY.md +50 -0
  143. package/.mindforge/org/TOOLS.md +53 -0
  144. package/.mindforge/org/integrations/INTEGRATIONS-CONFIG.md +58 -0
  145. package/.mindforge/org/skills/MANIFEST.md +38 -0
  146. package/.mindforge/personas/analyst.md +52 -0
  147. package/.mindforge/personas/architect.md +75 -0
  148. package/.mindforge/personas/debug-specialist.md +52 -0
  149. package/.mindforge/personas/developer.md +85 -0
  150. package/.mindforge/personas/overrides/README.md +85 -0
  151. package/.mindforge/personas/qa-engineer.md +61 -0
  152. package/.mindforge/personas/release-manager.md +76 -0
  153. package/.mindforge/personas/security-reviewer.md +91 -0
  154. package/.mindforge/personas/tech-writer.md +51 -0
  155. package/.mindforge/plugins/PLUGINS-MANIFEST.md +23 -0
  156. package/.mindforge/plugins/plugin-loader.md +93 -0
  157. package/.mindforge/plugins/plugin-registry.md +44 -0
  158. package/.mindforge/plugins/plugin-schema.md +68 -0
  159. package/.mindforge/pr-review/ai-reviewer.md +266 -0
  160. package/.mindforge/pr-review/finding-formatter.md +46 -0
  161. package/.mindforge/pr-review/review-prompt-templates.md +44 -0
  162. package/.mindforge/production/compatibility-layer.md +39 -0
  163. package/.mindforge/production/migration-engine.md +52 -0
  164. package/.mindforge/production/production-checklist.md +165 -0
  165. package/.mindforge/production/token-optimiser.md +68 -0
  166. package/.mindforge/skills/accessibility/SKILL.md +106 -0
  167. package/.mindforge/skills/api-design/SKILL.md +98 -0
  168. package/.mindforge/skills/code-quality/SKILL.md +88 -0
  169. package/.mindforge/skills/data-privacy/SKILL.md +126 -0
  170. package/.mindforge/skills/database-patterns/SKILL.md +192 -0
  171. package/.mindforge/skills/documentation/SKILL.md +91 -0
  172. package/.mindforge/skills/incident-response/SKILL.md +180 -0
  173. package/.mindforge/skills/performance/SKILL.md +120 -0
  174. package/.mindforge/skills/security-review/SKILL.md +83 -0
  175. package/.mindforge/skills/testing-standards/SKILL.md +97 -0
  176. package/.mindforge/team/TEAM-PROFILE.md +42 -0
  177. package/.mindforge/team/multi-handoff.md +23 -0
  178. package/.mindforge/team/profiles/README.md +13 -0
  179. package/.mindforge/team/session-merger.md +18 -0
  180. package/.planning/ARCHITECTURE.md +0 -0
  181. package/.planning/AUDIT.jsonl +0 -0
  182. package/.planning/HANDOFF.json +28 -0
  183. package/.planning/PROJECT.md +33 -0
  184. package/.planning/RELEASE-CHECKLIST.md +68 -0
  185. package/.planning/REQUIREMENTS.md +0 -0
  186. package/.planning/ROADMAP.md +0 -0
  187. package/.planning/STATE.md +31 -0
  188. package/.planning/approvals/.gitkeep +1 -0
  189. package/.planning/archive/.gitkeep +1 -0
  190. package/.planning/audit-archive/.gitkeep +1 -0
  191. package/.planning/decisions/.gitkeep +0 -0
  192. package/.planning/decisions/ADR-001-handoff-tracking.md +41 -0
  193. package/.planning/decisions/ADR-002-markdown-commands.md +46 -0
  194. package/.planning/decisions/ADR-003-skills-trigger-model.md +37 -0
  195. package/.planning/decisions/ADR-004-wave-parallelism-model.md +45 -0
  196. package/.planning/decisions/ADR-005-append-only-audit-log.md +51 -0
  197. package/.planning/decisions/ADR-006-tiered-skills-system.md +22 -0
  198. package/.planning/decisions/ADR-007-trigger-keyword-model.md +22 -0
  199. package/.planning/decisions/ADR-008-just-in-time-skill-loading.md +29 -0
  200. package/.planning/decisions/ADR-009-enterprise-integration-retry-policy.md +8 -0
  201. package/.planning/decisions/ADR-010-governance-tier-escalation.md +8 -0
  202. package/.planning/decisions/ADR-011-multi-developer-handoff-contract.md +8 -0
  203. package/.planning/decisions/ADR-012-intelligence-feedback-loops.md +19 -0
  204. package/.planning/decisions/ADR-013-mindforge-md-constitution.md +16 -0
  205. package/.planning/decisions/ADR-014-metrics-as-signals-not-evaluation.md +15 -0
  206. package/.planning/decisions/ADR-015-npm-based-skill-registry.md +26 -0
  207. package/.planning/decisions/ADR-016-ci-exit-code-0-on-timeout.md +27 -0
  208. package/.planning/decisions/ADR-017-sdk-localhost-only.md +28 -0
  209. package/.planning/decisions/ADR-018-installer-self-install-detection.md +15 -0
  210. package/.planning/decisions/ADR-019-self-update-scope-preservation.md +14 -0
  211. package/.planning/decisions/ADR-020-v1.0.0-stable-interface-contract.md +23 -0
  212. package/.planning/jira-sync.json +9 -0
  213. package/.planning/milestones/.gitkeep +1 -0
  214. package/.planning/phases/day1/REVIEW-DAY1.md +50 -0
  215. package/.planning/phases/day1/SECURITY-REVIEW-DAY1.md +15 -0
  216. package/.planning/phases/day2/REVIEW-DAY2.md +521 -0
  217. package/.planning/phases/day3/REVIEW-DAY3.md +234 -0
  218. package/.planning/slack-threads.json +6 -0
  219. package/CHANGELOG.md +175 -0
  220. package/LICENSE +21 -0
  221. package/MINDFORGE.md +76 -0
  222. package/README.md +182 -0
  223. package/RELEASENOTES.md +41 -0
  224. package/SECURITY.md +4 -0
  225. package/bin/install.js +120 -0
  226. package/bin/installer-core.js +292 -0
  227. package/bin/migrations/0.1.0-to-0.5.0.js +37 -0
  228. package/bin/migrations/0.5.0-to-0.6.0.js +17 -0
  229. package/bin/migrations/0.6.0-to-1.0.0.js +100 -0
  230. package/bin/migrations/migrate.js +151 -0
  231. package/bin/migrations/schema-versions.js +64 -0
  232. package/bin/updater/changelog-fetcher.js +62 -0
  233. package/bin/updater/self-update.js +169 -0
  234. package/bin/updater/version-comparator.js +68 -0
  235. package/bin/validate-config.js +92 -0
  236. package/bin/wizard/config-generator.js +112 -0
  237. package/bin/wizard/environment-detector.js +76 -0
  238. package/bin/wizard/setup-wizard.js +237 -0
  239. package/docs/Context/Master-Context.md +701 -0
  240. package/docs/architecture/README.md +35 -0
  241. package/docs/architecture/decision-records-index.md +26 -0
  242. package/docs/ci-cd-integration.md +30 -0
  243. package/docs/ci-quickstart.md +78 -0
  244. package/docs/commands-reference.md +11 -0
  245. package/docs/contributing/CONTRIBUTING.md +38 -0
  246. package/docs/contributing/plugin-authoring.md +50 -0
  247. package/docs/contributing/skill-authoring.md +41 -0
  248. package/docs/enterprise-setup.md +25 -0
  249. package/docs/faq.md +38 -0
  250. package/docs/getting-started.md +36 -0
  251. package/docs/governance-guide.md +23 -0
  252. package/docs/mindforge-md-reference.md +53 -0
  253. package/docs/monorepo-guide.md +26 -0
  254. package/docs/persona-customisation.md +56 -0
  255. package/docs/quick-verify.md +33 -0
  256. package/docs/reference/audit-events.md +53 -0
  257. package/docs/reference/commands.md +82 -0
  258. package/docs/reference/config-reference.md +64 -0
  259. package/docs/reference/sdk-api.md +48 -0
  260. package/docs/reference/skills-api.md +57 -0
  261. package/docs/release-checklist-guide.md +37 -0
  262. package/docs/requirements.md +29 -0
  263. package/docs/sdk-reference.md +27 -0
  264. package/docs/security/SECURITY.md +42 -0
  265. package/docs/security/penetration-test-results.md +31 -0
  266. package/docs/security/threat-model.md +142 -0
  267. package/docs/skills-authoring-guide.md +119 -0
  268. package/docs/skills-publishing-guide.md +21 -0
  269. package/docs/team-setup-guide.md +21 -0
  270. package/docs/troubleshooting.md +119 -0
  271. package/docs/tutorial.md +195 -0
  272. package/docs/upgrade.md +44 -0
  273. package/docs/user-guide.md +131 -0
  274. package/docs/usp-features.md +214 -0
  275. package/eslint.config.mjs +31 -0
  276. package/examples/starter-project/.planning/AUDIT.jsonl +1 -0
  277. package/examples/starter-project/.planning/HANDOFF.json +23 -0
  278. package/examples/starter-project/.planning/PROJECT.md +27 -0
  279. package/examples/starter-project/.planning/STATE.md +10 -0
  280. package/examples/starter-project/MINDFORGE.md +40 -0
  281. package/examples/starter-project/README.md +14 -0
  282. package/implementation-roadmap/day-1-imp/DAY1-HARDEN.md +823 -0
  283. package/implementation-roadmap/day-1-imp/DAY1-IMPLEMENT.md +2459 -0
  284. package/implementation-roadmap/day-1-imp/DAY1-REVIEW.md +288 -0
  285. package/implementation-roadmap/day-2-imp/DAY2-HARDEN.md +954 -0
  286. package/implementation-roadmap/day-2-imp/DAY2-IMPLEMENT.md +2347 -0
  287. package/implementation-roadmap/day-2-imp/DAY2-REVIEW.md +422 -0
  288. package/implementation-roadmap/day-3-imp/DAY3-HARDEN.md +870 -0
  289. package/implementation-roadmap/day-3-imp/DAY3-IMPLEMENT.md +2798 -0
  290. package/implementation-roadmap/day-3-imp/DAY3-REVIEW.md +484 -0
  291. package/implementation-roadmap/day-4-imp/DAY4-HARDEN.md +1087 -0
  292. package/implementation-roadmap/day-4-imp/DAY4-IMPLEMENT.md +2874 -0
  293. package/implementation-roadmap/day-4-imp/DAY4-REVIEW.md +386 -0
  294. package/implementation-roadmap/day-5-imp/DAY5-HARDEN.md +1078 -0
  295. package/implementation-roadmap/day-5-imp/DAY5-IMPLEMENT.md +3151 -0
  296. package/implementation-roadmap/day-5-imp/DAY5-REVIEW.md +345 -0
  297. package/implementation-roadmap/day-6-imp/DAY6-COMPLETE.md +3919 -0
  298. package/implementation-roadmap/day-7-imp-prod/DAY7-PRODUCTION-FINAL.md +4513 -0
  299. package/package.json +31 -0
  300. package/sdk/README.md +69 -0
  301. package/sdk/eslint.config.mjs +34 -0
  302. package/sdk/package-lock.json +1507 -0
  303. package/sdk/package.json +30 -0
  304. package/sdk/src/client.ts +133 -0
  305. package/sdk/src/commands.ts +63 -0
  306. package/sdk/src/events.ts +166 -0
  307. package/sdk/src/index.ts +22 -0
  308. package/sdk/src/types.ts +87 -0
  309. package/sdk/tsconfig.json +13 -0
  310. package/tests/audit.test.js +206 -0
  311. package/tests/ci-mode.test.js +162 -0
  312. package/tests/compaction.test.js +161 -0
  313. package/tests/distribution.test.js +205 -0
  314. package/tests/e2e.test.js +618 -0
  315. package/tests/governance.test.js +130 -0
  316. package/tests/install.test.js +209 -0
  317. package/tests/integrations.test.js +128 -0
  318. package/tests/intelligence.test.js +117 -0
  319. package/tests/metrics.test.js +96 -0
  320. package/tests/migration.test.js +309 -0
  321. package/tests/production.test.js +416 -0
  322. package/tests/sdk.test.js +200 -0
  323. package/tests/skills-platform.test.js +403 -0
  324. package/tests/wave-engine.test.js +338 -0
@@ -0,0 +1,151 @@
1
+ /**
2
+ * MindForge — Migration Runner
3
+ * Safely upgrades .planning/ file schemas between MindForge versions.
4
+ * Philosophy: never lose data, always back up, always verify after.
5
+ */
6
+ 'use strict';
7
+
8
+ const fs = require('fs');
9
+ const path = require('path');
10
+
11
+ // Re-export for use by self-update.js
12
+ const { compareSemver } = require('../updater/version-comparator');
13
+ module.exports.compareSemver = compareSemver;
14
+
15
+ const PLANNING_DIR = path.join(process.cwd(), '.planning');
16
+
17
+ const PATHS = {
18
+ handoff: path.join(PLANNING_DIR, 'HANDOFF.json'),
19
+ state: path.join(PLANNING_DIR, 'STATE.md'),
20
+ audit: path.join(PLANNING_DIR, 'AUDIT.jsonl'),
21
+ mindforgemd: path.join(process.cwd(), 'MINDFORGE.md'),
22
+ };
23
+
24
+ /**
25
+ * Run all needed migrations from fromVersion to toVersion.
26
+ * Creates a backup first. Restores on failure.
27
+ * Returns { status, from, to, backupDir }
28
+ */
29
+ async function runMigrations(fromVersion, toVersion) {
30
+ console.log(`\n Migration: v${fromVersion} → v${toVersion}`);
31
+
32
+ if (!fs.existsSync(PLANNING_DIR)) {
33
+ console.log(` ℹ️ No .planning/ directory found — skipping migration`);
34
+ return { status: 'no-planning-dir' };
35
+ }
36
+
37
+ if (compareSemver(fromVersion, toVersion) >= 0) {
38
+ console.log(` ✅ No migration needed`);
39
+ return { status: 'no-migration-needed' };
40
+ }
41
+
42
+ // Determine which migrations to run
43
+ const allMigrations = [
44
+ require('./0.1.0-to-0.5.0'),
45
+ require('./0.5.0-to-0.6.0'),
46
+ require('./0.6.0-to-1.0.0'),
47
+ ];
48
+
49
+ // A migration should run if its DESTINATION VERSION falls within the range:
50
+ // (fromVersion, toVersion] — i.e., greater than fromVersion AND at most toVersion
51
+ const migrationsToRun = allMigrations.filter(m =>
52
+ compareSemver(m.toVersion, fromVersion) > 0 &&
53
+ compareSemver(m.toVersion, toVersion) <= 0
54
+ );
55
+
56
+ if (migrationsToRun.length === 0) {
57
+ console.log(` ✅ No applicable migrations`);
58
+ return { status: 'no-migrations' };
59
+ }
60
+
61
+ console.log(` Migrations to run (${migrationsToRun.length}):`);
62
+ migrationsToRun.forEach(m => console.log(` • v${m.fromVersion} → v${m.toVersion}: ${m.description}`));
63
+
64
+ // ── Create backup (abort if backup fails — never migrate without a backup) ──
65
+ const backupDir = path.join(PLANNING_DIR, `migration-backup-${Date.now()}`);
66
+ let backupCreated = false;
67
+ try {
68
+ fs.mkdirSync(backupDir, { recursive: true });
69
+ const filesToBackup = Object.values(PATHS).filter(p => fs.existsSync(p));
70
+
71
+ if (filesToBackup.length === 0) {
72
+ console.log(` ℹ️ No files to migrate`);
73
+ fs.rmdirSync(backupDir);
74
+ return { status: 'no-files' };
75
+ }
76
+
77
+ for (const f of filesToBackup) {
78
+ fs.copyFileSync(f, path.join(backupDir, path.basename(f)));
79
+ }
80
+
81
+ // Verify backup: check every backed-up file exists and has content
82
+ const backed = fs.readdirSync(backupDir);
83
+ const allBacked = filesToBackup.every(f =>
84
+ backed.includes(path.basename(f)) &&
85
+ fs.statSync(path.join(backupDir, path.basename(f))).size > 0
86
+ );
87
+
88
+ if (!allBacked) throw new Error('Backup verification failed — some files missing or empty');
89
+
90
+ backupCreated = true;
91
+ console.log(` 📦 Backup: .planning/${path.basename(backupDir)} (${filesToBackup.length} files)`);
92
+
93
+ } catch (backupErr) {
94
+ // Abort cleanly — no migration is safer than a migration without backup
95
+ if (fs.existsSync(backupDir)) {
96
+ try { fs.rmSync(backupDir, { recursive: true, force: true }); } catch {}
97
+ }
98
+ throw new Error(
99
+ `Migration aborted: cannot create backup (${backupErr.message}). ` +
100
+ `Free disk space and retry.`
101
+ );
102
+ }
103
+
104
+ // ── Execute migrations in order ───────────────────────────────────────────
105
+ for (const migration of migrationsToRun) {
106
+ console.log(`\n Running: v${migration.fromVersion} → v${migration.toVersion}...`);
107
+ try {
108
+ await migration.run(PATHS);
109
+ console.log(` ✅ Complete`);
110
+ } catch (migErr) {
111
+ console.error(` ❌ Failed: ${migErr.message}`);
112
+ console.log(` Restoring from backup...`);
113
+
114
+ // Restore all files from backup
115
+ for (const f of fs.readdirSync(backupDir)) {
116
+ const dst = Object.values(PATHS).find(p => path.basename(p) === f) ||
117
+ path.join(PLANNING_DIR, f);
118
+ fs.copyFileSync(path.join(backupDir, f), dst);
119
+ }
120
+ console.log(` ✅ Restored from backup. No changes applied.`);
121
+ throw new Error(`Migration failed at v${migration.toVersion}: ${migErr.message}`);
122
+ }
123
+ }
124
+
125
+ // ── Update schema_version in HANDOFF.json ────────────────────────────────
126
+ if (fs.existsSync(PATHS.handoff)) {
127
+ const handoff = JSON.parse(fs.readFileSync(PATHS.handoff, 'utf8'));
128
+ handoff.schema_version = toVersion;
129
+ handoff._migration_completed = new Date().toISOString();
130
+ fs.writeFileSync(PATHS.handoff, JSON.stringify(handoff, null, 2) + '\n');
131
+ }
132
+
133
+ console.log(`\n ✅ All migrations complete: v${fromVersion} → v${toVersion}`);
134
+
135
+ // ── Post-migration: clean up in CI, retain in interactive ─────────────────
136
+ if (process.env.CI === 'true') {
137
+ try {
138
+ fs.rmSync(backupDir, { recursive: true, force: true });
139
+ console.log(` 🗑️ CI mode: backup auto-deleted (disk space)`);
140
+ } catch {
141
+ // Silent failure on cleanup — migration succeeded, cleanup is optional
142
+ }
143
+ } else {
144
+ console.log(` Backup retained: .planning/${path.basename(backupDir)}`);
145
+ console.log(` Remove when satisfied: rm -rf .planning/${path.basename(backupDir)}\n`);
146
+ }
147
+
148
+ return { status: 'migrated', from: fromVersion, to: toVersion, backupDir };
149
+ }
150
+
151
+ module.exports.runMigrations = runMigrations;
@@ -0,0 +1,64 @@
1
+ /**
2
+ * MindForge — Schema Version Registry
3
+ * Documents every breaking schema change across all released versions.
4
+ * Used by the migration engine to determine what migrations are needed.
5
+ */
6
+ 'use strict';
7
+
8
+ const SCHEMA_HISTORY = [
9
+ {
10
+ version: '0.1.0',
11
+ date: '2026-01-01',
12
+ description: 'Initial release',
13
+ handoff_fields_added: [
14
+ 'schema_version', 'project', 'phase', 'plan', 'next_task',
15
+ 'blockers', 'decisions_needed', 'context_refs', '_warning', 'updated_at',
16
+ ],
17
+ handoff_fields_removed: [],
18
+ audit_fields_added: ['id', 'timestamp', 'event', 'agent', 'phase'],
19
+ breaking: [],
20
+ },
21
+ {
22
+ version: '0.5.0',
23
+ date: '2026-01-15',
24
+ description: 'Intelligence layer — smart compaction adds structured fields',
25
+ handoff_fields_added: [
26
+ 'decisions_made', 'discoveries', 'implicit_knowledge',
27
+ 'quality_signals', 'compaction_level', 'compaction_timestamp',
28
+ ],
29
+ handoff_fields_removed: [],
30
+ audit_fields_added: [],
31
+ breaking: [
32
+ 'compaction_protocol.md now requires Level 1/2/3 classification',
33
+ ],
34
+ },
35
+ {
36
+ version: '0.6.0',
37
+ date: '2026-02-01',
38
+ description: 'Distribution platform — adds per-developer and CI fields',
39
+ handoff_fields_added: [
40
+ 'developer_id', 'session_id', 'recent_commits', 'recent_files',
41
+ ],
42
+ handoff_fields_removed: [],
43
+ audit_fields_added: ['session_id'],
44
+ breaking: [
45
+ 'AUDIT.jsonl entries should now include session_id',
46
+ 'INTEGRATIONS-CONFIG.md gains EMERGENCY_APPROVERS field',
47
+ ],
48
+ },
49
+ {
50
+ version: '1.0.0',
51
+ date: '2026-03-22',
52
+ description: 'First stable release — plugin system and stable interface contract',
53
+ handoff_fields_added: ['plugin_api_version'],
54
+ handoff_fields_removed: [],
55
+ audit_fields_added: [],
56
+ breaking: [
57
+ 'VERIFY_PASS_RATE_WARNING_THRESHOLD in MINDFORGE.md is now 0.0-1.0 (was 0-100)',
58
+ 'AUDIT.jsonl session_id is now required (was optional)',
59
+ 'HANDOFF.json plugin_api_version field is now required for plugin compatibility',
60
+ ],
61
+ },
62
+ ];
63
+
64
+ module.exports = { SCHEMA_HISTORY };
@@ -0,0 +1,62 @@
1
+ /**
2
+ * MindForge — Changelog Fetcher
3
+ * Downloads and parses CHANGELOG.md entries between two versions.
4
+ * Used by /mindforge:update to show what changed.
5
+ */
6
+ 'use strict';
7
+
8
+ const { compareSemver } = require('./version-comparator');
9
+
10
+ const CHANGELOG_URL = 'https://raw.githubusercontent.com/mindforge-dev/mindforge/main/CHANGELOG.md';
11
+
12
+ /**
13
+ * Fetch CHANGELOG.md and extract entries between fromVersion and toVersion.
14
+ * Returns formatted markdown string, or null if unavailable.
15
+ */
16
+ async function fetchChangelog(fromVersion, toVersion) {
17
+ const raw = await fetchRaw();
18
+ if (!raw) return null;
19
+ return extractEntries(raw, fromVersion, toVersion);
20
+ }
21
+
22
+ async function fetchRaw() {
23
+ const https = require('https');
24
+ return new Promise(resolve => {
25
+ const req = https.get(CHANGELOG_URL, { timeout: 8000 }, res => {
26
+ if (res.statusCode !== 200) { resolve(null); return; }
27
+ let body = '';
28
+ res.setEncoding('utf8');
29
+ res.on('data', chunk => { body += chunk; });
30
+ res.on('end', () => resolve(body));
31
+ });
32
+ req.on('error', () => resolve(null));
33
+ req.on('timeout', () => { req.destroy(); resolve(null); });
34
+ });
35
+ }
36
+
37
+ /**
38
+ * Parse CHANGELOG.md and extract version sections in range (from, to].
39
+ */
40
+ function extractEntries(changelog, fromVersion, toVersion) {
41
+ const sections = [];
42
+ let current = null;
43
+
44
+ for (const line of changelog.split('\n')) {
45
+ const vMatch = line.match(/^## \[?v?(\d+\.\d+\.\d+)/);
46
+ if (vMatch) {
47
+ if (current) sections.push(current);
48
+ const v = vMatch[1];
49
+ const inRange = compareSemver(v, fromVersion) > 0 && compareSemver(v, toVersion) <= 0;
50
+ current = inRange ? { version: v, lines: [line] } : null;
51
+ } else if (current) {
52
+ current.lines.push(line);
53
+ }
54
+ }
55
+ if (current) sections.push(current);
56
+
57
+ return sections.length
58
+ ? sections.map(s => s.lines.join('\n').trimEnd()).join('\n\n')
59
+ : null;
60
+ }
61
+
62
+ module.exports = { fetchChangelog };
@@ -0,0 +1,169 @@
1
+ /**
2
+ * MindForge — Self-Update Engine
3
+ * Full update workflow: check → changelog → scope detection → apply → migrate → verify.
4
+ */
5
+ 'use strict';
6
+
7
+ const path = require('path');
8
+ const fs = require('fs');
9
+ const { execSync } = require('child_process');
10
+ const { compareSemver, upgradeType, fetchLatestVersion } = require('./version-comparator');
11
+ const { fetchChangelog } = require('./changelog-fetcher');
12
+
13
+ const CURRENT_VERSION = require('../../package.json').version;
14
+
15
+ /**
16
+ * Detect where MindForge was originally installed.
17
+ * Checks local before global (local installs take precedence).
18
+ * Returns { scope: 'local'|'global', runtime: 'claude'|'antigravity' }
19
+ */
20
+ function detectInstallScope() {
21
+ const home = process.env.HOME || process.env.USERPROFILE || '';
22
+ const cwd = process.cwd();
23
+
24
+ // Per ADR-019: local installs take precedence over global
25
+ const locations = [
26
+ { scope: 'local', runtime: 'claude', file: path.join(cwd, '.claude', 'CLAUDE.md') },
27
+ { scope: 'local', runtime: 'antigravity', file: path.join(cwd, '.agent', 'CLAUDE.md') },
28
+ { scope: 'global', runtime: 'claude', file: path.join(home, '.claude', 'CLAUDE.md') },
29
+ { scope: 'global', runtime: 'antigravity', file: path.join(home, '.gemini', 'antigravity', 'CLAUDE.md') },
30
+ ];
31
+
32
+ for (const loc of locations) {
33
+ if (fs.existsSync(loc.file) && fs.readFileSync(loc.file, 'utf8').includes('MindForge')) {
34
+ return { scope: loc.scope, runtime: loc.runtime };
35
+ }
36
+ }
37
+
38
+ // Default: global claude (most common installation)
39
+ return { scope: 'global', runtime: 'claude' };
40
+ }
41
+
42
+ /**
43
+ * Read the schema_version from HANDOFF.json.
44
+ * This is the authoritative "what version are the .planning files" source.
45
+ * Must be read BEFORE the update runs (after update, installer version = new).
46
+ */
47
+ function readHandoffSchemaVersion() {
48
+ const handoffPath = path.join(process.cwd(), '.planning', 'HANDOFF.json');
49
+ if (!fs.existsSync(handoffPath)) return null;
50
+ try {
51
+ const data = JSON.parse(fs.readFileSync(handoffPath, 'utf8'));
52
+ return data.schema_version || null;
53
+ } catch {
54
+ return null;
55
+ }
56
+ }
57
+
58
+ /**
59
+ * Main update entry point.
60
+ * Called by /mindforge:update command.
61
+ *
62
+ * options:
63
+ * apply {boolean} — actually apply the update (default: false = check only)
64
+ * force {boolean} — skip major-version safety warning
65
+ * skipChangelog {boolean} — skip changelog fetch
66
+ */
67
+ async function checkAndUpdate(options = {}) {
68
+ const { apply = false, force = false, skipChangelog = false } = options;
69
+ const isCI = process.env.CI === 'true' || process.env.MINDFORGE_CI === 'true';
70
+
71
+ const TTY = process.stdout.isTTY;
72
+ const bold = s => TTY ? `\x1b[1m${s}\x1b[0m` : s;
73
+ const warn = s => TTY ? `\x1b[33m${s}\x1b[0m` : s;
74
+ const ok = s => TTY ? `\x1b[32m${s}\x1b[0m` : s;
75
+ const err = s => TTY ? `\x1b[31m${s}\x1b[0m` : s;
76
+
77
+ console.log(`\n${bold('⚡ MindForge Update Check')}\n`);
78
+ console.log(` Current : v${CURRENT_VERSION}`);
79
+ process.stdout.write(` Latest : checking npm registry... `);
80
+
81
+ const latestVersion = await fetchLatestVersion();
82
+ if (!latestVersion) {
83
+ console.log(`${warn('unavailable')}`);
84
+ console.log(`\n ${warn('⚠️')} Cannot reach npm registry. Check your internet connection.`);
85
+ console.log(` Manual check: npm info mindforge-cc version\n`);
86
+ return { status: 'check-failed' };
87
+ }
88
+
89
+ const type = upgradeType(CURRENT_VERSION, latestVersion);
90
+ if (type === 'none') {
91
+ console.log(`${ok('up to date')}`);
92
+ console.log(`\n ${ok('✅')} v${CURRENT_VERSION} is the latest version.\n`);
93
+ return { status: 'up-to-date', current: CURRENT_VERSION };
94
+ }
95
+
96
+ console.log(`${ok(`v${latestVersion} available`)}`);
97
+ console.log(` Update : ${CURRENT_VERSION} → ${latestVersion} ${warn(`(${type})`)}`);
98
+
99
+ // Major version safety gate
100
+ if (type === 'major' && !force) {
101
+ console.log(`\n ${warn('⚠️ MAJOR UPDATE')} — may contain breaking changes.`);
102
+ console.log(` Review the changelog before applying.`);
103
+ console.log(` To apply anyway: /mindforge:update --apply --force\n`);
104
+ }
105
+
106
+ // Fetch and display changelog
107
+ if (!skipChangelog) {
108
+ process.stdout.write(`\n Fetching changelog... `);
109
+ const changelog = await fetchChangelog(CURRENT_VERSION, latestVersion);
110
+ if (changelog) {
111
+ console.log(`done\n`);
112
+ console.log('─'.repeat(62));
113
+ console.log(changelog.slice(0, 3000)); // Max 3000 chars to avoid flooding terminal
114
+ if (changelog.length > 3000) console.log(`\n [changelog truncated — see CHANGELOG.md for full details]`);
115
+ console.log('─'.repeat(62));
116
+ } else {
117
+ console.log(`unavailable\n`);
118
+ }
119
+ }
120
+
121
+ if (!apply) {
122
+ if (isCI) {
123
+ console.log(`\n CI mode: check-only (no apply without --apply)`);
124
+ }
125
+ console.log(`\n To apply: /mindforge:update --apply`);
126
+ console.log(` Or directly: npx mindforge-cc@${latestVersion} --update\n`);
127
+ return { status: 'update-available', current: CURRENT_VERSION, latest: latestVersion, type };
128
+ }
129
+
130
+ // ── Apply the update ────────────────────────────────────────────────────────
131
+
132
+ // Capture schema version BEFORE updating (critical for correct migration path)
133
+ const fromSchemaVersion = readHandoffSchemaVersion() || CURRENT_VERSION;
134
+ console.log(`\n Schema version: v${fromSchemaVersion}`);
135
+
136
+ // Detect original install scope to preserve it
137
+ const { scope, runtime } = detectInstallScope();
138
+ console.log(` Install scope : ${runtime} / ${scope}`);
139
+ console.log(`\n Applying update...`);
140
+
141
+ try {
142
+ execSync(
143
+ `npx mindforge-cc@${latestVersion} --${runtime} --${scope}`,
144
+ { stdio: 'inherit', timeout: 120_000 }
145
+ );
146
+ } catch (updateErr) {
147
+ console.error(`\n ${err('❌')} Update failed: ${updateErr.message}`);
148
+ console.error(` Fallback: npx mindforge-cc@${latestVersion} --${runtime} --${scope}`);
149
+ return { status: 'update-failed', error: updateErr.message };
150
+ }
151
+
152
+ // Run schema migration with the pre-update schema version
153
+ try {
154
+ const { runMigrations } = require('../migrations/migrate');
155
+ const migResult = await runMigrations(fromSchemaVersion, latestVersion);
156
+ if (migResult.status === 'migrated') {
157
+ console.log(` ✅ Schema migrated: v${fromSchemaVersion} → v${latestVersion}`);
158
+ }
159
+ } catch (migErr) {
160
+ console.warn(` ${warn('⚠️')} Schema migration had an issue: ${migErr.message}`);
161
+ console.warn(` Run /mindforge:migrate manually if state files look wrong.`);
162
+ }
163
+
164
+ console.log(`\n ${ok('✅')} MindForge updated to v${latestVersion}\n`);
165
+ console.log(` Run /mindforge:health to verify the update.\n`);
166
+ return { status: 'updated', from: CURRENT_VERSION, to: latestVersion };
167
+ }
168
+
169
+ module.exports = { checkAndUpdate, detectInstallScope, readHandoffSchemaVersion };
@@ -0,0 +1,68 @@
1
+ /**
2
+ * MindForge — Version Comparator
3
+ * Pure functions for semver comparison.
4
+ * No external dependencies — must work offline.
5
+ */
6
+ 'use strict';
7
+
8
+ /**
9
+ * Compare two semver strings (strips leading 'v').
10
+ * Returns: negative if a < b, 0 if a == b, positive if a > b
11
+ */
12
+ function compareSemver(a, b) {
13
+ const pa = a.replace(/^v/, '').split('.').map(Number);
14
+ const pb = b.replace(/^v/, '').split('.').map(Number);
15
+ for (let i = 0; i < 3; i++) {
16
+ const diff = (pa[i] || 0) - (pb[i] || 0);
17
+ if (diff !== 0) return diff;
18
+ }
19
+ return 0;
20
+ }
21
+
22
+ /**
23
+ * Determine the upgrade type between two versions.
24
+ * Returns 'major' | 'minor' | 'patch' | 'none'
25
+ */
26
+ function upgradeType(current, latest) {
27
+ const c = current.replace(/^v/, '').split('.').map(Number);
28
+ const l = latest.replace(/^v/, '').split('.').map(Number);
29
+ if (l[0] > c[0]) return 'major';
30
+ if (l[1] > c[1]) return 'minor';
31
+ if (l[2] > c[2]) return 'patch';
32
+ return 'none';
33
+ }
34
+
35
+ /**
36
+ * Fetch the latest published version from the npm registry.
37
+ * Returns null on any error — callers must handle gracefully.
38
+ * Timeout: 5 seconds (respects enterprise proxies that may be slow).
39
+ */
40
+ async function fetchLatestVersion(packageName = 'mindforge-cc') {
41
+ const https = require('https');
42
+ return new Promise(resolve => {
43
+ const options = {
44
+ hostname: 'registry.npmjs.org',
45
+ path: `/${encodeURIComponent(packageName)}/latest`,
46
+ method: 'GET',
47
+ headers: { 'Accept': 'application/json', 'User-Agent': `mindforge-cc/${require('../../package.json').version}` },
48
+ timeout: 5000,
49
+ };
50
+
51
+ const req = https.request(options, res => {
52
+ if (res.statusCode !== 200) { resolve(null); return; }
53
+ let body = '';
54
+ res.setEncoding('utf8');
55
+ res.on('data', chunk => { body += chunk; });
56
+ res.on('end', () => {
57
+ try { resolve(JSON.parse(body).version || null); }
58
+ catch { resolve(null); }
59
+ });
60
+ });
61
+
62
+ req.on('error', () => resolve(null));
63
+ req.on('timeout', () => { req.destroy(); resolve(null); });
64
+ req.end();
65
+ });
66
+ }
67
+
68
+ module.exports = { compareSemver, upgradeType, fetchLatestVersion };
@@ -0,0 +1,92 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * MindForge configuration validator
4
+ * Validates MINDFORGE.md against the JSON schema
5
+ * Usage: node bin/validate-config.js [path-to-MINDFORGE.md]
6
+ */
7
+
8
+ 'use strict';
9
+
10
+ const fs = require('fs');
11
+ const path = require('path');
12
+
13
+ const CONFIG_PATH = process.argv[2] || 'MINDFORGE.md';
14
+ const SCHEMA_PATH = '.mindforge/MINDFORGE-SCHEMA.json';
15
+
16
+ if (!fs.existsSync(CONFIG_PATH)) {
17
+ console.log('ℹ️ MINDFORGE.md not found — using all defaults. Create one to customise.');
18
+ process.exit(0);
19
+ }
20
+
21
+ if (!fs.existsSync(SCHEMA_PATH)) {
22
+ console.log('ℹ️ MINDFORGE-SCHEMA.json not found — skipping schema validation.');
23
+ process.exit(0);
24
+ }
25
+
26
+ const content = fs.readFileSync(CONFIG_PATH, 'utf8');
27
+ const schema = JSON.parse(fs.readFileSync(SCHEMA_PATH, 'utf8'));
28
+
29
+ const errors = [];
30
+ const warnings = [];
31
+
32
+ // Parse key=value pairs from MINDFORGE.md
33
+ const settings = {};
34
+ const lines = content.split('\n');
35
+ lines.forEach(line => {
36
+ const match = line.match(/^([A-Z_]+)=(.+)$/);
37
+ if (match) {
38
+ const [, key, value] = match;
39
+ settings[key] = value.trim();
40
+ }
41
+ });
42
+
43
+ // Validate against schema
44
+ for (const [key, def] of Object.entries(schema.properties || {})) {
45
+ const value = settings[key];
46
+
47
+ if (def.required && !value) {
48
+ errors.push(`${key} is required but not set`);
49
+ continue;
50
+ }
51
+
52
+ if (!value) continue;
53
+
54
+ if (def.type === 'number') {
55
+ const num = parseFloat(value);
56
+ if (isNaN(num)) errors.push(`${key}: expected number, got "${value}"`);
57
+ if (def.minimum !== undefined && num < def.minimum)
58
+ errors.push(`${key}: ${num} is below minimum ${def.minimum}`);
59
+ if (def.maximum !== undefined && num > def.maximum)
60
+ errors.push(`${key}: ${num} exceeds maximum ${def.maximum}`);
61
+ }
62
+
63
+ if (def.type === 'enum' && !def.values.includes(value)) {
64
+ errors.push(`${key}: "${value}" is not valid. Options: ${def.values.join(', ')}`);
65
+ }
66
+
67
+ if (def.type === 'boolean' && !['true','false'].includes(value)) {
68
+ errors.push(`${key}: expected true or false, got "${value}"`);
69
+ }
70
+
71
+ if (def.nonOverridable) {
72
+ warnings.push(`${key}: this is a non-overridable governance primitive (value will be ignored)`);
73
+ }
74
+ }
75
+
76
+ // Report
77
+ const total = errors.length + warnings.length;
78
+ if (total === 0) {
79
+ console.log(`✅ MINDFORGE.md valid — ${Object.keys(settings).length} settings configured`);
80
+ process.exit(0);
81
+ }
82
+
83
+ if (errors.length) {
84
+ console.error(`❌ MINDFORGE.md has ${errors.length} error(s):`);
85
+ errors.forEach(e => console.error(` • ${e}`));
86
+ }
87
+ if (warnings.length) {
88
+ console.warn(`⚠️ MINDFORGE.md has ${warnings.length} warning(s):`);
89
+ warnings.forEach(w => console.warn(` • ${w}`));
90
+ }
91
+
92
+ process.exit(errors.length ? 1 : 0);