maxsimcli 4.4.0 → 4.6.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 (53) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/assets/CHANGELOG.md +41 -0
  3. package/dist/assets/dashboard/server.js +248 -240
  4. package/dist/assets/templates/agents/AGENTS.md +1 -0
  5. package/dist/assets/templates/agents/maxsim-drift-checker.md +522 -0
  6. package/dist/assets/templates/commands/maxsim/check-drift.md +56 -0
  7. package/dist/assets/templates/commands/maxsim/discuss.md +70 -0
  8. package/dist/assets/templates/commands/maxsim/realign.md +39 -0
  9. package/dist/assets/templates/workflows/check-drift.md +248 -0
  10. package/dist/assets/templates/workflows/discuss.md +343 -0
  11. package/dist/assets/templates/workflows/progress.md +8 -0
  12. package/dist/assets/templates/workflows/realign.md +288 -0
  13. package/dist/assets/templates/workflows/roadmap.md +69 -20
  14. package/dist/backend-server.cjs +52 -29
  15. package/dist/backend-server.cjs.map +1 -1
  16. package/dist/cli.cjs +261 -5
  17. package/dist/cli.cjs.map +1 -1
  18. package/dist/cli.js +20 -1
  19. package/dist/cli.js.map +1 -1
  20. package/dist/core/core.d.ts.map +1 -1
  21. package/dist/core/core.js +1 -0
  22. package/dist/core/core.js.map +1 -1
  23. package/dist/core/drift.d.ts +37 -0
  24. package/dist/core/drift.d.ts.map +1 -0
  25. package/dist/core/drift.js +213 -0
  26. package/dist/core/drift.js.map +1 -0
  27. package/dist/core/frontmatter.d.ts.map +1 -1
  28. package/dist/core/frontmatter.js +3 -0
  29. package/dist/core/frontmatter.js.map +1 -1
  30. package/dist/core/index.d.ts +3 -2
  31. package/dist/core/index.d.ts.map +1 -1
  32. package/dist/core/index.js +12 -2
  33. package/dist/core/index.js.map +1 -1
  34. package/dist/core/init.d.ts +5 -3
  35. package/dist/core/init.d.ts.map +1 -1
  36. package/dist/core/init.js +89 -0
  37. package/dist/core/init.js.map +1 -1
  38. package/dist/core/types.d.ts +50 -1
  39. package/dist/core/types.d.ts.map +1 -1
  40. package/dist/core/types.js.map +1 -1
  41. package/dist/core-RRjCSt0G.cjs.map +1 -1
  42. package/dist/{lifecycle-0M4VqOMm.cjs → lifecycle-DxCru7rk.cjs} +2 -2
  43. package/dist/{lifecycle-0M4VqOMm.cjs.map → lifecycle-DxCru7rk.cjs.map} +1 -1
  44. package/dist/mcp/phase-tools.d.ts.map +1 -1
  45. package/dist/mcp/phase-tools.js +17 -4
  46. package/dist/mcp/phase-tools.js.map +1 -1
  47. package/dist/mcp-server.cjs +20 -5
  48. package/dist/mcp-server.cjs.map +1 -1
  49. package/dist/{server-G1MIg_Oe.cjs → server-By0TN-nC.cjs} +21 -6
  50. package/dist/server-By0TN-nC.cjs.map +1 -0
  51. package/dist/skills-MYlMkYNt.cjs.map +1 -1
  52. package/package.json +1 -1
  53. package/dist/server-G1MIg_Oe.cjs.map +0 -1
@@ -0,0 +1,288 @@
1
+ <sanity_check>
2
+ Before executing any step in this workflow, verify:
3
+ 1. The current directory contains a `.planning/` folder -- if not, stop and tell the user to run `/maxsim:new-project` first.
4
+ 2. `.planning/DRIFT-REPORT.md` exists -- if not, stop and tell the user to run `/maxsim:check-drift` first.
5
+ </sanity_check>
6
+
7
+ <purpose>
8
+ Correct spec-code divergence in either direction. Realign-to-code updates `.planning/` to match the actual codebase. Realign-to-spec generates new fix phases to make code match the spec. Reads the DRIFT-REPORT.md produced by `/maxsim:check-drift`.
9
+ </purpose>
10
+
11
+ <core_principle>
12
+ This is an interactive orchestrator workflow, not an agent spawn. Realign-to-code requires per-item user decisions (Accept/Skip/Edit). Realign-to-spec requires user approval of proposed phase groupings. The workflow drives the interaction directly.
13
+ </core_principle>
14
+
15
+ <required_reading>
16
+ Read STATE.md before any operation to load project context.
17
+ </required_reading>
18
+
19
+ <process>
20
+
21
+ <step name="initialize" priority="first">
22
+ Load context and validate prerequisites:
23
+
24
+ ```bash
25
+ INIT=$(node ~/.claude/maxsim/bin/maxsim-tools.cjs init realign "$DIRECTION")
26
+ ```
27
+
28
+ Parse JSON for: `has_report`, `has_planning`, `report_path`, `state_path`, `requirements_path`, `roadmap_path`, `phase_dirs`, `current_phase`, `commit_docs`.
29
+
30
+ **Validation gates:**
31
+ - If `has_planning` is false: "No `.planning/` directory found. Run `/maxsim:new-project` first." STOP.
32
+ - If `has_report` is false: "No DRIFT-REPORT.md found. Run `/maxsim:check-drift` first to generate a drift report." STOP.
33
+ </step>
34
+
35
+ <step name="read_report">
36
+ Read the drift report metadata and content:
37
+
38
+ ```bash
39
+ REPORT=$(node ~/.claude/maxsim/bin/maxsim-tools.cjs drift read-report)
40
+ ```
41
+
42
+ Parse the result to extract:
43
+ - **Frontmatter:** `status`, `critical_count`, `warning_count`, `info_count`, `undocumented_count`, `total_items`, `aligned_count`
44
+ - **Body sections:** "Spec Ahead of Code", "Code Ahead of Spec", "No-Go Violations", "Undocumented Features"
45
+
46
+ **If `status` is `aligned`:**
47
+ ```
48
+ No drift detected -- nothing to realign. All spec items match the codebase.
49
+ ```
50
+ STOP.
51
+ </step>
52
+
53
+ <step name="select_direction">
54
+ Determine the realignment direction.
55
+
56
+ **If `$DIRECTION` was provided via `$ARGUMENTS`:** Use it directly. Validate it is either `to-code` or `to-spec`.
57
+
58
+ **If no direction was provided:** Present the user with a choice:
59
+
60
+ ```markdown
61
+ ## Drift Report Summary
62
+
63
+ **Status:** {critical_count} critical | {warning_count} warning | {info_count} info | {undocumented_count} undocumented
64
+
65
+ Choose a realignment direction:
66
+
67
+ 1. **to-code** -- Update `.planning/` to match current codebase (spec follows code)
68
+ Best when: Code is correct and spec is outdated. Accepts code reality.
69
+
70
+ 2. **to-spec** -- Generate fix phases to make code match spec (code follows spec)
71
+ Best when: Spec is correct and code has gaps. Creates implementation phases.
72
+ ```
73
+
74
+ Wait for user selection.
75
+ </step>
76
+
77
+ <step name="realign_to_code">
78
+ **Execute only if direction is `to-code`.**
79
+
80
+ Parse the drift report body to extract all drifted items from:
81
+ - "Spec Ahead of Code" section (requirements marked complete but code missing/incomplete)
82
+ - "Code Ahead of Spec" section (features in code but not captured in spec)
83
+ - "No-Go Violations" section (code violating declared constraints)
84
+ - "Undocumented Features" section (features with no spec coverage)
85
+
86
+ Build a list of actionable items. For each item, extract:
87
+ - Requirement ID (if applicable)
88
+ - Section heading/description
89
+ - Current spec text and location
90
+ - What was found (or not found) in code
91
+ - The report's fix recommendation
92
+ - All spec file references from the evidence section
93
+
94
+ **Process each item interactively:**
95
+
96
+ For each drifted item, present it to the user:
97
+
98
+ ```markdown
99
+ ### Item {N}/{total}: {Requirement ID or Feature Name}
100
+
101
+ **Severity:** {CRITICAL | WARNING | INFO}
102
+ **Direction:** {Spec ahead of code | Code ahead of spec | No-go violation | Undocumented}
103
+
104
+ **Current spec:** {spec text from report}
105
+ **Code reality:** {what was found or not found}
106
+ **Recommendation:** {fix recommendation from report}
107
+
108
+ **Affected spec files:** {list of files that reference this item}
109
+
110
+ Choose:
111
+ - **Accept** -- Apply the recommended spec change
112
+ - **Skip** -- Leave as-is (no changes for this item)
113
+ - **Edit** -- Provide a custom change description
114
+ ```
115
+
116
+ Wait for user response.
117
+
118
+ **Apply accepted changes based on item direction:**
119
+
120
+ **For "Spec ahead of code" items** (requirement marked done but code missing):
121
+ - Update REQUIREMENTS.md: change `[x]` to `[ ]` for the requirement using `node ~/.claude/maxsim/bin/maxsim-tools.cjs requirements mark-incomplete {REQ_ID}`, or manually edit the checkbox if the tool does not support it.
122
+ - Check ROADMAP.md: if the requirement appears in success criteria for a phase, add a note that the criterion is unmet.
123
+ - Check STATE.md: if a decision references this requirement, add a note that the implementation is pending.
124
+ - Check phase SUMMARY.md files: if any summary claims this requirement was completed, add a caveat note.
125
+
126
+ **For "Code ahead of spec" items** (feature exists but spec does not mention it):
127
+ - If user accepts the default recommendation: add the feature as a new requirement in REQUIREMENTS.md under the appropriate version section.
128
+ - If user provides an edit: apply their custom text instead.
129
+ - Update PROJECT.md if the feature represents a significant capability not documented there.
130
+
131
+ **For "No-go violation" items** (code violating a declared constraint):
132
+ - Document as known tech debt in STATE.md under "Blockers/Concerns" or a "Known Tech Debt" section.
133
+ - Optionally mark for future fix phase.
134
+
135
+ **For "Undocumented feature" items** (code with no spec coverage):
136
+ - Add to REQUIREMENTS.md as a new entry documenting the existing capability.
137
+ - Or update PROJECT.md to document it as an existing capability, depending on user's edit.
138
+
139
+ **CRITICAL -- Multi-file consistency:** For each accepted item, identify ALL spec files that reference it (from the drift report evidence section) and update all of them. Do NOT update only REQUIREMENTS.md while leaving ROADMAP.md or STATE.md inconsistent. Use the spec file references in the drift report as the update checklist.
140
+
141
+ Track changes: maintain a running count of accepted, skipped, and edited items, and a list of all modified files.
142
+
143
+ **After processing all items:**
144
+
145
+ Check if any phase now has all success criteria met in code. For each phase referenced in the drift report:
146
+
147
+ ```bash
148
+ # Check if phase criteria are now all satisfied
149
+ PHASE_STATUS=$(node ~/.claude/maxsim/bin/maxsim-tools.cjs roadmap get-phase "{phase_number}")
150
+ ```
151
+
152
+ If all criteria for a phase are met after the realignment updates, auto-mark that phase complete:
153
+
154
+ ```bash
155
+ node ~/.claude/maxsim/bin/maxsim-tools.cjs phase complete "{phase_number}"
156
+ ```
157
+
158
+ **If ALL items were skipped:** "No changes applied. Drift report remains unchanged." STOP (do not commit).
159
+
160
+ **Commit changes:**
161
+
162
+ ```bash
163
+ node ~/.claude/maxsim/bin/maxsim-tools.cjs commit "docs: realign spec to match codebase" --files {space-separated list of all modified files}
164
+ ```
165
+ </step>
166
+
167
+ <step name="realign_to_spec">
168
+ **Execute only if direction is `to-spec`.**
169
+
170
+ Parse the drift report to extract all "Spec Ahead of Code" items -- requirements and success criteria that are specified but not yet implemented in code. Also include any "No-Go Violations" that require code changes.
171
+
172
+ Build a list of implementation gaps. For each gap, extract:
173
+ - Requirement ID
174
+ - Description of what needs to be implemented
175
+ - Current spec location (file and section)
176
+ - Evidence of what is missing from the report
177
+
178
+ **Group gaps into phases using this algorithm:**
179
+
180
+ 1. **Group by requirement prefix:** Collect all gaps sharing a requirement prefix (e.g., all `DRIFT-*` gaps into one phase, all `INIT-*` into another, all `ROT-*` into another). The prefix is the text before the hyphen and number in the requirement ID.
181
+
182
+ 2. **If no prefix grouping possible** (gaps have no requirement IDs or all have unique prefixes): group by affected subsystem. Cluster gaps whose evidence references common file paths or directories.
183
+
184
+ 3. **Apply the 5-phase cap:**
185
+ - If 5 or fewer groups: use them as-is.
186
+ - If more than 5 groups: sort groups by gap count (ascending). Merge the smallest groups into a "Remaining Gaps" phase until only 5 groups remain.
187
+
188
+ 4. **Minimum group size:** Each phase should have at minimum 2 gaps, unless it is the only group or merging is not possible.
189
+
190
+ 5. **Name each phase** descriptively: "{Prefix} Implementation Gaps" or "{Subsystem} Fixes" or similar concise name.
191
+
192
+ **Present proposed phases to user:**
193
+
194
+ ```markdown
195
+ ## Proposed Realignment Phases
196
+
197
+ Based on the drift report, {gap_count} implementation gaps will be organized into {phase_count} new phases inserted after the current active phase ({current_phase}).
198
+
199
+ | # | Phase Name | Requirements | Gap Count | Description |
200
+ |---|-----------|-------------|-----------|-------------|
201
+ | 1 | {name} | {REQ-01, REQ-02} | {N} | {brief description} |
202
+ | 2 | {name} | {REQ-03} | {N} | {brief description} |
203
+
204
+ Approve this breakdown? (yes / suggest changes)
205
+ ```
206
+
207
+ Wait for user approval. If user suggests changes, adjust the grouping accordingly.
208
+
209
+ **For each approved phase, insert after the current active phase:**
210
+
211
+ ```bash
212
+ RESULT=$(node ~/.claude/maxsim/bin/maxsim-tools.cjs phase insert "{current_phase}" "{phase_name}")
213
+ ```
214
+
215
+ The insert command creates the phase directory with decimal numbering (e.g., `04.1`, `04.2`) and updates ROADMAP.md.
216
+
217
+ **For each inserted phase, update the ROADMAP.md phase section** to include:
218
+ - The requirement IDs covered by this phase
219
+ - Success criteria extracted from the drift report (what needs to be implemented)
220
+ - A brief goal statement
221
+
222
+ Use the Edit tool to add requirement details and success criteria to each newly created phase entry in ROADMAP.md.
223
+
224
+ **Commit changes:**
225
+
226
+ ```bash
227
+ node ~/.claude/maxsim/bin/maxsim-tools.cjs commit "feat: add realignment phases from drift report" --files .planning/ROADMAP.md .planning/STATE.md
228
+ ```
229
+
230
+ Note: Include any new phase directories created by the insert commands in the commit files list.
231
+ </step>
232
+
233
+ <step name="summary">
234
+ Display a summary of what was changed.
235
+
236
+ **For realign-to-code:**
237
+
238
+ ```markdown
239
+ ## Realignment Complete (to-code)
240
+
241
+ **Items processed:** {total}
242
+ - Accepted: {accepted_count}
243
+ - Skipped: {skipped_count}
244
+ - Edited: {edited_count}
245
+
246
+ **Files modified:** {list of modified files}
247
+ **Phases auto-completed:** {list of phases marked complete, or "None"}
248
+ **Commit:** {commit hash}
249
+
250
+ The spec now reflects the current codebase state for the accepted items.
251
+ Skipped items remain as drift -- run `/maxsim:check-drift` again to see remaining drift.
252
+ ```
253
+
254
+ **For realign-to-spec:**
255
+
256
+ ```markdown
257
+ ## Realignment Complete (to-spec)
258
+
259
+ **Implementation gaps:** {gap_count}
260
+ **New phases created:** {phase_count}
261
+
262
+ | Phase | Name | Requirements |
263
+ |-------|------|-------------|
264
+ | {num} | {name} | {REQ IDs} |
265
+
266
+ **Next step:** Run `/maxsim:execute-phase {first_new_phase}` to begin implementing the gaps.
267
+ ```
268
+ </step>
269
+
270
+ </process>
271
+
272
+ <error_handling>
273
+ - **DRIFT-REPORT.md missing:** Direct user to run `/maxsim:check-drift` first. Do not attempt to generate a report.
274
+ - **Report status is "aligned":** Nothing to do. Inform user and stop.
275
+ - **All items skipped (to-code):** No changes made. Inform user that drift remains.
276
+ - **Zero "Spec Ahead of Code" gaps (to-spec):** Inform user "All specified items appear implemented. No fix phases needed. Consider realign-to-code instead to capture undocumented features."
277
+ - **Phase insert fails:** Report the error. Continue with remaining phases if possible. Document any failures in the summary.
278
+ - **Invalid direction argument:** Show usage: `/maxsim:realign [to-code | to-spec]`
279
+ </error_handling>
280
+
281
+ <critical_rules>
282
+ - **Item-by-item approval for to-code:** Never batch-apply changes. Present each item individually and wait for Accept/Skip/Edit.
283
+ - **Multi-file consistency:** When updating spec for an accepted item, update ALL referencing spec files, not just REQUIREMENTS.md. Use the evidence section from the drift report to identify all affected files.
284
+ - **Phase cap for to-spec:** Never create more than 5 new phases. Group and merge as described in the algorithm.
285
+ - **Insert after current phase:** New phases go after the current active phase, not at the end of the roadmap.
286
+ - **No auto-generation of reports:** This workflow reads an existing DRIFT-REPORT.md. It does not run drift detection itself.
287
+ - **Auto-complete phases:** After realign-to-code, check if any phase has all criteria met and auto-mark it complete.
288
+ </critical_rules>
@@ -1,5 +1,5 @@
1
1
  <purpose>
2
- Render the project roadmap in a readable format with phase status icons and plan progress counts. Read-only — does not modify any files.
2
+ Render the project roadmap in a readable format with phase status icons and plan progress counts. Auto-collapses completed phases to one-liners for visual clarity and paginates at 20 phases per page for large projects. Read-only — does not modify any files.
3
3
  </purpose>
4
4
 
5
5
  <process>
@@ -16,6 +16,8 @@ Parse JSON. If `planning_exists` is false, hard stop:
16
16
  > No roadmap found. Run /maxsim:new-project to initialize.
17
17
 
18
18
  Exit immediately. Do not continue.
19
+
20
+ **Parse `--page` argument:** If the command was invoked with `--page N`, extract the page number (default: 1). This controls which page of phases to display when total phases exceed 20.
19
21
  </step>
20
22
 
21
23
  <step name="analyze">
@@ -43,31 +45,74 @@ Print the roadmap to the terminal.
43
45
 
44
46
  **Blank line.**
45
47
 
46
- **Per-phase lines (in numeric order):**
48
+ **Auto-collapse completed phases (always active, regardless of phase count):**
47
49
 
48
- For each phase in `phases[]`:
49
- - `disk_status === 'complete'` → icon `✓`, label `DONE`
50
- - `disk_status === 'partial'` → icon `►`, label `IN PROGRESS`
51
- - `disk_status === 'planned' || 'empty' || 'discussed' || 'researched' || 'no_directory'` → icon `□`, label `PLANNED`
50
+ Render phases in two visual groups:
52
51
 
53
- Format per line:
54
- ```
55
- {icon} Phase {number}: {name} {label} ({summary_count}/{plan_count} plans)
56
- ```
52
+ 1. **Completed phases** — collapsed one-liners with no plan counts or status label:
53
+ ```
54
+ Phase {number}: {name}
55
+ ```
56
+ Just checkmark + phase number + name. One line per completed phase. This keeps the roadmap scannable when many phases are done.
57
+
58
+ 2. **Active and upcoming phases** — full detail format with icon, label, and plan counts:
59
+ ```
60
+ {icon} Phase {number}: {name} {label} ({summary_count}/{plan_count} plans)
61
+ ```
57
62
 
58
- Pad phase names with spaces so status labels align in a column.
63
+ For active/upcoming phases:
64
+ - `disk_status === 'partial'` -> icon `>`, label `IN PROGRESS`
65
+ - `disk_status === 'planned' || 'empty' || 'discussed' || 'researched' || 'no_directory'` -> icon `[ ]`, label `PLANNED`
66
+
67
+ Pad phase names with spaces so status labels align in a column (within the active/upcoming group only).
59
68
 
60
69
  Only show `({summary_count}/{plan_count} plans)` when `plan_count > 0`.
61
70
 
62
- Example output:
71
+ **Pagination (only when total phases exceed 20):**
72
+
73
+ After assembling all phase lines (both collapsed completed and full-detail active/upcoming), check the total phase count:
74
+
75
+ - If total phases is **20 or fewer**: show all phases. No pagination footer. This is the default experience for small/medium projects.
76
+ - If total phases **exceeds 20**: apply pagination.
77
+ - Page size: 20 phases per page.
78
+ - Use the `--page N` argument (default page 1) to determine which slice to show.
79
+ - Calculate: `first = (page - 1) * 20 + 1`, `last = min(page * 20, total)`.
80
+ - Show only phases from index `first` to `last`.
81
+ - Add a footer line after the phase list:
82
+ ```
83
+ Showing phases {first}-{last} of {total}. Use --page {next_page} for next.
84
+ ```
85
+ - If on the last page, omit the "Use --page" hint.
86
+
87
+ Example output (small project, no pagination):
63
88
  ```
64
- NX Monorepo Migration 5 done / 1 active / 6 planned
89
+ Context-Aware SDD3 done / 1 active / 1 planned
90
+
91
+ ✓ Phase 1: Context Rot Prevention
92
+ ✓ Phase 2: Init Flow Overhaul
93
+ ✓ Phase 3: Agent Coherence
94
+
95
+ > Phase 4: Spec Drift Management IN PROGRESS (2/3 plans)
96
+ [ ] Phase 5: Workflow Coverage PLANNED
97
+ ```
98
+
99
+ Example output (large project with pagination, page 1):
100
+ ```
101
+ NX Monorepo Migration — 15 done / 1 active / 9 planned
102
+
103
+ ✓ Phase 01: NX Workspace Scaffold
104
+ ✓ Phase 02: packages/core TypeScript Port
105
+ ✓ Phase 03: Shared Types
106
+ ...
107
+ ✓ Phase 15: CI Pipeline
108
+
109
+ > Phase 16: Dashboard Rewrite IN PROGRESS (2/5 plans)
110
+ [ ] Phase 17: Plugin System PLANNED
111
+ [ ] Phase 18: Performance Optimization PLANNED
112
+ [ ] Phase 19: Documentation PLANNED
113
+ [ ] Phase 20: Security Audit PLANNED
65
114
 
66
- ✓ Phase 01: NX Workspace Scaffold DONE (4/4 plans)
67
- ✓ Phase 02: packages/core TypeScript Port DONE (6/6 plans)
68
- ► Phase 09: End-to-end install and publish test loop IN PROGRESS (2/3 plans)
69
- □ Phase 11: Remove Discord command PLANNED
70
- □ Phase 12: UX Polish + Core Hardening PLANNED
115
+ Showing phases 1-20 of 25. Use --page 2 for next.
71
116
  ```
72
117
  </step>
73
118
 
@@ -75,7 +120,11 @@ NX Monorepo Migration — 5 done / 1 active / 6 planned
75
120
 
76
121
  <success_criteria>
77
122
  - [ ] Milestone summary header rendered with done/active/planned counts
78
- - [ ] All phases listed in numeric order with correct icon and label
79
- - [ ] Plan progress shown inline for phases that have plans
123
+ - [ ] Completed phases auto-collapsed to one-liners (checkmark + name only, no plan counts)
124
+ - [ ] Active/upcoming phases shown with full detail (icon, label, plan counts)
125
+ - [ ] Phases listed in numeric order within each group
126
+ - [ ] Pagination footer shown only when total phases exceed 20
127
+ - [ ] `--page N` argument controls which page to display
128
+ - [ ] Plan progress shown inline for active/upcoming phases that have plans
80
129
  - [ ] Hard stop if .planning/ is missing
81
130
  </success_criteria>
@@ -32122,17 +32122,17 @@ var require_view = /* @__PURE__ */ __commonJSMin(((exports, module) => {
32122
32122
  * @private
32123
32123
  */
32124
32124
  var debug = require_src$3()("express:view");
32125
- var path$22 = require("path");
32126
- var fs$20 = require("fs");
32125
+ var path$23 = require("path");
32126
+ var fs$21 = require("fs");
32127
32127
  /**
32128
32128
  * Module variables.
32129
32129
  * @private
32130
32130
  */
32131
- var dirname = path$22.dirname;
32132
- var basename = path$22.basename;
32133
- var extname = path$22.extname;
32134
- var join = path$22.join;
32135
- var resolve = path$22.resolve;
32131
+ var dirname = path$23.dirname;
32132
+ var basename = path$23.basename;
32133
+ var extname = path$23.extname;
32134
+ var join = path$23.join;
32135
+ var resolve = path$23.resolve;
32136
32136
  /**
32137
32137
  * Module exports.
32138
32138
  * @public
@@ -32229,7 +32229,7 @@ var require_view = /* @__PURE__ */ __commonJSMin(((exports, module) => {
32229
32229
  function tryStat(path) {
32230
32230
  debug("stat \"%s\"", path);
32231
32231
  try {
32232
- return fs$20.statSync(path);
32232
+ return fs$21.statSync(path);
32233
32233
  } catch (e) {
32234
32234
  return;
32235
32235
  }
@@ -34450,7 +34450,7 @@ var require_types$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
34450
34450
  //#region ../../node_modules/send/node_modules/mime/mime.js
34451
34451
  var require_mime = /* @__PURE__ */ __commonJSMin(((exports, module) => {
34452
34452
  require("path");
34453
- var fs$19 = require("fs");
34453
+ var fs$20 = require("fs");
34454
34454
  function Mime() {
34455
34455
  this.types = Object.create(null);
34456
34456
  this.extensions = Object.create(null);
@@ -34485,7 +34485,7 @@ var require_mime = /* @__PURE__ */ __commonJSMin(((exports, module) => {
34485
34485
  Mime.prototype.load = function(file) {
34486
34486
  this._loading = file;
34487
34487
  var map = {};
34488
- fs$19.readFileSync(file, "ascii").split(/[\r\n]+/).forEach(function(line) {
34488
+ fs$20.readFileSync(file, "ascii").split(/[\r\n]+/).forEach(function(line) {
34489
34489
  var fields = line.replace(/\s*#.*|^\s*|\s*$/g, "").split(/\s+/);
34490
34490
  map[fields.shift()] = fields;
34491
34491
  });
@@ -34764,12 +34764,12 @@ var require_send = /* @__PURE__ */ __commonJSMin(((exports, module) => {
34764
34764
  var escapeHtml = require_escape_html();
34765
34765
  var etag = require_etag();
34766
34766
  var fresh = require_fresh();
34767
- var fs$18 = require("fs");
34767
+ var fs$19 = require("fs");
34768
34768
  var mime = require_mime();
34769
34769
  var ms = require_ms();
34770
34770
  var onFinished = require_on_finished();
34771
34771
  var parseRange = require_range_parser();
34772
- var path$21 = require("path");
34772
+ var path$22 = require("path");
34773
34773
  var statuses = require_statuses();
34774
34774
  var Stream = require("stream");
34775
34775
  var util$3 = require("util");
@@ -34777,11 +34777,11 @@ var require_send = /* @__PURE__ */ __commonJSMin(((exports, module) => {
34777
34777
  * Path function references.
34778
34778
  * @private
34779
34779
  */
34780
- var extname = path$21.extname;
34781
- var join = path$21.join;
34782
- var normalize = path$21.normalize;
34783
- var resolve = path$21.resolve;
34784
- var sep = path$21.sep;
34780
+ var extname = path$22.extname;
34781
+ var join = path$22.join;
34782
+ var normalize = path$22.normalize;
34783
+ var resolve = path$22.resolve;
34784
+ var sep = path$22.sep;
34785
34785
  /**
34786
34786
  * Regular expression for identifying a bytes Range header.
34787
34787
  * @private
@@ -35229,7 +35229,7 @@ var require_send = /* @__PURE__ */ __commonJSMin(((exports, module) => {
35229
35229
  var i = 0;
35230
35230
  var self = this;
35231
35231
  debug("stat \"%s\"", path);
35232
- fs$18.stat(path, function onstat(err, stat) {
35232
+ fs$19.stat(path, function onstat(err, stat) {
35233
35233
  if (err && err.code === "ENOENT" && !extname(path) && path[path.length - 1] !== sep) return next(err);
35234
35234
  if (err) return self.onStatError(err);
35235
35235
  if (stat.isDirectory()) return self.redirect(path);
@@ -35240,7 +35240,7 @@ var require_send = /* @__PURE__ */ __commonJSMin(((exports, module) => {
35240
35240
  if (self._extensions.length <= i) return err ? self.onStatError(err) : self.error(404);
35241
35241
  var p = path + "." + self._extensions[i++];
35242
35242
  debug("stat \"%s\"", p);
35243
- fs$18.stat(p, function(err, stat) {
35243
+ fs$19.stat(p, function(err, stat) {
35244
35244
  if (err) return next(err);
35245
35245
  if (stat.isDirectory()) return next();
35246
35246
  self.emit("file", p, stat);
@@ -35264,7 +35264,7 @@ var require_send = /* @__PURE__ */ __commonJSMin(((exports, module) => {
35264
35264
  }
35265
35265
  var p = join(path, self._index[i]);
35266
35266
  debug("stat \"%s\"", p);
35267
- fs$18.stat(p, function(err, stat) {
35267
+ fs$19.stat(p, function(err, stat) {
35268
35268
  if (err) return next(err);
35269
35269
  if (stat.isDirectory()) return next();
35270
35270
  self.emit("file", p, stat);
@@ -35283,7 +35283,7 @@ var require_send = /* @__PURE__ */ __commonJSMin(((exports, module) => {
35283
35283
  SendStream.prototype.stream = function stream(path, options) {
35284
35284
  var self = this;
35285
35285
  var res = this.res;
35286
- var stream$5 = fs$18.createReadStream(path, options);
35286
+ var stream$5 = fs$19.createReadStream(path, options);
35287
35287
  this.emit("stream", stream$5);
35288
35288
  stream$5.pipe(res);
35289
35289
  function cleanup() {
@@ -38817,7 +38817,7 @@ var require_response = /* @__PURE__ */ __commonJSMin(((exports, module) => {
38817
38817
  var http$3 = require("http");
38818
38818
  var isAbsolute = require_utils$1().isAbsolute;
38819
38819
  var onFinished = require_on_finished();
38820
- var path$20 = require("path");
38820
+ var path$21 = require("path");
38821
38821
  var statuses = require_statuses();
38822
38822
  var merge = require_utils_merge();
38823
38823
  var sign = require_cookie_signature().sign;
@@ -38826,9 +38826,9 @@ var require_response = /* @__PURE__ */ __commonJSMin(((exports, module) => {
38826
38826
  var setCharset = require_utils$1().setCharset;
38827
38827
  var cookie = require_cookie();
38828
38828
  var send = require_send();
38829
- var extname = path$20.extname;
38829
+ var extname = path$21.extname;
38830
38830
  var mime = send.mime;
38831
- var resolve = path$20.resolve;
38831
+ var resolve = path$21.resolve;
38832
38832
  var vary = require_vary();
38833
38833
  /**
38834
38834
  * Response prototype.
@@ -74966,6 +74966,14 @@ function parseTodoFrontmatter(content) {
74966
74966
  * Ported from maxsim/bin/lib/verify.cjs
74967
74967
  */
74968
74968
 
74969
+ //#endregion
74970
+ //#region src/core/drift.ts
74971
+ /**
74972
+ * Drift — Drift report CRUD, requirement extraction, and spec extraction
74973
+ *
74974
+ * Provides CLI tool commands for the drift-checker agent and realign workflow.
74975
+ */
74976
+
74969
74977
  //#endregion
74970
74978
  //#region src/core/phase.ts
74971
74979
  /**
@@ -79004,14 +79012,22 @@ function registerPhaseTools(server) {
79004
79012
  return mcpError(e.message, "Operation failed");
79005
79013
  }
79006
79014
  });
79007
- server.tool("mcp_list_phases", "List all phase directories, sorted correctly. Optionally include archived phases from milestones.", { include_archived: booleanType().optional().default(false).describe("Include archived phases from completed milestones") }, async ({ include_archived }) => {
79015
+ server.tool("mcp_list_phases", "List phase directories with pagination. Returns sorted phases with offset/limit support.", {
79016
+ include_archived: booleanType().optional().default(false).describe("Include archived phases from completed milestones"),
79017
+ offset: numberType().optional().default(0).describe("Number of phases to skip (for pagination)"),
79018
+ limit: numberType().optional().default(20).describe("Maximum number of phases to return")
79019
+ }, async ({ include_archived, offset, limit }) => {
79008
79020
  try {
79009
79021
  const cwd = detectProjectRoot();
79010
79022
  if (!cwd) return mcpError("No .planning/ directory found", "Project not detected");
79011
79023
  const phasesDir = phasesPath(cwd);
79012
79024
  if (!node_fs.default.existsSync(phasesDir)) return mcpSuccess({
79013
79025
  directories: [],
79014
- count: 0
79026
+ count: 0,
79027
+ total_count: 0,
79028
+ offset,
79029
+ limit,
79030
+ has_more: false
79015
79031
  }, "No phases directory found");
79016
79032
  let dirs = listSubDirs(phasesDir);
79017
79033
  if (include_archived) {
@@ -79019,10 +79035,17 @@ function registerPhaseTools(server) {
79019
79035
  for (const a of archived) dirs.push(`${a.name} [${a.milestone}]`);
79020
79036
  }
79021
79037
  dirs.sort((a, b) => comparePhaseNum(a, b));
79038
+ const total_count = dirs.length;
79039
+ const paginated = dirs.slice(offset, offset + limit);
79040
+ const has_more = offset + limit < total_count;
79022
79041
  return mcpSuccess({
79023
- directories: dirs,
79024
- count: dirs.length
79025
- }, `Found ${dirs.length} phase(s)`);
79042
+ directories: paginated,
79043
+ count: paginated.length,
79044
+ total_count,
79045
+ offset,
79046
+ limit,
79047
+ has_more
79048
+ }, `Showing ${paginated.length} of ${total_count} phase(s)`);
79026
79049
  } catch (e) {
79027
79050
  return mcpError(e.message, "Operation failed");
79028
79051
  }