component-like-existing
Bootstrap a new component from an existing one, preserving its provided interfaces and receptacles under a different component name.
SKILL.md.claude/skills/component-like-existing/SKILL.md
GitHubBootstrapping a new component named $1 from the existing component named $0 involves the
following steps. The intent is to clone the contract of $0 — the interfaces it provides
and the receptacles it consumes — while giving it a new component name and its own crate.
Provided interfaces and receptacles are preserved as-is: they reference the existing
shared interface definitions in components/interfaces. Do not create new I...
interface files for the clone.
Only the contract and scaffolding are carried over — the component declaration, its
provides:/receptacles:, and the interface impl blocks. The method bodies are left
empty (todo!() stubs); the source's private implementation (helper modules, data
structures, behavioral tests) is not copied. The clone also starts a fresh spec-kit
session that inherits only the source's constitution.
The source component is $0 and the new component is $1. Locate the source component's sub-directory under
components/(the lower-case, hyphen-ized form of $0, or the directory whosedefine_component!block declares $0). If it does not exist, return an error and stop.If $1 was not supplied, interactively ask the user for the new component name and stop until provided. If a directory for $1 (lower-case, hyphen-ized) already exists under
components/, return an error and stop.Read the source component's
define_component!block and record itsprovides:interface list and itsreceptacles:block verbatim. These are preserved unchanged in the clone.Create a new sub-directory under
components/whose name is the lower-case, hyphen-ized form of $1.Copy the source component's implementation into the new directory —
src/andCargo.toml. Do not copy generated or spec directories:target/,specs/,.specify/,info/, or the source's.claude/directory.Reduce the copied source to a compiling skeleton and rename it:
- Rename the component type from the $0 name to the $1 name throughout (e.g.
FooBarComponent→BazComponent), and update crate-name references,//!module docs, and doc-comment examples to match. - Keep the
define_component!(and anydefine_interface!) declarations with theirprovides:andreceptacles:entries exactly as recorded in step 3 — the clone provides the same interfaces and consumes the same receptacles as $0. - Replace the body of every method that implements a provided interface with a
todo!("$1: <method>")stub, so the clone compiles but carries none of the source's logic. - Delete private helper modules, types, and fields that existed only to support the
source's implementation, keeping
fields:minimal but sufficient to construct the component. Remove any now-unuseduseimports. - Replace the source's behavioral tests with a minimal smoke test that constructs the
component and queries each provided interface via
query_interface!.
- Rename the component type from the $0 name to the $1 name throughout (e.g.
In the new
Cargo.toml, set[package] nameto the lower-case, hyphen-ized form of $1. Preserve all[dependencies]from the source (they reflect the interfaces and receptacles being kept).Register the new crate in the workspace root
Cargo.toml:- Add the new component path to
members. - If the source component is listed in
default-members, add the new one there too. - Add a
[workspace.dependencies]entry:<crate-name> = { path = "components/<dir>" }, mirroring any options (e.g.default-features = false) used by the source's entry.
- Add the new component path to
Add a permissions file
.claude/settings.jsonin the new sub-directory that allows access to the component itself,lib/component-framework,components/interfaces, and the directories of any components corresponding to its receptacles. Avoid granting access to components that are not directly used. Model it on the source component's.claude/settings.jsonif present.Copy into the new component directory's
.claude/skillsonly the skills whose names match anincludepattern in.claude/component-local-skills.json(patterns support a trailing*wildcard; other entries match exactly). This allowlist is the single source of truth for which skills are component-local — do not hard-code the list here. Skip any skill that does not match.Run
specify init . --ai claudein the new component source directory. This is a fresh spec-kit session — do not copy the source's specs, plans, tasks, or.specify/syncartifacts.Copy only the source component's constitution into the new component, overwriting the freshly-initialized default: copy
.specify/memory/constitution.mdfrom the source to the same path under the new component. Leave all other spec-kit state fresh.Run
specify extension add spec-kit-sync --from https://github.com/bgervin/spec-kit-sync/archive/refs/heads/master.zipin the new component directory.Verify the clone builds with
cargo build -p <new-crate-name>. Report any errors.