UNPKG

socraticode

Version:

SocratiCode — MCP server for local codebase indexing, semantic search, and code dependency graphs. All private, all local via Docker.

159 lines • 7.58 kB
/** * Context Artifacts — give the AI awareness of non-code project knowledge. * * Users define artifacts (database schemas, API specs, infra configs, etc.) * in a `.socraticodecontextartifacts.json` file at the project root. Each artifact points to * a file or directory with a name and description. * * Artifacts are chunked and embedded into Qdrant (collection: context_{projectId}) * for semantic search, using the same hybrid dense + BM25 approach as code search. * * Staleness detection: each artifact's content hash is stored. When a search is * performed, stale artifacts are automatically re-indexed (artifacts are typically * small, so re-indexing takes seconds). */ import type { ArtifactIndexState, ContextArtifact, SearchResult } from "../types.js"; import { type EffectiveIndexProfile } from "./index-profile.js"; export interface SocratiCodeConfig { artifacts?: ContextArtifact[]; } /** * Load and validate .socraticodecontextartifacts.json from a project root. * Returns null if the file doesn't exist. Throws on parse/validation errors. */ export declare function loadConfig(projectPath: string): Promise<SocratiCodeConfig | null>; /** * Files a directory walk left out, by reason. All zero for a single-file artifact. * * These count what the walk *found* and then rejected. `node_modules` and `.git` * are pruned by glob before the walk yields anything, so they appear in no * counter — see the note on that `ignore` option for why the prune is worth * keeping. */ export interface ArtifactExclusions { /** Rejected by the ignore chain. Excludes the glob-pruned trees above. */ ignored: number; /** Rejected by {@link isBinaryContent}. */ binary: number; /** Read threw — permissions, a dangling symlink, deleted mid-walk. */ unreadable: number; } /** One artifact's content, as {@link readArtifactContent} produced it. */ export interface ArtifactContent { content: string; contentHash: string; exclusions: Readonly<ArtifactExclusions>; } /** * Read the content of an artifact. If the path points to a directory, * concatenates all files within it (recursively), separated by headers. * Returns the combined content, a content hash for staleness detection, and * the count of files left out. * * A directory walk excludes three classes of file, each logged per-file at * debug: * 1. Anything the ignore chain rejects — built-in defaults + `.gitignore` + * `.socraticodeignore`, the same chain the code indexer uses. * 2. Binary content, per {@link isBinaryContent}. * 3. Files that fail to read at all (permissions, races). * Dot-files and dot-directories are never walked (`dot: false` below). * * The summary is returned rather than logged here, because this function also * serves the staleness check that runs on every search — logging it here would * repeat the same line per search instead of reporting it once per index. * {@link indexArtifact} logs it at info. * * A single-file artifact is read verbatim and gets none of this: a declared * path is an explicit instruction, and silently skipping it would replace one * silent failure with another. * * Exclusion happens here, inside the function that also computes the hash, so * the indexed content and the staleness hash cannot diverge. */ export declare function readArtifactContent(artifactPath: string, projectPath: string): Promise<ArtifactContent>; interface ArtifactChunk { id: string; content: string; startLine: number; endLine: number; artifactName: string; } /** * Chunk artifact content using line-based chunking with overlap. * Simple and universal — works for SQL, YAML, Protobuf, Markdown, etc. * * Chunks are cut by line count and then held to a cap counted in characters, * so a window of CHUNK_SIZE lines can exceed it. The overflow is split off into * further chunks rather than dropped: it used to be truncated away, which took * it out of the vector, the payload and the BM25 text alike, and artifacts are * exactly the kind of content that overflows — SQL, YAML and Markdown all run * well past MAX_CHUNK_CHARS / CHUNK_SIZE characters per line. */ export declare function chunkArtifactContent(content: string, artifactName: string, artifactPath: string, maxChunkChars?: number, indexFormatVersion?: number): ArtifactChunk[]; /** Hash the artifact settings that affect embedded text or stored payloads. */ export declare function artifactConfigurationSignature(projectPath: string, artifact: ContextArtifact): string; /** * Index a single artifact into Qdrant. * Generates replacement embeddings before removing the existing chunks. * * `preread` lets a caller that has *already* read the artifact hand the result * over instead of paying for a second full read. {@link ensureArtifactsIndexed} * reads every artifact to compute its staleness hash, and re-reading here would * walk the directory and re-read every file a second time — by far the largest * cost on that path. Passing the content through also closes the window between * the two reads, so what gets indexed is exactly what was hashed. */ export declare function indexArtifact(projectPath: string, artifact: ContextArtifact, collection: string, preread?: ArtifactContent, suppliedProfile?: EffectiveIndexProfile): Promise<ArtifactIndexState>; /** Whether this process is writing context artifacts for the project. */ export declare function isContextIndexingInProgress(projectPath: string): boolean; export declare function getContextIndexingInProgressProjects(): string[]; /** Index all artifacts defined in .socraticodecontextartifacts.json. */ export declare function indexAllArtifacts(projectPath: string): ReturnType<typeof indexAllArtifactsUnguarded>; /** Re-index only the artifacts whose content or configuration changed. */ export declare function ensureArtifactsIndexed(projectPath: string, projectId?: string): ReturnType<typeof ensureArtifactsIndexedUnguarded>; /** * Index all artifacts defined in .socraticodecontextartifacts.json. * Returns the list of indexed artifact states. */ declare function indexAllArtifactsUnguarded(projectPath: string): Promise<{ indexed: ArtifactIndexState[]; errors: Array<{ name: string; error: string; }>; }>; /** * Ensure all artifacts are indexed and up to date. * Compares content hashes to detect staleness and only re-indexes changed artifacts. * Returns true if any re-indexing occurred. */ declare function ensureArtifactsIndexedUnguarded(projectPath: string, projectId: string): Promise<{ reindexed: string[]; upToDate: string[]; errors: Array<{ name: string; error: string; }>; }>; /** * Search across context artifacts using hybrid semantic + BM25 search. * Optionally filter by artifact name. */ export declare function searchArtifacts(projectPath: string, query: string, artifactName?: string, limit?: number): Promise<SearchResult[]>; /** * Remove all context artifacts for a project. */ export declare function removeAllArtifacts(projectPath: string): Promise<void>; /** * Get a compact artifact status summary for a project. * Returns null if no .socraticodecontextartifacts.json exists. * This is the canonical helper for integrating artifact status into other commands. */ export declare function getArtifactStatusSummary(projectPath: string): Promise<{ configuredCount: number; indexedCount: number; totalChunks: number; lines: string[]; } | null>; export {}; //# sourceMappingURL=context-artifacts.d.ts.map