@ulysses-ai/create-workspace 0.13.0-beta.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 (86) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +108 -0
  3. package/bin/create.mjs +79 -0
  4. package/lib/git.mjs +26 -0
  5. package/lib/init.mjs +129 -0
  6. package/lib/payload.mjs +44 -0
  7. package/lib/prompts.mjs +113 -0
  8. package/lib/scaffold.mjs +84 -0
  9. package/lib/upgrade.mjs +42 -0
  10. package/package.json +43 -0
  11. package/template/.claude/agents/aside-researcher.md +48 -0
  12. package/template/.claude/agents/implementer.md +39 -0
  13. package/template/.claude/agents/researcher.md +40 -0
  14. package/template/.claude/agents/reviewer.md +47 -0
  15. package/template/.claude/hooks/_utils.mjs +196 -0
  16. package/template/.claude/hooks/_utils.test.mjs +99 -0
  17. package/template/.claude/hooks/post-compact.mjs +7 -0
  18. package/template/.claude/hooks/pre-compact.mjs +34 -0
  19. package/template/.claude/hooks/repo-write-detection.mjs +107 -0
  20. package/template/.claude/hooks/session-end.mjs +91 -0
  21. package/template/.claude/hooks/session-start.mjs +150 -0
  22. package/template/.claude/hooks/subagent-start.mjs +44 -0
  23. package/template/.claude/hooks/workspace-update-check.mjs +42 -0
  24. package/template/.claude/hooks/worktree-create.mjs +53 -0
  25. package/template/.claude/lib/session-frontmatter.mjs +265 -0
  26. package/template/.claude/lib/session-frontmatter.test.mjs +242 -0
  27. package/template/.claude/recipes/migrate-from-notion.md +120 -0
  28. package/template/.claude/rules/agent-rules.md.skip +32 -0
  29. package/template/.claude/rules/cloud-infrastructure.md.skip +15 -0
  30. package/template/.claude/rules/coherent-revisions.md +24 -0
  31. package/template/.claude/rules/documentation.md.skip +13 -0
  32. package/template/.claude/rules/git-conventions.md +34 -0
  33. package/template/.claude/rules/honest-pushback.md +56 -0
  34. package/template/.claude/rules/local-dev-environment.md.skip +60 -0
  35. package/template/.claude/rules/memory-guidance.md +26 -0
  36. package/template/.claude/rules/product-integrity.md.skip +24 -0
  37. package/template/.claude/rules/scope-guard.md.skip +22 -0
  38. package/template/.claude/rules/superpowers-workflow.md.skip +22 -0
  39. package/template/.claude/rules/token-economics.md.skip +31 -0
  40. package/template/.claude/rules/work-item-tracking.md +90 -0
  41. package/template/.claude/rules/workspace-structure.md +69 -0
  42. package/template/.claude/scripts/add-repo-to-session.mjs +78 -0
  43. package/template/.claude/scripts/cleanup-work-session.mjs +108 -0
  44. package/template/.claude/scripts/create-work-session.mjs +124 -0
  45. package/template/.claude/scripts/migrate-open-work.mjs +91 -0
  46. package/template/.claude/scripts/migrate-session-layout.mjs +236 -0
  47. package/template/.claude/scripts/migrate-session-layout.test.mjs +144 -0
  48. package/template/.claude/scripts/trackers/github-issues.mjs +170 -0
  49. package/template/.claude/scripts/trackers/github-issues.test.mjs +190 -0
  50. package/template/.claude/scripts/trackers/interface.mjs +25 -0
  51. package/template/.claude/scripts/trackers/interface.test.mjs +40 -0
  52. package/template/.claude/settings.json +107 -0
  53. package/template/.claude/skills/aside/SKILL.md +125 -0
  54. package/template/.claude/skills/braindump/SKILL.md +96 -0
  55. package/template/.claude/skills/build-docs-site/SKILL.md +323 -0
  56. package/template/.claude/skills/build-docs-site/checklists/framing.md +221 -0
  57. package/template/.claude/skills/build-docs-site/checklists/pitfalls.md +228 -0
  58. package/template/.claude/skills/build-docs-site/checklists/review.md +130 -0
  59. package/template/.claude/skills/build-docs-site/scripts/bulk-fill-migration.py +393 -0
  60. package/template/.claude/skills/build-docs-site/scripts/forbidden-word-grep.mjs +159 -0
  61. package/template/.claude/skills/build-docs-site/scripts/leak-grep.mjs +328 -0
  62. package/template/.claude/skills/build-docs-site/templates/custom.css.tmpl +212 -0
  63. package/template/.claude/skills/build-docs-site/templates/docusaurus.config.ts.tmpl +95 -0
  64. package/template/.claude/skills/build-docs-site/templates/primitives/Arrow.tsx +87 -0
  65. package/template/.claude/skills/build-docs-site/templates/primitives/Box.tsx +90 -0
  66. package/template/.claude/skills/build-docs-site/templates/primitives/DiagramContainer.tsx +46 -0
  67. package/template/.claude/skills/build-docs-site/templates/primitives/Region.tsx +68 -0
  68. package/template/.claude/skills/build-docs-site/templates/primitives/SectionTitle.tsx +42 -0
  69. package/template/.claude/skills/build-docs-site/templates/primitives/tokens.ts +67 -0
  70. package/template/.claude/skills/build-docs-site/templates/sidebars.ts.tmpl +89 -0
  71. package/template/.claude/skills/build-docs-site/templates/spec.md.tmpl +119 -0
  72. package/template/.claude/skills/complete-work/SKILL.md +369 -0
  73. package/template/.claude/skills/handoff/SKILL.md +98 -0
  74. package/template/.claude/skills/maintenance/SKILL.md +116 -0
  75. package/template/.claude/skills/pause-work/SKILL.md +98 -0
  76. package/template/.claude/skills/promote/SKILL.md +77 -0
  77. package/template/.claude/skills/release/SKILL.md +126 -0
  78. package/template/.claude/skills/setup-tracker/SKILL.md +117 -0
  79. package/template/.claude/skills/start-work/SKILL.md +234 -0
  80. package/template/.claude/skills/sync-work/SKILL.md +73 -0
  81. package/template/.claude/skills/workspace-init/SKILL.md +420 -0
  82. package/template/.claude/skills/workspace-update/SKILL.md +108 -0
  83. package/template/.mcp.json +12 -0
  84. package/template/CLAUDE.md.tmpl +32 -0
  85. package/template/_gitignore +28 -0
  86. package/template/workspace.json.tmpl +15 -0
@@ -0,0 +1,228 @@
1
+ # Pitfalls Checklist
2
+
3
+ Known traps in building a documentation site with diagrams. Each section: symptom, cause, fix, verification.
4
+
5
+ These were captured from real production work. Don't rediscover them — apply the fixes from the start.
6
+
7
+ ---
8
+
9
+ ## 1. CSS variables in SVG `fill` and `stroke`
10
+
11
+ ### Symptom
12
+
13
+ Diagrams render blank or with wrong colors in dark mode, even though `getComputedStyle` reports the expected resolved color values.
14
+
15
+ ### Cause
16
+
17
+ CSS variables used directly in SVG presentation attributes (`fill="var(--x)"`) or inline styles (`style={{fill: 'var(--x)'}}`) do not paint reliably across all loading contexts in Chromium. The variables resolve when queried via JS but the SVG paint pipeline may not honor them, especially when the SVG is loaded as an external file or when there's a hidden specificity conflict with a presentation attribute on the same element.
18
+
19
+ ### Fix
20
+
21
+ Use **class selectors** instead. CSS variables resolve through class rules consistently because the cascade evaluates them before the paint stage:
22
+
23
+ ```css
24
+ :root {
25
+ --dx-primary: #3B6EA8;
26
+ }
27
+ [data-theme='dark'] {
28
+ --dx-primary: #5A9FFF;
29
+ }
30
+
31
+ .dx-fill-primary { fill: var(--dx-primary); }
32
+ .dx-stroke-primary { stroke: var(--dx-primary); }
33
+ ```
34
+
35
+ Apply via `className`, never `fill`:
36
+
37
+ ```tsx
38
+ // Wrong
39
+ <rect fill={`var(--dx-primary)`} />
40
+ <rect style={{fill: 'var(--dx-primary)'}} />
41
+
42
+ // Right
43
+ <rect className="dx-fill-primary" />
44
+ ```
45
+
46
+ The diagram primitives library exports a `cls` map for this:
47
+
48
+ ```tsx
49
+ import { cls } from './tokens';
50
+ <rect className={cls.fill.primary} />
51
+ ```
52
+
53
+ ### Verification
54
+
55
+ Inspect the rendered DOM via `browser_evaluate`:
56
+
57
+ ```js
58
+ const rect = document.querySelector('rect.dx-fill-primary');
59
+ console.log(getComputedStyle(rect).fill);
60
+ // → rgb(91, 158, 255) in dark mode, rgb(59, 110, 168) in light mode
61
+ ```
62
+
63
+ Both modes should produce real RGB values, not the literal string `"var(--dx-primary)"`.
64
+
65
+ ---
66
+
67
+ ## 2. Bulk migration regressions
68
+
69
+ ### Symptom
70
+
71
+ After running `bulk-fill-migration.py` to convert `fill={colors.X}` to class-based styling:
72
+ - TypeScript build fails with `cls is not defined`
73
+ - Some elements have stale colors that don't update with theme switching
74
+ - Some elements have two `className=` attributes in the source
75
+
76
+ ### Cause
77
+
78
+ Three known issues with mechanical replacement:
79
+
80
+ 1. **Duplicate `className=`** — elements that already had a `className` attribute end up with two after the migration. JSX silently keeps only the second, which is the original (now-stale) one.
81
+ 2. **Missing `cls` import** — the migration adds `cls.fill.X` references but doesn't update the import line. Build fails.
82
+ 3. **Variable-bound fills** — patterns like `fill={labelColor}`, `fill={fillByVariant[variant]}`, or ternary fills are not matched by the script's regex. They stay as hardcoded colors.
83
+
84
+ ### Fix
85
+
86
+ The script handles issues 1 and 2 automatically:
87
+
88
+ - **Duplicate `className=`** → merged into a single template literal `className={\`${a} ${b}\`}`
89
+ - **Missing `cls` import** → added to any line matching `import { ... } from '...tokens...'`
90
+
91
+ For issue 3 (variable-bound fills), the script reports them in `needsManualReview` and the user fixes them by hand. Common patterns to fix:
92
+
93
+ ```tsx
94
+ // Before
95
+ const labelColor = isHighlighted ? colors.primary : colors.text;
96
+ <text fill={labelColor}>Label</text>
97
+
98
+ // After
99
+ <text className={isHighlighted ? cls.fill.primary : cls.fill.text}>Label</text>
100
+ ```
101
+
102
+ ```tsx
103
+ // Before
104
+ const fillsByVariant = [colors.primary, colors.accent, colors.text];
105
+ <rect fill={fillsByVariant[i]} />
106
+
107
+ // After
108
+ const fillClassesByVariant = [cls.fill.primary, cls.fill.accent, cls.fill.text];
109
+ <rect className={fillClassesByVariant[i]} />
110
+ ```
111
+
112
+ ### Verification
113
+
114
+ Run the migration script with `--dry-run` first to see what will change. After applying, run the build:
115
+
116
+ ```bash
117
+ npm run build
118
+ ```
119
+
120
+ If the build fails on `cls is not defined`, manually add `cls` to the import line. If the build succeeds but a chapter's diagrams don't theme-switch, check `needsManualReview` from the script output and fix those files by hand.
121
+
122
+ ---
123
+
124
+ ## 3. Playwright viewport screenshot quirks
125
+
126
+ ### Symptom
127
+
128
+ Playwright viewport-cropped screenshots of diagram regions come back blank, even though the diagrams render correctly when you visit the page in a real browser.
129
+
130
+ ### Cause
131
+
132
+ Best guess: scroll position and viewport sizing interact in Playwright's screenshot path such that the diagram region falls outside the captured viewport even when the visible browser shows it. Never fully diagnosed — the workaround is sufficient.
133
+
134
+ ### Fix
135
+
136
+ **Don't trust viewport screenshots for diagram debugging.** Use one of:
137
+
138
+ 1. **Full-page screenshots** (slower but reliable):
139
+ ```js
140
+ await page.screenshot({ fullPage: true });
141
+ ```
142
+
143
+ 2. **DOM inspection via `browser_evaluate`** (fastest, most authoritative):
144
+ ```js
145
+ const rect = document.querySelector('.dx-fill-primary');
146
+ console.log({
147
+ classes: rect.className.baseVal,
148
+ computedFill: getComputedStyle(rect).fill,
149
+ boundingBox: rect.getBoundingClientRect(),
150
+ });
151
+ ```
152
+
153
+ DOM inspection is the source of truth. If the DOM has the right classes and the computed style has the right resolved color, the diagram is correct — regardless of what a screenshot shows.
154
+
155
+ ### Verification
156
+
157
+ When in doubt, reload the page in your real browser. Visual confirmation overrides any automated screenshot.
158
+
159
+ ---
160
+
161
+ ## 4. Arrowhead markers don't theme-switch
162
+
163
+ ### Symptom
164
+
165
+ Arrow lines change color correctly between light and dark modes, but the arrowhead tips stay in light-mode color.
166
+
167
+ ### Cause
168
+
169
+ SVG `<marker>` elements live in a shadow DOM tree that does not inherit CSS classes from the host document. Class selectors don't apply to marker contents.
170
+
171
+ ### Fix
172
+
173
+ Two options:
174
+
175
+ 1. **Accept the cosmetic mismatch.** If the arrowhead color is close enough that it doesn't look broken, leave it. This is the simplest path — flag it as known-not-blocking and move on.
176
+
177
+ 2. **Render two markers and switch via media query.** Define separate marker elements for each theme and switch using a CSS media query on `prefers-color-scheme`. More work, but theme-correct.
178
+
179
+ The Arrow primitive in the library defaults to option 1 — passes a literal `markerColor` hex. Override per-arrow if needed for option 2.
180
+
181
+ ### Verification
182
+
183
+ Toggle dark mode in the browser. If the arrowheads look "off" against the new background, decide whether to live with it or implement option 2.
184
+
185
+ ---
186
+
187
+ ## 5. Notion exports — nested zips and emoji filenames
188
+
189
+ ### Symptom
190
+
191
+ When ingesting a Notion export into Phase 2 source gathering:
192
+ - The downloaded file is a zip containing another zip
193
+ - The standard `unzip` command fails partway through with errors about invalid characters
194
+
195
+ ### Cause
196
+
197
+ Notion exports two levels deep — the outer zip contains workspace metadata plus an inner zip with the actual page content. The inner zip contains filenames with emoji characters that confuse the standard `unzip` command on macOS and Linux.
198
+
199
+ ### Fix
200
+
201
+ Use Python's `zipfile` module, which handles Unicode filenames correctly:
202
+
203
+ ```python
204
+ import zipfile
205
+
206
+ # Step 1: extract the outer zip
207
+ with zipfile.ZipFile('notion-export.zip', 'r') as outer:
208
+ outer.extractall('extracted/')
209
+
210
+ # Step 2: find and extract the inner zip
211
+ import glob
212
+ inner_zips = glob.glob('extracted/**/*.zip', recursive=True)
213
+ for inner_zip in inner_zips:
214
+ with zipfile.ZipFile(inner_zip, 'r') as inner:
215
+ inner.extractall('extracted-inner/')
216
+ ```
217
+
218
+ ### Verification
219
+
220
+ After extraction, check that you have a flat directory of markdown files with their attachment folders. The filenames should preserve their emoji characters (e.g., `🏗 Architecture.md`), not become garbled.
221
+
222
+ Move the extracted files to `workspace-scratchpad/` for working access, not shared context. They're raw material, not source of truth.
223
+
224
+ ---
225
+
226
+ ## When to update this checklist
227
+
228
+ If you encounter a new pitfall while running this skill, add it here with the same five-section format (symptom, cause, fix, verification, when to update). The point of this file is to prevent rediscovery — every captured pitfall saves the next person hours.
@@ -0,0 +1,130 @@
1
+ # Review Checklist
2
+
3
+ The four review sweeps for `/build-docs-site` Phase 6. Run each pass fully before moving to the next. Each pass surfaces issues; the user decides on each one before completion.
4
+
5
+ ---
6
+
7
+ ## Pass 1 — Leak grep (implementation-detail detection)
8
+
9
+ **What it does:** Scans the project's dependency manifests to derive a list of installed packages, then greps documentation content for any mention of those names. Project-accurate detection, no hardcoded master list.
10
+
11
+ **Run:**
12
+ ```bash
13
+ node .claude/skills/build-docs-site/scripts/leak-grep.mjs {project-root} {docs-path}
14
+ ```
15
+
16
+ Optional flags:
17
+ - `--exclude path1,path2` — additional file paths to skip beyond the default Tech Stack exclusions
18
+
19
+ **Default exclusions:** Files under paths matching `tech-stack`, `appendix-tech-stack`, `appendix/tech-stack`, `technology`, `stack` are skipped because implementation choices are the subject in those locations.
20
+
21
+ **For each hit:**
22
+
23
+ 1. Show the user: file, line, matched term, context
24
+ 2. Propose a concept-level replacement
25
+ 3. User decides:
26
+ - **Replace** — apply the proposed rewrite
27
+ - **Rewrite** — user provides their own rewrite
28
+ - **Acceptable** — leave as-is (some terms are intentionally named, e.g., a primary integration that deserves naming)
29
+
30
+ **Pass complete when:** every hit has been addressed (replaced, rewritten, or marked acceptable).
31
+
32
+ **Audience consideration:** Strict for external audiences (B, C in framing Q1). More permissive for personal authoritative reference (D) where the author may want to name specific choices they care about.
33
+
34
+ ---
35
+
36
+ ## Pass 2 — Forbidden-word sweep
37
+
38
+ **What it does:** Greps documentation for user-supplied words to avoid (the language-constraints answer from Phase 1).
39
+
40
+ **Run:**
41
+ ```bash
42
+ node .claude/skills/build-docs-site/scripts/forbidden-word-grep.mjs {docs-path} {wordlist.json} [--word-boundary] [--case-sensitive]
43
+ ```
44
+
45
+ The `wordlist.json` was created during Phase 1 from the user's answers. Default options are case-insensitive, no word-boundary requirement.
46
+
47
+ **For each hit:**
48
+
49
+ 1. Show the user: file, line, matched word, reason (if provided), context
50
+ 2. User decides:
51
+ - **Replace** — propose alternate phrasing, user approves or rewrites
52
+ - **Acceptable** — sometimes a hit is a different meaning of the word (e.g., "leverage" as a noun in physics context vs. corporate filler)
53
+
54
+ **Pass complete when:** every hit has been addressed.
55
+
56
+ ---
57
+
58
+ ## Pass 3 — Coverage check
59
+
60
+ **What it does:** Verifies every item in the existing documentation mapping (from the spec) is covered in the new site. This is the pass that ensures the new site is strictly better than the old one — not just rewritten but complete.
61
+
62
+ **No script — this is a manual pass with structure.**
63
+
64
+ **For each row in the spec's "Existing documentation mapping" table:**
65
+
66
+ 1. Read the old file
67
+ 2. Extract the topics it covers (use Claude's reading, not regex)
68
+ 3. Open the mapped new chapter(s)
69
+ 4. Verify each topic is covered
70
+
71
+ **For any topic not covered:**
72
+ - Add it to the new chapter, OR
73
+ - Mark the old file as "partial replacement" and note what wasn't migrated, OR
74
+ - Decide the topic is genuinely obsolete and remove it from the mapping
75
+
76
+ **Update the mapping:**
77
+ - `replaced` — new site fully covers it; old file is safe to delete
78
+ - `partial` — some content didn't migrate; decisions noted in spec
79
+ - `superseded` — old content is obsolete; intentionally not carried forward
80
+
81
+ **Pass complete when:** every mapping row has a final status.
82
+
83
+ ---
84
+
85
+ ## Pass 4 — Visual check
86
+
87
+ **What it does:** Confirms the site builds cleanly and renders correctly in a real browser.
88
+
89
+ **Run:**
90
+ ```bash
91
+ cd {docs-path}
92
+ npm run build # must complete with no errors
93
+ npm start # dev server
94
+ ```
95
+
96
+ **Open in browser** (the user does this):
97
+ - Landing page
98
+ - 2-3 random chapters from different parts
99
+ - A chapter known to have diagrams (if Phase 7 has been done)
100
+
101
+ **Verify:**
102
+ - Layout and spacing feel right (justified text, heading spacing, no awkward gaps)
103
+ - Brand is applied correctly (colors, fonts, logo)
104
+ - Sidebar structure matches the spec
105
+ - Navigation works (sidebar links, breadcrumbs, in-page links)
106
+ - Dark mode toggles correctly
107
+ - Diagrams render (if applicable) — both light and dark modes
108
+ - Nothing visibly broken
109
+
110
+ **For any issues:**
111
+ - CSS polish issues (spacing, alignment, column width) → adjust `custom.css`
112
+ - Broken links → fix the `sidebars.ts` reference or doc id
113
+ - Layout problems → typically a typography setting in `custom.css`
114
+ - Diagram issues in dark mode → check `pitfalls.md` for the CSS-class-cascade pattern
115
+
116
+ **Pass complete when:** the user confirms the site looks ready.
117
+
118
+ ---
119
+
120
+ ## After all four passes
121
+
122
+ Update the session tracker with:
123
+ - Pass 1 hits resolved (count, summary of categories)
124
+ - Pass 2 hits resolved (count)
125
+ - Pass 3 mapping final state (replaced/partial/superseded counts)
126
+ - Pass 4 visual check confirmed
127
+
128
+ If Phase 7 (diagrams) hasn't been done yet, ask the user about doing it now or in a separate session (see SKILL.md Phase 7 checkpoint).
129
+
130
+ If Phase 7 is done, the skill is ready for `/complete-work`.