import type { ThinkingLevel } from "@oh-my-pi/pi-agent-core"; import type { ExtensionModule } from "../capability/extension-module"; import { type Rule } from "../capability/rule"; import type { Skill } from "../capability/skill"; import type { LoadContext, LoadResult, SourceMeta } from "../capability/types"; /** * Standard paths for each config source. */ export declare const SOURCE_PATHS: { readonly native: { readonly userBase: string; readonly userAgent: string; projectDir: string; }; readonly claude: { readonly userBase: ".claude"; readonly userAgent: ".claude"; readonly projectDir: ".claude"; }; readonly codex: { readonly userBase: ".codex"; readonly userAgent: ".codex"; readonly projectDir: ".codex"; }; readonly gemini: { readonly userBase: ".gemini"; readonly userAgent: ".gemini"; readonly projectDir: ".gemini"; }; readonly opencode: { readonly userBase: ".config/opencode"; readonly userAgent: ".config/opencode"; readonly projectDir: ".opencode"; }; readonly cursor: { readonly userBase: ".cursor"; readonly userAgent: ".cursor"; readonly projectDir: ".cursor"; }; readonly windsurf: { readonly userBase: ".codeium/windsurf"; readonly userAgent: ".codeium/windsurf"; readonly projectDir: ".windsurf"; }; readonly cline: { readonly userBase: ".cline"; readonly userAgent: ".cline"; readonly projectDir: null; }; readonly github: { readonly userBase: null; readonly userAgent: null; readonly projectDir: ".github"; }; readonly vscode: { readonly userBase: ".vscode"; readonly userAgent: ".vscode"; readonly projectDir: ".vscode"; }; }; export type SourceId = keyof typeof SOURCE_PATHS; /** * Get user-level path for a source. */ export declare function getUserPath(ctx: LoadContext, source: SourceId, subpath: string): string | null; /** * Get project-level path for a source (cwd only). */ export declare function getProjectPath(ctx: LoadContext, source: SourceId, subpath: string): string | null; /** * Create source metadata for an item. */ export declare function createSourceMeta(provider: string, filePath: string, level: "user" | "project"): SourceMeta; export declare function parseBoolean(value: unknown): boolean | undefined; /** * Parse a comma-separated string into an array of trimmed, non-empty strings. */ export declare function parseCSV(value: string): string[]; /** * Parse a value that may be an array of strings or a comma-separated string. * Returns undefined if the result would be empty. */ export declare function parseArrayOrCSV(value: unknown): string[] | undefined; /** * Build a canonical rule item from a markdown/markdown-frontmatter document. */ export declare function buildRuleFromMarkdown(name: string, content: string, filePath: string, source: SourceMeta, options?: { ruleName?: string; stripNamePattern?: RegExp; }): Rule; /** * Parse model field into a prioritized list. */ export declare function parseModelList(value: unknown): string[] | undefined; /** Parsed agent fields from frontmatter (excludes source/filePath/systemPrompt) */ export interface ParsedAgentFields { name: string; description: string; tools?: string[]; spawns?: string[] | "*"; model?: string[]; output?: unknown; thinkingLevel?: ThinkingLevel; blocking?: boolean; } /** * Parse agent fields from frontmatter. * Returns null if required fields (name, description) are missing. */ export declare function parseAgentFields(frontmatter: Record): ParsedAgentFields | null; export interface ScanSkillsFromDirOptions { dir: string; providerId: string; level: "user" | "project"; requireDescription?: boolean; } export declare function compareSkillOrder(aName: string, aPath: string, bName: string, bPath: string): number; export declare function scanSkillsFromDir(_ctx: LoadContext, options: ScanSkillsFromDirOptions): Promise>; /** * Recursively expand environment variables in an object. */ export declare function expandEnvVarsDeep(obj: T, extraEnv?: Record): T; /** * Load files from a directory matching extensions. * Uses native glob for fast filesystem scanning with gitignore support. */ export declare function loadFilesFromDir(_ctx: LoadContext, dir: string, provider: string, level: "user" | "project", options: { /** File extensions to match (without dot) */ extensions?: string[]; /** Transform file to item (return null to skip) */ transform: (name: string, content: string, path: string, source: SourceMeta) => T | null; /** Whether to recurse into subdirectories (default: false) */ recursive?: boolean; }): Promise>; /** * Calculate depth of target directory relative to current working directory. * Depth is the number of directory levels from cwd to target. * - Positive depth: target is above cwd (parent/ancestor) * - Zero depth: target is cwd * - This uses path splitting to count directory levels */ export declare function calculateDepth(cwd: string, targetDir: string, separator: string): number; /** * Discover extension module entry points in a directory. * * Discovery rules: * 1. Direct files: `extensions/*.ts` or `*.js` → load * 2. Subdirectory with index: `extensions//index.ts` or `index.js` → load * 3. Subdirectory with package.json: `extensions//package.json` with "omp"/"pi" field → load declared paths * * No recursion beyond one level. Complex packages must use package.json manifest. * Uses native glob for fast filesystem scanning with gitignore support. */ export declare function discoverExtensionModulePaths(_ctx: LoadContext, dir: string): Promise; /** * Derive a stable extension name from a path. */ export declare function getExtensionNameFromPath(extensionPath: string): string; /** * Build ExtensionModule items from discovered user/project paths. * Shared across providers that expose extension modules via user + project dirs. */ export declare function buildExtensionModuleItems(providerId: string, userPaths: string[], projectPaths: string[]): ExtensionModule[]; /** * Entry for an installed Claude Code plugin. */ export interface ClaudePluginEntry { scope: "user" | "project"; installPath: string; version: string; installedAt: string; lastUpdated: string; gitCommitSha?: string; enabled?: boolean; } /** * Claude Code installed_plugins.json registry format. */ export interface ClaudePluginsRegistry { version: number; plugins: Record; } /** * Resolved plugin root for loading. */ export interface ClaudePluginRoot { /** Plugin ID (e.g., "simpleclaude-core@simpleclaude") */ id: string; /** Marketplace name */ marketplace: string; /** Plugin name */ plugin: string; /** Version string */ version: string; /** Absolute path to plugin root */ path: string; /** Whether this is a user or project scope plugin */ scope: "user" | "project"; } /** * Parse Claude Code installed_plugins.json content. */ export declare function parseClaudePluginsRegistry(content: string): ClaudePluginsRegistry | null; /** * Resolve the active project registry path by walking up from `cwd`. * * Walk order: * 1. Walk up from `cwd` looking for the nearest directory containing `.omp/`. * The first match returns `/.omp/plugins/installed_plugins.json`. * 2. If no `.omp/` is found, rescan from `cwd` upward looking for `.git`. * The git root is used as an anchor: `/.omp/plugins/installed_plugins.json`. * 3. If neither is found, return `null` — no project context is active. * * This is the single source of truth for "active project root" used by install, * uninstall, list, upgrade, discovery, and doctor. Deterministic for a given `cwd`. */ export declare function resolveActiveProjectRegistryPath(cwd: string): Promise; /** * Like resolveActiveProjectRegistryPath, but falls back to `/.omp/plugins/installed_plugins.json` * when no project anchor (.omp/ or .git/) is found. * * Use this when the caller accepts an explicit --scope project so that installing into a freshly * bootstrapped directory (no .omp/ or .git/ yet) works: writeInstalledPluginsRegistry auto-creates * the directory tree on first write. * * Returns undefined when cwd is os.homedir() — that path is already the user registry and must * never alias as the project registry. */ export declare function resolveOrDefaultProjectRegistryPath(cwd: string): Promise; /** * List all installed Claude Code plugin roots from the plugin cache. * Reads ~/.claude/plugins/installed_plugins.json and ~/.omp/plugins/installed_plugins.json, * and optionally the nearest project-scoped registry resolved from `cwd`. * * Results are cached per `home:resolvedProjectPath` key to avoid repeated parsing. */ export declare function listClaudePluginRoots(home: string, cwd?: string): Promise<{ roots: ClaudePluginRoot[]; warnings: string[]; }>; /** * Clear the plugin roots cache (useful for testing or when plugins change). */ export declare function clearClaudePluginRootsCache(): void; /** * Invalidate fs caches for installed-plugin registry files and reset the * in-memory plugin roots cache. Used by MarketplaceManager clients after * installing/uninstalling/enabling/disabling plugins. */ export declare function clearPluginRootsAndCaches(extraPaths?: readonly string[]): void; /** * Populate the module-level plugin roots cache for sync consumers. * Call during session initialization, after dir resolution completes * but before any LSP config is read. */ export declare function preloadPluginRoots(home: string, cwd?: string): Promise; /** * Get pre-loaded plugin roots synchronously. * Returns empty array if preloadPluginRoots() hasn't been called. */ export declare function getPreloadedPluginRoots(): readonly ClaudePluginRoot[]; /** * Inject synthetic plugin roots from --plugin-dir paths. * These are prepended to the cache with highest precedence (before OMP/Claude entries). * Must be called before any listClaudePluginRoots() access. */ export declare function injectPluginDirRoots(home: string, dirs: string[], cwd?: string): Promise;