@kb-labs/agent-history 2.34.0 → 2.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -191,7 +191,7 @@ var SnapshotStorage = class {
191
191
  if (stats.isDirectory()) {
192
192
  sessions.push({
193
193
  id: sessionId,
194
- createdAt: stats.birthtimeMs
194
+ createdAt: stats.mtimeMs
195
195
  });
196
196
  }
197
197
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/snapshot-storage.ts","../src/change-store.ts","../src/conflict-detector.ts","../src/diff-generator.ts"],"names":["header"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Snapshot storage - persist file change snapshots to disk\n */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport type { FileChange, StorageConfig } from './types.js';\n\nconst DEFAULT_CONFIG: Required<StorageConfig> = {\n basePath: '.kb/agents/sessions',\n maxSessions: 30,\n maxAgeDays: 30,\n maxTotalSizeMb: 500,\n};\n\n/**\n * Storage for file change snapshots\n */\nexport class SnapshotStorage {\n private workingDir: string;\n private config: Required<StorageConfig>;\n\n constructor(workingDir: string, config?: Partial<StorageConfig>) {\n this.workingDir = workingDir;\n this.config = { ...DEFAULT_CONFIG, ...config };\n }\n\n /**\n * Save snapshot to disk\n */\n async saveSnapshot(sessionId: string, change: FileChange): Promise<void> {\n const sessionDir = this.getSessionDir(sessionId);\n const snapshotsDir = path.join(sessionDir, 'snapshots');\n\n // Ensure directories exist\n await fs.promises.mkdir(snapshotsDir, { recursive: true });\n\n // Write snapshot file\n const snapshotPath = path.join(snapshotsDir, `${change.id}.json`);\n await fs.promises.writeFile(\n snapshotPath,\n JSON.stringify(change, null, 2),\n 'utf-8'\n );\n\n // Update index\n await this.updateIndex(sessionId, change);\n }\n\n /**\n * Load snapshot by ID\n */\n async loadSnapshot(sessionId: string, changeId: string): Promise<FileChange | null> {\n try {\n const snapshotPath = path.join(\n this.getSessionDir(sessionId),\n 'snapshots',\n `${changeId}.json`\n );\n\n const content = await fs.promises.readFile(snapshotPath, 'utf-8');\n return JSON.parse(content) as FileChange;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return null;\n }\n if (error instanceof SyntaxError) {\n // Corrupted JSON - return null instead of throwing\n return null;\n }\n throw error;\n }\n }\n\n /**\n * List all snapshots for session\n */\n async listSnapshots(sessionId: string): Promise<FileChange[]> {\n try {\n const indexPath = path.join(this.getSessionDir(sessionId), 'index.json');\n const content = await fs.promises.readFile(indexPath, 'utf-8');\n const index = JSON.parse(content) as SessionIndex;\n\n // Load full snapshots\n const changes: FileChange[] = [];\n for (const changeId of index.changes) {\n const change = await this.loadSnapshot(sessionId, changeId);\n if (change) {\n changes.push(change);\n }\n }\n\n // Sort by timestamp (chronological order)\n changes.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());\n\n return changes;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n // Index missing - fall back to reading snapshots directory directly\n const snapshotsDir = path.join(this.getSessionDir(sessionId), 'snapshots');\n\n try {\n const files = await fs.promises.readdir(snapshotsDir);\n const changes: FileChange[] = [];\n\n for (const file of files) {\n if (file.endsWith('.json')) {\n const changeId = file.replace('.json', '');\n const change = await this.loadSnapshot(sessionId, changeId);\n if (change) {\n changes.push(change);\n }\n }\n }\n\n // Sort by timestamp\n changes.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());\n\n return changes;\n } catch {\n return [];\n }\n }\n throw error;\n }\n }\n\n /**\n * Delete all snapshots for session\n */\n async deleteSession(sessionId: string): Promise<void> {\n const sessionDir = this.getSessionDir(sessionId);\n\n try {\n await fs.promises.rm(sessionDir, { recursive: true, force: true });\n } catch (error) {\n // Ignore if doesn't exist\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {\n throw error;\n }\n }\n }\n\n /**\n * Cleanup old sessions based on retention policy\n */\n async cleanupOldSessions(): Promise<{ deleted: number; keptLast: number }> {\n const _sessionsBaseDir = path.join(this.workingDir, this.config.basePath);\n\n try {\n const sessions = await this.listAllSessions();\n\n // Sort by creation time (newest first)\n sessions.sort((a, b) => b.createdAt - a.createdAt);\n\n let deleted = 0;\n\n // Delete by count (keep last N)\n if (sessions.length > this.config.maxSessions) {\n const toDelete = sessions.slice(this.config.maxSessions);\n\n for (const session of toDelete) {\n await this.deleteSession(session.id);\n deleted++;\n }\n }\n\n // Delete by age\n const now = Date.now();\n const maxAge = this.config.maxAgeDays * 24 * 60 * 60 * 1000;\n\n for (const session of sessions) {\n if (now - session.createdAt > maxAge) {\n await this.deleteSession(session.id);\n deleted++;\n }\n }\n\n return {\n deleted,\n keptLast: Math.min(sessions.length, this.config.maxSessions),\n };\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return { deleted: 0, keptLast: 0 };\n }\n throw error;\n }\n }\n\n // ═══════════════════════════════════════════════════════════════════════\n // Private Methods\n // ═══════════════════════════════════════════════════════════════════════\n\n /**\n * Get session directory path\n */\n private getSessionDir(sessionId: string): string {\n return path.join(this.workingDir, this.config.basePath, sessionId);\n }\n\n /**\n * Update session index\n */\n private async updateIndex(sessionId: string, change: FileChange): Promise<void> {\n const sessionDir = this.getSessionDir(sessionId);\n const indexPath = path.join(sessionDir, 'index.json');\n\n let index: SessionIndex;\n\n try {\n const content = await fs.promises.readFile(indexPath, 'utf-8');\n index = JSON.parse(content);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n // Create new index\n index = {\n sessionId,\n createdAt: new Date().toISOString(),\n changes: [],\n };\n } else {\n throw error;\n }\n }\n\n // Add change to index\n if (!index.changes.includes(change.id)) {\n index.changes.push(change.id);\n }\n\n // Write index\n await fs.promises.writeFile(indexPath, JSON.stringify(index, null, 2), 'utf-8');\n }\n\n /**\n * List all sessions with metadata\n */\n private async listAllSessions(): Promise<SessionMetadata[]> {\n const _sessionsBaseDir = path.join(this.workingDir, this.config.basePath);\n\n try {\n const sessionDirs = await fs.promises.readdir(_sessionsBaseDir);\n\n const sessions: SessionMetadata[] = [];\n\n for (const sessionId of sessionDirs) {\n const sessionDir = path.join(_sessionsBaseDir, sessionId);\n const stats = await fs.promises.stat(sessionDir);\n\n if (stats.isDirectory()) {\n sessions.push({\n id: sessionId,\n createdAt: stats.birthtimeMs,\n });\n }\n }\n\n return sessions;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return [];\n }\n throw error;\n }\n }\n}\n\n// ═══════════════════════════════════════════════════════════════════════\n// Internal Types\n// ═══════════════════════════════════════════════════════════════════════\n\ninterface SessionIndex {\n sessionId: string;\n createdAt: string;\n changes: string[]; // Array of change IDs\n}\n\ninterface SessionMetadata {\n id: string;\n createdAt: number; // Timestamp\n}\n","/**\n * ChangeStore — persists and queries file change snapshots.\n *\n * Design principles (vs old FileChangeTracker):\n * - No EventEmitter: events belong in middleware (AgentEventBus)\n * - No agentId/runId state: injected per-call by ChangeTrackingMiddleware\n * - No rollback I/O: rollback logic lives in middleware (uses workingDir from RunContext)\n * - Pure storage + query: save, load, list, cleanup\n */\n\nimport * as crypto from 'node:crypto';\nimport type { FileChange, FileChangeSummary, StorageConfig } from './types.js';\nimport { SnapshotStorage } from './snapshot-storage.js';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Helpers\n// ─────────────────────────────────────────────────────────────────────────────\n\nfunction generateChangeId(): string {\n return `change-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;\n}\n\nexport function computeHash(content: string): string {\n return crypto.createHash('sha256').update(content, 'utf-8').digest('hex');\n}\n\nexport function toSummary(change: FileChange): FileChangeSummary {\n return {\n changeId: change.id,\n filePath: change.filePath,\n operation: change.operation,\n timestamp: change.timestamp,\n linesAdded: change.metadata?.linesAdded,\n linesRemoved: change.metadata?.linesRemoved,\n isNew: !change.before,\n sizeAfter: change.after.size,\n };\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// ChangeStore\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface SaveChangeInput {\n sessionId: string;\n agentId: string;\n runId: string;\n filePath: string;\n operation: 'write' | 'patch' | 'delete';\n beforeContent: string | undefined;\n afterContent: string;\n metadata?: FileChange['metadata'];\n}\n\nexport class ChangeStore {\n private readonly storage: SnapshotStorage;\n /** In-memory cache keyed by sessionId → changeId → FileChange */\n private readonly cache = new Map<string, Map<string, FileChange>>();\n\n constructor(workingDir: string, config?: Partial<StorageConfig>) {\n this.storage = new SnapshotStorage(workingDir, config);\n }\n\n // ── Write ────────────────────────────────────────────────────────────────\n\n async save(input: SaveChangeInput): Promise<FileChange> {\n const change: FileChange = {\n id: generateChangeId(),\n sessionId: input.sessionId,\n agentId: input.agentId,\n runId: input.runId,\n filePath: input.filePath,\n operation: input.operation,\n timestamp: new Date().toISOString(),\n before: input.beforeContent !== undefined\n ? {\n content: input.beforeContent,\n hash: computeHash(input.beforeContent),\n size: Buffer.byteLength(input.beforeContent, 'utf-8'),\n }\n : undefined,\n after: {\n content: input.afterContent,\n hash: computeHash(input.afterContent),\n size: Buffer.byteLength(input.afterContent, 'utf-8'),\n },\n metadata: input.metadata,\n };\n\n await this.storage.saveSnapshot(input.sessionId, change);\n this._cache(input.sessionId).set(change.id, change);\n return change;\n }\n\n // ── Read ─────────────────────────────────────────────────────────────────\n\n async get(sessionId: string, changeId: string): Promise<FileChange | null> {\n const cached = this._cache(sessionId).get(changeId);\n if (cached) {return cached;}\n const loaded = await this.storage.loadSnapshot(sessionId, changeId);\n if (loaded) {this._cache(sessionId).set(changeId, loaded);}\n return loaded;\n }\n\n async listSession(sessionId: string): Promise<FileChange[]> {\n return this.storage.listSnapshots(sessionId);\n }\n\n async listRun(sessionId: string, runId: string): Promise<FileChange[]> {\n const all = await this.listSession(sessionId);\n return all.filter((c) => c.runId === runId);\n }\n\n async listFile(sessionId: string, filePath: string): Promise<FileChange[]> {\n const all = await this.listSession(sessionId);\n return all.filter((c) => c.filePath === filePath);\n }\n\n /** Returns unique file paths touched in a session */\n async changedFiles(sessionId: string): Promise<string[]> {\n const all = await this.listSession(sessionId);\n return [...new Set(all.map((c) => c.filePath))];\n }\n\n // ── Summaries ─────────────────────────────────────────────────────────────\n\n async summariesForRun(sessionId: string, runId: string): Promise<FileChangeSummary[]> {\n const changes = await this.listRun(sessionId, runId);\n return changes.map(toSummary);\n }\n\n // ── Cleanup ───────────────────────────────────────────────────────────────\n\n async cleanup(): Promise<{ deleted: number; keptLast: number }> {\n return this.storage.cleanupOldSessions();\n }\n\n async deleteSession(sessionId: string): Promise<void> {\n await this.storage.deleteSession(sessionId);\n this.cache.delete(sessionId);\n }\n\n // ── Private ───────────────────────────────────────────────────────────────\n\n private _cache(sessionId: string): Map<string, FileChange> {\n let m = this.cache.get(sessionId);\n if (!m) {\n m = new Map();\n this.cache.set(sessionId, m);\n }\n return m;\n }\n}\n","/**\n * ConflictDetector — detects file conflicts before write operations.\n * Works with ChangeStore instead of the old FileChangeTracker.\n */\n\nimport type { ChangeStore } from './change-store.js';\n\nexport type ConflictType = 'none' | 'disjoint' | 'overlapping' | 'conflicting-intent' | 'semantic';\n\nexport interface DetectedConflict {\n type: ConflictType;\n filePath: string;\n /** Agent attempting the write */\n currentAgentId: string;\n /** Other agents who modified this file */\n conflictingAgents: string[];\n description: string;\n /** 0–1: higher = easier to auto-resolve */\n resolutionConfidence: number;\n metadata?: {\n overlapLines?: number[];\n intentA?: string;\n intentB?: string;\n semanticIssue?: string;\n };\n}\n\nexport interface ConflictCheckInput {\n sessionId: string;\n filePath: string;\n agentId: string;\n operation: 'write' | 'patch' | 'delete';\n metadata?: {\n startLine?: number;\n endLine?: number;\n content?: string;\n };\n}\n\nexport class ConflictDetector {\n constructor(private readonly store: ChangeStore) {}\n\n async detectConflict(input: ConflictCheckInput): Promise<DetectedConflict | null> {\n const { sessionId, filePath, agentId, operation, metadata } = input;\n\n const fileHistory = await this.store.listFile(sessionId, filePath);\n if (fileHistory.length === 0) {return null;}\n\n const otherChanges = fileHistory.filter((c) => c.agentId !== agentId);\n if (otherChanges.length === 0) {return null;}\n\n const conflictingAgents = [...new Set(otherChanges.map((c) => c.agentId))];\n const latest = fileHistory[fileHistory.length - 1]!;\n\n // Disjoint patches → safe to auto-merge\n if (operation === 'patch' && latest.operation === 'patch') {\n const overlaps = this._checkLineOverlap(\n metadata?.startLine, metadata?.endLine,\n latest.metadata?.startLine, latest.metadata?.endLine,\n );\n\n if (!overlaps) {\n return {\n type: 'disjoint',\n filePath,\n currentAgentId: agentId,\n conflictingAgents,\n description: 'Patches on different lines — safe to merge',\n resolutionConfidence: 1.0,\n };\n }\n\n const overlapLines = this._overlapLines(\n metadata?.startLine, metadata?.endLine,\n latest.metadata?.startLine, latest.metadata?.endLine,\n );\n return {\n type: 'overlapping',\n filePath,\n currentAgentId: agentId,\n conflictingAgents,\n description: `Patches overlap on lines ${overlapLines.join(', ')}`,\n resolutionConfidence: 0.7,\n metadata: { overlapLines },\n };\n }\n\n // Conflicting intent: one deletes, another modifies\n if (\n (operation === 'delete' && latest.operation !== 'delete') ||\n (operation !== 'delete' && latest.operation === 'delete')\n ) {\n return {\n type: 'conflicting-intent',\n filePath,\n currentAgentId: agentId,\n conflictingAgents,\n description: 'One agent deletes while another modifies',\n resolutionConfidence: 0.5,\n metadata: { intentA: operation, intentB: latest.operation },\n };\n }\n\n // Two full rewrites\n if (operation === 'write' && latest.operation === 'write') {\n const semanticIssue = this._detectSemanticConflict(\n latest.after.content,\n metadata?.content ?? '',\n );\n if (semanticIssue) {\n return {\n type: 'semantic',\n filePath,\n currentAgentId: agentId,\n conflictingAgents,\n description: 'Semantic conflict in file rewrites',\n resolutionConfidence: 0.3,\n metadata: { semanticIssue },\n };\n }\n return {\n type: 'overlapping',\n filePath,\n currentAgentId: agentId,\n conflictingAgents,\n description: 'Full file overwrite by multiple agents',\n resolutionConfidence: 0.6,\n };\n }\n\n return {\n type: 'overlapping',\n filePath,\n currentAgentId: agentId,\n conflictingAgents,\n description: 'Generic file modification conflict',\n resolutionConfidence: 0.5,\n };\n }\n\n // ── Private ───────────────────────────────────────────────────────────────\n\n private _checkLineOverlap(\n startA?: number, endA?: number,\n startB?: number, endB?: number,\n ): boolean {\n if (startA === undefined || endA === undefined || startB === undefined || endB === undefined) {\n return true; // conservative: assume overlap\n }\n return !(endA < startB || endB < startA);\n }\n\n private _overlapLines(\n startA?: number, endA?: number,\n startB?: number, endB?: number,\n ): number[] {\n if (startA === undefined || endA === undefined || startB === undefined || endB === undefined) {\n return [];\n }\n const from = Math.max(startA, startB);\n const to = Math.min(endA, endB);\n if (from > to) {return [];}\n const lines: number[] = [];\n for (let i = from; i <= to; i++) {lines.push(i);}\n return lines;\n }\n\n private _detectSemanticConflict(contentA: string, contentB: string): string | null {\n const linesA = contentA.split('\\n').length;\n const linesB = contentB.split('\\n').length;\n const diff = Math.abs(linesA - linesB);\n if (diff > linesA * 0.3) {\n return `Significant structural change (${diff} line difference)`;\n }\n return null;\n }\n}\n","/**\n * Unified diff generator for file change snapshots.\n * Pure implementation — no external dependencies.\n */\n\n/**\n * Compute longest common subsequence lengths for Myers diff algorithm.\n */\nfunction lcsTable(a: string[], b: string[]): number[][] {\n const m = a.length;\n const n = b.length;\n const dp: number[][] = Array.from({ length: m + 1 }, () => new Array(n + 1).fill(0));\n for (let i = 1; i <= m; i++) {\n for (let j = 1; j <= n; j++) {\n dp[i]![j] = a[i - 1] === b[j - 1] ? dp[i - 1]![j - 1]! + 1 : Math.max(dp[i - 1]![j]!, dp[i]![j - 1]!);\n }\n }\n return dp;\n}\n\ntype DiffOp = { op: '+' | '-' | ' '; line: string };\n\n/**\n * Compute line-level diff between two texts using LCS.\n */\nfunction lineDiff(oldText: string, newText: string): DiffOp[] {\n const oldLines = oldText ? oldText.split('\\n') : [];\n const newLines = newText ? newText.split('\\n') : [];\n\n // Remove trailing empty line from split if original had no trailing newline\n if (oldLines[oldLines.length - 1] === '') {oldLines.pop();}\n if (newLines[newLines.length - 1] === '') {newLines.pop();}\n\n const dp = lcsTable(oldLines, newLines);\n\n const ops: DiffOp[] = [];\n\n let i = oldLines.length;\n let j = newLines.length;\n\n while (i > 0 || j > 0) {\n if (i > 0 && j > 0 && oldLines[i - 1] === newLines[j - 1]) {\n ops.push({ op: ' ', line: oldLines[i - 1]! });\n i--;\n j--;\n } else if (j > 0 && (i === 0 || dp[i]![j - 1]! >= dp[i - 1]![j]!)) {\n ops.push({ op: '+', line: newLines[j - 1]! });\n j--;\n } else {\n ops.push({ op: '-', line: oldLines[i - 1]! });\n i--;\n }\n }\n\n ops.reverse();\n return ops;\n}\n\n/**\n * Generate a unified diff string from before/after content.\n * Context lines: 3 lines before and after each change hunk.\n */\nexport function generateUnifiedDiff(\n filePath: string,\n beforeContent: string | undefined,\n afterContent: string,\n operation: 'write' | 'patch' | 'delete'\n): string {\n if (operation === 'delete') {\n const lines = (beforeContent ?? '').split('\\n');\n if (lines[lines.length - 1] === '') {lines.pop();}\n const header = `--- ${filePath}\\t(before)\\n+++ /dev/null\\t(deleted)\\n`;\n const hunk = lines.length > 0\n ? `@@ -1,${lines.length} +0,0 @@\\n${lines.map((l) => `-${l}`).join('\\n')}\\n`\n : `@@ -0,0 +0,0 @@\\n`;\n return header + hunk;\n }\n\n const oldText = beforeContent ?? '';\n const newText = afterContent;\n const ops = lineDiff(oldText, newText);\n\n const CONTEXT = 3;\n const header = `--- ${filePath}\\t(before)\\n+++ ${filePath}\\t(after)\\n`;\n\n // Build hunks from ops\n type Hunk = { oldStart: number; oldCount: number; newStart: number; newCount: number; lines: string[] };\n const hunks: Hunk[] = [];\n\n const oldLine = 1;\n const newLine = 1;\n\n // Identify change ranges (with context)\n type ChangeRange = { start: number; end: number };\n const changeRanges: ChangeRange[] = [];\n\n for (let idx = 0; idx < ops.length; idx++) {\n if (ops[idx]!.op !== ' ') {\n const rangeStart = Math.max(0, idx - CONTEXT);\n const rangeEnd = Math.min(ops.length - 1, idx + CONTEXT);\n\n if (changeRanges.length > 0 && rangeStart <= changeRanges[changeRanges.length - 1]!.end) {\n changeRanges[changeRanges.length - 1]!.end = rangeEnd;\n } else {\n changeRanges.push({ start: rangeStart, end: rangeEnd });\n }\n }\n }\n\n // Merge overlapping ranges\n const merged: ChangeRange[] = [];\n for (const r of changeRanges) {\n if (merged.length > 0 && r.start <= merged[merged.length - 1]!.end + 1) {\n merged[merged.length - 1]!.end = Math.max(merged[merged.length - 1]!.end, r.end);\n } else {\n merged.push({ ...r });\n }\n }\n\n // Build actual line counters per op\n const opOldLine: number[] = [];\n const opNewLine: number[] = [];\n let ol = 1;\n let nl = 1;\n for (const op of ops) {\n opOldLine.push(ol);\n opNewLine.push(nl);\n if (op.op === ' ' || op.op === '-') {ol++;}\n if (op.op === ' ' || op.op === '+') {nl++;}\n }\n\n if (merged.length === 0) {\n // No changes\n return header + `@@ -1,${ol - 1} +1,${nl - 1} @@\\n` +\n ops.map((o) => ` ${o.line}`).join('\\n') + (ops.length > 0 ? '\\n' : '');\n }\n\n for (const range of merged) {\n const slicedOps = ops.slice(range.start, range.end + 1);\n const firstOldLine = opOldLine[range.start] ?? 1;\n const firstNewLine = opNewLine[range.start] ?? 1;\n\n let oldCount = 0;\n let newCount = 0;\n const hunkLines: string[] = [];\n for (const op of slicedOps) {\n if (op.op === ' ') { oldCount++; newCount++; hunkLines.push(` ${op.line}`); }\n else if (op.op === '-') { oldCount++; hunkLines.push(`-${op.line}`); }\n else { newCount++; hunkLines.push(`+${op.line}`); }\n }\n\n hunks.push({\n oldStart: firstOldLine,\n oldCount,\n newStart: firstNewLine,\n newCount,\n lines: hunkLines,\n });\n }\n\n // Silence unused variable warning\n void oldLine;\n void newLine;\n\n const hunkStr = hunks.map((h) => {\n const header2 = `@@ -${h.oldStart},${h.oldCount} +${h.newStart},${h.newCount} @@`;\n return header2 + '\\n' + h.lines.join('\\n') + '\\n';\n }).join('');\n\n return header + hunkStr;\n}\n\n/**\n * Count added and removed lines from a unified diff string.\n */\nexport function countDiffLines(diff: string): { added: number; removed: number } {\n const lines = diff.split('\\n');\n let added = 0;\n let removed = 0;\n for (const line of lines) {\n if (line.startsWith('+') && !line.startsWith('+++')) {added++;}\n if (line.startsWith('-') && !line.startsWith('---')) {removed++;}\n }\n return { added, removed };\n}\n"]}
1
+ {"version":3,"sources":["../src/snapshot-storage.ts","../src/change-store.ts","../src/conflict-detector.ts","../src/diff-generator.ts"],"names":["header"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Snapshot storage - persist file change snapshots to disk\n */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport type { FileChange, StorageConfig } from './types.js';\n\nconst DEFAULT_CONFIG: Required<StorageConfig> = {\n basePath: '.kb/agents/sessions',\n maxSessions: 30,\n maxAgeDays: 30,\n maxTotalSizeMb: 500,\n};\n\n/**\n * Storage for file change snapshots\n */\nexport class SnapshotStorage {\n private workingDir: string;\n private config: Required<StorageConfig>;\n\n constructor(workingDir: string, config?: Partial<StorageConfig>) {\n this.workingDir = workingDir;\n this.config = { ...DEFAULT_CONFIG, ...config };\n }\n\n /**\n * Save snapshot to disk\n */\n async saveSnapshot(sessionId: string, change: FileChange): Promise<void> {\n const sessionDir = this.getSessionDir(sessionId);\n const snapshotsDir = path.join(sessionDir, 'snapshots');\n\n // Ensure directories exist\n await fs.promises.mkdir(snapshotsDir, { recursive: true });\n\n // Write snapshot file\n const snapshotPath = path.join(snapshotsDir, `${change.id}.json`);\n await fs.promises.writeFile(\n snapshotPath,\n JSON.stringify(change, null, 2),\n 'utf-8'\n );\n\n // Update index\n await this.updateIndex(sessionId, change);\n }\n\n /**\n * Load snapshot by ID\n */\n async loadSnapshot(sessionId: string, changeId: string): Promise<FileChange | null> {\n try {\n const snapshotPath = path.join(\n this.getSessionDir(sessionId),\n 'snapshots',\n `${changeId}.json`\n );\n\n const content = await fs.promises.readFile(snapshotPath, 'utf-8');\n return JSON.parse(content) as FileChange;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return null;\n }\n if (error instanceof SyntaxError) {\n // Corrupted JSON - return null instead of throwing\n return null;\n }\n throw error;\n }\n }\n\n /**\n * List all snapshots for session\n */\n async listSnapshots(sessionId: string): Promise<FileChange[]> {\n try {\n const indexPath = path.join(this.getSessionDir(sessionId), 'index.json');\n const content = await fs.promises.readFile(indexPath, 'utf-8');\n const index = JSON.parse(content) as SessionIndex;\n\n // Load full snapshots\n const changes: FileChange[] = [];\n for (const changeId of index.changes) {\n const change = await this.loadSnapshot(sessionId, changeId);\n if (change) {\n changes.push(change);\n }\n }\n\n // Sort by timestamp (chronological order)\n changes.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());\n\n return changes;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n // Index missing - fall back to reading snapshots directory directly\n const snapshotsDir = path.join(this.getSessionDir(sessionId), 'snapshots');\n\n try {\n const files = await fs.promises.readdir(snapshotsDir);\n const changes: FileChange[] = [];\n\n for (const file of files) {\n if (file.endsWith('.json')) {\n const changeId = file.replace('.json', '');\n const change = await this.loadSnapshot(sessionId, changeId);\n if (change) {\n changes.push(change);\n }\n }\n }\n\n // Sort by timestamp\n changes.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());\n\n return changes;\n } catch {\n return [];\n }\n }\n throw error;\n }\n }\n\n /**\n * Delete all snapshots for session\n */\n async deleteSession(sessionId: string): Promise<void> {\n const sessionDir = this.getSessionDir(sessionId);\n\n try {\n await fs.promises.rm(sessionDir, { recursive: true, force: true });\n } catch (error) {\n // Ignore if doesn't exist\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {\n throw error;\n }\n }\n }\n\n /**\n * Cleanup old sessions based on retention policy\n */\n async cleanupOldSessions(): Promise<{ deleted: number; keptLast: number }> {\n const _sessionsBaseDir = path.join(this.workingDir, this.config.basePath);\n\n try {\n const sessions = await this.listAllSessions();\n\n // Sort by creation time (newest first)\n sessions.sort((a, b) => b.createdAt - a.createdAt);\n\n let deleted = 0;\n\n // Delete by count (keep last N)\n if (sessions.length > this.config.maxSessions) {\n const toDelete = sessions.slice(this.config.maxSessions);\n\n for (const session of toDelete) {\n await this.deleteSession(session.id);\n deleted++;\n }\n }\n\n // Delete by age\n const now = Date.now();\n const maxAge = this.config.maxAgeDays * 24 * 60 * 60 * 1000;\n\n for (const session of sessions) {\n if (now - session.createdAt > maxAge) {\n await this.deleteSession(session.id);\n deleted++;\n }\n }\n\n return {\n deleted,\n keptLast: Math.min(sessions.length, this.config.maxSessions),\n };\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return { deleted: 0, keptLast: 0 };\n }\n throw error;\n }\n }\n\n // ═══════════════════════════════════════════════════════════════════════\n // Private Methods\n // ═══════════════════════════════════════════════════════════════════════\n\n /**\n * Get session directory path\n */\n private getSessionDir(sessionId: string): string {\n return path.join(this.workingDir, this.config.basePath, sessionId);\n }\n\n /**\n * Update session index\n */\n private async updateIndex(sessionId: string, change: FileChange): Promise<void> {\n const sessionDir = this.getSessionDir(sessionId);\n const indexPath = path.join(sessionDir, 'index.json');\n\n let index: SessionIndex;\n\n try {\n const content = await fs.promises.readFile(indexPath, 'utf-8');\n index = JSON.parse(content);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n // Create new index\n index = {\n sessionId,\n createdAt: new Date().toISOString(),\n changes: [],\n };\n } else {\n throw error;\n }\n }\n\n // Add change to index\n if (!index.changes.includes(change.id)) {\n index.changes.push(change.id);\n }\n\n // Write index\n await fs.promises.writeFile(indexPath, JSON.stringify(index, null, 2), 'utf-8');\n }\n\n /**\n * List all sessions with metadata\n */\n private async listAllSessions(): Promise<SessionMetadata[]> {\n const _sessionsBaseDir = path.join(this.workingDir, this.config.basePath);\n\n try {\n const sessionDirs = await fs.promises.readdir(_sessionsBaseDir);\n\n const sessions: SessionMetadata[] = [];\n\n for (const sessionId of sessionDirs) {\n const sessionDir = path.join(_sessionsBaseDir, sessionId);\n const stats = await fs.promises.stat(sessionDir);\n\n if (stats.isDirectory()) {\n sessions.push({\n id: sessionId,\n createdAt: stats.mtimeMs,\n });\n }\n }\n\n return sessions;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return [];\n }\n throw error;\n }\n }\n}\n\n// ═══════════════════════════════════════════════════════════════════════\n// Internal Types\n// ═══════════════════════════════════════════════════════════════════════\n\ninterface SessionIndex {\n sessionId: string;\n createdAt: string;\n changes: string[]; // Array of change IDs\n}\n\ninterface SessionMetadata {\n id: string;\n createdAt: number; // Timestamp\n}\n","/**\n * ChangeStore — persists and queries file change snapshots.\n *\n * Design principles (vs old FileChangeTracker):\n * - No EventEmitter: events belong in middleware (AgentEventBus)\n * - No agentId/runId state: injected per-call by ChangeTrackingMiddleware\n * - No rollback I/O: rollback logic lives in middleware (uses workingDir from RunContext)\n * - Pure storage + query: save, load, list, cleanup\n */\n\nimport * as crypto from 'node:crypto';\nimport type { FileChange, FileChangeSummary, StorageConfig } from './types.js';\nimport { SnapshotStorage } from './snapshot-storage.js';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Helpers\n// ─────────────────────────────────────────────────────────────────────────────\n\nfunction generateChangeId(): string {\n return `change-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;\n}\n\nexport function computeHash(content: string): string {\n return crypto.createHash('sha256').update(content, 'utf-8').digest('hex');\n}\n\nexport function toSummary(change: FileChange): FileChangeSummary {\n return {\n changeId: change.id,\n filePath: change.filePath,\n operation: change.operation,\n timestamp: change.timestamp,\n linesAdded: change.metadata?.linesAdded,\n linesRemoved: change.metadata?.linesRemoved,\n isNew: !change.before,\n sizeAfter: change.after.size,\n };\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// ChangeStore\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface SaveChangeInput {\n sessionId: string;\n agentId: string;\n runId: string;\n filePath: string;\n operation: 'write' | 'patch' | 'delete';\n beforeContent: string | undefined;\n afterContent: string;\n metadata?: FileChange['metadata'];\n}\n\nexport class ChangeStore {\n private readonly storage: SnapshotStorage;\n /** In-memory cache keyed by sessionId → changeId → FileChange */\n private readonly cache = new Map<string, Map<string, FileChange>>();\n\n constructor(workingDir: string, config?: Partial<StorageConfig>) {\n this.storage = new SnapshotStorage(workingDir, config);\n }\n\n // ── Write ────────────────────────────────────────────────────────────────\n\n async save(input: SaveChangeInput): Promise<FileChange> {\n const change: FileChange = {\n id: generateChangeId(),\n sessionId: input.sessionId,\n agentId: input.agentId,\n runId: input.runId,\n filePath: input.filePath,\n operation: input.operation,\n timestamp: new Date().toISOString(),\n before: input.beforeContent !== undefined\n ? {\n content: input.beforeContent,\n hash: computeHash(input.beforeContent),\n size: Buffer.byteLength(input.beforeContent, 'utf-8'),\n }\n : undefined,\n after: {\n content: input.afterContent,\n hash: computeHash(input.afterContent),\n size: Buffer.byteLength(input.afterContent, 'utf-8'),\n },\n metadata: input.metadata,\n };\n\n await this.storage.saveSnapshot(input.sessionId, change);\n this._cache(input.sessionId).set(change.id, change);\n return change;\n }\n\n // ── Read ─────────────────────────────────────────────────────────────────\n\n async get(sessionId: string, changeId: string): Promise<FileChange | null> {\n const cached = this._cache(sessionId).get(changeId);\n if (cached) {return cached;}\n const loaded = await this.storage.loadSnapshot(sessionId, changeId);\n if (loaded) {this._cache(sessionId).set(changeId, loaded);}\n return loaded;\n }\n\n async listSession(sessionId: string): Promise<FileChange[]> {\n return this.storage.listSnapshots(sessionId);\n }\n\n async listRun(sessionId: string, runId: string): Promise<FileChange[]> {\n const all = await this.listSession(sessionId);\n return all.filter((c) => c.runId === runId);\n }\n\n async listFile(sessionId: string, filePath: string): Promise<FileChange[]> {\n const all = await this.listSession(sessionId);\n return all.filter((c) => c.filePath === filePath);\n }\n\n /** Returns unique file paths touched in a session */\n async changedFiles(sessionId: string): Promise<string[]> {\n const all = await this.listSession(sessionId);\n return [...new Set(all.map((c) => c.filePath))];\n }\n\n // ── Summaries ─────────────────────────────────────────────────────────────\n\n async summariesForRun(sessionId: string, runId: string): Promise<FileChangeSummary[]> {\n const changes = await this.listRun(sessionId, runId);\n return changes.map(toSummary);\n }\n\n // ── Cleanup ───────────────────────────────────────────────────────────────\n\n async cleanup(): Promise<{ deleted: number; keptLast: number }> {\n return this.storage.cleanupOldSessions();\n }\n\n async deleteSession(sessionId: string): Promise<void> {\n await this.storage.deleteSession(sessionId);\n this.cache.delete(sessionId);\n }\n\n // ── Private ───────────────────────────────────────────────────────────────\n\n private _cache(sessionId: string): Map<string, FileChange> {\n let m = this.cache.get(sessionId);\n if (!m) {\n m = new Map();\n this.cache.set(sessionId, m);\n }\n return m;\n }\n}\n","/**\n * ConflictDetector — detects file conflicts before write operations.\n * Works with ChangeStore instead of the old FileChangeTracker.\n */\n\nimport type { ChangeStore } from './change-store.js';\n\nexport type ConflictType = 'none' | 'disjoint' | 'overlapping' | 'conflicting-intent' | 'semantic';\n\nexport interface DetectedConflict {\n type: ConflictType;\n filePath: string;\n /** Agent attempting the write */\n currentAgentId: string;\n /** Other agents who modified this file */\n conflictingAgents: string[];\n description: string;\n /** 0–1: higher = easier to auto-resolve */\n resolutionConfidence: number;\n metadata?: {\n overlapLines?: number[];\n intentA?: string;\n intentB?: string;\n semanticIssue?: string;\n };\n}\n\nexport interface ConflictCheckInput {\n sessionId: string;\n filePath: string;\n agentId: string;\n operation: 'write' | 'patch' | 'delete';\n metadata?: {\n startLine?: number;\n endLine?: number;\n content?: string;\n };\n}\n\nexport class ConflictDetector {\n constructor(private readonly store: ChangeStore) {}\n\n async detectConflict(input: ConflictCheckInput): Promise<DetectedConflict | null> {\n const { sessionId, filePath, agentId, operation, metadata } = input;\n\n const fileHistory = await this.store.listFile(sessionId, filePath);\n if (fileHistory.length === 0) {return null;}\n\n const otherChanges = fileHistory.filter((c) => c.agentId !== agentId);\n if (otherChanges.length === 0) {return null;}\n\n const conflictingAgents = [...new Set(otherChanges.map((c) => c.agentId))];\n const latest = fileHistory[fileHistory.length - 1]!;\n\n // Disjoint patches → safe to auto-merge\n if (operation === 'patch' && latest.operation === 'patch') {\n const overlaps = this._checkLineOverlap(\n metadata?.startLine, metadata?.endLine,\n latest.metadata?.startLine, latest.metadata?.endLine,\n );\n\n if (!overlaps) {\n return {\n type: 'disjoint',\n filePath,\n currentAgentId: agentId,\n conflictingAgents,\n description: 'Patches on different lines — safe to merge',\n resolutionConfidence: 1.0,\n };\n }\n\n const overlapLines = this._overlapLines(\n metadata?.startLine, metadata?.endLine,\n latest.metadata?.startLine, latest.metadata?.endLine,\n );\n return {\n type: 'overlapping',\n filePath,\n currentAgentId: agentId,\n conflictingAgents,\n description: `Patches overlap on lines ${overlapLines.join(', ')}`,\n resolutionConfidence: 0.7,\n metadata: { overlapLines },\n };\n }\n\n // Conflicting intent: one deletes, another modifies\n if (\n (operation === 'delete' && latest.operation !== 'delete') ||\n (operation !== 'delete' && latest.operation === 'delete')\n ) {\n return {\n type: 'conflicting-intent',\n filePath,\n currentAgentId: agentId,\n conflictingAgents,\n description: 'One agent deletes while another modifies',\n resolutionConfidence: 0.5,\n metadata: { intentA: operation, intentB: latest.operation },\n };\n }\n\n // Two full rewrites\n if (operation === 'write' && latest.operation === 'write') {\n const semanticIssue = this._detectSemanticConflict(\n latest.after.content,\n metadata?.content ?? '',\n );\n if (semanticIssue) {\n return {\n type: 'semantic',\n filePath,\n currentAgentId: agentId,\n conflictingAgents,\n description: 'Semantic conflict in file rewrites',\n resolutionConfidence: 0.3,\n metadata: { semanticIssue },\n };\n }\n return {\n type: 'overlapping',\n filePath,\n currentAgentId: agentId,\n conflictingAgents,\n description: 'Full file overwrite by multiple agents',\n resolutionConfidence: 0.6,\n };\n }\n\n return {\n type: 'overlapping',\n filePath,\n currentAgentId: agentId,\n conflictingAgents,\n description: 'Generic file modification conflict',\n resolutionConfidence: 0.5,\n };\n }\n\n // ── Private ───────────────────────────────────────────────────────────────\n\n private _checkLineOverlap(\n startA?: number, endA?: number,\n startB?: number, endB?: number,\n ): boolean {\n if (startA === undefined || endA === undefined || startB === undefined || endB === undefined) {\n return true; // conservative: assume overlap\n }\n return !(endA < startB || endB < startA);\n }\n\n private _overlapLines(\n startA?: number, endA?: number,\n startB?: number, endB?: number,\n ): number[] {\n if (startA === undefined || endA === undefined || startB === undefined || endB === undefined) {\n return [];\n }\n const from = Math.max(startA, startB);\n const to = Math.min(endA, endB);\n if (from > to) {return [];}\n const lines: number[] = [];\n for (let i = from; i <= to; i++) {lines.push(i);}\n return lines;\n }\n\n private _detectSemanticConflict(contentA: string, contentB: string): string | null {\n const linesA = contentA.split('\\n').length;\n const linesB = contentB.split('\\n').length;\n const diff = Math.abs(linesA - linesB);\n if (diff > linesA * 0.3) {\n return `Significant structural change (${diff} line difference)`;\n }\n return null;\n }\n}\n","/**\n * Unified diff generator for file change snapshots.\n * Pure implementation — no external dependencies.\n */\n\n/**\n * Compute longest common subsequence lengths for Myers diff algorithm.\n */\nfunction lcsTable(a: string[], b: string[]): number[][] {\n const m = a.length;\n const n = b.length;\n const dp: number[][] = Array.from({ length: m + 1 }, () => new Array(n + 1).fill(0));\n for (let i = 1; i <= m; i++) {\n for (let j = 1; j <= n; j++) {\n dp[i]![j] = a[i - 1] === b[j - 1] ? dp[i - 1]![j - 1]! + 1 : Math.max(dp[i - 1]![j]!, dp[i]![j - 1]!);\n }\n }\n return dp;\n}\n\ntype DiffOp = { op: '+' | '-' | ' '; line: string };\n\n/**\n * Compute line-level diff between two texts using LCS.\n */\nfunction lineDiff(oldText: string, newText: string): DiffOp[] {\n const oldLines = oldText ? oldText.split('\\n') : [];\n const newLines = newText ? newText.split('\\n') : [];\n\n // Remove trailing empty line from split if original had no trailing newline\n if (oldLines[oldLines.length - 1] === '') {oldLines.pop();}\n if (newLines[newLines.length - 1] === '') {newLines.pop();}\n\n const dp = lcsTable(oldLines, newLines);\n\n const ops: DiffOp[] = [];\n\n let i = oldLines.length;\n let j = newLines.length;\n\n while (i > 0 || j > 0) {\n if (i > 0 && j > 0 && oldLines[i - 1] === newLines[j - 1]) {\n ops.push({ op: ' ', line: oldLines[i - 1]! });\n i--;\n j--;\n } else if (j > 0 && (i === 0 || dp[i]![j - 1]! >= dp[i - 1]![j]!)) {\n ops.push({ op: '+', line: newLines[j - 1]! });\n j--;\n } else {\n ops.push({ op: '-', line: oldLines[i - 1]! });\n i--;\n }\n }\n\n ops.reverse();\n return ops;\n}\n\n/**\n * Generate a unified diff string from before/after content.\n * Context lines: 3 lines before and after each change hunk.\n */\nexport function generateUnifiedDiff(\n filePath: string,\n beforeContent: string | undefined,\n afterContent: string,\n operation: 'write' | 'patch' | 'delete'\n): string {\n if (operation === 'delete') {\n const lines = (beforeContent ?? '').split('\\n');\n if (lines[lines.length - 1] === '') {lines.pop();}\n const header = `--- ${filePath}\\t(before)\\n+++ /dev/null\\t(deleted)\\n`;\n const hunk = lines.length > 0\n ? `@@ -1,${lines.length} +0,0 @@\\n${lines.map((l) => `-${l}`).join('\\n')}\\n`\n : `@@ -0,0 +0,0 @@\\n`;\n return header + hunk;\n }\n\n const oldText = beforeContent ?? '';\n const newText = afterContent;\n const ops = lineDiff(oldText, newText);\n\n const CONTEXT = 3;\n const header = `--- ${filePath}\\t(before)\\n+++ ${filePath}\\t(after)\\n`;\n\n // Build hunks from ops\n type Hunk = { oldStart: number; oldCount: number; newStart: number; newCount: number; lines: string[] };\n const hunks: Hunk[] = [];\n\n const oldLine = 1;\n const newLine = 1;\n\n // Identify change ranges (with context)\n type ChangeRange = { start: number; end: number };\n const changeRanges: ChangeRange[] = [];\n\n for (let idx = 0; idx < ops.length; idx++) {\n if (ops[idx]!.op !== ' ') {\n const rangeStart = Math.max(0, idx - CONTEXT);\n const rangeEnd = Math.min(ops.length - 1, idx + CONTEXT);\n\n if (changeRanges.length > 0 && rangeStart <= changeRanges[changeRanges.length - 1]!.end) {\n changeRanges[changeRanges.length - 1]!.end = rangeEnd;\n } else {\n changeRanges.push({ start: rangeStart, end: rangeEnd });\n }\n }\n }\n\n // Merge overlapping ranges\n const merged: ChangeRange[] = [];\n for (const r of changeRanges) {\n if (merged.length > 0 && r.start <= merged[merged.length - 1]!.end + 1) {\n merged[merged.length - 1]!.end = Math.max(merged[merged.length - 1]!.end, r.end);\n } else {\n merged.push({ ...r });\n }\n }\n\n // Build actual line counters per op\n const opOldLine: number[] = [];\n const opNewLine: number[] = [];\n let ol = 1;\n let nl = 1;\n for (const op of ops) {\n opOldLine.push(ol);\n opNewLine.push(nl);\n if (op.op === ' ' || op.op === '-') {ol++;}\n if (op.op === ' ' || op.op === '+') {nl++;}\n }\n\n if (merged.length === 0) {\n // No changes\n return header + `@@ -1,${ol - 1} +1,${nl - 1} @@\\n` +\n ops.map((o) => ` ${o.line}`).join('\\n') + (ops.length > 0 ? '\\n' : '');\n }\n\n for (const range of merged) {\n const slicedOps = ops.slice(range.start, range.end + 1);\n const firstOldLine = opOldLine[range.start] ?? 1;\n const firstNewLine = opNewLine[range.start] ?? 1;\n\n let oldCount = 0;\n let newCount = 0;\n const hunkLines: string[] = [];\n for (const op of slicedOps) {\n if (op.op === ' ') { oldCount++; newCount++; hunkLines.push(` ${op.line}`); }\n else if (op.op === '-') { oldCount++; hunkLines.push(`-${op.line}`); }\n else { newCount++; hunkLines.push(`+${op.line}`); }\n }\n\n hunks.push({\n oldStart: firstOldLine,\n oldCount,\n newStart: firstNewLine,\n newCount,\n lines: hunkLines,\n });\n }\n\n // Silence unused variable warning\n void oldLine;\n void newLine;\n\n const hunkStr = hunks.map((h) => {\n const header2 = `@@ -${h.oldStart},${h.oldCount} +${h.newStart},${h.newCount} @@`;\n return header2 + '\\n' + h.lines.join('\\n') + '\\n';\n }).join('');\n\n return header + hunkStr;\n}\n\n/**\n * Count added and removed lines from a unified diff string.\n */\nexport function countDiffLines(diff: string): { added: number; removed: number } {\n const lines = diff.split('\\n');\n let added = 0;\n let removed = 0;\n for (const line of lines) {\n if (line.startsWith('+') && !line.startsWith('+++')) {added++;}\n if (line.startsWith('-') && !line.startsWith('---')) {removed++;}\n }\n return { added, removed };\n}\n"]}
package/package.json CHANGED
@@ -1,11 +1,10 @@
1
1
  {
2
2
  "name": "@kb-labs/agent-history",
3
- "version": "2.34.0",
4
3
  "description": "File change history, snapshots and conflict resolution for KB Labs Agents",
5
- "files": [
6
- "dist"
7
- ],
4
+ "version": "2.35.0",
8
5
  "type": "module",
6
+ "author": "KB Labs",
7
+ "license": "MIT",
9
8
  "main": "./dist/index.js",
10
9
  "types": "./dist/index.d.ts",
11
10
  "exports": {
@@ -14,8 +13,11 @@
14
13
  "import": "./dist/index.js"
15
14
  }
16
15
  },
16
+ "files": [
17
+ "dist"
18
+ ],
17
19
  "dependencies": {
18
- "@kb-labs/agent-contracts": "2.34.0"
20
+ "@kb-labs/agent-contracts": "2.35.0"
19
21
  },
20
22
  "devDependencies": {
21
23
  "@types/node": "^24.3.3",
@@ -23,29 +25,27 @@
23
25
  "tsup": "^8.5.0",
24
26
  "typescript": "^5.6.3",
25
27
  "vitest": "^3.2.4",
26
- "@kb-labs/devkit": "2.34.0"
28
+ "@kb-labs/devkit": "2.35.0"
27
29
  },
28
- "keywords": [
29
- "kb-labs",
30
- "agents",
31
- "history",
32
- "snapshots",
33
- "conflict-resolution"
34
- ],
35
- "author": "KB Labs",
36
- "license": "MIT",
37
30
  "engines": {
38
31
  "node": ">=20.0.0",
39
32
  "pnpm": ">=9.0.0"
40
33
  },
34
+ "keywords": [
35
+ "agents",
36
+ "conflict-resolution",
37
+ "history",
38
+ "kb-labs",
39
+ "snapshots"
40
+ ],
41
41
  "scripts": {
42
42
  "build": "tsup",
43
- "dev": "tsup --watch",
44
43
  "clean": "rimraf dist",
45
- "type-check": "tsc --noEmit",
44
+ "dev": "tsup --watch",
46
45
  "lint": "eslint src --ext .ts",
47
46
  "lint:fix": "eslint . --fix",
48
47
  "test": "vitest run --passWithNoTests",
49
- "test:watch": "vitest"
48
+ "test:watch": "vitest",
49
+ "type-check": "tsc --noEmit"
50
50
  }
51
51
  }