-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Labels
enhancementNew feature or requestNew feature or request
Description
Goal
Add --update and --update-all flags to rafters add so users can pull the latest registry versions of installed components without manually specifying --overwrite for each one.
Exact Implementation Requirements
Required Interface/Class Structure
// Updated AddOptions
interface AddOptions {
overwrite?: boolean;
update?: boolean; // re-fetch named components from registry
updateAll?: boolean; // re-fetch ALL installed components from registry
list?: boolean;
registryUrl?: string;
agent?: boolean;
}
// New field in RaftersConfig (init.ts)
interface RaftersConfig {
framework: Framework;
componentsPath: string;
primitivesPath: string;
cssPath: string | null;
shadcn: boolean;
exports: ExportConfig;
installedComponents?: string[]; // NEW: tracks what was installed via `add`
}Behavior Requirements
Track installed components:
- When
addsuccessfully installs a component, append its name toinstalledComponentsinconfig.rafters.json - De-duplicate the list (Set-based)
- Include primitive dependencies in the list (they are installed too)
rafters add button --update:
- Equivalent to
rafters add button --overwritebut reads more clearly as intent - Fetches latest from registry, overwrites existing files
- Updates
installedComponentslist
rafters add --update-all:
- Reads
installedComponentsfromconfig.rafters.json - Re-fetches and overwrites every listed component from the registry
- No component names required on the CLI when using
--update-all - If
installedComponentsis empty or missing, error with:"No installed components found. Use 'rafters add <component>' to install first." - Reports what was updated and what was unchanged (content-identical)
No versioning:
- Components are always latest from registry (shadcn model: source code you own)
- No version tracking, no pinning, no diffing -- just re-fetch and overwrite
- The
installedComponentslist is purely "what names were installed", not "what version"
Error Handling
--update-allwith no config file:"No rafters config found. Run 'rafters init' first."--update-allwith emptyinstalledComponents:"No installed components found. Use 'rafters add <component>' to install first."--updatewithout component names: same error as currentaddwith no args--updateand--update-alltogether:--update-alltakes precedence, ignore component args- Registry fetch failure: existing error handling applies
Acceptance Criteria
Functional Tests Required
// Track installed components
test('add records component in installedComponents', async () => {
await add(['button'], { overwrite: false });
const config = JSON.parse(await readFile(configPath, 'utf-8'));
expect(config.installedComponents).toContain('button');
});
// --update overwrites existing
test('--update re-fetches and overwrites existing component', async () => {
await add(['button'], {});
await add(['button'], { update: true });
// Should succeed without error (no "already exists" error)
});
// --update-all refreshes all installed
test('--update-all refreshes all installed components', async () => {
await add(['button', 'input'], {});
await add([], { updateAll: true });
// Should re-fetch both button and input
});
// --update-all with nothing installed
test('--update-all errors when no components installed', async () => {
await add([], { updateAll: true });
expect(process.exitCode).toBe(1);
});TypeScript Requirements
- TypeScript 5.9.3 strict mode enabled
- No
anytypes anywhere (Biome enforced) - No
.forEach()- usefor...ofloops - No
.then()chains - useasync/awaitonly - All external data validated with Zod schemas
Build Requirements
- All existing Biome rules enforced
pnpm preflightmust pass
What NOT to Include
- Component versioning or pinning (not needed -- always latest)
- Diffing installed vs registry (future consideration)
- Interactive component selection for update (separate issue)
- Migration or changelog between component versions (out of scope)
File Locations
- Implementation:
packages/cli/src/commands/add.ts - Config type update:
packages/cli/src/commands/init.ts(RaftersConfig interface) - Unit Tests:
packages/cli/test/add.test.ts - Types:
packages/cli/src/registry/types.ts(if schema changes needed)
Integration Requirements
Dependencies
- Reads/writes
config.rafters.json(already used by init) - Uses existing
RegistryClientfor fetching - No new package dependencies
Usage Examples
# Install a component (now also tracks it)
rafters add button
# Update a specific component to latest
rafters add button --update
# Update all installed components to latest
rafters add --update-all
# Agent mode works too
rafters add --update-all --agentSuccess Criteria
-
rafters add <name>records installed components in config -
rafters add <name> --updatere-fetches and overwrites -
rafters add --update-allrefreshes all installed components - Existing
--overwritebehavior unchanged - All functional tests pass
- TypeScript compiles without errors
-
pnpm preflightpasses
This issue is complete when: rafters add --update-all successfully re-fetches and overwrites all previously installed components from the registry, and the installed component list persists across CLI invocations.
Context & References
- Current
--overwritebehavior: always re-fetches from registry, but requires flag to write over existing files - shadcn model: no versioning, components are source code you own
RaftersConfiginpackages/cli/src/commands/init.ts(line 78)AddOptionsinpackages/cli/src/commands/add.ts
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or request