@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.
- package/LICENSE +21 -0
- package/README.md +166 -0
- package/cli/bin/maude.exe +15 -0
- package/cli/bin/maude.mjs +45 -0
- package/cli/bin/mdcc.exe +10 -0
- package/cli/bin/mdcc.mjs +7 -0
- package/cli/cli-wrapper.cjs +67 -0
- package/cli/commands/config.mjs +94 -0
- package/cli/commands/design.mjs +386 -0
- package/cli/commands/help.mjs +57 -0
- package/cli/commands/init.mjs +178 -0
- package/cli/commands/version.mjs +7 -0
- package/cli/install.cjs +113 -0
- package/cli/lib/argv.mjs +37 -0
- package/cli/lib/argv.test.mjs +46 -0
- package/cli/lib/copy-tree.mjs +78 -0
- package/package.json +94 -0
- package/plugins/design/dev-server/annotations-context-toolbar.tsx +397 -0
- package/plugins/design/dev-server/annotations-layer.tsx +1717 -0
- package/plugins/design/dev-server/api.ts +674 -0
- package/plugins/design/dev-server/bin/_screenshot-playwright.mjs +50 -0
- package/plugins/design/dev-server/bin/bootstrap-check.sh +83 -0
- package/plugins/design/dev-server/bin/canvas-edit.sh +48 -0
- package/plugins/design/dev-server/bin/handoff.sh +27 -0
- package/plugins/design/dev-server/bin/screenshot.sh +232 -0
- package/plugins/design/dev-server/bin/server-up.sh +135 -0
- package/plugins/design/dev-server/bin/slug.sh +22 -0
- package/plugins/design/dev-server/bin/smoke.sh +272 -0
- package/plugins/design/dev-server/build.ts +267 -0
- package/plugins/design/dev-server/canvas-build.ts +219 -0
- package/plugins/design/dev-server/canvas-edit.ts +388 -0
- package/plugins/design/dev-server/canvas-header.ts +165 -0
- package/plugins/design/dev-server/canvas-icons.tsx +131 -0
- package/plugins/design/dev-server/canvas-lib-inline.ts +260 -0
- package/plugins/design/dev-server/canvas-lib-resolver.ts +85 -0
- package/plugins/design/dev-server/canvas-lib.tsx +1995 -0
- package/plugins/design/dev-server/canvas-meta.schema.json +181 -0
- package/plugins/design/dev-server/canvas-pipeline.ts +270 -0
- package/plugins/design/dev-server/canvas-shell.tsx +813 -0
- package/plugins/design/dev-server/client/app.jsx +2027 -0
- package/plugins/design/dev-server/client/hmr.mjs +85 -0
- package/plugins/design/dev-server/client/iframe-lazy.mjs +121 -0
- package/plugins/design/dev-server/client/index.html +15 -0
- package/plugins/design/dev-server/client/styles/0-reset.css +18 -0
- package/plugins/design/dev-server/client/styles/1-tokens.css +297 -0
- package/plugins/design/dev-server/client/styles/2-layout.css +35 -0
- package/plugins/design/dev-server/client/styles/3-shell.css +906 -0
- package/plugins/design/dev-server/client/styles/4-components.css +1268 -0
- package/plugins/design/dev-server/client/styles/5-utilities.css +4 -0
- package/plugins/design/dev-server/client/styles/_index.css +24 -0
- package/plugins/design/dev-server/client/styles.css +1419 -0
- package/plugins/design/dev-server/config.schema.json +147 -0
- package/plugins/design/dev-server/context-menu.tsx +343 -0
- package/plugins/design/dev-server/context.ts +173 -0
- package/plugins/design/dev-server/dist/client.bundle.js +20323 -0
- package/plugins/design/dev-server/dist/styles.css +2875 -0
- package/plugins/design/dev-server/examples/README.md +9 -0
- package/plugins/design/dev-server/examples/perf-100-artboards.tsx +113 -0
- package/plugins/design/dev-server/fs-watch.ts +63 -0
- package/plugins/design/dev-server/handoff.ts +721 -0
- package/plugins/design/dev-server/history.ts +125 -0
- package/plugins/design/dev-server/hmr-broadcast.ts +114 -0
- package/plugins/design/dev-server/http.ts +413 -0
- package/plugins/design/dev-server/input-router.tsx +485 -0
- package/plugins/design/dev-server/inspect.ts +365 -0
- package/plugins/design/dev-server/locator.ts +159 -0
- package/plugins/design/dev-server/mem.ts +97 -0
- package/plugins/design/dev-server/runtime-bundle.ts +235 -0
- package/plugins/design/dev-server/server.mjs +1246 -0
- package/plugins/design/dev-server/server.ts +131 -0
- package/plugins/design/dev-server/test/_helpers.ts +81 -0
- package/plugins/design/dev-server/test/active-state.test.ts +145 -0
- package/plugins/design/dev-server/test/annotations-api.test.ts +146 -0
- package/plugins/design/dev-server/test/annotations-layer.test.ts +419 -0
- package/plugins/design/dev-server/test/binary-smoke.test.ts +47 -0
- package/plugins/design/dev-server/test/bundle-smoke.test.ts +29 -0
- package/plugins/design/dev-server/test/canvas-build.test.ts +78 -0
- package/plugins/design/dev-server/test/canvas-edit.test.ts +139 -0
- package/plugins/design/dev-server/test/canvas-header.test.ts +127 -0
- package/plugins/design/dev-server/test/canvas-lib-inline.test.ts +146 -0
- package/plugins/design/dev-server/test/canvas-lib-resolver.test.ts +112 -0
- package/plugins/design/dev-server/test/canvas-meta-api.test.ts +236 -0
- package/plugins/design/dev-server/test/canvas-pipeline.test.ts +180 -0
- package/plugins/design/dev-server/test/canvas-route.test.ts +176 -0
- package/plugins/design/dev-server/test/fs-watch.test.ts +41 -0
- package/plugins/design/dev-server/test/handoff-static-frames.test.ts +215 -0
- package/plugins/design/dev-server/test/handoff.test.ts +281 -0
- package/plugins/design/dev-server/test/history-rollback.test.ts +62 -0
- package/plugins/design/dev-server/test/hmr-broadcast.test.ts +108 -0
- package/plugins/design/dev-server/test/input-router.test.ts +316 -0
- package/plugins/design/dev-server/test/locator.test.ts +214 -0
- package/plugins/design/dev-server/test/perf-harness.ts +193 -0
- package/plugins/design/dev-server/test/phase-3.6-smoke.test.ts +77 -0
- package/plugins/design/dev-server/test/runtime-bundle.test.ts +69 -0
- package/plugins/design/dev-server/test/server-lifecycle.test.ts +28 -0
- package/plugins/design/dev-server/test/tool-palette.test.tsx +55 -0
- package/plugins/design/dev-server/test/use-annotation-selection.test.tsx +77 -0
- package/plugins/design/dev-server/test/use-artboard-drag.test.ts +325 -0
- package/plugins/design/dev-server/test/use-selection-set.test.tsx +166 -0
- package/plugins/design/dev-server/test/use-snap-guides.test.ts +190 -0
- package/plugins/design/dev-server/test/use-tool-mode.test.tsx +93 -0
- package/plugins/design/dev-server/test/ws-handshake.test.ts +33 -0
- package/plugins/design/dev-server/tool-palette.tsx +278 -0
- package/plugins/design/dev-server/tsconfig.json +26 -0
- package/plugins/design/dev-server/use-annotation-selection.tsx +92 -0
- package/plugins/design/dev-server/use-annotations-visibility.tsx +43 -0
- package/plugins/design/dev-server/use-artboard-drag.tsx +445 -0
- package/plugins/design/dev-server/use-selection-set.tsx +224 -0
- package/plugins/design/dev-server/use-snap-guides.tsx +215 -0
- package/plugins/design/dev-server/use-tool-mode.tsx +114 -0
- package/plugins/design/dev-server/ws.ts +90 -0
- package/plugins/design/templates/_shell.html +177 -0
- package/plugins/design/templates/canvas.tsx.template +54 -0
- package/plugins/design/templates/design-system-inspiration/_MAPPING.md +277 -0
- package/plugins/design/templates/design-system-inspiration/_README.md +71 -0
- package/plugins/design/templates/design-system-inspiration/audience-consumer/components-banner.html +68 -0
- package/plugins/design/templates/design-system-inspiration/audience-consumer/components-empty-state-generous.html +39 -0
- package/plugins/design/templates/design-system-inspiration/audience-consumer/components-feature-grid.html +62 -0
- package/plugins/design/templates/design-system-inspiration/audience-consumer/components-marketing-card.html +63 -0
- package/plugins/design/templates/design-system-inspiration/audience-consumer/components-testimonial.html +80 -0
- package/plugins/design/templates/design-system-inspiration/audience-developer/components-code-block.html +71 -0
- package/plugins/design/templates/design-system-inspiration/audience-developer/components-diff-view.html +65 -0
- package/plugins/design/templates/design-system-inspiration/audience-developer/components-log-stream.html +62 -0
- package/plugins/design/templates/design-system-inspiration/audience-developer/components-monospace-table.html +57 -0
- package/plugins/design/templates/design-system-inspiration/audience-developer/components-terminal-pane.html +67 -0
- package/plugins/design/templates/design-system-inspiration/audience-developer/type-mono.html +57 -0
- package/plugins/design/templates/design-system-inspiration/audience-pro/colors-presence.html +74 -0
- package/plugins/design/templates/design-system-inspiration/audience-pro/components-command-palette.html +90 -0
- package/plugins/design/templates/design-system-inspiration/audience-pro/components-keyboard.html +51 -0
- package/plugins/design/templates/design-system-inspiration/audience-pro/components-list.html +89 -0
- package/plugins/design/templates/design-system-inspiration/audience-pro/components-shortcuts-overlay.html +85 -0
- package/plugins/design/templates/design-system-inspiration/audience-pro/components-toast-menu.html +80 -0
- package/plugins/design/templates/design-system-inspiration/core/INDEX.md.tpl +25 -0
- package/plugins/design/templates/design-system-inspiration/core/README.orchestration.md.tpl +71 -0
- package/plugins/design/templates/design-system-inspiration/core/README.philosophy.md.tpl +77 -0
- package/plugins/design/templates/design-system-inspiration/core/SKILL.md.tpl +50 -0
- package/plugins/design/templates/design-system-inspiration/core/colors_and_type.css.tpl +111 -0
- package/plugins/design/templates/design-system-inspiration/core/config.json.tpl +28 -0
- package/plugins/design/templates/design-system-inspiration/core/preview/_layout.css +113 -0
- package/plugins/design/templates/design-system-inspiration/core/preview/colors-accent.html +48 -0
- package/plugins/design/templates/design-system-inspiration/core/preview/colors-surfaces.html +49 -0
- package/plugins/design/templates/design-system-inspiration/core/preview/colors-text.html +52 -0
- package/plugins/design/templates/design-system-inspiration/core/preview/components-buttons.html +83 -0
- package/plugins/design/templates/design-system-inspiration/core/preview/components-cards.html +79 -0
- package/plugins/design/templates/design-system-inspiration/core/preview/components-inputs.html +82 -0
- package/plugins/design/templates/design-system-inspiration/core/preview/motion.html +66 -0
- package/plugins/design/templates/design-system-inspiration/core/preview/spacing-scale.html +53 -0
- package/plugins/design/templates/design-system-inspiration/core/preview/type-scale.html +62 -0
- package/plugins/design/templates/design-system-inspiration/foundations/borders.html +39 -0
- package/plugins/design/templates/design-system-inspiration/foundations/elevation.html +46 -0
- package/plugins/design/templates/design-system-inspiration/foundations/focus.html +48 -0
- package/plugins/design/templates/design-system-inspiration/foundations/grid.html +51 -0
- package/plugins/design/templates/design-system-inspiration/foundations/iconography.html +73 -0
- package/plugins/design/templates/design-system-inspiration/foundations/opacity.html +45 -0
- package/plugins/design/templates/design-system-inspiration/foundations/radii.html +40 -0
- package/plugins/design/templates/design-system-inspiration/foundations/selection.html +45 -0
- package/plugins/design/templates/design-system-inspiration/meta/accessibility.html +62 -0
- package/plugins/design/templates/design-system-inspiration/meta/i18n.html +73 -0
- package/plugins/design/templates/design-system-inspiration/meta/presence-multiplayer.html +71 -0
- package/plugins/design/templates/design-system-inspiration/meta/tokens-index.html +80 -0
- package/plugins/design/templates/design-system-inspiration/patterns/patterns-auth.html +78 -0
- package/plugins/design/templates/design-system-inspiration/patterns/patterns-data-density.html +61 -0
- package/plugins/design/templates/design-system-inspiration/patterns/patterns-error-pages.html +70 -0
- package/plugins/design/templates/design-system-inspiration/patterns/patterns-form-layouts.html +70 -0
- package/plugins/design/templates/design-system-inspiration/patterns/patterns-onboarding.html +71 -0
- package/plugins/design/templates/design-system-inspiration/patterns/patterns-pricing.html +83 -0
- package/plugins/design/templates/design-system-inspiration/platform-desktop/components-resize-panels.html +63 -0
- package/plugins/design/templates/design-system-inspiration/platform-desktop/ui_kits-desktop-index.html +55 -0
- package/plugins/design/templates/design-system-inspiration/platform-desktop/ui_kits-desktop-showcase.html +302 -0
- package/plugins/design/templates/design-system-inspiration/platform-mobile/components-bottom-sheet.html +63 -0
- package/plugins/design/templates/design-system-inspiration/platform-mobile/components-pull-to-refresh.html +74 -0
- package/plugins/design/templates/design-system-inspiration/platform-mobile/components-segmented-control.html +51 -0
- package/plugins/design/templates/design-system-inspiration/platform-mobile/components-tab-bar.html +57 -0
- package/plugins/design/templates/design-system-inspiration/platform-mobile/ui_kits-mobile-index.html +58 -0
- package/plugins/design/templates/design-system-inspiration/platform-mobile/ui_kits-mobile-showcase.html +237 -0
- package/plugins/design/templates/design-system-inspiration/status/colors-status.html +49 -0
- package/plugins/design/templates/design-system-inspiration/status/components-status.html +63 -0
- package/plugins/design/templates/design-system-inspiration/status/skeletons.html +74 -0
- package/plugins/design/templates/design-system-inspiration/theme-both/colors-themes-side-by-side.html +59 -0
- package/plugins/design/templates/design-system-inspiration/universal/components-callout.html +74 -0
- package/plugins/design/templates/design-system-inspiration/universal/components-dialogs.html +81 -0
- package/plugins/design/templates/design-system-inspiration/universal/components-tables.html +101 -0
- package/plugins/design/templates/design-system-inspiration/universal/components-toggles.html +74 -0
- package/plugins/design/templates/design-system-inspiration/universal/components-tooltips.html +74 -0
- package/plugins/design/templates/design-system-inspiration/universal/empty-state.html.tpl +34 -0
- package/plugins/design/templates/design-system-inspiration/universal/logo.html +42 -0
- package/plugins/design/templates/ds-specimen.tsx.template +59 -0
- package/plugins/flow/.claude-plugin/config.schema.json +398 -0
- package/plugins/flow/README.md +45 -0
- package/plugins/flow/templates/ai-skeleton/INDEX.md +50 -0
- package/plugins/flow/templates/ai-skeleton/README.md +46 -0
- package/plugins/flow/templates/ai-skeleton/browser/har/.gitkeep +0 -0
- package/plugins/flow/templates/ai-skeleton/browser/snapshots/.gitkeep +0 -0
- package/plugins/flow/templates/ai-skeleton/business/README.md +12 -0
- package/plugins/flow/templates/ai-skeleton/context/README.md +12 -0
- package/plugins/flow/templates/ai-skeleton/decisions/README.md +20 -0
- package/plugins/flow/templates/ai-skeleton/design-import/.gitkeep +0 -0
- package/plugins/flow/templates/ai-skeleton/dev-logs/.gitkeep +0 -0
- package/plugins/flow/templates/ai-skeleton/device/.gitkeep +0 -0
- package/plugins/flow/templates/ai-skeleton/docs/README.md +5 -0
- package/plugins/flow/templates/ai-skeleton/logs/.gitkeep +0 -0
- package/plugins/flow/templates/ai-skeleton/logs/README.md +13 -0
- package/plugins/flow/templates/ai-skeleton/plans/README.md +16 -0
- package/plugins/flow/templates/ai-skeleton/plans/archive/.gitkeep +0 -0
- package/plugins/flow/templates/ai-skeleton/release-guide.md +35 -0
- package/plugins/flow/templates/ai-skeleton/reviews/README.md +15 -0
- package/plugins/flow/templates/ai-skeleton/scenarios/README.md +26 -0
- package/plugins/flow/templates/ai-skeleton/scenarios/_lib/.gitkeep +0 -0
- package/plugins/flow/templates/ai-skeleton/state/STATE.md +25 -0
- package/plugins/flow/templates/ai-skeleton/templates/HANDOFF.md +32 -0
- 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
|