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
TypeScript
/**
* 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