Skip to content

feat(cli): implement modui add and modui init - #6

Open
hulk510 wants to merge 1 commit into
mainfrom
h-branch-2
Open

feat(cli): implement modui add and modui init#6
hulk510 wants to merge 1 commit into
mainfrom
h-branch-2

Conversation

@hulk510

@hulk510 hulk510 commented May 11, 2026

Copy link
Copy Markdown
Collaborator

Summary

First real implementation of the CLI. modui add <name> now copies component source from a registry into a user's project, and modui init scaffolds components.json + the default theme.

Design

Adopts shadcn/ui's embedded-source registry model rather than fetching individual files from GitHub raw. Reasons:

  • raw.githubusercontent.com has a 60 req/hour unauthenticated rate limit per IP — breaks in CI / NAT'd environments
  • atomic install (one JSON contains everything)
  • easier to mirror, sign, and integrate
  • third-party registries only need to host JSON files

What's included

  • packages/registry/scripts/build.ts — build script that scans src/ui/** and src/themes/** and emits dist/registry/<name>.json with embedded .tsx + .module.css content. Parses imports to auto-derive dependencies (npm) and registryDependencies (other modui components).
  • packages/cli/src/registry/ — schema (zod), fetcher with in-memory cache (URL or local path), recursive dep resolver.
  • packages/cli/src/commands/init.ts — creates components.json, prompts for component / theme paths, installs the default theme.
  • packages/cli/src/commands/add.ts — fetches items, resolves registryDependencies recursively, prompts on overwrite, installs npm deps via detected package manager (pnpm / yarn / bun / npm).

CLI deps

  • commander (args)
  • prompts (interactive)
  • kleur (colors)
  • execa (spawn pm)
  • zod (schema)

Tested

End-to-end against a local registry path:

  • init --yes creates config and copies theme
  • add input --skip-install copies files
  • add input --yes skips existing files
  • add input --overwrite overwrites
  • add button works as a new component
  • Missing config errors with a helpful message

Follow-ups (out of scope for this PR)

  • Host the registry JSON publicly (extend the Pages workflow to also publish packages/registry/dist/registry)
  • Bump CLI version and republish to npm once the registry has a stable URL

- Add registry build script that scans packages/registry/src/ui/** and
  emits per-component JSON with embedded source files (shadcn-style).
- Implement `modui init`: creates components.json and installs the
  default theme.
- Implement `modui add`: resolves registryDependencies recursively,
  prompts on overwrite, installs npm deps via detected package manager.
- Support both URL and local-path registries for dev/testing.
- Schema validation with zod, CLI structure with commander + prompts +
  kleur + execa.
Copilot AI review requested due to automatic review settings May 11, 2026 14:15

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Implements the first functional modui CLI workflow and an embedded-source registry build pipeline, enabling users to init a project (config + default theme) and add components by copying source files plus installing detected npm dependencies.

Changes:

  • Add a registry build script that emits JSON artifacts with embedded .tsx/.css content and derived dependency metadata.
  • Implement CLI registry fetching/caching + dependency resolution, plus modui init and modui add.
  • Update workspace dependencies/lockfile to include CLI/runtime dependencies (commander, prompts, execa, kleur, zod) and registry build tooling (tsx).

Reviewed changes

Copilot reviewed 12 out of 13 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
pnpm-lock.yaml Adds lock entries for new CLI and registry build dependencies.
packages/registry/scripts/build.ts Generates embedded-source registry JSON (components, themes, index) from src/.
packages/registry/package.json Adds build script using tsx and required dev deps.
packages/cli/src/utils/write-files.ts Writes registry files into the user project with overwrite prompting.
packages/cli/src/utils/install-deps.ts Detects package manager and installs resolved npm dependencies via execa.
packages/cli/src/utils/config.ts Defines and reads/writes components.json config via zod schema.
packages/cli/src/registry/schema.ts Defines registry/index/item schemas and types for validation.
packages/cli/src/registry/resolve.ts Recursively resolves registryDependencies to a full install set.
packages/cli/src/registry/fetch.ts Fetches registry JSON (remote or local) with an in-memory cache.
packages/cli/src/index.ts Replaces manual arg parsing with commander-based init and add commands.
packages/cli/src/commands/init.ts Implements modui init (config scaffolding + default theme install).
packages/cli/src/commands/add.ts Implements modui add (component selection, recursive deps, file writes, installs).
packages/cli/package.json Adds CLI runtime dependencies and typings for prompts.
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/cli/src/index.ts
}
});

program.parseAsync();
Comment on lines +28 to +44
let selected = names;
if (selected.length === 0) {
const index = await fetchIndex(registry);
const { picked } = await prompts({
type: "multiselect",
name: "picked",
message: "Which components would you like to add?",
choices: index.components.map((c) => ({ title: c.name, value: c.name })),
hint: "Space to select. Enter to submit.",
instructions: false,
});
if (!picked || picked.length === 0) {
console.log(kleur.yellow("No components selected."));
return;
}
selected = picked;
}
Comment on lines +20 to +23
console.error(
kleur.red("components.json not found. Run `modui init` first."),
);
process.exit(1);
Comment on lines +34 to +36
const target = resolveTarget(cwd, config, file);
const relTarget = target.replace(`${cwd}/`, "");

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants