@1agh/maude 0.15.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 (211) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +166 -0
  3. package/cli/bin/maude.exe +15 -0
  4. package/cli/bin/maude.mjs +45 -0
  5. package/cli/bin/mdcc.exe +10 -0
  6. package/cli/bin/mdcc.mjs +7 -0
  7. package/cli/cli-wrapper.cjs +67 -0
  8. package/cli/commands/config.mjs +94 -0
  9. package/cli/commands/design.mjs +386 -0
  10. package/cli/commands/help.mjs +57 -0
  11. package/cli/commands/init.mjs +178 -0
  12. package/cli/commands/version.mjs +7 -0
  13. package/cli/install.cjs +113 -0
  14. package/cli/lib/argv.mjs +37 -0
  15. package/cli/lib/argv.test.mjs +46 -0
  16. package/cli/lib/copy-tree.mjs +78 -0
  17. package/package.json +94 -0
  18. package/plugins/design/dev-server/annotations-context-toolbar.tsx +397 -0
  19. package/plugins/design/dev-server/annotations-layer.tsx +1717 -0
  20. package/plugins/design/dev-server/api.ts +674 -0
  21. package/plugins/design/dev-server/bin/_screenshot-playwright.mjs +50 -0
  22. package/plugins/design/dev-server/bin/bootstrap-check.sh +83 -0
  23. package/plugins/design/dev-server/bin/canvas-edit.sh +48 -0
  24. package/plugins/design/dev-server/bin/handoff.sh +27 -0
  25. package/plugins/design/dev-server/bin/screenshot.sh +232 -0
  26. package/plugins/design/dev-server/bin/server-up.sh +135 -0
  27. package/plugins/design/dev-server/bin/slug.sh +22 -0
  28. package/plugins/design/dev-server/bin/smoke.sh +272 -0
  29. package/plugins/design/dev-server/build.ts +267 -0
  30. package/plugins/design/dev-server/canvas-build.ts +219 -0
  31. package/plugins/design/dev-server/canvas-edit.ts +388 -0
  32. package/plugins/design/dev-server/canvas-header.ts +165 -0
  33. package/plugins/design/dev-server/canvas-icons.tsx +131 -0
  34. package/plugins/design/dev-server/canvas-lib-inline.ts +260 -0
  35. package/plugins/design/dev-server/canvas-lib-resolver.ts +85 -0
  36. package/plugins/design/dev-server/canvas-lib.tsx +1995 -0
  37. package/plugins/design/dev-server/canvas-meta.schema.json +181 -0
  38. package/plugins/design/dev-server/canvas-pipeline.ts +270 -0
  39. package/plugins/design/dev-server/canvas-shell.tsx +813 -0
  40. package/plugins/design/dev-server/client/app.jsx +2027 -0
  41. package/plugins/design/dev-server/client/hmr.mjs +85 -0
  42. package/plugins/design/dev-server/client/iframe-lazy.mjs +121 -0
  43. package/plugins/design/dev-server/client/index.html +15 -0
  44. package/plugins/design/dev-server/client/styles/0-reset.css +18 -0
  45. package/plugins/design/dev-server/client/styles/1-tokens.css +297 -0
  46. package/plugins/design/dev-server/client/styles/2-layout.css +35 -0
  47. package/plugins/design/dev-server/client/styles/3-shell.css +906 -0
  48. package/plugins/design/dev-server/client/styles/4-components.css +1268 -0
  49. package/plugins/design/dev-server/client/styles/5-utilities.css +4 -0
  50. package/plugins/design/dev-server/client/styles/_index.css +24 -0
  51. package/plugins/design/dev-server/client/styles.css +1419 -0
  52. package/plugins/design/dev-server/config.schema.json +147 -0
  53. package/plugins/design/dev-server/context-menu.tsx +343 -0
  54. package/plugins/design/dev-server/context.ts +173 -0
  55. package/plugins/design/dev-server/dist/client.bundle.js +20323 -0
  56. package/plugins/design/dev-server/dist/styles.css +2875 -0
  57. package/plugins/design/dev-server/examples/README.md +9 -0
  58. package/plugins/design/dev-server/examples/perf-100-artboards.tsx +113 -0
  59. package/plugins/design/dev-server/fs-watch.ts +63 -0
  60. package/plugins/design/dev-server/handoff.ts +721 -0
  61. package/plugins/design/dev-server/history.ts +125 -0
  62. package/plugins/design/dev-server/hmr-broadcast.ts +114 -0
  63. package/plugins/design/dev-server/http.ts +413 -0
  64. package/plugins/design/dev-server/input-router.tsx +485 -0
  65. package/plugins/design/dev-server/inspect.ts +365 -0
  66. package/plugins/design/dev-server/locator.ts +159 -0
  67. package/plugins/design/dev-server/mem.ts +97 -0
  68. package/plugins/design/dev-server/runtime-bundle.ts +235 -0
  69. package/plugins/design/dev-server/server.mjs +1246 -0
  70. package/plugins/design/dev-server/server.ts +131 -0
  71. package/plugins/design/dev-server/test/_helpers.ts +81 -0
  72. package/plugins/design/dev-server/test/active-state.test.ts +145 -0
  73. package/plugins/design/dev-server/test/annotations-api.test.ts +146 -0
  74. package/plugins/design/dev-server/test/annotations-layer.test.ts +419 -0
  75. package/plugins/design/dev-server/test/binary-smoke.test.ts +47 -0
  76. package/plugins/design/dev-server/test/bundle-smoke.test.ts +29 -0
  77. package/plugins/design/dev-server/test/canvas-build.test.ts +78 -0
  78. package/plugins/design/dev-server/test/canvas-edit.test.ts +139 -0
  79. package/plugins/design/dev-server/test/canvas-header.test.ts +127 -0
  80. package/plugins/design/dev-server/test/canvas-lib-inline.test.ts +146 -0
  81. package/plugins/design/dev-server/test/canvas-lib-resolver.test.ts +112 -0
  82. package/plugins/design/dev-server/test/canvas-meta-api.test.ts +236 -0
  83. package/plugins/design/dev-server/test/canvas-pipeline.test.ts +180 -0
  84. package/plugins/design/dev-server/test/canvas-route.test.ts +176 -0
  85. package/plugins/design/dev-server/test/fs-watch.test.ts +41 -0
  86. package/plugins/design/dev-server/test/handoff-static-frames.test.ts +215 -0
  87. package/plugins/design/dev-server/test/handoff.test.ts +281 -0
  88. package/plugins/design/dev-server/test/history-rollback.test.ts +62 -0
  89. package/plugins/design/dev-server/test/hmr-broadcast.test.ts +108 -0
  90. package/plugins/design/dev-server/test/input-router.test.ts +316 -0
  91. package/plugins/design/dev-server/test/locator.test.ts +214 -0
  92. package/plugins/design/dev-server/test/perf-harness.ts +193 -0
  93. package/plugins/design/dev-server/test/phase-3.6-smoke.test.ts +77 -0
  94. package/plugins/design/dev-server/test/runtime-bundle.test.ts +69 -0
  95. package/plugins/design/dev-server/test/server-lifecycle.test.ts +28 -0
  96. package/plugins/design/dev-server/test/tool-palette.test.tsx +55 -0
  97. package/plugins/design/dev-server/test/use-annotation-selection.test.tsx +77 -0
  98. package/plugins/design/dev-server/test/use-artboard-drag.test.ts +325 -0
  99. package/plugins/design/dev-server/test/use-selection-set.test.tsx +166 -0
  100. package/plugins/design/dev-server/test/use-snap-guides.test.ts +190 -0
  101. package/plugins/design/dev-server/test/use-tool-mode.test.tsx +93 -0
  102. package/plugins/design/dev-server/test/ws-handshake.test.ts +33 -0
  103. package/plugins/design/dev-server/tool-palette.tsx +278 -0
  104. package/plugins/design/dev-server/tsconfig.json +26 -0
  105. package/plugins/design/dev-server/use-annotation-selection.tsx +92 -0
  106. package/plugins/design/dev-server/use-annotations-visibility.tsx +43 -0
  107. package/plugins/design/dev-server/use-artboard-drag.tsx +445 -0
  108. package/plugins/design/dev-server/use-selection-set.tsx +224 -0
  109. package/plugins/design/dev-server/use-snap-guides.tsx +215 -0
  110. package/plugins/design/dev-server/use-tool-mode.tsx +114 -0
  111. package/plugins/design/dev-server/ws.ts +90 -0
  112. package/plugins/design/templates/_shell.html +177 -0
  113. package/plugins/design/templates/canvas.tsx.template +54 -0
  114. package/plugins/design/templates/design-system-inspiration/_MAPPING.md +277 -0
  115. package/plugins/design/templates/design-system-inspiration/_README.md +71 -0
  116. package/plugins/design/templates/design-system-inspiration/audience-consumer/components-banner.html +68 -0
  117. package/plugins/design/templates/design-system-inspiration/audience-consumer/components-empty-state-generous.html +39 -0
  118. package/plugins/design/templates/design-system-inspiration/audience-consumer/components-feature-grid.html +62 -0
  119. package/plugins/design/templates/design-system-inspiration/audience-consumer/components-marketing-card.html +63 -0
  120. package/plugins/design/templates/design-system-inspiration/audience-consumer/components-testimonial.html +80 -0
  121. package/plugins/design/templates/design-system-inspiration/audience-developer/components-code-block.html +71 -0
  122. package/plugins/design/templates/design-system-inspiration/audience-developer/components-diff-view.html +65 -0
  123. package/plugins/design/templates/design-system-inspiration/audience-developer/components-log-stream.html +62 -0
  124. package/plugins/design/templates/design-system-inspiration/audience-developer/components-monospace-table.html +57 -0
  125. package/plugins/design/templates/design-system-inspiration/audience-developer/components-terminal-pane.html +67 -0
  126. package/plugins/design/templates/design-system-inspiration/audience-developer/type-mono.html +57 -0
  127. package/plugins/design/templates/design-system-inspiration/audience-pro/colors-presence.html +74 -0
  128. package/plugins/design/templates/design-system-inspiration/audience-pro/components-command-palette.html +90 -0
  129. package/plugins/design/templates/design-system-inspiration/audience-pro/components-keyboard.html +51 -0
  130. package/plugins/design/templates/design-system-inspiration/audience-pro/components-list.html +89 -0
  131. package/plugins/design/templates/design-system-inspiration/audience-pro/components-shortcuts-overlay.html +85 -0
  132. package/plugins/design/templates/design-system-inspiration/audience-pro/components-toast-menu.html +80 -0
  133. package/plugins/design/templates/design-system-inspiration/core/INDEX.md.tpl +25 -0
  134. package/plugins/design/templates/design-system-inspiration/core/README.orchestration.md.tpl +71 -0
  135. package/plugins/design/templates/design-system-inspiration/core/README.philosophy.md.tpl +77 -0
  136. package/plugins/design/templates/design-system-inspiration/core/SKILL.md.tpl +50 -0
  137. package/plugins/design/templates/design-system-inspiration/core/colors_and_type.css.tpl +111 -0
  138. package/plugins/design/templates/design-system-inspiration/core/config.json.tpl +28 -0
  139. package/plugins/design/templates/design-system-inspiration/core/preview/_layout.css +113 -0
  140. package/plugins/design/templates/design-system-inspiration/core/preview/colors-accent.html +48 -0
  141. package/plugins/design/templates/design-system-inspiration/core/preview/colors-surfaces.html +49 -0
  142. package/plugins/design/templates/design-system-inspiration/core/preview/colors-text.html +52 -0
  143. package/plugins/design/templates/design-system-inspiration/core/preview/components-buttons.html +83 -0
  144. package/plugins/design/templates/design-system-inspiration/core/preview/components-cards.html +79 -0
  145. package/plugins/design/templates/design-system-inspiration/core/preview/components-inputs.html +82 -0
  146. package/plugins/design/templates/design-system-inspiration/core/preview/motion.html +66 -0
  147. package/plugins/design/templates/design-system-inspiration/core/preview/spacing-scale.html +53 -0
  148. package/plugins/design/templates/design-system-inspiration/core/preview/type-scale.html +62 -0
  149. package/plugins/design/templates/design-system-inspiration/foundations/borders.html +39 -0
  150. package/plugins/design/templates/design-system-inspiration/foundations/elevation.html +46 -0
  151. package/plugins/design/templates/design-system-inspiration/foundations/focus.html +48 -0
  152. package/plugins/design/templates/design-system-inspiration/foundations/grid.html +51 -0
  153. package/plugins/design/templates/design-system-inspiration/foundations/iconography.html +73 -0
  154. package/plugins/design/templates/design-system-inspiration/foundations/opacity.html +45 -0
  155. package/plugins/design/templates/design-system-inspiration/foundations/radii.html +40 -0
  156. package/plugins/design/templates/design-system-inspiration/foundations/selection.html +45 -0
  157. package/plugins/design/templates/design-system-inspiration/meta/accessibility.html +62 -0
  158. package/plugins/design/templates/design-system-inspiration/meta/i18n.html +73 -0
  159. package/plugins/design/templates/design-system-inspiration/meta/presence-multiplayer.html +71 -0
  160. package/plugins/design/templates/design-system-inspiration/meta/tokens-index.html +80 -0
  161. package/plugins/design/templates/design-system-inspiration/patterns/patterns-auth.html +78 -0
  162. package/plugins/design/templates/design-system-inspiration/patterns/patterns-data-density.html +61 -0
  163. package/plugins/design/templates/design-system-inspiration/patterns/patterns-error-pages.html +70 -0
  164. package/plugins/design/templates/design-system-inspiration/patterns/patterns-form-layouts.html +70 -0
  165. package/plugins/design/templates/design-system-inspiration/patterns/patterns-onboarding.html +71 -0
  166. package/plugins/design/templates/design-system-inspiration/patterns/patterns-pricing.html +83 -0
  167. package/plugins/design/templates/design-system-inspiration/platform-desktop/components-resize-panels.html +63 -0
  168. package/plugins/design/templates/design-system-inspiration/platform-desktop/ui_kits-desktop-index.html +55 -0
  169. package/plugins/design/templates/design-system-inspiration/platform-desktop/ui_kits-desktop-showcase.html +302 -0
  170. package/plugins/design/templates/design-system-inspiration/platform-mobile/components-bottom-sheet.html +63 -0
  171. package/plugins/design/templates/design-system-inspiration/platform-mobile/components-pull-to-refresh.html +74 -0
  172. package/plugins/design/templates/design-system-inspiration/platform-mobile/components-segmented-control.html +51 -0
  173. package/plugins/design/templates/design-system-inspiration/platform-mobile/components-tab-bar.html +57 -0
  174. package/plugins/design/templates/design-system-inspiration/platform-mobile/ui_kits-mobile-index.html +58 -0
  175. package/plugins/design/templates/design-system-inspiration/platform-mobile/ui_kits-mobile-showcase.html +237 -0
  176. package/plugins/design/templates/design-system-inspiration/status/colors-status.html +49 -0
  177. package/plugins/design/templates/design-system-inspiration/status/components-status.html +63 -0
  178. package/plugins/design/templates/design-system-inspiration/status/skeletons.html +74 -0
  179. package/plugins/design/templates/design-system-inspiration/theme-both/colors-themes-side-by-side.html +59 -0
  180. package/plugins/design/templates/design-system-inspiration/universal/components-callout.html +74 -0
  181. package/plugins/design/templates/design-system-inspiration/universal/components-dialogs.html +81 -0
  182. package/plugins/design/templates/design-system-inspiration/universal/components-tables.html +101 -0
  183. package/plugins/design/templates/design-system-inspiration/universal/components-toggles.html +74 -0
  184. package/plugins/design/templates/design-system-inspiration/universal/components-tooltips.html +74 -0
  185. package/plugins/design/templates/design-system-inspiration/universal/empty-state.html.tpl +34 -0
  186. package/plugins/design/templates/design-system-inspiration/universal/logo.html +42 -0
  187. package/plugins/design/templates/ds-specimen.tsx.template +59 -0
  188. package/plugins/flow/.claude-plugin/config.schema.json +398 -0
  189. package/plugins/flow/README.md +45 -0
  190. package/plugins/flow/templates/ai-skeleton/INDEX.md +50 -0
  191. package/plugins/flow/templates/ai-skeleton/README.md +46 -0
  192. package/plugins/flow/templates/ai-skeleton/browser/har/.gitkeep +0 -0
  193. package/plugins/flow/templates/ai-skeleton/browser/snapshots/.gitkeep +0 -0
  194. package/plugins/flow/templates/ai-skeleton/business/README.md +12 -0
  195. package/plugins/flow/templates/ai-skeleton/context/README.md +12 -0
  196. package/plugins/flow/templates/ai-skeleton/decisions/README.md +20 -0
  197. package/plugins/flow/templates/ai-skeleton/design-import/.gitkeep +0 -0
  198. package/plugins/flow/templates/ai-skeleton/dev-logs/.gitkeep +0 -0
  199. package/plugins/flow/templates/ai-skeleton/device/.gitkeep +0 -0
  200. package/plugins/flow/templates/ai-skeleton/docs/README.md +5 -0
  201. package/plugins/flow/templates/ai-skeleton/logs/.gitkeep +0 -0
  202. package/plugins/flow/templates/ai-skeleton/logs/README.md +13 -0
  203. package/plugins/flow/templates/ai-skeleton/plans/README.md +16 -0
  204. package/plugins/flow/templates/ai-skeleton/plans/archive/.gitkeep +0 -0
  205. package/plugins/flow/templates/ai-skeleton/release-guide.md +35 -0
  206. package/plugins/flow/templates/ai-skeleton/reviews/README.md +15 -0
  207. package/plugins/flow/templates/ai-skeleton/scenarios/README.md +26 -0
  208. package/plugins/flow/templates/ai-skeleton/scenarios/_lib/.gitkeep +0 -0
  209. package/plugins/flow/templates/ai-skeleton/state/STATE.md +25 -0
  210. package/plugins/flow/templates/ai-skeleton/templates/HANDOFF.md +32 -0
  211. package/plugins/flow/templates/ai-skeleton/workflows.config.json +74 -0
@@ -0,0 +1,50 @@
1
+ // _screenshot-playwright.mjs — playwright fallback for screenshot.sh.
2
+ // Element-scoped form (playwright CLI has no --selector flag, so we drive
3
+ // chromium via the API for that case). Full-page form is also implemented
4
+ // here so screenshot.sh has a single fallback entrypoint regardless of mode.
5
+ //
6
+ // Invocation (called by screenshot.sh — not directly by users):
7
+ // npm exec --package=playwright -- node _screenshot-playwright.mjs \
8
+ // --url <url> [--selector <css>] --out <path> [--timeout 8]
9
+ //
10
+ // First invocation may install chromium (~150 MB). Subsequent runs reuse cache.
11
+
12
+ import { mkdirSync } from 'node:fs';
13
+ import { dirname } from 'node:path';
14
+ import { chromium } from 'playwright';
15
+
16
+ const args = Object.fromEntries(
17
+ process.argv.slice(2).reduce((acc, cur, i, all) => {
18
+ if (cur.startsWith('--')) acc.push([cur.slice(2), all[i + 1]]);
19
+ return acc;
20
+ }, [])
21
+ );
22
+
23
+ const { url, selector, out, timeout = '8' } = args;
24
+ if (!url || !out) {
25
+ console.error(
26
+ 'usage: _screenshot-playwright.mjs --url <url> [--selector <css>] --out <path> [--timeout 8]'
27
+ );
28
+ process.exit(2);
29
+ }
30
+
31
+ const timeoutMs = Number(timeout) * 1000;
32
+ mkdirSync(dirname(out), { recursive: true });
33
+
34
+ const browser = await chromium.launch();
35
+ try {
36
+ const ctx = await browser.newContext({ viewport: { width: 1440, height: 900 } });
37
+ const page = await ctx.newPage();
38
+ await page.goto(url, { waitUntil: 'networkidle', timeout: timeoutMs });
39
+
40
+ if (selector) {
41
+ const loc = page.locator(selector).first();
42
+ await loc.waitFor({ state: 'visible', timeout: timeoutMs });
43
+ await loc.screenshot({ path: out });
44
+ } else {
45
+ await page.screenshot({ path: out, fullPage: true });
46
+ }
47
+ console.error(`✓ playwright wrote ${out}`);
48
+ } finally {
49
+ await browser.close();
50
+ }
@@ -0,0 +1,83 @@
1
+ #!/usr/bin/env bash
2
+ # bootstrap-check.sh — detect whether the project has a usable design system.
3
+ # Canonical recipe (was inline in `commands/new.md` step 0 + `commands/edit.md` step 0).
4
+ #
5
+ # Usage:
6
+ # bootstrap-check.sh # human-readable next-step on stdout, exit 0/10/11
7
+ # bootstrap-check.sh --json # JSON on stdout, exit 0/10/11
8
+ # bootstrap-check.sh --shell-export # `export FOO=bar` lines on stdout, eval-friendly
9
+ #
10
+ # Exit codes:
11
+ # 0 — ready (config + at least one DS in system/)
12
+ # 10 — needs `/design:init` (no .design/config.json)
13
+ # 11 — needs `/design:setup-ds` (config present, no DS folders)
14
+
15
+ MODE="default"
16
+ case "$1" in
17
+ --json) MODE="json" ;;
18
+ --shell-export) MODE="shell" ;;
19
+ --help|-h)
20
+ sed -n '2,16p' "$0" | sed 's/^# \?//'
21
+ exit 0
22
+ ;;
23
+ "") ;;
24
+ *)
25
+ echo "bootstrap-check.sh: unknown arg '$1' (try --help)" >&2
26
+ exit 2
27
+ ;;
28
+ esac
29
+
30
+ REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
31
+ CFG="$REPO_ROOT/.design/config.json"
32
+
33
+ CONFIG_PRESENT="false"
34
+ [ -f "$CFG" ] && CONFIG_PRESENT="true"
35
+
36
+ HAS_DS="false"
37
+ if [ -d "$REPO_ROOT/.design/system" ]; then
38
+ if find "$REPO_ROOT/.design/system" -mindepth 1 -maxdepth 1 -type d 2>/dev/null | grep -q .; then
39
+ HAS_DS="true"
40
+ fi
41
+ fi
42
+
43
+ KNOWN_DS=""
44
+ DEFAULT_DS="project"
45
+ if [ "$CONFIG_PRESENT" = "true" ] && command -v jq >/dev/null 2>&1; then
46
+ KNOWN_DS=$(jq -r '.designSystems[]?.name // empty' "$CFG" 2>/dev/null | tr '\n' ' ' | sed 's/ $//')
47
+ ds_default=$(jq -r '.defaultDesignSystem // empty' "$CFG" 2>/dev/null)
48
+ [ -n "$ds_default" ] && DEFAULT_DS="$ds_default"
49
+ fi
50
+
51
+ # Decide exit code
52
+ EXIT_CODE=0
53
+ if [ "$CONFIG_PRESENT" = "false" ]; then
54
+ EXIT_CODE=10
55
+ elif [ "$HAS_DS" = "false" ]; then
56
+ EXIT_CODE=11
57
+ fi
58
+
59
+ case "$MODE" in
60
+ json)
61
+ printf '{"has_ds":%s,"config_present":%s,"repo_root":"%s","known_ds":[%s],"default_ds":"%s","exit_code":%d}\n' \
62
+ "$HAS_DS" "$CONFIG_PRESENT" "$REPO_ROOT" \
63
+ "$(printf '%s' "$KNOWN_DS" | awk 'NF{for(i=1;i<=NF;i++) printf "%s\"%s\"",(i>1?",":""),$i}')" \
64
+ "$DEFAULT_DS" "$EXIT_CODE"
65
+ ;;
66
+ shell)
67
+ printf 'export HAS_DS=%s\n' "$HAS_DS"
68
+ printf 'export CONFIG_PRESENT=%s\n' "$CONFIG_PRESENT"
69
+ printf 'export REPO_ROOT=%s\n' "$REPO_ROOT"
70
+ printf 'export KNOWN_DS=%s\n' "\"$KNOWN_DS\""
71
+ printf 'export DEFAULT_DS=%s\n' "$DEFAULT_DS"
72
+ printf 'export BOOTSTRAP_EXIT=%d\n' "$EXIT_CODE"
73
+ ;;
74
+ default)
75
+ case "$EXIT_CODE" in
76
+ 0) echo "✓ ready — design system(s): ${KNOWN_DS:-$DEFAULT_DS}" ;;
77
+ 10) echo "→ Run /design:init first (no .design/config.json found at $REPO_ROOT)" ;;
78
+ 11) echo "→ Run /design:setup-ds <name> first (no DS in $REPO_ROOT/.design/system/)" ;;
79
+ esac
80
+ ;;
81
+ esac
82
+
83
+ exit $EXIT_CODE
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/env bash
2
+ # canvas-edit.sh — AST-aware single-attribute edit on a canvas .tsx file.
3
+ # Wraps `plugins/design/dev-server/canvas-edit.ts` so /design:edit Step 3a can
4
+ # shell out without booting a Bun module loader inline. Phase 3.6 Task 5.
5
+ #
6
+ # Usage: canvas-edit.sh <canvas-abs-path> <data-cd-id> <attr> <value>
7
+ #
8
+ # <canvas-abs-path> absolute path of the .tsx canvas file
9
+ # <data-cd-id> 8-hex id from the inspector / _locator.json
10
+ # <attr> "className" | "style.<prop>" | any JSX attribute name
11
+ # <value> new value (bare string for className / plain attrs;
12
+ # a JS expression for style.<prop> — e.g. '"#facc15"',
13
+ # `14`, `"calc(100% - 2px)"`)
14
+ #
15
+ # Exit codes:
16
+ # 0 edit applied (or no-op when source already matched)
17
+ # 1 bad usage / missing file
18
+ # 2 AST edit failed (id not found, parse error, unsupported attribute shape)
19
+ #
20
+ # Output:
21
+ # On success, prints one JSON line: {"canvas": "...", "id": "...", "delta": <int>}
22
+ # On failure, prints the underlying error to stderr.
23
+ #
24
+ # This script intentionally has no fallback path — Bun is the only supported
25
+ # runtime (DDR-009). Callers should pre-flight `mdcc --version` if the
26
+ # environment is uncertain.
27
+
28
+ set -euo pipefail
29
+
30
+ if [ $# -lt 4 ] || [ "$1" = "--help" ] || [ "$1" = "-h" ]; then
31
+ echo "Usage: canvas-edit.sh <canvas-abs-path> <data-cd-id> <attr> <value>" >&2
32
+ [ "$1" = "--help" ] || [ "$1" = "-h" ] && exit 0
33
+ exit 1
34
+ fi
35
+
36
+ CANVAS="$1"
37
+ ID="$2"
38
+ ATTR="$3"
39
+ VALUE="$4"
40
+
41
+ if [ ! -f "$CANVAS" ]; then
42
+ echo "canvas-edit: file not found: $CANVAS" >&2
43
+ exit 1
44
+ fi
45
+
46
+ HERE="$(cd "$(dirname "$0")/.." && pwd)"
47
+
48
+ bun --silent run "$HERE/canvas-edit.ts" --invoke "$CANVAS" "$ID" "$ATTR" "$VALUE" 2>&1 || exit 2
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env bash
2
+ # /design:handoff CLI wrapper — emits <Slug>.registry.json sidecar next to a
3
+ # canvas TSX. Thin shell-out so /design:handoff doesn't have to spin up Bun
4
+ # from the orchestrator side.
5
+ #
6
+ # Usage:
7
+ # bin/handoff.sh <canvas-abs-path> [designRoot]
8
+ #
9
+ # Output (stdout, line 1): JSON {"dest":"...","files":N,"deps":M}
10
+ # Exit code 0 on success, 2 on any failure (with reason on stderr).
11
+
12
+ set -euo pipefail
13
+
14
+ if [ $# -lt 1 ]; then
15
+ echo "usage: handoff.sh <canvas-abs-path> [designRoot]" >&2
16
+ exit 2
17
+ fi
18
+
19
+ CANVAS="$1"
20
+ DESIGN_ROOT="${2:-}"
21
+
22
+ DIR="$(cd "$(dirname "$0")/.." && pwd)"
23
+ if [ -n "$DESIGN_ROOT" ]; then
24
+ exec bun run "$DIR/handoff.ts" --emit "$CANVAS" "$DESIGN_ROOT"
25
+ else
26
+ exec bun run "$DIR/handoff.ts" --emit "$CANVAS"
27
+ fi
@@ -0,0 +1,232 @@
1
+ #!/usr/bin/env bash
2
+ # screenshot.sh — canonical screenshot helper for the design plugin.
3
+ # Wraps agent-browser (preferred) or playwright (fallback). Replaces the
4
+ # inline `agent-browser navigate + screenshot` bash blocks previously
5
+ # duplicated across new.md / edit.md / setup-ds.md / screenshot.md / critics.
6
+ #
7
+ # Usage:
8
+ # screenshot.sh [--port N | --url URL]
9
+ # [--screen <id> | --element <id> | --selector <css> | --full]
10
+ # [--all-screens] [--out <path>] [--out-dir <dir>]
11
+ # [--timeout 8] [--engine auto|agent-browser|playwright]
12
+ # [--root <repo>]
13
+ #
14
+ # Notes:
15
+ # - Exactly one of --screen / --element / --selector / --full is required
16
+ # (or --all-screens which loops over every [data-dc-screen]/[data-dc-slot]).
17
+ # - --out required for single-shot modes; --out-dir required for --all-screens.
18
+ # - URL resolution: --url > --port + _active.json > _server.json + _active.json.
19
+ # - Stdout: written PNG paths, one per line (composable in for-loops).
20
+ # - Stderr: diagnostic, engine choice, timing.
21
+ # - Exit: 0 success / 1 missing dependency / 2 bad args / 3 capture failed.
22
+
23
+ MODE=""
24
+ SEL=""
25
+ URL=""
26
+ PORT=""
27
+ OUT=""
28
+ OUT_DIR=""
29
+ TIMEOUT=8
30
+ ENGINE="auto"
31
+ ALL_SCREENS=0
32
+ ROOT=""
33
+
34
+ while [ $# -gt 0 ]; do
35
+ case "$1" in
36
+ --screen) MODE="screen"; SEL="$2"; shift 2 ;;
37
+ --element) MODE="element"; SEL="$2"; shift 2 ;;
38
+ --selector) MODE="selector"; SEL="$2"; shift 2 ;;
39
+ --full) MODE="full"; shift ;;
40
+ --all-screens) ALL_SCREENS=1; shift ;;
41
+ --url) URL="$2"; shift 2 ;;
42
+ --port) PORT="$2"; shift 2 ;;
43
+ --out) OUT="$2"; shift 2 ;;
44
+ --out-dir) OUT_DIR="$2"; shift 2 ;;
45
+ --timeout) TIMEOUT="$2"; shift 2 ;;
46
+ --engine) ENGINE="$2"; shift 2 ;;
47
+ --root) ROOT="$2"; shift 2 ;;
48
+ --help|-h)
49
+ sed -n '2,22p' "$0" | sed 's/^# \?//'
50
+ exit 0
51
+ ;;
52
+ *)
53
+ echo "screenshot.sh: unknown arg '$1' (try --help)" >&2
54
+ exit 2
55
+ ;;
56
+ esac
57
+ done
58
+
59
+ # ---------- arg validation ----------
60
+ if [ $ALL_SCREENS -eq 1 ]; then
61
+ [ -z "$OUT_DIR" ] && { echo "screenshot.sh: --all-screens needs --out-dir" >&2; exit 2; }
62
+ else
63
+ [ -z "$MODE" ] && { echo "screenshot.sh: pick one of --full/--screen/--element/--selector or --all-screens" >&2; exit 2; }
64
+ [ -z "$OUT" ] && { echo "screenshot.sh: --out required for single-shot modes" >&2; exit 2; }
65
+ fi
66
+
67
+ # ---------- url resolution ----------
68
+ if [ -z "$URL" ]; then
69
+ REPO="${ROOT:-${CLAUDE_PROJECT_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}}"
70
+ STATE="$REPO/.design/_server.json"
71
+ ACTIVE_JSON="$REPO/.design/_active.json"
72
+ if [ -z "$PORT" ] && [ -f "$STATE" ]; then
73
+ if command -v jq >/dev/null 2>&1; then
74
+ PORT=$(jq -r .port "$STATE" 2>/dev/null)
75
+ else
76
+ PORT=$(sed -nE 's/.*"port"[[:space:]]*:[[:space:]]*([0-9]+).*/\1/p' "$STATE" | head -n1)
77
+ fi
78
+ fi
79
+ [ -z "$PORT" ] && { echo "screenshot.sh: no --url/--port given and _server.json not found (run server-up.sh)" >&2; exit 1; }
80
+
81
+ if [ -f "$ACTIVE_JSON" ] && command -v jq >/dev/null 2>&1; then
82
+ ACTIVE=$(jq -r '.active // empty' "$ACTIVE_JSON" 2>/dev/null)
83
+ fi
84
+ [ -z "$ACTIVE" ] && { echo "screenshot.sh: no active canvas in _active.json (open one in browser first)" >&2; exit 1; }
85
+
86
+ # URL-encode spaces (rough); leave other chars alone.
87
+ ACTIVE_ENC=$(printf '%s' "$ACTIVE" | sed 's/ /%20/g')
88
+ URL="http://localhost:${PORT}/${ACTIVE_ENC}"
89
+ fi
90
+
91
+ # ---------- selector mapping ----------
92
+ case "$MODE" in
93
+ screen) CSS_SEL="[data-dc-screen=\"$SEL\"], [data-dc-slot=\"$SEL\"]" ;;
94
+ element) CSS_SEL="[data-dc-element=\"$SEL\"]" ;;
95
+ selector) CSS_SEL="$SEL" ;;
96
+ full|"") CSS_SEL="" ;;
97
+ esac
98
+
99
+ # ---------- engine resolution ----------
100
+ if [ "$ENGINE" = "auto" ]; then
101
+ if command -v agent-browser >/dev/null 2>&1; then
102
+ ENGINE="agent-browser"
103
+ else
104
+ ENGINE="playwright"
105
+ fi
106
+ fi
107
+ echo "→ screenshot engine: $ENGINE | url: $URL" >&2
108
+
109
+ # ---------- engine: agent-browser ----------
110
+ ab_screenshot() {
111
+ local css="$1"
112
+ local out="$2"
113
+ if [ -n "$css" ]; then
114
+ agent-browser screenshot "$css" "$out" >&2 || return 1
115
+ else
116
+ agent-browser screenshot --full "$out" >&2 || return 1
117
+ fi
118
+ # agent-browser sometimes reports success without writing — verify size.
119
+ if [ ! -s "$out" ]; then
120
+ echo "✗ agent-browser reported success but output file missing/empty: $out" >&2
121
+ return 1
122
+ fi
123
+ return 0
124
+ }
125
+
126
+ # ---------- engine: playwright ----------
127
+ pw_screenshot() {
128
+ local css="$1"
129
+ local out="$2"
130
+ local script_dir
131
+ script_dir="$(cd "$(dirname "$0")" && pwd)"
132
+ local pw_script="$script_dir/_screenshot-playwright.mjs"
133
+ if [ ! -f "$pw_script" ]; then
134
+ echo "✗ playwright fallback shim missing at $pw_script" >&2
135
+ return 1
136
+ fi
137
+ echo "→ playwright engine; first invocation may install chromium (~150MB, one-off)" >&2
138
+ if [ -n "$css" ]; then
139
+ npm exec --yes --package=playwright -- node "$pw_script" --url "$URL" --selector "$css" --out "$out" --timeout "$TIMEOUT" >&2 || return 1
140
+ else
141
+ npm exec --yes --package=playwright -- node "$pw_script" --url "$URL" --out "$out" --timeout "$TIMEOUT" >&2 || return 1
142
+ fi
143
+ [ -s "$out" ] || { echo "✗ playwright wrote no file: $out" >&2; return 1; }
144
+ return 0
145
+ }
146
+
147
+ navigate_once() {
148
+ if [ "$ENGINE" = "agent-browser" ]; then
149
+ agent-browser open "$URL" >&2
150
+ # Wait for canvas to mount — Babel/React canvases take 2–4s to settle.
151
+ # Poll for [data-dc-screen] or [data-dc-slot] up to $TIMEOUT seconds; fall
152
+ # through to a fixed sleep when the page isn't a DC canvas.
153
+ local poll=0
154
+ local got=0
155
+ while [ $poll -lt "$TIMEOUT" ]; do
156
+ sleep 1
157
+ poll=$((poll + 1))
158
+ local raw
159
+ raw=$(agent-browser eval "document.querySelectorAll('[data-dc-screen],[data-dc-slot]').length" 2>/dev/null)
160
+ # raw is a plain number on success — strip whitespace, validate.
161
+ local has=$(printf '%s' "$raw" | tr -d '[:space:]')
162
+ case "$has" in
163
+ ''|*[!0-9]*) continue ;;
164
+ 0) continue ;;
165
+ *) got=1; break ;;
166
+ esac
167
+ done
168
+ if [ $got -eq 0 ]; then
169
+ # Fallback: give static pages (specimens, non-canvas HTMLs) a chance.
170
+ echo "→ no DC mount detected after ${TIMEOUT}s — proceeding (may be a non-canvas page)" >&2
171
+ sleep 1
172
+ fi
173
+ fi
174
+ }
175
+
176
+ capture() {
177
+ local css="$1"
178
+ local out="$2"
179
+ mkdir -p "$(dirname "$out")"
180
+ if [ "$ENGINE" = "agent-browser" ]; then
181
+ ab_screenshot "$css" "$out"
182
+ else
183
+ pw_screenshot "$css" "$out"
184
+ fi
185
+ }
186
+
187
+ # ---------- --all-screens loop ----------
188
+ if [ $ALL_SCREENS -eq 1 ]; then
189
+ mkdir -p "$OUT_DIR"
190
+ navigate_once
191
+ IDS=""
192
+ if [ "$ENGINE" = "agent-browser" ]; then
193
+ # agent-browser wraps string results in quotes and escapes newlines as
194
+ # literal `\n`; comma-join + tr is simpler than parsing JSON for IDs.
195
+ raw=$(agent-browser eval \
196
+ "Array.from(document.querySelectorAll('[data-dc-screen],[data-dc-slot]')).map(e => e.getAttribute('data-dc-screen') || e.getAttribute('data-dc-slot')).filter(Boolean).join(',')" \
197
+ 2>/dev/null)
198
+ # Strip surrounding quotes, then split on comma.
199
+ IDS=$(printf '%s' "$raw" | sed 's/^"//; s/"$//' | tr ',' '\n')
200
+ fi
201
+ if [ -z "$IDS" ]; then
202
+ echo "✗ no [data-dc-screen]/[data-dc-slot] elements found (or eval unavailable on this engine)" >&2
203
+ exit 3
204
+ fi
205
+ N=0
206
+ FAILED=0
207
+ for ID in $IDS; do
208
+ N=$((N + 1))
209
+ NN=$(printf "%03d" "$N")
210
+ OUT_FILE="$OUT_DIR/${NN}-screen-${ID}.png"
211
+ if [ "$ENGINE" = "agent-browser" ]; then
212
+ agent-browser eval "document.querySelector('[data-dc-screen=\"$ID\"], [data-dc-slot=\"$ID\"]').scrollIntoView({block:'center'})" >/dev/null 2>&1
213
+ sleep 0.6
214
+ fi
215
+ if capture "[data-dc-screen=\"$ID\"], [data-dc-slot=\"$ID\"]" "$OUT_FILE"; then
216
+ echo "$OUT_FILE"
217
+ else
218
+ echo "✗ failed: $ID" >&2
219
+ FAILED=$((FAILED + 1))
220
+ fi
221
+ done
222
+ [ $FAILED -gt 0 ] && exit 3
223
+ exit 0
224
+ fi
225
+
226
+ # ---------- single-shot ----------
227
+ navigate_once
228
+ if capture "$CSS_SEL" "$OUT"; then
229
+ echo "$OUT"
230
+ exit 0
231
+ fi
232
+ exit 3
@@ -0,0 +1,135 @@
1
+ #!/usr/bin/env bash
2
+ # server-up.sh — ensure the design dev server is running for the given repo.
3
+ # Canonical recipe (was inline in `edit.md` step 2, `new.md` step 2, etc.).
4
+ #
5
+ # Usage:
6
+ # server-up.sh [--root <repo>] [--timeout 10] [--allow-legacy]
7
+ #
8
+ # Reads / writes:
9
+ # $DESIGN_ROOT/_server.json (PID + port the running server wrote)
10
+ # $DESIGN_ROOT/_server.log (stdout/stderr of the spawned server)
11
+ #
12
+ # Runtime selection (DDR-020):
13
+ # - Default: bun + server.ts. Hard-fails when bun is not on $PATH.
14
+ # - --allow-legacy: opt-in fallback to node + server.mjs (debug only;
15
+ # no TSX canvas pipeline, no HMR). Sunset in DDR-020 Phase B.
16
+ #
17
+ # Output: prints the port on stdout. Diagnostic lines go to stderr.
18
+ # Exit: 0 = server ready / 1 = start timeout or missing runtime / 2 = bad args.
19
+
20
+ REPO=""
21
+ TIMEOUT=10
22
+ ALLOW_LEGACY=0
23
+ while [ $# -gt 0 ]; do
24
+ case "$1" in
25
+ --root) REPO="$2"; shift 2 ;;
26
+ --timeout) TIMEOUT="$2"; shift 2 ;;
27
+ --allow-legacy) ALLOW_LEGACY=1; shift ;;
28
+ --help|-h)
29
+ sed -n '2,21p' "$0" | sed 's/^# \?//'
30
+ exit 0
31
+ ;;
32
+ *)
33
+ echo "server-up.sh: unknown arg '$1' (try --help)" >&2
34
+ exit 2
35
+ ;;
36
+ esac
37
+ done
38
+
39
+ # Resolve repo root.
40
+ if [ -z "$REPO" ]; then
41
+ REPO="${CLAUDE_PROJECT_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"
42
+ fi
43
+
44
+ # Resolve plugin root + pick a server runtime. DDR-020: bun + server.ts is
45
+ # authoritative. Legacy node + server.mjs is sunset; available only behind
46
+ # --allow-legacy (debug-only — no TSX canvas pipeline, no HMR).
47
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
48
+ PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT:-$(cd "$SCRIPT_DIR/../.." && pwd)}"
49
+ SERVER_TS="$PLUGIN_ROOT/dev-server/server.ts"
50
+ SERVER_MJS="$PLUGIN_ROOT/dev-server/server.mjs"
51
+ if [ ! -f "$SERVER_TS" ]; then SERVER_TS="$SCRIPT_DIR/../server.ts"; fi
52
+ if [ ! -f "$SERVER_MJS" ]; then SERVER_MJS="$SCRIPT_DIR/../server.mjs"; fi
53
+
54
+ RUNTIME=""
55
+ RUNTIME_CMD=""
56
+ if [ $ALLOW_LEGACY -eq 1 ]; then
57
+ if [ ! -f "$SERVER_MJS" ]; then
58
+ echo "server-up.sh: --allow-legacy requested but server.mjs not found at $SERVER_MJS" >&2
59
+ exit 1
60
+ fi
61
+ RUNTIME="node"
62
+ RUNTIME_CMD="node $SERVER_MJS"
63
+ echo "server-up.sh: WARNING — running legacy server.mjs (no TSX canvas pipeline, no HMR). DDR-020 sunsets this in Phase B." >&2
64
+ elif command -v bun >/dev/null 2>&1 && [ -f "$SERVER_TS" ]; then
65
+ RUNTIME="bun"
66
+ RUNTIME_CMD="bun $SERVER_TS"
67
+ else
68
+ echo "server-up.sh: bun not on \$PATH — install via https://bun.sh/install" >&2
69
+ echo "server-up.sh: DDR-020 made bun authoritative; the node fallback is opt-in via --allow-legacy (debug only)." >&2
70
+ exit 1
71
+ fi
72
+
73
+ DESIGN_ROOT="$REPO/.design"
74
+ STATE="$DESIGN_ROOT/_server.json"
75
+
76
+ read_port() {
77
+ if command -v jq >/dev/null 2>&1; then
78
+ jq -r .port "$STATE" 2>/dev/null
79
+ else
80
+ # Best-effort grep — jq is in repo deps but be defensive.
81
+ sed -nE 's/.*"port"[[:space:]]*:[[:space:]]*([0-9]+).*/\1/p' "$STATE" 2>/dev/null | head -n1
82
+ fi
83
+ }
84
+ read_pid() {
85
+ if command -v jq >/dev/null 2>&1; then
86
+ jq -r .pid "$STATE" 2>/dev/null
87
+ else
88
+ sed -nE 's/.*"pid"[[:space:]]*:[[:space:]]*([0-9]+).*/\1/p' "$STATE" 2>/dev/null | head -n1
89
+ fi
90
+ }
91
+
92
+ # Step 1 — check existing.
93
+ NEEDS_START=1
94
+ if [ -f "$STATE" ]; then
95
+ PID=$(read_pid)
96
+ PORT=$(read_port)
97
+ if [ -n "$PID" ] && [ -n "$PORT" ] \
98
+ && kill -0 "$PID" 2>/dev/null \
99
+ && curl -fs "http://localhost:$PORT/_health" >/dev/null 2>&1; then
100
+ echo "✓ server alive pid=$PID port=$PORT" >&2
101
+ echo "$PORT"
102
+ exit 0
103
+ else
104
+ echo "→ stale _server.json — clearing and respawning" >&2
105
+ rm -f "$STATE"
106
+ fi
107
+ fi
108
+
109
+ # Step 2 — spawn.
110
+ mkdir -p "$DESIGN_ROOT"
111
+ echo "→ starting dev server: $RUNTIME_CMD --root $REPO" >&2
112
+ if [ "$RUNTIME" = "bun" ]; then
113
+ nohup bun "$SERVER_TS" --root "$REPO" > "$DESIGN_ROOT/_server.log" 2>&1 &
114
+ elif [ "$RUNTIME" = "node" ]; then
115
+ nohup node "$SERVER_MJS" --root "$REPO" > "$DESIGN_ROOT/_server.log" 2>&1 &
116
+ fi
117
+ disown 2>/dev/null || true
118
+
119
+ # Step 3 — poll.
120
+ i=0
121
+ while [ $i -lt "$TIMEOUT" ]; do
122
+ sleep 1
123
+ i=$((i + 1))
124
+ if [ -f "$STATE" ]; then
125
+ PORT=$(read_port)
126
+ if [ -n "$PORT" ] && curl -fs "http://localhost:$PORT/_health" >/dev/null 2>&1; then
127
+ echo "✓ server started port=$PORT after ${i}s" >&2
128
+ echo "$PORT"
129
+ exit 0
130
+ fi
131
+ fi
132
+ done
133
+
134
+ echo "✗ server start timeout after ${TIMEOUT}s; check $DESIGN_ROOT/_server.log" >&2
135
+ exit 1
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env bash
2
+ # slug.sh — normalize a canvas relative-path into a filesystem-safe slug.
3
+ # Canonical recipe for `_history/<slug>/` path computation. Sourced from
4
+ # `commands/edit.md` step 3 originally; now the single source of truth.
5
+ #
6
+ # Usage: slug.sh "<path-relative-to-designRoot>"
7
+ # Output: lowercase kebab slug — e.g. "ui/showcase/Match Recap.tsx" -> "ui-showcase-match_recap"
8
+
9
+ if [ $# -lt 1 ] || [ "$1" = "--help" ] || [ "$1" = "-h" ]; then
10
+ echo "Usage: slug.sh <relative-path>" >&2
11
+ echo "Example: slug.sh 'ui/showcase/Match Recap.tsx' -> ui-showcase-match_recap" >&2
12
+ [ "$1" = "--help" ] || [ "$1" = "-h" ] && exit 0
13
+ exit 1
14
+ fi
15
+
16
+ printf '%s' "${1#./}" \
17
+ | tr '/' '-' \
18
+ | tr ' ' '_' \
19
+ | tr '[:upper:]' '[:lower:]' \
20
+ | sed -E 's/\.(tsx|jsx|html?|css|json|md)$//' \
21
+ | sed 's/^\.\+//'
22
+ echo