@maccesar/aiskills 1.17.0 → 1.18.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 (46) hide show
  1. package/README.md +42 -3
  2. package/commands/release.md +2 -4
  3. package/lib/commands/list.js +109 -22
  4. package/lib/commands/skills.js +1 -3
  5. package/lib/config.js +1 -0
  6. package/lib/prompts/checkboxCancel.js +0 -6
  7. package/lib/symlink.js +1 -1
  8. package/package.json +4 -2
  9. package/skills/refactoring-ui/SKILL.md +3 -7
  10. package/skills/seo-launch/SKILL.md +91 -0
  11. package/skills/seo-launch/assets/head.php +85 -0
  12. package/skills/seo-launch/assets/htaccess-static +86 -0
  13. package/skills/seo-launch/assets/robots.txt +17 -0
  14. package/skills/seo-launch/assets/social-meta.blade.php +90 -0
  15. package/skills/seo-launch/references/head-tags.md +109 -0
  16. package/skills/seo-launch/references/images.md +86 -0
  17. package/skills/seo-launch/references/search-engines.md +77 -0
  18. package/skills/seo-launch/references/server-files.md +168 -0
  19. package/skills/seo-launch/references/structured-data.md +139 -0
  20. package/skills/seo-launch/scripts/__pycache__/auditar_seo.cpython-312.pyc +0 -0
  21. package/skills/seo-launch/scripts/auditar_seo.py +539 -0
  22. package/skills/session-log/SKILL.md +83 -311
  23. package/skills/session-log/evals/README.md +16 -52
  24. package/skills/session-log/evals/ab-ronda-1.md +22 -67
  25. package/skills/session-log/evals/ab-ronda-2.md +28 -113
  26. package/skills/session-log/evals/defecto-experimento.md +3 -8
  27. package/skills/session-log/references/file-layout.md +44 -142
  28. package/skills/session-log/references/verification.md +22 -56
  29. package/skills/stitch-showcase/references/12-video-embedding.md +11 -28
  30. package/skills/stitch-showcase/references/13-language-detection.md +13 -38
  31. package/skills/stitch-showcase/references/14-troubleshooting-known-issues.md +18 -47
  32. package/skills/vscode-extension-dev/SKILL.md +3 -7
  33. package/skills/stitch-showcase/scripts/__pycache__/build_showcase.cpython-314.pyc +0 -0
  34. package/skills/stitch-showcase/scripts/__pycache__/component_utils.cpython-313.pyc +0 -0
  35. package/skills/stitch-showcase/scripts/__pycache__/component_utils.cpython-314.pyc +0 -0
  36. package/skills/stitch-showcase/scripts/__pycache__/detect_components.cpython-313.pyc +0 -0
  37. package/skills/stitch-showcase/scripts/__pycache__/detect_components.cpython-314.pyc +0 -0
  38. package/skills/stitch-showcase/scripts/__pycache__/extract_catalog.cpython-313.pyc +0 -0
  39. package/skills/stitch-showcase/scripts/__pycache__/extract_catalog.cpython-314.pyc +0 -0
  40. package/skills/stitch-showcase/scripts/__pycache__/extract_text.cpython-313.pyc +0 -0
  41. package/skills/stitch-showcase/scripts/__pycache__/extract_text.cpython-314.pyc +0 -0
  42. package/skills/stitch-showcase/scripts/__pycache__/extract_zips.cpython-313.pyc +0 -0
  43. package/skills/stitch-showcase/scripts/__pycache__/extract_zips.cpython-314.pyc +0 -0
  44. package/skills/stitch-showcase/scripts/__pycache__/parse_design_md.cpython-313.pyc +0 -0
  45. package/skills/stitch-showcase/scripts/__pycache__/parse_design_md.cpython-314.pyc +0 -0
  46. package/skills/stitch-showcase/scripts/__pycache__/slug_demangle.cpython-314.pyc +0 -0
@@ -1,7 +1,6 @@
1
1
  # The four files
2
2
 
3
- Read this when installing the convention in a project or migrating one that keeps
4
- its notes somewhere else.
3
+ Read this when installing the convention in a project or migrating one that keeps its notes somewhere else.
5
4
 
6
5
  <!-- TOC-START -->
7
6
  ## Contents
@@ -36,8 +35,7 @@ Same names in every project. That's what makes them findable without asking.
36
35
 
37
36
  ## The pointer block
38
37
 
39
- Identical in every context file. Keep it this short — duplicated prose drifts,
40
- three lines don't.
38
+ Identical in every context file. Keep it this short — duplicated prose drifts, three lines don't.
41
39
 
42
40
  ```markdown
43
41
  ## Project state
@@ -59,15 +57,13 @@ Where the tool supports imports, import the three stable files:
59
57
  @docs/project/decisions.md
60
58
  ```
61
59
 
62
- Never `@docs/project/status.md`. That single line is the difference between a
63
- cache that survives and one that gets thrown away on every update.
60
+ Never `@docs/project/status.md`. That single line is the difference between a cache that survives and one that gets thrown away on every update.
64
61
 
65
62
  ## Two variants
66
63
 
67
64
  ### One repo, several packages
68
65
 
69
- A monorepo takes the opposite answer from two sibling repos: **one `docs/project/`
70
- at the root**, with a heading per package.
66
+ A monorepo takes the opposite answer from two sibling repos: **one `docs/project/` at the root**, with a heading per package.
71
67
 
72
68
  ```
73
69
  docs/project/
@@ -75,19 +71,13 @@ docs/project/
75
71
  requirements.md same headings
76
72
  ```
77
73
 
78
- Sibling repos get their own files because each has its own branch, its own deploy
79
- state and its own history — three things that go stale independently. A monorepo has
80
- one of each. Splitting the notes per package there would invent a boundary git
81
- doesn't have, and the cross-package work — the half that actually goes wrong, the
82
- API change that breaks the web build — would have no obvious home.
74
+ Sibling repos get their own files because each has its own branch, its own deploy state and its own history — three things that go stale independently. A monorepo has one of each. Splitting the notes per package there would invent a boundary git doesn't have, and the cross-package work — the half that actually goes wrong, the API change that breaks the web build — would have no obvious home.
83
75
 
84
76
  The vocabulary rule is unchanged: `apps/api` is a heading, not a directory of notes.
85
77
 
86
78
  ### More than one person writing
87
79
 
88
- `status.md` is rewritten whole, by whoever is working, every session. Two people or
89
- two live branches means merge conflicts in it, reliably. That's a fact to plan for
90
- rather than a flaw to design around, because both obvious fixes are worse:
80
+ `status.md` is rewritten whole, by whoever is working, every session. Two people or two live branches means merge conflicts in it, reliably. That's a fact to plan for rather than a flaw to design around, because both obvious fixes are worse:
91
81
 
92
82
  | Tempting fix | What it costs |
93
83
  | --- | --- |
@@ -95,52 +85,30 @@ rather than a flaw to design around, because both obvious fixes are worse:
95
85
  | `.gitignore` it | The notes never reach the person they were written for |
96
86
  | Only the lead updates it | It goes stale the first week the lead is busy |
97
87
 
98
- Resolve conflicts by **keeping both sides and merging by section** — two people's
99
- "In flight" entries are both true, and whichever loses a conflict is information
100
- nobody gets back. If the friction is constant rather than occasional, the team wants
101
- a heading per workstream inside the file. Still one file.
88
+ Resolve conflicts by **keeping both sides and merging by section** — two people's "In flight" entries are both true, and whichever loses a conflict is information nobody gets back. If the friction is constant rather than occasional, the team wants a heading per workstream inside the file. Still one file.
102
89
 
103
90
  ## Repos that come in pairs
104
91
 
105
- A web backend and the mobile client that consumes it. The mechanics of installing
106
- and closing both are in the skill; what follows is the detail that didn't need to
107
- load every session.
92
+ A web backend and the mobile client that consumes it. The mechanics of installing and closing both are in the skill; what follows is the detail that didn't need to load every session.
108
93
 
109
- **Install from inside each repo, separately.** Open the backend, install; open the
110
- app, install. It's a one-time act per repo and it's worth doing from the right
111
- place: sitting inside the project means its own context file loads, its own MCP
112
- servers connect, and its stack-specific skills detect themselves. Installing a
113
- repo's notes from its sibling means describing a project you're looking at from
114
- outside — and the result reads like it, because the detail that makes `context.md`
115
- useful is exactly what you don't see from across the fence.
94
+ **Install from inside each repo, separately.** Open the backend, install; open the app, install. It's a one-time act per repo and it's worth doing from the right place: sitting inside the project means its own context file loads, its own MCP servers connect, and its stack-specific skills detect themselves. Installing a repo's notes from its sibling means describing a project you're looking at from outside — and the result reads like it, because the detail that makes `context.md` useful is exactly what you don't see from across the fence.
116
95
 
117
- Put the sibling's **path** in the header of `status.md`, not just its name, so
118
- whoever reads it next can actually go there:
96
+ Put the sibling's **path** in the header of `status.md`, not just its name, so whoever reads it next can actually go there:
119
97
 
120
98
  ```markdown
121
99
  **Sibling:** `../../Apps/EM Industrial` (Titanium client) — waiting on
122
100
  `/work-orders/{id}/progress`, not built here yet.
123
101
  ```
124
102
 
125
- **Once both are installed, updating them from one session is fine** — that's the
126
- day-to-day case, and it's different from installing. The files already exist and
127
- carry the project's own vocabulary; you're appending what changed, not inventing a
128
- description of a repo you can't see.
103
+ **Once both are installed, updating them from one session is fine** — that's the day-to-day case, and it's different from installing. The files already exist and carry the project's own vocabulary; you're appending what changed, not inventing a description of a repo you can't see.
129
104
 
130
- Write the sibling's status from what you did to it, not from what you assume about
131
- it. "Added the client call for `/work-orders/{id}/progress`" is something you know.
132
- "The app is now feature-complete for E5" is something the app would have to tell
133
- you. And if the sibling isn't reachable from where you're working, say so in the
134
- handoff rather than guessing: "endpoint added here; the app side needs its status
135
- updated, I couldn't reach that repo" is honest and actionable. A confident claim
136
- about a repo you didn't open is neither.
105
+ Write the sibling's status from what you did to it, not from what you assume about it. "Added the client call for `/work-orders/{id}/progress`" is something you know. "The app is now feature-complete for E5" is something the app would have to tell you. And if the sibling isn't reachable from where you're working, say so in the handoff rather than guessing: "endpoint added here; the app side needs its status updated, I couldn't reach that repo" is honest and actionable. A confident claim about a repo you didn't open is neither.
137
106
 
138
107
  ## Templates
139
108
 
140
109
  ### `docs/project/status.md`
141
110
 
142
- The only file that changes every session. Keep it short enough that someone
143
- actually reads it.
111
+ The only file that changes every session. Keep it short enough that someone actually reads it.
144
112
 
145
113
  ```markdown
146
114
  # Status — <YYYY-MM-DD>
@@ -178,17 +146,11 @@ actually reads it.
178
146
 
179
147
  Absolute dates, never "yesterday" — the file outlives the session that wrote it.
180
148
 
181
- The three header lines exist because they're the questions asked first and
182
- answered worst. **Deployed is not the same as committed**: on a project that
183
- deploys by file sync, a change can be live and uncommitted, or committed and never
184
- uploaded. Write what you know and mark what you don't; a confident wrong answer
185
- here sends someone debugging the wrong copy of the code.
149
+ The three header lines exist because they're the questions asked first and answered worst. **Deployed is not the same as committed**: on a project that deploys by file sync, a change can be live and uncommitted, or committed and never uploaded. Write what you know and mark what you don't; a confident wrong answer here sends someone debugging the wrong copy of the code.
186
150
 
187
151
  ### `docs/project/requirements.md`
188
152
 
189
- The contract: what the system must do and how you'd know it does. Stable — it
190
- changes when scope changes, not when work happens. **Progress lives in
191
- `status.md`**, not here.
153
+ The contract: what the system must do and how you'd know it does. Stable — it changes when scope changes, not when work happens. **Progress lives in `status.md`**, not here.
192
154
 
193
155
  ```markdown
194
156
  # Requirements
@@ -220,33 +182,19 @@ if nothing else exists>
220
182
  acceptance criterion belongs here, not in the table above.>
221
183
  ```
222
184
 
223
- **Invariants** are for projects where the risk isn't forgetting a feature — it's
224
- breaking a property while improving something else. Offline-first, no polling, a
225
- storage schema other code depends on, a latency budget. They read like
226
- conventions but they're stronger: a convention is how the team writes code, an
227
- invariant is a promise the system makes. Write what breaking it would look like,
228
- not just the rule, so it's recognizable when someone is about to do it.
185
+ **Invariants** are for projects where the risk isn't forgetting a feature — it's breaking a property while improving something else. Offline-first, no polling, a storage schema other code depends on, a latency budget. They read like conventions but they're stronger: a convention is how the team writes code, an invariant is a promise the system makes. Write what breaking it would look like, not just the rule, so it's recognizable when someone is about to do it.
229
186
 
230
- Not every project has them. Skip the section when the honest answer is that
231
- nothing here is that load-bearing.
187
+ Not every project has them. Skip the section when the honest answer is that nothing here is that load-bearing.
232
188
 
233
- **When the requirements live in another repo**, this file is an index pointing
234
- outward rather than a self-contained contract — half its rows may reference
235
- `../other-repo/…`. That's correct: copying the spec across creates a second copy
236
- that drifts. Say plainly at the top which repo owns the contract.
189
+ **When the requirements live in another repo**, this file is an index pointing outward rather than a self-contained contract — half its rows may reference `../other-repo/…`. That's correct: copying the spec across creates a second copy that drifts. Say plainly at the top which repo owns the contract.
237
190
 
238
- Write acceptance criteria you could hand to someone else to check. "Payments
239
- work" is not one; "charging a member writes a Payment row and the receipt shows
240
- the folio" is. If you can't write one, the requirement isn't specified — say so
241
- in **Unspecified** rather than pretending the table is complete.
191
+ Write acceptance criteria you could hand to someone else to check. "Payments work" is not one; "charging a member writes a Payment row and the receipt shows the folio" is. If you can't write one, the requirement isn't specified — say so in **Unspecified** rather than pretending the table is complete.
242
192
 
243
- The **Out of scope** section earns its place on client work: it's the cheapest
244
- insurance against a disagreement six weeks later about what was included.
193
+ The **Out of scope** section earns its place on client work: it's the cheapest insurance against a disagreement six weeks later about what was included.
245
194
 
246
195
  ### `docs/project/decisions.md`
247
196
 
248
- Append-only. Old entries stay even when superseded; a decision that was reversed
249
- is more informative than one that was deleted.
197
+ Append-only. Old entries stay even when superseded; a decision that was reversed is more informative than one that was deleted.
250
198
 
251
199
  ```markdown
252
200
  ## <YYYY-MM-DD> — <the decision in one line>
@@ -257,10 +205,7 @@ is more informative than one that was deleted.
257
205
  **Reverses:** <link to an earlier entry, when applicable>
258
206
  ```
259
207
 
260
- **When the date isn't knowable**, don't invent one. A repo with a single commit,
261
- or everything still under `[Unreleased]`, has real decisions with no traceable
262
- date — and stamping them with the commit date is a fabrication that later reads
263
- as fact. Put them in a separate section that says why:
208
+ **When the date isn't knowable**, don't invent one. A repo with a single commit, or everything still under `[Unreleased]`, has real decisions with no traceable date — and stamping them with the commit date is a fabrication that later reads as fact. Put them in a separate section that says why:
264
209
 
265
210
  ```markdown
266
211
  ## Decisions without a traceable date
@@ -272,13 +217,9 @@ reasoning is recovered from the code and the docs; the dates are not known.
272
217
  **Chose / Over / Because:** <as above>
273
218
  ```
274
219
 
275
- These are usually the most valuable entries in the file, because they're the ones
276
- that explain why the code doesn't match the spec. Losing them to keep the template
277
- tidy is the wrong trade.
220
+ These are usually the most valuable entries in the file, because they're the ones that explain why the code doesn't match the spec. Losing them to keep the template tidy is the wrong trade.
278
221
 
279
- **Archiving.** Append-only and imported-at-startup is a combination with a shelf
280
- life: every session pays for the whole file, and most of what it's paying for is a
281
- decision from two years ago that nobody is about to revisit.
222
+ **Archiving.** Append-only and imported-at-startup is a combination with a shelf life: every session pays for the whole file, and most of what it's paying for is a decision from two years ago that nobody is about to revisit.
282
223
 
283
224
  Past roughly two hundred lines, split it:
284
225
 
@@ -287,23 +228,15 @@ docs/project/decisions.md current year — imported
287
228
  docs/project/decisions-archive.md everything older — NOT imported
288
229
  ```
289
230
 
290
- Move entries oldest-first, keep them verbatim, and leave a line at the top of
291
- `decisions.md` saying where the rest went. Then check the import chain again — the
292
- archive must not be pulled in by any `@` line, or the split bought nothing.
231
+ Move entries oldest-first, keep them verbatim, and leave a line at the top of `decisions.md` saying where the rest went. Then check the import chain again — the archive must not be pulled in by any `@` line, or the split bought nothing.
293
232
 
294
- Two rules keep the archive honest. A superseded entry stays with its reverser, even
295
- if that means keeping an old entry in the current file — a reversal that outlives
296
- the decision it reversed reads as if the original never happened. And an entry the
297
- project still argues about is current by definition, whatever its date.
233
+ Two rules keep the archive honest. A superseded entry stays with its reverser, even if that means keeping an old entry in the current file — a reversal that outlives the decision it reversed reads as if the original never happened. And an entry the project still argues about is current by definition, whatever its date.
298
234
 
299
- Two hundred lines is a prompt to look, not a threshold to enforce. A project with
300
- twelve decisions in four years never needs this.
235
+ Two hundred lines is a prompt to look, not a threshold to enforce. A project with twelve decisions in four years never needs this.
301
236
 
302
237
  ### `docs/project/context.md`
303
238
 
304
- How the project is put together, and what a newcomer would get wrong on day one.
305
- Anything derivable from reading the code doesn't belong here — this is for what
306
- the code *doesn't* say.
239
+ How the project is put together, and what a newcomer would get wrong on day one. Anything derivable from reading the code doesn't belong here — this is for what the code *doesn't* say.
307
240
 
308
241
  ```markdown
309
242
  # Context
@@ -323,62 +256,31 @@ the code *doesn't* say.
323
256
  - <The thing that cost someone a day, and how to avoid it.>
324
257
  ```
325
258
 
326
- The map goes first because it's what someone new needs first: knowing what exists
327
- saves them from rewriting it. List every document you found, including the ones
328
- that turned out to be stale — marked as stale. A document omitted from the map is
329
- a document nobody will open again.
259
+ The map goes first because it's what someone new needs first: knowing what exists saves them from rewriting it. List every document you found, including the ones that turned out to be stale — marked as stale. A document omitted from the map is a document nobody will open again.
330
260
 
331
261
  ## Migrating an existing project
332
262
 
333
- Projects that already keep notes somewhere — `.claude/memory/`, a roadmap under
334
- `docs/`, a planning doc — get migrated rather than duplicated. Two locations is
335
- the problem this convention exists to solve.
263
+ Projects that already keep notes somewhere — `.claude/memory/`, a roadmap under `docs/`, a planning doc — get migrated rather than duplicated. Two locations is the problem this convention exists to solve.
336
264
 
337
- 1. **Read what's there** and sort it: is this line status, a decision, or context?
338
- Most existing notes are a mix, and that's exactly why they're hard to use.
339
- 2. **Split it into the four files.** Status goes to `status.md` even if it was
340
- living in an imported file — especially then.
341
- 3. **Delete the old location** and update anything that referenced it, including
342
- `@import` lines in context files.
265
+ 1. **Read what's there** and sort it: is this line status, a decision, or context? Most existing notes are a mix, and that's exactly why they're hard to use.
266
+ 2. **Split it into the four files.** Status goes to `status.md` even if it was living in an imported file — especially then.
267
+ 3. **Delete the old location** and update anything that referenced it, including `@import` lines in context files.
343
268
  4. **Add the pointer block** to every context file.
344
- 5. **Tell the person what moved where**, concretely. They need to be able to check
345
- that nothing was lost, and a migration they can't audit is one they won't trust.
269
+ 5. **Tell the person what moved where**, concretely. They need to be able to check that nothing was lost, and a migration they can't audit is one they won't trust.
346
270
 
347
- If the project has a planning doc with real structure — a numbered checklist, a
348
- PRD — don't flatten it into `status.md`. Leave it where it is and reference it
349
- from `status.md`. The convention is about knowing where to look, not about
350
- destroying work that already has a shape.
271
+ If the project has a planning doc with real structure — a numbered checklist, a PRD — don't flatten it into `status.md`. Leave it where it is and reference it from `status.md`. The convention is about knowing where to look, not about destroying work that already has a shape.
351
272
 
352
273
  ### Upgrading an earlier version of this convention
353
274
 
354
- Repos installed before the four-file layout settled look almost right and aren't:
355
- a lone `docs/status/current.md`, a `docs/project/` holding three files named by
356
- hand, an `estado-actual.md` next to a `decisiones.md`. This is an upgrade, not a
357
- migration, and the difference matters the content was written by someone who was
358
- there, so it's correct until the repo contradicts it.
359
-
360
- 1. **`git mv` into the fixed names**, so the history follows the file. Copying and
361
- deleting loses the one thing that made the old file trustworthy.
362
- 2. **Split by volatility, not by topic.** The usual finding is a single file mixing
363
- a stable architecture description with three lines of "where I left off". The
364
- stable half goes to `context.md` or `requirements.md`; only the volatile half
365
- ends up in `status.md`.
366
- 3. **Update every pointer**, including `@import` lines and any reference from
367
- `README.md` or a sibling repo's header. A pointer to the old path is worse than
368
- no pointer: it resolves to nothing and looks maintained.
369
- 4. **Say what moved where**, path by path. An upgrade someone can't audit is one
370
- they won't trust, and this one moves files they wrote.
275
+ Repos installed before the four-file layout settled look almost right and aren't: a lone `docs/status/current.md`, a `docs/project/` holding three files named by hand, an `estado-actual.md` next to a `decisiones.md`. This is an upgrade, not a migration, and the difference matters — the content was written by someone who was there, so it's correct until the repo contradicts it.
276
+
277
+ 1. **`git mv` into the fixed names**, so the history follows the file. Copying and deleting loses the one thing that made the old file trustworthy.
278
+ 2. **Split by volatility, not by topic.** The usual finding is a single file mixing a stable architecture description with three lines of "where I left off". The stable half goes to `context.md` or `requirements.md`; only the volatile half ends up in `status.md`.
279
+ 3. **Update every pointer**, including `@import` lines and any reference from `README.md` or a sibling repo's header. A pointer to the old path is worse than no pointer: it resolves to nothing and looks maintained.
280
+ 4. **Say what moved where**, path by path. An upgrade someone can't audit is one they won't trust, and this one moves files they wrote.
371
281
 
372
282
  ## Sizing
373
283
 
374
- A repo with one commit doesn't need four files with nothing in them. Start with
375
- whichever ones have content — often `requirements.md` and `status.md` early on,
376
- `context.md` and `decisions.md` once the thing exists — and add the rest when
377
- there's something real to put in them. A `decisions.md` whose only entry is the decision to keep decisions is a
378
- file that exists to look organized.
379
-
380
- **The pointer block lists the files that exist.** Listing all four from the start is
381
- tempting — it shows the shape — but three of the four lines then point at nothing,
382
- and a pointer that resolves to a missing file trains the next reader to distrust the
383
- block. Add the line when the file arrives; it's one line, at the moment it becomes
384
- true.
284
+ A repo with one commit doesn't need four files with nothing in them. Start with whichever ones have content — often `requirements.md` and `status.md` early on, `context.md` and `decisions.md` once the thing exists — and add the rest when there's something real to put in them. A `decisions.md` whose only entry is the decision to keep decisions is a file that exists to look organized.
285
+
286
+ **The pointer block lists the files that exist.** Listing all four from the start is tempting it shows the shape — but three of the four lines then point at nothing, and a pointer that resolves to a missing file trains the next reader to distrust the block. Add the line when the file arrives; it's one line, at the moment it becomes true.
@@ -1,12 +1,10 @@
1
1
  # Verifying that work actually exists
2
2
 
3
- Read this before marking anything as done. The goal is narrow: turn "I finished
4
- X" into "I found the artifacts X would have produced."
3
+ Read this before marking anything as done. The goal is narrow: turn "I finished X" into "I found the artifacts X would have produced."
5
4
 
6
5
  ## What "done" is allowed to mean
7
6
 
8
- Be careful with the word — these are different claims, and a record that collapses
9
- them into one checkmark loses the distinction exactly when someone needs it:
7
+ Be careful with the word — these are different claims, and a record that collapses them into one checkmark loses the distinction exactly when someone needs it:
10
8
 
11
9
  | Claim | What it means |
12
10
  | --- | --- |
@@ -15,39 +13,24 @@ them into one checkmark loses the distinction exactly when someone needs it:
15
13
  | Reviewed | A human looked at it |
16
14
  | Shipped | It's deployed or released |
17
15
 
18
- Use the distinction to be *more* precise, not to avoid answering. "Implemented,
19
- not yet verified — no test covers it" is a useful record. Marking nothing at all
20
- because verification was impossible is not.
16
+ Use the distinction to be *more* precise, not to avoid answering. "Implemented, not yet verified — no test covers it" is a useful record. Marking nothing at all because verification was impossible is not.
21
17
 
22
18
  ## Three ways records go bad
23
19
 
24
- **Percentages the repo can't support.** A percentage needs a fixed denominator —
25
- a checklist with a known number of items. Without one, any number is invented.
26
- Count what's enumerable or describe status in words.
20
+ **Percentages the repo can't support.** A percentage needs a fixed denominator — a checklist with a known number of items. Without one, any number is invented. Count what's enumerable or describe status in words.
27
21
 
28
- **Duplicating what the repo already records.** Git history, the CHANGELOG and the
29
- code are better sources than a note paraphrasing them. Record what they *can't*
30
- say: why an approach was abandoned, what failed, what looks wrong but is deliberate.
22
+ **Duplicating what the repo already records.** Git history, the CHANGELOG and the code are better sources than a note paraphrasing them. Record what they *can't* say: why an approach was abandoned, what failed, what looks wrong but is deliberate.
31
23
 
32
- **Padding.** A handoff nobody reads is a handoff that failed. Three specific lines
33
- beat a page of headers. Length is not thoroughness.
24
+ **Padding.** A handoff nobody reads is a handoff that failed. Three specific lines beat a page of headers. Length is not thoroughness.
34
25
 
35
26
  ## The method
36
27
 
37
- Someone's claim is about behavior. The repo holds artifacts. Verification is
38
- translating between the two:
39
-
40
- 1. **Name the artifacts before searching.** "Finished the payments module" should
41
- produce a concrete list first a service class, a route, a migration, a test.
42
- Writing that list before you look is what stops you from accepting whatever
43
- you happen to find as sufficient.
44
- 2. **Search for those specific things**, not for the feature name. Grepping for
45
- "payment" finds comments, TODOs, and unrelated strings. Grepping for the route
46
- registration or the class definition finds the thing itself.
47
- 3. **Distinguish existence from completeness.** A file that exists but contains a
48
- stub is not the feature. Open what you find when the claim is substantial.
49
- 4. **Report the gap, not just the verdict.** "Found the service and the routes;
50
- no tests and no migration" is useful. "Not done" is not.
28
+ Someone's claim is about behavior. The repo holds artifacts. Verification is translating between the two:
29
+
30
+ 1. **Name the artifacts before searching.** "Finished the payments module" should produce a concrete list first — a service class, a route, a migration, a test. Writing that list before you look is what stops you from accepting whatever you happen to find as sufficient.
31
+ 2. **Search for those specific things**, not for the feature name. Grepping for "payment" finds comments, TODOs, and unrelated strings. Grepping for the route registration or the class definition finds the thing itself.
32
+ 3. **Distinguish existence from completeness.** A file that exists but contains a stub is not the feature. Open what you find when the claim is substantial.
33
+ 4. **Report the gap, not just the verdict.** "Found the service and the routes; no tests and no migration" is useful. "Not done" is not.
51
34
 
52
35
  ## What to search for, by stack
53
36
 
@@ -80,8 +63,7 @@ A Livewire feature that has a class but no Blade view is not done. Check both.
80
63
  | Native module | Declared in `tiapp.xml` under `<modules>` **and** present in `modules/` |
81
64
  | Platform config | `tiapp.xml` |
82
65
 
83
- A controller without its view compiles to nothing usable. A string added to one
84
- locale and not the others ships as a raw key in the missing language.
66
+ A controller without its view compiles to nothing usable. A string added to one locale and not the others ships as a raw key in the missing language.
85
67
 
86
68
  ### Node / TypeScript
87
69
 
@@ -124,27 +106,17 @@ locale and not the others ships as a raw key in the missing language.
124
106
 
125
107
  ## Claims in a status file you didn't write
126
108
 
127
- Resuming work means reading claims written weeks ago by someone — possibly you —
128
- who is no longer available to ask. The method above applies unchanged, with one
129
- addition: an old record has a **direction of error**. It says what was true when it
130
- was written, so its claims rot toward being *understated* about what exists and
131
- *overstated* about what's blocked.
109
+ Resuming work means reading claims written weeks ago by someone — possibly you — who is no longer available to ask. The method above applies unchanged, with one addition: an old record has a **direction of error**. It says what was true when it was written, so its claims rot toward being *understated* about what exists and *overstated* about what's blocked.
132
110
 
133
- - "Not started" from three weeks ago may well be finished. Check the artifacts
134
- before repeating it this is the most common way a resumed session redoes work.
135
- - "Blocked on the client" has a date attached to a person who has probably answered
136
- since. Flag it as needing a human check rather than carrying it forward as fact.
137
- - "Next step: X" may be stale in a way the file cannot know. If X is already in the
138
- code, say so instead of proposing it again.
111
+ - "Not started" from three weeks ago may well be finished. Check the artifacts before repeating it — this is the most common way a resumed session redoes work.
112
+ - "Blocked on the client" has a date attached to a person who has probably answered since. Flag it as needing a human check rather than carrying it forward as fact.
113
+ - "Next step: X" may be stale in a way the file cannot know. If X is already in the code, say so instead of proposing it again.
139
114
 
140
- The safe form is attribution: "the file says the payments module was left half-done
141
- on 2026-07-14; the routes and the service exist now, so part of that landed after it
142
- was written". That gives the person both the record and the correction.
115
+ The safe form is attribution: "the file says the payments module was left half-done on 2026-07-14; the routes and the service exist now, so part of that landed after it was written". That gives the person both the record and the correction.
143
116
 
144
117
  ## Claims that can't be verified from the repo
145
118
 
146
- Some are legitimate and simply live elsewhere: work in another repository, a
147
- deploy, a conversation with a client, a design decision.
119
+ Some are legitimate and simply live elsewhere: work in another repository, a deploy, a conversation with a client, a design decision.
148
120
 
149
121
  Record them. Label them. The pattern that keeps the log trustworthy is:
150
122
 
@@ -158,16 +130,10 @@ The distinction costs one word and preserves the whole point of the record.
158
130
 
159
131
  ## Deployment is not git state
160
132
 
161
- A change can be live on a server without being committed, and committed without
162
- being live. Repos with file-sync deployment (SFTP-on-save watchers, rsync hooks)
163
- break the assumption that git reflects production entirely.
133
+ A change can be live on a server without being committed, and committed without being live. Repos with file-sync deployment (SFTP-on-save watchers, rsync hooks) break the assumption that git reflects production entirely.
164
134
 
165
- Never infer deployment state from git. When it matters, check the deployment
166
- configuration in the repo, or ask.
135
+ Never infer deployment state from git. When it matters, check the deployment configuration in the repo, or ask.
167
136
 
168
137
  ## Tests: the output is the evidence
169
138
 
170
- "Tests pass" is a claim like any other. If you ran them, quote the count and the
171
- result. If you didn't, say so. A log that records passing tests nobody ran is
172
- worse than one that records nothing, because it stops the next session from
173
- running them.
139
+ "Tests pass" is a claim like any other. If you ran them, quote the count and the result. If you didn't, say so. A log that records passing tests nobody ran is worse than one that records nothing, because it stops the next session from running them.
@@ -2,16 +2,11 @@
2
2
 
3
3
  ## Purpose
4
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.
5
+ Sometimes a Stitch slot needs to show a video instead of a still image (product demo, animated logo, looping background, recorded screen). This document captures the exact pattern that works across browsers and avoids the common pitfalls — content recropping, layout shift, AV1 codec, and aspect-ratio mismatch with the original wrapper.
10
6
 
11
7
  ## The Tag
12
8
 
13
- Use a plain `<video>` element with native `width` and `height` attributes
14
- plus inline styling for safe defaults:
9
+ Use a plain `<video>` element with native `width` and `height` attributes plus inline styling for safe defaults:
15
10
 
16
11
  ```html
17
12
  <video
@@ -27,8 +22,7 @@ plus inline styling for safe defaults:
27
22
  </video>
28
23
  ```
29
24
 
30
- Replace `W` / `H` with the **native** video dimensions and `<slug>` with
31
- the screen slug (or whatever filename you used inside `videos/`).
25
+ Replace `W` / `H` with the **native** video dimensions and `<slug>` with the screen slug (or whatever filename you used inside `videos/`).
32
26
 
33
27
  ### Why each attribute
34
28
 
@@ -43,15 +37,13 @@ the screen slug (or whatever filename you used inside `videos/`).
43
37
 
44
38
  ## File Workflow
45
39
 
46
- 1. **Download** the source video. For Facebook/Instagram/YouTube/TikTok we
47
- recommend `yt-dlp`:
40
+ 1. **Download** the source video. For Facebook/Instagram/YouTube/TikTok we recommend `yt-dlp`:
48
41
 
49
42
  ```bash
50
43
  yt-dlp "https://www.facebook.com/<...>/videos/<id>" -o "videos/<slug>.%(ext)s"
51
44
  ```
52
45
 
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:
46
+ 2. **Re-encode to H.264** if the source comes down as AV1. AV1 doesn't preview in macOS Finder and is rejected by Safari < 17:
55
47
 
56
48
  ```bash
57
49
  ffmpeg -i in.mp4 \
@@ -63,12 +55,9 @@ the screen slug (or whatever filename you used inside `videos/`).
63
55
 
64
56
  - `-preset fast`: balanced speed/quality.
65
57
  - `-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.
58
+ - `-movflags +faststart`: moves the moov atom to the front so the video can start playing before fully downloaded.
68
59
 
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:
60
+ 3. **Place** the encoded `.mp4` in a `videos/` folder at the **project level** (the same level as `stitch/` or `showcase/`, not inside `assets/`), so the build keeps it out of the screen-extraction pipeline:
72
61
 
73
62
  ```text
74
63
  my-project/
@@ -80,8 +69,7 @@ the screen slug (or whatever filename you used inside `videos/`).
80
69
  └── <slug>.html ← references ../../videos/hero.mp4
81
70
  ```
82
71
 
83
- 4. **Reference from the screen HTML** with a relative path. From inside
84
- `showcase/assets/<slug>.html`, `videos/` is two levels up:
72
+ 4. **Reference from the screen HTML** with a relative path. From inside `showcase/assets/<slug>.html`, `videos/` is two levels up:
85
73
 
86
74
  ```html
87
75
  <source src="../../videos/hero.mp4" type="video/mp4">
@@ -89,18 +77,14 @@ the screen slug (or whatever filename you used inside `videos/`).
89
77
 
90
78
  ## Aspect-Ratio Mismatch
91
79
 
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:
80
+ The original Stitch wrapper for a video slot usually carries a fixed aspect ratio (e.g. `aspect-[4/5]`). If your video is a different shape — say 9/16 — keeping the wrapper's aspect locks the video into the wrong box, which then forces a choice:
96
81
 
97
82
  | Option | Effect |
98
83
  |--------|--------|
99
84
  | Keep wrapper's `aspect-*` + `object-cover` | Video crops; logos and edges get chopped. |
100
85
  | **Remove wrapper's `aspect-*` + `height:auto`** | Video keeps its native aspect; the slot grows or shrinks vertically to fit. ✅ |
101
86
 
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.
87
+ The second option is almost always what you want — better to have a slightly taller card than to chop the brand logo out of the frame.
104
88
 
105
89
  ## Quick Sanity Checks
106
90
 
@@ -109,5 +93,4 @@ After embedding, open the screen in a browser and confirm:
109
93
  - The video autoplays without a tap on Chrome, Safari, and Firefox.
110
94
  - The video loops cleanly (no flash on rewind).
111
95
  - 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.
96
+ - The file size is reasonable — re-encode with a higher `-crf` if it's more than ~3-5 MB per 10 seconds.
@@ -2,19 +2,13 @@
2
2
 
3
3
  ## Purpose
4
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.
5
+ The `<html lang="…">` attribute on the generated `index.html` and `viewer.html` tells the browser which natural language the content uses. If the value disagrees with the actual content, Chrome shows a "Translate this page" banner and assistive technologies pronounce words with the wrong phoneme set. This document explains how the build picks the value and how to override it.
11
6
 
12
7
  ## Resolution Order
13
8
 
14
9
  The `lang` attribute is chosen by the first rule that fires:
15
10
 
16
- 1. **CLI flag** (future — not implemented yet): `--lang es` on
17
- `build_showcase.py`.
11
+ 1. **CLI flag** (future — not implemented yet): `--lang es` on `build_showcase.py`.
18
12
  2. **`showcase.json` field**:
19
13
 
20
14
  ```json
@@ -33,50 +27,31 @@ The `lang` attribute is chosen by the first rule that fires:
33
27
  es
34
28
  ```
35
29
 
36
- 4. **Auto-detection** from the text content of `DESIGN.md` (project name,
37
- section names, descriptions). The detector counts Spanish signals:
30
+ 4. **Auto-detection** from the text content of `DESIGN.md` (project name, section names, descriptions). The detector counts Spanish signals:
38
31
 
39
32
  - Accented characters (`á é í ó ú ñ`).
40
- - Common Spanish stop words (`de`, `el`, `la`, `los`, `las`, `para`,
41
- `con`, `pantalla`, `aplicación`, `usuario`, etc.).
33
+ - Common Spanish stop words (`de`, `el`, `la`, `los`, `las`, `para`, `con`, `pantalla`, `aplicación`, `usuario`, etc.).
42
34
 
43
- If the Spanish score crosses a small threshold, the lang resolves to
44
- `"es"`; otherwise it falls through.
35
+ If the Spanish score crosses a small threshold, the lang resolves to `"es"`; otherwise it falls through.
45
36
 
46
37
  5. **Default**: `"en"`.
47
38
 
48
39
  ## When to Override
49
40
 
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:
41
+ The auto-detector handles obvious cases (a project whose DESIGN.md is entirely Spanish or entirely English), but it can be fooled by very short DESIGN.md files or by projects where the UI language differs from the documentation language. Use an explicit override when:
54
42
 
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).
43
+ - The DESIGN.md is in English but the actual screen content is Spanish (you'd be documenting an es-MX app in English for a client).
57
44
  - 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.
45
+ - You want a non-Spanish, non-English language (`pt`, `fr`, `de` …) — the auto-detector only distinguishes Spanish vs everything else.
60
46
 
61
47
  ## Why It Matters
62
48
 
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.
49
+ - **Chrome's translate prompt**: with `lang="en"` and Spanish content, Chrome offers to translate the page to the user's locale. Users perceive this as a bug.
50
+ - **Screen readers**: VoiceOver and TalkBack switch pronunciation engines per `lang`. A wrong value makes Spanish text sound like a speech synthesizer trying to pronounce "configuración" as English.
51
+ - **Search engines**: the `lang` attribute is a soft signal but it's read by indexers when ranking pages by locale.
71
52
 
72
53
  ## Common Mistake: Mismatched Lang and Content
73
54
 
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).
55
+ The previous template hard-coded `lang="en"` even for Spanish-only projects. The fix wasn't to flip the default to `"es"` (that just moves the bug to English projects) — it was to detect or accept an override. The same logic now lives in `parse_design_md.py` (`_detect_lang`) and `build_showcase.py` (the `{{HTML_LANG}}` placeholder substitution).
79
56
 
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.
57
+ If you ever see Chrome offering to translate one of your showcases: that's the signal that the resolved `lang` is wrong. Add an override to `showcase.json` or `DESIGN.md` and rebuild.