crewswarm-cli 0.1.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/LICENSE +21 -0
- package/README.md +209 -0
- package/bin/crew.js +94 -0
- package/dist/crew.mjs +22964 -0
- package/dist/crew.mjs.map +7 -0
- package/dist/engine.mjs +3381 -0
- package/dist/engine.mjs.map +7 -0
- package/dist/memory.mjs +850 -0
- package/dist/memory.mjs.map +7 -0
- package/package.json +113 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/memory/agentkeeper.ts", "../src/pipeline/agent-memory.ts", "../src/memory/broker.ts", "../src/collections/index.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * AgentKeeper \u2014 cross-tier persistent task memory.\n *\n * Stores planner decisions, worker outputs, and task results in a local\n * append-only JSONL store (`.crew/agentkeeper.jsonl`). Supports retrieval\n * of prior entries by task similarity so repeated tasks can reuse earlier\n * decomposition patterns. Compaction keeps the store bounded.\n */\n\nimport { appendFile, mkdir, readFile, stat, writeFile } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport { randomUUID } from 'node:crypto';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface MemoryEntry {\n id: string;\n runId: string;\n tier: 'planner' | 'worker' | 'orchestrator';\n task: string;\n result: string;\n structured?: {\n problem?: string;\n plan?: string[];\n edits?: Array<{ path?: string; summary?: string }>;\n validation?: { lintPassed?: boolean; testsPassed?: boolean; notes?: string };\n outcome?: string;\n };\n agent?: string;\n model?: string;\n metadata?: Record<string, unknown>;\n timestamp: string;\n}\n\nexport interface MemoryMatch {\n entry: MemoryEntry;\n score: number;\n}\n\nexport interface CompactionResult {\n entriesBefore: number;\n entriesAfter: number;\n bytesFreed: number;\n}\n\ninterface AgentKeeperOptions {\n storageDir?: string;\n maxEntries?: number;\n maxBytes?: number;\n maxAgeDays?: number;\n autoCompactEvery?: number;\n semanticDedupe?: boolean;\n dedupeThreshold?: number;\n}\n\ninterface RecallOptions {\n preferSuccessful?: boolean;\n pathHints?: string[];\n nowMs?: number;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction tokenize(text: string): Set<string> {\n return new Set(\n text\n .toLowerCase()\n .replace(/[^a-z0-9\\s_-]/g, ' ')\n .split(/\\s+/)\n .filter(t => t.length > 2)\n );\n}\n\nfunction similarity(a: Set<string>, b: Set<string>): number {\n if (a.size === 0 || b.size === 0) return 0;\n let intersection = 0;\n for (const token of a) {\n if (b.has(token)) intersection++;\n }\n return intersection / Math.max(a.size, b.size);\n}\n\n// ---------------------------------------------------------------------------\n// AgentKeeper class\n// ---------------------------------------------------------------------------\n\nexport class AgentKeeper {\n private storePath: string;\n private maxEntries: number;\n private maxBytes: number;\n private maxAgeDays: number;\n private autoCompactEvery: number;\n private semanticDedupe: boolean;\n private dedupeThreshold: number;\n private writeCount = 0;\n\n constructor(baseDir: string, options: AgentKeeperOptions = {}) {\n const storageBase = options.storageDir || process.env.CREW_MEMORY_DIR || baseDir;\n this.storePath = join(storageBase, '.crew', 'agentkeeper.jsonl');\n this.maxEntries = options.maxEntries ?? 500;\n this.maxBytes = options.maxBytes ?? 2_000_000;\n this.maxAgeDays = options.maxAgeDays ?? 30;\n this.autoCompactEvery = options.autoCompactEvery ?? 20;\n this.semanticDedupe = options.semanticDedupe ?? true;\n this.dedupeThreshold = options.dedupeThreshold ?? 0.9;\n }\n\n private redactText(input: string): string {\n let out = String(input || '');\n const replacements: Array<[RegExp, string]> = [\n [/\\bsk-[A-Za-z0-9]{16,}\\b/g, '[REDACTED_API_KEY]'],\n [/\\b(?:ghp|gho|ghu|ghs|github_pat)_[A-Za-z0-9_]{16,}\\b/g, '[REDACTED_GITHUB_TOKEN]'],\n [/\\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}\\b/gi, '[REDACTED_EMAIL]'],\n [/\\beyJ[A-Za-z0-9_\\-]{8,}\\.[A-Za-z0-9_\\-]{8,}\\.[A-Za-z0-9_\\-]{8,}\\b/g, '[REDACTED_JWT]'],\n [/\\b[A-Fa-f0-9]{40,}\\b/g, '[REDACTED_HEX_TOKEN]'],\n [/\\b[A-Za-z0-9+/]{80,}={0,2}\\b/g, '[REDACTED_BASE64_BLOB]']\n ];\n for (const [rx, replacement] of replacements) {\n out = out.replace(rx, replacement);\n }\n return out;\n }\n\n private sanitizeText(input: string, maxChars = 6000): string {\n const redacted = this.redactText(String(input || ''));\n if (redacted.length <= maxChars) return redacted;\n return `${redacted.slice(0, maxChars)}\\n... [truncated ${redacted.length - maxChars} chars]`;\n }\n\n private sanitizeMetadata(value: unknown, depth = 0): unknown {\n if (depth > 3) return '[TRUNCATED_DEPTH]';\n if (value === null || value === undefined) return value;\n if (typeof value === 'string') return this.sanitizeText(value, 1000);\n if (typeof value === 'number' || typeof value === 'boolean') return value;\n if (Array.isArray(value)) return value.slice(0, 50).map(item => this.sanitizeMetadata(item, depth + 1));\n if (typeof value === 'object') {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value as Record<string, unknown>).slice(0, 100)) {\n out[k] = this.sanitizeMetadata(v, depth + 1);\n }\n return out;\n }\n return String(value);\n }\n\n private normalizeStructured(structured: MemoryEntry['structured']): MemoryEntry['structured'] | undefined {\n if (!structured) return undefined;\n const out: NonNullable<MemoryEntry['structured']> = {};\n if (structured.problem) out.problem = this.sanitizeText(structured.problem, 1200);\n if (Array.isArray(structured.plan)) {\n out.plan = structured.plan.slice(0, 50).map(step => this.sanitizeText(step, 300));\n }\n if (Array.isArray(structured.edits)) {\n out.edits = structured.edits.slice(0, 100).map(edit => ({\n path: edit.path ? this.sanitizeText(edit.path, 300) : undefined,\n summary: edit.summary ? this.sanitizeText(edit.summary, 300) : undefined\n }));\n }\n if (structured.validation) {\n out.validation = {\n lintPassed: Boolean(structured.validation.lintPassed),\n testsPassed: Boolean(structured.validation.testsPassed),\n notes: structured.validation.notes ? this.sanitizeText(structured.validation.notes, 600) : undefined\n };\n }\n if (structured.outcome) out.outcome = this.sanitizeText(structured.outcome, 600);\n return out;\n }\n\n private estimateStoreBytes(entries: MemoryEntry[]): number {\n return entries.reduce((sum, entry) => sum + Buffer.byteLength(JSON.stringify(entry) + '\\n', 'utf8'), 0);\n }\n\n private pruneEntries(entries: MemoryEntry[]): MemoryEntry[] {\n const now = Date.now();\n const maxAgeMs = Math.max(1, this.maxAgeDays) * 24 * 60 * 60 * 1000;\n let kept = entries.filter(entry => {\n const ts = Date.parse(entry.timestamp || '');\n if (!Number.isFinite(ts)) return true;\n return now - ts <= maxAgeMs;\n });\n\n if (kept.length > this.maxEntries) {\n kept = kept.slice(-this.maxEntries);\n }\n\n while (kept.length > 1 && this.estimateStoreBytes(kept) > this.maxBytes) {\n kept = kept.slice(1);\n }\n\n return kept;\n }\n\n private dedupeSemantically(entries: MemoryEntry[]): MemoryEntry[] {\n if (!this.semanticDedupe || entries.length < 2) return entries;\n\n const keptNewestFirst: MemoryEntry[] = [];\n const keptTokens: Array<Set<string>> = [];\n const descending = entries.slice().reverse();\n\n for (const entry of descending) {\n const entryText = `${entry.task || ''}\\n${String(entry.result || '').slice(0, 1200)}`;\n const entryTokenSet = tokenize(entryText);\n if (entryTokenSet.size < 6) {\n keptNewestFirst.push(entry);\n keptTokens.push(entryTokenSet);\n continue;\n }\n let duplicate = false;\n\n for (let i = 0; i < keptNewestFirst.length; i += 1) {\n const existing = keptNewestFirst[i];\n if (existing.tier !== entry.tier) continue;\n if ((existing.agent || '') !== (entry.agent || '')) continue;\n if (keptTokens[i].size < 6) continue;\n const sim = similarity(entryTokenSet, keptTokens[i]);\n if (sim >= this.dedupeThreshold) {\n duplicate = true;\n break;\n }\n }\n\n if (!duplicate) {\n keptNewestFirst.push(entry);\n keptTokens.push(entryTokenSet);\n }\n }\n\n return keptNewestFirst.reverse();\n }\n\n private async maybeAutoCompact(): Promise<void> {\n this.writeCount += 1;\n if (this.writeCount % this.autoCompactEvery !== 0) return;\n try {\n await this.compact();\n } catch {\n // Never fail runtime flows due to maintenance compaction.\n }\n }\n\n /** Append a new memory entry. */\n async record(entry: Omit<MemoryEntry, 'id' | 'timestamp'>): Promise<MemoryEntry> {\n await mkdir(dirname(this.storePath), { recursive: true });\n const full: MemoryEntry = {\n ...entry,\n id: randomUUID(),\n task: this.sanitizeText(entry.task, 1200),\n result: this.sanitizeText(entry.result, 6000),\n structured: this.normalizeStructured(entry.structured),\n metadata: this.sanitizeMetadata(entry.metadata) as Record<string, unknown> | undefined,\n timestamp: new Date().toISOString()\n };\n const line = JSON.stringify(full) + '\\n';\n await appendFile(this.storePath, line, 'utf8');\n await this.maybeAutoCompact();\n return full;\n }\n\n /** Best-effort append: never throws, returns success state. */\n async recordSafe(entry: Omit<MemoryEntry, 'id' | 'timestamp'>): Promise<{ ok: boolean; entry?: MemoryEntry; error?: string }> {\n try {\n const saved = await this.record(entry);\n return { ok: true, entry: saved };\n } catch (error) {\n return { ok: false, error: (error as Error).message };\n }\n }\n\n /** Load all entries from the JSONL store. */\n async loadAll(): Promise<MemoryEntry[]> {\n let raw: string;\n try {\n raw = await readFile(this.storePath, 'utf8');\n } catch {\n return [];\n }\n const entries: MemoryEntry[] = [];\n for (const line of raw.split('\\n')) {\n if (!line.trim()) continue;\n try {\n entries.push(JSON.parse(line));\n } catch {\n // skip malformed lines\n }\n }\n return entries;\n }\n\n /**\n * Retrieve entries similar to the given task description.\n * Returns up to `maxResults` matches sorted by similarity score descending.\n */\n async recall(task: string, maxResults = 5, options: RecallOptions = {}): Promise<MemoryMatch[]> {\n const entries = await this.loadAll();\n if (entries.length === 0) return [];\n\n const queryTokens = tokenize(task);\n const now = options.nowMs || Date.now();\n const hints = new Set((options.pathHints || []).map(x => String(x || '').trim()).filter(Boolean));\n const scored: MemoryMatch[] = [];\n\n for (const entry of entries) {\n const entryTokens = tokenize(entry.task);\n const sim = similarity(queryTokens, entryTokens);\n\n let recencyBoost = 0;\n const ts = Date.parse(entry.timestamp || '');\n if (Number.isFinite(ts)) {\n const ageDays = Math.max(0, (now - ts) / (24 * 60 * 60 * 1000));\n recencyBoost = Math.max(0, 1 - Math.min(ageDays, 30) / 30) * 0.15;\n }\n\n let successBoost = 0;\n const success = Boolean((entry.metadata as any)?.success)\n || Boolean(entry.structured?.outcome?.toLowerCase().includes('success'));\n if (options.preferSuccessful !== false && success) {\n successBoost = 0.1;\n }\n\n let pathBoost = 0;\n if (hints.size > 0) {\n const entryPaths = new Set<string>();\n for (const edit of entry.structured?.edits || []) {\n if (edit.path) entryPaths.add(edit.path);\n }\n const metadataPaths = (entry.metadata as any)?.paths;\n if (Array.isArray(metadataPaths)) {\n for (const p of metadataPaths) {\n entryPaths.add(String(p || ''));\n }\n }\n let overlap = 0;\n for (const h of hints) {\n if (entryPaths.has(h)) overlap += 1;\n }\n if (overlap > 0) {\n pathBoost = Math.min(0.2, overlap / Math.max(1, hints.size) * 0.2);\n }\n }\n\n const score = sim + recencyBoost + successBoost + pathBoost;\n if (score > 0.15) {\n scored.push({ entry, score: Math.round(score * 100) / 100 });\n }\n }\n\n scored.sort((a, b) => b.score - a.score);\n return scored.slice(0, maxResults);\n }\n\n /**\n * Format recalled memories into a context block for prompt injection.\n * Recent entries shown full, older entries compressed (progressive disclosure pattern).\n */\n async recallAsContext(task: string, maxResults = 3, options: RecallOptions = {}): Promise<string> {\n const matches = await this.recall(task, maxResults, options);\n if (matches.length === 0) return '';\n\n const lines = ['## Prior Task Memory'];\n const keepFullCount = Math.min(5, Math.ceil(matches.length * 0.5)); // Keep top 50% full\n \n for (let i = 0; i < matches.length; i++) {\n const m = matches[i];\n const isFull = i < keepFullCount;\n \n // Full version for recent/high-scoring entries\n if (isFull) {\n const resultPreview = m.entry.result.length > 400\n ? m.entry.result.slice(0, 400) + '...'\n : m.entry.result;\n lines.push(`### [${m.entry.tier}] ${m.entry.task} (score: ${m.score})`);\n if (m.entry.agent) lines.push(`Agent: ${m.entry.agent}`);\n lines.push(`Result: ${resultPreview}`);\n lines.push('');\n } else {\n // Compressed version for older/lower-scoring entries\n const hasError = /error|failed|exception/i.test(m.entry.result);\n const statusIcon = hasError ? '\u274C' : '\u2713';\n const preview = m.entry.result.slice(0, 120);\n lines.push(`### ${statusIcon} [${m.entry.tier}] ${m.entry.task}`);\n lines.push(`${preview}... [${hasError ? 'failed' : 'completed'}]`);\n lines.push('');\n }\n }\n return lines.join('\\n');\n }\n\n /**\n * Compact the store: keep only the most recent `maxEntries` entries.\n */\n async compact(): Promise<CompactionResult> {\n const entries = await this.loadAll();\n const entriesBefore = entries.length;\n\n let bytesBefore = 0;\n try {\n const st = await stat(this.storePath);\n bytesBefore = st.size;\n } catch {\n bytesBefore = 0;\n }\n\n const deduped = this.dedupeSemantically(entries);\n const kept = this.pruneEntries(deduped);\n if (kept.length === entries.length) {\n return { entriesBefore, entriesAfter: kept.length, bytesFreed: 0 };\n }\n const content = kept.map(e => JSON.stringify(e)).join('\\n') + '\\n';\n await writeFile(this.storePath, content, 'utf8');\n\n let bytesAfter = 0;\n try {\n const st = await stat(this.storePath);\n bytesAfter = st.size;\n } catch {\n bytesAfter = content.length;\n }\n\n return {\n entriesBefore,\n entriesAfter: kept.length,\n bytesFreed: Math.max(0, bytesBefore - bytesAfter)\n };\n }\n\n /** Get summary stats. */\n async stats(): Promise<{ entries: number; byTier: Record<string, number>; byAgent: Record<string, number>; bytes: number }> {\n const entries = await this.loadAll();\n const byTier: Record<string, number> = {};\n const byAgent: Record<string, number> = {};\n for (const e of entries) {\n byTier[e.tier] = (byTier[e.tier] || 0) + 1;\n if (e.agent) byAgent[e.agent] = (byAgent[e.agent] || 0) + 1;\n }\n return { entries: entries.length, byTier, byAgent, bytes: this.estimateStoreBytes(entries) };\n }\n}\n", "/**\n * AgentMemory - Cognitive persistence layer for cross-model memory continuity\n * Inspired by AgentKeeper (https://github.com/Thinklanceai/agentkeeper)\n * \n * Extends ContextPackManager with:\n * - Critical fact prioritization\n * - Cross-provider memory persistence\n * - Token budget management\n * - Provider-agnostic context injection\n */\n\nimport { randomUUID } from 'node:crypto';\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\n\nexport interface MemoryFact {\n id: string;\n content: string;\n critical: boolean;\n timestamp: string;\n tags: string[];\n provider?: string;\n}\n\nexport interface AgentMemoryState {\n agentId: string;\n facts: MemoryFact[];\n createdAt: string;\n updatedAt: string;\n}\n\nexport class AgentMemory {\n private state: AgentMemoryState;\n private storageDir: string;\n\n constructor(agentId: string, options?: { storageDir?: string }) {\n // Use CREW_MEMORY_DIR for shared cross-system memory, or local dir for CLI-only\n const baseDir = options?.storageDir || \n process.env.CREW_MEMORY_DIR || \n process.cwd();\n this.storageDir = resolve(baseDir, '.crew', 'agent-memory');\n this.ensureStorageDir();\n this.state = this.loadOrCreate(agentId);\n }\n\n /**\n * Store a fact in agent memory\n */\n remember(content: string, options: {\n critical?: boolean;\n tags?: string[];\n provider?: string;\n } = {}): string {\n const fact: MemoryFact = {\n id: randomUUID(),\n content,\n critical: options.critical || false,\n timestamp: new Date().toISOString(),\n tags: options.tags || [],\n provider: options.provider\n };\n\n this.state.facts.push(fact);\n this.state.updatedAt = new Date().toISOString();\n this.persist();\n return fact.id;\n }\n\n /**\n * Remove a fact by ID\n */\n forget(factId: string): boolean {\n const before = this.state.facts.length;\n this.state.facts = this.state.facts.filter(f => f.id !== factId);\n if (this.state.facts.length < before) {\n this.state.updatedAt = new Date().toISOString();\n this.persist();\n return true;\n }\n return false;\n }\n\n /**\n * Recall facts optimized for current context\n * Priority: critical facts first, then most recent\n */\n recall(options: {\n tokenBudget?: number;\n criticalOnly?: boolean;\n tags?: string[];\n provider?: string;\n } = {}): string {\n const budget = options.tokenBudget || 2000;\n const estimatedCharsPerToken = 4; // Conservative estimate\n const charBudget = budget * estimatedCharsPerToken;\n\n // Filter facts\n let facts = this.state.facts;\n \n if (options.criticalOnly) {\n facts = facts.filter(f => f.critical);\n }\n \n if (options.tags && options.tags.length > 0) {\n facts = facts.filter(f => \n options.tags!.some(tag => f.tags.includes(tag))\n );\n }\n\n if (options.provider) {\n facts = facts.filter(f => !f.provider || f.provider === options.provider);\n }\n\n // Sort: critical first, then newest\n facts.sort((a, b) => {\n if (a.critical && !b.critical) return -1;\n if (!a.critical && b.critical) return 1;\n return new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime();\n });\n\n // Pack into budget\n const selected: MemoryFact[] = [];\n let used = 0;\n\n for (const fact of facts) {\n const block = `[${fact.critical ? 'CRITICAL' : 'INFO'}] ${fact.content}\\n`;\n if (used + block.length > charBudget) break;\n selected.push(fact);\n used += block.length;\n }\n\n if (selected.length === 0) return '';\n\n // Format for injection\n const header = '=== AGENT MEMORY (Context from previous decisions) ===\\n';\n const body = selected.map(f => \n `[${f.critical ? 'CRITICAL' : 'INFO'}] ${f.content}`\n ).join('\\n');\n const footer = '\\n=== END AGENT MEMORY ===\\n';\n\n return header + body + footer;\n }\n\n /**\n * Search facts by lexical similarity for brokered retrieval.\n */\n search(query: string, options: {\n maxResults?: number;\n tags?: string[];\n provider?: string;\n } = {}): MemoryFact[] {\n const maxResults = Math.max(1, Number(options.maxResults || 5));\n const qTokens = new Set(\n String(query || '')\n .toLowerCase()\n .replace(/[^a-z0-9\\s_-]/g, ' ')\n .split(/\\s+/)\n .filter(t => t.length > 2)\n );\n\n let facts = this.state.facts.slice();\n if (options.tags && options.tags.length > 0) {\n facts = facts.filter(f => options.tags!.some(tag => f.tags.includes(tag)));\n }\n if (options.provider) {\n facts = facts.filter(f => !f.provider || f.provider === options.provider);\n }\n\n const score = (fact: MemoryFact): number => {\n const toks = new Set(\n String(fact.content || '')\n .toLowerCase()\n .replace(/[^a-z0-9\\s_-]/g, ' ')\n .split(/\\s+/)\n .filter(t => t.length > 2)\n );\n if (qTokens.size === 0 || toks.size === 0) return 0;\n let inter = 0;\n for (const t of qTokens) {\n if (toks.has(t)) inter += 1;\n }\n const sim = inter / Math.max(qTokens.size, toks.size);\n return sim + (fact.critical ? 0.1 : 0);\n };\n\n const ranked = facts\n .map(f => ({ fact: f, score: score(f) }))\n .filter(x => x.score > 0.12)\n .sort((a, b) => b.score - a.score)\n .slice(0, maxResults)\n .map(x => x.fact);\n\n return ranked;\n }\n\n /**\n * Get memory statistics\n */\n stats(): {\n totalFacts: number;\n criticalFacts: number;\n providers: string[];\n oldestFact: string | null;\n newestFact: string | null;\n } {\n const facts = this.state.facts || [];\n const timestamps = facts.map(f => f.timestamp).sort();\n const providers = Array.from(new Set(\n facts.map(f => f.provider).filter(Boolean) as string[]\n ));\n\n return {\n totalFacts: facts.length,\n criticalFacts: facts.filter(f => f.critical).length,\n providers,\n oldestFact: timestamps[0] || null,\n newestFact: timestamps[timestamps.length - 1] || null\n };\n }\n\n /**\n * Clear all facts (useful for testing)\n */\n clear(): void {\n this.state.facts = [];\n this.state.updatedAt = new Date().toISOString();\n this.persist();\n }\n\n private loadOrCreate(agentId: string): AgentMemoryState {\n const path = this.getStatePath(agentId);\n \n if (existsSync(path)) {\n try {\n const raw = readFileSync(path, 'utf8');\n return JSON.parse(raw);\n } catch (err) {\n console.warn(`[AgentMemory] Failed to load state for ${agentId}, creating new`);\n }\n }\n\n const now = new Date().toISOString();\n return {\n agentId,\n facts: [],\n createdAt: now,\n updatedAt: now\n };\n }\n\n private persist(): void {\n const path = this.getStatePath(this.state.agentId);\n writeFileSync(path, JSON.stringify(this.state, null, 2), 'utf8');\n }\n\n private getStatePath(agentId: string): string {\n return join(this.storageDir, `${agentId}.json`);\n }\n\n private ensureStorageDir(): void {\n if (!existsSync(this.storageDir)) {\n mkdirSync(this.storageDir, { recursive: true });\n }\n }\n}\n\n/**\n * Global memory instance for pipeline-wide memory\n */\nlet _pipelineMemory: AgentMemory | null = null;\n\nexport function getPipelineMemory(agentId: string = 'pipeline'): AgentMemory {\n if (!_pipelineMemory) {\n _pipelineMemory = new AgentMemory(agentId);\n }\n return _pipelineMemory;\n}\n\n/**\n * Get or create a crew-wide memory instance (shared across CLI and gateway)\n */\nexport function getCrewMemory(crewId: string = 'crew-lead'): AgentMemory {\n // Always create fresh instance to ensure latest state from shared storage\n return new AgentMemory(crewId);\n}\n", "import { resolve, join } from 'node:path';\nimport { AgentKeeper, type MemoryMatch } from './agentkeeper.js';\nimport { AgentMemory, type MemoryFact } from '../pipeline/agent-memory.js';\nimport { buildCollectionIndex, searchCollection, type CollectionChunk } from '../collections/index.js';\n\nexport interface BrokerHit {\n source: 'agentkeeper' | 'agent-memory' | 'collections';\n score: number;\n title: string;\n text: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface BrokerRecallOptions {\n maxResults?: number;\n includeDocs?: boolean;\n includeCode?: boolean;\n docsPaths?: string[];\n preferSuccessful?: boolean;\n pathHints?: string[];\n}\n\nfunction tokenize(text: string): Set<string> {\n return new Set(\n String(text || '')\n .toLowerCase()\n .replace(/[^a-z0-9\\s_-]/g, ' ')\n .split(/\\s+/)\n .filter(t => t.length > 2)\n );\n}\n\nfunction similarity(a: Set<string>, b: Set<string>): number {\n if (a.size === 0 || b.size === 0) return 0;\n let intersection = 0;\n for (const token of a) {\n if (b.has(token)) intersection += 1;\n }\n return intersection / Math.max(a.size, b.size);\n}\n\nfunction mapKeeperHit(m: MemoryMatch): BrokerHit {\n return {\n source: 'agentkeeper',\n score: Number(m.score || 0),\n title: `[${m.entry.tier}] ${m.entry.task}`,\n text: m.entry.result,\n metadata: {\n agent: m.entry.agent,\n runId: m.entry.runId,\n timestamp: m.entry.timestamp\n }\n };\n}\n\nfunction mapFactHit(f: MemoryFact, score: number): BrokerHit {\n return {\n source: 'agent-memory',\n score: Number(score.toFixed(3)),\n title: `[${f.critical ? 'CRITICAL' : 'INFO'}] ${f.tags.join(', ') || 'memory-fact'}`,\n text: f.content,\n metadata: {\n critical: f.critical,\n tags: f.tags,\n timestamp: f.timestamp,\n provider: f.provider\n }\n };\n}\n\nfunction mapCollectionHit(c: CollectionChunk): BrokerHit {\n return {\n source: 'collections',\n score: Number(c.score || 0),\n title: `${c.source}:${c.startLine}`,\n text: c.text,\n metadata: {\n path: c.source,\n startLine: c.startLine\n }\n };\n}\n\nfunction normalizeCollectionPathForDedupe(input: string): string {\n const value = String(input || '').replace(/\\\\/g, '/').replace(/^\\.\\/+/, '');\n if (value.startsWith('docs/')) return value.slice('docs/'.length);\n return value;\n}\n\nexport class MemoryBroker {\n private readonly projectDir: string;\n private readonly keeper: AgentKeeper;\n private readonly factMemory: AgentMemory;\n private readonly docsIndexCache = new Map<string, Awaited<ReturnType<typeof buildCollectionIndex>>>();\n\n constructor(projectDir: string, options: { crewId?: string; storageDir?: string } = {}) {\n this.projectDir = resolve(projectDir);\n this.keeper = new AgentKeeper(this.projectDir, {\n storageDir: options.storageDir || process.env.CREW_MEMORY_DIR\n });\n this.factMemory = new AgentMemory(options.crewId || 'crew-lead', {\n storageDir: options.storageDir || process.env.CREW_MEMORY_DIR || this.projectDir\n });\n }\n\n private scoreFacts(query: string, facts: MemoryFact[], max: number): BrokerHit[] {\n const queryTokens = tokenize(query);\n const scored = facts.map(f => {\n const sim = similarity(queryTokens, tokenize(f.content));\n const criticalBoost = f.critical ? 0.3 : 0; // Increased from 0.1\n const tagBoost = f.tags.some(t => query.toLowerCase().includes(t.toLowerCase())) ? 0.15 : 0;\n return { fact: f, score: sim + criticalBoost + tagBoost };\n }).filter(x => x.score > 0.08); // Lowered from 0.12 to catch critical facts\n\n // Force critical facts to top even if similarity is lower\n scored.sort((a, b) => {\n if (a.fact.critical && !b.fact.critical) return -1;\n if (!a.fact.critical && b.fact.critical) return 1;\n return b.score - a.score;\n });\n \n return scored.slice(0, max).map(x => mapFactHit(x.fact, x.score));\n }\n\n private async getDocsIndex(paths: string[], includeCode: boolean) {\n const key = `${paths.map(p => resolve(p)).join('|')}::${includeCode ? 'code' : 'docs'}`;\n if (this.docsIndexCache.has(key)) return this.docsIndexCache.get(key)!;\n const idx = await buildCollectionIndex(paths, { includeCode });\n this.docsIndexCache.set(key, idx);\n return idx;\n }\n\n async recall(query: string, options: BrokerRecallOptions = {}): Promise<BrokerHit[]> {\n const maxResults = Math.max(1, Number(options.maxResults || 5));\n const includeDocs = options.includeDocs !== false;\n const includeCode = Boolean(options.includeCode);\n const docsPaths = (options.docsPaths && options.docsPaths.length > 0)\n ? options.docsPaths\n : [join(this.projectDir, 'docs'), this.projectDir];\n\n const [keeperHits, factHits, collectionHits] = await Promise.all([\n this.keeper.recall(query, Math.max(maxResults, 8), {\n preferSuccessful: options.preferSuccessful !== false,\n pathHints: options.pathHints || []\n }),\n this.factMemory.search(query, { maxResults: Math.max(maxResults, 8) }),\n includeDocs\n ? (async () => {\n const index = await this.getDocsIndex(docsPaths, includeCode);\n return searchCollection(index, query, Math.max(maxResults, 8)).hits;\n })()\n : Promise.resolve([])\n ]);\n\n const merged = [\n ...keeperHits.map(mapKeeperHit),\n ...this.scoreFacts(query, factHits, Math.max(maxResults, 8)),\n ...collectionHits.map(mapCollectionHit)\n ];\n\n merged.sort((a, b) => b.score - a.score);\n\n // Dedupe near-identical collection hits that appear when both docs/ and repo root\n // are indexed together (same chunk can be surfaced twice with different source paths).\n const seen = new Set<string>();\n const deduped: BrokerHit[] = [];\n for (const hit of merged) {\n let signature = `${hit.source}|${hit.title}|${hit.text.slice(0, 180)}`;\n if (hit.source === 'collections') {\n const path = normalizeCollectionPathForDedupe(String(hit.metadata?.path || hit.title.split(':')[0] || ''));\n const startLine = Number(hit.metadata?.startLine || 0);\n signature = `${hit.source}|${path}|${startLine}|${hit.text.slice(0, 220)}`;\n }\n if (seen.has(signature)) continue;\n seen.add(signature);\n deduped.push(hit);\n if (deduped.length >= maxResults) break;\n }\n return deduped;\n }\n\n async recallAsContext(query: string, options: BrokerRecallOptions = {}): Promise<string> {\n const hits = await this.recall(query, options);\n if (hits.length === 0) return '';\n const lines = ['## Shared Memory + RAG Context'];\n for (const h of hits) {\n const preview = h.text.length > 260 ? `${h.text.slice(0, 260)}...` : h.text;\n lines.push(`### [${h.source}] ${h.title} (score: ${h.score.toFixed(3)})`);\n lines.push(preview);\n lines.push('');\n }\n return lines.join('\\n');\n }\n}\n", "/**\n * Collections Search \u2014 lightweight local RAG over docs and markdown files.\n *\n * Indexes markdown / text files under configurable paths, builds a simple\n * TF-IDF\u2013style term index, and returns ranked chunks with source attribution.\n */\n\nimport { readdir, readFile, stat } from 'node:fs/promises';\nimport { extname, join, relative, resolve } from 'node:path';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface CollectionChunk {\n /** Relative path from the collection root */\n source: string;\n /** 1-based line number where the chunk starts */\n startLine: number;\n /** The raw text of the chunk */\n text: string;\n /** Relevance score (higher = more relevant) */\n score: number;\n}\n\nexport interface CollectionIndex {\n root: string;\n fileCount: number;\n chunkCount: number;\n /** term \u2192 Set of chunk indices */\n terms: Map<string, Set<number>>;\n chunks: CollectionChunk[];\n}\n\nexport interface BuildCollectionOptions {\n includeCode?: boolean;\n}\n\nexport interface SearchResult {\n query: string;\n hits: CollectionChunk[];\n totalChunks: number;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nconst DOC_EXTENSIONS = new Set(['.md', '.mdx', '.txt', '.rst', '.adoc']);\nconst CODE_EXTENSIONS = new Set([\n '.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs', '.json',\n '.py', '.go', '.rs', '.java', '.kt', '.swift',\n '.sh', '.bash', '.zsh', '.yaml', '.yml', '.toml'\n]);\n\nconst IGNORED_DIRS = new Set([\n 'node_modules', '.git', 'dist', 'build', '.crew',\n '.next', '.turbo', 'coverage', '__pycache__'\n]);\n\nfunction tokenize(text: string): string[] {\n return text\n .toLowerCase()\n .replace(/[^a-z0-9\\s_-]/g, ' ')\n .split(/\\s+/)\n .filter(t => t.length > 1);\n}\n\nfunction hashToken(token: string, dim: number): number {\n let h = 2166136261;\n for (let i = 0; i < token.length; i++) {\n h ^= token.charCodeAt(i);\n h = Math.imul(h, 16777619);\n }\n return Math.abs(h) % dim;\n}\n\nfunction toHashedVector(text: string, dim = 256): Float64Array {\n const vec = new Float64Array(dim);\n const toks = tokenize(text);\n for (const t of toks) {\n vec[hashToken(t, dim)] += 1;\n }\n // l2 normalize\n let norm = 0;\n for (let i = 0; i < dim; i++) norm += vec[i] * vec[i];\n norm = Math.sqrt(norm);\n if (norm > 0) {\n for (let i = 0; i < dim; i++) vec[i] /= norm;\n }\n return vec;\n}\n\nfunction cosineSimilarity(a: Float64Array, b: Float64Array): number {\n const dim = Math.min(a.length, b.length);\n let dot = 0;\n for (let i = 0; i < dim; i++) {\n dot += a[i] * b[i];\n }\n return dot;\n}\n\n/**\n * Split a file into chunks \u2014 one chunk per heading section, or fixed-size\n * paragraphs for files without headings.\n */\nfunction chunkFile(content: string, source: string): CollectionChunk[] {\n const lines = content.split('\\n');\n const chunks: CollectionChunk[] = [];\n let currentLines: string[] = [];\n let currentStart = 1;\n\n const flush = () => {\n const text = currentLines.join('\\n').trim();\n if (text.length > 0) {\n chunks.push({ source, startLine: currentStart, text, score: 0 });\n }\n currentLines = [];\n };\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n // Split on markdown headings\n if (/^#{1,4}\\s/.test(line) && currentLines.length > 0) {\n flush();\n currentStart = i + 1;\n }\n currentLines.push(line);\n\n // Also split on large paragraphs (every ~40 lines if no heading)\n if (currentLines.length >= 40 && !/^#{1,4}\\s/.test(line)) {\n flush();\n currentStart = i + 2;\n }\n }\n flush();\n return chunks;\n}\n\n// ---------------------------------------------------------------------------\n// Walk & Index\n// ---------------------------------------------------------------------------\n\nasync function walkDocs(rootDir: string, includeCode = false): Promise<string[]> {\n const files: string[] = [];\n\n async function walk(dir: string) {\n let entries: string[];\n try {\n entries = await readdir(dir);\n } catch {\n return;\n }\n for (const entry of entries) {\n if (IGNORED_DIRS.has(entry)) continue;\n const fullPath = join(dir, entry);\n let st;\n try {\n st = await stat(fullPath);\n } catch {\n continue;\n }\n if (st.isDirectory()) {\n await walk(fullPath);\n } else {\n const ext = extname(entry).toLowerCase();\n if (DOC_EXTENSIONS.has(ext) || (includeCode && CODE_EXTENSIONS.has(ext))) {\n files.push(fullPath);\n }\n }\n }\n }\n\n await walk(rootDir);\n return files;\n}\n\nexport async function buildCollectionIndex(\n paths: string[],\n options: BuildCollectionOptions = {}\n): Promise<CollectionIndex> {\n const allChunks: CollectionChunk[] = [];\n const roots = paths.map(p => resolve(p));\n let fileCount = 0;\n\n for (const rootPath of roots) {\n let st;\n try {\n st = await stat(rootPath);\n } catch {\n continue;\n }\n\n const files = st.isDirectory() ? await walkDocs(rootPath, Boolean(options.includeCode)) : [rootPath];\n\n for (const file of files) {\n let content: string;\n try {\n content = await readFile(file, 'utf8');\n } catch {\n continue;\n }\n fileCount++;\n const rel = relative(resolve(rootPath, st.isDirectory() ? '.' : '..'), file);\n const chunks = chunkFile(content, rel);\n allChunks.push(...chunks);\n }\n }\n\n // Build inverted term index\n const terms = new Map<string, Set<number>>();\n for (let i = 0; i < allChunks.length; i++) {\n const tokens = tokenize(allChunks[i].text);\n for (const token of tokens) {\n if (!terms.has(token)) terms.set(token, new Set());\n terms.get(token)!.add(i);\n }\n }\n\n return {\n root: roots[0] || '.',\n fileCount,\n chunkCount: allChunks.length,\n terms,\n chunks: allChunks\n };\n}\n\n// ---------------------------------------------------------------------------\n// Search\n// ---------------------------------------------------------------------------\n\nexport function searchCollection(\n index: CollectionIndex,\n query: string,\n maxResults = 10\n): SearchResult {\n const queryTokens = tokenize(query);\n if (queryTokens.length === 0) {\n return { query, hits: [], totalChunks: index.chunkCount };\n }\n\n // Score each chunk by number of matching query terms + term rarity (IDF-like)\n const scores = new Float64Array(index.chunkCount);\n\n for (const token of queryTokens) {\n const matchingChunks = index.terms.get(token);\n if (!matchingChunks) continue;\n // IDF-like weight: rarer terms score higher\n const idf = Math.log(1 + index.chunkCount / matchingChunks.size);\n for (const idx of matchingChunks) {\n scores[idx] += idf;\n }\n }\n\n // Collect non-zero scores\n const candidates: Array<{ idx: number; score: number }> = [];\n for (let i = 0; i < scores.length; i++) {\n if (scores[i] > 0) {\n candidates.push({ idx: i, score: scores[i] });\n }\n }\n\n // Sort descending by score\n candidates.sort((a, b) => b.score - a.score);\n\n const queryVector = toHashedVector(query);\n const maxTfidf = candidates.length > 0 ? candidates[0].score : 1;\n const tfidfWeight = 0.7;\n const vectorWeight = 0.3;\n\n const hybrid = candidates.map(c => {\n const chunk = index.chunks[c.idx];\n const chunkVector = toHashedVector(chunk.text);\n const cosine = Math.max(0, cosineSimilarity(queryVector, chunkVector));\n const tfidfNorm = maxTfidf > 0 ? (c.score / maxTfidf) : 0;\n const hybridScore = (tfidfNorm * tfidfWeight) + (cosine * vectorWeight);\n return { idx: c.idx, score: hybridScore };\n });\n\n hybrid.sort((a, b) => b.score - a.score);\n\n const hits = hybrid.slice(0, maxResults).map(c => ({\n ...index.chunks[c.idx],\n score: Math.round(c.score * 1000) / 1000\n }));\n\n return { query, hits, totalChunks: index.chunkCount };\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["randomUUID", "join", "resolve", "join", "readFile", "stat", "join", "resolve", "tokenize", "tokenize", "similarity", "resolve", "join"]
|
|
7
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "crewswarm-cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Multi-model AI coding CLI with 34+ tools, multi-agent swarm, and real-time streaming — works with GPT, Claude, Gemini, Grok, DeepSeek, and more",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/crew.mjs",
|
|
7
|
+
"bin": {
|
|
8
|
+
"crew": "bin/crew.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"bin/",
|
|
12
|
+
"dist/",
|
|
13
|
+
"README.md",
|
|
14
|
+
"LICENSE"
|
|
15
|
+
],
|
|
16
|
+
"scripts": {
|
|
17
|
+
"start": "node bin/crew.js",
|
|
18
|
+
"build": "npm run build:cli && npm run build:memory && npm run build:engine",
|
|
19
|
+
"build:cli": "esbuild src/cli/index.ts --bundle --platform=node --format=esm --target=node20 --sourcemap --outfile=dist/crew.mjs --packages=external",
|
|
20
|
+
"build:memory": "esbuild src/memory/index.ts --bundle --platform=node --format=esm --target=node20 --sourcemap --outfile=dist/memory.mjs --packages=external",
|
|
21
|
+
"build:engine": "esbuild src/engine-api.ts --bundle --platform=node --format=esm --target=node20 --sourcemap --outfile=dist/engine.mjs --packages=external",
|
|
22
|
+
"test": "node --import tsx --test tests/unit/*.test.js",
|
|
23
|
+
"test:coverage": "node --import tsx --test --experimental-test-coverage tests/*.test.js tests/unit/*.test.js",
|
|
24
|
+
"qa:inventory": "node tools/qa-file-inventory.mjs",
|
|
25
|
+
"qa:smoke": "node tools/qa-command-smoke.mjs",
|
|
26
|
+
"qa:gateway-contract": "node tools/qa-gateway-contract.mjs",
|
|
27
|
+
"qa:engine-matrix": "node tools/qa-engine-matrix.mjs",
|
|
28
|
+
"qa:pm-loop": "node tools/qa-pm-loop-e2e.mjs",
|
|
29
|
+
"qa:review-strict": "node tools/qa-review-strict.mjs",
|
|
30
|
+
"qa:soak": "node tools/qa-soak-headless.mjs",
|
|
31
|
+
"qa:e2e": "npm run qa:gateway-contract && npm run qa:engine-matrix && npm run qa:pm-loop",
|
|
32
|
+
"qa:full": "npm run build && npm run test:coverage && npm run qa:inventory && npm run qa:smoke",
|
|
33
|
+
"benchmark:presets": "node scripts/benchmark-presets.mjs --tasks-file benchmarks/presets-corpus.json",
|
|
34
|
+
"benchmark:check": "node scripts/benchmark-presets.mjs --check --tasks-file benchmarks/presets-corpus.json --baseline benchmarks/presets-baseline.json",
|
|
35
|
+
"benchmark:check:ci": "node scripts/benchmark-presets.mjs --check --tasks-file benchmarks/presets-corpus.json --baseline benchmarks/presets-baseline.json --min-pass-rate 0.5 --max-regression-pct 40 --skip-if-unavailable",
|
|
36
|
+
"benchmark:baseline:update": "node scripts/benchmark-presets.mjs --update-baseline --tasks-file benchmarks/presets-corpus.json --baseline benchmarks/presets-baseline.json",
|
|
37
|
+
"typecheck": "tsc -p tsconfig.typecheck.json",
|
|
38
|
+
"typecheck:touched": "node scripts/typecheck-touched.mjs",
|
|
39
|
+
"check": "npm run build && node --check dist/crew.mjs",
|
|
40
|
+
"doctor": "node bin/crew.js doctor",
|
|
41
|
+
"lint": "eslint src/",
|
|
42
|
+
"prepublishOnly": "npm run build"
|
|
43
|
+
},
|
|
44
|
+
"engines": {
|
|
45
|
+
"node": ">=20.0.0"
|
|
46
|
+
},
|
|
47
|
+
"keywords": [
|
|
48
|
+
"ai",
|
|
49
|
+
"cli",
|
|
50
|
+
"coding",
|
|
51
|
+
"agent",
|
|
52
|
+
"multi-agent",
|
|
53
|
+
"grok",
|
|
54
|
+
"gemini",
|
|
55
|
+
"openai",
|
|
56
|
+
"claude",
|
|
57
|
+
"deepseek",
|
|
58
|
+
"agentic",
|
|
59
|
+
"code-generation",
|
|
60
|
+
"llm",
|
|
61
|
+
"crewswarm",
|
|
62
|
+
"orchestration",
|
|
63
|
+
"devtools"
|
|
64
|
+
],
|
|
65
|
+
"repository": {
|
|
66
|
+
"type": "git",
|
|
67
|
+
"url": "https://github.com/crewswarm/crewswarm.git",
|
|
68
|
+
"directory": "crew-cli"
|
|
69
|
+
},
|
|
70
|
+
"homepage": "https://crewswarm.com/cli",
|
|
71
|
+
"bugs": {
|
|
72
|
+
"url": "https://github.com/crewswarm/crewswarm/issues"
|
|
73
|
+
},
|
|
74
|
+
"author": "CrewSwarm <hello@crewswarm.com>",
|
|
75
|
+
"license": "ISC",
|
|
76
|
+
"publishConfig": {
|
|
77
|
+
"access": "public"
|
|
78
|
+
},
|
|
79
|
+
"dependencies": {
|
|
80
|
+
"@google/genai": "^1.44.0",
|
|
81
|
+
"ajv": "^8.18.0",
|
|
82
|
+
"ajv-formats": "^3.0.1",
|
|
83
|
+
"body-parser": "^1.20.4",
|
|
84
|
+
"chalk": "^5.3.0",
|
|
85
|
+
"chokidar": "^4.0.3",
|
|
86
|
+
"commander": "^11.0.0",
|
|
87
|
+
"diff": "^8.0.3",
|
|
88
|
+
"dotenv": "^16.3.0",
|
|
89
|
+
"express": "^4.22.1",
|
|
90
|
+
"fast-glob": "^3.3.3",
|
|
91
|
+
"fast-levenshtein": "^3.0.0",
|
|
92
|
+
"ignore": "^7.0.5",
|
|
93
|
+
"inquirer": "^9.2.0",
|
|
94
|
+
"mime": "^4.1.0",
|
|
95
|
+
"node-pty": "^1.1.0",
|
|
96
|
+
"ora": "^7.0.1",
|
|
97
|
+
"ws": "^8.14.0"
|
|
98
|
+
},
|
|
99
|
+
"devDependencies": {
|
|
100
|
+
"@types/diff": "^7.0.2",
|
|
101
|
+
"esbuild": "^0.25.0",
|
|
102
|
+
"eslint": "^8.50.0",
|
|
103
|
+
"tsx": "^4.21.0",
|
|
104
|
+
"typescript": "^5.9.3",
|
|
105
|
+
"typescript-eslint": "^8.0.0"
|
|
106
|
+
},
|
|
107
|
+
"directories": {
|
|
108
|
+
"doc": "docs",
|
|
109
|
+
"example": "examples",
|
|
110
|
+
"lib": "lib",
|
|
111
|
+
"test": "tests"
|
|
112
|
+
}
|
|
113
|
+
}
|