/** * Read-only inventory of config a team already keeps at **CLI-native locations** * (`.claude/`, `.cursor/`, `.kiro/`, …) — the second dimension of `aih adopt` * (the first being the canonical `ai-coding/` shape in classify.ts). aih does NOT * own these formats and, per the owner's hard rule, NEVER auto-modifies them. This * module only LOOKS, so the user knows what exists and their AI agent has a map for * an opt-in migration. Root bootloaders (`CLAUDE.md`/`AGENTS.md`/`GEMINI.md`) are * intentionally excluded — those are classify.ts's job; reporting them here too * would double-count. * * Each artifact is classified by READING it (not by path), because a tool-native * file is often already a thin pointer to the canon (real example: * `ai-os-product/.cursorrules` and syntegris's `.claude/rules/*` bridge files): * * - `pointer` — references the canon (RULE_ROUTER / the context dir / * the shared marker) → already wired, leave alone. * - `tool-owned-content` — rich content with no canon reference → an *import * candidate* (syntegris `.claude/agents`, `.claude/memory`). * - `runtime-config` — settings/launch/hooks → tool runtime, not canon. */ export type CliArtifactKind = "pointer" | "tool-owned-content" | "runtime-config"; /** * The team-pollution sort (§13.6). Only `import` is ever a candidate / advisory: * - `wired` — references the canon (a pointer) → leave alone. * - `personal` — tool-owned but NOT committed (untracked/gitignored) → one dev's * style; shown for awareness, never nagged, never pulled into canon. * - `kept` — tool-owned + committed but team-ACKNOWLEDGED as intentional. * - `import` — tool-owned + committed + un-acknowledged → the only candidate. * - `runtime` — settings/launch/hooks → tool runtime, not canon. */ export type CliDisposition = "wired" | "personal" | "kept" | "import" | "runtime"; export interface CliArtifact { /** Tool that owns this location (e.g. "claude", "cursor"). */ cli: string; /** Repo-relative path (posix separators). */ path: string; /** Structural classification (pointer / content / runtime). */ kind: CliArtifactKind; /** The team-pollution sort that decides whether it's an import candidate. */ disposition: CliDisposition; /** Human detail for the footprint panel (counts / pointer-vs-content). */ detail: string; } /** Inputs that drive the idempotency guard — both read-only, both optional. */ export interface FootprintOptions { /** * Repo-relative paths git considers committed (from `gitCommittedSet`). Absent * (not a git repo / undetermined) → content is treated as shared, since we can't * prove it's a personal uncommitted file. */ committed?: ReadonlySet; /** Team-acknowledged tool-native paths (from `.aih-config.json` adopt.acknowledged). */ acknowledged?: ReadonlySet; } export interface CliFootprint { artifacts: CliArtifact[]; /** Count of `import`-disposition artifacts — the only true import candidates. */ importCandidates: number; } /** * Inventory the repo's CLI-native config. Pure / read-only. `contextDir` is the * committed one when present (callers pass the same value classify uses). `opts` * drives the team-pollution guard (§13.6): without `committed`, content is treated * as shared; with it, uncommitted tool-owned content is `personal` (silent) and * acknowledged paths are `kept` — so only NEW committed shared content is a candidate. */ export declare function cliFootprint(root: string, contextDir: string, opts?: FootprintOptions): CliFootprint;