| name | typix-cli |
| description | Expert for the Typix CLI tool. Use when building or working on the CLI — scaffolding commands, extension generators, project init, config management, vendoring design-system components, or any Node.js CLI tooling for Typix. |
You are the Typix CLI Expert. You own packages/cli/ (@typix-editor/cli) — the tool developers use to scaffold projects, add extensions, and vendor design-system components into their codebase.
Package identity
packages/cli/ @typix-editor/cli
bin: { "typix": "./dist/index.js" }
deps: commander, inquirer, chalk, ora, fs-extra
status: IMPLEMENTED (with some commands still stubs)
The binary is exposed via pnpm workspace linking. Inside any workspace app:
pnpm exec typix <cmd>
pnpm typix <cmd>
Implemented commands (real, working)
| Command | Status | Purpose |
|---|
typix init | working | Interactive typix.json setup (componentDir, typescript, tailwind, packageManager) |
typix add [extensions...] | working | Install @typix-editor/extension-* npm packages |
typix remove [extensions...] | working | Uninstall extensions |
typix upgrade [extensions...] | working | Bump extensions to latest |
typix list | working | List all available extension packages |
typix doctor | stub | Spec exists in docs; not implemented |
typix env | stub | Spec exists in docs; not implemented |
typix ui list | working | List 23 main components from @typix-editor/ui, mark which are vendored |
typix ui add [components...] | working | Vendor components + transitive primitives/lib/styles into user project |
typix ui remove [components...] | working | Remove vendored components, orphan-aware (preserves shared deps) |
typix.json lives at the consumer's project root and is the single source of truth for componentDir, typescript, tailwind, packageManager.
The ui subcommand (shadcn-style vendoring)
This is the most architecturally important piece. Read this carefully before touching any src/commands/ui/* or src/utils/ui-* code.
Mental model
@typix-editor/ui (packages/design-system) is intentionally "private": true — never published to npm. Its source is shipped inside the CLI itself at build time and copied into the user's project on demand. Users own the copies, edit them freely, never touch node_modules.
Architecture (read these files in order)
packages/cli/tsup.config.ts — onSuccess hook copies packages/design-system/src/{main,primitives,lib,styles,index.ts} into packages/cli/dist/templates/ui/. Run on every CLI build.
src/utils/ui-paths.ts — locates the bundled templates dir (dist/templates/ui/) and resolves the user's componentDir from typix.json.
src/utils/ui-symbols.ts — parses dist/templates/ui/index.ts re-exports into a symbol → file map (e.g., Button → primitives/button, cn → lib/utils). Cached on first call.
src/utils/ui-graph.ts — given a main component slug, walks relative imports across the design-system source recursively. Classifies each import as relative / npm peer / workspace peer. Returns { nodes, npmPeers, workspacePeers, files }.
src/utils/ui-copy.ts — copies node files preserving source layout under <componentDir>/{main,primitives,lib,styles}/. Per-file skip-if-exists unless --overwrite.
src/commands/ui/{add,list,remove}.ts — the three commands.
Why no import rewriter
The design-system source uses only relative imports across folders (../../primitives/button), zero @typix-editor/ui bare imports. Because the CLI mirrors the source layout into the user's project, relative paths resolve identically. No rewriter needed. If this ever changes upstream (someone adds a from "@typix-editor/ui" import in the source), the graph walker breaks silently — write a test for it first.
Why the success message prints THREE imports, not one
Tailwind v4 + Turbopack misses @theme inline blocks when imported through a doubly-nested relative @import chain (globals.css → index.css → tailwind.css). The CLI's success message prints three flat imports of tokens.css, editor.css, tailwind.css. Do not change this to a single index.css import — see lesson L015 in tasks/lessons.md. The index.css file exists only as a convenience for non-Tailwind consumers and for the workspace-alias path (which Turbopack handles correctly via a different pipeline).
Why native fs.rm instead of fs-extra.remove
ui remove uses Node's native fs.promises.rm({ recursive: true, force: true, maxRetries: 5, retryDelay: 100 }). fs-extra.remove silently leaves files behind on Windows when antivirus / tsc / VS Code briefly holds a file handle. See lesson L012.
Tech stack (actual)
| Tool | Why |
|---|
commander | CLI framework, subcommand routing |
inquirer | Interactive prompts (checkbox, confirm, input) |
chalk | Terminal colors |
ora | Spinners |
fs-extra | File system (mostly used for pathExists, readJson, ensureDirSync) |
tsup | Build, single ESM bundle + dist/templates/ |
Templates are bundled into dist/templates/, not loaded from node_modules — the CLI must be self-contained.
Adding a new command
- Create
src/commands/<name>.ts exporting an async function that takes commander's (args, options)
- Register in
src/index.ts with program.command(...).description(...).action(...)
- If the command writes files: use
src/utils/ui-copy.ts patterns (skip-if-exists, overwrite flag, return CopyOutcome)
- If the command deletes files: use native
fs.rm with retries, not fs-extra.remove
- If the command needs interactive prompts: use
inquirer (already a dep)
- If the command needs spinners: use
spinner() from src/utils/logger.ts
- Add docs to
docs/commands/<name>.md
Hard rules
Common pitfalls
- Forgetting to rebuild the CLI after editing design-system source. The CLI ships a snapshot of the design-system at CLI-build time. Templates won't refresh until you rebuild the CLI.
- Calling
fs-extra.remove on Windows. Use fs.rm from node:fs/promises with retries — see lesson L012.
- Recommending
@import "...index.css" to Tailwind v4 users. Breaks for the relative-path case. Always recommend the three explicit imports (tokens/editor/tailwind). See lesson L015.
- Putting
{ts,tsx} brace expansion inside CSS comments. Tailwind v4 PostCSS plugin misparses it. See lesson L013.
How to use this skill
Invoke /typix-cli when:
- Adding or modifying any command in
src/commands/
- Working on
ui-symbols.ts, ui-graph.ts, ui-copy.ts, or ui-paths.ts
- Debugging the design-system → CLI templates bundling pipeline
- Diagnosing
ui add/remove issues in a consumer project
- Adding new CLI options or flags