/**
 * Repo Mesh Config — Local mesh configuration stored in ~/.adhdev/meshes.json
 *
 * Manages repo mesh definitions for OSS standalone mode.
 * Cloud mode syncs these to D1 via server routes; standalone mode
 * uses this file as the single source of truth.
 */
import type { LocalMeshEntry, LocalMeshNodeEntry, RepoMeshPolicy, RepoMeshNodePolicy, RepoMeshNodeCapabilities, RepoMeshCoordinatorConfig, RepoMeshHostMetadata, RepoMeshDaemonRole, MeshReportedMemberState } from '../repo-mesh-types.js';
import type { MagiKindPanelMap, MagiSlot, DifficultyBrainMap } from '@adhdev/mesh-shared';
/**
 * Migrate a node policy's legacy `providerRoles` cap onto `slots[].maxParallel`,
 * in place, then delete the `providerRoles` field. Defensive against malformed
 * entries. Returns true when the policy was mutated.
 *
 * Behavior-preserving: the resulting slots carry the same per-(node, provider)
 * cap the queue previously enforced from providerRoles. When the node had no
 * explicit slots, slots are derived from the legacy providerPriority (folding the
 * caps in via deriveSlotsFromLegacy-equivalent logic); when it did, each cap is
 * merged into the first matching-provider slot lacking a maxParallel.
 */
export declare function migrateProviderRolesToSlots(policy: unknown): boolean;
export declare function normalizeCapabilityTags(value: unknown): string[] | undefined;
/**
 * Normalize a Git remote URL into a stable identity string.
 * e.g. "git@github.com:user/repo.git" → "github.com/user/repo"
 *      "https://github.com/user/repo.git" → "github.com/user/repo"
 */
export declare function normalizeRepoIdentity(remoteUrl: string): string;
export declare function listMeshes(): LocalMeshEntry[];
export declare function getMesh(meshId: string): LocalMeshEntry | undefined;
export declare function getMeshByRepo(repoIdentity: string): LocalMeshEntry | undefined;
export interface CreateMeshOptions {
    name: string;
    repoRemoteUrl?: string;
    repoIdentity?: string;
    defaultBranch?: string;
    policy?: Partial<RepoMeshPolicy>;
    coordinator?: RepoMeshCoordinatorConfig;
    meshHost?: RepoMeshHostMetadata;
}
export declare function createMesh(opts: CreateMeshOptions): LocalMeshEntry;
export interface UpdateMeshOptions {
    name?: string;
    defaultBranch?: string;
    policy?: Partial<RepoMeshPolicy>;
    coordinator?: RepoMeshCoordinatorConfig;
    meshHost?: RepoMeshHostMetadata;
}
export declare function updateMesh(meshId: string, opts: UpdateMeshOptions): LocalMeshEntry | undefined;
export declare function deleteMesh(meshId: string): boolean;
export declare function tokenIdForManualPairing(token: string): string;
export interface ConfigureMeshHostPairingOptions {
    hostAddress: string;
    token: string;
    now?: string;
}
export declare function configureMeshHostPairing(meshId: string, opts: ConfigureMeshHostPairingOptions): {
    mesh: LocalMeshEntry;
    meshHost: RepoMeshHostMetadata;
    hostAddress: string;
} | undefined;
export interface CreateMeshHostPairingTokenOptions {
    token?: string;
    expiresAt?: string;
    now?: string;
}
export declare function createMeshHostPairingToken(meshId: string, opts?: CreateMeshHostPairingTokenOptions): {
    mesh: LocalMeshEntry;
    meshHost: RepoMeshHostMetadata;
    token: string;
    tokenId: string;
    expiresAt?: string;
} | undefined;
export interface MeshHostJoinMemberNodeInput {
    id?: string;
    workspace: string;
    repoRoot?: string;
    daemonId?: string;
    machineId?: string;
    userOverrides?: Partial<RepoMeshNodeCapabilities>;
    policy?: RepoMeshNodePolicy;
    role?: RepoMeshDaemonRole;
}
export interface ApplyMeshHostJoinOptions {
    token: string;
    memberNode: MeshHostJoinMemberNodeInput;
    memberMeshId?: string;
    now?: string;
}
export declare function applyMeshHostJoinRequest(meshId: string, opts: ApplyMeshHostJoinOptions): {
    accepted: true;
    mesh: LocalMeshEntry;
    meshHost: RepoMeshHostMetadata;
    node: LocalMeshNodeEntry;
    tokenId: string;
} | {
    accepted: false;
    mesh?: LocalMeshEntry;
    meshHost?: RepoMeshHostMetadata;
    tokenId?: string;
    reason: string;
} | undefined;
export declare function markMeshHostPairingJoined(meshId: string, opts: {
    hostDaemonId?: string;
    hostNodeId?: string;
    joinedAt?: string;
    token?: string;
    tokenId?: string;
}): {
    mesh: LocalMeshEntry;
    meshHost: RepoMeshHostMetadata;
} | undefined;
export interface AddNodeOptions {
    workspace: string;
    repoRoot?: string;
    daemonId?: string;
    machineId?: string;
    capabilities?: string[];
    userOverrides?: Partial<RepoMeshNodeCapabilities>;
    policy?: RepoMeshNodePolicy;
    isLocalWorktree?: boolean;
    worktreeBranch?: string;
    clonedFromNodeId?: string;
    worktreeBootstrap?: LocalMeshNodeEntry['worktreeBootstrap'];
    role?: RepoMeshDaemonRole;
    /** Owning daemon's machine nickname. Defaults to this daemon's local
     *  config.machineNickname when omitted — a node is always added by (and on)
     *  the daemon that owns its workspace (self/base node or a local worktree
     *  clone), so the local config is the correct source. */
    machineNickname?: string;
}
export declare function addNode(meshId: string, opts: AddNodeOptions): LocalMeshNodeEntry | undefined;
export declare function removeNode(meshId: string, nodeId: string): boolean;
export declare function updateNode(meshId: string, nodeId: string, opts: {
    userOverrides?: Partial<RepoMeshNodeCapabilities>;
    policy?: RepoMeshNodePolicy;
    /** Operator-defined custom capability tags used by mesh queue matching.
     *  Passing an array replaces the node's custom tags (empty/whitespace
     *  entries dropped, deduped); an empty result clears them. Omit to leave
     *  the existing tags untouched. */
    capabilities?: string[];
    worktreeBootstrap?: LocalMeshNodeEntry['worktreeBootstrap'];
    /** Per-node instruction surfaced in the coordinator prompt. Pass an
     *  empty string or undefined to clear it. */
    systemPrompt?: string;
    /** Live self-reported platform/arch from the owning daemon's git_status
     *  envelope. Persisted distinctly from userOverrides (auto-detected, not
     *  operator intent) so capability-tag os=/arch= self-heals across loads. */
    reportedPlatform?: string;
    reportedArch?: string;
    /** Owning daemon's self-reported machine nickname, carried on the
     *  git_status envelope. Persisted so the friendly label survives across
     *  coordinator restarts (mirrors reportedPlatform/reportedArch). */
    reportedMachineNickname?: string;
    /** Owning daemon's self-reported provider CLI/ACP versions + build version,
     *  carried on the git_status envelope. Persisted distinctly from userOverrides
     *  (auto-detected observability, not operator intent), mirroring the
     *  reportedPlatform/reportedArch self-heal so the value survives restarts and
     *  is overwritten by the next report. */
    reportedProviderVersions?: Record<string, string>;
    reportedDaemonBuildVersion?: string;
    /** Unified mirrored member state (per-machine runtime facts: provider versions
     *  + daemon build + lastReportedAt) self-reported by the owning daemon on the
     *  git_status envelope. Persisted wholesale so a remote node's version chips
     *  survive a coordinator restart, mirroring the per-field reported* self-heal.
     *  Slots are NOT carried — they are coordinator-owned config
     *  (REMOTE-NODE-SLOTS-COORDINATOR-LOCAL fix). */
    reportedMemberState?: MeshReportedMemberState;
}): LocalMeshNodeEntry | undefined;
/**
 * Validate + normalize a kind-panel's slots (the SOLE MAGI slot normalizer): provider
 * required per slot, trims strings, drops empties, clamps replica counts, and carries
 * an optional per-slot `model`. Throws on structurally invalid input (empty list / no
 * provider) so the write returns a clear error. Returns the normalized slot array.
 */
export declare function normalizeMagiSlots(slots: unknown): MagiSlot[];
/** All configured kind-panels (machine-local), keyed by task_kind. Empty when none. */
export declare function listMagiKindPanels(): MagiKindPanelMap;
/** The slot list for one task_kind, or undefined when the kind is not configured. */
export declare function getMagiKindPanel(kind: string): MagiSlot[] | undefined;
/**
 * Upsert the slot list for one task_kind. Unlike named panels this ALWAYS overwrites
 * (a kind has exactly one binding) — the editor pushes the full desired slot set.
 * Returns the normalized, persisted slots.
 */
export declare function setMagiKindPanel(kind: string, slots: unknown): MagiSlot[];
/** Remove the binding for one task_kind. Returns true when a binding was removed. */
export declare function removeMagiKindPanel(kind: string): boolean;
/**
 * The difficulty→brain presets, machine-local. When nothing is configured yet,
 * returns the sensible DEFAULT_DIFFICULTY_BRAINS so the coordinator always has a
 * usable mapping (the operator can override via setDifficultyBrains). Returns a
 * normalized copy — never the stored reference.
 */
export declare function getDifficultyBrains(): DifficultyBrainMap;
/**
 * Replace the difficulty→brain presets wholesale (the editor pushes the full map).
 * Passing an empty/normalized-empty map clears the override, so getDifficultyBrains
 * falls back to the defaults again. Returns the normalized, persisted map.
 */
export declare function setDifficultyBrains(map: unknown): DifficultyBrainMap;
