@stackmemoryai/stackmemory 0.3.6 → 0.3.7
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/agents/verifiers/base-verifier.js.map +2 -2
- package/dist/agents/verifiers/formatter-verifier.js.map +2 -2
- package/dist/agents/verifiers/llm-judge.js.map +2 -2
- package/dist/cli/claude-sm.js +24 -13
- package/dist/cli/claude-sm.js.map +2 -2
- package/dist/cli/codex-sm.js +24 -13
- package/dist/cli/codex-sm.js.map +2 -2
- package/dist/cli/commands/agent.js.map +2 -2
- package/dist/cli/commands/chromadb.js +217 -32
- package/dist/cli/commands/chromadb.js.map +2 -2
- package/dist/cli/commands/clear.js +12 -1
- package/dist/cli/commands/clear.js.map +2 -2
- package/dist/cli/commands/context.js +13 -2
- package/dist/cli/commands/context.js.map +2 -2
- package/dist/cli/commands/dashboard.js.map +2 -2
- package/dist/cli/commands/gc.js +202 -0
- package/dist/cli/commands/gc.js.map +7 -0
- package/dist/cli/commands/handoff.js +12 -1
- package/dist/cli/commands/handoff.js.map +2 -2
- package/dist/cli/commands/infinite-storage.js +32 -21
- package/dist/cli/commands/infinite-storage.js.map +2 -2
- package/dist/cli/commands/linear-create.js +13 -2
- package/dist/cli/commands/linear-create.js.map +2 -2
- package/dist/cli/commands/linear-list.js +12 -1
- package/dist/cli/commands/linear-list.js.map +2 -2
- package/dist/cli/commands/linear-migrate.js +12 -1
- package/dist/cli/commands/linear-migrate.js.map +2 -2
- package/dist/cli/commands/linear-test.js +12 -1
- package/dist/cli/commands/linear-test.js.map +2 -2
- package/dist/cli/commands/linear-unified.js +262 -0
- package/dist/cli/commands/linear-unified.js.map +7 -0
- package/dist/cli/commands/linear.js +17 -6
- package/dist/cli/commands/linear.js.map +2 -2
- package/dist/cli/commands/monitor.js.map +2 -2
- package/dist/cli/commands/onboard.js.map +2 -2
- package/dist/cli/commands/quality.js.map +2 -2
- package/dist/cli/commands/search.js.map +2 -2
- package/dist/cli/commands/session.js.map +2 -2
- package/dist/cli/commands/skills.js +12 -1
- package/dist/cli/commands/skills.js.map +2 -2
- package/dist/cli/commands/storage.js +18 -7
- package/dist/cli/commands/storage.js.map +2 -2
- package/dist/cli/commands/tasks.js.map +2 -2
- package/dist/cli/commands/tui.js +13 -2
- package/dist/cli/commands/tui.js.map +2 -2
- package/dist/cli/commands/webhook.js +14 -3
- package/dist/cli/commands/webhook.js.map +2 -2
- package/dist/cli/commands/workflow.js +14 -3
- package/dist/cli/commands/workflow.js.map +2 -2
- package/dist/cli/commands/worktree.js.map +2 -2
- package/dist/cli/index.js +18 -5
- package/dist/cli/index.js.map +2 -2
- package/dist/core/config/config-manager.js.map +2 -2
- package/dist/core/context/auto-context.js.map +2 -2
- package/dist/core/context/compaction-handler.js.map +2 -2
- package/dist/core/context/context-bridge.js.map +2 -2
- package/dist/core/context/dual-stack-manager.js.map +2 -2
- package/dist/core/context/frame-database.js.map +2 -2
- package/dist/core/context/frame-digest.js.map +2 -2
- package/dist/core/context/frame-handoff-manager.js.map +2 -2
- package/dist/core/context/frame-manager.js +12 -1
- package/dist/core/context/frame-manager.js.map +2 -2
- package/dist/core/context/frame-stack.js.map +2 -2
- package/dist/core/context/incremental-gc.js +279 -0
- package/dist/core/context/incremental-gc.js.map +7 -0
- package/dist/core/context/permission-manager.js +12 -1
- package/dist/core/context/permission-manager.js.map +2 -2
- package/dist/core/context/refactored-frame-manager.js.map +2 -2
- package/dist/core/context/shared-context-layer.js +12 -1
- package/dist/core/context/shared-context-layer.js.map +2 -2
- package/dist/core/context/stack-merge-resolver.js.map +2 -2
- package/dist/core/context/validation.js.map +2 -2
- package/dist/core/database/batch-operations.js.map +2 -2
- package/dist/core/database/connection-pool.js.map +2 -2
- package/dist/core/database/migration-manager.js.map +2 -2
- package/dist/core/database/paradedb-adapter.js.map +2 -2
- package/dist/core/database/query-cache.js.map +2 -2
- package/dist/core/database/query-router.js.map +2 -2
- package/dist/core/database/sqlite-adapter.js.map +2 -2
- package/dist/core/digest/enhanced-hybrid-digest.js.map +2 -2
- package/dist/core/errors/recovery.js.map +2 -2
- package/dist/core/merge/resolution-engine.js.map +2 -2
- package/dist/core/monitoring/error-handler.js.map +2 -2
- package/dist/core/monitoring/logger.js +14 -3
- package/dist/core/monitoring/logger.js.map +2 -2
- package/dist/core/monitoring/metrics.js +13 -2
- package/dist/core/monitoring/metrics.js.map +2 -2
- package/dist/core/monitoring/progress-tracker.js +12 -1
- package/dist/core/monitoring/progress-tracker.js.map +2 -2
- package/dist/core/monitoring/session-monitor.js.map +2 -2
- package/dist/core/performance/context-cache.js.map +2 -2
- package/dist/core/performance/lazy-context-loader.js.map +2 -2
- package/dist/core/performance/monitor.js.map +2 -2
- package/dist/core/performance/optimized-frame-context.js.map +2 -2
- package/dist/core/performance/performance-benchmark.js.map +2 -2
- package/dist/core/performance/performance-profiler.js +12 -1
- package/dist/core/performance/performance-profiler.js.map +2 -2
- package/dist/core/performance/streaming-jsonl-parser.js.map +2 -2
- package/dist/core/persistence/postgres-adapter.js.map +2 -2
- package/dist/core/projects/project-manager.js.map +2 -2
- package/dist/core/retrieval/context-retriever.js.map +2 -2
- package/dist/core/retrieval/graph-retrieval.js.map +2 -2
- package/dist/core/retrieval/llm-context-retrieval.js.map +2 -2
- package/dist/core/retrieval/retrieval-benchmarks.js.map +2 -2
- package/dist/core/retrieval/summary-generator.js.map +2 -2
- package/dist/core/session/clear-survival.js.map +2 -2
- package/dist/core/session/handoff-generator.js.map +2 -2
- package/dist/core/session/session-manager.js +16 -5
- package/dist/core/session/session-manager.js.map +2 -2
- package/dist/core/skills/skill-storage.js +13 -2
- package/dist/core/skills/skill-storage.js.map +2 -2
- package/dist/core/storage/chromadb-adapter.js.map +2 -2
- package/dist/core/storage/chromadb-simple.js.map +2 -2
- package/dist/core/storage/infinite-storage.js.map +2 -2
- package/dist/core/storage/railway-optimized-storage.js +19 -8
- package/dist/core/storage/railway-optimized-storage.js.map +2 -2
- package/dist/core/storage/remote-storage.js +12 -1
- package/dist/core/storage/remote-storage.js.map +2 -2
- package/dist/core/trace/cli-trace-wrapper.js +16 -5
- package/dist/core/trace/cli-trace-wrapper.js.map +2 -2
- package/dist/core/trace/db-trace-wrapper.js.map +2 -2
- package/dist/core/trace/debug-trace.js +21 -10
- package/dist/core/trace/debug-trace.js.map +2 -2
- package/dist/core/trace/index.js +46 -35
- package/dist/core/trace/index.js.map +2 -2
- package/dist/core/trace/trace-demo.js +12 -1
- package/dist/core/trace/trace-demo.js.map +2 -2
- package/dist/core/trace/trace-detector.js.map +2 -2
- package/dist/core/trace/trace-store.js.map +2 -2
- package/dist/core/utils/update-checker.js.map +2 -2
- package/dist/core/worktree/worktree-manager.js.map +2 -2
- package/dist/features/analytics/api/analytics-api.js.map +2 -2
- package/dist/features/analytics/core/analytics-service.js +12 -1
- package/dist/features/analytics/core/analytics-service.js.map +2 -2
- package/dist/features/analytics/queries/metrics-queries.js.map +2 -2
- package/dist/features/tasks/pebbles-task-store.js.map +2 -2
- package/dist/features/tui/components/analytics-panel.js.map +2 -2
- package/dist/features/tui/components/pr-tracker.js.map +2 -2
- package/dist/features/tui/components/session-monitor.js.map +2 -2
- package/dist/features/tui/components/subagent-fleet.js.map +2 -2
- package/dist/features/tui/components/task-board.js +650 -2
- package/dist/features/tui/components/task-board.js.map +2 -2
- package/dist/features/tui/index.js +16 -5
- package/dist/features/tui/index.js.map +2 -2
- package/dist/features/tui/services/data-service.js +25 -14
- package/dist/features/tui/services/data-service.js.map +2 -2
- package/dist/features/tui/services/linear-task-reader.js.map +2 -2
- package/dist/features/tui/services/websocket-client.js +13 -2
- package/dist/features/tui/services/websocket-client.js.map +2 -2
- package/dist/features/tui/terminal-compat.js +27 -16
- package/dist/features/tui/terminal-compat.js.map +2 -2
- package/dist/features/web/client/stores/task-store.js.map +2 -2
- package/dist/features/web/server/index.js +13 -2
- package/dist/features/web/server/index.js.map +2 -2
- package/dist/integrations/claude-code/enhanced-pre-clear-hooks.js.map +2 -2
- package/dist/integrations/claude-code/lifecycle-hooks.js.map +2 -2
- package/dist/integrations/claude-code/post-task-hooks.js.map +2 -2
- package/dist/integrations/linear/auth.js +17 -6
- package/dist/integrations/linear/auth.js.map +2 -2
- package/dist/integrations/linear/auto-sync.js.map +2 -2
- package/dist/integrations/linear/client.js.map +2 -2
- package/dist/integrations/linear/config.js.map +2 -2
- package/dist/integrations/linear/migration.js.map +2 -2
- package/dist/integrations/linear/oauth-server.js +13 -2
- package/dist/integrations/linear/oauth-server.js.map +2 -2
- package/dist/integrations/linear/rest-client.js.map +2 -2
- package/dist/integrations/linear/sync-enhanced.js +202 -0
- package/dist/integrations/linear/sync-enhanced.js.map +7 -0
- package/dist/integrations/linear/sync-manager.js.map +2 -2
- package/dist/integrations/linear/sync-service.js +12 -1
- package/dist/integrations/linear/sync-service.js.map +2 -2
- package/dist/integrations/linear/sync.js +34 -3
- package/dist/integrations/linear/sync.js.map +2 -2
- package/dist/integrations/linear/unified-sync.js +560 -0
- package/dist/integrations/linear/unified-sync.js.map +7 -0
- package/dist/integrations/linear/webhook-handler.js +12 -1
- package/dist/integrations/linear/webhook-handler.js.map +2 -2
- package/dist/integrations/linear/webhook-server.js +14 -3
- package/dist/integrations/linear/webhook-server.js.map +2 -2
- package/dist/integrations/linear/webhook.js +12 -1
- package/dist/integrations/linear/webhook.js.map +2 -2
- package/dist/integrations/mcp/handlers/context-handlers.js.map +2 -2
- package/dist/integrations/mcp/handlers/linear-handlers.js.map +2 -2
- package/dist/integrations/mcp/handlers/skill-handlers.js +13 -2
- package/dist/integrations/mcp/handlers/skill-handlers.js.map +2 -2
- package/dist/integrations/mcp/handlers/task-handlers.js.map +2 -2
- package/dist/integrations/mcp/handlers/trace-handlers.js.map +2 -2
- package/dist/integrations/mcp/middleware/tool-scoring.js.map +2 -2
- package/dist/integrations/mcp/refactored-server.js +15 -4
- package/dist/integrations/mcp/refactored-server.js.map +2 -2
- package/dist/integrations/mcp/server.js +12 -1
- package/dist/integrations/mcp/server.js.map +2 -2
- package/dist/integrations/mcp/tool-definitions.js.map +2 -2
- package/dist/integrations/pg-aiguide/embedding-provider.js +13 -2
- package/dist/integrations/pg-aiguide/embedding-provider.js.map +2 -2
- package/dist/integrations/pg-aiguide/semantic-search.js.map +2 -2
- package/dist/mcp/stackmemory-mcp-server.js +12 -1
- package/dist/mcp/stackmemory-mcp-server.js.map +2 -2
- package/dist/middleware/exponential-rate-limiter.js.map +2 -2
- package/dist/servers/production/auth-middleware.js +13 -2
- package/dist/servers/production/auth-middleware.js.map +2 -2
- package/dist/servers/railway/index.js +22 -11
- package/dist/servers/railway/index.js.map +2 -2
- package/dist/services/config-service.js.map +2 -2
- package/dist/services/context-service.js.map +2 -2
- package/dist/skills/claude-skills.js +105 -2
- package/dist/skills/claude-skills.js.map +2 -2
- package/dist/skills/dashboard-launcher.js.map +2 -2
- package/dist/skills/repo-ingestion-skill.js +561 -0
- package/dist/skills/repo-ingestion-skill.js.map +7 -0
- package/dist/utils/logger.js +12 -1
- package/dist/utils/logger.js.map +2 -2
- package/package.json +5 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/cli/commands/agent.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Agent command - Integrates Spotify's background coding agent strategies\n * with StackMemory's task system\n *\n * Usage: stackmemory agent <action> [options]\n */\n\nimport { Command } from 'commander';\nimport Database from 'better-sqlite3';\nimport { join } from 'path';\nimport { existsSync } from 'fs';\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport { PebblesTaskStore } from '../../features/tasks/pebbles-task-store.js';\nimport { FrameManager } from '../../core/context/frame-manager.js';\nimport {\n AgentTaskManager,\n AgentTaskSession,\n} from '../../agents/core/agent-task-manager.js';\nimport { FormatterVerifier } from '../../agents/verifiers/formatter-verifier.js';\nimport { LLMJudge } from '../../agents/verifiers/llm-judge.js';\nimport { logger } from '../../core/monitoring/logger.js';\n\nexport function createAgentCommand(): Command {\n const agent = new Command('agent')\n .description('AI agent task execution with Spotify-inspired strategies')\n .option('-p, --project <path>', 'Project root directory', process.cwd());\n\n agent\n .command('execute <taskId>')\n .description('Execute a task with agent assistance')\n .option('-f, --frame <frameId>', 'Frame ID to use')\n .option('--max-turns <number>', 'Maximum turns per session', '10')\n .option('--no-verify', 'Skip verification loops')\n .action(async (taskId: string, options) => {\n const spinner = ora('Initializing agent...').start();\n\n try {\n const { taskManager, session } = await initializeAgent(\n options.project,\n taskId,\n options.frame,\n parseInt(options.maxTurns)\n );\n\n spinner.succeed('Agent initialized');\n\n // Display session info\n console.log(chalk.cyan('\\n\uD83D\uDCCB Task Session Started'));\n console.log(chalk.gray(' Session ID:'), session.id);\n console.log(chalk.gray(' Task ID:'), session.taskId);\n console.log(chalk.gray(' Max Turns:'), session.maxTurns);\n console.log(\n chalk.gray(' Verification:'),\n options.verify ? 'Enabled' : 'Disabled'\n );\n\n // Execute task with feedback loop\n await executeTaskWithFeedback(taskManager, session, options.verify);\n } catch (error) {\n spinner.fail('Agent execution failed');\n console.error(\n chalk.red('Error:'),\n error instanceof Error ? error.message : String(error)\n );\n process.exit(1);\n }\n });\n\n agent\n .command('status')\n .description('Show active agent sessions')\n .action(async (options) => {\n const spinner = ora('Loading sessions...').start();\n\n try {\n const projectRoot = options.parent?.project || process.cwd();\n const { taskManager } = await initializeAgentManager(projectRoot);\n\n const sessions = taskManager.getActiveSessions();\n spinner.stop();\n\n if (sessions.length === 0) {\n console.log(chalk.yellow('No active agent sessions'));\n return;\n }\n\n console.log(chalk.cyan('\\n\uD83E\uDD16 Active Agent Sessions\\n'));\n\n for (const session of sessions) {\n console.log(chalk.bold(`Session: ${session.sessionId}`));\n console.log(chalk.gray(' Task:'), session.taskId);\n console.log(\n chalk.gray(' Status:'),\n getStatusColor(session.status)(session.status)\n );\n console.log(chalk.gray(' Turn:'), `${session.turnCount}/10`);\n console.log(\n chalk.gray(' Started:'),\n session.startedAt.toLocaleString()\n );\n console.log('');\n }\n } catch (error) {\n spinner.fail('Failed to load sessions');\n console.error(\n chalk.red('Error:'),\n error instanceof Error ? error.message : String(error)\n );\n process.exit(1);\n }\n });\n\n agent\n .command('retry <sessionId>')\n .description('Retry a failed session with learned context')\n .action(async (sessionId: string, options) => {\n const spinner = ora('Retrying session...').start();\n\n try {\n const projectRoot = options.parent?.project || process.cwd();\n const { taskManager } = await initializeAgentManager(projectRoot);\n\n const newSession = await taskManager.retrySession(sessionId);\n\n if (!newSession) {\n spinner.fail(\n 'Cannot retry session (max retries reached or session active)'\n );\n return;\n }\n\n spinner.succeed('Session retry started');\n console.log(chalk.cyan('\\n\u267B\uFE0F Retry Session Started'));\n console.log(chalk.gray(' New Session ID:'), newSession.id);\n console.log(chalk.gray(' Task ID:'), newSession.taskId);\n\n // Execute with feedback\n await executeTaskWithFeedback(taskManager, newSession, true);\n } catch (error) {\n spinner.fail('Retry failed');\n console.error(\n chalk.red('Error:'),\n error instanceof Error ? error.message : String(error)\n );\n process.exit(1);\n }\n });\n\n agent\n .command('breakdown <taskId>')\n .description('Break down a complex task into subtasks')\n .action(async (taskId: string, options) => {\n const spinner = ora('Analyzing task complexity...').start();\n\n try {\n const projectRoot = options.parent?.project || process.cwd();\n const db = await openDatabase(projectRoot);\n const taskStore = new PebblesTaskStore(projectRoot, db);\n\n const task = taskStore.getTask(taskId);\n if (!task) {\n spinner.fail(`Task ${taskId} not found`);\n return;\n }\n\n spinner.text = 'Breaking down task...';\n\n // Simulate task breakdown (in production, would use LLM)\n const subtasks = generateTaskBreakdown(\n task.title,\n task.description || ''\n );\n\n spinner.succeed('Task breakdown complete');\n\n console.log(chalk.cyan(`\\n\uD83D\uDCCA Task Breakdown: ${task.title}\\n`));\n\n subtasks.forEach((subtask, index) => {\n console.log(chalk.bold(`${index + 1}. ${subtask.title}`));\n console.log(chalk.gray(' Description:'), subtask.description);\n console.log(\n chalk.gray(' Estimated turns:'),\n subtask.estimatedTurns\n );\n console.log(\n chalk.gray(' Verifiers:'),\n subtask.verifiers.join(', ')\n );\n console.log('');\n });\n\n console.log(\n chalk.yellow('Total estimated turns:'),\n subtasks.reduce((sum, st) => sum + st.estimatedTurns, 0)\n );\n } catch (error) {\n spinner.fail('Breakdown failed');\n console.error(\n chalk.red('Error:'),\n error instanceof Error ? error.message : String(error)\n );\n process.exit(1);\n }\n });\n\n return agent;\n}\n\n/**\n * Initialize agent and start task session\n */\nasync function initializeAgent(\n projectRoot: string,\n taskId: string,\n frameId?: string,\n maxTurns = 10\n): Promise<{\n taskManager: AgentTaskManager;\n session: AgentTaskSession;\n}> {\n const { taskManager, frameManager, taskStore } =\n await initializeAgentManager(projectRoot);\n\n // Create or get frame\n const finalFrameId =\n frameId ||\n frameManager.createFrame({\n type: 'task',\n name: `Agent task execution for ${taskId}`,\n inputs: { taskId, agentSession: true },\n });\n\n // Start session\n const session = await taskManager.startTaskSession(taskId, finalFrameId);\n\n // Override max turns if specified\n if (maxTurns !== 10) {\n session.maxTurns = maxTurns;\n }\n\n return { taskManager, session };\n}\n\n/**\n * Initialize agent manager components\n */\nasync function initializeAgentManager(projectRoot: string): Promise<{\n taskManager: AgentTaskManager;\n frameManager: FrameManager;\n taskStore: PebblesTaskStore;\n}> {\n const db = await openDatabase(projectRoot);\n const taskStore = new PebblesTaskStore(projectRoot, db);\n const frameManager = new FrameManager(db, projectRoot, undefined);\n const taskManager = new AgentTaskManager(taskStore, frameManager);\n\n return { taskManager, frameManager, taskStore };\n}\n\n/**\n * Execute task with feedback loop (Spotify pattern)\n */\nasync function executeTaskWithFeedback(\n taskManager: AgentTaskManager,\n session: AgentTaskSession,\n enableVerification: boolean\n): Promise<void> {\n console.log(chalk.cyan('\\n\uD83D\uDD04 Starting execution loop...\\n'));\n\n let turnCount = 0;\n let shouldContinue = true;\n let lastFeedback = '';\n\n while (shouldContinue && turnCount < session.maxTurns) {\n turnCount++;\n\n console.log(chalk.bold(`\\n\u2550\u2550\u2550 Turn ${turnCount}/${session.maxTurns} \u2550\u2550\u2550`));\n\n // Simulate agent action (in production, would use actual AI)\n const action = generateMockAction(turnCount, lastFeedback);\n console.log(chalk.gray('Action:'), action.substring(0, 100) + '...');\n\n // Execute turn with verification\n const spinner = ora('Executing...').start();\n\n const result = await taskManager.executeTurn(session.id, action, {\n codeChange: turnCount > 1,\n testsPresent: turnCount > 2,\n enableVerification,\n });\n\n if (result.success) {\n spinner.succeed('Turn completed successfully');\n } else {\n spinner.warn('Turn completed with issues');\n }\n\n // Display feedback\n console.log(chalk.yellow('\\n\uD83D\uDCDD Feedback:'));\n console.log(result.feedback);\n\n // Display verification results if any\n if (result.verificationResults.length > 0) {\n console.log(chalk.cyan('\\n\u2713 Verification Results:'));\n for (const vr of result.verificationResults) {\n const icon = vr.passed ? '\u2713' : '\u2717';\n const color = vr.passed ? chalk.green : chalk.red;\n console.log(color(` ${icon} ${vr.verifierId}: ${vr.message}`));\n }\n }\n\n shouldContinue = result.shouldContinue;\n lastFeedback = result.feedback;\n\n // Short delay for readability\n await delay(1000);\n }\n\n // Final status\n console.log(chalk.cyan('\\n\u2550\u2550\u2550 Session Complete \u2550\u2550\u2550\\n'));\n console.log(chalk.gray('Total turns:'), turnCount);\n console.log(chalk.gray('Final status:'), session.status);\n}\n\n/**\n * Generate mock action for demonstration\n */\nfunction generateMockAction(turn: number, previousFeedback: string): string {\n const actions = [\n 'Analyzing task requirements and constraints',\n 'Setting up project structure and dependencies',\n 'Implementing core functionality',\n 'Adding error handling and validation',\n 'Writing unit tests',\n 'Refactoring for better code organization',\n 'Adding documentation and comments',\n 'Running final verification checks',\n 'Optimizing performance',\n 'Completing final cleanup',\n ];\n\n if (previousFeedback.includes('error')) {\n return `Fixing issues: ${previousFeedback.substring(0, 50)}...`;\n }\n\n return actions[Math.min(turn - 1, actions.length - 1)];\n}\n\n/**\n * Generate task breakdown for complex tasks\n */\nfunction generateTaskBreakdown(\n title: string,\n description: string\n): Array<{\n title: string;\n description: string;\n estimatedTurns: number;\n verifiers: string[];\n}> {\n // Simple heuristic breakdown (in production, would use LLM)\n return [\n {\n title: `Analyze and plan: ${title}`,\n description: 'Understand requirements and create implementation plan',\n estimatedTurns: 2,\n verifiers: ['semantic-validator'],\n },\n {\n title: `Implement core: ${title}`,\n description: 'Build main functionality',\n estimatedTurns: 4,\n verifiers: ['formatter', 'linter', 'semantic-validator'],\n },\n {\n title: `Test and validate: ${title}`,\n description: 'Add tests and validate implementation',\n estimatedTurns: 3,\n verifiers: ['test-runner', 'semantic-validator'],\n },\n {\n title: `Polish and document: ${title}`,\n description: 'Final improvements and documentation',\n estimatedTurns: 1,\n verifiers: ['formatter', 'linter'],\n },\n ];\n}\n\n/**\n * Open or create database\n */\nasync function openDatabase(projectRoot: string): Promise<Database.Database> {\n const dbPath = join(projectRoot, '.stackmemory', 'cache.db');\n\n if (!existsSync(join(projectRoot, '.stackmemory'))) {\n throw new Error(\n 'StackMemory not initialized. Run \"stackmemory init\" first.'\n );\n }\n\n return new Database(dbPath);\n}\n\n/**\n * Get color function for status\n */\nfunction getStatusColor(status: string): (text: string) => string {\n switch (status) {\n case 'active':\n return chalk.green;\n case 'completed':\n return chalk.blue;\n case 'failed':\n return chalk.red;\n case 'timeout':\n return chalk.yellow;\n default:\n return chalk.gray;\n }\n}\n\n/**\n * Delay helper\n */\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n"],
|
|
5
|
-
"mappings": "AAOA,SAAS,eAAe;AACxB,OAAO,cAAc;AACrB,SAAS,YAAY;AACrB,SAAS,kBAAkB;AAC3B,OAAO,WAAW;AAClB,OAAO,SAAS;AAChB,SAAS,wBAAwB;AACjC,SAAS,oBAAoB;AAC7B;AAAA,EACE;AAAA,OAEK;AAKA,SAAS,qBAA8B;AAC5C,QAAM,QAAQ,IAAI,QAAQ,OAAO,EAC9B,YAAY,0DAA0D,EACtE,OAAO,wBAAwB,0BAA0B,QAAQ,IAAI,CAAC;AAEzE,QACG,QAAQ,kBAAkB,EAC1B,YAAY,sCAAsC,EAClD,OAAO,yBAAyB,iBAAiB,EACjD,OAAO,wBAAwB,6BAA6B,IAAI,EAChE,OAAO,eAAe,yBAAyB,EAC/C,OAAO,OAAO,QAAgB,YAAY;AACzC,UAAM,UAAU,IAAI,uBAAuB,EAAE,MAAM;AAEnD,QAAI;AACF,YAAM,EAAE,aAAa,QAAQ,IAAI,MAAM;AAAA,QACrC,QAAQ;AAAA,QACR;AAAA,QACA,QAAQ;AAAA,QACR,SAAS,QAAQ,QAAQ;AAAA,MAC3B;AAEA,cAAQ,QAAQ,mBAAmB;AAGnC,cAAQ,IAAI,MAAM,KAAK,kCAA2B,CAAC;AACnD,cAAQ,IAAI,MAAM,KAAK,eAAe,GAAG,QAAQ,EAAE;AACnD,cAAQ,IAAI,MAAM,KAAK,YAAY,GAAG,QAAQ,MAAM;AACpD,cAAQ,IAAI,MAAM,KAAK,cAAc,GAAG,QAAQ,QAAQ;AACxD,cAAQ;AAAA,QACN,MAAM,KAAK,iBAAiB;AAAA,QAC5B,QAAQ,SAAS,YAAY;AAAA,MAC/B;AAGA,YAAM,wBAAwB,aAAa,SAAS,QAAQ,MAAM;AAAA,IACpE,SAAS,
|
|
4
|
+
"sourcesContent": ["/**\n * Agent command - Integrates Spotify's background coding agent strategies\n * with StackMemory's task system\n *\n * Usage: stackmemory agent <action> [options]\n */\n\nimport { Command } from 'commander';\nimport Database from 'better-sqlite3';\nimport { join } from 'path';\nimport { existsSync } from 'fs';\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport { PebblesTaskStore } from '../../features/tasks/pebbles-task-store.js';\nimport { FrameManager } from '../../core/context/frame-manager.js';\nimport {\n AgentTaskManager,\n AgentTaskSession,\n} from '../../agents/core/agent-task-manager.js';\nimport { FormatterVerifier } from '../../agents/verifiers/formatter-verifier.js';\nimport { LLMJudge } from '../../agents/verifiers/llm-judge.js';\nimport { logger } from '../../core/monitoring/logger.js';\n\nexport function createAgentCommand(): Command {\n const agent = new Command('agent')\n .description('AI agent task execution with Spotify-inspired strategies')\n .option('-p, --project <path>', 'Project root directory', process.cwd());\n\n agent\n .command('execute <taskId>')\n .description('Execute a task with agent assistance')\n .option('-f, --frame <frameId>', 'Frame ID to use')\n .option('--max-turns <number>', 'Maximum turns per session', '10')\n .option('--no-verify', 'Skip verification loops')\n .action(async (taskId: string, options) => {\n const spinner = ora('Initializing agent...').start();\n\n try {\n const { taskManager, session } = await initializeAgent(\n options.project,\n taskId,\n options.frame,\n parseInt(options.maxTurns)\n );\n\n spinner.succeed('Agent initialized');\n\n // Display session info\n console.log(chalk.cyan('\\n\uD83D\uDCCB Task Session Started'));\n console.log(chalk.gray(' Session ID:'), session.id);\n console.log(chalk.gray(' Task ID:'), session.taskId);\n console.log(chalk.gray(' Max Turns:'), session.maxTurns);\n console.log(\n chalk.gray(' Verification:'),\n options.verify ? 'Enabled' : 'Disabled'\n );\n\n // Execute task with feedback loop\n await executeTaskWithFeedback(taskManager, session, options.verify);\n } catch (error: unknown) {\n spinner.fail('Agent execution failed');\n console.error(\n chalk.red('Error:'),\n error instanceof Error ? error.message : String(error)\n );\n process.exit(1);\n }\n });\n\n agent\n .command('status')\n .description('Show active agent sessions')\n .action(async (options) => {\n const spinner = ora('Loading sessions...').start();\n\n try {\n const projectRoot = options.parent?.project || process.cwd();\n const { taskManager } = await initializeAgentManager(projectRoot);\n\n const sessions = taskManager.getActiveSessions();\n spinner.stop();\n\n if (sessions.length === 0) {\n console.log(chalk.yellow('No active agent sessions'));\n return;\n }\n\n console.log(chalk.cyan('\\n\uD83E\uDD16 Active Agent Sessions\\n'));\n\n for (const session of sessions) {\n console.log(chalk.bold(`Session: ${session.sessionId}`));\n console.log(chalk.gray(' Task:'), session.taskId);\n console.log(\n chalk.gray(' Status:'),\n getStatusColor(session.status)(session.status)\n );\n console.log(chalk.gray(' Turn:'), `${session.turnCount}/10`);\n console.log(\n chalk.gray(' Started:'),\n session.startedAt.toLocaleString()\n );\n console.log('');\n }\n } catch (error: unknown) {\n spinner.fail('Failed to load sessions');\n console.error(\n chalk.red('Error:'),\n error instanceof Error ? error.message : String(error)\n );\n process.exit(1);\n }\n });\n\n agent\n .command('retry <sessionId>')\n .description('Retry a failed session with learned context')\n .action(async (sessionId: string, options) => {\n const spinner = ora('Retrying session...').start();\n\n try {\n const projectRoot = options.parent?.project || process.cwd();\n const { taskManager } = await initializeAgentManager(projectRoot);\n\n const newSession = await taskManager.retrySession(sessionId);\n\n if (!newSession) {\n spinner.fail(\n 'Cannot retry session (max retries reached or session active)'\n );\n return;\n }\n\n spinner.succeed('Session retry started');\n console.log(chalk.cyan('\\n\u267B\uFE0F Retry Session Started'));\n console.log(chalk.gray(' New Session ID:'), newSession.id);\n console.log(chalk.gray(' Task ID:'), newSession.taskId);\n\n // Execute with feedback\n await executeTaskWithFeedback(taskManager, newSession, true);\n } catch (error: unknown) {\n spinner.fail('Retry failed');\n console.error(\n chalk.red('Error:'),\n error instanceof Error ? error.message : String(error)\n );\n process.exit(1);\n }\n });\n\n agent\n .command('breakdown <taskId>')\n .description('Break down a complex task into subtasks')\n .action(async (taskId: string, options) => {\n const spinner = ora('Analyzing task complexity...').start();\n\n try {\n const projectRoot = options.parent?.project || process.cwd();\n const db = await openDatabase(projectRoot);\n const taskStore = new PebblesTaskStore(projectRoot, db);\n\n const task = taskStore.getTask(taskId);\n if (!task) {\n spinner.fail(`Task ${taskId} not found`);\n return;\n }\n\n spinner.text = 'Breaking down task...';\n\n // Simulate task breakdown (in production, would use LLM)\n const subtasks = generateTaskBreakdown(\n task.title,\n task.description || ''\n );\n\n spinner.succeed('Task breakdown complete');\n\n console.log(chalk.cyan(`\\n\uD83D\uDCCA Task Breakdown: ${task.title}\\n`));\n\n subtasks.forEach((subtask, index) => {\n console.log(chalk.bold(`${index + 1}. ${subtask.title}`));\n console.log(chalk.gray(' Description:'), subtask.description);\n console.log(\n chalk.gray(' Estimated turns:'),\n subtask.estimatedTurns\n );\n console.log(\n chalk.gray(' Verifiers:'),\n subtask.verifiers.join(', ')\n );\n console.log('');\n });\n\n console.log(\n chalk.yellow('Total estimated turns:'),\n subtasks.reduce((sum, st) => sum + st.estimatedTurns, 0)\n );\n } catch (error: unknown) {\n spinner.fail('Breakdown failed');\n console.error(\n chalk.red('Error:'),\n error instanceof Error ? error.message : String(error)\n );\n process.exit(1);\n }\n });\n\n return agent;\n}\n\n/**\n * Initialize agent and start task session\n */\nasync function initializeAgent(\n projectRoot: string,\n taskId: string,\n frameId?: string,\n maxTurns = 10\n): Promise<{\n taskManager: AgentTaskManager;\n session: AgentTaskSession;\n}> {\n const { taskManager, frameManager, taskStore } =\n await initializeAgentManager(projectRoot);\n\n // Create or get frame\n const finalFrameId =\n frameId ||\n frameManager.createFrame({\n type: 'task',\n name: `Agent task execution for ${taskId}`,\n inputs: { taskId, agentSession: true },\n });\n\n // Start session\n const session = await taskManager.startTaskSession(taskId, finalFrameId);\n\n // Override max turns if specified\n if (maxTurns !== 10) {\n session.maxTurns = maxTurns;\n }\n\n return { taskManager, session };\n}\n\n/**\n * Initialize agent manager components\n */\nasync function initializeAgentManager(projectRoot: string): Promise<{\n taskManager: AgentTaskManager;\n frameManager: FrameManager;\n taskStore: PebblesTaskStore;\n}> {\n const db = await openDatabase(projectRoot);\n const taskStore = new PebblesTaskStore(projectRoot, db);\n const frameManager = new FrameManager(db, projectRoot, undefined);\n const taskManager = new AgentTaskManager(taskStore, frameManager);\n\n return { taskManager, frameManager, taskStore };\n}\n\n/**\n * Execute task with feedback loop (Spotify pattern)\n */\nasync function executeTaskWithFeedback(\n taskManager: AgentTaskManager,\n session: AgentTaskSession,\n enableVerification: boolean\n): Promise<void> {\n console.log(chalk.cyan('\\n\uD83D\uDD04 Starting execution loop...\\n'));\n\n let turnCount = 0;\n let shouldContinue = true;\n let lastFeedback = '';\n\n while (shouldContinue && turnCount < session.maxTurns) {\n turnCount++;\n\n console.log(chalk.bold(`\\n\u2550\u2550\u2550 Turn ${turnCount}/${session.maxTurns} \u2550\u2550\u2550`));\n\n // Simulate agent action (in production, would use actual AI)\n const action = generateMockAction(turnCount, lastFeedback);\n console.log(chalk.gray('Action:'), action.substring(0, 100) + '...');\n\n // Execute turn with verification\n const spinner = ora('Executing...').start();\n\n const result = await taskManager.executeTurn(session.id, action, {\n codeChange: turnCount > 1,\n testsPresent: turnCount > 2,\n enableVerification,\n });\n\n if (result.success) {\n spinner.succeed('Turn completed successfully');\n } else {\n spinner.warn('Turn completed with issues');\n }\n\n // Display feedback\n console.log(chalk.yellow('\\n\uD83D\uDCDD Feedback:'));\n console.log(result.feedback);\n\n // Display verification results if any\n if (result.verificationResults.length > 0) {\n console.log(chalk.cyan('\\n\u2713 Verification Results:'));\n for (const vr of result.verificationResults) {\n const icon = vr.passed ? '\u2713' : '\u2717';\n const color = vr.passed ? chalk.green : chalk.red;\n console.log(color(` ${icon} ${vr.verifierId}: ${vr.message}`));\n }\n }\n\n shouldContinue = result.shouldContinue;\n lastFeedback = result.feedback;\n\n // Short delay for readability\n await delay(1000);\n }\n\n // Final status\n console.log(chalk.cyan('\\n\u2550\u2550\u2550 Session Complete \u2550\u2550\u2550\\n'));\n console.log(chalk.gray('Total turns:'), turnCount);\n console.log(chalk.gray('Final status:'), session.status);\n}\n\n/**\n * Generate mock action for demonstration\n */\nfunction generateMockAction(turn: number, previousFeedback: string): string {\n const actions = [\n 'Analyzing task requirements and constraints',\n 'Setting up project structure and dependencies',\n 'Implementing core functionality',\n 'Adding error handling and validation',\n 'Writing unit tests',\n 'Refactoring for better code organization',\n 'Adding documentation and comments',\n 'Running final verification checks',\n 'Optimizing performance',\n 'Completing final cleanup',\n ];\n\n if (previousFeedback.includes('error')) {\n return `Fixing issues: ${previousFeedback.substring(0, 50)}...`;\n }\n\n return actions[Math.min(turn - 1, actions.length - 1)];\n}\n\n/**\n * Generate task breakdown for complex tasks\n */\nfunction generateTaskBreakdown(\n title: string,\n description: string\n): Array<{\n title: string;\n description: string;\n estimatedTurns: number;\n verifiers: string[];\n}> {\n // Simple heuristic breakdown (in production, would use LLM)\n return [\n {\n title: `Analyze and plan: ${title}`,\n description: 'Understand requirements and create implementation plan',\n estimatedTurns: 2,\n verifiers: ['semantic-validator'],\n },\n {\n title: `Implement core: ${title}`,\n description: 'Build main functionality',\n estimatedTurns: 4,\n verifiers: ['formatter', 'linter', 'semantic-validator'],\n },\n {\n title: `Test and validate: ${title}`,\n description: 'Add tests and validate implementation',\n estimatedTurns: 3,\n verifiers: ['test-runner', 'semantic-validator'],\n },\n {\n title: `Polish and document: ${title}`,\n description: 'Final improvements and documentation',\n estimatedTurns: 1,\n verifiers: ['formatter', 'linter'],\n },\n ];\n}\n\n/**\n * Open or create database\n */\nasync function openDatabase(projectRoot: string): Promise<Database.Database> {\n const dbPath = join(projectRoot, '.stackmemory', 'cache.db');\n\n if (!existsSync(join(projectRoot, '.stackmemory'))) {\n throw new Error(\n 'StackMemory not initialized. Run \"stackmemory init\" first.'\n );\n }\n\n return new Database(dbPath);\n}\n\n/**\n * Get color function for status\n */\nfunction getStatusColor(status: string): (text: string) => string {\n switch (status) {\n case 'active':\n return chalk.green;\n case 'completed':\n return chalk.blue;\n case 'failed':\n return chalk.red;\n case 'timeout':\n return chalk.yellow;\n default:\n return chalk.gray;\n }\n}\n\n/**\n * Delay helper\n */\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -4,11 +4,23 @@ import ora from "ora";
|
|
|
4
4
|
import { ChromaDBAdapter } from "../../core/storage/chromadb-adapter.js";
|
|
5
5
|
import { FrameManager } from "../../core/context/frame-manager.js";
|
|
6
6
|
import { Logger } from "../../core/monitoring/logger.js";
|
|
7
|
+
import { RepoIngestionSkill } from "../../skills/repo-ingestion-skill.js";
|
|
7
8
|
import Table from "cli-table3";
|
|
8
9
|
import dotenv from "dotenv";
|
|
9
10
|
import path from "path";
|
|
10
11
|
import { fileURLToPath } from "url";
|
|
11
12
|
import fs from "fs";
|
|
13
|
+
function getEnv(key, defaultValue) {
|
|
14
|
+
const value = process.env[key];
|
|
15
|
+
if (value === void 0) {
|
|
16
|
+
if (defaultValue !== void 0) return defaultValue;
|
|
17
|
+
throw new Error(`Environment variable ${key} is required`);
|
|
18
|
+
}
|
|
19
|
+
return value;
|
|
20
|
+
}
|
|
21
|
+
function getOptionalEnv(key) {
|
|
22
|
+
return process.env[key];
|
|
23
|
+
}
|
|
12
24
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
13
25
|
dotenv.config({
|
|
14
26
|
path: path.join(__dirname, "../../../.env"),
|
|
@@ -22,12 +34,12 @@ function createChromaDBCommand() {
|
|
|
22
34
|
const spinner = ora("Initializing ChromaDB...").start();
|
|
23
35
|
try {
|
|
24
36
|
const config = {
|
|
25
|
-
apiKey: options.apiKey || process.env
|
|
26
|
-
tenant: options.tenant || process.env
|
|
27
|
-
database: options.database || process.env
|
|
37
|
+
apiKey: options.apiKey || process.env["CHROMADB_API_KEY"] || "",
|
|
38
|
+
tenant: options.tenant || process.env["CHROMADB_TENANT"] || "",
|
|
39
|
+
database: options.database || process.env["CHROMADB_DATABASE"] || "stackmemory"
|
|
28
40
|
};
|
|
29
|
-
const userId = options.userId || process.env
|
|
30
|
-
const teamId = options.teamId || process.env
|
|
41
|
+
const userId = options.userId || process.env["USER"] || "default";
|
|
42
|
+
const teamId = options.teamId || process.env["CHROMADB_TEAM_ID"];
|
|
31
43
|
if (!config.apiKey || !config.tenant) {
|
|
32
44
|
spinner.fail("Missing ChromaDB credentials");
|
|
33
45
|
console.log(chalk.yellow("\nPlease provide:"));
|
|
@@ -76,12 +88,12 @@ function createChromaDBCommand() {
|
|
|
76
88
|
const spinner = ora("Storing context...").start();
|
|
77
89
|
try {
|
|
78
90
|
const config = {
|
|
79
|
-
apiKey: process.env
|
|
80
|
-
tenant: process.env
|
|
81
|
-
database: process.env
|
|
91
|
+
apiKey: process.env["CHROMADB_API_KEY"] || "",
|
|
92
|
+
tenant: process.env["CHROMADB_TENANT"] || "",
|
|
93
|
+
database: process.env["CHROMADB_DATABASE"] || "stackmemory"
|
|
82
94
|
};
|
|
83
|
-
const userId = process.env
|
|
84
|
-
const teamId = process.env
|
|
95
|
+
const userId = process.env["USER"] || "default";
|
|
96
|
+
const teamId = process.env["CHROMADB_TEAM_ID"];
|
|
85
97
|
const adapter = new ChromaDBAdapter(config, userId, teamId);
|
|
86
98
|
await adapter.initialize();
|
|
87
99
|
if (options.type === "frame") {
|
|
@@ -96,8 +108,8 @@ function createChromaDBCommand() {
|
|
|
96
108
|
const metadata = {
|
|
97
109
|
project_name: options.project || path.basename(process.cwd())
|
|
98
110
|
};
|
|
99
|
-
if (process.env
|
|
100
|
-
metadata.session_id = process.env
|
|
111
|
+
if (process.env["STACKMEMORY_SESSION_ID"]) {
|
|
112
|
+
metadata.session_id = process.env["STACKMEMORY_SESSION_ID"];
|
|
101
113
|
}
|
|
102
114
|
await adapter.storeContext(
|
|
103
115
|
options.type,
|
|
@@ -116,12 +128,12 @@ function createChromaDBCommand() {
|
|
|
116
128
|
const spinner = ora("Searching...").start();
|
|
117
129
|
try {
|
|
118
130
|
const config = {
|
|
119
|
-
apiKey: process.env
|
|
120
|
-
tenant: process.env
|
|
121
|
-
database: process.env
|
|
131
|
+
apiKey: process.env["CHROMADB_API_KEY"] || "",
|
|
132
|
+
tenant: process.env["CHROMADB_TENANT"] || "",
|
|
133
|
+
database: process.env["CHROMADB_DATABASE"] || "stackmemory"
|
|
122
134
|
};
|
|
123
|
-
const userId = process.env
|
|
124
|
-
const teamId = process.env
|
|
135
|
+
const userId = process.env["USER"] || "default";
|
|
136
|
+
const teamId = process.env["CHROMADB_TEAM_ID"];
|
|
125
137
|
const adapter = new ChromaDBAdapter(config, userId, teamId);
|
|
126
138
|
await adapter.initialize();
|
|
127
139
|
const filters = {};
|
|
@@ -168,12 +180,12 @@ function createChromaDBCommand() {
|
|
|
168
180
|
const spinner = ora("Fetching recent contexts...").start();
|
|
169
181
|
try {
|
|
170
182
|
const config = {
|
|
171
|
-
apiKey: process.env
|
|
172
|
-
tenant: process.env
|
|
173
|
-
database: process.env
|
|
183
|
+
apiKey: process.env["CHROMADB_API_KEY"] || "",
|
|
184
|
+
tenant: process.env["CHROMADB_TENANT"] || "",
|
|
185
|
+
database: process.env["CHROMADB_DATABASE"] || "stackmemory"
|
|
174
186
|
};
|
|
175
|
-
const userId = process.env
|
|
176
|
-
const teamId = process.env
|
|
187
|
+
const userId = process.env["USER"] || "default";
|
|
188
|
+
const teamId = process.env["CHROMADB_TEAM_ID"];
|
|
177
189
|
const adapter = new ChromaDBAdapter(config, userId, teamId);
|
|
178
190
|
await adapter.initialize();
|
|
179
191
|
const results = await adapter.getRecentContexts(
|
|
@@ -213,12 +225,12 @@ function createChromaDBCommand() {
|
|
|
213
225
|
const spinner = ora("Fetching statistics...").start();
|
|
214
226
|
try {
|
|
215
227
|
const config = {
|
|
216
|
-
apiKey: process.env
|
|
217
|
-
tenant: process.env
|
|
218
|
-
database: process.env
|
|
228
|
+
apiKey: process.env["CHROMADB_API_KEY"] || "",
|
|
229
|
+
tenant: process.env["CHROMADB_TENANT"] || "",
|
|
230
|
+
database: process.env["CHROMADB_DATABASE"] || "stackmemory"
|
|
219
231
|
};
|
|
220
|
-
const userId = process.env
|
|
221
|
-
const teamId = process.env
|
|
232
|
+
const userId = process.env["USER"] || "default";
|
|
233
|
+
const teamId = process.env["CHROMADB_TEAM_ID"];
|
|
222
234
|
const adapter = new ChromaDBAdapter(config, userId, teamId);
|
|
223
235
|
await adapter.initialize();
|
|
224
236
|
const stats = await adapter.getStats();
|
|
@@ -243,12 +255,12 @@ function createChromaDBCommand() {
|
|
|
243
255
|
const spinner = ora("Cleaning old contexts...").start();
|
|
244
256
|
try {
|
|
245
257
|
const config = {
|
|
246
|
-
apiKey: process.env
|
|
247
|
-
tenant: process.env
|
|
248
|
-
database: process.env
|
|
258
|
+
apiKey: process.env["CHROMADB_API_KEY"] || "",
|
|
259
|
+
tenant: process.env["CHROMADB_TENANT"] || "",
|
|
260
|
+
database: process.env["CHROMADB_DATABASE"] || "stackmemory"
|
|
249
261
|
};
|
|
250
|
-
const userId = process.env
|
|
251
|
-
const teamId = process.env
|
|
262
|
+
const userId = process.env["USER"] || "default";
|
|
263
|
+
const teamId = process.env["CHROMADB_TEAM_ID"];
|
|
252
264
|
const adapter = new ChromaDBAdapter(config, userId, teamId);
|
|
253
265
|
await adapter.initialize();
|
|
254
266
|
const deleted = await adapter.deleteOldContexts(parseInt(options.days));
|
|
@@ -259,6 +271,179 @@ function createChromaDBCommand() {
|
|
|
259
271
|
console.error(chalk.red(error instanceof Error ? error.message : "Unknown error"));
|
|
260
272
|
}
|
|
261
273
|
});
|
|
274
|
+
chromadb.command("ingest <name>").description("Ingest a repository into ChromaDB for code search").option("--path <path>", "Repository path (default: current directory)").option("--incremental", "Only process changed files").option("--include-tests", "Include test files").option("--include-docs", "Include documentation files").option("--force-update", "Force re-indexing of all files").option("--max-file-size <bytes>", "Maximum file size to process").option("--chunk-size <lines>", "Lines per chunk").action(async (name, options) => {
|
|
275
|
+
const spinner = ora("Ingesting repository...").start();
|
|
276
|
+
try {
|
|
277
|
+
const config = {
|
|
278
|
+
apiKey: process.env["CHROMADB_API_KEY"] || "",
|
|
279
|
+
tenant: process.env["CHROMADB_TENANT"] || "",
|
|
280
|
+
database: process.env["CHROMADB_DATABASE"] || "stackmemory",
|
|
281
|
+
collectionName: "stackmemory_repos"
|
|
282
|
+
};
|
|
283
|
+
if (!config.apiKey || !config.tenant) {
|
|
284
|
+
spinner.fail("ChromaDB not configured");
|
|
285
|
+
console.log(chalk.yellow("\nPlease run: stackmemory chromadb init"));
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
const userId = process.env["USER"] || "default";
|
|
289
|
+
const teamId = process.env["CHROMADB_TEAM_ID"];
|
|
290
|
+
const skill = new RepoIngestionSkill(config, userId, teamId);
|
|
291
|
+
await skill.initialize();
|
|
292
|
+
const repoPath = options.path || process.cwd();
|
|
293
|
+
const result = await skill.ingestRepository(repoPath, name, {
|
|
294
|
+
incremental: options.incremental,
|
|
295
|
+
forceUpdate: options.forceUpdate,
|
|
296
|
+
includeTests: options.includeTests,
|
|
297
|
+
includeDocs: options.includeDocs,
|
|
298
|
+
maxFileSize: options.maxFileSize ? parseInt(options.maxFileSize) : void 0,
|
|
299
|
+
chunkSize: options.chunkSize ? parseInt(options.chunkSize) : void 0
|
|
300
|
+
});
|
|
301
|
+
if (result.success) {
|
|
302
|
+
spinner.succeed(result.message);
|
|
303
|
+
if (result.stats) {
|
|
304
|
+
console.log(chalk.green("\n\u{1F4CA} Ingestion Statistics:"));
|
|
305
|
+
console.log(` Files processed: ${result.stats.filesProcessed}`);
|
|
306
|
+
console.log(` Chunks created: ${result.stats.chunksCreated}`);
|
|
307
|
+
console.log(` Total size: ${(result.stats.totalSize / 1024 / 1024).toFixed(2)} MB`);
|
|
308
|
+
console.log(` Time elapsed: ${(result.stats.timeElapsed / 1e3).toFixed(2)} seconds`);
|
|
309
|
+
}
|
|
310
|
+
} else {
|
|
311
|
+
spinner.fail(result.message);
|
|
312
|
+
}
|
|
313
|
+
} catch (error) {
|
|
314
|
+
spinner.fail("Failed to ingest repository");
|
|
315
|
+
logger.error("Ingestion error", error);
|
|
316
|
+
console.error(chalk.red(error instanceof Error ? error.message : "Unknown error"));
|
|
317
|
+
}
|
|
318
|
+
});
|
|
319
|
+
chromadb.command("update <name>").description("Update an existing repository in ChromaDB").option("--path <path>", "Repository path (default: current directory)").option("--force-update", "Force re-indexing of all files").action(async (name, options) => {
|
|
320
|
+
const spinner = ora("Updating repository...").start();
|
|
321
|
+
try {
|
|
322
|
+
const config = {
|
|
323
|
+
apiKey: process.env["CHROMADB_API_KEY"] || "",
|
|
324
|
+
tenant: process.env["CHROMADB_TENANT"] || "",
|
|
325
|
+
database: process.env["CHROMADB_DATABASE"] || "stackmemory",
|
|
326
|
+
collectionName: "stackmemory_repos"
|
|
327
|
+
};
|
|
328
|
+
if (!config.apiKey || !config.tenant) {
|
|
329
|
+
spinner.fail("ChromaDB not configured");
|
|
330
|
+
console.log(chalk.yellow("\nPlease run: stackmemory chromadb init"));
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
const userId = process.env["USER"] || "default";
|
|
334
|
+
const teamId = process.env["CHROMADB_TEAM_ID"];
|
|
335
|
+
const skill = new RepoIngestionSkill(config, userId, teamId);
|
|
336
|
+
await skill.initialize();
|
|
337
|
+
const repoPath = options.path || process.cwd();
|
|
338
|
+
const result = await skill.updateRepository(repoPath, name, {
|
|
339
|
+
forceUpdate: options.forceUpdate
|
|
340
|
+
});
|
|
341
|
+
if (result.success) {
|
|
342
|
+
spinner.succeed(result.message);
|
|
343
|
+
if (result.stats) {
|
|
344
|
+
console.log(chalk.green("\n\u{1F4CA} Update Statistics:"));
|
|
345
|
+
console.log(` Files updated: ${result.stats.filesUpdated}`);
|
|
346
|
+
console.log(` Files added: ${result.stats.filesAdded}`);
|
|
347
|
+
console.log(` Files removed: ${result.stats.filesRemoved}`);
|
|
348
|
+
console.log(` Time elapsed: ${(result.stats.timeElapsed / 1e3).toFixed(2)} seconds`);
|
|
349
|
+
}
|
|
350
|
+
} else {
|
|
351
|
+
spinner.fail(result.message);
|
|
352
|
+
}
|
|
353
|
+
} catch (error) {
|
|
354
|
+
spinner.fail("Failed to update repository");
|
|
355
|
+
logger.error("Update error", error);
|
|
356
|
+
console.error(chalk.red(error instanceof Error ? error.message : "Unknown error"));
|
|
357
|
+
}
|
|
358
|
+
});
|
|
359
|
+
chromadb.command("search-code <query>").description("Search code in ingested repositories").option("--repo <name>", "Filter by repository name").option("--language <lang>", "Filter by programming language").option("--limit <n>", "Maximum results", "20").action(async (query, options) => {
|
|
360
|
+
const spinner = ora("Searching code...").start();
|
|
361
|
+
try {
|
|
362
|
+
const config = {
|
|
363
|
+
apiKey: process.env["CHROMADB_API_KEY"] || "",
|
|
364
|
+
tenant: process.env["CHROMADB_TENANT"] || "",
|
|
365
|
+
database: process.env["CHROMADB_DATABASE"] || "stackmemory",
|
|
366
|
+
collectionName: "stackmemory_repos"
|
|
367
|
+
};
|
|
368
|
+
if (!config.apiKey || !config.tenant) {
|
|
369
|
+
spinner.fail("ChromaDB not configured");
|
|
370
|
+
console.log(chalk.yellow("\nPlease run: stackmemory chromadb init"));
|
|
371
|
+
return;
|
|
372
|
+
}
|
|
373
|
+
const userId = process.env["USER"] || "default";
|
|
374
|
+
const teamId = process.env["CHROMADB_TEAM_ID"];
|
|
375
|
+
const skill = new RepoIngestionSkill(config, userId, teamId);
|
|
376
|
+
await skill.initialize();
|
|
377
|
+
const results = await skill.searchCode(query, {
|
|
378
|
+
repoName: options.repo,
|
|
379
|
+
language: options.language,
|
|
380
|
+
limit: parseInt(options.limit)
|
|
381
|
+
});
|
|
382
|
+
spinner.stop();
|
|
383
|
+
if (results.length === 0) {
|
|
384
|
+
console.log(chalk.yellow("No results found"));
|
|
385
|
+
return;
|
|
386
|
+
}
|
|
387
|
+
console.log(chalk.cyan(`
|
|
388
|
+
\u{1F50D} Found ${results.length} code matches:
|
|
389
|
+
`));
|
|
390
|
+
for (const result of results) {
|
|
391
|
+
console.log(chalk.green(`\u{1F4C1} ${result.repoName}/${result.filePath}`));
|
|
392
|
+
console.log(chalk.gray(` Lines ${result.startLine}-${result.endLine} | Score: ${result.score.toFixed(3)}`));
|
|
393
|
+
const lines = result.content.split("\n").slice(0, 3);
|
|
394
|
+
lines.forEach((line) => {
|
|
395
|
+
console.log(chalk.dim(` ${line.slice(0, 80)}${line.length > 80 ? "..." : ""}`));
|
|
396
|
+
});
|
|
397
|
+
console.log();
|
|
398
|
+
}
|
|
399
|
+
} catch (error) {
|
|
400
|
+
spinner.fail("Failed to search code");
|
|
401
|
+
logger.error("Search error", error);
|
|
402
|
+
console.error(chalk.red(error instanceof Error ? error.message : "Unknown error"));
|
|
403
|
+
}
|
|
404
|
+
});
|
|
405
|
+
chromadb.command("repo-stats [name]").description("Get statistics for ingested repositories").action(async (name) => {
|
|
406
|
+
const spinner = ora("Fetching repository statistics...").start();
|
|
407
|
+
try {
|
|
408
|
+
const config = {
|
|
409
|
+
apiKey: process.env["CHROMADB_API_KEY"] || "",
|
|
410
|
+
tenant: process.env["CHROMADB_TENANT"] || "",
|
|
411
|
+
database: process.env["CHROMADB_DATABASE"] || "stackmemory",
|
|
412
|
+
collectionName: "stackmemory_repos"
|
|
413
|
+
};
|
|
414
|
+
if (!config.apiKey || !config.tenant) {
|
|
415
|
+
spinner.fail("ChromaDB not configured");
|
|
416
|
+
console.log(chalk.yellow("\nPlease run: stackmemory chromadb init"));
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
const userId = process.env["USER"] || "default";
|
|
420
|
+
const teamId = process.env["CHROMADB_TEAM_ID"];
|
|
421
|
+
const skill = new RepoIngestionSkill(config, userId, teamId);
|
|
422
|
+
await skill.initialize();
|
|
423
|
+
const stats = await skill.getRepoStats(name);
|
|
424
|
+
spinner.stop();
|
|
425
|
+
console.log(chalk.cyan("\n\u{1F4CA} Repository Statistics\n"));
|
|
426
|
+
console.log(`Total repositories: ${chalk.bold(stats.totalRepos)}`);
|
|
427
|
+
console.log(`Total files: ${chalk.bold(stats.totalFiles)}`);
|
|
428
|
+
console.log(`Total chunks: ${chalk.bold(stats.totalChunks)}`);
|
|
429
|
+
if (Object.keys(stats.languages).length > 0) {
|
|
430
|
+
console.log("\nLanguages:");
|
|
431
|
+
for (const [lang, count] of Object.entries(stats.languages)) {
|
|
432
|
+
console.log(` ${lang}: ${count}`);
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
if (Object.keys(stats.frameworks).length > 0) {
|
|
436
|
+
console.log("\nFrameworks:");
|
|
437
|
+
for (const [framework, count] of Object.entries(stats.frameworks)) {
|
|
438
|
+
console.log(` ${framework}: ${count}`);
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
} catch (error) {
|
|
442
|
+
spinner.fail("Failed to get repository statistics");
|
|
443
|
+
logger.error("Stats error", error);
|
|
444
|
+
console.error(chalk.red(error instanceof Error ? error.message : "Unknown error"));
|
|
445
|
+
}
|
|
446
|
+
});
|
|
262
447
|
return chromadb;
|
|
263
448
|
}
|
|
264
449
|
export {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/cli/commands/chromadb.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * ChromaDB CLI Commands for StackMemory\n * \n * Provides commands to interact with ChromaDB vector storage\n */\n\nimport { Command } from 'commander';\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport { ChromaDBAdapter } from '../../core/storage/chromadb-adapter.js';\nimport { FrameManager } from '../../core/context/frame-manager.js';\nimport { Logger } from '../../core/monitoring/logger.js';\nimport Table from 'cli-table3';\nimport dotenv from 'dotenv';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\nimport fs from 'fs';\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\n// Load environment variables\ndotenv.config({ \n path: path.join(__dirname, '../../../.env'),\n override: true,\n silent: true\n});\n\nconst logger = new Logger('ChromaDB-CLI');\n\nexport function createChromaDBCommand(): Command {\n const chromadb = new Command('chromadb')\n .description('Manage ChromaDB vector storage for context')\n .alias('chroma');\n\n // Initialize ChromaDB\n chromadb\n .command('init')\n .description('Initialize ChromaDB connection')\n .option('--api-key <key>', 'ChromaDB API key')\n .option('--tenant <tenant>', 'ChromaDB tenant ID')\n .option('--database <database>', 'ChromaDB database name')\n .option('--user-id <id>', 'User ID for segmentation')\n .option('--team-id <id>', 'Team ID for segmentation')\n .action(async (options) => {\n const spinner = ora('Initializing ChromaDB...').start();\n\n try {\n // Get config from options or environment\n const config = {\n apiKey: options.apiKey || process.env.CHROMADB_API_KEY || '',\n tenant: options.tenant || process.env.CHROMADB_TENANT || '',\n database: options.database || process.env.CHROMADB_DATABASE || 'stackmemory',\n };\n\n const userId = options.userId || process.env.USER || 'default';\n const teamId = options.teamId || process.env.CHROMADB_TEAM_ID;\n\n if (!config.apiKey || !config.tenant) {\n spinner.fail('Missing ChromaDB credentials');\n console.log(chalk.yellow('\\nPlease provide:'));\n console.log(' --api-key <key> ChromaDB API key');\n console.log(' --tenant <tenant> ChromaDB tenant ID');\n console.log('\\nOr set environment variables:');\n console.log(' CHROMADB_API_KEY');\n console.log(' CHROMADB_TENANT');\n return;\n }\n\n // Initialize adapter\n const adapter = new ChromaDBAdapter(config, userId, teamId);\n await adapter.initialize();\n\n // Save config to .env if not present\n const envPath = path.join(__dirname, '../../../.env');\n let envContent = '';\n \n if (fs.existsSync(envPath)) {\n envContent = fs.readFileSync(envPath, 'utf8');\n }\n\n const updates: string[] = [];\n if (!envContent.includes('CHROMADB_API_KEY')) {\n updates.push(`CHROMADB_API_KEY=${config.apiKey}`);\n }\n if (!envContent.includes('CHROMADB_TENANT')) {\n updates.push(`CHROMADB_TENANT=${config.tenant}`);\n }\n if (!envContent.includes('CHROMADB_DATABASE')) {\n updates.push(`CHROMADB_DATABASE=${config.database}`);\n }\n\n if (updates.length > 0) {\n fs.appendFileSync(envPath, '\\n# ChromaDB Configuration\\n' + updates.join('\\n') + '\\n');\n }\n\n spinner.succeed('ChromaDB initialized successfully');\n \n console.log(chalk.green('\\n\u2705 Configuration:'));\n console.log(` Tenant: ${config.tenant}`);\n console.log(` Database: ${config.database}`);\n console.log(` User ID: ${userId}`);\n if (teamId) {\n console.log(` Team ID: ${teamId}`);\n }\n } catch (error) {\n spinner.fail('Failed to initialize ChromaDB');\n logger.error('Initialization error', error);\n console.error(chalk.red(error instanceof Error ? error.message : 'Unknown error'));\n }\n });\n\n // Store current context\n chromadb\n .command('store')\n .description('Store current context in ChromaDB')\n .option('--type <type>', 'Context type (frame/decision/observation)', 'frame')\n .option('--content <content>', 'Content to store')\n .option('--project <name>', 'Project name')\n .action(async (options) => {\n const spinner = ora('Storing context...').start();\n\n try {\n const config = {\n apiKey: process.env.CHROMADB_API_KEY || '',\n tenant: process.env.CHROMADB_TENANT || '',\n database: process.env.CHROMADB_DATABASE || 'stackmemory',\n };\n\n const userId = process.env.USER || 'default';\n const teamId = process.env.CHROMADB_TEAM_ID;\n\n const adapter = new ChromaDBAdapter(config, userId, teamId);\n await adapter.initialize();\n\n if (options.type === 'frame') {\n // Store current frames\n const frameManager = new FrameManager();\n const frames = frameManager.getAllFrames();\n \n for (const frame of frames) {\n await adapter.storeFrame(frame);\n }\n \n spinner.succeed(`Stored ${frames.length} frames`);\n } else {\n // Store decision or observation\n const content = options.content || `${options.type} at ${new Date().toISOString()}`;\n const metadata: any = {\n project_name: options.project || path.basename(process.cwd()),\n };\n \n // Only add session_id if it exists\n if (process.env.STACKMEMORY_SESSION_ID) {\n metadata.session_id = process.env.STACKMEMORY_SESSION_ID;\n }\n \n await adapter.storeContext(\n options.type as 'decision' | 'observation',\n content,\n metadata\n );\n \n spinner.succeed(`Stored ${options.type}`);\n }\n } catch (error) {\n spinner.fail('Failed to store context');\n logger.error('Store error', error);\n console.error(chalk.red(error instanceof Error ? error.message : 'Unknown error'));\n }\n });\n\n // Query contexts\n chromadb\n .command('query <search>')\n .description('Query contexts from ChromaDB')\n .option('--limit <n>', 'Number of results', '10')\n .option('--type <type>', 'Filter by type')\n .option('--project <name>', 'Filter by project')\n .action(async (search, options) => {\n const spinner = ora('Searching...').start();\n\n try {\n const config = {\n apiKey: process.env.CHROMADB_API_KEY || '',\n tenant: process.env.CHROMADB_TENANT || '',\n database: process.env.CHROMADB_DATABASE || 'stackmemory',\n };\n\n const userId = process.env.USER || 'default';\n const teamId = process.env.CHROMADB_TEAM_ID;\n\n const adapter = new ChromaDBAdapter(config, userId, teamId);\n await adapter.initialize();\n\n const filters: any = {};\n if (options.type) {\n filters.type = [options.type];\n }\n if (options.project) {\n filters.projectName = options.project;\n }\n\n const results = await adapter.queryContexts(\n search,\n parseInt(options.limit),\n filters\n );\n\n spinner.stop();\n\n if (results.length === 0) {\n console.log(chalk.yellow('No results found'));\n return;\n }\n\n // Display results\n const table = new Table({\n head: ['Type', 'Project', 'Content', 'Distance'],\n colWidths: [15, 20, 50, 10],\n wordWrap: true,\n });\n\n for (const result of results) {\n const content = result.content.substring(0, 100) + \n (result.content.length > 100 ? '...' : '');\n \n table.push([\n result.metadata.type || 'unknown',\n result.metadata.project_name || 'default',\n content,\n result.distance.toFixed(3),\n ]);\n }\n\n console.log(table.toString());\n console.log(chalk.green(`\\n\u2705 Found ${results.length} results`));\n } catch (error) {\n spinner.fail('Failed to query contexts');\n logger.error('Query error', error);\n console.error(chalk.red(error instanceof Error ? error.message : 'Unknown error'));\n }\n });\n\n // Get recent contexts\n chromadb\n .command('recent')\n .description('Get recent contexts')\n .option('--limit <n>', 'Number of results', '20')\n .option('--type <type>', 'Filter by type')\n .action(async (options) => {\n const spinner = ora('Fetching recent contexts...').start();\n\n try {\n const config = {\n apiKey: process.env.CHROMADB_API_KEY || '',\n tenant: process.env.CHROMADB_TENANT || '',\n database: process.env.CHROMADB_DATABASE || 'stackmemory',\n };\n\n const userId = process.env.USER || 'default';\n const teamId = process.env.CHROMADB_TEAM_ID;\n\n const adapter = new ChromaDBAdapter(config, userId, teamId);\n await adapter.initialize();\n\n const results = await adapter.getRecentContexts(\n parseInt(options.limit),\n options.type\n );\n\n spinner.stop();\n\n if (results.length === 0) {\n console.log(chalk.yellow('No recent contexts found'));\n return;\n }\n\n // Display results\n const table = new Table({\n head: ['Time', 'Type', 'Project', 'Content'],\n colWidths: [20, 12, 20, 48],\n wordWrap: true,\n });\n\n for (const result of results) {\n const time = new Date(result.metadata.timestamp).toLocaleString();\n const content = result.content.substring(0, 100) + \n (result.content.length > 100 ? '...' : '');\n \n table.push([\n time,\n result.metadata.type || 'unknown',\n result.metadata.project_name || 'default',\n content,\n ]);\n }\n\n console.log(table.toString());\n console.log(chalk.green(`\\n\u2705 Found ${results.length} recent contexts`));\n } catch (error) {\n spinner.fail('Failed to get recent contexts');\n logger.error('Recent error', error);\n console.error(chalk.red(error instanceof Error ? error.message : 'Unknown error'));\n }\n });\n\n // Get statistics\n chromadb\n .command('stats')\n .description('Get ChromaDB storage statistics')\n .action(async () => {\n const spinner = ora('Fetching statistics...').start();\n\n try {\n const config = {\n apiKey: process.env.CHROMADB_API_KEY || '',\n tenant: process.env.CHROMADB_TENANT || '',\n database: process.env.CHROMADB_DATABASE || 'stackmemory',\n };\n\n const userId = process.env.USER || 'default';\n const teamId = process.env.CHROMADB_TEAM_ID;\n\n const adapter = new ChromaDBAdapter(config, userId, teamId);\n await adapter.initialize();\n\n const stats = await adapter.getStats();\n\n spinner.stop();\n\n console.log(chalk.cyan('\\n\uD83D\uDCCA ChromaDB Statistics\\n'));\n console.log(`Total Documents: ${chalk.bold(stats.totalDocuments)}`);\n console.log(`User Documents: ${chalk.bold(stats.userDocuments)}`);\n \n if (stats.teamDocuments !== undefined) {\n console.log(`Team Documents: ${chalk.bold(stats.teamDocuments)}`);\n }\n\n console.log('\\nDocuments by Type:');\n for (const [type, count] of Object.entries(stats.documentsByType)) {\n console.log(` ${type}: ${count}`);\n }\n } catch (error) {\n spinner.fail('Failed to get statistics');\n logger.error('Stats error', error);\n console.error(chalk.red(error instanceof Error ? error.message : 'Unknown error'));\n }\n });\n\n // Clean old contexts\n chromadb\n .command('clean')\n .description('Clean old contexts')\n .option('--days <n>', 'Delete contexts older than N days', '30')\n .action(async (options) => {\n const spinner = ora('Cleaning old contexts...').start();\n\n try {\n const config = {\n apiKey: process.env.CHROMADB_API_KEY || '',\n tenant: process.env.CHROMADB_TENANT || '',\n database: process.env.CHROMADB_DATABASE || 'stackmemory',\n };\n\n const userId = process.env.USER || 'default';\n const teamId = process.env.CHROMADB_TEAM_ID;\n\n const adapter = new ChromaDBAdapter(config, userId, teamId);\n await adapter.initialize();\n\n const deleted = await adapter.deleteOldContexts(parseInt(options.days));\n\n spinner.succeed(`Deleted ${deleted} old contexts`);\n } catch (error) {\n spinner.fail('Failed to clean contexts');\n logger.error('Clean error', error);\n console.error(chalk.red(error instanceof Error ? error.message : 'Unknown error'));\n }\n });\n\n return chromadb;\n}"],
|
|
5
|
-
"mappings": "AAMA,SAAS,eAAe;AACxB,OAAO,WAAW;AAClB,OAAO,SAAS;AAChB,SAAS,uBAAuB;AAChC,SAAS,oBAAoB;AAC7B,SAAS,cAAc;AACvB,OAAO,WAAW;AAClB,OAAO,YAAY;AACnB,OAAO,UAAU;AACjB,SAAS,qBAAqB;AAC9B,OAAO,QAAQ;AAEf,MAAM,YAAY,KAAK,QAAQ,cAAc,YAAY,GAAG,CAAC;AAG7D,OAAO,OAAO;AAAA,EACZ,MAAM,KAAK,KAAK,WAAW,eAAe;AAAA,EAC1C,UAAU;AAAA,EACV,QAAQ;AACV,CAAC;AAED,MAAM,SAAS,IAAI,OAAO,cAAc;AAEjC,SAAS,wBAAiC;AAC/C,QAAM,WAAW,IAAI,QAAQ,UAAU,EACpC,YAAY,4CAA4C,EACxD,MAAM,QAAQ;AAGjB,WACG,QAAQ,MAAM,EACd,YAAY,gCAAgC,EAC5C,OAAO,mBAAmB,kBAAkB,EAC5C,OAAO,qBAAqB,oBAAoB,EAChD,OAAO,yBAAyB,wBAAwB,EACxD,OAAO,kBAAkB,0BAA0B,EACnD,OAAO,kBAAkB,0BAA0B,EACnD,OAAO,OAAO,YAAY;AACzB,UAAM,UAAU,IAAI,0BAA0B,EAAE,MAAM;AAEtD,QAAI;AAEF,YAAM,SAAS;AAAA,QACb,QAAQ,QAAQ,UAAU,QAAQ,IAAI,oBAAoB;AAAA,QAC1D,QAAQ,QAAQ,UAAU,QAAQ,IAAI,mBAAmB;AAAA,QACzD,UAAU,QAAQ,YAAY,QAAQ,IAAI,qBAAqB;AAAA,MACjE;AAEA,YAAM,SAAS,QAAQ,UAAU,QAAQ,IAAI,QAAQ;AACrD,YAAM,SAAS,QAAQ,UAAU,QAAQ,IAAI;AAE7C,UAAI,CAAC,OAAO,UAAU,CAAC,OAAO,QAAQ;AACpC,gBAAQ,KAAK,8BAA8B;AAC3C,gBAAQ,IAAI,MAAM,OAAO,mBAAmB,CAAC;AAC7C,gBAAQ,IAAI,uCAAuC;AACnD,gBAAQ,IAAI,yCAAyC;AACrD,gBAAQ,IAAI,iCAAiC;AAC7C,gBAAQ,IAAI,oBAAoB;AAChC,gBAAQ,IAAI,mBAAmB;AAC/B;AAAA,MACF;AAGA,YAAM,UAAU,IAAI,gBAAgB,QAAQ,QAAQ,MAAM;AAC1D,YAAM,QAAQ,WAAW;AAGzB,YAAM,UAAU,KAAK,KAAK,WAAW,eAAe;AACpD,UAAI,aAAa;AAEjB,UAAI,GAAG,WAAW,OAAO,GAAG;AAC1B,qBAAa,GAAG,aAAa,SAAS,MAAM;AAAA,MAC9C;AAEA,YAAM,UAAoB,CAAC;AAC3B,UAAI,CAAC,WAAW,SAAS,kBAAkB,GAAG;AAC5C,gBAAQ,KAAK,oBAAoB,OAAO,MAAM,EAAE;AAAA,MAClD;AACA,UAAI,CAAC,WAAW,SAAS,iBAAiB,GAAG;AAC3C,gBAAQ,KAAK,mBAAmB,OAAO,MAAM,EAAE;AAAA,MACjD;AACA,UAAI,CAAC,WAAW,SAAS,mBAAmB,GAAG;AAC7C,gBAAQ,KAAK,qBAAqB,OAAO,QAAQ,EAAE;AAAA,MACrD;AAEA,UAAI,QAAQ,SAAS,GAAG;AACtB,WAAG,eAAe,SAAS,iCAAiC,QAAQ,KAAK,IAAI,IAAI,IAAI;AAAA,MACvF;AAEA,cAAQ,QAAQ,mCAAmC;AAEnD,cAAQ,IAAI,MAAM,MAAM,yBAAoB,CAAC;AAC7C,cAAQ,IAAI,aAAa,OAAO,MAAM,EAAE;AACxC,cAAQ,IAAI,eAAe,OAAO,QAAQ,EAAE;AAC5C,cAAQ,IAAI,cAAc,MAAM,EAAE;AAClC,UAAI,QAAQ;AACV,gBAAQ,IAAI,cAAc,MAAM,EAAE;AAAA,MACpC;AAAA,IACF,SAAS,OAAO;AACd,cAAQ,KAAK,+BAA+B;AAC5C,aAAO,MAAM,wBAAwB,KAAK;AAC1C,cAAQ,MAAM,MAAM,IAAI,iBAAiB,QAAQ,MAAM,UAAU,eAAe,CAAC;AAAA,IACnF;AAAA,EACF,CAAC;AAGH,WACG,QAAQ,OAAO,EACf,YAAY,mCAAmC,EAC/C,OAAO,iBAAiB,6CAA6C,OAAO,EAC5E,OAAO,uBAAuB,kBAAkB,EAChD,OAAO,oBAAoB,cAAc,EACzC,OAAO,OAAO,YAAY;AACzB,UAAM,UAAU,IAAI,oBAAoB,EAAE,MAAM;AAEhD,QAAI;AACF,YAAM,SAAS;AAAA,QACb,QAAQ,QAAQ,IAAI,oBAAoB;AAAA,QACxC,QAAQ,QAAQ,IAAI,mBAAmB;AAAA,QACvC,UAAU,QAAQ,IAAI,qBAAqB;AAAA,MAC7C;AAEA,YAAM,SAAS,QAAQ,IAAI,QAAQ;AACnC,YAAM,SAAS,QAAQ,IAAI;AAE3B,YAAM,UAAU,IAAI,gBAAgB,QAAQ,QAAQ,MAAM;AAC1D,YAAM,QAAQ,WAAW;AAEzB,UAAI,QAAQ,SAAS,SAAS;AAE5B,cAAM,eAAe,IAAI,aAAa;AACtC,cAAM,SAAS,aAAa,aAAa;AAEzC,mBAAW,SAAS,QAAQ;AAC1B,gBAAM,QAAQ,WAAW,KAAK;AAAA,QAChC;AAEA,gBAAQ,QAAQ,UAAU,OAAO,MAAM,SAAS;AAAA,MAClD,OAAO;AAEL,cAAM,UAAU,QAAQ,WAAW,GAAG,QAAQ,IAAI,QAAO,oBAAI,KAAK,GAAE,YAAY,CAAC;AACjF,cAAM,WAAgB;AAAA,UACpB,cAAc,QAAQ,WAAW,KAAK,SAAS,QAAQ,IAAI,CAAC;AAAA,QAC9D;AAGA,YAAI,QAAQ,IAAI,wBAAwB;AACtC,mBAAS,aAAa,QAAQ,IAAI;AAAA,QACpC;AAEA,cAAM,QAAQ;AAAA,UACZ,QAAQ;AAAA,UACR;AAAA,UACA;AAAA,QACF;AAEA,gBAAQ,QAAQ,UAAU,QAAQ,IAAI,EAAE;AAAA,MAC1C;AAAA,IACF,SAAS,OAAO;AACd,cAAQ,KAAK,yBAAyB;AACtC,aAAO,MAAM,eAAe,KAAK;AACjC,cAAQ,MAAM,MAAM,IAAI,iBAAiB,QAAQ,MAAM,UAAU,eAAe,CAAC;AAAA,IACnF;AAAA,EACF,CAAC;AAGH,WACG,QAAQ,gBAAgB,EACxB,YAAY,8BAA8B,EAC1C,OAAO,eAAe,qBAAqB,IAAI,EAC/C,OAAO,iBAAiB,gBAAgB,EACxC,OAAO,oBAAoB,mBAAmB,EAC9C,OAAO,OAAO,QAAQ,YAAY;AACjC,UAAM,UAAU,IAAI,cAAc,EAAE,MAAM;AAE1C,QAAI;AACF,YAAM,SAAS;AAAA,QACb,QAAQ,QAAQ,IAAI,oBAAoB;AAAA,QACxC,QAAQ,QAAQ,IAAI,mBAAmB;AAAA,QACvC,UAAU,QAAQ,IAAI,qBAAqB;AAAA,MAC7C;AAEA,YAAM,SAAS,QAAQ,IAAI,QAAQ;AACnC,YAAM,SAAS,QAAQ,IAAI;AAE3B,YAAM,UAAU,IAAI,gBAAgB,QAAQ,QAAQ,MAAM;AAC1D,YAAM,QAAQ,WAAW;AAEzB,YAAM,UAAe,CAAC;AACtB,UAAI,QAAQ,MAAM;AAChB,gBAAQ,OAAO,CAAC,QAAQ,IAAI;AAAA,MAC9B;AACA,UAAI,QAAQ,SAAS;AACnB,gBAAQ,cAAc,QAAQ;AAAA,MAChC;AAEA,YAAM,UAAU,MAAM,QAAQ;AAAA,QAC5B;AAAA,QACA,SAAS,QAAQ,KAAK;AAAA,QACtB;AAAA,MACF;AAEA,cAAQ,KAAK;AAEb,UAAI,QAAQ,WAAW,GAAG;AACxB,gBAAQ,IAAI,MAAM,OAAO,kBAAkB,CAAC;AAC5C;AAAA,MACF;AAGA,YAAM,QAAQ,IAAI,MAAM;AAAA,QACtB,MAAM,CAAC,QAAQ,WAAW,WAAW,UAAU;AAAA,QAC/C,WAAW,CAAC,IAAI,IAAI,IAAI,EAAE;AAAA,QAC1B,UAAU;AAAA,MACZ,CAAC;AAED,iBAAW,UAAU,SAAS;AAC5B,cAAM,UAAU,OAAO,QAAQ,UAAU,GAAG,GAAG,KAC9B,OAAO,QAAQ,SAAS,MAAM,QAAQ;AAEvD,cAAM,KAAK;AAAA,UACT,OAAO,SAAS,QAAQ;AAAA,UACxB,OAAO,SAAS,gBAAgB;AAAA,UAChC;AAAA,UACA,OAAO,SAAS,QAAQ,CAAC;AAAA,QAC3B,CAAC;AAAA,MACH;AAEA,cAAQ,IAAI,MAAM,SAAS,CAAC;AAC5B,cAAQ,IAAI,MAAM,MAAM;AAAA,eAAa,QAAQ,MAAM,UAAU,CAAC;AAAA,IAChE,SAAS,OAAO;AACd,cAAQ,KAAK,0BAA0B;AACvC,aAAO,MAAM,eAAe,KAAK;AACjC,cAAQ,MAAM,MAAM,IAAI,iBAAiB,QAAQ,MAAM,UAAU,eAAe,CAAC;AAAA,IACnF;AAAA,EACF,CAAC;AAGH,WACG,QAAQ,QAAQ,EAChB,YAAY,qBAAqB,EACjC,OAAO,eAAe,qBAAqB,IAAI,EAC/C,OAAO,iBAAiB,gBAAgB,EACxC,OAAO,OAAO,YAAY;AACzB,UAAM,UAAU,IAAI,6BAA6B,EAAE,MAAM;AAEzD,QAAI;AACF,YAAM,SAAS;AAAA,QACb,QAAQ,QAAQ,IAAI,oBAAoB;AAAA,QACxC,QAAQ,QAAQ,IAAI,mBAAmB;AAAA,QACvC,UAAU,QAAQ,IAAI,qBAAqB;AAAA,MAC7C;AAEA,YAAM,SAAS,QAAQ,IAAI,QAAQ;AACnC,YAAM,SAAS,QAAQ,IAAI;AAE3B,YAAM,UAAU,IAAI,gBAAgB,QAAQ,QAAQ,MAAM;AAC1D,YAAM,QAAQ,WAAW;AAEzB,YAAM,UAAU,MAAM,QAAQ;AAAA,QAC5B,SAAS,QAAQ,KAAK;AAAA,QACtB,QAAQ;AAAA,MACV;AAEA,cAAQ,KAAK;AAEb,UAAI,QAAQ,WAAW,GAAG;AACxB,gBAAQ,IAAI,MAAM,OAAO,0BAA0B,CAAC;AACpD;AAAA,MACF;AAGA,YAAM,QAAQ,IAAI,MAAM;AAAA,QACtB,MAAM,CAAC,QAAQ,QAAQ,WAAW,SAAS;AAAA,QAC3C,WAAW,CAAC,IAAI,IAAI,IAAI,EAAE;AAAA,QAC1B,UAAU;AAAA,MACZ,CAAC;AAED,iBAAW,UAAU,SAAS;AAC5B,cAAM,OAAO,IAAI,KAAK,OAAO,SAAS,SAAS,EAAE,eAAe;AAChE,cAAM,UAAU,OAAO,QAAQ,UAAU,GAAG,GAAG,KAC9B,OAAO,QAAQ,SAAS,MAAM,QAAQ;AAEvD,cAAM,KAAK;AAAA,UACT;AAAA,UACA,OAAO,SAAS,QAAQ;AAAA,UACxB,OAAO,SAAS,gBAAgB;AAAA,UAChC;AAAA,QACF,CAAC;AAAA,MACH;AAEA,cAAQ,IAAI,MAAM,SAAS,CAAC;AAC5B,cAAQ,IAAI,MAAM,MAAM;AAAA,eAAa,QAAQ,MAAM,kBAAkB,CAAC;AAAA,IACxE,SAAS,OAAO;AACd,cAAQ,KAAK,+BAA+B;AAC5C,aAAO,MAAM,gBAAgB,KAAK;AAClC,cAAQ,MAAM,MAAM,IAAI,iBAAiB,QAAQ,MAAM,UAAU,eAAe,CAAC;AAAA,IACnF;AAAA,EACF,CAAC;AAGH,WACG,QAAQ,OAAO,EACf,YAAY,iCAAiC,EAC7C,OAAO,YAAY;AAClB,UAAM,UAAU,IAAI,wBAAwB,EAAE,MAAM;AAEpD,QAAI;AACF,YAAM,SAAS;AAAA,QACb,QAAQ,QAAQ,IAAI,oBAAoB;AAAA,QACxC,QAAQ,QAAQ,IAAI,mBAAmB;AAAA,QACvC,UAAU,QAAQ,IAAI,qBAAqB;AAAA,MAC7C;AAEA,YAAM,SAAS,QAAQ,IAAI,QAAQ;AACnC,YAAM,SAAS,QAAQ,IAAI;AAE3B,YAAM,UAAU,IAAI,gBAAgB,QAAQ,QAAQ,MAAM;AAC1D,YAAM,QAAQ,WAAW;AAEzB,YAAM,QAAQ,MAAM,QAAQ,SAAS;AAErC,cAAQ,KAAK;AAEb,cAAQ,IAAI,MAAM,KAAK,mCAA4B,CAAC;AACpD,cAAQ,IAAI,oBAAoB,MAAM,KAAK,MAAM,cAAc,CAAC,EAAE;AAClE,cAAQ,IAAI,mBAAmB,MAAM,KAAK,MAAM,aAAa,CAAC,EAAE;AAEhE,UAAI,MAAM,kBAAkB,QAAW;AACrC,gBAAQ,IAAI,mBAAmB,MAAM,KAAK,MAAM,aAAa,CAAC,EAAE;AAAA,MAClE;AAEA,cAAQ,IAAI,sBAAsB;AAClC,iBAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,MAAM,eAAe,GAAG;AACjE,gBAAQ,IAAI,KAAK,IAAI,KAAK,KAAK,EAAE;AAAA,MACnC;AAAA,IACF,SAAS,OAAO;AACd,cAAQ,KAAK,0BAA0B;AACvC,aAAO,MAAM,eAAe,KAAK;AACjC,cAAQ,MAAM,MAAM,IAAI,iBAAiB,QAAQ,MAAM,UAAU,eAAe,CAAC;AAAA,IACnF;AAAA,EACF,CAAC;AAGH,WACG,QAAQ,OAAO,EACf,YAAY,oBAAoB,EAChC,OAAO,cAAc,qCAAqC,IAAI,EAC9D,OAAO,OAAO,YAAY;AACzB,UAAM,UAAU,IAAI,0BAA0B,EAAE,MAAM;AAEtD,QAAI;AACF,YAAM,SAAS;AAAA,QACb,QAAQ,QAAQ,IAAI,oBAAoB;AAAA,QACxC,QAAQ,QAAQ,IAAI,mBAAmB;AAAA,QACvC,UAAU,QAAQ,IAAI,qBAAqB;AAAA,MAC7C;AAEA,YAAM,SAAS,QAAQ,IAAI,QAAQ;AACnC,YAAM,SAAS,QAAQ,IAAI;AAE3B,YAAM,UAAU,IAAI,gBAAgB,QAAQ,QAAQ,MAAM;AAC1D,YAAM,QAAQ,WAAW;AAEzB,YAAM,UAAU,MAAM,QAAQ,kBAAkB,SAAS,QAAQ,IAAI,CAAC;AAEtE,cAAQ,QAAQ,WAAW,OAAO,eAAe;AAAA,IACnD,SAAS,OAAO;AACd,cAAQ,KAAK,0BAA0B;AACvC,aAAO,MAAM,eAAe,KAAK;AACjC,cAAQ,MAAM,MAAM,IAAI,iBAAiB,QAAQ,MAAM,UAAU,eAAe,CAAC;AAAA,IACnF;AAAA,EACF,CAAC;AAEH,SAAO;AACT;",
|
|
4
|
+
"sourcesContent": ["/**\n * ChromaDB CLI Commands for StackMemory\n * \n * Provides commands to interact with ChromaDB vector storage\n */\n\nimport { Command } from 'commander';\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport { ChromaDBAdapter } from '../../core/storage/chromadb-adapter.js';\nimport { FrameManager } from '../../core/context/frame-manager.js';\nimport { Logger } from '../../core/monitoring/logger.js';\nimport { RepoIngestionSkill } from '../../skills/repo-ingestion-skill.js';\nimport Table from 'cli-table3';\nimport dotenv from 'dotenv';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\nimport fs from 'fs';\n// Type-safe environment variable access\nfunction getEnv(key: string, defaultValue?: string): string {\n const value = process.env[key];\n if (value === undefined) {\n if (defaultValue !== undefined) return defaultValue;\n throw new Error(`Environment variable ${key} is required`);\n }\n return value;\n}\n\nfunction getOptionalEnv(key: string): string | undefined {\n return process.env[key];\n}\n\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\n// Load environment variables\ndotenv.config({ \n path: path.join(__dirname, '../../../.env'),\n override: true,\n silent: true\n});\n\nconst logger = new Logger('ChromaDB-CLI');\n\nexport function createChromaDBCommand(): Command {\n const chromadb = new Command('chromadb')\n .description('Manage ChromaDB vector storage for context')\n .alias('chroma');\n\n // Initialize ChromaDB\n chromadb\n .command('init')\n .description('Initialize ChromaDB connection')\n .option('--api-key <key>', 'ChromaDB API key')\n .option('--tenant <tenant>', 'ChromaDB tenant ID')\n .option('--database <database>', 'ChromaDB database name')\n .option('--user-id <id>', 'User ID for segmentation')\n .option('--team-id <id>', 'Team ID for segmentation')\n .action(async (options) => {\n const spinner = ora('Initializing ChromaDB...').start();\n\n try {\n // Get config from options or environment\n const config = {\n apiKey: options.apiKey || process.env['CHROMADB_API_KEY'] || '',\n tenant: options.tenant || process.env['CHROMADB_TENANT'] || '',\n database: options.database || process.env['CHROMADB_DATABASE'] || 'stackmemory',\n };\n\n const userId = options.userId || process.env['USER'] || 'default';\n const teamId = options.teamId || process.env['CHROMADB_TEAM_ID'];\n\n if (!config.apiKey || !config.tenant) {\n spinner.fail('Missing ChromaDB credentials');\n console.log(chalk.yellow('\\nPlease provide:'));\n console.log(' --api-key <key> ChromaDB API key');\n console.log(' --tenant <tenant> ChromaDB tenant ID');\n console.log('\\nOr set environment variables:');\n console.log(' CHROMADB_API_KEY');\n console.log(' CHROMADB_TENANT');\n return;\n }\n\n // Initialize adapter\n const adapter = new ChromaDBAdapter(config, userId, teamId);\n await adapter.initialize();\n\n // Save config to .env if not present\n const envPath = path.join(__dirname, '../../../.env');\n let envContent = '';\n \n if (fs.existsSync(envPath)) {\n envContent = fs.readFileSync(envPath, 'utf8');\n }\n\n const updates: string[] = [];\n if (!envContent.includes('CHROMADB_API_KEY')) {\n updates.push(`CHROMADB_API_KEY=${config.apiKey}`);\n }\n if (!envContent.includes('CHROMADB_TENANT')) {\n updates.push(`CHROMADB_TENANT=${config.tenant}`);\n }\n if (!envContent.includes('CHROMADB_DATABASE')) {\n updates.push(`CHROMADB_DATABASE=${config.database}`);\n }\n\n if (updates.length > 0) {\n fs.appendFileSync(envPath, '\\n# ChromaDB Configuration\\n' + updates.join('\\n') + '\\n');\n }\n\n spinner.succeed('ChromaDB initialized successfully');\n \n console.log(chalk.green('\\n\u2705 Configuration:'));\n console.log(` Tenant: ${config.tenant}`);\n console.log(` Database: ${config.database}`);\n console.log(` User ID: ${userId}`);\n if (teamId) {\n console.log(` Team ID: ${teamId}`);\n }\n } catch (error: unknown) {\n spinner.fail('Failed to initialize ChromaDB');\n logger.error('Initialization error', error);\n console.error(chalk.red(error instanceof Error ? error.message : 'Unknown error'));\n }\n });\n\n // Store current context\n chromadb\n .command('store')\n .description('Store current context in ChromaDB')\n .option('--type <type>', 'Context type (frame/decision/observation)', 'frame')\n .option('--content <content>', 'Content to store')\n .option('--project <name>', 'Project name')\n .action(async (options) => {\n const spinner = ora('Storing context...').start();\n\n try {\n const config = {\n apiKey: process.env['CHROMADB_API_KEY'] || '',\n tenant: process.env['CHROMADB_TENANT'] || '',\n database: process.env['CHROMADB_DATABASE'] || 'stackmemory',\n };\n\n const userId = process.env['USER'] || 'default';\n const teamId = process.env['CHROMADB_TEAM_ID'];\n\n const adapter = new ChromaDBAdapter(config, userId, teamId);\n await adapter.initialize();\n\n if (options.type === 'frame') {\n // Store current frames\n const frameManager = new FrameManager();\n const frames = frameManager.getAllFrames();\n \n for (const frame of frames) {\n await adapter.storeFrame(frame);\n }\n \n spinner.succeed(`Stored ${frames.length} frames`);\n } else {\n // Store decision or observation\n const content = options.content || `${options.type} at ${new Date().toISOString()}`;\n const metadata: any = {\n project_name: options.project || path.basename(process.cwd()),\n };\n \n // Only add session_id if it exists\n if (process.env['STACKMEMORY_SESSION_ID']) {\n metadata.session_id = process.env['STACKMEMORY_SESSION_ID'];\n }\n \n await adapter.storeContext(\n options.type as 'decision' | 'observation',\n content,\n metadata\n );\n \n spinner.succeed(`Stored ${options.type}`);\n }\n } catch (error: unknown) {\n spinner.fail('Failed to store context');\n logger.error('Store error', error);\n console.error(chalk.red(error instanceof Error ? error.message : 'Unknown error'));\n }\n });\n\n // Query contexts\n chromadb\n .command('query <search>')\n .description('Query contexts from ChromaDB')\n .option('--limit <n>', 'Number of results', '10')\n .option('--type <type>', 'Filter by type')\n .option('--project <name>', 'Filter by project')\n .action(async (search, options) => {\n const spinner = ora('Searching...').start();\n\n try {\n const config = {\n apiKey: process.env['CHROMADB_API_KEY'] || '',\n tenant: process.env['CHROMADB_TENANT'] || '',\n database: process.env['CHROMADB_DATABASE'] || 'stackmemory',\n };\n\n const userId = process.env['USER'] || 'default';\n const teamId = process.env['CHROMADB_TEAM_ID'];\n\n const adapter = new ChromaDBAdapter(config, userId, teamId);\n await adapter.initialize();\n\n const filters: any = {};\n if (options.type) {\n filters.type = [options.type];\n }\n if (options.project) {\n filters.projectName = options.project;\n }\n\n const results = await adapter.queryContexts(\n search,\n parseInt(options.limit),\n filters\n );\n\n spinner.stop();\n\n if (results.length === 0) {\n console.log(chalk.yellow('No results found'));\n return;\n }\n\n // Display results\n const table = new Table({\n head: ['Type', 'Project', 'Content', 'Distance'],\n colWidths: [15, 20, 50, 10],\n wordWrap: true,\n });\n\n for (const result of results) {\n const content = result.content.substring(0, 100) + \n (result.content.length > 100 ? '...' : '');\n \n table.push([\n result.metadata.type || 'unknown',\n result.metadata.project_name || 'default',\n content,\n result.distance.toFixed(3),\n ]);\n }\n\n console.log(table.toString());\n console.log(chalk.green(`\\n\u2705 Found ${results.length} results`));\n } catch (error: unknown) {\n spinner.fail('Failed to query contexts');\n logger.error('Query error', error);\n console.error(chalk.red(error instanceof Error ? error.message : 'Unknown error'));\n }\n });\n\n // Get recent contexts\n chromadb\n .command('recent')\n .description('Get recent contexts')\n .option('--limit <n>', 'Number of results', '20')\n .option('--type <type>', 'Filter by type')\n .action(async (options) => {\n const spinner = ora('Fetching recent contexts...').start();\n\n try {\n const config = {\n apiKey: process.env['CHROMADB_API_KEY'] || '',\n tenant: process.env['CHROMADB_TENANT'] || '',\n database: process.env['CHROMADB_DATABASE'] || 'stackmemory',\n };\n\n const userId = process.env['USER'] || 'default';\n const teamId = process.env['CHROMADB_TEAM_ID'];\n\n const adapter = new ChromaDBAdapter(config, userId, teamId);\n await adapter.initialize();\n\n const results = await adapter.getRecentContexts(\n parseInt(options.limit),\n options.type\n );\n\n spinner.stop();\n\n if (results.length === 0) {\n console.log(chalk.yellow('No recent contexts found'));\n return;\n }\n\n // Display results\n const table = new Table({\n head: ['Time', 'Type', 'Project', 'Content'],\n colWidths: [20, 12, 20, 48],\n wordWrap: true,\n });\n\n for (const result of results) {\n const time = new Date(result.metadata.timestamp).toLocaleString();\n const content = result.content.substring(0, 100) + \n (result.content.length > 100 ? '...' : '');\n \n table.push([\n time,\n result.metadata.type || 'unknown',\n result.metadata.project_name || 'default',\n content,\n ]);\n }\n\n console.log(table.toString());\n console.log(chalk.green(`\\n\u2705 Found ${results.length} recent contexts`));\n } catch (error: unknown) {\n spinner.fail('Failed to get recent contexts');\n logger.error('Recent error', error);\n console.error(chalk.red(error instanceof Error ? error.message : 'Unknown error'));\n }\n });\n\n // Get statistics\n chromadb\n .command('stats')\n .description('Get ChromaDB storage statistics')\n .action(async () => {\n const spinner = ora('Fetching statistics...').start();\n\n try {\n const config = {\n apiKey: process.env['CHROMADB_API_KEY'] || '',\n tenant: process.env['CHROMADB_TENANT'] || '',\n database: process.env['CHROMADB_DATABASE'] || 'stackmemory',\n };\n\n const userId = process.env['USER'] || 'default';\n const teamId = process.env['CHROMADB_TEAM_ID'];\n\n const adapter = new ChromaDBAdapter(config, userId, teamId);\n await adapter.initialize();\n\n const stats = await adapter.getStats();\n\n spinner.stop();\n\n console.log(chalk.cyan('\\n\uD83D\uDCCA ChromaDB Statistics\\n'));\n console.log(`Total Documents: ${chalk.bold(stats.totalDocuments)}`);\n console.log(`User Documents: ${chalk.bold(stats.userDocuments)}`);\n \n if (stats.teamDocuments !== undefined) {\n console.log(`Team Documents: ${chalk.bold(stats.teamDocuments)}`);\n }\n\n console.log('\\nDocuments by Type:');\n for (const [type, count] of Object.entries(stats.documentsByType)) {\n console.log(` ${type}: ${count}`);\n }\n } catch (error: unknown) {\n spinner.fail('Failed to get statistics');\n logger.error('Stats error', error);\n console.error(chalk.red(error instanceof Error ? error.message : 'Unknown error'));\n }\n });\n\n // Clean old contexts\n chromadb\n .command('clean')\n .description('Clean old contexts')\n .option('--days <n>', 'Delete contexts older than N days', '30')\n .action(async (options) => {\n const spinner = ora('Cleaning old contexts...').start();\n\n try {\n const config = {\n apiKey: process.env['CHROMADB_API_KEY'] || '',\n tenant: process.env['CHROMADB_TENANT'] || '',\n database: process.env['CHROMADB_DATABASE'] || 'stackmemory',\n };\n\n const userId = process.env['USER'] || 'default';\n const teamId = process.env['CHROMADB_TEAM_ID'];\n\n const adapter = new ChromaDBAdapter(config, userId, teamId);\n await adapter.initialize();\n\n const deleted = await adapter.deleteOldContexts(parseInt(options.days));\n\n spinner.succeed(`Deleted ${deleted} old contexts`);\n } catch (error: unknown) {\n spinner.fail('Failed to clean contexts');\n logger.error('Clean error', error);\n console.error(chalk.red(error instanceof Error ? error.message : 'Unknown error'));\n }\n });\n\n // Ingest repository\n chromadb\n .command('ingest <name>')\n .description('Ingest a repository into ChromaDB for code search')\n .option('--path <path>', 'Repository path (default: current directory)')\n .option('--incremental', 'Only process changed files')\n .option('--include-tests', 'Include test files')\n .option('--include-docs', 'Include documentation files')\n .option('--force-update', 'Force re-indexing of all files')\n .option('--max-file-size <bytes>', 'Maximum file size to process')\n .option('--chunk-size <lines>', 'Lines per chunk')\n .action(async (name, options) => {\n const spinner = ora('Ingesting repository...').start();\n\n try {\n const config = {\n apiKey: process.env['CHROMADB_API_KEY'] || '',\n tenant: process.env['CHROMADB_TENANT'] || '',\n database: process.env['CHROMADB_DATABASE'] || 'stackmemory',\n collectionName: 'stackmemory_repos',\n };\n\n if (!config.apiKey || !config.tenant) {\n spinner.fail('ChromaDB not configured');\n console.log(chalk.yellow('\\nPlease run: stackmemory chromadb init'));\n return;\n }\n\n const userId = process.env['USER'] || 'default';\n const teamId = process.env['CHROMADB_TEAM_ID'];\n\n const skill = new RepoIngestionSkill(config, userId, teamId);\n await skill.initialize();\n\n const repoPath = options.path || process.cwd();\n const result = await skill.ingestRepository(repoPath, name, {\n incremental: options.incremental,\n forceUpdate: options.forceUpdate,\n includeTests: options.includeTests,\n includeDocs: options.includeDocs,\n maxFileSize: options.maxFileSize ? parseInt(options.maxFileSize) : undefined,\n chunkSize: options.chunkSize ? parseInt(options.chunkSize) : undefined,\n });\n\n if (result.success) {\n spinner.succeed(result.message);\n if (result.stats) {\n console.log(chalk.green('\\n\uD83D\uDCCA Ingestion Statistics:'));\n console.log(` Files processed: ${result.stats.filesProcessed}`);\n console.log(` Chunks created: ${result.stats.chunksCreated}`);\n console.log(` Total size: ${(result.stats.totalSize / 1024 / 1024).toFixed(2)} MB`);\n console.log(` Time elapsed: ${(result.stats.timeElapsed / 1000).toFixed(2)} seconds`);\n }\n } else {\n spinner.fail(result.message);\n }\n } catch (error: unknown) {\n spinner.fail('Failed to ingest repository');\n logger.error('Ingestion error', error);\n console.error(chalk.red(error instanceof Error ? error.message : 'Unknown error'));\n }\n });\n\n // Update repository\n chromadb\n .command('update <name>')\n .description('Update an existing repository in ChromaDB')\n .option('--path <path>', 'Repository path (default: current directory)')\n .option('--force-update', 'Force re-indexing of all files')\n .action(async (name, options) => {\n const spinner = ora('Updating repository...').start();\n\n try {\n const config = {\n apiKey: process.env['CHROMADB_API_KEY'] || '',\n tenant: process.env['CHROMADB_TENANT'] || '',\n database: process.env['CHROMADB_DATABASE'] || 'stackmemory',\n collectionName: 'stackmemory_repos',\n };\n\n if (!config.apiKey || !config.tenant) {\n spinner.fail('ChromaDB not configured');\n console.log(chalk.yellow('\\nPlease run: stackmemory chromadb init'));\n return;\n }\n\n const userId = process.env['USER'] || 'default';\n const teamId = process.env['CHROMADB_TEAM_ID'];\n\n const skill = new RepoIngestionSkill(config, userId, teamId);\n await skill.initialize();\n\n const repoPath = options.path || process.cwd();\n const result = await skill.updateRepository(repoPath, name, {\n forceUpdate: options.forceUpdate,\n });\n\n if (result.success) {\n spinner.succeed(result.message);\n if (result.stats) {\n console.log(chalk.green('\\n\uD83D\uDCCA Update Statistics:'));\n console.log(` Files updated: ${result.stats.filesUpdated}`);\n console.log(` Files added: ${result.stats.filesAdded}`);\n console.log(` Files removed: ${result.stats.filesRemoved}`);\n console.log(` Time elapsed: ${(result.stats.timeElapsed / 1000).toFixed(2)} seconds`);\n }\n } else {\n spinner.fail(result.message);\n }\n } catch (error: unknown) {\n spinner.fail('Failed to update repository');\n logger.error('Update error', error);\n console.error(chalk.red(error instanceof Error ? error.message : 'Unknown error'));\n }\n });\n\n // Search code\n chromadb\n .command('search-code <query>')\n .description('Search code in ingested repositories')\n .option('--repo <name>', 'Filter by repository name')\n .option('--language <lang>', 'Filter by programming language')\n .option('--limit <n>', 'Maximum results', '20')\n .action(async (query, options) => {\n const spinner = ora('Searching code...').start();\n\n try {\n const config = {\n apiKey: process.env['CHROMADB_API_KEY'] || '',\n tenant: process.env['CHROMADB_TENANT'] || '',\n database: process.env['CHROMADB_DATABASE'] || 'stackmemory',\n collectionName: 'stackmemory_repos',\n };\n\n if (!config.apiKey || !config.tenant) {\n spinner.fail('ChromaDB not configured');\n console.log(chalk.yellow('\\nPlease run: stackmemory chromadb init'));\n return;\n }\n\n const userId = process.env['USER'] || 'default';\n const teamId = process.env['CHROMADB_TEAM_ID'];\n\n const skill = new RepoIngestionSkill(config, userId, teamId);\n await skill.initialize();\n\n const results = await skill.searchCode(query, {\n repoName: options.repo,\n language: options.language,\n limit: parseInt(options.limit),\n });\n\n spinner.stop();\n\n if (results.length === 0) {\n console.log(chalk.yellow('No results found'));\n return;\n }\n\n console.log(chalk.cyan(`\\n\uD83D\uDD0D Found ${results.length} code matches:\\n`));\n\n for (const result of results) {\n console.log(chalk.green(`\uD83D\uDCC1 ${result.repoName}/${result.filePath}`));\n console.log(chalk.gray(` Lines ${result.startLine}-${result.endLine} | Score: ${result.score.toFixed(3)}`));\n \n // Show snippet\n const lines = result.content.split('\\n').slice(0, 3);\n lines.forEach(line => {\n console.log(chalk.dim(` ${line.slice(0, 80)}${line.length > 80 ? '...' : ''}`));\n });\n console.log();\n }\n } catch (error: unknown) {\n spinner.fail('Failed to search code');\n logger.error('Search error', error);\n console.error(chalk.red(error instanceof Error ? error.message : 'Unknown error'));\n }\n });\n\n // Repository stats\n chromadb\n .command('repo-stats [name]')\n .description('Get statistics for ingested repositories')\n .action(async (name) => {\n const spinner = ora('Fetching repository statistics...').start();\n\n try {\n const config = {\n apiKey: process.env['CHROMADB_API_KEY'] || '',\n tenant: process.env['CHROMADB_TENANT'] || '',\n database: process.env['CHROMADB_DATABASE'] || 'stackmemory',\n collectionName: 'stackmemory_repos',\n };\n\n if (!config.apiKey || !config.tenant) {\n spinner.fail('ChromaDB not configured');\n console.log(chalk.yellow('\\nPlease run: stackmemory chromadb init'));\n return;\n }\n\n const userId = process.env['USER'] || 'default';\n const teamId = process.env['CHROMADB_TEAM_ID'];\n\n const skill = new RepoIngestionSkill(config, userId, teamId);\n await skill.initialize();\n\n const stats = await skill.getRepoStats(name);\n\n spinner.stop();\n\n console.log(chalk.cyan('\\n\uD83D\uDCCA Repository Statistics\\n'));\n console.log(`Total repositories: ${chalk.bold(stats.totalRepos)}`);\n console.log(`Total files: ${chalk.bold(stats.totalFiles)}`);\n console.log(`Total chunks: ${chalk.bold(stats.totalChunks)}`);\n \n if (Object.keys(stats.languages).length > 0) {\n console.log('\\nLanguages:');\n for (const [lang, count] of Object.entries(stats.languages)) {\n console.log(` ${lang}: ${count}`);\n }\n }\n \n if (Object.keys(stats.frameworks).length > 0) {\n console.log('\\nFrameworks:');\n for (const [framework, count] of Object.entries(stats.frameworks)) {\n console.log(` ${framework}: ${count}`);\n }\n }\n } catch (error: unknown) {\n spinner.fail('Failed to get repository statistics');\n logger.error('Stats error', error);\n console.error(chalk.red(error instanceof Error ? error.message : 'Unknown error'));\n }\n });\n\n return chromadb;\n}"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -9,6 +9,17 @@ import { existsSync } from "fs";
|
|
|
9
9
|
import { ClearSurvival } from "../../core/session/clear-survival-stub.js";
|
|
10
10
|
import { FrameManager } from "../../core/context/frame-manager.js";
|
|
11
11
|
import { sessionManager } from "../../core/session/session-manager.js";
|
|
12
|
+
function getEnv(key, defaultValue) {
|
|
13
|
+
const value = process.env[key];
|
|
14
|
+
if (value === void 0) {
|
|
15
|
+
if (defaultValue !== void 0) return defaultValue;
|
|
16
|
+
throw new Error(`Environment variable ${key} is required`);
|
|
17
|
+
}
|
|
18
|
+
return value;
|
|
19
|
+
}
|
|
20
|
+
function getOptionalEnv(key) {
|
|
21
|
+
return process.env[key];
|
|
22
|
+
}
|
|
12
23
|
const clearCommand = new Command("clear").description("Manage context clearing with ledger preservation").option("--save", "Save continuity ledger before clearing").option("--restore", "Restore from continuity ledger").option("--check", "Check if clear is recommended").option("--auto", "Automatically save if needed and clear").option("--status", "Show current context usage").option("--show-ledger", "Display current ledger").action(async (options) => {
|
|
13
24
|
const spinner = ora();
|
|
14
25
|
try {
|
|
@@ -59,7 +70,7 @@ const clearCommand = new Command("clear").description("Manage context clearing w
|
|
|
59
70
|
}
|
|
60
71
|
} catch (error) {
|
|
61
72
|
console.error(chalk.red("Error: " + error.message));
|
|
62
|
-
if (process.env
|
|
73
|
+
if (process.env["NODE_ENV"] !== "test") {
|
|
63
74
|
process.exit(1);
|
|
64
75
|
}
|
|
65
76
|
}
|