mindsystem-cc 3.10.1 → 3.11.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.
@@ -18,7 +18,7 @@ Decimal phases enable urgent work insertion without renumbering:
18
18
  1. .planning/ROADMAP.md
19
19
  2. .planning/PROJECT.md
20
20
 
21
- **Note:** Heavy references (phase-prompt.md, plan-format.md, scope-estimation.md, checkpoints.md, goal-backward.md, plan-risk-assessment.md) are loaded by the ms-plan-writer subagent, not main context. Lighter references (checkpoint-detection.md, tdd.md) are loaded on demand during task breakdown.
21
+ **Note:** Heavy references (phase-prompt.md, plan-format.md, scope-estimation.md, goal-backward.md, plan-risk-assessment.md) are loaded by the ms-plan-writer subagent, not main context. Lighter references (tdd.md) are loaded on demand during task breakdown.
22
22
  </required_reading>
23
23
 
24
24
  <purpose>
@@ -184,7 +184,6 @@ type: execute
184
184
  wave: 1 # Gap closures typically single wave
185
185
  depends_on: [] # Usually independent of each other
186
186
  files_modified: [...]
187
- autonomous: true
188
187
  gap_closure: true # Flag for tracking
189
188
  ---
190
189
  ```
@@ -450,9 +449,9 @@ For each potential task, ask:
450
449
  3. **Can this run independently?** (no dependencies = Wave 1 candidate)
451
450
 
452
451
  **Standard tasks need:**
453
- - **Type**: auto, checkpoint:human-verify, checkpoint:decision (human-action rarely needed)
452
+ - **Type**: auto
454
453
  - **Task name**: Clear, action-oriented
455
- - **Files**: Which files created/modified (for auto tasks)
454
+ - **Files**: Which files created/modified
456
455
  - **Action hint**: Brief implementation guidance
457
456
  - **Verify hint**: How to prove it worked
458
457
  - **Done hint**: Acceptance criteria
@@ -480,11 +479,9 @@ Standard tasks (remain in standard plans):
480
479
 
481
480
  Read `~/.claude/mindsystem/references/tdd.md` now for TDD criteria and plan structure.
482
481
 
483
- **Checkpoints:** Visual/functional verification checkpoint:human-verify. Implementation choices checkpoint:decision. Manual action (email, 2FA) checkpoint:human-action (rare).
482
+ **Decisions:** If you identify a task that requires choosing between approaches (which auth provider, which database, etc.), use AskUserQuestion to resolve it now. Don't defer decisions to execution. For purely technical choices where the user hasn't expressed preference, make the decision and document it in the plan's objective.
484
483
 
485
- **Critical:** If external resource has CLI/API (Vercel, Stripe, etc.), use type="auto" to automate. Only checkpoint for verification AFTER automation.
486
-
487
- Read `~/.claude/mindsystem/references/checkpoint-detection.md` now for detection rules.
484
+ **Critical:** If external resource has CLI/API (Vercel, Stripe, etc.), use type="auto" to automate.
488
485
 
489
486
  **User setup detection:** For tasks involving external services, identify human-required configuration:
490
487
 
@@ -506,7 +503,6 @@ Note external services for risk scoring.
506
503
  <type>auto</type>
507
504
  <needs>nothing</needs>
508
505
  <creates>src/models/user.ts</creates>
509
- <checkpoint>false</checkpoint>
510
506
  <tdd_candidate>false</tdd_candidate>
511
507
  <action_hint>Define User type with id, email, createdAt</action_hint>
512
508
  <verify_hint>tsc --noEmit passes</verify_hint>
@@ -517,33 +513,20 @@ Note external services for risk scoring.
517
513
  <type>auto</type>
518
514
  <needs>src/models/user.ts</needs>
519
515
  <creates>src/app/api/auth/login/route.ts</creates>
520
- <checkpoint>false</checkpoint>
521
516
  <tdd_candidate>true</tdd_candidate>
522
517
  <action_hint>POST endpoint with bcrypt validation</action_hint>
523
518
  <verify_hint>curl returns 200 with valid credentials</verify_hint>
524
519
  <done_hint>Login works with valid credentials</done_hint>
525
520
  </task>
526
- <task id="3">
527
- <name>Verify login flow</name>
528
- <type>checkpoint:human-verify</type>
529
- <needs>src/app/api/auth/login/route.ts</needs>
530
- <creates>nothing</creates>
531
- <checkpoint>true</checkpoint>
532
- <tdd_candidate>false</tdd_candidate>
533
- <action_hint>N/A</action_hint>
534
- <verify_hint>User tests login manually</verify_hint>
535
- <done_hint>User approves login flow</done_hint>
536
- </task>
537
521
  </task_list>
538
522
  ```
539
523
 
540
524
  Each task captures:
541
525
  - `id`: Sequential identifier
542
526
  - `name`: Action-oriented task name
543
- - `type`: auto, checkpoint:human-verify, checkpoint:decision, checkpoint:human-action
527
+ - `type`: auto
544
528
  - `needs`: Files/types this task requires (or "nothing")
545
529
  - `creates`: Files/types this task produces (or "nothing")
546
- - `checkpoint`: true if requires user interaction
547
530
  - `tdd_candidate`: true if should be TDD plan
548
531
  - `action_hint`: Brief implementation guidance (subagent expands)
549
532
  - `verify_hint`: How to verify completion
@@ -790,7 +773,7 @@ Tasks are instructions for Claude, not Jira tickets.
790
773
  - [ ] Tasks identified with needs/creates dependencies
791
774
  - [ ] Task list handed off to ms-plan-writer
792
775
  - [ ] PLAN file(s) created by subagent with XML structure
793
- - [ ] Each plan: depends_on, files_modified, autonomous in frontmatter
776
+ - [ ] Each plan: depends_on, files_modified in frontmatter
794
777
  - [ ] Each plan: must_haves derived (truths, artifacts, key_links)
795
778
  - [ ] Each plan: 2-3 tasks (~50% context)
796
779
  - [ ] Wave structure maximizes parallelism
@@ -139,25 +139,63 @@ Skip internal/non-observable items (refactors, type changes, etc.).
139
139
  </step>
140
140
 
141
141
  <step name="classify_tests">
142
- **Classify all tests by mock requirements:**
142
+ **Classify all tests by mock requirements using two-tier analysis:**
143
143
 
144
- For each test, analyze the expected behavior to determine:
144
+ For each test, determine:
145
145
  1. **mock_required**: Does this need special backend state?
146
- 2. **mock_type**: Freeform string describing needed state (e.g., "error_state", "premium_user", "empty_response")
146
+ 2. **mock_type**: Classification (e.g., "transient_state", "external_data", "error_state", "premium_user", "empty_response")
147
147
  3. **dependencies**: Other tests this depends on (infer from descriptions)
148
148
 
149
- **Classification heuristics:**
149
+ **Tier 1: SUMMARY.md mock_hints (primary)**
150
+
151
+ Check if SUMMARY.md files contain mock_hints frontmatter:
152
+ ```bash
153
+ grep -l "mock_hints:" "$PHASE_DIR"/*-SUMMARY.md 2>/dev/null
154
+ ```
155
+
156
+ If found, check the value:
157
+
158
+ - **`mock_hints: none`** → Short-circuit: all tests start as `mock_required: false`. Apply keyword heuristics only as safety net (scan test descriptions for obvious mock signals like "error", "loading", "empty").
159
+
160
+ - **`mock_hints` with content** → Parse and match tests against hints:
161
+ - Test relates to a `transient_states` entry → `mock_type: "transient_state"`, `mock_reason: "[from hint]"`
162
+ - Test relates to an `external_data` entry → `mock_type: "external_data"`, `needs_user_confirmation: true`
163
+ - Test doesn't match any hint → apply keyword heuristics below
164
+
165
+ **Tier 2: Inline classification (fallback for legacy summaries)**
166
+
167
+ When no `mock_hints` key found in any SUMMARY.md (legacy summaries written before executor populated this field):
168
+
169
+ Classify in main context using the two-question framework:
170
+
171
+ 1. **Is the observable state transient?** — Does it appear briefly during async operations? (loading skeleton, spinner, transition animation). If YES → `mock_type: "transient_state"`
172
+
173
+ 2. **Does the test depend on external data?** — Does the feature fetch from an API, database, or external service? Would the test fail without specific data existing? If YES → `mock_type: "external_data"`, `needs_user_confirmation: true`
174
+
175
+ Reason over SUMMARY.md content (accomplishments, files created/modified, decisions) to answer these questions. Supplement with keyword heuristics:
150
176
 
151
177
  | Expected behavior contains | Likely mock_type |
152
178
  |---------------------------|------------------|
153
- | "error", "fails", "invalid" | error_state |
179
+ | "error", "fails", "invalid", "retry" | error_state |
154
180
  | "premium", "pro", "paid", "subscription" | premium_user |
155
181
  | "empty", "no results", "placeholder" | empty_response |
156
- | "loading", "spinner", "skeleton" | loading_state |
182
+ | "loading", "spinner", "skeleton" | transient_state |
157
183
  | "offline", "no connection" | offline_state |
158
184
  | Normal happy path | no mock needed |
159
185
 
160
- **Dependency inference:**
186
+ For tests that remain genuinely uncertain after both the two-question framework and keyword heuristics, present them via AskUserQuestion grouped by uncertainty:
187
+ ```
188
+ questions:
189
+ - question: "Does [test name] require mock data or a special app state to test?"
190
+ header: "Mock needed?"
191
+ options:
192
+ - label: "No mock needed"
193
+ description: "Can test with real/local data"
194
+ - label: "Needs mock"
195
+ description: "Requires simulated state or data"
196
+ ```
197
+
198
+ **Dependency inference (both tiers):**
161
199
  - "Reply to comment" depends on "View comments"
162
200
  - "Delete account" depends on "Login"
163
201
  - Tests mentioning prior state depend on tests that create that state
@@ -173,12 +211,21 @@ tests:
173
211
  - name: "Login error message"
174
212
  mock_required: true
175
213
  mock_type: "error_state"
214
+ mock_reason: "error response from auth endpoint"
176
215
  dependencies: ["login_flow"]
177
216
 
178
- - name: "Premium badge display"
217
+ - name: "Recipe list loading skeleton"
179
218
  mock_required: true
180
- mock_type: "premium_user"
181
- dependencies: ["login_flow"]
219
+ mock_type: "transient_state"
220
+ mock_reason: "loading skeleton during recipe fetch — async, resolves in <1s"
221
+ dependencies: []
222
+
223
+ - name: "View recipe list"
224
+ mock_required: true
225
+ mock_type: "external_data"
226
+ mock_reason: "recipe items from /api/recipes"
227
+ needs_user_confirmation: true
228
+ dependencies: []
182
229
  ```
183
230
  </step>
184
231
 
@@ -189,10 +236,33 @@ tests:
189
236
 
190
237
  **Rules:**
191
238
  1. Group by mock_type (tests needing same mock state go together)
192
- 2. Respect dependencies (if B depends on A, A must be in same or earlier batch)
193
- 3. Max 4 tests per batch (AskUserQuestion limit)
194
- 4. No-mock tests first (run before any mock setup)
195
- 5. Order mock states logically: success → error → empty → loading
239
+ 2. **User confirmation for external_data tests:** Before batching, collect all tests with `needs_user_confirmation: true`, grouped by data source. Present via AskUserQuestion:
240
+
241
+ ```
242
+ questions:
243
+ - question: "Do you have [data_type] data from [source] locally?"
244
+ header: "[data_type]"
245
+ options:
246
+ - label: "Yes, data exists"
247
+ description: "I have [data_type] in my local environment"
248
+ - label: "No, needs mock"
249
+ description: "I need this data mocked for testing"
250
+ - label: "Skip these tests"
251
+ description: "Log as assumptions and move on"
252
+ multiSelect: false
253
+ ```
254
+
255
+ Handle responses:
256
+ - "Yes, data exists" → reclassify affected tests as `mock_required: false`
257
+ - "No, needs mock" → keep as `mock_required: true`, `mock_type: "external_data"`
258
+ - "Skip these tests" → mark all affected tests as `skipped`
259
+
260
+ Group by data source (not per-test) to stay within AskUserQuestion's 4-question limit.
261
+
262
+ 3. **Separate transient_state batch:** Transient states use a different mock strategy (delay/force) than data mocks. Give them their own batch.
263
+ 4. Respect dependencies (if B depends on A, A must be in same or earlier batch)
264
+ 5. Max 4 tests per batch (AskUserQuestion limit)
265
+ 6. Batch ordering: no-mock → external_data → error_state → empty_response → transient_state → premium_user → offline_state
196
266
 
197
267
  **Batch structure:**
198
268
  ```yaml
@@ -203,14 +273,24 @@ batches:
203
273
  tests: [1, 2, 3]
204
274
 
205
275
  - batch: 2
276
+ name: "External Data"
277
+ mock_type: "external_data"
278
+ tests: [4, 5]
279
+
280
+ - batch: 3
206
281
  name: "Error States"
207
282
  mock_type: "error_state"
208
- tests: [4, 5, 6, 7]
283
+ tests: [6, 7, 8]
209
284
 
210
- - batch: 3
285
+ - batch: 4
286
+ name: "Transient States"
287
+ mock_type: "transient_state"
288
+ tests: [9, 10]
289
+
290
+ - batch: 5
211
291
  name: "Premium Features"
212
292
  mock_type: "premium_user"
213
- tests: [8, 9, 10]
293
+ tests: [11, 12]
214
294
  ```
215
295
  </step>
216
296
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mindsystem-cc",
3
- "version": "3.10.1",
3
+ "version": "3.11.0",
4
4
  "description": "A meta-prompting, context engineering and spec-driven development system for Claude Code by TÂCHES.",
5
5
  "bin": {
6
6
  "mindsystem-cc": "bin/install.js"
@@ -0,0 +1,219 @@
1
+ #!/usr/bin/env python3
2
+ # /// script
3
+ # requires-python = ">=3.10"
4
+ # ///
5
+ """Combine variant-*.html mockup files into a single side-by-side comparison page."""
6
+
7
+ import re
8
+ import sys
9
+ from pathlib import Path
10
+
11
+
12
+ def extract_title(html: str) -> str:
13
+ """Extract the content of the <title> tag from an HTML string."""
14
+ match = re.search(r"<title>(.*?)</title>", html, re.IGNORECASE)
15
+ return match.group(1) if match else "Untitled"
16
+
17
+
18
+ def is_device_mockup(html: str) -> bool:
19
+ """Detect if the HTML is a phone-frame mockup (has a fixed-size .device element)."""
20
+ return bool(re.search(r"\.device\s*\{", html))
21
+
22
+
23
+ def build_device_html(panels: list[tuple[str, str]]) -> str:
24
+ """Side-by-side layout for phone-frame mockups."""
25
+ panels_html = ""
26
+ for label, filename in panels:
27
+ panels_html += f"""
28
+ <div class="panel">
29
+ <h2>{label}</h2>
30
+ <iframe src="{filename}"></iframe>
31
+ </div>"""
32
+
33
+ return f"""\
34
+ <!DOCTYPE html>
35
+ <html lang="en">
36
+ <head>
37
+ <meta charset="UTF-8">
38
+ <title>Mockup Comparison</title>
39
+ <style>
40
+ * {{ margin: 0; padding: 0; box-sizing: border-box; }}
41
+ body {{
42
+ background: #1a1a1a;
43
+ color: #fff;
44
+ font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", sans-serif;
45
+ padding: 24px;
46
+ }}
47
+ h1 {{
48
+ text-align: center;
49
+ margin-bottom: 24px;
50
+ font-size: 24px;
51
+ font-weight: 600;
52
+ }}
53
+ .container {{
54
+ display: flex;
55
+ justify-content: center;
56
+ gap: 32px;
57
+ flex-wrap: wrap;
58
+ }}
59
+ .panel {{
60
+ display: flex;
61
+ flex-direction: column;
62
+ align-items: center;
63
+ gap: 12px;
64
+ }}
65
+ .panel h2 {{
66
+ font-size: 16px;
67
+ font-weight: 500;
68
+ color: #ccc;
69
+ }}
70
+ iframe {{
71
+ border: none;
72
+ border-radius: 8px;
73
+ background: #e5e5e5;
74
+ width: 450px;
75
+ height: 920px;
76
+ }}
77
+ </style>
78
+ </head>
79
+ <body>
80
+ <h1>Mockup Comparison</h1>
81
+ <div class="container">{panels_html}
82
+ </div>
83
+ </body>
84
+ </html>
85
+ """
86
+
87
+
88
+ def build_fluid_html(panels: list[tuple[str, str]]) -> str:
89
+ """Tabbed layout for full web page mockups."""
90
+ tabs_html = ""
91
+ panes_html = ""
92
+ for i, (label, filename) in enumerate(panels):
93
+ active = " active" if i == 0 else ""
94
+ tabs_html += f"""
95
+ <button class="tab{active}" data-index="{i}">{label}</button>"""
96
+ panes_html += f"""
97
+ <iframe class="pane{active}" data-index="{i}" src="{filename}"></iframe>"""
98
+
99
+ return f"""\
100
+ <!DOCTYPE html>
101
+ <html lang="en">
102
+ <head>
103
+ <meta charset="UTF-8">
104
+ <title>Mockup Comparison</title>
105
+ <style>
106
+ * {{ margin: 0; padding: 0; box-sizing: border-box; }}
107
+ html, body {{ height: 100%; }}
108
+ body {{
109
+ background: #1a1a1a;
110
+ color: #fff;
111
+ font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", sans-serif;
112
+ display: flex;
113
+ flex-direction: column;
114
+ }}
115
+ .tab-bar {{
116
+ display: flex;
117
+ gap: 4px;
118
+ padding: 16px 24px 0;
119
+ flex-shrink: 0;
120
+ }}
121
+ .tab {{
122
+ padding: 10px 24px;
123
+ border: none;
124
+ border-radius: 8px 8px 0 0;
125
+ background: #2a2a2a;
126
+ color: #888;
127
+ font-size: 14px;
128
+ font-weight: 500;
129
+ font-family: inherit;
130
+ cursor: pointer;
131
+ transition: background 0.15s, color 0.15s;
132
+ }}
133
+ .tab:hover {{
134
+ background: #333;
135
+ color: #bbb;
136
+ }}
137
+ .tab.active {{
138
+ background: #e5e5e5;
139
+ color: #111;
140
+ }}
141
+ .pane-container {{
142
+ flex: 1;
143
+ padding: 0 24px 24px;
144
+ min-height: 0;
145
+ }}
146
+ .pane {{
147
+ display: none;
148
+ width: 100%;
149
+ height: 100%;
150
+ border: none;
151
+ border-radius: 0 8px 8px 8px;
152
+ background: #e5e5e5;
153
+ }}
154
+ .pane.active {{
155
+ display: block;
156
+ }}
157
+ </style>
158
+ </head>
159
+ <body>
160
+ <div class="tab-bar">{tabs_html}
161
+ </div>
162
+ <div class="pane-container">{panes_html}
163
+ </div>
164
+ <script>
165
+ document.querySelectorAll('.tab').forEach(tab => {{
166
+ tab.addEventListener('click', () => {{
167
+ const idx = tab.dataset.index;
168
+ document.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
169
+ document.querySelectorAll('.pane').forEach(p => p.classList.remove('active'));
170
+ tab.classList.add('active');
171
+ document.querySelector('.pane[data-index="' + idx + '"]').classList.add('active');
172
+ }});
173
+ }});
174
+ </script>
175
+ </body>
176
+ </html>
177
+ """
178
+
179
+
180
+ def main() -> None:
181
+ if len(sys.argv) > 1:
182
+ mockups_dir = Path(sys.argv[1])
183
+ else:
184
+ mockups_dir = Path.cwd()
185
+
186
+ variants = sorted(mockups_dir.glob("variant-*.html"))
187
+ if not variants:
188
+ print(f"No variant-*.html files found in {mockups_dir}", file=sys.stderr)
189
+ sys.exit(1)
190
+
191
+ print(f"Found {len(variants)} variants: {', '.join(v.name for v in variants)}")
192
+
193
+ # Read variants and detect layout mode
194
+ panels: list[tuple[str, str]] = []
195
+ all_device = True
196
+ for path in variants:
197
+ html = path.read_text()
198
+ letter = path.stem.split("-")[-1].upper()
199
+ title = extract_title(html)
200
+ label = f"Variant {letter}: {title}"
201
+ if not is_device_mockup(html):
202
+ all_device = False
203
+ panels.append((label, path.name))
204
+
205
+ mode = "device" if all_device else "fluid"
206
+ print(f"Layout mode: {mode}")
207
+
208
+ if mode == "device":
209
+ comparison = build_device_html(panels)
210
+ else:
211
+ comparison = build_fluid_html(panels)
212
+
213
+ output = mockups_dir / "comparison.html"
214
+ output.write_text(comparison)
215
+ print(f"Generated: {output}")
216
+
217
+
218
+ if __name__ == "__main__":
219
+ main()
@@ -1,50 +0,0 @@
1
- <checkpoint_detection>
2
- Lite reference for identifying checkpoint types during task breakdown. Full checkpoint templates and examples are in the ms-plan-writer subagent.
3
-
4
- <checkpoint_types>
5
-
6
- | Type | Use When | Frequency |
7
- |------|----------|-----------|
8
- | `checkpoint:human-verify` | Claude automated work, human confirms visual/functional correctness | 90% |
9
- | `checkpoint:decision` | Human must choose between options affecting implementation | 9% |
10
- | `checkpoint:human-action` | Truly unavoidable manual step with no CLI/API (rare) | 1% |
11
-
12
- </checkpoint_types>
13
-
14
- <detection_rules>
15
-
16
- **Mark as `checkpoint:human-verify` when:**
17
- - Visual UI checks needed (layout, styling, responsiveness)
18
- - Interactive flows require human testing (click through wizard, test user flows)
19
- - Functional verification beyond automated tests (feature works as expected)
20
- - Audio/video playback, animation smoothness, accessibility
21
-
22
- **Mark as `checkpoint:decision` when:**
23
- - Technology selection (auth provider, database, library)
24
- - Architecture choices (monorepo vs separate, API patterns)
25
- - Design decisions (color scheme, layout approach)
26
- - Feature prioritization between variants
27
-
28
- **Mark as `checkpoint:human-action` when (rare):**
29
- - Email verification links (account creation)
30
- - SMS 2FA codes (phone verification)
31
- - Manual account approvals
32
- - Credit card 3D Secure flows
33
- - OAuth app approvals requiring browser
34
-
35
- </detection_rules>
36
-
37
- <automation_first_principle>
38
- **If it has CLI/API, Claude automates it. No exceptions.**
39
-
40
- Never create `checkpoint:human-action` for:
41
- - Deployments (use `vercel`, `railway`, `fly` CLI)
42
- - Database operations (use provider CLI)
43
- - Webhook setup (use APIs)
44
- - Environment files (use Write tool)
45
- - Running builds/tests (use Bash tool)
46
-
47
- The rule: Claude does everything automatable. Checkpoints verify AFTER automation, not replace it.
48
- </automation_first_principle>
49
-
50
- </checkpoint_detection>