A new project is judged by everything except its code: the toolchain, CI, release and docs must work from the first commit, while the code itself stays a placeholder until the user asks for logic.
Read guide.md before writing any file. It explains how to read the request, what you may change in a template and why, how to write the docs, and what to do when no template fits.
Required initialization gate
For a completely new project, finish the managed project initialization before writing any scaffold or project files:
- Load the
$global-projectsskill and use its paired resolver to find the configured project root and project CLI. - Resolve the repository owner and name. If either is missing or ambiguous, ask the user before creating the project directory.
- Resolve whether the repository should be public or private. If the user did not specify visibility, ask before continuing. "Private" only sets the GitHub repository visibility, never
private: truein a package. - Resolve a one-sentence description of what the project does. If the request doesn't say, ask instead of describing the scaffold.
- Run the selected CLI's
initcommand with the explicit visibility option from<root>/<owner>/<repo>. - Verify the local path and
originremote, then create the scaffold inside that initialized repository (see Templates).
An explicit request to create or initialize a new project authorizes the managed initialization. Once the owner, name, visibility, and description are known, do not ask for a second confirmation before running moi init --public, moi init --private, or the paired mo command.
Do not create the project anywhere else (the current task directory, work/, outputs/), and do not use plain git init instead of the managed init. If a required choice is missing, ask for it instead of skipping the initialization.
Templates
Templates live in templates/ next to this file. Load $choosing-tools to pick the stack, then copy its layers in order into <root>/<owner>/<repo>:
| Stack | Layers | Use for |
|---|---|---|
rust |
common + rust |
Rust crates and CLIs |
js-lib |
common + js + js-lib |
npm libraries |
js-cli |
common + js + js-cli |
Node.js command line tools |
Websites and napi-rs projects have no template yet. Build them by hand as described in guide.md.
For a workspace (monorepo), apply the stack in two levels as described in guide.md.
While copying:
- Rename
_namepaths to.name, and__repo__paths to the repo name. - Don't copy
AGENTS.part.mdandCONTRIBUTING.part.md. Merge every layer's part, in layer order, into the{{toolchain}}line ofAGENTS.mdand the{{setup}}line ofCONTRIBUTING.md. - Fill
{{owner}},{{repo}},{{repo_ident}}(the repo name with-replaced by_),{{description}},{{year}}and{{rust_version}}(fromrustc --version). - Add
.github/FUNDING.ymlwithgithub: [<owner>]when the owner has a GitHub Sponsors profile.
Templates don't pin dependency versions. Add them at their latest versions inside the new project instead, and never copy pinned versions from other projects:
js: Write the current Node major version to.node-version. Addvite(aliased tonpm:@voidzero-dev/vite-plus-core@<version>),vite-plus(pinned to the version@liangmi/vp-configsupports),@liangmi/vp-config,typescript,@typescript/native-preview,@types/nodeandbumppto the catalog and todevDependenciesascatalog:, as described in guide.md. Overridevite@*tocatalog:and allow anyviteversion inpeerDependencyRules, then runvp install.js-cli: Addcacandpicocolorsthe same way, as dev dependencies (CLI dependencies are bundled).rust:cargo add insta --dev -p <repo>,cargo add criterion --dev -p benchmark,cargo add <repo> --path crates/<repo> --dev -p benchmark, thendprint config update --yes.
After scaffolding:
-
Write every
{{TODO: ...}}placeholder, mostly inAGENTS.md. Config owned by a fast-moving tool, likevite.config.tsfor@liangmi/vp-config, is left as a placeholder; write it by following that tool's skill ($use-vp-configfor@liangmi/vp-config). Delete a section instead of leaving it empty. Keep what you write intoAGENTS.mdshort, so the file stays around 40 lines. -
Adjust the scaffold to the project: the package name (for example a scoped npm name), extra crates or packages, CLI binaries, and the CI matrix.
-
Set the GitHub repo settings (squash merge only, PR title and description as the commit message, auto delete branches, a description):
gh repo edit <owner>/<repo> --description "<description>" --enable-squash-merge --enable-merge-commit=false --enable-rebase-merge=false --delete-branch-on-merge gh api -X PATCH repos/<owner>/<repo> -f squash_merge_commit_title=PR_TITLE -f squash_merge_commit_message=PR_BODY -
Run the stack's checks:
just readyfor Rust,vp run check && vp run build && vp run testfor JavaScript. They must not leave formatting changes behind. -
Search for
{{to make sure no placeholder is left. -
diffevery generated file against its template, and check each difference as described in guide.md.