/** * Layered `team-mode` configuration — the FILE READER + runtime wiring * (package ②, 2026-10-06). * * Package ① (`config-layers.ts`) is the PURE layer: it takes raw JSONC text * and returns the merged view. This module is the IO half — it LOCATES and * READS the two file layers, then hands the merged JSON values to * `resolveConfig` (the registry-driven validator). * * Two layers only, low→high: `全局 < 项目`. There is NO session layer and * NO env layer (the host's own config has none either — * `opencode.ai/v2/docs/config`). * * The project layer MIRRORS the host's layering semantics: search from the * current directory up to the filesystem root; merge the DIRECT files * farthest→closest, then the `.opencode/` files in the same order, and every * `.opencode/` file overrides every direct file. Within each group the * ancestor files are merged (closer wins) into ONE text so the pure layer's * two project slots (`project` / `project:.opencode`) keep their meaning. * * `envOnly` is an explicit parameter (test injection) — it removes every file * layer BEFORE any read, so the escape valve costs zero IO. * * Every root is INJECTABLE (`ConfigFileRoots`) so tests point at a temp dir * and never touch the user's real `~/.config/opencode`. */ import { type EnvLike, type LayeredConfigResult } from "./config-layers.js"; import { type TmConfig } from "./config.js"; import type { AutoCreateState } from "./config-template.js"; /** The file name both layers use. */ export declare const CONFIG_FILE_NAME = "team-mode.jsonc"; export interface ConfigFileRoots { /** Directory holding the GLOBAL file (default `~/.config/opencode`). */ globalDir?: string; /** Directory the PROJECT search starts from (default `process.cwd()`). */ projectDir?: string; /** Home dir used to derive the default global dir (default `os.homedir()`). */ home?: string; } export interface ConfigFileRead { /** The resolved global dir (whether or not the file exists). */ globalDir: string; /** Global file raw JSONC, or null when it does not exist / is unreadable. */ globalLayer: string | null; /** Absolute path of the global file when it was read. */ globalPath: string | null; /** Project layers low→high: `[direct-merged, .opencode-merged]`. */ projectLayer: Array; /** Every project file that was read, in the order they were merged. */ projectPaths: string[]; /** The `.opencode/` subset of `projectPaths` (for the report). */ opencodePaths: string[]; /** Files dropped WHOLE because they failed to parse (never half-applied). */ skipped: Array<{ name: string; reason: string; }>; } /** * The resolved global config dir. The host's global config dir is * `~/.config/opencode`, overridable by `OPENCODE_CONFIG_DIR` — the global * `team-mode.jsonc` lives beside the host's own global config, so honor the * same override (and it keeps a test that redirects OPENCODE_CONFIG_DIR * hermetic). `OPENCODE_CONFIG_DIR` is the host's own variable, not ours. */ export declare function resolveGlobalDir(roots?: ConfigFileRoots, env?: EnvLike): string; /** Locate and read both file layers. Pure IO — no globals beyond the * injected roots. */ export declare function readConfigFiles(roots?: ConfigFileRoots, env?: EnvLike): ConfigFileRead; export interface LayeredTmConfig { /** The resolved runtime config (file values folded in). */ cfg: TmConfig; /** The pure layer's full view — sources, red-line ignores, unknown keys. */ layered: LayeredConfigResult; /** What the reader actually found on disk. */ files: ConfigFileRead; } export interface ResolveLayeredTmConfigOptions { /** Remove every file layer (test injection). */ envOnly?: boolean; /** Lowest-priority default overrides (BELOW the file layers). v2 uses it to * default `webfetchAllowedDomains` to `["*"]` when no file sets it. The * auto-created global file is INERT (every key commented), so it sets * nothing and never shadows these; a user-edited file still wins. */ configDefaults?: Record; /** Env used only for `OPENCODE_CONFIG_DIR` (the host's own variable). */ env?: EnvLike; } /** * Resolve the runtime config through the layered pipeline: read the files * (unless `envOnly`), merge with the pure resolver, then hand the merged JSON * values (plus any `configDefaults`) to `resolveConfig`. The returned * `layered`/`files` are what `tm_stats` renders so the user can see WHERE * each key came from. */ export declare function resolveLayeredTmConfig(roots?: ConfigFileRoots, opts?: ResolveLayeredTmConfigOptions): LayeredTmConfig; /** * The `tm_stats` config section. Renders the per-key source, the red-line * keys a PROJECT file tried to set, the unknown keys (warned, never applied), * the env-only flag and the auto-create outcome — the facts that make "which * layer won" checkable. `autoCreate` is the state the boot row recorded * (`ensureGlobalConfig`); omitted only by a caller that never ran it. */ export declare function renderConfigSection(layered: LayeredConfigResult, files: ConfigFileRead, autoCreate?: AutoCreateState): string; //# sourceMappingURL=config-files.d.ts.map