craft is a deprecated compatibility alias, but its SKILL_CATEGORIES entry
kept it advertised in every generated SKILL.md argument-hint. Unmapping it
removes it from the hint while the alias keeps routing through the router
table and command-metadata.json.
AI-assisted change (reviewed by maintainer).
Co-authored-by: Cursor <cursoragent@cursor.com>
Phase one is near-pixel-perfect reproduction at the comp's breakpoint,
with exactly three concessions (closest font, icons unless a library
was chosen, genuine comp defects); the overlap comparison is the
authority because models systematically believe their code recreation
succeeded when it did not, and regions that keep losing the comparison
ship as composited rendered assets instead. Phase two brings the
reproduction to life (interaction, motion, responsiveness), and
anything beyond the comp inherits the recorded system, never invented
container chrome.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The containment gate re-canonicalized projectCwd for every target file
in the per-edit and Stop loops. The hook runs as a fresh process per
tool event, so a module-level memo makes it once-per-event work; the
size cap only matters to long-lived importers like the test runner.
Addresses Copilot review feedback on PR #471.
Written with AI assistance (Claude Code).
Co-Authored-By: Claude Code <noreply@anthropic.com>
Replace three duplicate matcher loops with one declarative pattern list while preserving import resolution behavior. Add Sass @use and @forward characterization coverage.\n\nAI-assisted change prepared under pbakaus's scheduled architecture-refactor authorization.
hook-before-edit.mjs kept its own string-based isInsideProject; it now
uses the shared isScanTargetInsideProject so all three hook passes
apply one containment semantic, symlink canonicalization included.
Because the before-edit hook gates proposed Writes whose target does
not exist yet, canonicalPath now resolves the nearest existing
ancestor and re-appends the remainder instead of falling back to the
raw resolved path — a new file under a symlinked root compares equal
to its canonical project.
Written with AI assistance (Claude Code).
Co-Authored-By: Claude Code <noreply@anthropic.com>
The per-edit and Stop deep passes gated on sensitive paths, generated
paths, extension, config ignores, and size, but never on containment.
Any file the session touched outside the project (harness scratchpad
dirs under the system temp root, sibling checkouts) was scanned and
judged against THIS project's config and DESIGN.md palette, producing
design-system findings that are wrong by construction.
Both loops now check isScanTargetInsideProject() (audit reason:
outside-project), matching the gate hook-before-edit.mjs already had.
Paths are canonicalized so a symlinked root doesn't split the
comparison. The Stop pass re-checks containment itself because caches
written by older hook versions can still list out-of-project paths.
Umbrella-dir launches (issue #305) are unaffected: their projectCwd
resolves to the edited file's own project root, so containment holds.
Written with AI assistance (Claude Code).
Co-Authored-By: Claude Code <noreply@anthropic.com>
Review follow-up: the regex stopped at the literal ?token= and tolerated
anything after it, so removing the encoded token value from the URL
still passed. Requiring encodeURIComponent(TOKEN) right after the
prefix makes the mutation fail.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Review follow-up: the reflected-origin contract matters most on the
OPTIONS preflight, where a cached response authorized for one origin
must never be served to another.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Covers the fix for the ddev breakage reported in #304: the live server
now reflects Access-Control-Allow-Origin for any request bearing the
valid session token, so dev servers on loopback aliases (https://*.ddev.site,
Valet's *.test, hosts-file entries) work again while tokenless remote
origins stay blocked. The server/browser source changes shipped in
b1c5707f; this adds the test coverage that was written alongside them:
- tokenless remote origins get no ACAO on any route, token'd or not
- a non-loopback origin with the valid token is reflected, with
Vary: Origin, on both the real request and its OPTIONS preflight
- the /manual-edit-stash source assertion tracks the token-bearing URL
Prepared with AI assistance.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
context.mjs now probes cwebp/sips/magick/ffmpeg once (which/where per
OS) and prints IMAGE_TOOLS, replacing macOS-specific prose; the
IMAGE_GEN_AVAILABLE directive leads with the harness-native tool so a
present OpenAI key stops reading as an instruction to bill it; and the
sandboxed board-start guidance sheds codex vocabulary.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sandboxed shells cannot bind the board's port; every codex session paid
one failed start before retrying escalated.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Recognize both slash- and dollar-prefixed prescribed seed markers and exercise each variant in coverage tests.
AI assistance: Codex addressed Cursor and Copilot review feedback and reran validation under maintainer authorization.
Treat Components as optional only when DESIGN.md carries the prescribed seed marker, while retaining Colors and Typography checks.
AI assistance: Codex reproduced the issue, implemented the fix, and added regression coverage under maintainer authorization.
Join indented Markdown bullet continuations and keep them out of Overview philosophy text.
AI assistance: Codex reproduced the issue, implemented the fix, and added regression coverage under maintainer authorization.
Describe the catalog as independent of SKILL.md extraction rather than repository content, addressing Copilot's review feedback.
Prepared with Codex assistance under pbakaus's scheduled architecture cleanup authorization.
Remove the unreachable legacy SKILL.md pattern parser now that readPatterns uses the curated catalog exclusively.
Prepared with Codex assistance under pbakaus's scheduled architecture cleanup authorization.
Three lessons from the Tortuga containment-map run. The first rebuild
directive now executes immediately, informing the user instead of
asking permission to fix a failure; consultation waits for a second
rebuild verdict or user-approved content at risk. The asset producer
spawns on every subagent-capable run even when produce looks empty,
because its manifest is the independent check on the inventory's media
and the skipped spawn marks every all-CSS failure to date. And the
inventory now opens by reading the comp as a design system (component
grammar, corners, line weights, elevation, type ramp), because the
sections the comp does not show get built from that record, and without
it the fallback is the stock kit: square boxes, 1px grids, bentos, hard
shadows.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The condensation pass folded the old textures-are-raster-by-default
sentence into the medium gate's lighting-and-depth clause, and the next
codex run drove straight through the gap: woven cotton as 'layered CSS
textures', a black nylon band as plain CSS, and a physical evidence-tag
CTA as CSS shapes, so the produce bucket stayed empty and the asset
producer was never called. The gate now names textures explicitly,
woven cloth, paper grain, fabric, leather, brushed metal, with no depth
argument owed, and calls 'layered CSS textures' what it is: not a
medium.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Three of the six axes cannot be read from a world's prose, and widening their
keywords manufactures signal rather than finding it. Depth's probe matched
worlds that said "no cast shadow anywhere" and "without perspective or depth";
motion and colour strategy describe properties the system rules never state, so
they place 28% and 7%.
An optional axes object on the concept records the value instead. Absent means
inferred from the rules as before, so nothing needs backfilling. Validated
against the axes definition when the caller supplies it, because a typo would
read as "unrecorded" and fall back to a probe already known not to work, which
is the quietest way for this to fail.
This is what makes an assigned wave measurable. If a wave draws "drenched" and
"simulated physics" before designing anything, the world it produces has to
carry those values or the assignment is lost the moment it lands, and occupancy
goes back to guessing at prose.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>