feat: retarget the canton stack and split stack config into modules - #16
feat: retarget the canton stack and split stack config into modules#16gabitoesmiapodo wants to merge 17 commits into
Conversation
The initial commit was made as "dAppBooster <no-reply@dappbooster.dev>", so the first entry in every new project's history belonged to the installer instead of the person who ran it. Drop the hardcoded name and email and let git fall back to the user's own configuration. Signing stays off, and --no-verify stays, so the project's own hooks do not lint a tree nobody has touched yet.
Canton now points at canton-dappbooster and installs with pnpm. It is cloned at its newest tag, copies one root .env file, and offers no optional features, so the wizard asks only for a project name and the CLI rejects --mode and --features for it. Stack metadata leaves source/constants/config.ts for one module per stack under source/stacks/, with source/stacks/index.ts holding the record and the accessors. Every type moves to source/types/types.ts. New fields in StackConfig: - prepare: the paths, scripts and devDependencies every scaffold drops. It runs before the install, so the package manager resolves the pruned manifest once. Replaces removeAfterClone and hygiene. - minNodeVersion: checked at the top of cloneRepo, so a Node that is too old fails with a plain message instead of a confusing install error. - postInstallComponent: a richer closing screen for the wizard, imported on demand so --info and the non-interactive path never load Ink. A stack is cloned at its newest tag unless ref names one, which today only DAPPBOOSTER_<STACK>_REF does. That leaves refType with nothing to decide, so it is gone, along with npm as a package manager. No stack used either.
Update the architecture guide, the readme and the agent instructions for the new layout. source/stacks/ is the single source of truth for stack and feature metadata, and every type lives in source/types/types.ts. Also covers: - the prepare step, and what it replaced - the Canton stack, and why it takes neither --mode nor --features - the rule that no file outside source/stacks/ and source/cli.tsx may test a stack by name
The review step printed everything on one long line, separating the settings with a middle dot. Each setting now gets its own line, and the value after the colon is bold green, the same style the stack and installation type answers already use. The installation mode is named from one shared table, so the review spells it the same way the selector did. - describeInstallPlan returns a label and a value per setting instead of a finished string, so the step decides how a line looks - MODE_LABELS moves to utils.ts, where both the selector and the review read it - the confirmation answers now read "Yes." and "No, start over." - planSummary is memoised, because the step list is built from it
The divider read "Full installation" or "Custom installation", built from the mode name. Stacks with no modes have nothing to put there, so the title is now fixed and works for any stack.
The divider read "Post-install instructions — EVM". The stack is already settled by the time this step runs, so the title is now fixed.
Canton fell back to a plain list of lines while EVM had a proper screen. It now has one too, laid out the same way: the steps to start, then a warning, then where to read more. Canton: - highlights dev-stack, the cd command, the script path and Stack Up - warns in bold that the first run pulls about 10 GB - links the README, the components documentation and the issue tracker EVM: - drops the line about the installer's own issue tracker - reports issues against the dAppBooster repo instead - adds a link to the components documentation - rewords the documentation line to match Canton's The postInstall lines in the stack config stay as they are. They are what --ni prints as JSON.
The running step showed a static circle and the word "Working...". It now shows a spinner, so a long clone or install looks alive instead of stuck. Adds ink-spinner, which resolves to the same ink 5.2.1 the other ink packages use, so there is still one renderer. Clone, cleanup and install all render through StepProgress, so all three get it.
Project names took letters, numbers and underscores only, so the common my-dapp spelling was rejected. Dashes are now allowed, but not as the first character: the name is the last argument of git clone, and git reads a leading dash as an option. --upload-pack= runs a command, so the name has to start with a letter, a number or an underscore. The wizard tip, the --ni error and the --help text all say so. Ask takes its tip as a node now, so the tip can put "non-initial" in bold.
Once a stack is picked, the title shows which one, so the stack stays visible for the rest of the run instead of scrolling away with the selection step. MainTitle takes the stack and reads its label from the config, so a third stack needs no change here. Nothing shows before a stack is chosen. The badge sits on the last line of the logo. ink-big-text pads its block with two blank lines top and bottom, which is what the bottom margin cancels out.
Patch and minor bumps only. No API changes, so nothing in the source had to move. - @biomejs/biome 2.5.12 -> 2.5.13 - knip 6.33.0 -> 6.35.1 - @types/node 24.13.3 -> 24.13.4 - lint-staged 17.5.0 -> 17.5.1 biome.json points at the matching schema, which biome migrate wrote. The major bumps are left alone: ink 7 wants react 19, and ink-divider depends on ink 5 outright rather than as a peer, so taking it would load two renderers. TypeScript 7 is its own decision.
The readme dropped its development section. Everything in it was already here except two things, which move over: - the full command table. Only the five validation commands were listed, so build, dev, test:coverage and lint:fix were missing, as was the fact that typecheck runs two passes - the warning to run the built CLI from a scratch directory, since it scaffolds into the folder it starts from
architecture.md was an index pointing at three files under docs/architecture/. The split existed so a reader could open one part instead of all of it, but the whole guide is only 280 lines, so it bought nothing and cost an index table to keep in sync and links between files that break when a section moves. It is one file now, with the sub-docs as sections: Key Abstractions, Data Flow, Extending the Installer. The docs folder is gone. The prose is unchanged. Only the heading levels moved, and the two links between sub-docs became in-page anchors.
Most of the readme repeated what CLAUDE.md and architecture.md already say, at more length and with less accuracy. The flag table was also incomplete. It now lists --info, --help, --version and the --non-interactive long form, checked against cli.tsx and the --help output, and the --name row shows the real pattern now that dashes are allowed.
demo.svg still showed an older wizard. It now shows the current one: the stack prompt, the badge, the stacked review screen and the spinner. It is cut at 15 seconds, ending as the clone starts. Past that point it is the package install, a long stretch of near-static output that reads as a frozen image rather than a loop. The file is 28 KB, down from 90 KB. scripts/record-demo.py regenerates it in one command. It scaffolds a real EVM project in a temporary directory, drives the wizard, and runs svg-term-cli. CLAUDE.md records what was expensive to work out: the exact svg-term flags that match the committed geometry, why asciinema cannot be scripted here, and why the script uses a pty from the Python standard library.
Claims that this branch made wrong: - stacks were said to declare a "ref strategy (tag-latest vs branch)". refType is gone; a stack declares an optional ref and is cloned at its newest tag without one - the interactive step order read "install then cleanup". It is clone, cleanup, install, post-install - installPackages was said to use pnpm or npm. It is pnpm only - Confirmation was said to show a one-line summary. It shows one line per setting Also adds ink-spinner to the styling row, CantonPostInstall.tsx to the structure tree, and the stack badge to the MainTitle description.
The installer accepted Node 22 while the Canton stack needs 24.15.0, so a Canton user on Node 22 got as far as the clone before being turned away. Everything now asks for the same version. - engines.node is >=24.15.0 - the CI floor job runs 24.15.0 instead of 22 - the readme, CLAUDE.md and architecture.md say the same .nvmrc stays at 24. It already resolves to the newest 24.x, and pinning development to the floor is worse than following the latest patch. CI still covers both. dAppBooster declares no Node version at all, which is BootNodeDev/dAppBooster#484. The EVM stack gets no minNodeVersion until that lands, since the number should come from the template.
There was a problem hiding this comment.
🔵 Needs a closer look
It is a large, multi-file refactor that retargets a stack, changes CLI/UX behavior, and touches CI and dependency floors, so final human verification is warranted.
Pull request overview
This PR retargets the Canton stack at the new canton-dappbooster repository (whose three libraries now ship on npm) and refactors stack/feature metadata out of a single source/constants/config.ts into a per-stack module layout under source/stacks/. Scaffolding Canton is now essentially deletion: a prepare phase removes the in-tree library folders (canton-connect, canton-dappbooster, canton-theme, kit/) and repo-only tooling before a single pnpm install, so the same package.json resolves the libraries from the registry. Canton declares no features, so the wizard asks only for a project name and the non-interactive path rejects --mode/--features for it. The EVM path keeps its features and behavior, with cosmetic UI updates (per-line review screen, running spinner, stack badge, dedicated post-install screens).
Changes:
- Split
constants/config.tsintosource/stacks/{index,evm,canton}.ts+ sharedsource/types/types.ts; all consumers read viagetStackConfig, andgetInstallationModesreturns[]for featureless stacks to drive step-skipping and CLI rejection. - Retarget Canton (new
repoUrl,pnpm,minNodeVersion 24.15.0,initialCommit, latest-tag clone,preparepaths/scripts/devDependencies, single.env.example → .env), drop the Canton feature system, and generalizeremoveAfterCloneinto a config-driven prepare phase applied before install. - Allow dashes (not leading) in project names, add spinner/badge/per-line review UI, dedicated
EvmPostInstall/CantonPostInstall, dropnpm/refType, bump four dev deps, raiseengines.nodefloor, and update docs/demo/CI.
File summaries
| File | Description |
|---|---|
source/stacks/index.ts |
New accessors (getStackConfig with env overrides, getInstallationModes) that centralize stack metadata. |
source/stacks/evm.ts |
EVM StackConfig with prepare/staging and the five features unchanged. |
source/stacks/canton.ts |
Retargeted Canton config: new repo, pnpm, prepare deletions, no features, dedicated post-install. |
source/types/types.ts |
Home for shared types (Stack, FeatureName, StackConfig, PrepareStep, PlanSummaryItem, …). |
source/operations/cleanupFiles.ts |
Config-driven prepare phase: delete paths, strip scripts referencing removed dirs, prune devDependencies pre-install. |
source/operations/installPackages.ts |
Simplified to pnpm-only (remove) install/post-install flow. |
source/operations/cloneRepo.ts |
Uses ref (env override) or latest tag; enforces minNodeVersion before disk work. |
source/nonInteractive.ts |
Rejects --mode/--features for featureless stacks with a named reason. |
source/app.tsx |
Skips mode/feature/confirmation steps when a stack has no features. |
source/utils/utils.ts |
Adds meetsNodeVersion, MODE_LABELS, per-item describeInstallPlan, dash-aware isValidName. |
source/components/steps/* |
New spinner (StepProgress), stack badge (MainTitle), and Evm/Canton post-install screens. |
source/info.ts |
--info reports empty modes/features for Canton. |
tests, docs, demo, CI, package.json |
Comprehensive test updates, doc merge, re-recorded demo, dep bumps, and Node-floor CI rename. |
Review details
Files not reviewed (1)
- pnpm-lock.yaml: Generated file
- Files reviewed: 48/50 changed files
- Comments generated: 0
- Review effort level: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Summary
Closes #15
canton-dappbooster moved to a new repository and publishes its three libraries to npm. The installer still pointed at the old repo and described a tree that no longer exists.
Changes
Deviations
refTyperemoved entirely rather than set totag-latest. With both stacks on tags it had nothing left to decide, sorefalone drives the cloneAcceptance criteria
pnpm dlx dappbooster --canton --name testproj --niscaffolds a working project from the latest canton-dappbooster tagpackage.jsonhas neither the seven scripts nor typedoc and postcsspnpm installin the scaffolded project resolves the three@bootnodedev/*libraries from npm, with no path pointing into a workspace library folderpnpm lint,pnpm typecheck,pnpm testandpnpm knipall pass in the scaffolded project (knip printing configuration hints is fine, as long as it exits 0)--modeor--featureswith--cantonfails with a message naming the reasonsource/outsidestacks/andcli.tsxtests a stack by nameTest plan
Automated tests
pnpm installpnpm lint && pnpm typecheck && pnpm build && pnpm test && pnpm knipManual verification
pnpm buildnode <repo>/dist/cli.js./scripts/dev-stack.sh upin the new project and choose Stack UpOptional: EVM
pnpm subgraph-codegenandpnpm dev, and open the printed URLNon-interactive, driven by an agent verification
Give a coding agent only the goal, never the flags, and watch what it does.
--infofirst, and to readmodesbefore choosing anything--canton --ni --name <name>and no--modeor--features"success": trueand an emptyfeatureslist--evm --ni --mode custom --features demo,subgraph, and the same features echoed backTo check the failure paths by hand:
--canton --ni --name x --mode fulland expect a refusal naming Canton--evm --ni --name x --mode custom --features nopeand expect the valid feature names listed--canton --evmand expect a conflicting-flags errorBreaking changes
None.
Checklist