create-cloc
v0.1.1
Published
Scaffold a new Cloc data repo (cloc.yml + .cloc/, no app code) — the create-* on-ramp.
Downloads
238
Readme
create-cloc
The scaffolder. npx create-cloc [name] stands up a data repo — a root cloc.yml plus a
.cloc/ folder, facts and config only, zero application code — then commits it, ready to be
taught by 0. It is the create-next-app analogue for Cloc (§38 Table 20, §41A, §65).
npx create-cloc acme
? seed from… (a) a prompt (b) a folder of docs (c) nothing — start blank
? Git host? github
? who serves the model? hosted (AI Gateway)
✓ created acme/ · cloc.yml + .cloc/ committedThe prompts are implemented with @clack/prompts
(not Ink — the scaffolder's linear question set needs no React TUI). Cancelling a prompt (Ctrl-C)
exits 130; any other failure exits non-zero with a one-line message (fail-fast on duplicate config
names, etc.). On success the binary makes exactly one reviewable commit and exits 0.
CLI flags
The argument parser is intentionally dependency-free (no oclif/yargs) for a fast cold start and a
tiny install footprint. Beyond the positional [name], the shipped src/bin.ts accepts these
additive options — every one defaults to the prior behavior, and unknown --flags are ignored so
future flags stay forward-compatible:
| Flag | Meaning |
|---|---|
| [name] | Positional project name; pre-fills the prompt and names the new folder. |
| --name <name> | Alternative to the positional name (the positional wins if both are given). |
| --target-dir <dir> | Write into <dir> instead of <cwd>/<name> (advanced / CI). |
| -y, --yes, --non-interactive | Skip the TTY and use documented defaults (seed: blank, git: github, model: hosted). |
| -h, --help | Print usage and exit 0 without scaffolding. |
| -V, --version | Print the create-cloc version and exit 0 without scaffolding. |
| -- | POSIX end-of-options marker, so a name beginning with - is still reachable. |
npx create-cloc acme --yes
npx create-cloc --name acme --target-dir ./sites/acme --yesBoth
--name <value>and--name=<value>forms are supported; a value-taking flag with a missing value fails fast with a clear message.
What it produces
cloc.yml— the declarative root config (YAML, nevercloc.config.ts). Provider selections are recorded as tokens; secrets are referenced by name, never inlined (Principle 9). Every emit runs throughassertNoInlineSecrets(overridable viaDEFAULT_SECRET_PATTERNS), so a pasted credential (sk-…,ghp_…,AKIA…,xox[bp]-…, or anapiKey:/password:line) can never be committed (NFR-003)..cloc/— the framework-managed, committed, reviewable folder:instructions.md,state.json(schema-versioned viaSTATE_VERSION), and the curatedkit/,journal/,evals/skeletons (kept committed withREADME.mdplaceholders).- Optional seed content (a
docs/copy or anabout/index.mdintent file) grounding the first render. The docs seed copies only document extensions (.md/.mdx/.markdown/.txt/.json/.yml/.yaml/.pdf/.csv), never follows symlinks, and skips VCS/build/dependency dirs — facts only, zero application code (Principle 1, FR-004).
Everything is written create-only: the writers never overwrite or delete a pre-existing path and
refuse any path that escapes the repo root, so output is provably non-destructive (NFR-004). The same
writer backs initInPlace() (used by 0 init and the detected-app "init in place" choice), which
adds .cloc/ + cloc.yml to the current repo without creating a new repository or touching your
existing files (FR-013..FR-016).
The shared on-ramp engine
src/onramp/ is the single source of truth for the three on-ramps — classifyDirectory,
detectApp, autodiscover, scaffold, initInPlace, the cloc.yml emitter, and the config-name
rules — so npx create-cloc, bare 0, and 0 init cannot drift (FR-023). It commits through a
swappable GitProvider (isomorphic-git), never a shelled-out git (Principle 8).
The classifyDirectory gate is a cheap, deterministic, model-free scan (NFR-005) that branches
the cwd into empty → scaffold, detected-app (Next.js/Astro) → in-place offer, or has-content
→ autodiscover. Autodiscovery infers each folder's role from its shape (front-matter Markdown →
collection, prose/PDFs → rag, images → assets); a per-folder marker (cloc.yml/.cloc.yml/…)
overrides inference (FR-010/FR-022). Detection is evidence-based and reports its signals (a
next.config.*/astro.config.* file or a recognized package.json dependency) plus informational
notes (e.g. Contentful/Sanity/Prisma SDKs, env files).
Recent hardening added additive tuning seams — all optional, all defaulting to the documented behavior, all additive (they widen recognition, never shrink it):
detectApp(cwd, { extraDepSignals, extraNoteHints })— recognize extradependency → framework/dependency → notesignals beyond the Next/Astro built-ins.autodiscover(cwd, { extraIgnoredDirs, frontMatterSniffBytes })— skip extra folders and tune the Markdown front-matter sniff window (FRONT_MATTER_SNIFF_BYTES, default 64).classifyDirectory(cwd, { detect, autodiscover })— forwards the two option bags above.assertNoInlineSecrets(raw, { patterns })— tighten (never loosen) the secret gate.resolveSeedhonors a configurable docs subdir / max walk depth viacollectDocsoptions.
Importable API
The package is also a library: src/index.ts re-exports the whole engine so bare 0, 0 init, and
tests call the exact same logic. The notable exports:
- Orchestrators:
runScaffolder(+RunScaffolderOptions),main/parseArgs/USAGE(+ParsedArgs),runOnboarding,validateProjectName,PromptCancelledError. - Engine:
classifyDirectory,detectApp,autodiscover,scaffold,initInPlace,resolveFolderConfig, plus their option/result types and the constants (ACCEPTED_CONFIG_NAMES,ROOT_CONFIG_NAME,DEFAULT_AUTHOR,IMAGE_EXTS,PROSE_EXTS,MARKDOWN_EXTS,IGNORED_DIRS,EMPTY_IGNORED,FRONT_MATTER_SNIFF_BYTES) and errors (DuplicateConfigError,RootConfigCollisionError). cloc.yml:ClocYmlSchema,buildClocYml,renderClocYml,emitClocYml,assertNoInlineSecrets,DEFAULT_SECRET_PATTERNS.- Templates / seed:
planDotClocSkeleton,planDotClocSkeletonInPlace,STATE_VERSION,IN_PLACE_INSTRUCTIONS_NOTE,PlannedFile,resolveSeed,DOC_EXTS. - Git seam:
IsomorphicGitProvider,defaultGitProvider,CommitCapableGitProvider,CommitRequest. - Plugin (default export): the package's
defaultexport is aClocPlugin(src/plugin.ts) that contributes thecreate-cloccommand to the0kernel'sCommandPointand provides the commit-capableGitProviderforGitProviderRef. Importing it is side-effect-free. - Version:
VERSION.
The plan's long-term home for this engine is
@cloc/core/src/onramp/(D10). It lives here until that core submodule ships; the shapes do not change when it moves (seesrc/onramp/contract.ts).
Package surface
bin:create-cloc→./dist/bin.js(sonpx create-clocresolves after a build).exports:"."→ types./dist/index.d.ts, default./src/index.ts(the importable engine).type:module(ESM). Publishedfiles:dist+src.- Runtime deps:
@cloc/core,@cloc/plugin,@clack/prompts,isomorphic-git,yaml,zod.
Scripts
pnpm build—tsc -p tsconfig.jsonpnpm typecheck—tsc --noEmit -p tsconfig.jsonpnpm test—vitest run(e2e + the zero-app-code and non-destructiveness invariants, plus the hardening + on-ramp unit suites intest/)pnpm test:watch—vitestin watch mode
Status: pre-alpha (
VERSION/package.jsonversion0.0.0). Seedocs/specs/011-scaffolder-init/for the spec, plan, data model, quickstart, and thecontracts/(cli-surface.md,onramp.contract.ts,cloc-yml.schema.ts).
