/** * Workspace discovery + framework detection for `clustly deploy`. * * Design: docs/designs/clustly-cli.md §2 step 2 and build-plan slice 2.2. Discovery is a strict * fallback chain: explicit path → walk-up from cwd (the git model — standing inside a workspace * is authoritative) → the OpenClaw registry (~/.openclaw/openclaw.json `agents.list[].workspace` * + the implicit default workspace) → a bounded shallow scan. The caller confirms the resolved * path before bundling (interactively; in --ci the unambiguous result or explicit path is the * consent — see wizard.ts). */ export type Framework = "openclaw" | "hermes" | "node" | "python"; export type CandidateSource = "explicit" | "cwd" | "walk-up" | "registry" | "scan"; export interface WorkspaceCandidate { path: string; framework: Framework; source: CandidateSource; /** OpenClaw agent id when the candidate came from the registry. */ agentId?: string; } /** OpenClaw's on-disk layout (spike recon 2026-07-28). Shared with inventory.ts — a contract. */ export declare const OPENCLAW_HOME_DIR = ".openclaw"; export declare const OPENCLAW_CONFIG_FILE = "openclaw.json"; export declare const OPENCLAW_DEFAULT_WORKSPACE_DIR = "workspace"; /** * Detect the agent framework of a directory from its marker files. Priority: agent frameworks * (openclaw, hermes) over generic runtimes (node, python) — a workspace with both AGENTS.md and * package.json is an OpenClaw workspace that happens to contain node code. */ export declare function detectFramework(dir: string): Framework | undefined; /** * The cwd ITSELF as a workspace — no walk-up, no registry, no scan. This is the only discovery * a non-interactive run may use without an explicit path: a `--ci` deploy launched from the * wrong directory once walked up to an unrelated parent `package.json`, confirmed nothing * (there is nobody to confirm), and wrote a `clustly.yaml` into someone else's project * (2026-08-22 report). Without a human at the prompt, "where you stand" is the only consent. */ export declare function cwdWorkspace(cwd: string): WorkspaceCandidate | undefined; /** Walk up from `from` to the filesystem root, returning the first framework-marked directory. */ export declare function walkUp(from: string): WorkspaceCandidate | undefined; /** * Read the OpenClaw registry under `home`: every `agents.list[].workspace` plus the implicit * default workspace at ~/.openclaw/workspace. Non-throwing — a missing or corrupt install just * yields no candidates. */ export declare function readOpenClawRegistry(home: string): WorkspaceCandidate[]; /** * Bounded breadth-first scan for agent-framework workspaces (openclaw/hermes only — flagging * every package.json under $HOME would be noise). Skips dot-directories and SCAN_SKIP names. */ export declare function shallowScan(roots: string[], depth?: number): WorkspaceCandidate[]; export interface DiscoverOptions { cwd: string; home: string; /** `clustly deploy ` — bypasses discovery, still framework-checked. */ explicitPath?: string; /** Scan roots (defaults to [home]); injectable for tests. */ scanRoots?: string[]; } /** * The discovery pipeline (design §2 step 2) — a strict fallback chain, each source consulted * only when the previous one missed: explicit path → walk-up (standing inside a workspace is * authoritative, like git — other registered agents must not turn it into a picker or a --ci * ambiguity failure) → registry → scan. */ export declare function discoverWorkspaces(opts: DiscoverOptions): WorkspaceCandidate[];