@maccesar/aiskills 1.11.0 → 1.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/README.md +43 -8
- package/lib/cleanup.js +42 -0
- package/lib/commands/skills.js +110 -8
- package/lib/config.js +17 -12
- package/lib/installer.js +5 -3
- package/lib/platform.js +1 -1
- package/lib/symlink.js +45 -3
- package/lib/utils.js +41 -0
- package/package.json +1 -1
- package/skills/audit-codebase/SKILL.md +70 -0
- package/skills/audit-codebase/agents/openai.yaml +4 -0
- package/skills/audit-codebase/references/comprehensive-audit.md +220 -0
- package/skills/audit-codebase/references/report-format.md +119 -0
- package/skills/humaniza/SKILL.md +55 -4
- package/skills/humaniza/references/ai-patterns-es.md +40 -0
- package/skills/humaniza/references/checklist.md +9 -0
- package/skills/humaniza/references/examples.md +16 -0
- package/skills/humaniza/references/lexicon-es-mx.md +18 -0
- package/skills/humaniza/references/structures-es.md +132 -0
- package/skills/humaniza/scripts/check_ai_patterns.py +216 -0
- package/skills/refactoring-ui/SKILL.md +65 -29
- package/skills/refactoring-ui/references/05-motion.md +124 -0
- package/skills/refactoring-ui/references/06-dark-mode.md +117 -0
- package/skills/refactoring-ui/references/07-component-patterns.md +181 -0
- package/skills/stitch-showcase/SKILL.md +24 -232
- package/skills/stitch-showcase/references/07-theme-system.md +12 -0
- package/skills/stitch-showcase/references/08-type-detection.md +9 -1
- package/skills/stitch-showcase/references/10-component-standardization.md +25 -0
- package/skills/stitch-showcase/references/12-video-embedding.md +113 -0
- package/skills/stitch-showcase/references/13-language-detection.md +82 -0
- package/skills/stitch-showcase/references/14-troubleshooting-known-issues.md +122 -0
- package/skills/stitch-showcase/references/15-build-flags.md +71 -0
- package/skills/stitch-showcase/references/16-design-md-format.md +107 -0
- package/skills/stitch-showcase/references/index.html +25 -19
- package/skills/stitch-showcase/references/viewer.html +24 -12
- package/skills/stitch-showcase/scripts/__pycache__/build_showcase.cpython-314.pyc +0 -0
- package/skills/stitch-showcase/scripts/__pycache__/component_utils.cpython-314.pyc +0 -0
- package/skills/stitch-showcase/scripts/__pycache__/detect_components.cpython-314.pyc +0 -0
- package/skills/stitch-showcase/scripts/__pycache__/extract_catalog.cpython-314.pyc +0 -0
- package/skills/stitch-showcase/scripts/__pycache__/extract_text.cpython-314.pyc +0 -0
- package/skills/stitch-showcase/scripts/__pycache__/extract_zips.cpython-314.pyc +0 -0
- package/skills/stitch-showcase/scripts/__pycache__/parse_design_md.cpython-314.pyc +0 -0
- package/skills/stitch-showcase/scripts/__pycache__/slug_demangle.cpython-314.pyc +0 -0
- package/skills/stitch-showcase/scripts/build_showcase.py +150 -10
- package/skills/stitch-showcase/scripts/parse_design_md.py +145 -12
- package/skills/stitch-showcase/scripts/slug_demangle.py +209 -0
- package/skills/vscode-extension-dev/SKILL.md +90 -41
- package/skills/vscode-extension-dev/references/api-additional.md +168 -0
- package/skills/vscode-extension-dev/references/api-progress.md +55 -0
- package/skills/vscode-extension-dev/references/api-quickpick.md +75 -0
- package/skills/vscode-extension-dev/references/api-secretstorage.md +57 -0
- package/skills/vscode-extension-dev/references/api-statusbar.md +38 -0
- package/skills/vscode-extension-dev/references/api-treeview.md +78 -0
- package/skills/vscode-extension-dev/references/api-webview.md +149 -0
- package/skills/vscode-extension-dev/references/architecture.md +67 -0
- package/skills/vscode-extension-dev/references/debugger.md +179 -0
- package/skills/vscode-extension-dev/references/lsp.md +175 -0
- package/skills/vscode-extension-dev/references/notebooks.md +208 -0
- package/skills/vscode-extension-dev/references/testing.md +208 -0
- package/skills/vscode-extension-dev/references/api-patterns.md +0 -625
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# Section: Video Embedding in Slots
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Sometimes a Stitch slot needs to show a video instead of a still image
|
|
6
|
+
(product demo, animated logo, looping background, recorded screen). This
|
|
7
|
+
document captures the exact pattern that works across browsers and avoids
|
|
8
|
+
the common pitfalls — content recropping, layout shift, AV1 codec, and
|
|
9
|
+
aspect-ratio mismatch with the original wrapper.
|
|
10
|
+
|
|
11
|
+
## The Tag
|
|
12
|
+
|
|
13
|
+
Use a plain `<video>` element with native `width` and `height` attributes
|
|
14
|
+
plus inline styling for safe defaults:
|
|
15
|
+
|
|
16
|
+
```html
|
|
17
|
+
<video
|
|
18
|
+
autoplay
|
|
19
|
+
muted
|
|
20
|
+
loop
|
|
21
|
+
playsinline
|
|
22
|
+
width="W"
|
|
23
|
+
height="H"
|
|
24
|
+
preload="metadata"
|
|
25
|
+
style="display:block;width:100%;height:auto;background:#000">
|
|
26
|
+
<source src="../videos/<slug>.mp4" type="video/mp4">
|
|
27
|
+
</video>
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Replace `W` / `H` with the **native** video dimensions and `<slug>` with
|
|
31
|
+
the screen slug (or whatever filename you used inside `videos/`).
|
|
32
|
+
|
|
33
|
+
### Why each attribute
|
|
34
|
+
|
|
35
|
+
| Attribute | Why |
|
|
36
|
+
|-----------|-----|
|
|
37
|
+
| `autoplay muted loop playsinline` | All four are required for in-app autoplay on iOS and Android. Drop any one and mobile browsers refuse to play without a tap. |
|
|
38
|
+
| Native `width` / `height` | Lets the browser compute the aspect ratio from the very first paint — prevents layout shift and CLS regressions. |
|
|
39
|
+
| `preload="metadata"` | Loads just enough to know the dimensions and duration; avoids hammering the user's bandwidth when the screen is offscreen. |
|
|
40
|
+
| `style="display:block"` | Removes the small descender gap inline videos otherwise get. |
|
|
41
|
+
| `style="width:100%;height:auto"` | Scales the video to fit the parent column while keeping its native aspect ratio. **Do NOT use `object-cover`** — it crops the video. |
|
|
42
|
+
| `background:#000` | Hides letterboxing during the brief moment before the first frame paints. |
|
|
43
|
+
|
|
44
|
+
## File Workflow
|
|
45
|
+
|
|
46
|
+
1. **Download** the source video. For Facebook/Instagram/YouTube/TikTok we
|
|
47
|
+
recommend `yt-dlp`:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
yt-dlp "https://www.facebook.com/<...>/videos/<id>" -o "videos/<slug>.%(ext)s"
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
2. **Re-encode to H.264** if the source comes down as AV1. AV1 doesn't
|
|
54
|
+
preview in macOS Finder and is rejected by Safari < 17:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
ffmpeg -i in.mp4 \
|
|
58
|
+
-c:v libx264 -preset fast -crf 23 \
|
|
59
|
+
-c:a aac \
|
|
60
|
+
-movflags +faststart \
|
|
61
|
+
videos/<slug>.mp4
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
- `-preset fast`: balanced speed/quality.
|
|
65
|
+
- `-crf 23`: visually-lossless default; lower number = bigger file.
|
|
66
|
+
- `-movflags +faststart`: moves the moov atom to the front so the video
|
|
67
|
+
can start playing before fully downloaded.
|
|
68
|
+
|
|
69
|
+
3. **Place** the encoded `.mp4` in a `videos/` folder at the **project
|
|
70
|
+
level** (the same level as `stitch/` or `showcase/`, not inside
|
|
71
|
+
`assets/`), so the build keeps it out of the screen-extraction pipeline:
|
|
72
|
+
|
|
73
|
+
```text
|
|
74
|
+
my-project/
|
|
75
|
+
├── stitch/ ← Stitch exports (zips)
|
|
76
|
+
├── videos/ ← your videos
|
|
77
|
+
│ └── hero.mp4
|
|
78
|
+
└── showcase/ ← generated
|
|
79
|
+
└── assets/
|
|
80
|
+
└── <slug>.html ← references ../../videos/hero.mp4
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
4. **Reference from the screen HTML** with a relative path. From inside
|
|
84
|
+
`showcase/assets/<slug>.html`, `videos/` is two levels up:
|
|
85
|
+
|
|
86
|
+
```html
|
|
87
|
+
<source src="../../videos/hero.mp4" type="video/mp4">
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Aspect-Ratio Mismatch
|
|
91
|
+
|
|
92
|
+
The original Stitch wrapper for a video slot usually carries a fixed
|
|
93
|
+
aspect ratio (e.g. `aspect-[4/5]`). If your video is a different shape —
|
|
94
|
+
say 9/16 — keeping the wrapper's aspect locks the video into the wrong
|
|
95
|
+
box, which then forces a choice:
|
|
96
|
+
|
|
97
|
+
| Option | Effect |
|
|
98
|
+
|--------|--------|
|
|
99
|
+
| Keep wrapper's `aspect-*` + `object-cover` | Video crops; logos and edges get chopped. |
|
|
100
|
+
| **Remove wrapper's `aspect-*` + `height:auto`** | Video keeps its native aspect; the slot grows or shrinks vertically to fit. ✅ |
|
|
101
|
+
|
|
102
|
+
The second option is almost always what you want — better to have a
|
|
103
|
+
slightly taller card than to chop the brand logo out of the frame.
|
|
104
|
+
|
|
105
|
+
## Quick Sanity Checks
|
|
106
|
+
|
|
107
|
+
After embedding, open the screen in a browser and confirm:
|
|
108
|
+
|
|
109
|
+
- The video autoplays without a tap on Chrome, Safari, and Firefox.
|
|
110
|
+
- The video loops cleanly (no flash on rewind).
|
|
111
|
+
- On mobile (iOS Safari), it autoplays silently inline (not fullscreen).
|
|
112
|
+
- The file size is reasonable — re-encode with a higher `-crf` if it's
|
|
113
|
+
more than ~3-5 MB per 10 seconds.
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# Section: Language Detection
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
The `<html lang="…">` attribute on the generated `index.html` and
|
|
6
|
+
`viewer.html` tells the browser which natural language the content uses.
|
|
7
|
+
If the value disagrees with the actual content, Chrome shows a "Translate
|
|
8
|
+
this page" banner and assistive technologies pronounce words with the
|
|
9
|
+
wrong phoneme set. This document explains how the build picks the value
|
|
10
|
+
and how to override it.
|
|
11
|
+
|
|
12
|
+
## Resolution Order
|
|
13
|
+
|
|
14
|
+
The `lang` attribute is chosen by the first rule that fires:
|
|
15
|
+
|
|
16
|
+
1. **CLI flag** (future — not implemented yet): `--lang es` on
|
|
17
|
+
`build_showcase.py`.
|
|
18
|
+
2. **`showcase.json` field**:
|
|
19
|
+
|
|
20
|
+
```json
|
|
21
|
+
{
|
|
22
|
+
"source": "stitch",
|
|
23
|
+
"type": "mobile",
|
|
24
|
+
"name": "My App",
|
|
25
|
+
"lang": "es"
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
3. **`## Lang` section in `DESIGN.md`** (same shape as `## Type`):
|
|
30
|
+
|
|
31
|
+
```markdown
|
|
32
|
+
## Lang
|
|
33
|
+
es
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
4. **Auto-detection** from the text content of `DESIGN.md` (project name,
|
|
37
|
+
section names, descriptions). The detector counts Spanish signals:
|
|
38
|
+
|
|
39
|
+
- Accented characters (`á é í ó ú ñ`).
|
|
40
|
+
- Common Spanish stop words (`de`, `el`, `la`, `los`, `las`, `para`,
|
|
41
|
+
`con`, `pantalla`, `aplicación`, `usuario`, etc.).
|
|
42
|
+
|
|
43
|
+
If the Spanish score crosses a small threshold, the lang resolves to
|
|
44
|
+
`"es"`; otherwise it falls through.
|
|
45
|
+
|
|
46
|
+
5. **Default**: `"en"`.
|
|
47
|
+
|
|
48
|
+
## When to Override
|
|
49
|
+
|
|
50
|
+
The auto-detector handles obvious cases (a project whose DESIGN.md is
|
|
51
|
+
entirely Spanish or entirely English), but it can be fooled by very
|
|
52
|
+
short DESIGN.md files or by projects where the UI language differs from
|
|
53
|
+
the documentation language. Use an explicit override when:
|
|
54
|
+
|
|
55
|
+
- The DESIGN.md is in English but the actual screen content is Spanish
|
|
56
|
+
(you'd be documenting an es-MX app in English for a client).
|
|
57
|
+
- The DESIGN.md is sparse and the heuristic has nothing to score on.
|
|
58
|
+
- You want a non-Spanish, non-English language (`pt`, `fr`, `de` …) —
|
|
59
|
+
the auto-detector only distinguishes Spanish vs everything else.
|
|
60
|
+
|
|
61
|
+
## Why It Matters
|
|
62
|
+
|
|
63
|
+
- **Chrome's translate prompt**: with `lang="en"` and Spanish content,
|
|
64
|
+
Chrome offers to translate the page to the user's locale. Users
|
|
65
|
+
perceive this as a bug.
|
|
66
|
+
- **Screen readers**: VoiceOver and TalkBack switch pronunciation
|
|
67
|
+
engines per `lang`. A wrong value makes Spanish text sound like a
|
|
68
|
+
speech synthesizer trying to pronounce "configuración" as English.
|
|
69
|
+
- **Search engines**: the `lang` attribute is a soft signal but it's
|
|
70
|
+
read by indexers when ranking pages by locale.
|
|
71
|
+
|
|
72
|
+
## Common Mistake: Mismatched Lang and Content
|
|
73
|
+
|
|
74
|
+
The previous template hard-coded `lang="en"` even for Spanish-only
|
|
75
|
+
projects. The fix wasn't to flip the default to `"es"` (that just moves
|
|
76
|
+
the bug to English projects) — it was to detect or accept an override.
|
|
77
|
+
The same logic now lives in `parse_design_md.py` (`_detect_lang`) and
|
|
78
|
+
`build_showcase.py` (the `{{HTML_LANG}}` placeholder substitution).
|
|
79
|
+
|
|
80
|
+
If you ever see Chrome offering to translate one of your showcases:
|
|
81
|
+
that's the signal that the resolved `lang` is wrong. Add an override to
|
|
82
|
+
`showcase.json` or `DESIGN.md` and rebuild.
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# Section: Troubleshooting & Known Issues
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Working notes on issues that have shown up in real projects, the cause
|
|
6
|
+
when it's understood, and the workaround. New issues should be added here
|
|
7
|
+
before they show up a second time.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## `catalog.html` stays on "Loading…"
|
|
12
|
+
|
|
13
|
+
**Symptom**: opening `catalog.html` shows the skeleton header but the
|
|
14
|
+
component grid never appears.
|
|
15
|
+
|
|
16
|
+
**Cause** (suspected, not yet confirmed): in projects with very dense
|
|
17
|
+
HTMLs or many near-duplicate variants, `extract_catalog.py` either times
|
|
18
|
+
out or returns a structure the catalog viewer chokes on.
|
|
19
|
+
|
|
20
|
+
**Workaround**: the `index.html` template ships without the "Catalog"
|
|
21
|
+
button in the header, so end users don't hit the broken page. If you
|
|
22
|
+
want to inspect the catalog data, open `component_catalog.json` directly.
|
|
23
|
+
|
|
24
|
+
**Status**: open. Restore the Catalog button in
|
|
25
|
+
`references/index.html` once the root cause is fixed.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Chrome shows "Translate this page" banner
|
|
30
|
+
|
|
31
|
+
**Symptom**: Chrome offers to translate the showcase, sometimes to a
|
|
32
|
+
language that isn't even one of the two involved (Portuguese is common).
|
|
33
|
+
|
|
34
|
+
**Cause**: the `<html lang="…">` attribute on `index.html` or
|
|
35
|
+
`viewer.html` disagrees with the actual text content. See
|
|
36
|
+
[`13-language-detection.md`](13-language-detection.md) for the full
|
|
37
|
+
resolution order.
|
|
38
|
+
|
|
39
|
+
**Workaround**: add an override.
|
|
40
|
+
|
|
41
|
+
`showcase.json`:
|
|
42
|
+
|
|
43
|
+
```json
|
|
44
|
+
{
|
|
45
|
+
"lang": "es"
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
or, in `DESIGN.md`:
|
|
50
|
+
|
|
51
|
+
```markdown
|
|
52
|
+
## Lang
|
|
53
|
+
es
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Then rebuild.
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Video doesn't preview in Finder / Safari rejects it
|
|
61
|
+
|
|
62
|
+
**Symptom**: a `.mp4` downloaded from Facebook / YouTube / TikTok plays
|
|
63
|
+
fine in VLC and Chrome but shows a black square in macOS Finder and
|
|
64
|
+
fails to play in Safari < 17.
|
|
65
|
+
|
|
66
|
+
**Cause**: the source was encoded in AV1, which neither macOS Finder
|
|
67
|
+
nor older Safari can decode.
|
|
68
|
+
|
|
69
|
+
**Workaround**: re-encode to H.264 with ffmpeg. See
|
|
70
|
+
[`12-video-embedding.md`](12-video-embedding.md) for the exact command.
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Skill installed both as plugin and standalone
|
|
75
|
+
|
|
76
|
+
**Symptom**: after `aiskills install`, the skill folder exists at both
|
|
77
|
+
`~/.claude/skills/<name>/` (from the standalone CLI) **and**
|
|
78
|
+
`~/.claude/plugins/cache/<plugin>/<version>/skills/<name>/` (from the
|
|
79
|
+
marketplace plugin), so changes to one path are invisible to the other.
|
|
80
|
+
|
|
81
|
+
**Cause**: older versions of the `aiskills` CLI didn't detect when the
|
|
82
|
+
plugin marketplace had already installed the skill and dropped a
|
|
83
|
+
duplicate symlink.
|
|
84
|
+
|
|
85
|
+
**Workaround**:
|
|
86
|
+
|
|
87
|
+
1. Update the CLI: `npm install -g @maccesar/aiskills@latest`.
|
|
88
|
+
2. Remove the standalone copy: `rm -rf ~/.claude/skills/<skill-name>`.
|
|
89
|
+
3. Reinstall: `aiskills install`. The CLI now skips skills that the
|
|
90
|
+
plugin already provides.
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Showcase background and app background match (thumbnails disappear)
|
|
95
|
+
|
|
96
|
+
**Symptom**: every card in `index.html` shows a blank rectangle because
|
|
97
|
+
the screen has the same background color as the showcase canvas.
|
|
98
|
+
|
|
99
|
+
**Cause**: someone reused the project's brand color as the showcase
|
|
100
|
+
background instead of a neutral surface.
|
|
101
|
+
|
|
102
|
+
**Workaround**: see `07-theme-system.md` and the Color Strategy section
|
|
103
|
+
of `SKILL.md` — never use a brand color for large showcase surfaces.
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Stitch slugs come with `_` in place of accents
|
|
108
|
+
|
|
109
|
+
**Symptom**: filenames like `configuraci_n_oscuro.html` and the showcase
|
|
110
|
+
displays them as "Configuraci_N Oscuro".
|
|
111
|
+
|
|
112
|
+
**Cause**: Google Stitch strips accented characters from filenames.
|
|
113
|
+
|
|
114
|
+
**Workaround**: the build now de-mangles slugs automatically through
|
|
115
|
+
`scripts/slug_demangle.py`. If a slug doesn't appear in the demangler's
|
|
116
|
+
dictionary, override the title explicitly in `DESIGN.md` using the
|
|
117
|
+
`Title | Description` format:
|
|
118
|
+
|
|
119
|
+
```markdown
|
|
120
|
+
### Cuenta
|
|
121
|
+
- nuevo_slug_man_leado: Corrección Manual | Texto descriptivo.
|
|
122
|
+
```
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Build Script Reference
|
|
2
|
+
|
|
3
|
+
Detailed reference for `scripts/build_showcase.py` — flags, output structure, source discovery, and supported input layouts.
|
|
4
|
+
|
|
5
|
+
## Running the build
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Point to the project root — the script discovers the source automatically
|
|
9
|
+
python <SKILL_DIR>/scripts/build_showcase.py /path/to/project
|
|
10
|
+
|
|
11
|
+
# Or point directly to the folder with zips/screens
|
|
12
|
+
python <SKILL_DIR>/scripts/build_showcase.py /path/to/project/stitch
|
|
13
|
+
|
|
14
|
+
# Single mega-zip (zip containing all screens as subfolders)
|
|
15
|
+
python <SKILL_DIR>/scripts/build_showcase.py /path/to/export.zip
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Flags
|
|
19
|
+
|
|
20
|
+
| Flag | Description |
|
|
21
|
+
|------|-------------|
|
|
22
|
+
| `--type mobile\|web` | Set default view mode instead of auto-detecting |
|
|
23
|
+
| `--name "Title"` | Set project name when no DESIGN.md is present |
|
|
24
|
+
| `--init` | Generate a DESIGN.md skeleton from detected screen slugs |
|
|
25
|
+
| `--update` | Detect new screens not yet in DESIGN.md and append under `### Por Clasificar` |
|
|
26
|
+
| `--extract-text` | Extract visible text from screen HTMLs → `screen_summaries.txt` (for LLM consumption) |
|
|
27
|
+
| `--context` | (Debug only) Generate showcase_context.json without building HTML — do NOT use for normal builds |
|
|
28
|
+
| `--watch` | Auto-rebuild on file changes (Ctrl+C to stop) |
|
|
29
|
+
|
|
30
|
+
Component detection and catalog generation are automatic — no `--catalog` or `--components` flags needed. Every build produces `catalog.html` alongside `index.html` and `viewer.html`.
|
|
31
|
+
|
|
32
|
+
## Output structure
|
|
33
|
+
|
|
34
|
+
The script creates a single `showcase/` directory next to the source folder:
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
showcase/ ← single output dir (view mode toggle inside)
|
|
38
|
+
├── index.html ← open this in browser (gallery + design system)
|
|
39
|
+
├── viewer.html ← individual screen viewer
|
|
40
|
+
├── catalog.html ← component catalog with comparison view
|
|
41
|
+
├── component_catalog.json ← atomic + composite + cluster data
|
|
42
|
+
├── shared_components.json ← structural component variants
|
|
43
|
+
├── DESIGN.md ← copy from source
|
|
44
|
+
└── assets/
|
|
45
|
+
├── splash_screen.html
|
|
46
|
+
├── splash_screen.png
|
|
47
|
+
├── login.html
|
|
48
|
+
├── login.png
|
|
49
|
+
└── ...
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Source folder with original zips is **never touched**.
|
|
53
|
+
|
|
54
|
+
## Source discovery
|
|
55
|
+
|
|
56
|
+
The script accepts **any folder in the project** — it doesn't need to be the exact folder with screens. Discovery order:
|
|
57
|
+
|
|
58
|
+
1. If the given path has screens (zips or `code.html` folders) → use it directly
|
|
59
|
+
2. If `showcase.json` exists in the given path or its parent → follow its `source` field
|
|
60
|
+
3. Auto-discover: scan one level of subdirectories for screens (skips `showcase`, `showcase-mobile`, `showcase-web` output dirs)
|
|
61
|
+
4. Clear error with a suggestion to create `showcase.json`
|
|
62
|
+
|
|
63
|
+
## Supported input structures
|
|
64
|
+
|
|
65
|
+
| Structure | Example |
|
|
66
|
+
|-----------|---------|
|
|
67
|
+
| Project root with `showcase.json` | `project/showcase.json` → `{"source": "stitch"}` |
|
|
68
|
+
| Folder of individual zips | `folder/login.zip`, `folder/home.zip` |
|
|
69
|
+
| Folder of pre-extracted screen folders | `folder/login/code.html`, `folder/home/code.html` |
|
|
70
|
+
| Single mega-zip (Stitch "Export all") | `export.zip → stitch/screen1/code.html, stitch/screen2/code.html` |
|
|
71
|
+
| Single screen zip | `screen.zip → code.html + screen.png` |
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# DESIGN.md & showcase.json Format
|
|
2
|
+
|
|
3
|
+
Configuration formats that drive the showcase build: project metadata, screen grouping, and description fallbacks.
|
|
4
|
+
|
|
5
|
+
## DESIGN.md Format
|
|
6
|
+
|
|
7
|
+
```markdown
|
|
8
|
+
# Project Name
|
|
9
|
+
|
|
10
|
+
## Type
|
|
11
|
+
mobile ← or "web"
|
|
12
|
+
|
|
13
|
+
## Screens
|
|
14
|
+
### Onboarding
|
|
15
|
+
- splash_screen
|
|
16
|
+
- login
|
|
17
|
+
|
|
18
|
+
### Home
|
|
19
|
+
- home_dashboard
|
|
20
|
+
|
|
21
|
+
## Colors
|
|
22
|
+
- Primary: #FDD900
|
|
23
|
+
- Background: #0A0A0A
|
|
24
|
+
|
|
25
|
+
## Typography
|
|
26
|
+
- **Inter**
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
The parser also accepts:
|
|
30
|
+
|
|
31
|
+
- Free-form bullets/numbered lists under `## Screens`
|
|
32
|
+
- Markdown table format: `| slug | title | description |`
|
|
33
|
+
- Color tokens in Stitch format: `` `primary-container` (#FDD900) `` or bare `surface (#0B1326)`
|
|
34
|
+
- Token named `primary-*` → accent color for tabs and hover
|
|
35
|
+
- Token named `surface` or `background` → used to compute smart showcase theme
|
|
36
|
+
- Optional `## Lang` section to override `<html lang>` (e.g. `es`, `en`, `pt-BR`). Auto-detected from content if absent. See [`13-language-detection.md`](13-language-detection.md).
|
|
37
|
+
|
|
38
|
+
The `--init` flag auto-generates a skeleton DESIGN.md from detected slugs.
|
|
39
|
+
|
|
40
|
+
## Screen Grouping
|
|
41
|
+
|
|
42
|
+
Screens are grouped into sections in this priority order:
|
|
43
|
+
|
|
44
|
+
1. **`DESIGN.md` sections** (best result) — explicit `### Section Name` blocks under `## Screens`
|
|
45
|
+
2. **Auto-grouping** (fallback) — keyword overlap between slugs; screens sharing a meaningful word are grouped together
|
|
46
|
+
|
|
47
|
+
When auto-grouping applies, offer to improve it:
|
|
48
|
+
|
|
49
|
+
- List the detected screen names for the user
|
|
50
|
+
- Suggest logical section groupings based on the app domain
|
|
51
|
+
- Write the sections to `DESIGN.md` in the source folder
|
|
52
|
+
- Re-run the script to apply them
|
|
53
|
+
|
|
54
|
+
### DESIGN.md section format for explicit grouping
|
|
55
|
+
|
|
56
|
+
```markdown
|
|
57
|
+
## Screens
|
|
58
|
+
### Onboarding
|
|
59
|
+
- splash_screen
|
|
60
|
+
- welcome
|
|
61
|
+
|
|
62
|
+
### Login & Registration
|
|
63
|
+
- login
|
|
64
|
+
- signup
|
|
65
|
+
- forgot_password
|
|
66
|
+
|
|
67
|
+
### Home
|
|
68
|
+
- home
|
|
69
|
+
- home_oscuro
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
The script merges DESIGN.md sections with slug auto-detection — slugs not listed in any section appear in an "Other screens" group at the end.
|
|
73
|
+
|
|
74
|
+
## Description Sources (priority)
|
|
75
|
+
|
|
76
|
+
When building cards, the script picks the description from these sources, in order:
|
|
77
|
+
|
|
78
|
+
1. `DESIGN.md` — screen list with descriptions
|
|
79
|
+
2. Individual `{num}-{name}.md` in source folder (per-screen prompt files)
|
|
80
|
+
3. `<meta name="description">` or `<meta property="og:description">` inside the HTML
|
|
81
|
+
4. First `<h1>` or `<h2>` visible text in the HTML body
|
|
82
|
+
5. `<title>` tag (skipped if generic: "Untitled", "index", "screen", etc.)
|
|
83
|
+
6. First meaningful visible text phrase found in the HTML body (strips scripts/styles/SVGs)
|
|
84
|
+
7. Formatted slug fallback ("splash_screen" → "Splash Screen")
|
|
85
|
+
|
|
86
|
+
Stitch-exported HTML rarely has `<title>` or meta descriptions — steps 4 and 6 are the most useful for those files.
|
|
87
|
+
|
|
88
|
+
## showcase.json
|
|
89
|
+
|
|
90
|
+
Optional config file in the project root. Tells the script where to find screens, the project type, and name — so you can point the script at any folder in the project.
|
|
91
|
+
|
|
92
|
+
```json
|
|
93
|
+
{
|
|
94
|
+
"source": "stitch",
|
|
95
|
+
"type": "mobile",
|
|
96
|
+
"name": "SNAP Gym"
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
| Field | Required | Description |
|
|
101
|
+
|-------|----------|-------------|
|
|
102
|
+
| `source` | yes | Relative path from the JSON file to the folder with screens |
|
|
103
|
+
| `type` | no | `"mobile"` or `"web"` (overridden by `--type` CLI flag) |
|
|
104
|
+
| `name` | no | Project name (overridden by `--name` CLI flag or DESIGN.md) |
|
|
105
|
+
| `lang` | no | BCP-47 code for `<html lang>` (e.g. `"es"`, `"pt-BR"`). Overrides DESIGN.md auto-detect. See [`13-language-detection.md`](13-language-detection.md). |
|
|
106
|
+
|
|
107
|
+
The `--init` flag generates this file automatically alongside DESIGN.md.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<!DOCTYPE html>
|
|
2
|
-
<html lang="
|
|
2
|
+
<html lang="{{HTML_LANG}}">
|
|
3
3
|
|
|
4
4
|
<head>
|
|
5
5
|
<meta charset="UTF-8">
|
|
@@ -37,13 +37,23 @@
|
|
|
37
37
|
|
|
38
38
|
/* List mode overrides — thumbnail always horizontal rectangle, regardless of view mode */
|
|
39
39
|
.screens-grid.list-mode { display: flex; flex-direction: column; gap: 8px; }
|
|
40
|
-
.screens-grid.list-mode .screen-card { display: flex; flex-direction: row; gap:
|
|
41
|
-
.screens-grid.list-mode .screen-card .card-thumb { width:
|
|
40
|
+
.screens-grid.list-mode .screen-card { display: flex; flex-direction: row; gap: 12px; }
|
|
41
|
+
.screens-grid.list-mode .screen-card .card-thumb { width: 140px; flex-shrink: 0; aspect-ratio: 16/10 !important; border-radius: 12px; }
|
|
42
42
|
.screens-grid.list-mode .screen-card .card-info { flex: 1; min-width: 0; padding-top: 4px; }
|
|
43
43
|
.screens-grid.list-mode .screen-card .card-desc { -webkit-line-clamp: unset; overflow: visible; white-space: normal; }
|
|
44
|
+
@media (min-width: 640px) {
|
|
45
|
+
.screens-grid.list-mode .screen-card { gap: 16px; }
|
|
46
|
+
.screens-grid.list-mode .screen-card .card-thumb { width: 240px; }
|
|
47
|
+
}
|
|
44
48
|
|
|
45
|
-
/* Grid columns per view mode */
|
|
46
|
-
.view-mobile .screens-grid:not(.list-mode) { grid-template-columns: repeat(
|
|
49
|
+
/* Grid columns per view mode — responsive, mobile-first */
|
|
50
|
+
.view-mobile .screens-grid:not(.list-mode) { grid-template-columns: repeat(2, 1fr) !important; }
|
|
51
|
+
@media (min-width: 640px) {
|
|
52
|
+
.view-mobile .screens-grid:not(.list-mode) { grid-template-columns: repeat(3, 1fr) !important; }
|
|
53
|
+
}
|
|
54
|
+
@media (min-width: 768px) {
|
|
55
|
+
.view-mobile .screens-grid:not(.list-mode) { grid-template-columns: repeat(4, 1fr) !important; }
|
|
56
|
+
}
|
|
47
57
|
.view-web .screens-grid:not(.list-mode) { grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)) !important; }
|
|
48
58
|
|
|
49
59
|
/* Hide scrollbar on tabs */
|
|
@@ -56,22 +66,18 @@
|
|
|
56
66
|
|
|
57
67
|
<!-- ── Header ─────────────────────────────────────────── -->
|
|
58
68
|
<header class="sticky top-0 z-50 border-b border-gray-200/60 backdrop-blur-xl bg-white/80 dark:border-white/10 dark:bg-[#0d0d0d]/80">
|
|
59
|
-
<div class="mx-auto flex h-14 max-w-[1280px] items-center justify-between gap-4 px-6">
|
|
69
|
+
<div class="mx-auto flex h-14 max-w-[1280px] items-center justify-between gap-2 px-3 sm:gap-4 sm:px-6">
|
|
60
70
|
|
|
61
|
-
<div class="flex min-w-0 items-center gap-3">
|
|
71
|
+
<div class="flex min-w-0 items-center gap-2 sm:gap-3">
|
|
62
72
|
<span class="truncate text-sm font-semibold">{{PROJECT_NAME}}</span>
|
|
63
|
-
<span id="view-badge" class="
|
|
73
|
+
<span id="view-badge" class="hidden sm:inline-flex shrink-0 items-center gap-1.5 rounded-full border border-gray-200 bg-gray-100 px-2.5 py-0.5 text-[11px] font-medium text-gray-500 dark:border-white/10 dark:bg-white/5 dark:text-gray-400">
|
|
64
74
|
</span>
|
|
65
|
-
<span class="shrink-0 text-xs text-gray-400 dark:text-gray-500">{{SCREEN_COUNT}}
|
|
66
|
-
<a href="catalog.html" class="shrink-0 inline-flex items-center gap-1 rounded-full border border-gray-200 bg-gray-50 px-2.5 py-0.5 text-[11px] font-medium text-gray-500 transition-colors hover:border-accent hover:text-accent dark:border-white/10 dark:bg-white/5 dark:text-gray-400 dark:hover:border-accent dark:hover:text-accent">
|
|
67
|
-
<svg class="h-3 w-3" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/></svg>
|
|
68
|
-
Catalog
|
|
69
|
-
</a>
|
|
75
|
+
<span class="hidden sm:inline shrink-0 text-xs text-gray-400 dark:text-gray-500">{{SCREEN_COUNT}} pantallas</span>
|
|
70
76
|
</div>
|
|
71
77
|
|
|
72
78
|
<div class="flex shrink-0 items-center gap-2">
|
|
73
79
|
<!-- View mode toggle (mobile/web) -->
|
|
74
|
-
<button id="view-mode-toggle" title="
|
|
80
|
+
<button id="view-mode-toggle" title="Cambiar vista móvil/web" class="flex h-8 w-8 items-center justify-center rounded-lg text-gray-500 transition-colors hover:bg-gray-100 dark:text-gray-400 dark:hover:bg-white/10">
|
|
75
81
|
<svg id="icon-phone" class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
76
82
|
<rect x="5" y="2" width="14" height="20" rx="2" ry="2"/><line x1="12" y1="18" x2="12.01" y2="18"/>
|
|
77
83
|
</svg>
|
|
@@ -89,7 +95,7 @@
|
|
|
89
95
|
</svg>
|
|
90
96
|
</button>
|
|
91
97
|
<!-- Theme toggle -->
|
|
92
|
-
<button id="theme-toggle" title="
|
|
98
|
+
<button id="theme-toggle" title="Cambiar claro/oscuro" class="flex h-8 w-8 items-center justify-center rounded-lg text-gray-500 transition-colors hover:bg-gray-100 dark:text-gray-400 dark:hover:bg-white/10">
|
|
93
99
|
<svg class="block h-4 w-4 dark:hidden" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
94
100
|
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" />
|
|
95
101
|
</svg>
|
|
@@ -117,7 +123,7 @@
|
|
|
117
123
|
<div class="mt-8 flex items-center gap-6 text-sm text-gray-500 dark:text-gray-400">
|
|
118
124
|
<div class="flex items-center gap-2">
|
|
119
125
|
<span class="font-semibold text-gray-900 dark:text-white">{{SCREEN_COUNT}}</span>
|
|
120
|
-
<span>
|
|
126
|
+
<span>Pantallas</span>
|
|
121
127
|
</div>
|
|
122
128
|
<div class="h-4 w-px bg-gray-200 dark:bg-white/10"></div>
|
|
123
129
|
<div class="flex items-center gap-2">
|
|
@@ -150,7 +156,7 @@
|
|
|
150
156
|
<circle cx="11" cy="11" r="8" />
|
|
151
157
|
<path d="m21 21-4.35-4.35" />
|
|
152
158
|
</svg>
|
|
153
|
-
<input id="search-input" type="text" placeholder="
|
|
159
|
+
<input id="search-input" type="text" placeholder="Buscar pantallas..." autocomplete="off" class="h-8 w-48 rounded-lg border border-gray-200 bg-gray-50 pl-8 pr-3 text-xs text-gray-900 placeholder-gray-400 transition-all focus:w-64 focus:outline-none focus:ring-2 focus:ring-accent/40 dark:border-white/10 dark:bg-white/5 dark:text-gray-100">
|
|
154
160
|
</div>
|
|
155
161
|
</div>
|
|
156
162
|
|
|
@@ -163,7 +169,7 @@
|
|
|
163
169
|
<circle cx="11" cy="11" r="8" />
|
|
164
170
|
<path d="m21 21-4.35-4.35" />
|
|
165
171
|
</svg>
|
|
166
|
-
<p class="text-sm">
|
|
172
|
+
<p class="text-sm">Ninguna pantalla coincide con tu búsqueda.</p>
|
|
167
173
|
</div>
|
|
168
174
|
|
|
169
175
|
</section>
|
|
@@ -184,7 +190,7 @@
|
|
|
184
190
|
root.classList.add('view-' + currentView);
|
|
185
191
|
|
|
186
192
|
// Update badge text
|
|
187
|
-
viewBadge.textContent = currentView === 'mobile' ? '
|
|
193
|
+
viewBadge.textContent = currentView === 'mobile' ? 'Móvil' : 'Web';
|
|
188
194
|
|
|
189
195
|
// Update toggle icon: show the icon of the CURRENT mode (matches the badge)
|
|
190
196
|
if (currentView === 'mobile') {
|