Skip to content

Commit cfbb0fa

Browse files
committed
docs: reflect the reordered interactive flow and interrupt guard
Update docs/architecture/data-flow.md for the questions-before-operations order and the Confirmation step, document installGuard under abstractions, and list it in the architecture index's project structure.
1 parent eec8d8d commit cfbb0fa

3 files changed

Lines changed: 14 additions & 2 deletions

File tree

architecture.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ source/
3737
createEnvFile.ts Copy each stack's envFiles (with optional ifFeature gate)
3838
installPackages.ts Stack-aware: uses stack.packageManager (pnpm or npm)
3939
cleanupFiles.ts Dispatches to per-stack cleanup (cleanupEvmFiles / cleanupCantonFiles)
40+
installGuard.ts Removes the partial project dir if interrupted mid-scaffold
4041
index.ts Barrel export
4142
components/
4243
steps/ TUI step components (presentation-only)

docs/architecture/abstractions.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ Plain async functions, no UI dependencies. Each operation that varies per stack
5656
| `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> run postinstall`. Custom with all features: `<pm> install`. `execFile` only — never shell. |
5757
| `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. |
5858
59+
### Interrupt safety (`installGuard`)
60+
61+
`source/operations/installGuard.ts` makes a Ctrl+C mid-scaffold leave no partial directory behind. `beginInstall(projectFolder)` is called the instant disk work starts (before `cloneRepo`) and registers `SIGINT`/`SIGTERM` handlers; `completeInstall()` is called once cleanup finishes. On an interrupt while a scaffold is in progress, the handler removes the project directory; after `completeInstall` it is a no-op, so a finished project (or a Ctrl+C on the post-install screen) is never deleted. It only ever removes a directory created this run — both entry paths reject a pre-existing directory up front — so user data is never touched. Both paths wire it in: the non-interactive runner brackets its operation block, and interactively `CloneRepo` calls `beginInstall` while `FileCleanup` calls `completeInstall`.
62+
5963
## Shell Execution (`source/operations/exec.ts`)
6064
6165
Two helpers with different security profiles:

docs/architecture/data-flow.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,15 @@ User input via Ink components
7070
→ Ink renders progress/status
7171
```
7272

73-
Steps: StackSelection → ProjectName → CloneRepo → InstallationMode → OptionalPackages → Install → FileCleanup → PostInstall
73+
All questions come **before** any disk work, mirroring the non-interactive path — so abandoning the wizard while answering leaves nothing behind.
7474

75-
When `cli.tsx` resolves a stack flag, it passes `preselectedStack` to `<App>`, which skips the StackSelection step by starting `currentStep` at 2.
75+
```
76+
Questions (no disk): ProjectName → [StackSelection] → InstallationMode → OptionalPackages (custom only) → Confirmation
77+
Operations (disk): CloneRepo → Install → FileCleanup → PostInstall
78+
```
79+
80+
`Confirmation` shows a one-line plan summary (`describeInstallPlan`) and is the last side-effect-free step. **Yes** starts the operations; **No** loops back to the first question (state is reset and the question steps are re-keyed so they re-mount fresh). When `cli.tsx` resolves a stack flag, it passes `preselectedStack` to `<App>`, which skips the `StackSelection` step.
81+
82+
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.
7683

7784
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.

0 commit comments

Comments
 (0)