/** * Shared prefer-sverklo instructions written to CLAUDE.md, AGENTS.md, * and .github/copilot-instructions.md. Single source of truth — divergence * across agents would silently desync guidance. */ export declare const SVERKLO_SNIPPET = "\n## Sverklo \u2014 Code Intelligence\n\nThis project has the sverklo MCP server installed. Sverklo is a code-intelligence index: ranked search, dependency graph, persistent memory. Use it as the **default** tool for code discovery in this repo.\n\n### Always Do\n\n- **MUST call `overview` before exploring an unfamiliar directory.** It returns the PageRank-ranked map of the codebase in one call \u2014 much cheaper than `ls` + `Read` loops.\n- **MUST use `search` instead of Grep for any query that is conceptual or fuzzy** (\"how does auth work\", \"anything related to billing\", \"where do we handle retries\"). Grep is for exact strings only.\n- **MUST use `lookup` to find a symbol's definition** by name \u2014 never grep + Read for this.\n- **MUST run `impact` before renaming, deleting, or changing the signature of any function/class/method** that may be called from elsewhere. Report the blast radius (callers, depth) to the user before editing.\n- **MUST use `refs` to enumerate callers of a symbol.**\n- **MUST use `deps` to see imports + importers of a file** before moving or splitting it.\n- **MUST call `remember` when the user corrects you** with phrasing like \"stop X\", \"never X\", \"always Y\", \"don't Y\", \"prefer Z\", \"remember that I want Q\", \"actually, do W\". Save with `category:correction` (stop/never/don't) or `category:preference` (prefer/want/like), `kind:semantic`, and the user's instruction as content. Save before continuing the response. Do not ask permission \u2014 corrections are explicit instructions to persist behavior across sessions.\n- **MUST call `recall` at the start of work** on a non-trivial task to surface prior decisions and corrections.\n\n### Never Do\n\n- **NEVER use Grep when the query is conceptual.** Grep cannot find \"the auth flow\" \u2014 sverklo's `search` can.\n- **NEVER edit a function or class without first running `impact`** on it. Silently breaking a caller is the most expensive bug this codebase produces.\n- **NEVER ignore HIGH or CRITICAL impact warnings** without surfacing them to the user.\n- **NEVER rename symbols with find-and-replace.** Use `refs` first; it knows which \"foo\" is the function and which is a string.\n- **NEVER save routine task summaries to memory.** `recall` is only useful when hits are signal-dense \u2014 save only (a) bugs that took >1h to debug, (b) recurring mistakes, (c) non-obvious architectural decisions, (d) audit findings needing user judgment.\n- **NEVER re-read a file sverklo just returned a path for.** Use `lookup` for the specific symbol instead.\n\n### When Grep / Read still wins\n\n| Task | Tool |\n|---|---|\n| Exact string match (`\"TODO(alice)\"`, error message text) | Grep |\n| Read a known file at a known path | Read |\n| Inspect a specific line range | Read with offset/limit |\n\n### Exploration order\n\n`overview` (1 call) \u2192 `search` (1 call) \u2192 `lookup` on the top hit \u2192 `refs` / `impact` only if you need the blast radius. If you've made 5 sverklo calls and still don't have the answer, **stop and ask a clarifying question** \u2014 don't burn 10 more.\n\n### Output discipline\n\nNo preambles (\"Here are the results\", \"Great question\"), no closing affirmations, no em-dashes as conversational pauses. State the finding, show the fix, stop. User instructions override this file.\n"; /** * Finding 6: case-insensitive lookup for instruction files in the * project root. Linux is case-sensitive, so a user with `Agents.md` * (Codex's lowercase convention) wouldn't match `existsSync("AGENTS.md")`. * On macOS/Windows the underlying FS is case-insensitive but we still * want to report the user's actual filename so messages match what * they see in their editor. */ export declare function findInstructionFile(projectPath: string, baseName: string): { exists: boolean; content: string; path: string; }; export interface AgentsFileInputs { projectPath: string; claudeMd: { exists: boolean; content: string; path: string; }; agentsMd: { exists: boolean; content: string; path: string; }; sentinel: string; } export type AgentsFileAction = { action: "skip"; fileName: string; path: string; } | { action: "append"; fileName: string; path: string; existingContent: string; note?: string; } | { action: "create-claude-md"; fileName: "CLAUDE.md"; path: string; }; /** * Decide which agent-instructions file to write the prefer-sverklo * snippet into. Issue #19 (RuslanZavacky): respect AGENTS.md when it * exists, especially when CLAUDE.md is a redirect-only file. * * Rules (in order): * 1. If either file already contains the snippet (literal sentinel * OR `## Sverklo` heading), skip — idempotent. * 2. AGENTS.md is preferred IF it has real content, OR CLAUDE.md * is missing/empty. An empty placeholder AGENTS.md (Finding 12) * shouldn't beat a populated CLAUDE.md. * 3. Else if CLAUDE.md exists, append to it. * 4. Else create CLAUDE.md (don't auto-create AGENTS.md — too * opinionated; we only modify files the user has opted into). */ export declare function resolveAgentsFileTarget(inputs: AgentsFileInputs): AgentsFileAction; export interface CopilotInstructionsInputs { projectPath: string; copilotFile: { exists: boolean; content: string; path: string; }; githubDirExists: boolean; vscodeDirExists: boolean; copilotExtensionDetected: boolean; sentinel: string; } export type CopilotInstructionsAction = { action: "skip-no-signal"; } | { action: "skip-already-present"; path: string; } | { action: "append"; path: string; existingContent: string; } | { action: "create"; path: string; }; /** * Decide whether to write `.github/copilot-instructions.md` and how. * * Copilot reads this file as a preamble appended to every Chat prompt * (per github.com/copilot docs, custom-instructions). Without it, even * with sverklo's MCP server wired up, Copilot keeps grep-ing because * nothing tells it to prefer sverklo's tools. * * Signals (any one is enough — Copilot has no project-level marker file): * - `.github/copilot-instructions.md` already exists (definite — append/skip) * - `.github/` dir exists (project uses GitHub conventions) * - `.vscode/` dir exists (VS Code is THE Copilot host) * - `~/.vscode/extensions/github.copilot*` present (Copilot installed) * * If none of those, skip silently — don't create `.github/` or * `.vscode/` for projects that have nothing to do with either. Match * resolveAgentsFileTarget's "we only modify files the user has opted * into" philosophy. */ export declare function resolveCopilotInstructionsTarget(inputs: CopilotInstructionsInputs): CopilotInstructionsAction; /** * Best-effort scan for the GitHub Copilot VS Code extension. Returns * true if any directory under ~/.vscode/extensions/ or * ~/.vscode-insiders/extensions/ matches `github.copilot*`. Silent on * failure (unreadable home, no extensions dir) — never throws. */ export declare function detectCopilotExtension(): boolean; export type CodexMergeResult = { status: "added"; next: string; } | { status: "updated"; next: string; previousProject: string | null; } | { status: "already"; next: string; }; export declare function mergeCodexToml(currentSrc: string, sverkloBin: string, projectPath: string): CodexMergeResult; export type CopilotMergeResult = { status: "added"; next: string; } | { status: "updated"; next: string; previousProject: string | null; } | { status: "already"; next: string; }; export declare function mergeCopilotJson(currentSrc: string | null, sverkloBin: string, projectPath: string): CopilotMergeResult; export interface InitDryRunOptions { autoCapture?: boolean; mineChats?: boolean; } export declare function renderInitDryRun(projectPath: string, options?: InitDryRunOptions): string; export declare function initProject(projectPath: string, options?: { autoCapture?: boolean; mineChats?: boolean; }): Promise;