export type Scope = 'user' | 'project' | 'builtin'; export declare const ExitCode: { readonly SUCCESS: 0; readonly GENERAL: 1; readonly USAGE: 2; readonly NOT_FOUND: 3; readonly AMBIGUOUS: 4; readonly NETWORK: 5; }; export type ExitCodeValue = (typeof ExitCode)[keyof typeof ExitCode]; export declare const SCHEMA_VERSION = 4; export interface OwnerRef { name?: string; email?: string; } export interface PluginManifest { name: string; version?: string; description?: string; source?: string; owner?: OwnerRef; kinds?: string[]; /** Plugin-root-relative path to one declarative command manifest * (`commands.json`). When present on an installed, enabled plugin, that * manifest contributes top-level command branches to the `crtr` tree — * crtr owns parse/help/render/errors and direct-spawns the plugin's one * executable per leaf invocation. See `src/core/command-plugins/`. */ commands?: string; } export interface MarketplacePluginEntry { name: string; source: string; version?: string; description?: string; keywords?: string[]; } export interface MarketplaceManifest { name: string; version?: string; owner?: OwnerRef; plugins: MarketplacePluginEntry[]; } export interface ConfigMarketplaceEntry { url: string; ref: string; installed_at: string; } export interface ConfigPluginEntry { enabled: boolean; source_marketplace?: string; version?: string; } export interface ConfigConfiguredCliEntry { endpoint: string; authEnvVar?: string; } export type AutoUpdateMode = 'notify' | 'apply' | false; export interface AutoUpdateConfig { crtr: AutoUpdateMode; content: AutoUpdateMode; interval_hours: number; } /** Host-wide broker pressure thresholds. These are read only from user scope * by crtrd: project configuration must not change another user's daemon. */ export interface BrokerThresholdsConfig { /** Surface a broker-pressure warning once the live broker census reaches this count. */ warning: number; /** Defer daemon-initiated revives once the live broker census reaches this count. */ automaticReviveCap: number; } export type KeybindingOverrides = Record; /** Compile-time seam for runtime consumers migrating to semantic binding IDs. */ export type CanvasAction = { kind?: 'crtr'; run: string; confirm?: boolean; } | { kind: 'keys'; keys: string; } | { kind: 'menu'; items: CanvasMenuItem[]; } | { kind: 'popup'; run: string; }; export interface CanvasMenuItem { key: string; desc: string; action: CanvasAction; confirm?: boolean; } export type ModelStrength = 'ultra' | 'strong' | 'medium' | 'light'; export type ModelProvider = 'anthropic' | 'openai'; export interface ModelLaddersConfig { /** Optional default provider for bare strengths. If unset, runtime falls back * to CRTR_MODEL_PROVIDER, then anthropic. */ defaultProvider?: ModelProvider; anthropic: Record; openai: Record; } /** Launch metadata for one kind (a top-level kind like `developer`, or a full * sub-kind string like `plan/reviewers/security`) — the settings-file * replacement for per-kind persona frontmatter. `model`/`tools`/`extensions` * are launch knobs consumed by `buildLaunchSpec` (Phase 3); `whenToUse` is the * one-line gloss shown in `node new -h` / `node promote -h`. `availableTo` is * VISIBILITY-ONLY (never launch validation): the list of top-level kind names * whose spawn menus surface this sub-kind, `'*'` meaning every kind; omitted * defaults to the sub-kind's own top-level ancestor (e.g. * `plan/reviewers/security` defaults to `['plan']`) — this reproduces the * original sub-persona `availableTo` semantics. A direct launch by full kind * string is always valid regardless of `availableTo`. */ export interface KindConfig { model?: string; /** Model override for ORCHESTRATOR mode only, e.g. a kind whose orchestrator * body warrants a stronger model than its base worker. Selection: base mode * always uses `model`; orchestrator mode uses `orchestratorModel ?? model`. * Omit when the kind runs the same model in both modes. */ orchestratorModel?: string; tools?: string[]; extensions?: string[]; whenToUse: string; availableTo?: string[]; } export interface ScopeConfig { schema_version: number; marketplaces: Record; plugins: Record; configuredClis: Record; auto_update: AutoUpdateConfig; max_panes_per_window: number; brokerThresholds: BrokerThresholdsConfig; /** Ring a short completion sound in the attach viewer when the node you are * watching finishes a turn and hands control back (the Claude-Code Stop-hook * ding). Only ever fires inside a live viewer pane — a headless/background * node with no viewer attached is silent regardless. Default true. */ completion_bell: boolean; /** How many trailing refresh-yield CYCLES the attach viewer renders at full * fidelity. Older cycles are condensed (cycle dividers plus whatever * `condensed_history` admits) and frozen into a flat line block: * no tool components are built for them, and they never re-wrap on resize. * Tool calls and results measure ~63% of a transcript's rendered lines and * ~69% of its build time, so this is the dominant cost of attaching to a long * multi-cycle node. Full detail for every cycle stays in the session file. * Minimum 1 (the live cycle is never condensed). Default 2. */ live_cycles: number; /** What survives from a CONDENSED cycle (one older than the trailing * `live_cycles`). The cycle dividers always remain as seams so you can see * that older cycles exist; this chooses which of their messages are kept: * `none` (default) drops every message, `user` keeps only your prompts, * `agent` keeps only the assistant's prose plus compaction/branch summaries, * `both` keeps both. Tool calls and results are never kept. Full detail for * every cycle stays in the session file. */ condensed_history: CondensedHistoryMode; keybindings: KeybindingOverrides; modelLadders: ModelLaddersConfig; /** The kind registry (spec §1.5): kind existence + launch knobs, keyed by * full kind string (top-level e.g. `developer`, or sub-kind e.g. * `plan/reviewers/security`). Builtins ship a default registry via * `defaultScopeConfig()`; user/project `config.json` adds or shadows * entries at the same scope precedence as the rest of `ScopeConfig`. */ kinds: Record; /** Named remote-canvas targets for `crtr surface attach to --canvas * `, `crtr node inspect list/show --canvas `, and `crtr canvas * browse --canvas ` — registered/managed via `crtr canvas config * add/list/show/remove` and selected durably via `crtr canvas use`. Unset * via `sys config set` — not in `TOP_LEVEL_KEYS`. */ remoteCanvas: RemoteCanvasConfig; /** Extra env-var names/globs a scope explicitly admits across the broker * spawn-env boundary (`buildBrokerEnv`, `core/runtime/spawn-env.ts`) — the * "I accept this crosses as a shell-visible credential" escape hatch for a * bespoke provider key, a deliberate `GIT_*` var, or a credentialed proxy. * Default empty; merged additively across project > profile > user > * builtin scope precedence, same as the rest of `ScopeConfig`. */ spawnEnv?: { allow?: string[]; }; } /** One remote canvas target: where to relay-attach and how to find its * bearer token. The token itself is NEVER stored here — only a ref into the * 0600 secrets store, resolved at connect time by `resolveRemoteCanvasTarget` * (`src/core/view/remote-canvas-target.ts`) via `getRelayToken` * (`src/core/secrets.ts`). */ export interface RemoteCanvasTarget { previewEndpoint: string; /** Name/ref under which the raw token is stored in secrets.json — NEVER the * token itself. Resolved via `getRelayToken` (`core/secrets.ts`) at connect * time. Defaults to the target name at creation but is a distinct field so * a future rename doesn't orphan the secret. */ relayTokenRef: string; cpOrigin?: string; } export interface RemoteCanvasConfig { targets: Record; } export interface ScopeState { marketplaces: Record; plugins: Record; last_self_check?: string; bootstrap_done?: boolean; /** The name of the remote canvas target `crtr canvas use` last selected * (see `RemoteCanvasConfig`), or `null`/omitted for local. Read by * `resolveCanvasSource` (`core/canvas/source.ts`) as the durable fallback * when a command's own `--canvas` flag is absent. */ activeCanvas?: string | null; } export interface SubagentFrontmatter { name: string; description?: string; /** Tool allow-list (pi tool names). Passed through to pi via `--tools`. */ tools?: string[]; /** Model pattern/id passed to the agent CLI via `--model`. */ model?: string; } export interface Subagent { name: string; /** Plugin the subagent belongs to, or the sentinel '_' for a scope-root * agent stored at `/agents/.md`. */ plugin: string; scope: Scope; /** Absolute path to the agent's .md file. */ path: string; frontmatter: SubagentFrontmatter; /** Markdown body — used as the spawned agent's appended system prompt. */ systemPrompt: string; } export interface InstalledPlugin { name: string; scope: Scope; root: string; manifest: PluginManifest; enabled: boolean; builtin?: boolean; sourceMarketplace?: string; version?: string; } export interface InstalledMarketplace { name: string; scope: Scope; root: string; manifest: MarketplaceManifest; url: string; ref: string; } /** The on-disk manifest at `~/.crouter/profiles/-/profile.json` * (spec §2.1). A profile is an agent identity defined at the user root: it * names N project directories and owns its own `memory/` store. `projects` * are absolute, real-path-resolved directories in manifest order — the * pointer set `findProjectScopeRoots` walks (Phase 5), after the node's own * cwd. `name` is the mutable display name (and the gateable `profile` subject * field, Phase 6); `-` in the directory name is the stable id and * never changes on rename. See `src/core/profiles/manifest.ts` for every * read/write of this file — it is the sole owner of path resolution and * mutation. */ export interface ProfileManifest { schema_version: number; name: string; projects: string[]; created_at: string; last_used_at: string | null; } export declare const PLUGIN_MANIFEST_DIR = ".crouter-plugin"; export declare const PLUGIN_MANIFEST_FILE = "plugin.json"; export declare const MARKETPLACE_MANIFEST_DIR = ".crouter-marketplace"; export declare const MARKETPLACE_MANIFEST_FILE = "marketplace.json"; export declare const CRTR_DIR_NAME = ".crouter"; export declare const CONFIG_FILE = "config.json"; export declare const STATE_FILE = "state.json"; export declare const AGENTS_DIR = "agents"; export declare const PROFILE_DIR = "profiles"; export declare const DEFAULT_MAX_PANES_PER_WINDOW = 3; /** Trailing cycles the attach viewer keeps at full fidelity (see `live_cycles`). */ export declare const DEFAULT_LIVE_CYCLES = 2; /** Messages kept from a condensed cycle (see `condensed_history`). */ export declare const CONDENSED_HISTORY_MODES: readonly ["none", "user", "agent", "both"]; export type CondensedHistoryMode = (typeof CONDENSED_HISTORY_MODES)[number]; export declare const DEFAULT_CONDENSED_HISTORY: CondensedHistoryMode; export declare function defaultScopeConfig(): ScopeConfig; /** No remote canvas targets are configured out of the box — every one is * registered via `crtr canvas config add` (see `RemoteCanvasConfig`). */ export declare function defaultRemoteCanvasConfig(): RemoteCanvasConfig; /** The builtin kind registry (spec §1.5): the built-in defaults for every * top-level kind and its sub-persona kinds. `whenToUse`/`model` are the * base-worker defaults; `orchestratorModel` optionally raises the default * for a coordinating persona. Roadmap-shaping guidance is orchestrator-only — * an orchestrator-gated memory doc keyed to the kind, not baked into the * registry entry. Sub-persona `availableTo` is * omitted where it only reproduces the default (its own top-level * ancestor) — `product/teardown` is included explicitly below for parity * even though its value equals the default. */ export declare function defaultKindsConfig(): Record; export declare function defaultModelLaddersConfig(): ModelLaddersConfig; export declare function defaultScopeState(): ScopeState;