You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: AGENTS.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -9,8 +9,8 @@
9
9
A CLI installer tool for dAppBooster projects. It supports two **stacks** and two **modes**:
10
10
11
11
-**Stacks:**`evm` (the original dAppBooster for EVM chains) and `canton` (dAppBooster for Canton: Daml ledger, Carpincho wallet, off-chain services). Each stack declares its own source repository, ref strategy (tag-latest vs branch), package manager, env files, optional `removeAfterClone` paths, and features.
12
-
-**Interactive** (default): React + Ink TUI that prompts for stack first, then project name, then clone → installation mode → optional packages → install → cleanup → post-install. The stack prompt is skipped when `--canton`, `--evm`, or `--stack` is supplied.
13
-
-**Non-interactive**: Flag-driven (`--ni` or auto-detected when not a TTY) for AI agents and CI. Outputs JSON to stdout. Run `--info` for stack + feature discovery, then `--canton`/`--evm` (or `--stack`) + `--name` + `--mode`[+ `--features`]. Omitting a stack flag in non-interactive mode defaults to `evm` for backward compatibility.
12
+
-**Interactive** (default): React + Ink TUI that prompts for stack first, then project name, then installation mode (Canton offers **default** / full / custom; EVM offers full / custom) → optional packages → install → cleanup → post-install. The stack prompt is skipped when `--canton`, `--evm`, or `--stack` is supplied.
13
+
-**Non-interactive**: Flag-driven (`--ni` or auto-detected when not a TTY) for AI agents and CI. Outputs JSON to stdout. Run `--info` for stack + feature discovery, then `--canton`/`--evm` (or `--stack`) + `--name` + `--mode`[+ `--features`]. Canton supports `--mode default` (the recommended set: keeps `carpincho` + `llm`, removes `github` + `precommit`); `default` is rejected for EVM. Omitting a stack flag in non-interactive mode defaults to `evm` for backward compatibility.
Installation modes are stack-aware via `getInstallationModes(stack)` — Canton offers `default` / `full` / `custom`, EVM offers `full` / `custom`. The `default:boolean` flag on a feature has two roles: it pre-checks the feature in the custom multiselect **and** defines membership in `default` mode (`getDefaultFeatureNames(stack)` = the `default:true` set). `default` mode is Canton-only because EVM has no `default:false` features (there it would equal `full`).
26
+
24
27
`getStackConfig(stack)` reads the base config and overlays the env-var overrides `DAPPBOOSTER_<STACK>_REPO_URL` and `DAPPBOOSTER_<STACK>_REF` before returning — that's the single hook for retargeting either stack at a fork or pre-release branch without editing code.
25
28
26
29
`getFeatureNames(stack)` and `isFeatureNameValid(stack, name)` are the per-stack feature accessors. There is no global `featureDefinitions` export — that would imply a single stack.
@@ -43,7 +46,7 @@ type FeatureDefinition = {
43
46
44
47
When adding a new feature, add it to the relevant stack's `features` map. Programmatic consumers pick it up automatically. Canton feature cleanup is fully data-driven from `paths` (see the Operations Layer below), so a new Canton feature needs no cleanup code — only its `paths`. EVM features still need an explicit per-feature cleanup function. The CLI `--help` text in `cli.tsx` maintains its own copy in both cases.
45
48
46
-
**Feature dependencies (`requires`)** are resolved by pure helpers in `utils.ts`. `resolveSelectedFeatures(stack, selected)` expands a selection to include every transitive requirement (used by the non-interactive path, so `--featurese2e` yields `[counter, e2e]`). `applyFeatureToggle(stack, selection, toggled, action)` keeps the interactive multiselect consistent: selecting a feature pulls its requirements in, deselecting one cascades its dependents out. `e2erequirescounter` is the only dependency today.`--info` surfaces each feature's `requires` so agents can resolve dependencies themselves.
49
+
**Feature dependencies (`requires`)** are resolved by pure helpers in `utils.ts`. `resolveSelectedFeatures(stack, selected)` expands a selection to include every transitive requirement; `resolveModeFeatures(stack, mode, customSelection)` maps a mode to its kept-feature list (full → all, default → the `default:true` set, custom → the resolved selection) and is shared by the non-interactive path and the interactive Install/FileCleanup/PostInstall steps. `applyFeatureToggle(stack, selection, toggled, action)` keeps the interactive multiselect consistent: selecting a feature pulls its requirements in, deselecting one cascades its dependents out. No feature declares `requires` today (the machinery remains for future use);`--info` surfaces each feature's `requires` so agents can resolve dependencies themselves.
47
50
48
51
## Operations Layer (`source/operations/`)
49
52
@@ -53,8 +56,8 @@ Plain async functions, no UI dependencies. Each operation that varies per stack
53
56
|---|---|
54
57
| `cloneRepo(stack, projectName, onProgress?)` | Reads `stack.refType`. **tag-latest**: shallow clone with `--no-checkout`, `gitfetch --tags`, then `gitcheckout$(gitdescribe --tags …)` (shell required for `$()`). **branch**: shallow clone with `--branch <stack.ref> --single-branch` (no shell). After that, runs `fs.rm` for every entry in `stack.removeAfterClone` (empty for both stacks today), removes `.git`, and reinitializes with `gitinit`. Uses `execFile` everywhere except the tag-latest shell substitution. |
55
58
| `createEnvFile(stack, projectFolder, features?)` | Copies every entry from `stack.envFiles`. Entries with `ifFeature` are skipped unless the named feature is in the selection (e.g. Canton's `carpincho-wallet/.env.local` only when `carpincho` is selected). |
56
-
| `installPackages(stack, projectFolder, mode, features, onProgress?)` | Uses `stack.packageManager`. Full: `<pm> install`. Custom with packages to remove: `<pm> remove` (pnpm) or `<pm> uninstall` (npm) + `<pm> runpostinstall`. Custom with all features: `<pm> install`. `execFile` only — never shell. |
57
-
| `cleanupFiles(stack, projectFolder, mode, features, onProgress?)` | First runs **repository hygiene** (every stack/mode): both stacks always remove `.github` (CI) and the husky/commitlint automation (`.husky`, `.lintstagedrc.mjs`, `commitlint.config.js`) and sanitize tooling deps/scripts from `package.json`; **EVM additionally** always removes its own agent metadata (`.claude`, `AGENTS.md`, `CLAUDE.md`, `architecture.md`), whereas **Canton keeps that metadata** under the optional `llm` feature. Then dispatches to `cleanupEvmFiles` or `cleanupCantonFiles`. EVM removes deselected feature files via per-feature functions plus the `.install-files` staging directory, and patches `package.json` by feature name. Canton cleanup is **data-driven**: it loops the stack's features and, in custom mode, removes each deselected feature's `paths` (e.g. `counter/`, `e2e/`, `carpincho-wallet`, the `llm` artifact paths). The removed directories then drive `package.json` script stripping by **command target** — any script whose command invokes a removed directory is dropped (so deselecting `carpincho` strips `wallet:dev` / `carpincho:build:extension`). Command-based matching keeps cleanup correct as the upstream repo renames or adds scripts. In `full` mode no feature paths are removed, so a full Canton scaffold keeps `carpincho-wallet`, the agent docs, and every script. Canton then makes an initial `git` commit of the scaffold. |
59
+
| `installPackages(stack, projectFolder, mode, features, onProgress?)` | Uses `stack.packageManager`. Full: `<pm> install`. `default`/`custom` with packages to remove: `<pm> remove` (pnpm) or `<pm> uninstall` (npm) + `<pm> runpostinstall`; with nothing to remove: `<pm> install`. Canton features all carry `packages: []`, so Canton always runs a plain `npminstall` (husky-dep removal happens in cleanup, not here — the Canton template has no `postinstall` script). `execFile` only — never shell. |
60
+
| `cleanupFiles(stack, projectFolder, mode, features, onProgress?)` | **EVM** runs **repository hygiene** first (always): removes `.github` (CI), the husky/commitlint automation (`.husky`, `.lintstagedrc.mjs`, `commitlint.config.js`), and its own agent metadata (`.claude`, `AGENTS.md`, `CLAUDE.md`, `architecture.md`), and sanitizes tooling deps/scripts from `package.json`; then `cleanupEvmFiles` removes deselected feature files via per-feature functions plus the `.install-files` staging directory. **Canton** runs **no forced hygiene** — `.github` and the pre-commit automation are the optional `github` and `precommit` features. `cleanupCantonFiles` is **data-driven**: for `default` and `custom` modes (not `full`) it loops the stack's features and removes each deselected feature's `paths` (`github` → `.github`; `precommit` → the husky files; `carpincho` → `carpincho-wallet`; `llm` → the agent/LLM artifacts). Removed directories drive `package.json` script stripping by **command target** — any script whose command invokes a removed directory is dropped (so deselecting `carpincho` strips `wallet:dev` / `carpincho:build:extension`). When `precommit` is removed it additionally strips the `prepare`/commitlint scripts and the husky/lint-staged/commitlint dev-dependencies. In `full` mode nothing is removed, so a full Canton scaffold keeps `.github`, the hooks, `carpincho-wallet`, and the agent docs. Canton then makes an initial `git` commit of the scaffold. |
@@ -50,14 +52,14 @@ Any error produces `{ "success": false, "error": "..." }` and exit code 1. Error
50
52
"success": true,
51
53
"stack": "evm|canton",
52
54
"projectName": "...",
53
-
"mode": "full|custom",
55
+
"mode": "full|default|custom",
54
56
"features": ["..."],
55
57
"path": "/absolute/path",
56
58
"postInstall": ["..."]
57
59
}
58
60
```
59
61
60
-
For full mode, `features` lists all of the stack's feature names. For custom mode, the selected ones plus any dependencies they pulled in.
62
+
For full mode, `features` lists all of the stack's feature names; for default mode, the `default: true` set (Canton: `carpincho`, `llm`); for custom mode, the selected ones plus any dependencies they pulled in.
Once operations begin, `CloneRepo` calls `beginInstall` (see [abstractions → installGuard](./abstractions.md#interrupt-safety-installguard)) and `FileCleanup` calls `completeInstall` on success, so a Ctrl+C mid-scaffold removes the partial directory while a finished project is left intact.
83
85
84
-
Components are presentation-only — they call operations via `useEffect` and render status. Components receive `MultiSelectItem[]` for feature selection (TUI concern) and convert to `FeatureName[]` before calling operations. The `OptionalPackages` multiselect enforces feature dependencies live via `applyFeatureToggle`. `PostInstall` renders stack-specific instructions; the EVM branch shows the subgraph warning when applicable, the Canton branch shows the `canton:up`/`app:dev` commands and — when the `carpincho` feature is selected (or full mode) — the Carpincho extension build/load instructions.
86
+
Components are presentation-only — they call operations via `useEffect` and render status. Components receive `MultiSelectItem[]` for feature selection (TUI concern), then derive the kept-feature `FeatureName[]`via `resolveModeFeatures(stack, mode, selected)`before calling operations — so `full`/`default` resolve correctly even though the multiselect is skipped. The `OptionalPackages` multiselect pre-checks `default: true` features and enforces feature dependencies live via `applyFeatureToggle`. `PostInstall` renders stack-specific instructions; the EVM branch shows the subgraph warning when applicable, the Canton branch always shows the `canton:up`/`app:dev` commands and — when the `carpincho` feature is in the resolved set — the Carpincho extension build/load instructions.
Copy file name to clipboardExpand all lines: docs/architecture/extending.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -14,7 +14,7 @@
14
14
15
15
## How to Add a New Feature to an Existing Stack
16
16
17
-
1.**`source/constants/config.ts`** — add an entry to the stack's `features` map. For **Canton**, also list the feature's `paths`: cleanup is data-driven, so no cleanup code is needed and scripts that target a removed directory are stripped automatically. If it ships an env file, add an `ifFeature`-gated `envFiles` entry. If it depends on another feature, add `requires` — resolution is automatic in both the interactive and non-interactive paths.
17
+
1.**`source/constants/config.ts`** — add an entry to the stack's `features` map. The `default` flag governs both the custom-mode pre-check and `default`-mode membership: set `default: true` for "kept by the recommended install", `default: false` for "removed by default / opt-in" (Canton's `github` and `precommit`). For **Canton**, also list the feature's `paths`: cleanup is data-driven, so no cleanup code is needed and scripts that target a removed directory are stripped automatically. If it ships an env file, add an `ifFeature`-gated `envFiles` entry. If it depends on another feature, add `requires` — resolution is automatic in both the interactive and non-interactive paths.
18
18
2.**`source/operations/cleanupFiles.ts`** — **EVM only**: add a cleanup function for the feature and call it from `cleanupEvmFiles` when deselected; if it has scripts, add removal to `patchPackageJsonEvm`. Canton needs no change here.
19
19
3.**`source/components/steps/PostInstall.tsx`** — extend stack-specific instructions if needed.
20
20
4.**`source/cli.tsx`** — update the `--help` text.
0 commit comments