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,403 @@
1
+ /**
2
+ * MindForge Skills Platform Tests
3
+ * Run: node tests/skills-platform.test.js
4
+ */
5
+
6
+ const fs = require('fs');
7
+ const path = require('path');
8
+ const assert = require('assert');
9
+
10
+ let passed = 0;
11
+ let failed = 0;
12
+
13
+ function test(name, fn) {
14
+ try {
15
+ fn();
16
+ console.log(` ✅ ${name}`);
17
+ passed++;
18
+ } catch (err) {
19
+ console.error(` ❌ ${name}`);
20
+ console.error(` ${err.message}`);
21
+ failed++;
22
+ }
23
+ }
24
+
25
+ // ── Skill frontmatter parser ──────────────────────────────────────────────────
26
+ function parseSkillFrontmatter(filePath) {
27
+ const content = fs.readFileSync(filePath, 'utf8');
28
+ if (!content.startsWith('---')) {
29
+ throw new Error(`${filePath}: missing frontmatter (must start with ---)`);
30
+ }
31
+ const end = content.indexOf('---', 3);
32
+ if (end === -1) throw new Error(`${filePath}: unclosed frontmatter`);
33
+ const fm = content.slice(3, end).trim();
34
+
35
+ const result = {};
36
+ fm.split('\n').forEach(line => {
37
+ const colon = line.indexOf(':');
38
+ if (colon === -1) return;
39
+ const key = line.slice(0, colon).trim();
40
+ const val = line.slice(colon + 1).trim();
41
+ result[key] = val;
42
+ });
43
+ return result;
44
+ }
45
+
46
+ // ── Semver validator ──────────────────────────────────────────────────────────
47
+ function isValidSemver(version) {
48
+ return /^\d+\.\d+\.\d+$/.test(version);
49
+ }
50
+
51
+ // ── Skills directory scanner ──────────────────────────────────────────────────
52
+ function getAllSkillPaths() {
53
+ const skillsDir = '.mindforge/skills';
54
+ if (!fs.existsSync(skillsDir)) return [];
55
+ return fs.readdirSync(skillsDir)
56
+ .map(dir => path.join(skillsDir, dir, 'SKILL.md'))
57
+ .filter(p => fs.existsSync(p));
58
+ }
59
+
60
+ // ── Manifest parser ───────────────────────────────────────────────────────────
61
+ function parseManifest() {
62
+ const manifestPath = '.mindforge/org/skills/MANIFEST.md';
63
+ if (!fs.existsSync(manifestPath)) return { skills: [] };
64
+ const content = fs.readFileSync(manifestPath, 'utf8');
65
+ const rows = content.match(/\|\s+(\S+)\s+\|\s+(\d+\.\d+\.\d+)\s+\|\s+(\w+)\s+\|\s+(\d+\.\d+\.\d+)\s+\|/g) || [];
66
+ return {
67
+ skills: rows.map(row => {
68
+ const parts = row.split('|').map(p => p.trim()).filter(Boolean);
69
+ return { name: parts[0], version: parts[1], status: parts[2] };
70
+ })
71
+ };
72
+ }
73
+
74
+ // ── Tests ─────────────────────────────────────────────────────────────────────
75
+
76
+ console.log('\nMindForge Day 3 — Skills Platform Tests\n');
77
+
78
+ console.log('Skills directory structure:');
79
+
80
+ test('skills directory exists', () => {
81
+ assert.ok(fs.existsSync('.mindforge/skills'), 'Missing .mindforge/skills/');
82
+ });
83
+
84
+ test('all 10 skill directories exist', () => {
85
+ const required = [
86
+ 'security-review', 'code-quality', 'api-design', 'testing-standards',
87
+ 'documentation', 'performance', 'accessibility', 'data-privacy',
88
+ 'incident-response', 'database-patterns'
89
+ ];
90
+ required.forEach(skill => {
91
+ const p = `.mindforge/skills/${skill}/SKILL.md`;
92
+ assert.ok(fs.existsSync(p), `Missing: ${p}`);
93
+ });
94
+ });
95
+
96
+ test('engine skills directory has all 4 engine files', () => {
97
+ const required = ['registry.md', 'loader.md', 'versioning.md', 'conflict-resolver.md'];
98
+ required.forEach(f => {
99
+ const p = `.mindforge/engine/skills/${f}`;
100
+ assert.ok(fs.existsSync(p), `Missing: ${p}`);
101
+ });
102
+ });
103
+
104
+ console.log('\nSkill frontmatter validation:');
105
+
106
+ const skillPaths = getAllSkillPaths();
107
+ test(`found ${skillPaths.length} skill files to validate`, () => {
108
+ assert.ok(skillPaths.length >= 10, `Expected >= 10 skill files, found ${skillPaths.length}`);
109
+ });
110
+
111
+ skillPaths.forEach(skillPath => {
112
+ const skillName = skillPath.split('/').slice(-2)[0];
113
+
114
+ test(`${skillName}: has valid frontmatter`, () => {
115
+ const fm = parseSkillFrontmatter(skillPath);
116
+ assert.ok(fm.name, 'Missing name field');
117
+ assert.ok(fm.version, 'Missing version field');
118
+ assert.ok(fm.status, 'Missing status field');
119
+ assert.ok(fm.triggers, 'Missing triggers field');
120
+ });
121
+
122
+ test(`${skillName}: name matches directory`, () => {
123
+ const fm = parseSkillFrontmatter(skillPath);
124
+ assert.strictEqual(fm.name, skillName, `Skill name "${fm.name}" doesn't match directory "${skillName}"`);
125
+ });
126
+
127
+ test(`${skillName}: version is valid semver`, () => {
128
+ const fm = parseSkillFrontmatter(skillPath);
129
+ assert.ok(isValidSemver(fm.version), `Invalid semver: "${fm.version}"`);
130
+ });
131
+
132
+ test(`${skillName}: has at least 10 trigger keywords`, () => {
133
+ const fm = parseSkillFrontmatter(skillPath);
134
+ const triggers = fm.triggers.split(',').map(t => t.trim()).filter(Boolean);
135
+ assert.ok(triggers.length >= 10, `Too few triggers: ${triggers.length} (min 10)`);
136
+ });
137
+
138
+ test(`${skillName}: status is a valid value`, () => {
139
+ const fm = parseSkillFrontmatter(skillPath);
140
+ const validStatuses = ['stable', 'beta', 'alpha', 'deprecated'];
141
+ assert.ok(validStatuses.includes(fm.status), `Invalid status: "${fm.status}"`);
142
+ });
143
+
144
+ test(`${skillName}: has mandatory actions section`, () => {
145
+ const content = fs.readFileSync(skillPath, 'utf8');
146
+ assert.ok(
147
+ content.includes('## Mandatory actions') || content.includes('mandatory actions'),
148
+ 'Missing mandatory actions section'
149
+ );
150
+ });
151
+
152
+ test(`${skillName}: has self-check or checklist section`, () => {
153
+ const content = fs.readFileSync(skillPath, 'utf8');
154
+ assert.ok(
155
+ content.includes('checklist') || content.includes('self-check') || content.includes('- [ ]'),
156
+ 'Missing checklist or self-check section'
157
+ );
158
+ });
159
+ });
160
+
161
+ console.log('\nManifest validation:');
162
+
163
+ test('MANIFEST.md exists', () => {
164
+ assert.ok(fs.existsSync('.mindforge/org/skills/MANIFEST.md'), 'Missing MANIFEST.md');
165
+ });
166
+
167
+ test('registry defines manifest path and missing-manifest handling', () => {
168
+ const registry = fs.readFileSync('.mindforge/engine/skills/registry.md', 'utf8');
169
+ assert.ok(
170
+ registry.includes('.mindforge/org/skills/MANIFEST.md'),
171
+ 'Registry missing explicit manifest path'
172
+ );
173
+ assert.ok(
174
+ registry.includes('MANIFEST.md was missing') || registry.includes('If MANIFEST.md does not exist'),
175
+ 'Registry missing missing-manifest handling'
176
+ );
177
+ });
178
+
179
+ test('MANIFEST.md registers all 10 core skills', () => {
180
+ const content = fs.readFileSync('.mindforge/org/skills/MANIFEST.md', 'utf8');
181
+ const requiredSkills = [
182
+ 'security-review', 'code-quality', 'api-design', 'testing-standards',
183
+ 'documentation', 'performance', 'accessibility', 'data-privacy',
184
+ 'incident-response', 'database-patterns'
185
+ ];
186
+ requiredSkills.forEach(skill => {
187
+ assert.ok(content.includes(skill), `MANIFEST.md missing skill: ${skill}`);
188
+ });
189
+ });
190
+
191
+ test('MANIFEST.md has schema version header', () => {
192
+ const content = fs.readFileSync('.mindforge/org/skills/MANIFEST.md', 'utf8');
193
+ assert.ok(content.includes('Schema version') || content.includes('schema version:'), 'Missing schema version');
194
+ });
195
+
196
+ console.log('\nTrigger keyword uniqueness (within Tier 1):');
197
+
198
+ test('no duplicate triggers between Tier 1 skills at exact match', () => {
199
+ const triggerMap = {};
200
+ const conflicts = [];
201
+
202
+ getAllSkillPaths().forEach(skillPath => {
203
+ const fm = parseSkillFrontmatter(skillPath);
204
+ const skillName = fm.name;
205
+ const triggers = fm.triggers.split(',').map(t => t.trim().toLowerCase()).filter(Boolean);
206
+
207
+ triggers.forEach(trigger => {
208
+ if (triggerMap[trigger] && triggerMap[trigger] !== skillName) {
209
+ conflicts.push(`"${trigger}": ${triggerMap[trigger]} vs ${skillName}`);
210
+ } else {
211
+ triggerMap[trigger] = skillName;
212
+ }
213
+ });
214
+ });
215
+
216
+ // Conflicts are allowed (Type 1 in conflict-resolver.md) but should be minimal
217
+ // Flag if more than 5 conflicts exist (suggests poor trigger hygiene)
218
+ assert.ok(
219
+ conflicts.length <= 5,
220
+ `Too many trigger conflicts (${conflicts.length} > 5): ${conflicts.slice(0, 3).join(', ')}`
221
+ );
222
+ });
223
+
224
+ console.log('\nPersona override system:');
225
+
226
+ test('personas/overrides directory exists', () => {
227
+ assert.ok(fs.existsSync('.mindforge/personas/overrides'), 'Missing personas/overrides directory');
228
+ });
229
+
230
+ test('personas/overrides/README.md exists and has content', () => {
231
+ const p = '.mindforge/personas/overrides/README.md';
232
+ assert.ok(fs.existsSync(p), 'Missing overrides README.md');
233
+ const content = fs.readFileSync(p, 'utf8');
234
+ assert.ok(content.length > 200, 'README.md too short');
235
+ assert.ok(content.includes('override'), 'README.md should explain overrides');
236
+ });
237
+
238
+ console.log('\nNew commands (21 total):');
239
+
240
+ const allCommands = [
241
+ 'help', 'init-project', 'plan-phase', 'execute-phase', 'verify-phase', 'ship', // Day 1
242
+ 'next', 'quick', 'status', 'debug', // Day 2
243
+ 'skills', 'review', 'security-scan', 'map-codebase', 'discuss-phase', // Day 3
244
+ 'audit', 'milestone', 'complete-milestone', 'approve', 'sync-jira', // Day 4
245
+ 'sync-confluence'
246
+ ];
247
+
248
+ test('all 21 commands exist in .claude/commands/mindforge/', () => {
249
+ allCommands.forEach(cmd => {
250
+ const p = `.claude/commands/mindforge/${cmd}.md`;
251
+ assert.ok(fs.existsSync(p), `Missing command: ${p}`);
252
+ });
253
+ });
254
+
255
+ test('all 21 commands mirrored to .agent/mindforge/', () => {
256
+ allCommands.forEach(cmd => {
257
+ const p = `.agent/mindforge/${cmd}.md`;
258
+ assert.ok(fs.existsSync(p), `Missing mirrored command: ${p}`);
259
+ });
260
+ });
261
+
262
+ test('command files are not empty', () => {
263
+ allCommands.forEach(cmd => {
264
+ const p = `.claude/commands/mindforge/${cmd}.md`;
265
+ if (fs.existsSync(p)) {
266
+ const size = fs.statSync(p).size;
267
+ assert.ok(size > 200, `Command file too small (${size} bytes): ${cmd}.md`);
268
+ }
269
+ });
270
+ });
271
+
272
+ test('command files include usage or step markers', () => {
273
+ allCommands.forEach(cmd => {
274
+ const p = `.claude/commands/mindforge/${cmd}.md`;
275
+ const content = fs.readFileSync(p, 'utf8');
276
+ const hasMarker = /Usage:|## Step|## Pre-check|Steps/gi.test(content);
277
+ assert.ok(hasMarker, `Command missing usage/steps markers: ${cmd}.md`);
278
+ });
279
+ });
280
+
281
+ console.log('\nSkills loader ordering:');
282
+
283
+ test('loader prioritizes tiers and protects security skill from summarisation', () => {
284
+ const content = fs.readFileSync('.mindforge/engine/skills/loader.md', 'utf8');
285
+ assert.ok(
286
+ content.includes('Project → Org → Core'),
287
+ 'Loader missing tier priority order'
288
+ );
289
+ assert.ok(
290
+ content.toLowerCase().includes('never summarise a security skill'),
291
+ 'Loader missing security summarisation rule'
292
+ );
293
+ });
294
+
295
+ console.log('\nHardening-prompted tests:');
296
+
297
+ test('all MANIFEST.md skill paths resolve to existing files', () => {
298
+ const content = fs.readFileSync('.mindforge/org/skills/MANIFEST.md', 'utf8');
299
+ const pathPattern = /\.mindforge\/skills\/[\w-]+\/SKILL\.md/g;
300
+ const paths = content.match(pathPattern) || [];
301
+ assert.ok(paths.length >= 10, `Expected >= 10 paths in manifest, found ${paths.length}`);
302
+ paths.forEach(p => {
303
+ assert.ok(fs.existsSync(p), `MANIFEST.md references missing file: ${p}`);
304
+ });
305
+ });
306
+
307
+ test('database-patterns SKILL.md has compound cursor documentation', () => {
308
+ const content = fs.readFileSync('.mindforge/skills/database-patterns/SKILL.md', 'utf8');
309
+ assert.ok(
310
+ content.includes('compound cursor') || content.includes('cursor_time') || content.includes('(created_at, id)'),
311
+ 'database-patterns should document compound cursor pagination'
312
+ );
313
+ });
314
+
315
+ test('skills loader has injection guard section', () => {
316
+ const content = fs.readFileSync('.mindforge/engine/skills/loader.md', 'utf8');
317
+ assert.ok(
318
+ content.includes('injection') || content.includes('IGNORE ALL PREVIOUS'),
319
+ 'Loader should have injection guard documentation'
320
+ );
321
+ });
322
+
323
+ test('skills loader has file-name matching', () => {
324
+ const content = fs.readFileSync('.mindforge/engine/skills/loader.md', 'utf8');
325
+ assert.ok(
326
+ content.includes('File NAME matching') || content.includes('file name') || content.includes('file-name'),
327
+ 'Loader should have file-name matching (not just directory matching)'
328
+ );
329
+ });
330
+
331
+ test('plan-phase command references CONTEXT.md', () => {
332
+ const content = fs.readFileSync('.claude/commands/mindforge/plan-phase.md', 'utf8');
333
+ assert.ok(
334
+ content.includes('CONTEXT.md'),
335
+ 'plan-phase should read CONTEXT.md from discuss-phase'
336
+ );
337
+ });
338
+
339
+ test('map-codebase has secret exclusion list', () => {
340
+ const content = fs.readFileSync('.claude/commands/mindforge/map-codebase.md', 'utf8');
341
+ assert.ok(
342
+ content.includes('.env') || content.includes('EXCLUDED') || content.includes('secret'),
343
+ 'map-codebase should exclude .env and secret files'
344
+ );
345
+ });
346
+
347
+ test('security-scan has visibility guidance', () => {
348
+ const content = fs.readFileSync('.claude/commands/mindforge/security-scan.md', 'utf8');
349
+ assert.ok(
350
+ content.includes('public repository') || content.includes('.gitignore'),
351
+ 'security-scan should mention report visibility guidance'
352
+ );
353
+ });
354
+
355
+ test('accessibility skill mentions reduced motion', () => {
356
+ const content = fs.readFileSync('.mindforge/skills/accessibility/SKILL.md', 'utf8');
357
+ assert.ok(
358
+ content.includes('reduced-motion') || content.includes('prefers-reduced-motion') || content.includes('reduced motion'),
359
+ 'Accessibility skill should cover reduced motion preference'
360
+ );
361
+ });
362
+
363
+ test('performance skill marks latency targets as adjustable', () => {
364
+ const content = fs.readFileSync('.mindforge/skills/performance/SKILL.md', 'utf8');
365
+ assert.ok(
366
+ content.includes('NFR') || content.includes('override') || content.includes('adjust'),
367
+ 'Performance skill should note that targets are adjustable per NFRs'
368
+ );
369
+ });
370
+
371
+ test('data-privacy skill covers consent withdrawal', () => {
372
+ const content = fs.readFileSync('.mindforge/skills/data-privacy/SKILL.md', 'utf8');
373
+ assert.ok(
374
+ content.includes('withdraw') || content.includes('withdrawal') || content.includes('opt-out'),
375
+ 'Data privacy skill should cover consent withdrawal requirement'
376
+ );
377
+ });
378
+
379
+ test('package.json version is at least 0.3.0', () => {
380
+ const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
381
+ const [major, minor, patch] = pkg.version.split('.').map(Number);
382
+ assert.ok(
383
+ major > 0 || (major === 0 && minor >= 3),
384
+ `package.json version ${pkg.version} should be >= 0.3.0 for Day 3 skill compatibility`
385
+ );
386
+ });
387
+
388
+ test('CHANGELOG.md exists and has 0.3.0 entry', () => {
389
+ assert.ok(fs.existsSync('CHANGELOG.md'), 'CHANGELOG.md should exist after Day 3');
390
+ const content = fs.readFileSync('CHANGELOG.md', 'utf8');
391
+ assert.ok(content.includes('0.3.0'), 'CHANGELOG.md should have a 0.3.0 entry');
392
+ });
393
+
394
+ // ── Results ───────────────────────────────────────────────────────────────────
395
+ console.log(`\n${'─'.repeat(50)}`);
396
+ console.log(`Results: ${passed} passed, ${failed} failed`);
397
+
398
+ if (failed > 0) {
399
+ console.error(`\n❌ ${failed} test(s) failed.\n`);
400
+ process.exit(1);
401
+ } else {
402
+ console.log(`\n✅ All skills platform tests passed.\n`);
403
+ }