import { deriveSlackConnectorSlug, ensureChannel, type ChannelKind, type EvePackageContract } from "#setup/scaffold/index.js";
import { detectPackageManager } from "#setup/package-manager.js";
import { runPackageManagerInstall } from "#setup/primitives/pm/run.js";
import { runVercel } from "#setup/primitives/run-vercel.js";
import { detectDeployment, type ProjectResolution } from "../project-resolution.js";
import { type Asker } from "../ask.js";
import type { Prompter } from "../prompter.js";
import { provisionSlackbot, reconcileSlackUid } from "../slackbot.js";
import { type SetupState } from "../state.js";
import { type SetupBox } from "../step.js";
/** Injected for tests; defaults to the real scaffold, Connect, and Vercel effects. */
export interface AddChannelsDeps {
    ensureChannel: typeof ensureChannel;
    deriveSlackConnectorSlug: typeof deriveSlackConnectorSlug;
    provisionSlackbot: typeof provisionSlackbot;
    reconcileSlackUid: typeof reconcileSlackUid;
    detectPackageManager: typeof detectPackageManager;
    runPackageManagerInstall: typeof runPackageManagerInstall;
    runVercel: typeof runVercel;
    detectDeployment: typeof detectDeployment;
}
export interface AddChannelsOptions {
    /** Resolves the slackbot question; the composed stack decides how. */
    asker: Asker;
    /**
     * Logs through `prompter.log` in `perform`, and owns the interactive
     * `vercel link` fallback. The slackbot question itself now travels the asker,
     * not this prompter.
     */
    prompter: Prompter;
    /**
     * Headless mode: gates the interactive `vercel link` fallback inside `perform`
     * and refuses Slack up front. Fixed at composition time (the same place the
     * asker base is chosen), since `gather` cannot read the mode off the asker.
     */
    headless?: boolean;
    /**
     * eve package metadata for the scaffolded web `package.json`. When omitted,
     * every package value comes from the build-stamped defaults.
     */
    evePackage?: EvePackageContract;
    /** Skip the "Create slackbot?" prompt and use this answer. */
    presetCreateSlackbot?: boolean;
    /** Overwrite existing channel files (`eve channels add --force`). */
    force?: boolean;
    /**
     * Override for the web scaffold's Vercel services config. Defaults to
     * `hasVercelProject(state)`; `eve channels add` pins it to true so an
     * unlinked directory still gets the config, matching the dissolved engine.
     */
    configureVercelServices?: boolean;
    /**
     * Opt-in fallback when Slack is chosen interactively but `state.project` is
     * unresolved: run the interactive bare `vercel link` before provisioning the
     * slackbot. Only the `eve channels add` composition sets this; onboarding
     * resolves the project up front via the link box and keeps the hard gate.
     */
    ensureLinkedProject?: "interactive-vercel-link";
    /**
     * What a failed slackbot provision (create or attach) does to the run. The
     * default, "abort", fails the whole box — right for `eve channels add slack`,
     * where Slack is the point. Onboarding passes "warn-and-continue": the agent
     * still scaffolds, deploys, and chats without Slack (recorded as nothing, so
     * a later `eve channels add slack` starts clean).
     */
    slackbotFailure?: "abort" | "warn-and-continue";
    deps?: AddChannelsDeps;
}
/**
 * What the user (or the preset) decided before `perform` runs effects.
 * `createSlackbot` is only consulted when Slack is in the channel selection.
 */
export interface AddChannelsInput {
    headless: boolean;
    createSlackbot: boolean | undefined;
}
/** Slackbot facts resolved by a successful Connect provision. */
export interface AddChannelsSlackbotFacts {
    connectorUid: string;
    /** Deep link that opens a DM compose with the bot ("chat with your agent"). */
    chatUrl?: string;
    workspaceName?: string;
}
/**
 * What `perform` actually did. `channelsAdded` lists the channels recorded this
 * run (web before slack); a skipped Web scaffold (Next.js detected) records
 * nothing, deliberately. `slackbot` is present only after a fresh, fully
 * attached provision; every failure mode either throws or (under
 * `slackbotFailure: "warn-and-continue"`) skips Slack entirely, so a failed
 * Slack setup records nothing (atomicity).
 */
export interface AddChannelsPayload {
    channelsAdded: ChannelKind[];
    webScaffolded: boolean;
    slackScaffolded: boolean;
    /**
     * Whether the post-scaffold dependency install succeeded. False both when no
     * channels were recorded (nothing ran) and when the install failed; only a
     * success lets `apply` mark the deploy-time install as already done.
     */
    dependenciesInstalled: boolean;
    project: ProjectResolution;
    slackbot?: AddChannelsSlackbotFacts;
}
/**
 * THE CHANNEL SCAFFOLD BOX. Scaffolds the channels chosen up front by the
 * select-channels box (`state.channelSelection`): writes the Web Chat files,
 * provisions the Slackbot through Vercel Connect, writes the Slack channel
 * definition, reconciles a Connect-assigned connector UID, and installs the
 * dependencies the scaffold added to `package.json` so a running `eve dev`
 * can load the new channel modules right away. The only prompt
 * (the slackbot question) travels the asker in `gather`; `perform` is promptless
 * and reads `state.project` directly, resolved earlier by the link box or the
 * in-project seed.
 */
export declare function addChannels(options: AddChannelsOptions): SetupBox<SetupState, AddChannelsInput, AddChannelsPayload>;
