16 Commits

Author SHA1 Message Date
notbucki
15de38fb70
fix(design): make workflows self-contained, add bundled-skill contract (#498)
* fix(design): make workflows self-contained, add bundled-skill contract (#474 finding 2)

The design skill's banner and social-photos workflows named skills the plugin
does not ship (frontend-design, ai-artist, ai-multimodal, chrome-devtools,
project-management, assets-organizing) and claudekit command namespaces
(/ckm:brand, /ck:ui-ux-pro-max), so those steps fail or force the agent to
improvise under a plugin or CLI install. Rewrite them after the pattern of
#473: bundled skills stay referenced by name, optional tooling becomes an
optional runtime capability, unbundled steps are implemented inline or
dropped. The same references sat in references/social-photos-design.md, so
the fix covers the skill directory, not just SKILL.md; the CLI copy is synced.

check-asset-sync.yml gains a bundled-skill contract over both skill trees:
no /ck: or /ckm: namespace, every "`name` skill" reference must be a
directory under .claude/skills, and none of the claudekit-only names above
in any spelling.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* fix(design): address review - list-aware skill grep, case-insensitive denylist, banner intro, report naming

- contract grep 2 walks comma/and/or lists so every member is checked, not
  only the last one, and accepts the sub-skill and bold forms; grep 3 matches
  case-insensitively; the step comment states what is not covered
- banner intro no longer claims "no sibling skills" while step 2 names the
  bundled ui-ux-pro-max skill
- social-photos report name stated inline instead of "naming pattern from
  session hooks" (a claudekit convention nothing in the bundle provides);
  "persistent" dropped from the task-list step; device-scale note scoped to
  tools that support it

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* fix(ci): match wrapped skill lists - read each file as one record in the bundled-skill contract

A Markdown list wrapped over two lines ("`playwright-mcp`,\n`brand`, and
`ui-ux-pro-max` skills") passed the line-oriented allowlist grep. Read the
file as one record (-z, separators as \s+) so wrapped lists are still lists;
a hit now names the file and the name instead of the line. grep's own exit
status is taken inside the substitution so an unreadable file still fails the
step under plain bash -e, pipefail or not.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-15 16:29:29 +07:00
nadiiasoshenko-netizen
d8ce090f82
fix(brand): stop adjustBrightness collapsing dark color shades to black (#497)
adjustBrightness() added/subtracted a flat 255*percent to every RGB
channel. For a dark base color (channels already close to 0), darkening
by -0.3/-0.45/-0.6 clamped every channel to 0, so shades 700, 800, and
900 all came back as the identical, useless #000000 instead of a graded
dark scale -- reproducible with any sufficiently dark brand primary
(e.g. #4A3228), not just an edge case.

Blend each channel proportionally toward white (percent > 0) or black
(percent < 0) instead, so the shift scales with how much headroom the
channel actually has.

Adds a regression test that syncs a dark brand color and asserts the
700/800/900 shades stay distinct and non-black.


Claude-Session: https://claude.ai/code/session_01MmtTPnoqMrjjhKjod9VTzr

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-15 07:00:09 +07:00
notbucki
91c193ac05
fix(skills): skill-relative paths below SKILL.md, widen path contract (#482)
Refs #474 (finding 1 follow-up to #476, which rewrote design/SKILL.md
and added a contract that grepped only */SKILL.md; the same defect one
level down survived).

- 29 home-rooted paths (~/.claude/skills/design/scripts/...) in
  design/references/{cip,icon,logo}-design.md -> scripts/... (27 at
  review time, two more added by #470); the printed
  hint in design/scripts/cip/generate.py now derives the absolute path
  from __file__
- 19 project-rooted invocations (.claude/skills/<skill>/scripts/...) in
  brand/, slides/ and design/ references -> scripts/... (own skill) or
  ../<skill>/scripts/... (sibling sub-skill; sub-skills are installed
  side by side in every layout)
- brand/scripts/sync-brand-to-tokens.cjs resolved its sibling script from
  process.cwd(), silently skipping CSS regeneration under plugin and
  --global installs; now resolved from __dirname, with a warning when
  the sibling skill is missing; regression test asserts the regeneration
- brand/scripts/extract-colors.cjs: tool-neutral hint instead of a
  project-rooted path into a skill this plugin does not ship
- "Script Paths" section in the five sub-skills that invoke scripts:
  script path from the skill directory, working directory at the
  project root
- new test_skill_script_paths.py (src, mirrored to both scripts/tests
  copies): every python/node/bash invocation in every shipped skill
  markdown must be skill-relative and name a file that ships
- check-asset-sync.yml: contract covers every file under both skill
  trees and home-/project-/variable-rooted forms; ${CLAUDE_PLUGIN_ROOT}
  allowed only in the plugin-only core SKILL.md; LC_ALL=C + -I for the tracked
  .coverage binary; grep errors fail instead of passing; push filter
  includes the workflow and sync-assets.mjs
- CLI copy regenerated via sync-assets.mjs

Co-authored-by: notbucki <daniel@buckenmaier.xyz>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-03 15:14:02 +07:00
Anil-matcha
26f79bdfb6 fix(design): use MuAPI result URL from creation response 2026-09-01 15:13:29 +05:30
Anil-matcha
36c879d974 Merge current upstream main 2026-09-01 15:02:16 +05:30
djatadougbewilfried-star
f23267105a
fix(design-system): make the skill work outside a vendored checkout and on Windows (#460)
* fix(design-system): resolve project root from cwd, not __file__

fetch-background.py and html-token-validator.py derived PROJECT_ROOT with five
.parent hops, which only reaches the project root when the skill is vendored at
<project>/.claude/skills/design-system/scripts/. Installed at user level
(~/.claude/skills/) or as a plugin, PROJECT_ROOT pointed outside the project, so
both scripts silently ran against no tokens at all.

Resolve from the working directory instead, matching generate-tokens.cjs and
validate-tokens.cjs which already use process.cwd(). DESIGN_SYSTEM_PROJECT_ROOT
overrides it when the project root cannot be inferred.

slide_search_core.py is left alone: it resolves skill-relative data, which is
the correct use of __file__.

Refs #459

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* fix(design-system): stop findProjectRoot from hanging on Windows

embed-tokens.cjs walked up the tree with `while (dir !== '/')`. On Windows the
filesystem root is 'C:\', so that condition is never true, and path.dirname('C:\')
returns 'C:\' unchanged -- the loop spins forever at 100% CPU instead of erroring
out, whenever assets/design-tokens.css is not found above the cwd.

Stop when dirname stops changing, which terminates on every platform.

Refs #459

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* fix(design-system): force UTF-8 stdout so emoji output works on cp1252 consoles

search-slides.py --context and html-token-validator.py print emoji. On a Windows
console the default encoding is cp1252, so the first emoji raises
UnicodeEncodeError and the command dies with a traceback instead of output --
this takes out --context, the entry point of the contextual slide system.

Reuse the guard already shipped in src/ui-ux-pro-max/scripts/search.py.

Refs #459

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* test(design-system): decode subprocess output as UTF-8 in validate-tokens tests

test_validate_tokens.py drives validate-tokens.cjs through subprocess.run with
text=True but no explicit encoding, so Python decodes the pipe with the locale
codec. On Windows (cp1252) the validator's emoji output raises UnicodeDecodeError
inside the reader thread, result.stdout comes back as None, and the assertion
fails with a confusing `TypeError: argument of type 'NoneType' is not a
container` -- this suite cannot pass on Windows at all today.

Pin the pipe and the fixture write to UTF-8. The validator itself was never at
fault: run by hand it flags the hardcoded hex correctly.

Note: brand/scripts/tests/test_sync_brand_to_tokens.py uses the same
text=True-without-encoding pattern and is one emoji away from failing the same
way. Left alone to keep this PR scoped to design-system.

Refs #459

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-09-01 01:42:36 +07:00
notbucki
c7d413e7c3
fix(design): use skill-relative script paths + CI path contract (#474 finding 1) (#476)
Replace all 22 hard-coded ~/.claude/skills/design/scripts/... invocations
in the design skill with skill-relative paths (python3 scripts/...), the
same convention the brand and design-system sub-skills already use. The
user-level path only works in one install context: under a marketplace/
plugin install the skill lives in the plugin cache, and under project-level
CLI installs there is no ~/.claude/skills/design/ either.

Edited .claude/skills/design/SKILL.md (source of truth) and regenerated
the CLI copy with cli/scripts/sync-assets.mjs; --check passes.

Adds a path-contract step to check-asset-sync.yml that fails if any
SKILL.md (either copy) reintroduces a ~/.claude/skills/ invocation, and
widens the workflow's path filters to .claude/skills/** so the contract
actually fires on sub-skill edits.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-09-01 00:21:02 +07:00
Mortal
d95bdf5669
fix(banner): make workflow self-contained (#473)
Remove references to tools and sibling skills that are not bundled with banner-design. Add plugin, asset, and Claude CLI installation path-contract coverage.
2026-08-31 23:44:38 +07:00
Anil-matcha
e7e873dada fix(design): document MuAPI model contracts 2026-08-30 07:53:09 +05:30
Anil-matcha
0720614e6e fix(design): preserve existing logo provider docs 2026-08-29 11:46:39 +05:30
Anil-matcha
dfe8765f10 feat(design): add opt-in MuAPI logo provider 2026-08-29 11:16:47 +05:30
nb213
8bd29e7754
feat(design): add Atlas Cloud logo provider (#447)
Signed-off-by: binyangzhu000-sudo <224954946+binyangzhu000-sudo@users.noreply.github.com>
Co-authored-by: binyangzhu000-sudo <224954946+binyangzhu000-sudo@users.noreply.github.com>
2026-08-27 16:15:36 +07:00
Wilfried Djata
a8f4e7e1ec test(brand): decode subprocess output as UTF-8 and cover the error path
test_sync_brand_to_tokens.py drives sync-brand-to-tokens.cjs through
subprocess.run with text=True but no explicit encoding, so Python decodes the
pipe with the locale codec. Three of the script's messages carry emoji whose
UTF-8 bytes land on cp1252's undefined slots: 0x8F in the "no base hex found"
warning (sync-brand-to-tokens.cjs:132), 0x9D in the "brand guidelines not found"
error (:198), and 0x8F in the dry-run notice (:223). Decoding then raises inside
subprocess's reader thread, the stream comes back as None, and any assertion
against it fails with `TypeError: argument of type 'NoneType' is not a
container` -- which hides the real result behind an unrelated error.

The existing test passes today only because the bundled starter fixture happens
to take none of those three paths.

Pin the pipe to UTF-8, extracted into a shared _run helper to match the idiom in
design-system's test module, and add a regression test for the missing-guidelines
path -- the default state of any project that has not run the brand skill yet.
That test fails without the encoding fix (stderr is None) and passes with it.

Follow-up to #460

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-25 14:33:39 +00:00
Kc
4857a2c5ef
fix(cli): sync shadcn test asset (#433) 2026-07-28 12:00:07 +07:00
文敏華
4f341e2af1 Sync cli/assets with src (catch up pre-existing drift)
cli/assets had fallen out of sync with src/ui-ux-pro-max ahead of this
change (unrelated to the motion-domain feature) - colors.csv, products.csv,
google-fonts.csv, draft.csv, several platform templates, and sub-skill
scripts/tests had all drifted. Ran the project's own `sync-assets.mjs`
to bring cli/assets back in line with the source of truth per the
documented Sync Rules; `--check` now reports assets as in sync.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-01 22:54:13 +08:00
Alexander
ef5f5ba0e6
fix(cli): install all 7 skills via uipro init, not just the orchestrator (#362) (#387)
* fix(cli): install all 7 skills via uipro init, not just the orchestrator

`uipro init` rendered only the orchestrator (ui-ux-pro-max) and never
delivered the 6 sibling skills (banner-design, brand, design,
design-system, slides, ui-styling), so users got 1 of 7 skills (#362).

- sync-assets.mjs: bundle the 6 sub-skills into cli/assets/skills/ as
  static copies (source of truth: .claude/skills/), with sync + check
  coverage. Excludes ui-styling/canvas-fonts (~5.8MB of TTF) and
  __pycache__/.pyc cruft — a skill registers from its SKILL.md, not its
  fonts — so the bundle adds ~0.9MB, not ~6.6MB.
- template.ts: after rendering the orchestrator, install each bundled
  sub-skill as a sibling. The skills parent is derived from the
  platform's skillPath (skills/ for most, prompts/ for copilot,
  steering/ for kiro) rather than hardcoded.
- uninstall.ts: remove the sub-skills too.

Verified: check:assets in sync, tsc passes, and a per-platform install
harness delivers all 7 skills to the correct parent dir with no fonts.

Closes #362

* fix(cli): filter excluded files from target side of check:assets

check:assets filtered sourceFiles with isExcludedAssetFile but not
targetFiles, so a stray cli/assets/scripts/__pycache__/*.pyc (generated
by a local Python run) was reported as an "extra asset file" and failed
the gate. Apply the same predicate to targetFiles in both the
dirsToSync and sub-skill loops.

Verified: check:assets now passes with __pycache__/*.pyc present in the
target tree; typecheck passes.

* fix(cli): uninstall from each platform's real skills dir, not hardcoded skills/

removeSkillDir() hardcoded <folder>/skills/<name>, but the installer
places skills under each platform config's skillPath parent — copilot in
.github/prompts/, kiro in .kiro/steering/. So uninstall left those
platforms' skills (orchestrator + sub-skills) behind.

Derive the install parent from loadPlatformConfig(aiType).folderStructure
(same source the installer uses), and keep the legacy <folder>/skills/
cleanup (incl. .shared/) for older installs. Deduped via a Set.

Verified: typecheck passes; an install+uninstall harness removes all 7
skills with zero leftovers for claude (.claude/skills), copilot
(.github/prompts) and kiro (.kiro/steering).

* fix(cli): re-sync bundled sub-skills after #385 stripped ckm- names

#385 merged to main and removed the ckm- prefix from the six
.claude/skills/*/SKILL.md name fields. This branch's bundled copies
under cli/assets/skills/ still carried the old ckm- names, so after the
PR merges with main the source no longer matched the bundle and the
check-asset-sync CI gate failed (stale asset file: skills/*/SKILL.md).

Merge main and regenerate the bundle so cli/assets/skills matches the
current .claude/skills source of truth. check:assets and typecheck pass.
2026-06-25 17:33:23 +07:00