Sync from nextlevelbuilder - #1
Open
arunabhdas wants to merge 121 commits into
Open
Conversation
…s, extended palette, and dark/light mode Upgrade the design system terminal output from basic ASCII to Unicode box-drawing characters, add ANSI true color swatches with graceful fallback, expand the color palette from 5 to 10 colors (Primary, On Primary, Secondary, Accent, Background, Foreground, Muted, Border, Destructive, Ring) with CSS variable names, and surface Light/Dark mode support from styles.csv. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Create python-package-conda.yml
…vements Improve design system output visuals
…n CLAUDE.md (#365) Co-authored-by: Xavier Virrey <xavier@Xaviers-MacBook-Air.local>
Skip docs-only changes (*.md, docs/**, .claude/**) from triggering the Conda build/lint/test pipeline. Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Both files were stuck at v2.2.1 while plugin.json, skill.json and cli/package.json had moved to v2.5.0. Claude marketplace reads marketplace.json for version and palette count — the stale entry showed outdated data (96 palettes vs actual 161, 13 stacks vs 15). Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
The --force option was accepted by Commander but ignored: writeFile() always overwrote existing files silently. Users expecting protection against accidental overwrites had no way to preserve existing configs. - generatePlatformFiles: check file existence before writing; skip with a clear message when file exists and force=false - generateAllPlatformFiles / templateInstall: propagate force parameter - initCommand: pass options.force through to templateInstall Behavior change: uipro init --ai claude → skips if SKILL.md already exists uipro init --ai claude --force → overwrites regardless Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
OpenClaw (https://openclaw.ai) is an open-source agent gateway that runs Claude as its primary backend. This skill works out-of-the-box inside OpenClaw agents — same SKILL.md + python3 search.py invocation pattern as the other supported platforms. Adding it to the list so the install flow can target it. Co-authored-by: yinhaoti <yinhaoti@macmini.home>
Line 14 contained a raw `<args>$ARGUMENTS</args>` tag that was never replaced during skill generation. This literal XML-like string renders as part of the skill body and can confuse LLM consumers. Co-authored-by: claude[bot] <claude[bot]@users.noreply.github.com> Co-authored-by: Claude Code <noreply@anthropic.com>
Add cross-platform Python command note to skills and docs: - CLAUDE.md: Add Windows note in Prerequisites - ui-ux-pro-max/SKILL.md: Add Windows note in Prerequisites - design/SKILL.md: Add Prerequisites section with Windows note - banner-design/SKILL.md: Add Prerequisites section with Windows note - templates/base/skill-content.md: Add Windows note (source template) Windows uses 'python' instead of 'python3' to run scripts. Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
…rsist path) (#321) All three are in the canonical src/ tree, reproduced on Python 3.14.5: 1. data/typography.csv — all 73 'Google Fonts URL' values were unusable fonts.google.com/share *UI* links, not stylesheet hrefs. Replaced with the proper fonts.googleapis.com/css2 URLs (extracted verbatim from each row's correct 'CSS Import' column), so the URL column is actually loadable. 2. scripts/core.py — BM25 tokenizer kept only words >2 chars, so common design terms 'ux', 'ui', 'ai', '3d' tokenized to nothing and returned 0 results (e.g. `--domain style "3d"`). Changed >2 to >=2; '3d'/'ai' now match. 3. scripts/search.py — `--persist` without `-p` printed 'design-system/default/' but actually wrote to the query slug (e.g. design-system/fintech-crypto/). Use the same default the writer uses so the printed path matches reality. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
) execSync with a backtick template string creates a shell-expansion surface. Although all three variables (generateScript, DESIGN_TOKENS_JSON, DESIGN_TOKENS_CSS) are currently hardcoded constants, the pattern is fragile — any future substitution of user-controlled data would create shell injection. Replace with execFileSync('node', [...args]) to eliminate the shell entirely and make the boundary explicit. Co-authored-by: claude[bot] <claude[bot]@users.noreply.github.com> Co-authored-by: Claude Code <noreply@anthropic.com>
Breaking changes fixed:
- Row 8/9: icon format corrected from 'lucide:home' (v3) to 'i-lucide-home' (v4 Iconify i-prefix)
- Row 18: useOverlay API updated from .open(Component, {props}) to .create(Component).open({props})
New v4 guidelines added (rows 51-70):
- Auto-registered modules: do not re-add @nuxt/icon @nuxt/fonts @nuxtjs/color-mode
- Official nuxi init templates for project bootstrapping
- Local Iconify JSON install for SSR reliability
- Global icon overrides via appConfig.ui.icons
- New form components: UFileUpload, UInputDate, UInputTags, UColorPicker
- New data components: UTree, UMarquee
- UContextMenu for right-click menus
- Awaiting overlay result Promise for confirmation dialogs
- UCommandPalette grouped items and extractShortcuts
- UHeader/UFooter/UPageAside layout components
- ClientOnly pattern for color mode hydration safety
- Generated theme file (.nuxt/ui/) for slot discovery
- defineShortcuts whenever condition guard
- UApp locale prop for i18n (50+ built-in locales)
Sync cli/assets to match src.
* feat(release): add semantic release automation * fix(release): disable npm publishing * ci: remove obsolete conda workflow * ci: remove Claude review workflows --------- Co-authored-by: Mỹ Ngân <bot@goclaw.dev> Co-authored-by: Mỹ Ngân <my-ngan@goclaw.local>
…de injection (#275) The _format_plugins() method interpolated plugin names directly into require() statements without sanitization. A plugin name containing a single quote could break out of require() and inject arbitrary JavaScript that executes when Node.js loads the generated config. Add a strict regex allowlist matching valid npm package name patterns (optional @scope, alphanumeric/hyphen/underscore, optional subpath). Reject any plugin name that doesn't match before generating output. Closes #246
Add html.escape() to all 46 user-controlled data.get() calls across all 7 slide generator functions (title, problem, solution, metrics, chart, testimonial, cta) and the deck title. Add URL scheme validation for cta_url href to block javascript: URI injection. Closes #247
Co-authored-by: Bilal Hasan <bhaasan26@my.whitworth.edu>
* fix: bump skill.json version to 2.6.2 * fix: bump marketplace.json and plugin.json version to 2.6.2 --------- Co-authored-by: shipengqi <pooky.shi@gamil.com>
Merge PR #284: pin the shadcn CLI helper to a deterministic version fallback while still allowing project package.json overrides.
The Agent Skills spec requires names to match [a-z0-9-] only. The colon in 'ckm:' prefix causes daily validation errors: name contains invalid characters (must be lowercase a-z, 0-9, hyphens only) This affects all six ckm-prefixed skills. Replace ':' with '-'. Co-authored-by: Thomas Schneider <tho.schneider@sap.com>
…ts (#294) * fix: V-001 security vulnerability Automated security fix generated by Orbis Security AI * feat(cli): add optional GitHub token support with proper UX and docs - Rename env var from GITHUB_TOKEN to UI_PRO_MAX_GITHUB_TOKEN (primary), with GITHUB_TOKEN as fallback — avoids silently attaching CI workflow credentials that GitHub Actions injects automatically - Add whitespace trim guard to prevent malformed Authorization headers - Add getGitHubTokenGuidance() helper exported from github.ts so rate-limit errors and spinner warnings tell users exactly how to fix the problem - Thread optional token param through fetchReleases, getLatestRelease, downloadRelease signatures - Add --token flag to init, versions, update commands (Commander.js wiring) - Update rate-limit catch in tryGitHubInstall to show token guidance - Document token options (flag, env var, fallback) in cli/README.md with CI warning about GITHUB_TOKEN scope Supersedes the narrower env-only approach in PR #294 and incorporates the safeguards requested during review of closed PR #186. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix CLI asset sync * fix(cli): normalize line endings in asset sync/check check:assets hashed raw bytes, so identical CSV/JSON/py content with CRLF vs LF (git autocrlf on checkout) was reported as stale drift, blocking the release guard on Windows/mixed checkouts. - fileHash now normalizes CRLF->LF before hashing, so check:assets compares content, not line endings. - sync:assets writes LF-normalized copies instead of a raw byte copy, so re-syncing is deterministic across platforms. All synced assets are text (csv/json/md/py); no binaries affected. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * ci: enforce CLI asset sync on PRs Adds a Check asset sync workflow that runs `npm run check:assets` on any PR touching src/ui-ux-pro-max/** or cli/assets/**, so the bundled CLI assets can't silently drift from the source of truth. The check uses only node builtins (no install step) and normalizes line endings before hashing, so it hard-fails on real content drift without the CRLF/LF soft-fail hack other approaches needed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Adds semantic-release npm publishing for the cli package with pkgRoot=cli and NPM_TOKEN wiring, completing the npm-publish slice of #353.
On Windows, an older install (or a git checkout that materialized the repo's symlinked data/scripts as plain "pointer" files) leaves a regular file at <skill>/data or <skill>/scripts. copyDataAndScripts then calls mkdir on that path, which throws EEXIST; under `uipro init --ai all` the per-platform error is swallowed, leaving e.g. codex with the stale pointer files and no real directories. Add ensureCleanDir(): before mkdir, lstat the target and remove it if it is not already a directory. Existing real directories are preserved (re-install is unaffected). Verified with a repro harness. Closes #237
…388) persist_design_system crashed with AttributeError: 'NoneType' object has no attribute 'lower' when the design_system dict carries an explicit project_name of None (the default of generate(query, project_name=None)). dict.get("project_name", "default") only substitutes the default for a MISSING key, not a present-but-None value, so project_name.lower() blew up. Coalesce falsy values (None/""/missing) to "default" before slugifying. Applied to both the source of truth and the bundled cli/assets copy. The "search blindness" half of #159 (core.py tokenize length filter) is already resolved on main (`len(w) >= 2`), so this targets the remaining crash only. Closes #159 Co-authored-by: YangKuoshih <155388493+YangKuoshih@users.noreply.github.com>
…verage test(cli): add droid to script-path rendering coverage
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>
…encoding test(brand): decode subprocess output as UTF-8 so the suite can pass on Windows
fix(cli): detect .claude-plugin directory for Claude Code in detectAIType
Signed-off-by: binyangzhu000-sudo <224954946+binyangzhu000-sudo@users.noreply.github.com> Co-authored-by: binyangzhu000-sudo <224954946+binyangzhu000-sudo@users.noreply.github.com>
GitHub renders Hangul with fallback font metrics that differ from ASCII spacing. Replace right-bordered diagrams with borderless layouts so alignment no longer depends on browser-specific font rendering.
docs: add Korean README
Remove references to tools and sibling skills that are not bundled with banner-design. Add plugin, asset, and Claude CLI installation path-contract coverage.
…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>
- replaced hardcoded python3 in npm scripts with a node wrapper to support windows natively without breaking unix systems - updated stale catalog-summary.json snapshot Co-authored-by: khietan <118370929+khietan@users.noreply.github.com>
…nd 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>
docs: add Indonesian README
* fix(data): regenerate stale catalog-summary snapshot hashes catalog-summary.json was not regenerated after google-fonts.csv, google-font-licenses.json, icons.csv and phosphor-icons-upstream.json changed, so `npm --prefix cli run verify:data` fails on a clean checkout of main: validate:semantic 4 stale snapshot errors validate:catalog-summary "catalog-summary.json is stale" test:python 1 failure / 153 check:assets 2 files out of sync Regenerated with the existing --verified-at 2026-08-26: only the four sha256 fields change. The date is a human attestation that the font catalog was checked against the upstream google/fonts repository, so it is deliberately left untouched -- no such verification was performed here. verify:data now exits 0. Note: prepublishOnly runs sync:assets before verify:data, which regenerates the snapshot at publish time. That is why released packages are unaffected and the drift stayed invisible on main. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015UidECV1wVBD8SW6Abuj71 * fix(data): make catalog snapshot hashes line-ending independent Root cause of the stale snapshot restored in the previous commit. bd19ab9 (#462) regenerated catalog-summary.json from a CRLF checkout. Every recorded sha256 was the CRLF hash of its source file, so the check failed on every LF platform. The four committed values are exactly sha256(crlf_bytes): google-fonts.csv committed d03194d2… = CRLF hash google-font-licenses.json committed 7c35e410… = CRLF hash icons.csv committed 272ccf0e… = CRLF hash phosphor-icons-upstream.json committed 81c37fb3… = CRLF hash Two conditions had to combine: the digest hashed raw bytes, and no .gitattributes pinned these files to LF, so Windows checkouts get CRLF by default. Restoring the hashes alone would let the next contributor on Windows reproduce the same commit. Three changes: - normalize line endings in generate-catalog-summary.py's digest(), so the snapshot no longer depends on the checkout - apply the same normalization in validate_data.py, which independently recomputes the hashes and has to agree with the generator - add .gitattributes pinning src/ui-ux-pro-max/data/*.{csv,json} to LF, so a Windows checkout matches the committed bytes in the first place sync-assets.mjs already normalizes to LF, so this only extends an existing project convention to the two places that were missing it. Adds test_catalog_summary_line_endings.py: LF and CRLF inputs must digest identically, the committed snapshot must match the normalized sources, and a simulated CRLF checkout must still produce the recorded hashes. The third case fails against the pre-fix digest. verify:data exits 0; the Python suite goes from 153 to 156 tests. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015UidECV1wVBD8SW6Abuj71 --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
--persist writes design-system/<project-slug>/MASTER.md, but all four
READMEs document design-system/MASTER.md, omitting the per-project
folder. Following the README leads readers to look for files that are
never created there.
The code is unambiguous (design_system.py:1020):
design_system_dir = base_dir / "design-system" / project_slug
and search.py's own --help already documents it correctly, so this is a
documentation gap rather than a behaviour question.
The slug level is not incidental: without it, two projects persisted
into the same directory would overwrite each other's MASTER.md.
Updated in README.md, README.ko.md, README.vi.md and README.zh.md:
the folder tree, the hierarchical-retrieval steps and the context-aware
retrieval prompt. Uses the concrete slug "myapp" where the surrounding
example runs -p "MyApp", and [project-slug] where the text is generic.
Claude-Session: https://claude.ai/code/session_015UidECV1wVBD8SW6Abuj71
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
feat(design): add opt-in MuAPI logo provider
…#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>
The README instructed users to run `uipro init --ai openclaw`, but "openclaw" is not a supported AIType in the CLI (cli/src/types/index.ts), so the command fails.
…nd plugin manifests (#488)
…riting (#489) feat(cli): add --dry-run to init to preview install actions without writing (#489) Closes #291 - Adds resolveInstallPaths helper shared by real install and dry-run preview - New planPlatformInstallActions / planAllPlatformInstallActions for read-only preview - 3 e2e tests verify output content, no-write guarantee, and all-platforms coverage - README docs included *Approved and merged by github-maintain cron*
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Sync from nextlevelbuilder