mindsystem-cc 3.10.0 → 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.
- package/README.md +3 -6
- package/agents/ms-designer.md +8 -8
- package/agents/ms-executor.md +14 -163
- package/agents/ms-plan-checker.md +2 -3
- package/agents/ms-plan-writer.md +5 -11
- package/agents/ms-roadmapper.md +101 -16
- package/agents/ms-verify-fixer.md +1 -1
- package/commands/ms/complete-milestone.md +1 -1
- package/commands/ms/create-roadmap.md +126 -56
- package/commands/ms/design-phase.md +12 -10
- package/commands/ms/execute-phase.md +0 -9
- package/commands/ms/help.md +24 -35
- package/commands/ms/new-milestone.md +184 -80
- package/commands/ms/new-project.md +3 -3
- package/commands/ms/research-project.md +2 -2
- package/commands/ms/review-design.md +9 -5
- package/commands/ms/verify-work.md +1 -1
- package/mindsystem/references/continuation-format.md +2 -3
- package/mindsystem/references/design-directions.md +1 -1
- package/mindsystem/references/mock-patterns.md +48 -0
- package/mindsystem/references/plan-format.md +2 -129
- package/mindsystem/references/routing/between-milestones-routing.md +5 -7
- package/mindsystem/references/scope-estimation.md +3 -3
- package/mindsystem/templates/config.json +0 -2
- package/mindsystem/templates/design.md +1 -1
- package/mindsystem/templates/milestone-context.md +76 -0
- package/mindsystem/templates/phase-prompt.md +6 -142
- package/mindsystem/templates/summary.md +24 -0
- package/mindsystem/workflows/complete-milestone.md +27 -8
- package/mindsystem/workflows/execute-phase.md +35 -124
- package/mindsystem/workflows/execute-plan.md +12 -517
- package/mindsystem/workflows/generate-mocks.md +74 -0
- package/mindsystem/workflows/mockup-generation.md +1 -1
- package/mindsystem/workflows/plan-phase.md +7 -24
- package/mindsystem/workflows/verify-work.md +97 -17
- package/package.json +1 -1
- package/scripts/__pycache__/compare_mockups.cpython-314.pyc +0 -0
- package/scripts/compare_mockups.py +219 -0
- package/skills/flutter-code-quality/SKILL.md +1 -1
- package/skills/flutter-code-simplification/SKILL.md +1 -1
- package/skills/flutter-senior-review/AGENTS.md +1 -1
- package/skills/flutter-senior-review/SKILL.md +1 -1
- package/commands/ms/define-requirements.md +0 -128
- package/mindsystem/references/checkpoint-detection.md +0 -50
- package/mindsystem/references/checkpoints.md +0 -788
- package/mindsystem/workflows/create-milestone.md +0 -243
- package/mindsystem/workflows/discuss-milestone.md +0 -310
|
@@ -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,
|
|
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
|
|
452
|
+
- **Type**: auto
|
|
454
453
|
- **Task name**: Clear, action-oriented
|
|
455
|
-
- **Files**: Which files created/modified
|
|
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
|
-
**
|
|
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.
|
|
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
|
|
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
|
|
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,
|
|
144
|
+
For each test, determine:
|
|
145
145
|
1. **mock_required**: Does this need special backend state?
|
|
146
|
-
2. **mock_type**:
|
|
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
|
-
**
|
|
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" |
|
|
182
|
+
| "loading", "spinner", "skeleton" | transient_state |
|
|
157
183
|
| "offline", "no connection" | offline_state |
|
|
158
184
|
| Normal happy path | no mock needed |
|
|
159
185
|
|
|
160
|
-
|
|
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: "
|
|
217
|
+
- name: "Recipe list loading skeleton"
|
|
179
218
|
mock_required: true
|
|
180
|
-
mock_type: "
|
|
181
|
-
|
|
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.
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
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: [
|
|
283
|
+
tests: [6, 7, 8]
|
|
209
284
|
|
|
210
|
-
- batch:
|
|
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: [
|
|
293
|
+
tests: [11, 12]
|
|
214
294
|
```
|
|
215
295
|
</step>
|
|
216
296
|
|
package/package.json
CHANGED
|
Binary file
|
|
@@ -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()
|
|
@@ -3,7 +3,7 @@ name: flutter-code-quality
|
|
|
3
3
|
description: Flutter/Dart code quality, widget organization, and folder structure guidelines. Use when reviewing, refactoring, or cleaning up Flutter code after implementation.
|
|
4
4
|
license: MIT
|
|
5
5
|
metadata:
|
|
6
|
-
author:
|
|
6
|
+
author: Roland Tolnay
|
|
7
7
|
version: "1.0.0"
|
|
8
8
|
date: January 2026
|
|
9
9
|
argument-hint: <file-or-pattern>
|
|
@@ -3,7 +3,7 @@ name: flutter-code-simplification
|
|
|
3
3
|
description: Flutter/Dart code simplification principles. Use when simplifying, refactoring, or cleaning up Flutter code for clarity and maintainability.
|
|
4
4
|
license: MIT
|
|
5
5
|
metadata:
|
|
6
|
-
author:
|
|
6
|
+
author: Roland Tolnay
|
|
7
7
|
version: "1.0.0"
|
|
8
8
|
date: January 2026
|
|
9
9
|
argument-hint: <file-or-pattern>
|
|
@@ -3,7 +3,7 @@ name: flutter-senior-review
|
|
|
3
3
|
description: Senior engineering principles for Flutter/Dart code reviews. Apply when reviewing, refactoring, or writing Flutter code to identify structural improvements that make code evolvable, not just working.
|
|
4
4
|
license: MIT
|
|
5
5
|
metadata:
|
|
6
|
-
author:
|
|
6
|
+
author: Roland Tolnay
|
|
7
7
|
version: "1.0.0"
|
|
8
8
|
date: January 2026
|
|
9
9
|
abstract: Code review framework focused on structural improvements that typical reviews miss. Uses 3 core lenses (State Modeling, Responsibility Boundaries, Abstraction Timing) backed by 12 detailed principles organized into 4 categories. Each principle includes detection signals, smell examples, senior solutions, and Dart-specific patterns.
|
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: ms:define-requirements
|
|
3
|
-
description: Define what "done" looks like with checkable requirements
|
|
4
|
-
allowed-tools:
|
|
5
|
-
- Read
|
|
6
|
-
- Write
|
|
7
|
-
- Bash
|
|
8
|
-
- Glob
|
|
9
|
-
- AskUserQuestion
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
<objective>
|
|
13
|
-
Define concrete, checkable requirements for v1.
|
|
14
|
-
|
|
15
|
-
Two modes:
|
|
16
|
-
1. **With research** — Transform FEATURES.md into scoped requirements
|
|
17
|
-
2. **Without research** — Gather requirements through questioning
|
|
18
|
-
|
|
19
|
-
Run before `/ms:create-roadmap`.
|
|
20
|
-
|
|
21
|
-
Output: `.planning/REQUIREMENTS.md`
|
|
22
|
-
</objective>
|
|
23
|
-
|
|
24
|
-
<execution_context>
|
|
25
|
-
@~/.claude/mindsystem/references/principles.md
|
|
26
|
-
@~/.claude/mindsystem/workflows/define-requirements.md
|
|
27
|
-
@~/.claude/mindsystem/templates/requirements.md
|
|
28
|
-
</execution_context>
|
|
29
|
-
|
|
30
|
-
<context>
|
|
31
|
-
@.planning/PROJECT.md
|
|
32
|
-
@.planning/research/FEATURES.md (if exists)
|
|
33
|
-
@.planning/research/SUMMARY.md (if exists)
|
|
34
|
-
</context>
|
|
35
|
-
|
|
36
|
-
<process>
|
|
37
|
-
|
|
38
|
-
<step name="validate">
|
|
39
|
-
```bash
|
|
40
|
-
# Verify project exists
|
|
41
|
-
[ -f .planning/PROJECT.md ] || { echo "ERROR: No PROJECT.md found. Run /ms:new-project first."; exit 1; }
|
|
42
|
-
|
|
43
|
-
# Check for research
|
|
44
|
-
[ -f .planning/research/FEATURES.md ] && echo "HAS_RESEARCH" || echo "NO_RESEARCH"
|
|
45
|
-
|
|
46
|
-
# Check if requirements already exist
|
|
47
|
-
[ -f .planning/REQUIREMENTS.md ] && echo "REQUIREMENTS_EXISTS" || echo "NO_REQUIREMENTS"
|
|
48
|
-
```
|
|
49
|
-
</step>
|
|
50
|
-
|
|
51
|
-
<step name="check_existing">
|
|
52
|
-
**If REQUIREMENTS_EXISTS:**
|
|
53
|
-
|
|
54
|
-
Use AskUserQuestion:
|
|
55
|
-
- header: "Requirements exist"
|
|
56
|
-
- question: "Requirements already defined. What would you like to do?"
|
|
57
|
-
- options:
|
|
58
|
-
- "View existing" — Show current requirements
|
|
59
|
-
- "Replace" — Define requirements fresh (will overwrite)
|
|
60
|
-
- "Cancel" — Keep existing requirements
|
|
61
|
-
|
|
62
|
-
If "View existing": Read and display `.planning/REQUIREMENTS.md`, then exit
|
|
63
|
-
If "Cancel": Exit
|
|
64
|
-
If "Replace": Continue with workflow
|
|
65
|
-
</step>
|
|
66
|
-
|
|
67
|
-
<step name="execute">
|
|
68
|
-
**If HAS_RESEARCH:**
|
|
69
|
-
Follow the define-requirements.md workflow:
|
|
70
|
-
- Load research features from FEATURES.md
|
|
71
|
-
- Present features by category
|
|
72
|
-
- Ask user to scope each category (v1 / v2 / out of scope)
|
|
73
|
-
- Capture any additions research missed
|
|
74
|
-
- Generate REQUIREMENTS.md with checkable list
|
|
75
|
-
|
|
76
|
-
**If NO_RESEARCH:**
|
|
77
|
-
Gather requirements through questioning:
|
|
78
|
-
- Read PROJECT.md for core value and context
|
|
79
|
-
- Ask: "What are the main things users need to be able to do?"
|
|
80
|
-
- For each capability mentioned, probe for specifics
|
|
81
|
-
- Group into categories (Authentication, Content, etc.)
|
|
82
|
-
- For each category, ask what's v1 vs v2 vs out of scope
|
|
83
|
-
- Generate REQUIREMENTS.md with checkable list
|
|
84
|
-
|
|
85
|
-
Same output format either way — the difference is source (research vs conversation).
|
|
86
|
-
</step>
|
|
87
|
-
|
|
88
|
-
<step name="done">
|
|
89
|
-
```
|
|
90
|
-
Requirements defined:
|
|
91
|
-
|
|
92
|
-
- Requirements: .planning/REQUIREMENTS.md
|
|
93
|
-
- v1 scope: [N] requirements across [M] categories
|
|
94
|
-
- v2 scope: [X] requirements deferred
|
|
95
|
-
- Out of scope: [Y] requirements excluded
|
|
96
|
-
|
|
97
|
-
---
|
|
98
|
-
|
|
99
|
-
## ▶ Next Up
|
|
100
|
-
|
|
101
|
-
**Create roadmap** — phases mapped to requirements
|
|
102
|
-
|
|
103
|
-
`/ms:create-roadmap`
|
|
104
|
-
|
|
105
|
-
<sub>`/clear` first → fresh context window</sub>
|
|
106
|
-
|
|
107
|
-
---
|
|
108
|
-
```
|
|
109
|
-
</step>
|
|
110
|
-
|
|
111
|
-
<step name="update_last_command">
|
|
112
|
-
Update `.planning/STATE.md` Last Command field:
|
|
113
|
-
- Find line starting with `Last Command:` in Current Position section
|
|
114
|
-
- Replace with: `Last Command: ms:define-requirements | YYYY-MM-DD HH:MM`
|
|
115
|
-
- If line doesn't exist, add it after `Status:` line
|
|
116
|
-
</step>
|
|
117
|
-
|
|
118
|
-
</process>
|
|
119
|
-
|
|
120
|
-
<success_criteria>
|
|
121
|
-
- [ ] PROJECT.md validated
|
|
122
|
-
- [ ] Features gathered (from research OR questioning)
|
|
123
|
-
- [ ] User scoped each category (v1/v2/out of scope)
|
|
124
|
-
- [ ] User had opportunity to add missing requirements
|
|
125
|
-
- [ ] REQUIREMENTS.md created with checkable list
|
|
126
|
-
- [ ] Requirements committed to git
|
|
127
|
-
- [ ] User knows next step (create-roadmap)
|
|
128
|
-
</success_criteria>
|