/** * Core type definitions for openlore */ export type ProjectType = 'nodejs' | 'python' | 'rust' | 'go' | 'java' | 'ruby' | 'php' | 'unknown'; export interface OpenLoreConfig { version: string; projectType: ProjectType; openspecPath: string; analysis: AnalysisConfig; generation: GenerationConfig; llm?: LLMConfig; embedding?: EmbeddingConfig; createdAt: string; lastRun: string | null; } export interface EmbeddingConfig { /** Base URL of the OpenAI-compatible embeddings endpoint */ baseUrl: string; /** Embedding model name */ model: string; /** API key — optional for local servers */ apiKey?: string; /** Maximum number of texts per embedding batch (default: 64) */ batchSize?: number; /** Disable SSL certificate verification (e.g. self-signed certs on local servers) */ skipSslVerify?: boolean; } export interface AnalysisConfig { maxFiles: number; includePatterns: string[]; excludePatterns: string[]; } export interface GenerationConfig { provider?: 'anthropic' | 'openai' | 'openai-compat' | 'copilot' | 'gemini' | 'claude-code' | 'mistral-vibe' | 'gemini-cli' | 'cursor-agent'; model?: string; openaiCompatBaseUrl?: string; skipSslVerify?: boolean; /** Disable response_format field in requests (for endpoints that don't support structured output) */ disableResponseFormat?: boolean; /** LLM request timeout in milliseconds. Default: 120000 (2 minutes) */ timeout?: number; /** Max characters per file chunk sent to the LLM. Default: 8000. Increase for large-context models. */ chunkMaxChars?: number; domains: string | string[]; } export interface LLMConfig { /** Custom API base URL for OpenAI-compatible servers */ apiBase?: string; /** Whether to verify SSL certificates (default: true) */ sslVerify?: boolean; } export interface FileMetadata { path: string; absolutePath: string; name: string; extension: string; size: number; lines: number; depth: number; directory: string; isEntryPoint: boolean; isConfig: boolean; isTest: boolean; isGenerated: boolean; } export interface ScoredFile extends FileMetadata { score: number; scoreBreakdown: { name: number; path: number; structure: number; connectivity: number; }; tags: string[]; } export interface FileWalkerResult { files: FileMetadata[]; summary: { totalFiles: number; totalDirectories: number; byExtension: Record; byDirectory: Record; skippedCount: number; skippedReasons: Record; }; rootPath: string; timestamp: string; } export interface GlobalOptions { quiet: boolean; verbose: boolean; noColor: boolean; config: string; } export interface InitOptions extends GlobalOptions { force: boolean; openspecPath: string; } export interface AnalyzeOptions extends GlobalOptions { output: string; maxFiles: number; include: string[]; exclude: string[]; } export interface GenerateOptions extends GlobalOptions { analysis: string; model: string; dryRun: boolean; domains: string[]; adr: boolean; adrOnly: boolean; force?: boolean; } export interface VerifyOptions extends GlobalOptions { samples: number; threshold: number; } export interface AnalysisResult { repositoryMap: RepositoryMap; dependencyGraph: DependencyGraph; summary: AnalysisSummary; timestamp: string; } export interface RepositoryMap { root: string; files: ScoredFile[]; directories: DirectoryInfo[]; projectType: ProjectType; } export interface DirectoryInfo { path: string; fileCount: number; purpose: string; } export interface DependencyGraph { nodes: DependencyNode[]; edges: DependencyEdge[]; } export interface DependencyNode { id: string; path: string; type: 'file' | 'module' | 'package'; } export interface DependencyEdge { from: string; to: string; type: 'import' | 'export' | 'extends' | 'implements'; } export interface AnalysisSummary { totalFiles: number; analyzedFiles: number; skippedFiles: number; detectedDomains: string[]; entryPoints: string[]; confidence: number; } export interface OpenSpecDomain { name: string; path: string; requirements: OpenSpecRequirement[]; entities: OpenSpecEntity[]; sourceFiles: string[]; confidence: number; } export interface OpenSpecRequirement { name: string; description: string; keyword: 'SHALL' | 'MUST' | 'SHOULD' | 'MAY'; scenarios: OpenSpecScenario[]; } export interface OpenSpecScenario { name: string; given: string; when: string; then: string; and?: string[]; } export interface OpenSpecEntity { name: string; properties: EntityProperty[]; sourceFile: string; } export interface EntityProperty { name: string; type: string; description: string; required: boolean; } export type DriftSeverity = 'error' | 'warning' | 'info'; export type DriftIssueKind = 'gap' | 'stale' | 'uncovered' | 'orphaned-spec' | 'adr-gap' | 'adr-orphaned' | 'memory-drifted' | 'memory-orphaned'; export interface DriftOptions extends GlobalOptions { base: string; files: string[]; domains: string[]; useLlm: boolean; json: boolean; installHook: boolean; uninstallHook: boolean; failOn: DriftSeverity; maxFiles: number; suggestTests: boolean; } export interface DriftIssue { id: string; kind: DriftIssueKind; severity: DriftSeverity; message: string; filePath: string; domain: string | null; specPath: string | null; changedLines?: { added: number; removed: number; }; suggestion: string; } export interface DriftResult { timestamp: string; baseRef: string; totalChangedFiles: number; specRelevantFiles: number; issues: DriftIssue[]; summary: { gaps: number; stale: number; uncovered: number; orphanedSpecs: number; adrGaps: number; adrOrphaned: number; memoryDrifted: number; memoryOrphaned: number; total: number; }; hasDrift: boolean; duration: number; mode: 'static' | 'llm-enhanced'; } export interface ChangedFile { path: string; status: 'added' | 'modified' | 'deleted' | 'renamed'; oldPath?: string; additions: number; deletions: number; isTest: boolean; isConfig: boolean; isGenerated: boolean; extension: string; } export interface SpecMapping { domain: string; specPath: string; declaredSourceFiles: string[]; inferredSourceFiles: string[]; allSourceFiles: string[]; requirements: string[]; entities: string[]; } export interface SpecMap { byDomain: Map; byFile: Map; domainCount: number; totalMappedFiles: number; } export interface SpecSnapshotDomain { name: string; specFile: string; sourceFiles: string[]; requirementCount: number; mappedFunctionCount: number; coveragePct: number; specModifiedAt: string; sourcesModifiedAt: string; } export interface SpecSnapshotHub { name: string; file: string; fanIn: number; covered: boolean; } export interface SpecSnapshot { version: '1'; generatedAt: string; git: { commit: string; branch: string; dirty: boolean; }; coverage: { totalFunctions: number; coveredFunctions: number; orphanFunctions: number; coveragePct: number; }; domains: SpecSnapshotDomain[]; hubs: SpecSnapshotHub[]; } export interface AuditUncoveredFunction { name: string; file: string; kind: string; fanIn: number; fanOut: number; isHub: boolean; } export interface AuditOrphanRequirement { requirement: string; domain: string; specFile: string; } export interface AuditStaleDomain { name: string; specFile: string; specModifiedAt: string; sourcesModifiedAt: string; staleSince: string; } export interface AuditReport { generatedAt: string; summary: { totalFunctions: number; coveredFunctions: number; coveragePct: number; uncoveredCount: number; hubGapCount: number; orphanRequirementCount: number; staleDomainCount: number; }; uncoveredFunctions: AuditUncoveredFunction[]; hubGaps: AuditUncoveredFunction[]; orphanRequirements: AuditOrphanRequirement[]; staleDomains: AuditStaleDomain[]; } export type DecisionScope = 'local' | 'component' | 'cross-domain' | 'system'; export type DecisionStatus = 'draft' | 'consolidated' | 'verified' | 'phantom' | 'approved' | 'rejected' | 'synced'; /** A single architectural decision recorded during a dev session. */ export interface PendingDecision { /** Stable 8-char ID: sha1(sessionId:domain:title).slice(0,8) */ id: string; status: DecisionStatus; title: string; rationale: string; consequences: string; proposedRequirement: string | null; affectedDomains: string[]; affectedFiles: string[]; /** * Structural anchors binding this decision to the code it describes, resolved * deterministically against the call graph at record time. Optional and * additive: legacy decisions recorded before anchoring fall back to file-level * freshness derived from `affectedFiles`. See {@link StructuralAnchor}. */ anchors?: StructuralAnchor[]; /** ID of a prior decision this one supersedes (agent signals a reversal) */ supersedes?: string; sessionId: string; recordedAt: string; consolidatedAt?: string; verifiedAt?: string; scope?: DecisionScope; confidence: 'high' | 'medium' | 'low'; evidenceFile?: string; reviewedAt?: string; reviewNote?: string; syncedAt?: string; syncedToSpecs: string[]; } /** Persistent store written to .openlore/decisions/pending.json */ export interface DecisionStore { version: '1'; /** Cleared when a new session starts (new commit cycle) */ sessionId: string; updatedAt: string; /** * Monotonic write counter for atomic compare-and-swap on save * (change: harden-memory-integrity-invariant). Additive — defaults to 0 for * legacy stores written before this field existed. */ sequence?: number; /** Set after consolidation runs — gate uses this to skip no_decisions_recorded warning */ lastConsolidatedAt?: string; decisions: PendingDecision[]; } /** * A structural anchor binds a persisted memory to the code it describes so that * the memory can self-invalidate deterministically when that code changes or * dies. Resolution and freshness use only static analysis — no LLM. * * - Symbol-level anchor: `nodeId` + `symbolName` set, `contentHash` is the hash * of the function's source span captured at record time. * - File-level anchor: only `filePath` set (with optional `contentHash` = the * file's content hash at record time). Used when no symbol resolves, and for * legacy decisions backfilled from `affectedFiles`. */ export interface StructuralAnchor { /** Call-graph node id; absent for a file-level anchor. */ nodeId?: string; /** * Content-addressed, location-independent stable id of the anchored symbol * (add-content-addressed-stable-symbol-ids). Recorded alongside `nodeId` so a * symbol that is later moved/renamed can be re-resolved when its `nodeId` no * longer matches. Absent on anchors recorded before this change and on symbols * with no derivable stable id — both keep their exact current behavior. */ stableId?: string; /** Symbol name resolved at record time; absent for a pure file-level anchor. */ symbolName?: string; /** Repo-relative path of the anchored file. Always present. */ filePath: string; /** * Hash of the anchored span at record time. For a symbol anchor, the function * source span; for a file anchor, the whole-file content. Absent for a truly * legacy file anchor with no captured baseline (only existence can be checked). */ contentHash?: string; } /** Deterministic freshness verdict for a single anchor or an aggregated memory. */ export type MemoryFreshness = 'fresh' | 'drifted' | 'orphaned'; /** The freshness of one anchor, with the new location when a rename was detected. */ export interface AnchorVerdict { anchor: StructuralAnchor; freshness: MemoryFreshness; /** New location when the anchored symbol was confidently renamed/relocated. */ relocatedTo?: string; } /** * Evidence behind a `fresh` verdict (add-trust-calibrated-context-economy). The * exact span and hash OpenLore already compared to produce `fresh` — surfaced so * an agent can cite it and skip re-reading the source. Never attached to a * `drifted` or `orphaned` fact. */ export interface GroundingCertificate { /** Resolved symbol name; absent for a file-level certificate. */ symbol?: string; /** Repo-relative path of the verified file. */ filePath: string; /** 1-based inclusive line range of the verified span, when known. */ lineSpan?: { start: number; end: number; }; /** Hash of the verified span — the same hash the freshness check compared. */ contentHash: string; } /** * A general, code-anchored agent memory (kind `note`) — the substrate behind the * `remember`/`recall` tools. Stored separately from the decision gate in * .openlore/memory/notes.json so it never touches the commit pipeline. */ export interface AnchoredMemory { /** Stable 8-char content-derived id. */ id: string; kind: 'note'; content: string; anchors: StructuralAnchor[]; recordedAt: string; /** Free-form retrieval tags (optional). */ tags?: string[]; } /** Persistent store written to .openlore/memory/notes.json */ export interface MemoryStore { version: '1'; updatedAt: string; /** * Monotonic write counter for atomic compare-and-swap on save * (change: harden-memory-integrity-invariant). Additive — defaults to 0 for * legacy stores written before this field existed. */ sequence?: number; memories: AnchoredMemory[]; } //# sourceMappingURL=index.d.ts.map