import { z } from "zod"; import type { McpTool } from "../tool.js"; declare const inputSchema: z.ZodObject<{ /** * Repo source. Either: * - Local path (relative or absolute) → walk in place. * - Git URL (https://host/path[.git], git@host:path, ssh://...) * → shallow-clone to a tmpdir, walk, cleanup. Requires `git` * on PATH. * Detection is by isGitUrl(); when ambiguous (e.g. a path that * happens to look like a URL), local-path interpretation wins. */ path: z.ZodString; /** Project slug. Optional — defaults to the sentinel "default" project, * the same Phase 1D-friendly fallback that ingest_content uses. */ project: z.ZodDefault; tags: z.ZodDefault>; /** * Branch / ref to clone. Only honored for git-URL inputs. Default * = the repo's HEAD (whatever the remote points at). */ branch: z.ZodOptional; /** * Per-clone timeout in milliseconds. Aborts a slow clone. Default * 5 minutes — generous for a shallow clone of a typical repo; * pathological repos with binary blobs in history get killed. */ cloneTimeoutMs: z.ZodDefault; /** * Run in the background and return a jobId immediately. Default * true (the safe default — even small repos can exceed the MCP * transport timeout once embeddings + enrichment land, and the * client polls `kb_job_status({ jobId })` for progress + the * eventual result). Set false ONLY when the caller knows the repo * is small (under ~50 files) and wants the result inline; the sync * shape is kept for that and for backward-compat with older callers. */ async: z.ZodDefault; /** * Per-file size cap. Files larger than this get skipped (recorded in * `errors`). Default 256 KiB — enough for almost any source file, * small enough to keep huge generated artifacts (lockfiles, minified * bundles, fixtures) from blowing the chunk budget. */ maxFileBytes: z.ZodDefault; /** * Hard cap on the total number of files visited per call. Prevents a * runaway recursion through node_modules-shaped trees. Default 2000. */ maxFiles: z.ZodDefault; /** * Override the default ignore set when present. Otherwise the defaults * (node_modules, .git, dist, build, .next, .turbo, target, etc.) apply. */ ignoreDirs: z.ZodOptional>; /** * Ingest mode. Picks which pipeline(s) the repo is fed through: * * - 'dossier' (default): the new 3-pass code-dossier pipeline * (structural → synthesis → brief). Produces a small set of * high-signal memories that describe the repo (brief, decisions, * references). Matches the user intent "ingest this repo should * give me knowledge ABOUT the code, not the entire codebase". * * - 'full': legacy per-file walk. Every readable source file * becomes one or more chunks in engram. High-volume, low-signal — * useful when you actually want byte-level grep across the repo. * * - 'both': dossier first (so high-signal memories are queryable * fast), then full (bulk index in the background). Source_id * prefixes differ so the two memory sets don't collide. * * Default flipped to 'dossier' in 0.6 — the "knowledge ABOUT" intent * is the right default for "I just connected a repo, what is it?" * The dashboard's mode toggle (Slice D) makes 'full' / 'both' a * one-click override. */ mode: z.ZodDefault>; /** * SHA-gated re-derivation. When true (default) and mode includes * 'dossier', the handler computes a SHA over the dossier inputs * (file tree + project + tags + sourceUrl) and skips the run when * the prior dossier's stored SHA matches. Set false to force a * re-run — useful when the pipeline itself was updated and you * want fresh memories even though the inputs didn't change. * * Has no effect on mode='full' (no SHA gate for the bulk index). */ skipIfUnchanged: z.ZodDefault; }, "strip", z.ZodTypeAny, { project: string; path: string; mode: "dossier" | "full" | "both"; tags: string[]; async: boolean; cloneTimeoutMs: number; maxFileBytes: number; maxFiles: number; skipIfUnchanged: boolean; branch?: string | undefined; ignoreDirs?: string[] | undefined; }, { path: string; project?: string | undefined; mode?: "dossier" | "full" | "both" | undefined; tags?: string[] | undefined; async?: boolean | undefined; branch?: string | undefined; cloneTimeoutMs?: number | undefined; maxFileBytes?: number | undefined; maxFiles?: number | undefined; ignoreDirs?: string[] | undefined; skipIfUnchanged?: boolean | undefined; }>; interface FileResult { source_id: string; ingested: number; bytes: number; type: string; } interface Output { /** Which mode the call ran. Echoed back so the renderer can pick its * card / progress style without re-reading the request. */ mode: "dossier" | "full" | "both"; /** Resolved local path the walk ran against. For git-URL inputs this * is the tmpdir clone destination (already cleaned up by the time * the result is returned). Empty when the SHA gate skipped the run. */ resolvedPath: string; /** True when the input was detected as a git URL and shallow-cloned. */ cloned: boolean; /** When cloned: the URL that was cloned. Useful for the renderer's * "ingested github.com/foo/bar" display. */ source?: string; /** Number of source files that produced at least one chunk. Populated * by the full-walk path only. */ filesIngested: number; /** Sum of chunks across every file. Populated by the full-walk path. */ chunksIngested: number; /** Files visited but skipped (oversize, unreadable, unsupported extension). */ filesSkipped: number; filesByType: Record; totalBytes: number; /** Per-file partial results — capped at 50 entries to keep payloads sane. */ files: FileResult[]; /** Per-file errors — capped at 50 entries. */ errors: Array<{ source_id: string; error: string; }>; /** True when the walk stopped because maxFiles was hit. */ truncated: boolean; /** * Memory counts by category. `brief` / `decisions` / `references` are * populated by the dossier path; `chunks` by the full path. mode='both' * fills all four when the SHA gate didn't fire. */ memories: { brief?: number; decisions?: number; references?: number; chunks?: number; }; /** Set when the SHA gate matched and the dossier run was skipped. * mode='full' never sets this. */ skipped?: boolean; /** Why the run was skipped — present only when `skipped` is true. */ skipReason?: string; /** Job id that produced the prior dossier — surfaced on a SHA hit * so callers can fetch the prior result without searching. */ priorJobId?: string; } /** * Detect a git remote URL. Recognized shapes: * - https?://... (any host; shallow-clones via HTTPS) * - git@host:owner/repo[.git] (SSH) * - ssh://git@host[:port]/... (SSH) * - git://host/... (unauthenticated, rare) * * A bare github.com URL without scheme would be ambiguous — it could * be a path. We require an explicit scheme or `git@` prefix to avoid * misclassifying a local path that happens to contain "github.com". */ export declare function isGitUrl(input: string): boolean; /** * Run `git clone --depth=1 [--branch ] `. Caller is * responsible for the tmpdir lifecycle. Throws on non-zero exit, on * timeout, or when `git` isn't on PATH. */ export declare function shallowClone(args: { url: string; dest: string; branch?: string; timeoutMs: number; }): Promise; /** * Walk a local repo OR shallow-clone a git URL and walk the result. * * For git URLs the clone lands in an OS tmpdir (mkdtemp prefix * `cortex-ingest-repo-`) and is rm -rf'd in the finally block, so a * crash mid-walk never leaks the working tree. * * The walk is breadth-first on directories. Default ignore set prunes * common build/output dirs. `maxFiles` is a hard ceiling that aborts * the walk when hit (recorded in `truncated`). */ export declare const ingestRepo: McpTool; export {}; //# sourceMappingURL=ingest-repo.d.ts.map