maxsimcli 4.6.0 → 4.7.1

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 (234) hide show
  1. package/dist/assets/CHANGELOG.md +39 -0
  2. package/dist/cli.cjs +470 -961
  3. package/dist/cli.cjs.map +1 -1
  4. package/dist/{core-RRjCSt0G.cjs → core-D5zUr9cb.cjs} +4 -3
  5. package/dist/core-D5zUr9cb.cjs.map +1 -0
  6. package/dist/install.cjs +3 -195
  7. package/dist/install.cjs.map +1 -1
  8. package/dist/mcp-server.cjs +2853 -217
  9. package/dist/mcp-server.cjs.map +1 -1
  10. package/dist/{skills-MYlMkYNt.cjs → skills-CjFWZIGM.cjs} +6 -6
  11. package/dist/{skills-MYlMkYNt.cjs.map → skills-CjFWZIGM.cjs.map} +1 -1
  12. package/package.json +1 -7
  13. package/dist/.tsbuildinfo +0 -1
  14. package/dist/assets/dashboard/client/assets/index-C199D4Eb.css +0 -32
  15. package/dist/assets/dashboard/client/assets/index-nAXJLp0_.js +0 -233
  16. package/dist/assets/dashboard/client/index.html +0 -19
  17. package/dist/assets/dashboard/server.js +0 -78813
  18. package/dist/backend/index.d.ts +0 -4
  19. package/dist/backend/index.d.ts.map +0 -1
  20. package/dist/backend/index.js +0 -12
  21. package/dist/backend/index.js.map +0 -1
  22. package/dist/backend/lifecycle.d.ts +0 -13
  23. package/dist/backend/lifecycle.d.ts.map +0 -1
  24. package/dist/backend/lifecycle.js +0 -168
  25. package/dist/backend/lifecycle.js.map +0 -1
  26. package/dist/backend/server.d.ts +0 -13
  27. package/dist/backend/server.d.ts.map +0 -1
  28. package/dist/backend/server.js +0 -1013
  29. package/dist/backend/server.js.map +0 -1
  30. package/dist/backend/terminal.d.ts +0 -49
  31. package/dist/backend/terminal.d.ts.map +0 -1
  32. package/dist/backend/terminal.js +0 -209
  33. package/dist/backend/terminal.js.map +0 -1
  34. package/dist/backend/types.d.ts +0 -77
  35. package/dist/backend/types.d.ts.map +0 -1
  36. package/dist/backend/types.js +0 -6
  37. package/dist/backend/types.js.map +0 -1
  38. package/dist/backend-server.cjs +0 -80672
  39. package/dist/backend-server.cjs.map +0 -1
  40. package/dist/backend-server.d.cts +0 -2
  41. package/dist/backend-server.d.ts +0 -11
  42. package/dist/backend-server.d.ts.map +0 -1
  43. package/dist/backend-server.js +0 -43
  44. package/dist/backend-server.js.map +0 -1
  45. package/dist/cli.d.cts +0 -2
  46. package/dist/cli.d.ts +0 -7
  47. package/dist/cli.d.ts.map +0 -1
  48. package/dist/cli.js +0 -510
  49. package/dist/cli.js.map +0 -1
  50. package/dist/core/artefakte.d.ts +0 -12
  51. package/dist/core/artefakte.d.ts.map +0 -1
  52. package/dist/core/artefakte.js +0 -152
  53. package/dist/core/artefakte.js.map +0 -1
  54. package/dist/core/commands.d.ts +0 -26
  55. package/dist/core/commands.d.ts.map +0 -1
  56. package/dist/core/commands.js +0 -550
  57. package/dist/core/commands.js.map +0 -1
  58. package/dist/core/config.d.ts +0 -10
  59. package/dist/core/config.d.ts.map +0 -1
  60. package/dist/core/config.js +0 -143
  61. package/dist/core/config.js.map +0 -1
  62. package/dist/core/context-loader.d.ts +0 -21
  63. package/dist/core/context-loader.d.ts.map +0 -1
  64. package/dist/core/context-loader.js +0 -212
  65. package/dist/core/context-loader.js.map +0 -1
  66. package/dist/core/core.d.ts +0 -91
  67. package/dist/core/core.d.ts.map +0 -1
  68. package/dist/core/core.js +0 -823
  69. package/dist/core/core.js.map +0 -1
  70. package/dist/core/dashboard-launcher.d.ts +0 -56
  71. package/dist/core/dashboard-launcher.d.ts.map +0 -1
  72. package/dist/core/dashboard-launcher.js +0 -246
  73. package/dist/core/dashboard-launcher.js.map +0 -1
  74. package/dist/core/drift.d.ts +0 -37
  75. package/dist/core/drift.d.ts.map +0 -1
  76. package/dist/core/drift.js +0 -213
  77. package/dist/core/drift.js.map +0 -1
  78. package/dist/core/frontmatter.d.ts +0 -33
  79. package/dist/core/frontmatter.d.ts.map +0 -1
  80. package/dist/core/frontmatter.js +0 -193
  81. package/dist/core/frontmatter.js.map +0 -1
  82. package/dist/core/index.d.ts +0 -28
  83. package/dist/core/index.d.ts.map +0 -1
  84. package/dist/core/index.js +0 -189
  85. package/dist/core/index.js.map +0 -1
  86. package/dist/core/init.d.ts +0 -287
  87. package/dist/core/init.d.ts.map +0 -1
  88. package/dist/core/init.js +0 -816
  89. package/dist/core/init.js.map +0 -1
  90. package/dist/core/milestone.d.ts +0 -9
  91. package/dist/core/milestone.d.ts.map +0 -1
  92. package/dist/core/milestone.js +0 -230
  93. package/dist/core/milestone.js.map +0 -1
  94. package/dist/core/phase.d.ts +0 -53
  95. package/dist/core/phase.d.ts.map +0 -1
  96. package/dist/core/phase.js +0 -891
  97. package/dist/core/phase.js.map +0 -1
  98. package/dist/core/roadmap.d.ts +0 -10
  99. package/dist/core/roadmap.d.ts.map +0 -1
  100. package/dist/core/roadmap.js +0 -165
  101. package/dist/core/roadmap.js.map +0 -1
  102. package/dist/core/skills.d.ts +0 -20
  103. package/dist/core/skills.d.ts.map +0 -1
  104. package/dist/core/skills.js +0 -144
  105. package/dist/core/skills.js.map +0 -1
  106. package/dist/core/start.d.ts +0 -15
  107. package/dist/core/start.d.ts.map +0 -1
  108. package/dist/core/start.js +0 -80
  109. package/dist/core/start.js.map +0 -1
  110. package/dist/core/state.d.ts +0 -32
  111. package/dist/core/state.d.ts.map +0 -1
  112. package/dist/core/state.js +0 -582
  113. package/dist/core/state.js.map +0 -1
  114. package/dist/core/template.d.ts +0 -30
  115. package/dist/core/template.d.ts.map +0 -1
  116. package/dist/core/template.js +0 -223
  117. package/dist/core/template.js.map +0 -1
  118. package/dist/core/types.d.ts +0 -519
  119. package/dist/core/types.d.ts.map +0 -1
  120. package/dist/core/types.js +0 -60
  121. package/dist/core/types.js.map +0 -1
  122. package/dist/core/verify.d.ts +0 -128
  123. package/dist/core/verify.d.ts.map +0 -1
  124. package/dist/core/verify.js +0 -754
  125. package/dist/core/verify.js.map +0 -1
  126. package/dist/core-RRjCSt0G.cjs.map +0 -1
  127. package/dist/esm-iIOBzmdz.cjs +0 -1561
  128. package/dist/esm-iIOBzmdz.cjs.map +0 -1
  129. package/dist/hooks/index.d.ts +0 -11
  130. package/dist/hooks/index.d.ts.map +0 -1
  131. package/dist/hooks/index.js +0 -18
  132. package/dist/hooks/index.js.map +0 -1
  133. package/dist/hooks/maxsim-check-update.d.ts +0 -17
  134. package/dist/hooks/maxsim-check-update.d.ts.map +0 -1
  135. package/dist/hooks/maxsim-check-update.js +0 -101
  136. package/dist/hooks/maxsim-check-update.js.map +0 -1
  137. package/dist/hooks/maxsim-context-monitor.d.ts +0 -21
  138. package/dist/hooks/maxsim-context-monitor.d.ts.map +0 -1
  139. package/dist/hooks/maxsim-context-monitor.js +0 -131
  140. package/dist/hooks/maxsim-context-monitor.js.map +0 -1
  141. package/dist/hooks/maxsim-statusline.d.ts +0 -19
  142. package/dist/hooks/maxsim-statusline.d.ts.map +0 -1
  143. package/dist/hooks/maxsim-statusline.js +0 -146
  144. package/dist/hooks/maxsim-statusline.js.map +0 -1
  145. package/dist/hooks/shared.d.ts +0 -11
  146. package/dist/hooks/shared.d.ts.map +0 -1
  147. package/dist/hooks/shared.js +0 -29
  148. package/dist/hooks/shared.js.map +0 -1
  149. package/dist/index.d.ts +0 -2
  150. package/dist/index.d.ts.map +0 -1
  151. package/dist/index.js +0 -3
  152. package/dist/index.js.map +0 -1
  153. package/dist/install/adapters.d.ts +0 -6
  154. package/dist/install/adapters.d.ts.map +0 -1
  155. package/dist/install/adapters.js +0 -65
  156. package/dist/install/adapters.js.map +0 -1
  157. package/dist/install/copy.d.ts +0 -6
  158. package/dist/install/copy.d.ts.map +0 -1
  159. package/dist/install/copy.js +0 -71
  160. package/dist/install/copy.js.map +0 -1
  161. package/dist/install/dashboard.d.ts +0 -16
  162. package/dist/install/dashboard.d.ts.map +0 -1
  163. package/dist/install/dashboard.js +0 -273
  164. package/dist/install/dashboard.js.map +0 -1
  165. package/dist/install/hooks.d.ts +0 -31
  166. package/dist/install/hooks.d.ts.map +0 -1
  167. package/dist/install/hooks.js +0 -260
  168. package/dist/install/hooks.js.map +0 -1
  169. package/dist/install/index.d.ts +0 -2
  170. package/dist/install/index.d.ts.map +0 -1
  171. package/dist/install/index.js +0 -534
  172. package/dist/install/index.js.map +0 -1
  173. package/dist/install/manifest.d.ts +0 -23
  174. package/dist/install/manifest.d.ts.map +0 -1
  175. package/dist/install/manifest.js +0 -133
  176. package/dist/install/manifest.js.map +0 -1
  177. package/dist/install/patches.d.ts +0 -10
  178. package/dist/install/patches.d.ts.map +0 -1
  179. package/dist/install/patches.js +0 -124
  180. package/dist/install/patches.js.map +0 -1
  181. package/dist/install/shared.d.ts +0 -56
  182. package/dist/install/shared.d.ts.map +0 -1
  183. package/dist/install/shared.js +0 -181
  184. package/dist/install/shared.js.map +0 -1
  185. package/dist/install/uninstall.d.ts +0 -5
  186. package/dist/install/uninstall.d.ts.map +0 -1
  187. package/dist/install/uninstall.js +0 -222
  188. package/dist/install/uninstall.js.map +0 -1
  189. package/dist/install/utils.d.ts +0 -27
  190. package/dist/install/utils.d.ts.map +0 -1
  191. package/dist/install/utils.js +0 -99
  192. package/dist/install/utils.js.map +0 -1
  193. package/dist/install.d.cts +0 -2
  194. package/dist/lifecycle-DxCru7rk.cjs +0 -136
  195. package/dist/lifecycle-DxCru7rk.cjs.map +0 -1
  196. package/dist/mcp/config-tools.d.ts +0 -13
  197. package/dist/mcp/config-tools.d.ts.map +0 -1
  198. package/dist/mcp/config-tools.js +0 -66
  199. package/dist/mcp/config-tools.js.map +0 -1
  200. package/dist/mcp/context-tools.d.ts +0 -13
  201. package/dist/mcp/context-tools.d.ts.map +0 -1
  202. package/dist/mcp/context-tools.js +0 -176
  203. package/dist/mcp/context-tools.js.map +0 -1
  204. package/dist/mcp/index.d.ts +0 -11
  205. package/dist/mcp/index.d.ts.map +0 -1
  206. package/dist/mcp/index.js +0 -26
  207. package/dist/mcp/index.js.map +0 -1
  208. package/dist/mcp/phase-tools.d.ts +0 -13
  209. package/dist/mcp/phase-tools.d.ts.map +0 -1
  210. package/dist/mcp/phase-tools.js +0 -177
  211. package/dist/mcp/phase-tools.js.map +0 -1
  212. package/dist/mcp/roadmap-tools.d.ts +0 -13
  213. package/dist/mcp/roadmap-tools.d.ts.map +0 -1
  214. package/dist/mcp/roadmap-tools.js +0 -79
  215. package/dist/mcp/roadmap-tools.js.map +0 -1
  216. package/dist/mcp/state-tools.d.ts +0 -13
  217. package/dist/mcp/state-tools.d.ts.map +0 -1
  218. package/dist/mcp/state-tools.js +0 -185
  219. package/dist/mcp/state-tools.js.map +0 -1
  220. package/dist/mcp/todo-tools.d.ts +0 -13
  221. package/dist/mcp/todo-tools.d.ts.map +0 -1
  222. package/dist/mcp/todo-tools.js +0 -143
  223. package/dist/mcp/todo-tools.js.map +0 -1
  224. package/dist/mcp/utils.d.ts +0 -27
  225. package/dist/mcp/utils.d.ts.map +0 -1
  226. package/dist/mcp/utils.js +0 -82
  227. package/dist/mcp/utils.js.map +0 -1
  228. package/dist/mcp-server.d.cts +0 -2
  229. package/dist/mcp-server.d.ts +0 -12
  230. package/dist/mcp-server.d.ts.map +0 -1
  231. package/dist/mcp-server.js +0 -31
  232. package/dist/mcp-server.js.map +0 -1
  233. package/dist/server-By0TN-nC.cjs +0 -2995
  234. package/dist/server-By0TN-nC.cjs.map +0 -1
@@ -1,754 +0,0 @@
1
- "use strict";
2
- /**
3
- * Verify — Verification suite, consistency, and health validation
4
- *
5
- * Ported from maxsim/bin/lib/verify.cjs
6
- */
7
- var __importDefault = (this && this.__importDefault) || function (mod) {
8
- return (mod && mod.__esModule) ? mod : { "default": mod };
9
- };
10
- Object.defineProperty(exports, "__esModule", { value: true });
11
- exports.cmdVerifySummary = cmdVerifySummary;
12
- exports.cmdVerifyPlanStructure = cmdVerifyPlanStructure;
13
- exports.cmdVerifyPhaseCompleteness = cmdVerifyPhaseCompleteness;
14
- exports.cmdVerifyReferences = cmdVerifyReferences;
15
- exports.cmdVerifyCommits = cmdVerifyCommits;
16
- exports.cmdVerifyArtifacts = cmdVerifyArtifacts;
17
- exports.cmdVerifyKeyLinks = cmdVerifyKeyLinks;
18
- exports.cmdValidateConsistency = cmdValidateConsistency;
19
- exports.cmdValidateHealth = cmdValidateHealth;
20
- const node_fs_1 = __importDefault(require("node:fs"));
21
- const node_path_1 = __importDefault(require("node:path"));
22
- const core_js_1 = require("./core.js");
23
- const frontmatter_js_1 = require("./frontmatter.js");
24
- const types_js_1 = require("./types.js");
25
- // ─── Verify Summary ──────────────────────────────────────────────────────────
26
- async function cmdVerifySummary(cwd, summaryPath, checkFileCount) {
27
- if (!summaryPath) {
28
- return (0, types_js_1.cmdErr)('summary-path required');
29
- }
30
- const fullPath = node_path_1.default.join(cwd, summaryPath);
31
- const checkCount = checkFileCount || 2;
32
- if (!node_fs_1.default.existsSync(fullPath)) {
33
- const result = {
34
- passed: false,
35
- checks: {
36
- summary_exists: false,
37
- files_created: { checked: 0, found: 0, missing: [] },
38
- commits_exist: false,
39
- self_check: 'not_found',
40
- },
41
- errors: ['SUMMARY.md not found'],
42
- };
43
- return (0, types_js_1.cmdOk)(result, 'failed');
44
- }
45
- const content = node_fs_1.default.readFileSync(fullPath, 'utf-8');
46
- const errors = [];
47
- // Spot-check files mentioned in summary
48
- const mentionedFiles = new Set();
49
- const patterns = [
50
- /`([^`]+\.[a-zA-Z]+)`/g,
51
- /(?:Created|Modified|Added|Updated|Edited):\s*`?([^\s`]+\.[a-zA-Z]+)`?/gi,
52
- ];
53
- for (const pattern of patterns) {
54
- let m;
55
- while ((m = pattern.exec(content)) !== null) {
56
- const filePath = m[1];
57
- if (filePath && !filePath.startsWith('http') && filePath.includes('/')) {
58
- mentionedFiles.add(filePath);
59
- }
60
- }
61
- }
62
- const filesToCheck = Array.from(mentionedFiles).slice(0, checkCount);
63
- const missing = [];
64
- for (const file of filesToCheck) {
65
- if (!node_fs_1.default.existsSync(node_path_1.default.join(cwd, file))) {
66
- missing.push(file);
67
- }
68
- }
69
- // Check commits exist
70
- const commitHashPattern = /\b[0-9a-f]{7,40}\b/g;
71
- const hashes = content.match(commitHashPattern) || [];
72
- let commitsExist = false;
73
- if (hashes.length > 0) {
74
- for (const hash of hashes.slice(0, 3)) {
75
- const result = await (0, core_js_1.execGit)(cwd, ['cat-file', '-t', hash]);
76
- if (result.exitCode === 0 && result.stdout === 'commit') {
77
- commitsExist = true;
78
- break;
79
- }
80
- }
81
- }
82
- // Self-check section
83
- let selfCheck = 'not_found';
84
- const selfCheckPattern = /##\s*(?:Self[- ]?Check|Verification|Quality Check)/i;
85
- if (selfCheckPattern.test(content)) {
86
- const passPattern = /(?:all\s+)?(?:pass|✓|✅|complete|succeeded)/i;
87
- const failPattern = /(?:fail|✗|❌|incomplete|blocked)/i;
88
- const checkSection = content.slice(content.search(selfCheckPattern));
89
- if (failPattern.test(checkSection)) {
90
- selfCheck = 'failed';
91
- }
92
- else if (passPattern.test(checkSection)) {
93
- selfCheck = 'passed';
94
- }
95
- }
96
- if (missing.length > 0)
97
- errors.push('Missing files: ' + missing.join(', '));
98
- if (!commitsExist && hashes.length > 0)
99
- errors.push('Referenced commit hashes not found in git history');
100
- if (selfCheck === 'failed')
101
- errors.push('Self-check section indicates failure');
102
- const checks = {
103
- summary_exists: true,
104
- files_created: { checked: filesToCheck.length, found: filesToCheck.length - missing.length, missing },
105
- commits_exist: commitsExist,
106
- self_check: selfCheck,
107
- };
108
- const passed = missing.length === 0 && selfCheck !== 'failed';
109
- const result = { passed, checks, errors };
110
- return (0, types_js_1.cmdOk)(result, passed ? 'passed' : 'failed');
111
- }
112
- // ─── Verify Plan Structure ───────────────────────────────────────────────────
113
- function cmdVerifyPlanStructure(cwd, filePath) {
114
- if (!filePath) {
115
- return (0, types_js_1.cmdErr)('file path required');
116
- }
117
- const fullPath = node_path_1.default.isAbsolute(filePath) ? filePath : node_path_1.default.join(cwd, filePath);
118
- const content = (0, core_js_1.safeReadFile)(fullPath);
119
- if (!content) {
120
- return (0, types_js_1.cmdOk)({ error: 'File not found', path: filePath });
121
- }
122
- const fm = (0, frontmatter_js_1.extractFrontmatter)(content);
123
- const errors = [];
124
- const warnings = [];
125
- const required = ['phase', 'plan', 'type', 'wave', 'depends_on', 'files_modified', 'autonomous', 'must_haves'];
126
- for (const field of required) {
127
- if (fm[field] === undefined)
128
- errors.push(`Missing required frontmatter field: ${field}`);
129
- }
130
- const taskPattern = /<task[^>]*>([\s\S]*?)<\/task>/g;
131
- const tasks = [];
132
- let taskMatch;
133
- while ((taskMatch = taskPattern.exec(content)) !== null) {
134
- const taskContent = taskMatch[1];
135
- const nameMatch = taskContent.match(/<name>([\s\S]*?)<\/name>/);
136
- const taskName = nameMatch ? nameMatch[1].trim() : 'unnamed';
137
- const hasFiles = /<files>/.test(taskContent);
138
- const hasAction = /<action>/.test(taskContent);
139
- const hasVerify = /<verify>/.test(taskContent);
140
- const hasDone = /<done>/.test(taskContent);
141
- if (!nameMatch)
142
- errors.push('Task missing <name> element');
143
- if (!hasAction)
144
- errors.push(`Task '${taskName}' missing <action>`);
145
- if (!hasVerify)
146
- warnings.push(`Task '${taskName}' missing <verify>`);
147
- if (!hasDone)
148
- warnings.push(`Task '${taskName}' missing <done>`);
149
- if (!hasFiles)
150
- warnings.push(`Task '${taskName}' missing <files>`);
151
- tasks.push({ name: taskName, hasFiles, hasAction, hasVerify, hasDone });
152
- }
153
- if (tasks.length === 0)
154
- warnings.push('No <task> elements found');
155
- if (fm.wave && parseInt(String(fm.wave)) > 1 && (!fm.depends_on || (Array.isArray(fm.depends_on) && fm.depends_on.length === 0))) {
156
- warnings.push('Wave > 1 but depends_on is empty');
157
- }
158
- const hasCheckpoints = /<task\s+type=["']?checkpoint/.test(content);
159
- if (hasCheckpoints && fm.autonomous !== 'false' && fm.autonomous !== false) {
160
- errors.push('Has checkpoint tasks but autonomous is not false');
161
- }
162
- const result = {
163
- valid: errors.length === 0,
164
- errors,
165
- warnings,
166
- task_count: tasks.length,
167
- tasks,
168
- frontmatter_fields: Object.keys(fm),
169
- };
170
- return (0, types_js_1.cmdOk)(result, errors.length === 0 ? 'valid' : 'invalid');
171
- }
172
- // ─── Verify Phase Completeness ───────────────────────────────────────────────
173
- function cmdVerifyPhaseCompleteness(cwd, phase) {
174
- if (!phase) {
175
- return (0, types_js_1.cmdErr)('phase required');
176
- }
177
- const phaseInfo = (0, core_js_1.findPhaseInternal)(cwd, phase);
178
- if (!phaseInfo) {
179
- return (0, types_js_1.cmdOk)({ error: 'Phase not found', phase });
180
- }
181
- const errors = [];
182
- const warnings = [];
183
- const phaseDir = node_path_1.default.join(cwd, phaseInfo.directory);
184
- let files;
185
- try {
186
- files = node_fs_1.default.readdirSync(phaseDir);
187
- }
188
- catch {
189
- return (0, types_js_1.cmdOk)({ error: 'Cannot read phase directory' });
190
- }
191
- const plans = files.filter(f => (0, core_js_1.isPlanFile)(f));
192
- const summaries = files.filter(f => (0, core_js_1.isSummaryFile)(f));
193
- const planIds = new Set(plans.map(p => (0, core_js_1.planId)(p)));
194
- const summaryIds = new Set(summaries.map(s => (0, core_js_1.summaryId)(s)));
195
- const incompletePlans = [...planIds].filter(id => !summaryIds.has(id));
196
- if (incompletePlans.length > 0) {
197
- errors.push(`Plans without summaries: ${incompletePlans.join(', ')}`);
198
- }
199
- const orphanSummaries = [...summaryIds].filter(id => !planIds.has(id));
200
- if (orphanSummaries.length > 0) {
201
- warnings.push(`Summaries without plans: ${orphanSummaries.join(', ')}`);
202
- }
203
- const result = {
204
- complete: errors.length === 0,
205
- phase: phaseInfo.phase_number,
206
- plan_count: plans.length,
207
- summary_count: summaries.length,
208
- incomplete_plans: incompletePlans,
209
- orphan_summaries: orphanSummaries,
210
- errors,
211
- warnings,
212
- };
213
- return (0, types_js_1.cmdOk)(result, errors.length === 0 ? 'complete' : 'incomplete');
214
- }
215
- // ─── Verify References ───────────────────────────────────────────────────────
216
- function cmdVerifyReferences(cwd, filePath) {
217
- if (!filePath) {
218
- return (0, types_js_1.cmdErr)('file path required');
219
- }
220
- const fullPath = node_path_1.default.isAbsolute(filePath) ? filePath : node_path_1.default.join(cwd, filePath);
221
- const content = (0, core_js_1.safeReadFile)(fullPath);
222
- if (!content) {
223
- return (0, types_js_1.cmdOk)({ error: 'File not found', path: filePath });
224
- }
225
- const found = [];
226
- const missing = [];
227
- const atRefs = content.match(/@([^\s\n,)]+\/[^\s\n,)]+)/g) || [];
228
- for (const ref of atRefs) {
229
- const cleanRef = ref.slice(1);
230
- const resolved = cleanRef.startsWith('~/')
231
- ? node_path_1.default.join(process.env.HOME || '', cleanRef.slice(2))
232
- : node_path_1.default.join(cwd, cleanRef);
233
- if (node_fs_1.default.existsSync(resolved)) {
234
- found.push(cleanRef);
235
- }
236
- else {
237
- missing.push(cleanRef);
238
- }
239
- }
240
- const backtickRefs = content.match(/`([^`]+\/[^`]+\.[a-zA-Z]{1,10})`/g) || [];
241
- for (const ref of backtickRefs) {
242
- const cleanRef = ref.slice(1, -1);
243
- if (cleanRef.startsWith('http') || cleanRef.includes('${') || cleanRef.includes('{{'))
244
- continue;
245
- if (found.includes(cleanRef) || missing.includes(cleanRef))
246
- continue;
247
- const resolved = node_path_1.default.join(cwd, cleanRef);
248
- if (node_fs_1.default.existsSync(resolved)) {
249
- found.push(cleanRef);
250
- }
251
- else {
252
- missing.push(cleanRef);
253
- }
254
- }
255
- const result = {
256
- valid: missing.length === 0,
257
- found: found.length,
258
- missing,
259
- total: found.length + missing.length,
260
- };
261
- return (0, types_js_1.cmdOk)(result, missing.length === 0 ? 'valid' : 'invalid');
262
- }
263
- // ─── Verify Commits ──────────────────────────────────────────────────────────
264
- async function cmdVerifyCommits(cwd, hashes) {
265
- if (!hashes || hashes.length === 0) {
266
- return (0, types_js_1.cmdErr)('At least one commit hash required');
267
- }
268
- const valid = [];
269
- const invalid = [];
270
- for (const hash of hashes) {
271
- const result = await (0, core_js_1.execGit)(cwd, ['cat-file', '-t', hash]);
272
- if (result.exitCode === 0 && result.stdout.trim() === 'commit') {
273
- valid.push(hash);
274
- }
275
- else {
276
- invalid.push(hash);
277
- }
278
- }
279
- const commitResult = {
280
- all_valid: invalid.length === 0,
281
- valid,
282
- invalid,
283
- total: hashes.length,
284
- };
285
- return (0, types_js_1.cmdOk)(commitResult, invalid.length === 0 ? 'valid' : 'invalid');
286
- }
287
- function cmdVerifyArtifacts(cwd, planFilePath) {
288
- if (!planFilePath) {
289
- return (0, types_js_1.cmdErr)('plan file path required');
290
- }
291
- const fullPath = node_path_1.default.isAbsolute(planFilePath) ? planFilePath : node_path_1.default.join(cwd, planFilePath);
292
- const content = (0, core_js_1.safeReadFile)(fullPath);
293
- if (!content) {
294
- return (0, types_js_1.cmdOk)({ error: 'File not found', path: planFilePath });
295
- }
296
- const artifacts = (0, frontmatter_js_1.parseMustHavesBlock)(content, 'artifacts');
297
- if (artifacts.length === 0) {
298
- return (0, types_js_1.cmdOk)({ error: 'No must_haves.artifacts found in frontmatter', path: planFilePath });
299
- }
300
- const results = [];
301
- for (const artifact of artifacts) {
302
- if (typeof artifact === 'string')
303
- continue;
304
- const artObj = artifact;
305
- const artPath = artObj.path;
306
- if (!artPath)
307
- continue;
308
- const artFullPath = node_path_1.default.join(cwd, artPath);
309
- const exists = node_fs_1.default.existsSync(artFullPath);
310
- const check = { path: artPath, exists, issues: [], passed: false };
311
- if (exists) {
312
- const fileContent = (0, core_js_1.safeReadFile)(artFullPath) || '';
313
- const lineCount = fileContent.split('\n').length;
314
- if (artObj.min_lines && lineCount < artObj.min_lines) {
315
- check.issues.push(`Only ${lineCount} lines, need ${artObj.min_lines}`);
316
- }
317
- if (artObj.contains && !fileContent.includes(artObj.contains)) {
318
- check.issues.push(`Missing pattern: ${artObj.contains}`);
319
- }
320
- if (artObj.exports) {
321
- const exportList = Array.isArray(artObj.exports) ? artObj.exports : [artObj.exports];
322
- for (const exp of exportList) {
323
- if (!fileContent.includes(exp))
324
- check.issues.push(`Missing export: ${exp}`);
325
- }
326
- }
327
- check.passed = check.issues.length === 0;
328
- }
329
- else {
330
- check.issues.push('File not found');
331
- }
332
- results.push(check);
333
- }
334
- const passed = results.filter(r => r.passed).length;
335
- const artifactsResult = {
336
- all_passed: passed === results.length,
337
- passed,
338
- total: results.length,
339
- artifacts: results,
340
- };
341
- return (0, types_js_1.cmdOk)(artifactsResult, passed === results.length ? 'valid' : 'invalid');
342
- }
343
- function cmdVerifyKeyLinks(cwd, planFilePath) {
344
- if (!planFilePath) {
345
- return (0, types_js_1.cmdErr)('plan file path required');
346
- }
347
- const fullPath = node_path_1.default.isAbsolute(planFilePath) ? planFilePath : node_path_1.default.join(cwd, planFilePath);
348
- const content = (0, core_js_1.safeReadFile)(fullPath);
349
- if (!content) {
350
- return (0, types_js_1.cmdOk)({ error: 'File not found', path: planFilePath });
351
- }
352
- const keyLinks = (0, frontmatter_js_1.parseMustHavesBlock)(content, 'key_links');
353
- if (keyLinks.length === 0) {
354
- return (0, types_js_1.cmdOk)({ error: 'No must_haves.key_links found in frontmatter', path: planFilePath });
355
- }
356
- const results = [];
357
- for (const link of keyLinks) {
358
- if (typeof link === 'string')
359
- continue;
360
- const linkObj = link;
361
- const check = {
362
- from: linkObj.from || '',
363
- to: linkObj.to || '',
364
- via: linkObj.via || '',
365
- verified: false,
366
- detail: '',
367
- };
368
- const sourceContent = (0, core_js_1.safeReadFile)(node_path_1.default.join(cwd, linkObj.from || ''));
369
- if (!sourceContent) {
370
- check.detail = 'Source file not found';
371
- }
372
- else if (linkObj.pattern) {
373
- try {
374
- const regex = new RegExp(linkObj.pattern);
375
- if (regex.test(sourceContent)) {
376
- check.verified = true;
377
- check.detail = 'Pattern found in source';
378
- }
379
- else {
380
- const targetContent = (0, core_js_1.safeReadFile)(node_path_1.default.join(cwd, linkObj.to || ''));
381
- if (targetContent && regex.test(targetContent)) {
382
- check.verified = true;
383
- check.detail = 'Pattern found in target';
384
- }
385
- else {
386
- check.detail = `Pattern "${linkObj.pattern}" not found in source or target`;
387
- }
388
- }
389
- }
390
- catch {
391
- check.detail = `Invalid regex pattern: ${linkObj.pattern}`;
392
- }
393
- }
394
- else {
395
- if (sourceContent.includes(linkObj.to || '')) {
396
- check.verified = true;
397
- check.detail = 'Target referenced in source';
398
- }
399
- else {
400
- check.detail = 'Target not referenced in source';
401
- }
402
- }
403
- results.push(check);
404
- }
405
- const verified = results.filter(r => r.verified).length;
406
- const linksResult = {
407
- all_verified: verified === results.length,
408
- verified,
409
- total: results.length,
410
- links: results,
411
- };
412
- return (0, types_js_1.cmdOk)(linksResult, verified === results.length ? 'valid' : 'invalid');
413
- }
414
- // ─── Validate Consistency ────────────────────────────────────────────────────
415
- function cmdValidateConsistency(cwd) {
416
- const rmPath = (0, core_js_1.roadmapPath)(cwd);
417
- const phasesDir = (0, core_js_1.phasesPath)(cwd);
418
- const errors = [];
419
- const warnings = [];
420
- if (!node_fs_1.default.existsSync(rmPath)) {
421
- errors.push('ROADMAP.md not found');
422
- return (0, types_js_1.cmdOk)({ passed: false, errors, warnings }, 'failed');
423
- }
424
- const roadmapContent = node_fs_1.default.readFileSync(rmPath, 'utf-8');
425
- const roadmapPhases = new Set();
426
- const phasePattern = (0, core_js_1.getPhasePattern)();
427
- let m;
428
- while ((m = phasePattern.exec(roadmapContent)) !== null) {
429
- roadmapPhases.add(m[1]);
430
- }
431
- const diskPhases = new Set();
432
- try {
433
- const dirs = (0, core_js_1.listSubDirs)(phasesDir);
434
- for (const dir of dirs) {
435
- const dm = dir.match(/^(\d+[A-Z]?(?:\.\d+)?)/i);
436
- if (dm)
437
- diskPhases.add(dm[1]);
438
- }
439
- }
440
- catch (e) {
441
- /* optional op, ignore */
442
- (0, core_js_1.debugLog)(e);
443
- }
444
- for (const p of roadmapPhases) {
445
- if (!diskPhases.has(p) && !diskPhases.has((0, core_js_1.normalizePhaseName)(p))) {
446
- warnings.push(`Phase ${p} in ROADMAP.md but no directory on disk`);
447
- }
448
- }
449
- for (const p of diskPhases) {
450
- const unpadded = String(parseInt(p, 10));
451
- if (!roadmapPhases.has(p) && !roadmapPhases.has(unpadded)) {
452
- warnings.push(`Phase ${p} exists on disk but not in ROADMAP.md`);
453
- }
454
- }
455
- const integerPhases = [...diskPhases]
456
- .filter(p => !p.includes('.'))
457
- .map(p => parseInt(p, 10))
458
- .sort((a, b) => a - b);
459
- for (let i = 1; i < integerPhases.length; i++) {
460
- if (integerPhases[i] !== integerPhases[i - 1] + 1) {
461
- warnings.push(`Gap in phase numbering: ${integerPhases[i - 1]} → ${integerPhases[i]}`);
462
- }
463
- }
464
- try {
465
- const dirs = (0, core_js_1.listSubDirs)(phasesDir, true);
466
- for (const dir of dirs) {
467
- const phaseFiles = node_fs_1.default.readdirSync(node_path_1.default.join(phasesDir, dir));
468
- const plans = phaseFiles.filter(f => (0, core_js_1.isPlanFile)(f)).sort();
469
- const planNums = plans.map(p => {
470
- const pm = p.match(/-(\d{2})-PLAN\.md$/);
471
- return pm ? parseInt(pm[1], 10) : null;
472
- }).filter((n) => n !== null);
473
- for (let i = 1; i < planNums.length; i++) {
474
- if (planNums[i] !== planNums[i - 1] + 1) {
475
- warnings.push(`Gap in plan numbering in ${dir}: plan ${planNums[i - 1]} → ${planNums[i]}`);
476
- }
477
- }
478
- const summaries = phaseFiles.filter(f => (0, core_js_1.isSummaryFile)(f));
479
- const planIdsSet = new Set(plans.map(p => (0, core_js_1.planId)(p)));
480
- const summaryIdsSet = new Set(summaries.map(s => (0, core_js_1.summaryId)(s)));
481
- for (const sid of summaryIdsSet) {
482
- if (!planIdsSet.has(sid)) {
483
- warnings.push(`Summary ${sid}-SUMMARY.md in ${dir} has no matching PLAN.md`);
484
- }
485
- }
486
- }
487
- }
488
- catch (e) {
489
- /* optional op, ignore */
490
- (0, core_js_1.debugLog)(e);
491
- }
492
- try {
493
- const dirs = (0, core_js_1.listSubDirs)(phasesDir);
494
- for (const dir of dirs) {
495
- const phaseFiles = node_fs_1.default.readdirSync(node_path_1.default.join(phasesDir, dir));
496
- const plans = phaseFiles.filter(f => (0, core_js_1.isPlanFile)(f));
497
- for (const plan of plans) {
498
- const content = node_fs_1.default.readFileSync(node_path_1.default.join(phasesDir, dir, plan), 'utf-8');
499
- const fm = (0, frontmatter_js_1.extractFrontmatter)(content);
500
- if (!fm.wave) {
501
- warnings.push(`${dir}/${plan}: missing 'wave' in frontmatter`);
502
- }
503
- }
504
- }
505
- }
506
- catch (e) {
507
- /* optional op, ignore */
508
- (0, core_js_1.debugLog)(e);
509
- }
510
- const passed = errors.length === 0;
511
- const result = { passed, errors, warnings, warning_count: warnings.length };
512
- return (0, types_js_1.cmdOk)(result, passed ? 'passed' : 'failed');
513
- }
514
- // ─── Validate Health ─────────────────────────────────────────────────────────
515
- function cmdValidateHealth(cwd, options) {
516
- const planningDir = (0, core_js_1.planningPath)(cwd);
517
- const projectPath = (0, core_js_1.planningPath)(cwd, 'PROJECT.md');
518
- const rmPath = (0, core_js_1.roadmapPath)(cwd);
519
- const stPath = (0, core_js_1.statePath)(cwd);
520
- const cfgPath = (0, core_js_1.configPath)(cwd);
521
- const phasesDir = (0, core_js_1.phasesPath)(cwd);
522
- const errors = [];
523
- const warnings = [];
524
- const info = [];
525
- const repairs = [];
526
- const addIssue = (severity, code, message, fix, repairable = false) => {
527
- const issue = { code, message, fix, repairable };
528
- if (severity === 'error')
529
- errors.push(issue);
530
- else if (severity === 'warning')
531
- warnings.push(issue);
532
- else
533
- info.push(issue);
534
- };
535
- // Check 1: .planning/ exists
536
- if (!node_fs_1.default.existsSync(planningDir)) {
537
- addIssue('error', 'E001', '.planning/ directory not found', 'Run /maxsim:new-project to initialize');
538
- return (0, types_js_1.cmdOk)({
539
- status: 'broken',
540
- errors,
541
- warnings,
542
- info,
543
- repairable_count: 0,
544
- });
545
- }
546
- // Check 2: PROJECT.md
547
- if (!node_fs_1.default.existsSync(projectPath)) {
548
- addIssue('error', 'E002', 'PROJECT.md not found', 'Run /maxsim:new-project to create');
549
- }
550
- else {
551
- const content = node_fs_1.default.readFileSync(projectPath, 'utf-8');
552
- const requiredSections = ['## What This Is', '## Core Value', '## Requirements'];
553
- for (const section of requiredSections) {
554
- if (!content.includes(section)) {
555
- addIssue('warning', 'W001', `PROJECT.md missing section: ${section}`, 'Add section manually');
556
- }
557
- }
558
- }
559
- // Check 3: ROADMAP.md
560
- if (!node_fs_1.default.existsSync(rmPath)) {
561
- addIssue('error', 'E003', 'ROADMAP.md not found', 'Run /maxsim:new-milestone to create roadmap');
562
- }
563
- // Check 4: STATE.md
564
- if (!node_fs_1.default.existsSync(stPath)) {
565
- addIssue('error', 'E004', 'STATE.md not found', 'Run /maxsim:health --repair to regenerate', true);
566
- repairs.push('regenerateState');
567
- }
568
- else {
569
- const stateContent = node_fs_1.default.readFileSync(stPath, 'utf-8');
570
- const phaseRefs = [...stateContent.matchAll(/[Pp]hase\s+(\d+(?:\.\d+)?)/g)].map(m => m[1]);
571
- const diskPhases = new Set();
572
- try {
573
- for (const dir of (0, core_js_1.listSubDirs)(phasesDir)) {
574
- const dm = dir.match(/^(\d+(?:\.\d+)?)/);
575
- if (dm)
576
- diskPhases.add(dm[1]);
577
- }
578
- }
579
- catch (e) {
580
- /* optional op, ignore */
581
- (0, core_js_1.debugLog)(e);
582
- }
583
- for (const ref of phaseRefs) {
584
- const normalizedRef = String(parseInt(ref, 10)).padStart(2, '0');
585
- if (!diskPhases.has(ref) && !diskPhases.has(normalizedRef) && !diskPhases.has(String(parseInt(ref, 10)))) {
586
- if (diskPhases.size > 0) {
587
- addIssue('warning', 'W002', `STATE.md references phase ${ref}, but only phases ${[...diskPhases].sort().join(', ')} exist`, 'Run /maxsim:health --repair to regenerate STATE.md', true);
588
- if (!repairs.includes('regenerateState'))
589
- repairs.push('regenerateState');
590
- }
591
- }
592
- }
593
- }
594
- // Check 5: config.json
595
- if (!node_fs_1.default.existsSync(cfgPath)) {
596
- addIssue('warning', 'W003', 'config.json not found', 'Run /maxsim:health --repair to create with defaults', true);
597
- repairs.push('createConfig');
598
- }
599
- else {
600
- try {
601
- const rawContent = node_fs_1.default.readFileSync(cfgPath, 'utf-8');
602
- const parsed = JSON.parse(rawContent);
603
- const validProfiles = ['quality', 'balanced', 'budget', 'tokenburner'];
604
- if (parsed.model_profile && !validProfiles.includes(parsed.model_profile)) {
605
- addIssue('warning', 'W004', `config.json: invalid model_profile "${parsed.model_profile}"`, `Valid values: ${validProfiles.join(', ')}`);
606
- }
607
- }
608
- catch (thrown) {
609
- const parseErr = thrown;
610
- addIssue('error', 'E005', `config.json: JSON parse error - ${parseErr.message}`, 'Run /maxsim:health --repair to reset to defaults', true);
611
- repairs.push('resetConfig');
612
- }
613
- }
614
- // Check 6: Phase directory naming
615
- try {
616
- for (const dirName of (0, core_js_1.listSubDirs)(phasesDir)) {
617
- if (!dirName.match(/^\d{2}(?:\.\d+)?-[\w-]+$/)) {
618
- addIssue('warning', 'W005', `Phase directory "${dirName}" doesn't follow NN-name format`, 'Rename to match pattern (e.g., 01-setup)');
619
- }
620
- }
621
- }
622
- catch (e) {
623
- /* optional op, ignore */
624
- (0, core_js_1.debugLog)(e);
625
- }
626
- // Check 7: Orphaned plans
627
- try {
628
- const orphanDirs = (0, core_js_1.listSubDirs)(phasesDir);
629
- for (const dirName of orphanDirs) {
630
- const phaseFiles = node_fs_1.default.readdirSync(node_path_1.default.join(phasesDir, dirName));
631
- const plans = phaseFiles.filter(f => (0, core_js_1.isPlanFile)(f));
632
- const summaries = phaseFiles.filter(f => (0, core_js_1.isSummaryFile)(f));
633
- const summaryBases = new Set(summaries.map(s => (0, core_js_1.summaryId)(s)));
634
- for (const plan of plans) {
635
- const planBase = (0, core_js_1.planId)(plan);
636
- if (!summaryBases.has(planBase)) {
637
- addIssue('info', 'I001', `${dirName}/${plan} has no SUMMARY.md`, 'May be in progress');
638
- }
639
- }
640
- }
641
- }
642
- catch (e) {
643
- /* optional op, ignore */
644
- (0, core_js_1.debugLog)(e);
645
- }
646
- // Check 8: Roadmap consistency
647
- if (node_fs_1.default.existsSync(rmPath)) {
648
- const roadmapContent = node_fs_1.default.readFileSync(rmPath, 'utf-8');
649
- const roadmapPhases = new Set();
650
- const phasePattern = (0, core_js_1.getPhasePattern)();
651
- let m;
652
- while ((m = phasePattern.exec(roadmapContent)) !== null) {
653
- roadmapPhases.add(m[1]);
654
- }
655
- const diskPhases = new Set();
656
- try {
657
- for (const dir of (0, core_js_1.listSubDirs)(phasesDir)) {
658
- const dm = dir.match(/^(\d+[A-Z]?(?:\.\d+)?)/i);
659
- if (dm)
660
- diskPhases.add(dm[1]);
661
- }
662
- }
663
- catch (e) {
664
- /* optional op, ignore */
665
- (0, core_js_1.debugLog)(e);
666
- }
667
- for (const p of roadmapPhases) {
668
- const padded = String(parseInt(p, 10)).padStart(2, '0');
669
- if (!diskPhases.has(p) && !diskPhases.has(padded)) {
670
- addIssue('warning', 'W006', `Phase ${p} in ROADMAP.md but no directory on disk`, 'Create phase directory or remove from roadmap');
671
- }
672
- }
673
- for (const p of diskPhases) {
674
- const unpadded = String(parseInt(p, 10));
675
- if (!roadmapPhases.has(p) && !roadmapPhases.has(unpadded)) {
676
- addIssue('warning', 'W007', `Phase ${p} exists on disk but not in ROADMAP.md`, 'Add to roadmap or remove directory');
677
- }
678
- }
679
- }
680
- // Perform repairs if requested
681
- const repairActions = [];
682
- if (options.repair && repairs.length > 0) {
683
- for (const repair of repairs) {
684
- try {
685
- switch (repair) {
686
- case 'createConfig':
687
- case 'resetConfig': {
688
- const defaults = {
689
- model_profile: 'balanced',
690
- commit_docs: true,
691
- search_gitignored: false,
692
- branching_strategy: 'none',
693
- research: true,
694
- plan_checker: true,
695
- verifier: true,
696
- parallelization: true,
697
- };
698
- node_fs_1.default.writeFileSync(cfgPath, JSON.stringify(defaults, null, 2), 'utf-8');
699
- repairActions.push({ action: repair, success: true, path: 'config.json' });
700
- break;
701
- }
702
- case 'regenerateState': {
703
- if (node_fs_1.default.existsSync(stPath)) {
704
- const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);
705
- const backupPath = `${stPath}.bak-${timestamp}`;
706
- node_fs_1.default.copyFileSync(stPath, backupPath);
707
- repairActions.push({ action: 'backupState', success: true, path: backupPath });
708
- }
709
- const milestone = (0, core_js_1.getMilestoneInfo)(cwd);
710
- let stateContent = `# Session State\n\n`;
711
- stateContent += `## Project Reference\n\n`;
712
- stateContent += `See: .planning/PROJECT.md\n\n`;
713
- stateContent += `## Position\n\n`;
714
- stateContent += `**Milestone:** ${milestone.version} ${milestone.name}\n`;
715
- stateContent += `**Current phase:** (determining...)\n`;
716
- stateContent += `**Status:** Resuming\n\n`;
717
- stateContent += `## Session Log\n\n`;
718
- stateContent += `- ${(0, core_js_1.todayISO)()}: STATE.md regenerated by /maxsim:health --repair\n`;
719
- node_fs_1.default.writeFileSync(stPath, stateContent, 'utf-8');
720
- repairActions.push({ action: repair, success: true, path: 'STATE.md' });
721
- break;
722
- }
723
- }
724
- }
725
- catch (thrown) {
726
- const repairErr = thrown;
727
- repairActions.push({ action: repair, success: false, error: repairErr.message });
728
- }
729
- }
730
- }
731
- // Determine overall status
732
- let status;
733
- if (errors.length > 0) {
734
- status = 'broken';
735
- }
736
- else if (warnings.length > 0) {
737
- status = 'degraded';
738
- }
739
- else {
740
- status = 'healthy';
741
- }
742
- const repairableCount = errors.filter(e => e.repairable).length +
743
- warnings.filter(w => w.repairable).length;
744
- const result = {
745
- status,
746
- errors,
747
- warnings,
748
- info,
749
- repairable_count: repairableCount,
750
- repairs_performed: repairActions.length > 0 ? repairActions : undefined,
751
- };
752
- return (0, types_js_1.cmdOk)(result);
753
- }
754
- //# sourceMappingURL=verify.js.map