/**
 * Project workspace probing — the drift signal behind `projects status`.
 *
 * Projects are natively multi-device: the same definition (home-relative paths)
 * re-roots on every fleet machine, and the question is whether the project's
 * repos are PRESENT on each box, on which branch, how far ahead/behind their
 * upstream, and whether they carry uncommitted changes. This module is the pure
 * local half: given a set of home-relative paths it probes each one with a
 * handful of read-only git calls. Drift is measured against the LAST-FETCHED
 * upstream (`@{upstream}`) — deliberately no `git fetch`, so a probe is fast
 * and offline-safe. The fleet half (`--fleet`) just runs this probe on every
 * peer via the canonical `remote-agents-json` SSH fan-out.
 */
import { type ProjectDef } from './projects.js';
/** The on-disk state of one workspace repo on one machine. */
export interface RepoWorkspaceStatus {
    /** The probed path, echoed home-relative (re-roots per machine). */
    path: string;
    /** `.git` exists (a directory, or a FILE for a linked worktree). */
    present: boolean;
    branch?: string;
    /** The configured upstream ref (e.g. `origin/main`); absent → no upstream. */
    upstream?: string;
    /** Commits on HEAD not on the upstream. Undefined without an upstream. */
    ahead?: number;
    /** Commits on the upstream not on HEAD. Undefined without an upstream. */
    behind?: number;
    /** Uncommitted (incl. untracked) paths from `git status --porcelain`. */
    dirty?: number;
    /** ISO 8601 committer date of HEAD. */
    lastCommit?: string;
    /** `.git` exists but git could not read it — never looks silently clean. */
    error?: string;
}
/** A probe result tagged with the machine that answered (the fleet view). */
export interface HostWorkspaceStatus extends RepoWorkspaceStatus {
    host: string;
}
/**
 * Probe one workspace repo. A missing path yields `{present: false}` and no
 * git call is made. On a present repo every signal is best-effort: whatever
 * succeeded is reported, and a repo whose `.git` exists yet every git call
 * failed surfaces as present-with-error rather than silently clean.
 */
export declare function probeRepoWorkspace(absPath: string): RepoWorkspaceStatus;
/** Probe each home-relative path (expanded against the local home), in order. */
export declare function probeProjectWorkspaces(paths: string[]): RepoWorkspaceStatus[];
/**
 * The home-relative paths to probe for a project definition: its `root` plus
 * each `repos[].path` (the opt-in for additional repos), deduped. Every target
 * is normalized through the same `toHomeRelative(expandLocalHome(...))` the
 * probe echoes, so a hand-edited def (absolute path under home, trailing
 * slash) matches its probe rows exactly — `writeProjectDef` normalizes on
 * write, but defs are hand-editable YAML and never silently drop a row.
 *
 * The walk itself lives in `projects.ts` so the probe and the spawn grants read
 * one definition of "the project's directories" instead of two that drift.
 */
export declare function workspaceTargetsForDef(def: ProjectDef): string[];
/**
 * Parse a peer's `projects probe` stdout, tagging each row with the
 * machine that answered. Defensive against version skew / partial output, the
 * same boundary contract as `parseRemoteActive`: non-JSON or a non-array
 * yields `[]`, and rows without a `path`/`present` core are dropped.
 */
export declare function parseRemoteProbe(stdout: string, machine: string): HostWorkspaceStatus[];
/**
 * One workspace's compact state: `✓ clean · main`, `⚠ 12 dirty · ↑3 ↓1 ·
 * feature/x`, `✗ missing`, or `⚠ error: …`. Pure — chalk styling only.
 */
export declare function formatWorkspaceLine(s: RepoWorkspaceStatus): string;
/**
 * The fleet view of one project's workspaces: one content line per probed
 * path (host-sorted `host: state` cells joined by ` · `), labelled with the
 * path when a project probes more than one. Pure — the caller adds the
 * `fleet` row label.
 */
export declare function formatFleetWorkspaces(statuses: HostWorkspaceStatus[]): string[];
/**
 * One-line fleet health summary — `6/13 clean · 4 behind · 4 dirty · 1 missing`.
 * Sits ABOVE the per-host {@link formatFleetWorkspaces} table so the card is
 * scannable without reading every host cell; the table keeps the per-host branch
 * and drift detail. Zero buckets are omitted. `behind` colours red when any host
 * is ≥10 behind (matching the footer's critical threshold), else yellow; a host
 * that is both behind and dirty counts in both. Each host×path row is one unit,
 * the same unit the table renders. Pure — chalk styling only.
 */
export declare function formatFleetSummary(statuses: HostWorkspaceStatus[]): string;
/** Severity for a workspace/repo warning on the project card. */
export type WorkspaceWarningSeverity = 'critical' | 'continue';
export interface WorkspaceWarning {
    severity: WorkspaceWarningSeverity;
    text: string;
    remediation?: string;
}
/**
 * Turn probed workspace rows into card-footer warnings, GROUPED by root cause so
 * a fleet where eight hosts drift is a few lines, not sixteen (each with its own
 * repeated remediation).
 *
 * - missing / unreadable git → critical (agents there cannot share a tree)
 * - behind upstream → critical when ANY host is ≥10 commits behind, else continue
 * - dirty tree → continue (local work is fine; just note it)
 * - ahead-only is not a warning (that is progress waiting to push)
 *
 * Within one probed path, all behind hosts collapse to one warning listing each
 * host with its count (`4 hosts behind origin/main — mac-mini ↓172, …`) plus one
 * shared remediation; a lone host keeps its full sentence. Missing and dirty
 * collapse the same way. `error` stays per-host (each message is distinct).
 * Grouping is per path so two different repos never merge into one count. Unlike
 * doctor's `emitGroup`, the list names EVERY host, not the first two — each
 * host's drift count differs and is individually actionable. Pure — chalk only.
 * Caller decides whether the rows came from `--fleet` or a local probe.
 */
export declare function workspaceWarnings(statuses: HostWorkspaceStatus[]): WorkspaceWarning[];
