/** * initDiablo scaffolds a project for diablo: it writes a default * diablo.config.json (without clobbering an existing one), runs the * setup-matt-pocock-skills flow, and OPT-IN asks whether to bootstrap project * tooling. Declining skips bootstrapping silently; this is the only * bootstrapping surface — `run` never auto-bootstraps. * * initDiabloNonInteractive is the flag-driven alternative: scaffolds everything * with sensible defaults, zero stdin, fully AFK-friendly. Controlled by the * InitFlags from args.ts. * * Bootstrap policy lives HERE (not in main.ts glue) so it is unit-tested: * 1. opt-in confirm — decline does nothing further; * 2. on accept, choose a package manager (bun/npm/pnpm) or "skip"; * 3. `git init` runs for any real choice, independent of the manager; * 4. husky/commitlint are installed only for a real manager — "skip" is the * escape hatch for non-Node projects (Go/Rust/Python), where these Node * tools don't belong. * * The side-effecting steps (skill setup, git init, tooling install) are injected * as functions so this use-case is unit-tested against fakes; main.ts wires the * real implementations. */ import type { FsPort } from "../ports/fs.ts"; import type { PromptPort } from "../ports/prompt.ts"; import { type PackageManager } from "../domain/package-manager.ts"; /** * Minimal deps shared between interactive and non-interactive init. Only the * filesystem seam and the commit-check (for greenfield vs brownfield gitignore). */ export interface BaseInitDeps { fs: FsPort; /** True when the repo already has commits (brownfield). */ hasCommits: () => Promise; } export interface InitDeps extends BaseInitDeps { prompt: PromptPort; /** Runs the interactive setup-matt-pocock-skills flow (real: a Pi session). */ setupSkills: () => Promise; /** Initialises a git repo if the directory is not already one (idempotent). */ gitInit: () => Promise; /** Installs + initialises husky/commitlint using the chosen package manager. */ installTooling: (pm: PackageManager) => Promise; } export interface InitConfig { /** Absolute path where diablo.config.json should be scaffolded. */ configPath: string; /** Absolute path where the project's .gitignore lives (created/merged). */ gitignorePath: string; /** Absolute path to the project root (for .scratch/, docs/agents/, etc.). */ repoRoot: string; } /** Options for the non-interactive init, derived from CLI flags. */ export interface InitNonInteractiveOptions { /** Which agent guidance doc to scaffold. */ agentDoc: "agents" | "claude"; /** Context layout mode. */ context: "single" | "multiple"; /** * Triage label scaffold policy. * - `[]` → scaffold with the default 5-label vocabulary * - `["a","b"]` → scaffold with custom labels * - `null` → skip triage scaffold entirely */ triageLabels: string[] | null; } export declare function initDiablo(deps: InitDeps, config: InitConfig): Promise; /** * Scaffolds a diablo project with sensible defaults, zero stdin. Every * scaffolded file is idempotent: if it already exists, it is skipped. * * This is the AFK-friendly alternative to the interactive `initDiablo`. */ export declare function initDiabloNonInteractive(deps: BaseInitDeps, config: InitConfig, options: InitNonInteractiveOptions): Promise;