import { IKnowledgeStore } from "../../store/dist/index.js"; import { IEmbedder } from "../../embeddings/dist/index.js"; //#region packages/server/src/diagram/types.d.ts /** * Diagram Generation Core Types * * Types for the typed renderer pipeline: structured JSON → schema validation → HTML+SVG output. * Inspired by archify's 5-diagram-type system. */ /** Supported diagram types */ type DiagramType = 'architecture' | 'workflow' | 'sequence' | 'dataflow' | 'lifecycle'; /** Semantic component type for color assignment */ type ComponentType = 'frontend' | 'backend' | 'database' | 'cloud' | 'security' | 'messagebus' | 'external'; /** Edge/connection variant for visual distinction */ type EdgeVariant = 'default' | 'emphasis' | 'security' | 'dashed' | 'animated' | 'return'; /** Side from which an edge connects to a node */ type Side = 'top' | 'right' | 'bottom' | 'left'; /** Edge route mode */ type RouteMode = 'straight' | 'drop' | 'auto' | 'outside-right' | 'return-left' | 'bottom-channel' | 'up-channel' | 'vertical-channel' | 'top-channel' | 'right-channel' | 'left-channel'; /** Theme palette name */ type PaletteName = 'technical' | 'warm'; /** State type for lifecycle diagrams */ type StateType = 'start' | 'active' | 'waiting' | 'decision' | 'success' | 'failure' | 'neutral' | 'external'; /** Base metadata for all diagram types */ interface DiagramMeta { title: string; subtitle?: string; output?: string; viewBox?: [number, number]; palette?: PaletteName; } /** A position in 2D space */ interface Position { x: number; y: number; } /** A node/component in an architecture diagram */ interface ArchitectureComponent { id: string; type: ComponentType; label: string; sublabel?: string; pos: Position; size?: [number, number]; } /** A boundary group in an architecture diagram */ interface ArchitectureBoundary { kind: 'region' | 'security-group'; label: string; wraps: string[]; } /** A connection between architecture components */ interface Connection { from: string; to: string; label?: string; variant?: EdgeVariant; fromSide?: Side; toSide?: Side; route?: RouteMode; via?: Position[]; labelDx?: number; labelDy?: number; } /** Architecture diagram input */ interface ArchitectureDiagram { schema_version: number; diagram_type: 'architecture'; meta: DiagramMeta; components: ArchitectureComponent[]; boundaries?: ArchitectureBoundary[]; connections: Connection[]; cards?: DiagramCard[]; } /** Workflow lane */ interface WorkflowLane { id: string; label: string; } /** Workflow node */ interface WorkflowNode { id: string; lane: string; col: number; type: ComponentType; label: string; sublabel?: string; tag?: string; width?: number; height?: number; yOffset?: number; } /** Workflow edge */ interface WorkflowEdge { from: string; to: string; label?: string; variant?: EdgeVariant; fromSide?: Side; toSide?: Side; route?: RouteMode; bias?: number; channelX?: number; channelY?: number; via?: Position[]; labelDx?: number; labelDy?: number; labelSegment?: number; } /** Workflow diagram input */ interface WorkflowDiagram { schema_version: number; diagram_type: 'workflow'; meta: DiagramMeta; lanes: WorkflowLane[]; nodes: WorkflowNode[]; edges: WorkflowEdge[]; cards?: DiagramCard[]; } /** Sequence participant */ interface SequenceParticipant { id: string; type: ComponentType; label: string; sublabel?: string; } /** Sequence message */ interface SequenceMessage { from: string; to: string; y: number; label: string; variant?: EdgeVariant; note?: string; } /** Sequence time segment */ interface SequenceSegment { from: number; to: number; label: string; } /** Sequence activation bar */ interface SequenceActivation { participant: string; from: number; to: number; type: ComponentType; } /** Sequence diagram input */ interface SequenceDiagram { schema_version: number; diagram_type: 'sequence'; meta: DiagramMeta; participants: SequenceParticipant[]; messages: SequenceMessage[]; segments?: SequenceSegment[]; activations?: SequenceActivation[]; cards?: DiagramCard[]; } /** Data flow stage (column) */ interface DataFlowStage { label: string; } /** Data flow node */ interface DataFlowNode { id: string; type: ComponentType; label: string; stage: number; row: number; sublabel?: string; tag?: string; width?: number; height?: number; yOffset?: number; } /** Data flow edge */ interface DataFlowEdge { from: string; to: string; label: string; classification?: string; variant?: EdgeVariant; fromSide?: Side; toSide?: Side; route?: RouteMode; channelX?: number; channelY?: number; via?: Position[]; labelDx?: number; labelDy?: number; } /** Data flow diagram input */ interface DataFlowDiagram { schema_version: number; diagram_type: 'dataflow'; meta: DiagramMeta; stages: DataFlowStage[]; nodes: DataFlowNode[]; flows: DataFlowEdge[]; cards?: DiagramCard[]; } /** Lifecycle state */ interface LifecycleState { id: string; type: StateType; label: string; lane: string; col: number; step?: string; sublabel?: string; tag?: string; width?: number; height?: number; yOffset?: number; } /** Lifecycle transition */ interface LifecycleTransition { from: string; to: string; label?: string; note?: string; variant?: EdgeVariant; fromSide?: Side; toSide?: Side; route?: RouteMode; channelX?: number; channelY?: number; via?: Position[]; cornerRadius?: number; labelDx?: number; labelDy?: number; } /** Lifecycle/lane definition */ interface LifecycleLane { id: string; label: string; } /** Lifecycle diagram input */ interface LifecycleDiagram { schema_version: number; diagram_type: 'lifecycle'; meta: DiagramMeta; lanes: LifecycleLane[]; states: LifecycleState[]; transitions: LifecycleTransition[]; cards?: DiagramCard[]; } /** Summary card displayed below the diagram */ interface DiagramCard { dot: string; title: string; items: string[]; } /** Union type for all diagram inputs */ type DiagramInput = ArchitectureDiagram | WorkflowDiagram | SequenceDiagram | DataFlowDiagram | LifecycleDiagram; /** Rendered diagram output */ interface DiagramOutput { html: string; title: string; diagramType: DiagramType; filePath?: string; } //#endregion //#region packages/server/src/diagram/export.d.ts /** * Extract the SVG content from a rendered diagram HTML page. * Pure function — no IO, no browser needed. * * Returns the SVG element as a standalone string. * Returns null if the SVG marker is not found. */ declare function extractSvg(html: string): string | null; /** * Export a diagram to multiple formats on disk. * Writes HTML, SVG, and Markdown files side by side. * * @param html — Rendered HTML from diagram engine * @param markdown — Optional markdown representation * @param outputDir — Directory to write files into * @returns Object with paths to all written files */ declare function exportDiagram(html: string, markdown: string | undefined, outputDir: string): Promise<{ htmlPath: string; svgPath: string | null; mdPath: string | null; }>; //#endregion //#region packages/server/src/diagram/index.d.ts interface RenderOptions { title?: string; subtitle?: string; /** Generate both HTML and markdown (default: true) */ dualOutput?: boolean; /** Output directory for filesystem writes (used by renderDiagram) */ outputDir?: string; } /** Result of rendering — both strings, no IO */ interface RenderResult { html: string; markdown?: string; } /** * Render a diagram to HTML + optional markdown. * Pure function — no filesystem access. * Throws on validation failure or input limits exceeded. */ declare function renderToResult(input: DiagramInput, options?: RenderOptions): RenderResult; /** Render only HTML string (no markdown) */ declare function renderHtml(input: DiagramInput, options?: RenderOptions): string; /** Render only markdown string (no HTML) */ declare function renderMd(input: DiagramInput): string; /** Validate diagram input. Returns empty array on success, error messages on failure. */ declare function validate(input: DiagramInput): string[]; /** Sanitize a string for use as a filename */ declare function sanitizeTitle(title: string): string; //#endregion //#region packages/server/src/server-utils.d.ts declare function readVersion(): string; declare function getSessionIdHeader(req: import('express').Request): string | undefined; declare function readPositiveIntEnv(name: string, fallback: number): number; interface CorsOriginResolution { allowOrigin: string | null; warn: boolean; } interface ResolveCorsOriginOptions { requestOrigin: string | undefined; configuredOrigin: string | undefined; allowAnyOrigin: boolean; fallbackOrigin: string; } declare function resolveCorsOrigin({ requestOrigin, configuredOrigin, allowAnyOrigin, fallbackOrigin }: ResolveCorsOriginOptions): CorsOriginResolution; interface SlidingWindowRateLimiter { allow: (key: string, now?: number) => boolean; getRetryAfterMs: (key: string, now?: number) => number; } declare function createSlidingWindowRateLimiter({ limit, windowMs }: { limit: number; windowMs: number; }): SlidingWindowRateLimiter; //#endregion //#region packages/server/src/workspace-bootstrap.d.ts type WorkspaceLogger = { debug: (msg: string, data?: Record) => void; info: (msg: string, data?: Record) => void; warn: (msg: string, data?: Record) => void; error: (msg: string, data?: Record) => void; }; type WorkspaceRootConfig = { allRoots?: string[]; sources?: Array<{ path: string; }>; }; type WorkspaceRootApplyDeps = { config: Config; log: WorkspaceLogger; reconfigureForWorkspace: (config: Config, workspaceRoot: string) => void; roots: Array<{ uri: string; }>; }; type WorkspaceRootBootstrapDeps = { config: Config; indexMode: string; log: WorkspaceLogger; rootsChangedNotificationSchema: unknown; reconfigureForWorkspace: (config: Config, workspaceRoot: string) => void; runInitialIndex: () => Promise | undefined; server: { server: unknown; }; startInit: () => void; timeoutMs?: number; getCwd?: () => string; version?: string; }; declare function selectWorkspaceRoot({ config, roots }: Pick, 'config' | 'roots'>): string | null; declare function applyWorkspaceRoots({ config, log, reconfigureForWorkspace, roots }: WorkspaceRootApplyDeps): boolean; declare function bootstrapWorkspaceRoots({ config, indexMode, log, rootsChangedNotificationSchema, reconfigureForWorkspace, runInitialIndex, server, startInit, timeoutMs, getCwd, version }: WorkspaceRootBootstrapDeps): Promise; //#endregion //#region packages/server/src/curated-adapter.interface.d.ts /** * Abstraction for curated knowledge storage. * The default implementation uses the filesystem; alternative implementations * could use databases, cloud storage, or other backends. */ interface ICuratedAdapter { /** One-time initialization (e.g. ensure base directory exists). */ initialize(): Promise; /** * Read a file by its relative path (e.g. "decisions/my-entry.md"). * Returns the raw file content, or null if the file does not exist. */ read(relativePath: string): Promise; /** * Write content to a relative path. Creates parent directories as needed. * @param options.exclusive If true, fail if the file already exists. */ write(relativePath: string, content: string, options?: { exclusive?: boolean; }): Promise; /** * Delete a file by relative path. Returns true if the file existed, false otherwise. */ delete(relativePath: string): Promise; /** * List entries, optionally filtered by a category prefix. * Returns objects with the relative path, file size in bytes, and optional * filesystem modification timestamp. */ list(categoryPrefix?: string): Promise>; /** * Check whether a path exists. */ exists(relativePath: string): Promise; /** * List subdirectories in the base directory. * Returns directory names only (not full paths). */ listDirectories(): Promise; /** Clean up any resources. */ close(): Promise; } //#endregion //#region packages/server/src/curated-manager.d.ts type CuratedCategory = string; interface CuratedEntry { path: string; title: string; category: string; tags: string[]; version: number; created: string; updated: string; contentPreview: string; } interface CuratedListFilters { category?: CuratedCategory; tag?: string; limit?: number; offset?: number; orderBy?: 'path' | 'created' | 'updated'; order?: 'asc' | 'desc'; } interface CuratedListPage { entries: CuratedEntry[]; totalCount: number; totalCountIsExact: boolean; limit: number | null; offset: number; hasMore: boolean; } interface CuratedFrontmatter { title: string; category: string; tags: string[]; created: string; updated: string; version: number; origin: 'curated'; changelog: Array<{ version: number; date: string; reason: string; }>; } type DeterministicCuratedWriteResult = { path: string; status: 'created' | 'updated' | 'unchanged'; version: number; }; /** * Manages curated knowledge files — the LLM's persistent memory. * Files are stored as markdown in a .ai/curated/ directory with YAML frontmatter. */ declare class CuratedKnowledgeManager { readonly curatedDir: string; private readonly store; private readonly embedder; private readonly adapter; constructor(curatedDir: string, store: IKnowledgeStore, embedder: IEmbedder, adapter?: ICuratedAdapter); remember(title: string, content: string, category: CuratedCategory, tags?: string[]): Promise<{ path: string; }>; upsertAutoKnowledge(relativePath: string, title: string, content: string, category: CuratedCategory, tags?: string[], reason?: string): Promise; update(relativePath: string, newContent: string, reason: string): Promise<{ path: string; version: number; }>; forget(relativePath: string, _reason: string): Promise<{ path: string; }>; /** * Get the git commit history for a curated knowledge entry. * Returns commits from newest to oldest. */ history(relativePath: string, limit?: number): Promise>; /** * Get the diff between two versions of a curated knowledge entry. * If only toSha provided, shows that version's full content. * If both fromSha and toSha, shows unified diff between them. */ diff(relativePath: string, fromSha?: string, toSha?: string): Promise; /** * Recover a curated knowledge entry from git when the filesystem copy is missing. * Reads the latest committed version from the git ref and writes it back to the filesystem + vector store. * Returns null if no git ref exists for this path. */ recover(relativePath: string): Promise<{ path: string; version: number; } | null>; /** * Find git refs that have no corresponding filesystem file (orphaned refs). * These are entries that were deleted from filesystem but still have git history. * Useful for discovering recoverable entries. */ listOrphaned(): Promise>; read(relativePath: string): Promise; list(filters?: CuratedListFilters): Promise; listPage(filters?: CuratedListFilters): Promise; count(filters?: { category?: CuratedCategory; tag?: string; }): Promise; listPaths(filters?: { category?: CuratedCategory; limit?: number; offset?: number; }): Promise; private sortCandidateMetadata; private readCandidateEntries; /** * Re-index all curated files into the vector store. * Call this after the indexer has run to restore curated vectors * that may have been lost, or to bulk-sync disk state to vectors. */ reindexAll(): Promise<{ indexed: number; errors: string[]; }>; /** * Embed and upsert a batch of curated items. On embedder failure, recursively * retries with halved sub-batches to recover from worker-exit / oversized-batch * errors. Upsert failures are reported directly without recursive retry. * Returns the number of successfully indexed items. */ private embedAndUpsertBatch; /** * Commit curated knowledge content to a git orphan ref. * Fires after successful filesystem write — never blocks or throws on failure. */ private gitCommitKnowledge; /** * Delete the git ref for a curated knowledge entry. * Called after successful filesystem deletion. */ private gitDeleteKnowledgeRef; private knowledgeRefForPath; private indexCuratedFile; private indexCuratedFileBestEffort; private discoverCategories; /** * Normalize and validate a relative path within .ai/curated/. * Returns the cleaned path (mutates nothing — caller must use the return value). */ private guardPath; private validateCategoryName; private validateContentSize; private slugify; private normalizeTags; private sameTags; private ensureCategoryPath; /** Return a unique `category/slug.md` path, appending `-2`, `-3`, … on collision. */ private uniqueRelativePath; private hash; private hashId; /** * Simple YAML frontmatter serializer (no gray-matter dependency). */ private serializeFile; /** * Simple YAML frontmatter parser (no gray-matter dependency). */ parseFile(raw: string): { frontmatter: CuratedFrontmatter; content: string; }; } //#endregion //#region packages/server/src/index.d.ts declare function main(): Promise; //#endregion export { CuratedKnowledgeManager, type DiagramInput, type DiagramOutput, type DiagramType, applyWorkspaceRoots, bootstrapWorkspaceRoots, createSlidingWindowRateLimiter, exportDiagram, extractSvg, getSessionIdHeader, main, readPositiveIntEnv, readVersion, renderHtml, renderMd, renderToResult, resolveCorsOrigin, sanitizeTitle, selectWorkspaceRoot, validate };