/** * `aidlc init` command — set up AIDLC in a project. * * Single entry point that merges the former `setup` (interactive configuration * wizard) and `init` (per-platform skill install) commands: * * - `aidlc init` — interactive wizard: collect SetupAnswers via the prompt seam, * write `.aidlc/config.yaml`, install skills for each configured platform, * run discovery to generate context docs. * - `aidlc init --platform ` — non-interactive: add the platform to the * config and install skills without prompts. * - `aidlc init --non-interactive` — no prompts; preserve existing config or * apply defaults. * - `--dry-run` — print what would be written without making any changes. * - Unsupported platform → exit code 2, stderr lists supported platforms (Req 1.3). * - Success → exit code 0, summary of files written (Req 1.7). * * `aidlc setup` remains registered as a hidden, deprecated alias. * * Requirements: 1.1, 1.3, 1.5, 17.1, 17.9, 21.1, 21.9, 7.8 * * @module */ import { Command } from 'commander'; import { type Prompter } from '../core/prompt.js'; import type { PlatformId } from '../core/types.js'; import { type SetupAnswers, type SetupConfig } from '../setup/setup-compute.js'; import { type RoadmapStatus } from '../roadmap/paths.js'; import { type GhRunner } from '../roadmap/sync/gh.js'; import { type ReleasePreset } from '../autopilot/presets.js'; import { type AutopilotPicks, type InitWrites } from '../autopilot/questions.js'; import { type AutopilotConfig, type AutopilotPaths } from '../autopilot/state.js'; import { type TeamDefaults } from '../autopilot/team.js'; import { type HostPlan } from '../setup/host.js'; /** * The statuses to pre-check, or null when the project has no `roadmap.sync` section. * * The distinction between "section present with no `statuses`" and "no section" is the one * that matters, and it is not cosmetic. A section that omits `statuses` projects * `DEFAULT_STATUSES` today, so pre-checking all five instead would let somebody who pressed * Enter through an update silently start publishing their `inbox/` and `hold/` — the exact * retroactive widening the feature's design rules out by name. Full visibility is the * default *offered* to a project answering the question for the first time, not one applied * to a config whose author was never asked (issue-tracker-in-init/AC-15). */ export declare function existingSyncStatuses(existing: SetupConfig | null): string[] | null; /** * Turn a multi-select result into a list that is safe to write. * * Two jobs. It forces `done` on, because `validateStatuses` refuses a list without it and * the wizard must never write a config its own reader rejects — enforcing it here rather * than letting the user discover the refusal at `sync` time is the whole point. And it * orders the result by `ROADMAP_STATUSES`, so the written list reads in lifecycle order * whatever order the boxes were checked in. * * `done` is re-added rather than re-prompted deliberately. clack's multiselect has no * per-option lock, and a validation loop the user can only escape by cancelling — which * aborts the entire init — is a trap. The option's hint already says REQUIRED, so the * printed line confirms what the list claimed instead of surprising anybody * (issue-tracker-in-init/AC-7, AC-8, AC-9). */ export declare function normalizeSyncStatuses(chosen: readonly string[]): { ok: true; statuses: RoadmapStatus[]; doneReadded: boolean; } | { ok: false; error: string; }; /** * Probe `gh` once the user has said yes. Returns the warning to print, or null. * * The probe runs **after** the answer, never in front of the question. Gating the prompt * would make the wizard's contents depend on the machine it ran on, and the person who * initializes on a laptop with no `gh` and runs `sync` from CI is a normal case — * withholding the option from them is a worse failure than a warning they can read. * * So this never fails init. It returns text; the caller writes it to stderr, the section is * written anyway, and init exits 0. The config is not dangerous while `gh` is missing: sync * runs the same preflight and refuses at the moment it matters. A warning at init plus a * refusal at sync is two honest signals; a hidden prompt is none. * * Exported with an injected runner because `runInit` is not injectable, and the caller does * nothing with the result but print it (issue-tracker-in-init/AC-17 … AC-20). */ export declare function roadmapSyncPreflight(gh: GhRunner): string | null; /** * Everything `init` says about the roadmap projection after the config is written. * * Returns lines; the caller writes them to stderr. Extracted rather than inlined in * `runInit` because `runInit` is not injectable, and three criteria live entirely in the * decisions this function makes — that the probe runs only after a yes, that the preview * command is printed whether or not `gh` resolved, and that a dry run does neither. * * `gh` is a **factory**, not a runner, so a test can assert it was never called. "No probe * happened" is then a property of the call graph rather than of a mock's recorded argv: * a version that probed under `--dry-run` would construct the runner and fail * (issue-tracker-in-init/AC-17, AC-19 … AC-22). */ export declare function roadmapSyncReport(answer: readonly string[] | null | undefined, existing: SetupConfig | null, opts: { dryRun: boolean; gh: () => GhRunner; }): string[]; /** * The line to print when an explicit "no" removed a section that was there. * * Named rather than silent because removal discards `repo` and `label`, which the wizard * never asks about and could not restore (issue-tracker-in-init/AC-14). */ export declare function roadmapSyncRemovalNotice(existing: SetupConfig | null): string | null; /** * Platform choices offered by the interactive setup wizard. * * Exported so a test can assert it covers every registered adapter. A platform * that exists in the registry but not here is installable only via * `--platform `, which nobody discovers — that is how a supported platform * stays invisible (copilot-platform-support/AC-4). */ export declare const PLATFORM_OPTIONS: ReadonlyArray<{ value: PlatformId; label: string; hint: string; }>; /** * Collect answers interactively through the prompt seam. * * Exported and prompter-injectable so the whole five-question wizard can be * driven by a test double — both the answered path and the `no-tty` path — * without spawning a subprocess (single-clack-prompt-seam/AC-21). This is the * richest prompt path in the CLI: three selects, a multiselect, and the two * `initialValue` uses. * * Returns `null` for every no-answer outcome, as before: `runInit` has already * refused when there is no terminal, so the caller's contract is unchanged. */ export declare function collectInteractiveAnswers(existing: SetupConfig | null, prompt?: Prompter, hostPlan?: HostPlan): Promise; /** Where autopilot keeps this machine's state, and the answers already in force. */ export interface AutopilotContext { paths: AutopilotPaths; machine: AutopilotConfig | null; team: TeamDefaults; releases: ReleasePreset[]; } /** * Autopilot's side of init, resolved once. `ctx` is null outside a git repository, * and also when this machine's config is not valid JSON: init never offers to * rewrite a file it could not read, and says which file it was. */ export declare function autopilotContext(projectRoot: string): { ctx: AutopilotContext | null; warning?: string; }; /** * The interactive wizard: the project questions, then the "how work runs" step. * * Exported and prompter-injectable because `runInit` is not; this is the seam that * shows the step comes after every project question and that a cancel in it * cancels the whole init (init-sets-work-mode/AC-1, AC-11). */ export declare function collectInitAnswers(existing: SetupConfig | null, ap: AutopilotContext | null, autopilotFlag: boolean, prompt?: Prompter, hostPlan?: HostPlan): Promise<{ answers: SetupAnswers; picks?: AutopilotPicks; } | null>; /** * Where each saved autopilot answer went, naming both files (init-sets-work-mode/AC-19). * The agent's permissions are a per-machine choice, so the reader is shown that they * did not go anywhere a clone would pick them up. */ export declare function autopilotSummary(w: InitWrites, machineFile: string, teamFile: string): string[]; /** * The lifecycle hooks `init` installs, returning the lines to print * (hooks-carry-lifecycle-state/AC-17..AC-19). * * Claude Code gets the session-start hook with no question, beside the cost * hooks. Codex gets it only on an explicit yes, defaulting to no: Codex trusts a * hook by its hash and only the user's config can record that, so a declaration * nobody agreed to is one the user later finds and has to judge. Every path that * does not write it names the command that does. The phase guard is never * installed here (AC-14). * * Exported and prompter-injectable so both Codex branches run under test without * a terminal, as `collectInteractiveAnswers` is. */ export declare function installLifecycleHooksAtInit(projectRoot: string, platforms: string[], flags: { nonInteractive?: boolean; platform?: string; }, prompt?: Prompter, interactive?: boolean): Promise; /** * Register the `aidlc init` command (and its deprecated `setup` alias) * on the given commander program. */ export declare function registerInit(program: Command): void; //# sourceMappingURL=init.d.ts.map