Use this skill only for a new repository. It resolves the selected channel from the official Git source, verifies the installed bundled template matches that exact commit, renders the bundle, records the commit for future three-way updates, initializes the new-project workflow, and validates the generated documentation. It does not migrate legacy project state.
Resolve <skill-dir> as the directory containing this SKILL.md; resolve <core-dir> as its sibling dstack-core
skill directory. Run the setup helper through the shared workflow runner so uv reuses one environment for the workflow
rather than creating one environment per script path.
Shared trust contract
Before executing this workflow, read and follow
../dstack-core/references/TRUST-AND-AUTHORITY.md. That contract is
normative for this workflow. If it conflicts with this skill, follow the more restrictive rule and report the conflict.
Startup version evidence
Before rendering or initializing a project, follow
../dstack-core/references/SKILL-VERSION.md for setup-project. After
the read-only destination preflight, capture the exact one-line output and include it in the setup JSON/response before
project mutation. A stale result warns with npx skills update; unavailable records that no freshness claim was
made and does not block offline work.
Setup-specific authority:
- The default source is
gh:RobertDeRose/dstack;stableselects its newest stable PEP 440 tag andunstableselects its default-branch HEAD. Stable is the default. - The helper dereferences the selected tag, branch, or explicit revision, verifies the bundled
copier.ymlandtemplate/match that commit, and records the exact reachable 40-character SHA in.copier-answers.yml; skill metadata is never used as template provenance. --template-sourceand--vcs-refare explicit development/testing overrides. A requested revision must be retrievable from the recorded source.- Existing project content is never interpreted as migration input by this workflow. The helper has no overwrite mode
for project files; route existing repositories through
/migrate-workflow.
Routing preflight
Inspect the destination before invoking the helper.
- If
.copier-answers.ymlexists, do not run setup. Explain that the project is already Copier-managed and ask exactly one question withAskUserQuestion:Run /update-project instead? - Run
/update-projectonly when the user agrees. If the user declines, stop without modifying the repository. - If project files exist but
.copier-answers.ymldoes not, stop and route the user to/migrate-workflow; do not copy migration utilities into the project and do not merge an existing repository from this workflow. - Continue with setup only when the destination is a new project directory, apart from an installed local skills tree
or
skills-lock.json.
The helper independently refuses an existing .copier-answers.yml; this is a non-interactive safety backstop, not
permission to invoke /update-project automatically.
Project brief
Before invoking the helper, collect missing facts with AskUserQuestion, one question at a time, in this order:
--purpose: one sentence describing the problem and intended outcome;--users: one sentence describing intended users;--scope: one sentence describing current supported scope;--boundaries: one sentence describing key exclusions and ownership boundaries;--project-kind: selectlibrary,cli,service,application,infrastructure,documentation, orother;--language-profile: select one or more ofpython,typescript,rust,go,elixir,nix, orother.
Selecting the kind and profiles is confirmation; do not ask a second confirmation question. other is exclusive and
means no recognized language tooling. Values must be non-empty single lines. Do not infer missing facts from the project
name or fabricate defaults.
Then ask whether the repository is single-package (the default) or monorepo. For monorepo mode, collect 1-32
explicit package objects with exact display_name, lowercase hyphenated slug, normalized relative POSIX path, and a
nonempty canonical language_profiles list. Preserve display names and technical acronyms exactly. Pass each object as
JSON with --monorepo-package and pass --repository-layout monorepo. Report the helper's complete layout_preflight;
do not render when it reports an invalid, reserved, overlapping, case-colliding, or symlinked path.
Defaults
- Project name: supplied value, otherwise
basename "$PWD". - Destination: current working directory.
- Template channel:
stable; pass--unstableto select the source default-branch HEAD. - Render source: the installed bundle after exact revision verification; explicit
--template-sourceoverrides it. - Recorded update source:
gh:RobertDeRose/dstackunless--template-sourceis explicit. - Recorded baseline revision: the exact resolved commit SHA; stable results also report the selected release tag.
- Default branch:
main. - Beads: run native non-stealth initialization in the project repository. Native Beads commits collaborative controls,
discovers Git origin, owns Dolt placement, and configures synchronization. Keep
--skip-hooksduringbd init, verify its exact commit paths, apply the machine-authored README exclusion, amend that commit through project hooks, then runbd hooks installand verifybd hooks list --json. Ifbdis unavailable, report initialization and hook verification as outstanding; never substitute--stealthor commit runtime/database paths. - Tooling: after rendering and optional Git initialization, resolve
mise.lockfor Linux/macOS x64/ARM64, install withmise install --locked, then install repository-local hk hooks separately. These steps require mise and network access.
Execution
uv run <core-dir>/scripts/run-workflow.py <skill-dir>/scripts/setup-project.py [project-name] \
--purpose "<problem and outcome>" \
--users "<intended users>" \
--scope "<current supported scope>" \
--boundaries "<key exclusions and ownership boundaries>" \
--project-kind <kind> \
--language-profile <profile> [...] \
--repository-layout single-package
The project name remains optional and defaults to basename "$PWD". Add --destination <path> to target another new
directory, --delete-readme to omit the starter README, or --unstable to use the latest default-branch commit.
Development-only template overrides retain the same required brief flags:
uv run <core-dir>/scripts/run-workflow.py <skill-dir>/scripts/setup-project.py "Reader Control Plane" \
--purpose "Coordinate reader devices from one control plane." \
--users "Operators responsible for reader fleets." \
--scope "Provisioning and health workflows for supported readers." \
--boundaries "Reader firmware and identity-provider administration remain external." \
--project-kind service \
--language-profile python \
--language-profile typescript \
--template-source gh:example/dstack-fork \
--vcs-ref <reviewed-tag-or-commit>
The setup helper performs post-render initialization itself. It does not generate scripts/bootstrap.py,
scripts/migrate-legacy-workflow.py, or a migration guide in the new project. Use --skip-post-setup to skip tooling,
Beads, and documentation setup while preserving exact recovery commands. --no-git-init still resolves tools but
reports hooks and collaborative Beads initialization as outstanding unless the destination is already its own Git
repository.
Verification
Confirm at least:
.copier-answers.yml
AGENTS.md
.beads/formulas/dstack-feature.formula.toml
docs/book.toml
docs/src/SUMMARY.md
docs/src/planned-features.md
docs/src/features/_template/design.md
docs/src/features/_template/index.md
scripts/check-docs.py
scripts/setup-tooling.py
mise.toml
hk.pkl
.config/rumdl.toml
Confirm these new-project-inappropriate paths do not exist:
MIGRATION.md
scripts/bootstrap.py
scripts/migrate-legacy-workflow.py
Verify .copier-answers.yml records the selected source, exact resolved commit SHA, and dstack_template_channel.
Verify generated AGENTS.md requires real multiline commit messages via git commit -F <file> (never multiple -m
flags or escaped \n) and permits only git merge --ff-only into main. The helper runs
uv run --no-project python scripts/check-docs.py as part of setup. A successful tooling run creates a nonempty
mise.lock, installs with --locked, and runs mise x -- hk install --mise. The Beads phase runs bd hooks install
only after the native init amend commit, then requires every hook reported by bd hooks list --json to be installed and
current. If mise, resolution, installation, hk hook setup, or Beads hook setup fails, the scaffold remains intact and
the JSON tooling and beads_hooks objects report separate states, bounded error text, and exact recovery commands.
Rerun recovery with:
python3 scripts/setup-tooling.py --json
Check availability before invoking Beads verification:
if command -v bd >/dev/null 2>&1; then
bd prime
bd list --type epic --label workflow:feature --all --json --limit 0
else
printf '%s\n' 'Beads verification outstanding: install bd, initialize it, then run bd prime.'
fi
Do not run bd prime when bd is unavailable. In that case setup may complete, but the return must list Beads
initialization and verification as outstanding.
Copier contract
- Commit
.copier-answers.ymland the initial scaffold. - Stable setup and updates select the newest stable tag; unstable setup and updates select the source default-branch HEAD. Both persist the exact commit used.
npx skills updateupdates installed skill definitions and scripts./update-projectpreserves the recorded channel unless explicitly overridden.- Do not edit
.copier-answers.ymlmanually.
Return
Report project name, slug, purpose, users, scope, boundaries, kind, language profiles, repository layout, exact package
answers, layout preflight/render destinations, destination, template channel, selected ref, exact recorded commit, skill
version, Git result, Beads result, documentation validation, the complete tooling and beads_hooks statuses,
outstanding recovery commands, and the next /plan-features action. If setup was routed to /update-project, report
the user's consent decision and do not claim setup ran.