@stackmemoryai/stackmemory 0.3.6 → 0.3.8
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/core/agent-task-manager.js +5 -5
- package/dist/agents/core/agent-task-manager.js.map +2 -2
- package/dist/agents/verifiers/base-verifier.js +2 -2
- 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 +13 -13
- package/dist/cli/claude-sm.js.map +2 -2
- package/dist/cli/codex-sm.js +13 -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 +261 -46
- package/dist/cli/commands/chromadb.js.map +2 -2
- package/dist/cli/commands/clear.js +10 -3
- package/dist/cli/commands/clear.js.map +2 -2
- package/dist/cli/commands/config.js +43 -33
- package/dist/cli/commands/config.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 +41 -13
- package/dist/cli/commands/dashboard.js.map +2 -2
- package/dist/cli/commands/gc.js +251 -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 +92 -40
- package/dist/cli/commands/infinite-storage.js.map +2 -2
- package/dist/cli/commands/linear-create.js +49 -10
- package/dist/cli/commands/linear-create.js.map +2 -2
- package/dist/cli/commands/linear-list.js +45 -11
- package/dist/cli/commands/linear-list.js.map +2 -2
- package/dist/cli/commands/linear-migrate.js +29 -5
- package/dist/cli/commands/linear-migrate.js.map +2 -2
- package/dist/cli/commands/linear-test.js +26 -7
- package/dist/cli/commands/linear-test.js.map +2 -2
- package/dist/cli/commands/linear-unified.js +350 -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 +35 -8
- package/dist/cli/commands/onboard.js.map +2 -2
- package/dist/cli/commands/quality.js +2 -7
- package/dist/cli/commands/quality.js.map +2 -2
- package/dist/cli/commands/search.js.map +2 -2
- package/dist/cli/commands/session.js +23 -6
- package/dist/cli/commands/session.js.map +2 -2
- package/dist/cli/commands/skills.js +84 -28
- package/dist/cli/commands/skills.js.map +2 -2
- package/dist/cli/commands/storage.js +119 -38
- 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 +71 -21
- package/dist/cli/commands/webhook.js.map +2 -2
- package/dist/cli/commands/workflow.js +11 -7
- package/dist/cli/commands/workflow.js.map +2 -2
- package/dist/cli/commands/worktree.js +34 -13
- package/dist/cli/commands/worktree.js.map +2 -2
- package/dist/cli/index.js +7 -5
- package/dist/cli/index.js.map +2 -2
- package/dist/core/config/config-manager.js.map +2 -2
- package/dist/core/config/types.js.map +1 -1
- package/dist/core/context/auto-context.js +10 -6
- 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 +13 -3
- package/dist/core/context/frame-database.js.map +2 -2
- package/dist/core/context/frame-digest.js +7 -5
- 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 +16 -5
- package/dist/core/context/frame-stack.js.map +2 -2
- package/dist/core/context/incremental-gc.js +286 -0
- package/dist/core/context/incremental-gc.js.map +7 -0
- package/dist/core/context/index.js.map +1 -1
- 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 +12 -3
- package/dist/core/context/refactored-frame-manager.js.map +2 -2
- package/dist/core/context/shared-context-layer.js +16 -3
- 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 +112 -86
- 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 +19 -9
- 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 +1 -1
- package/dist/core/database/sqlite-adapter.js.map +2 -2
- package/dist/core/digest/enhanced-hybrid-digest.js +8 -2
- package/dist/core/digest/enhanced-hybrid-digest.js.map +2 -2
- package/dist/core/errors/recovery.js +9 -2
- package/dist/core/errors/recovery.js.map +2 -2
- package/dist/core/frame/workflow-templates-stub.js.map +1 -1
- package/dist/core/frame/workflow-templates.js +40 -1
- package/dist/core/frame/workflow-templates.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 +19 -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 +24 -20
- 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 +27 -12
- package/dist/core/performance/optimized-frame-context.js.map +2 -2
- package/dist/core/performance/performance-benchmark.js +10 -6
- package/dist/core/performance/performance-benchmark.js.map +2 -2
- package/dist/core/performance/performance-profiler.js +63 -15
- package/dist/core/performance/performance-profiler.js.map +2 -2
- package/dist/core/performance/streaming-jsonl-parser.js +5 -1
- 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 +14 -20
- 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-stub.js +5 -1
- package/dist/core/session/clear-survival-stub.js.map +2 -2
- package/dist/core/session/clear-survival.js +35 -0
- package/dist/core/session/clear-survival.js.map +2 -2
- package/dist/core/session/handoff-generator.js.map +2 -2
- package/dist/core/session/index.js.map +1 -1
- 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 +6 -2
- package/dist/core/storage/chromadb-adapter.js.map +2 -2
- package/dist/core/storage/chromadb-simple.js +17 -5
- package/dist/core/storage/chromadb-simple.js.map +2 -2
- package/dist/core/storage/infinite-storage.js +109 -46
- package/dist/core/storage/infinite-storage.js.map +2 -2
- package/dist/core/storage/railway-optimized-storage.js +67 -30
- package/dist/core/storage/railway-optimized-storage.js.map +2 -2
- package/dist/core/storage/remote-storage.js +53 -24
- package/dist/core/storage/remote-storage.js.map +2 -2
- package/dist/core/trace/cli-trace-wrapper.js +25 -7
- package/dist/core/trace/cli-trace-wrapper.js.map +2 -2
- package/dist/core/trace/db-trace-wrapper.js +96 -68
- package/dist/core/trace/db-trace-wrapper.js.map +2 -2
- package/dist/core/trace/debug-trace.js +44 -16
- package/dist/core/trace/debug-trace.js.map +2 -2
- package/dist/core/trace/index.js +50 -35
- package/dist/core/trace/index.js.map +2 -2
- package/dist/core/trace/linear-api-wrapper.js +10 -5
- package/dist/core/trace/linear-api-wrapper.js.map +2 -2
- package/dist/core/trace/trace-demo.js +26 -11
- package/dist/core/trace/trace-demo.js.map +2 -2
- package/dist/core/trace/trace-detector.js +9 -2
- package/dist/core/trace/trace-detector.js.map +2 -2
- package/dist/core/trace/trace-store.js.map +2 -2
- package/dist/core/trace/types.js.map +1 -1
- package/dist/core/utils/compression.js.map +1 -1
- package/dist/core/utils/update-checker.js.map +2 -2
- package/dist/core/worktree/worktree-manager.js +18 -7
- 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 +1 -1
- 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 +36 -15
- package/dist/features/tui/components/analytics-panel.js.map +2 -2
- package/dist/features/tui/components/pr-tracker.js +19 -7
- package/dist/features/tui/components/pr-tracker.js.map +2 -2
- package/dist/features/tui/components/session-monitor.js +22 -9
- package/dist/features/tui/components/session-monitor.js.map +2 -2
- package/dist/features/tui/components/subagent-fleet.js +20 -13
- package/dist/features/tui/components/subagent-fleet.js.map +2 -2
- package/dist/features/tui/components/task-board.js +666 -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 +30 -15
- package/dist/features/tui/services/data-service.js.map +2 -2
- package/dist/features/tui/services/linear-task-reader.js +3 -1
- package/dist/features/tui/services/linear-task-reader.js.map +2 -2
- package/dist/features/tui/services/websocket-client.js +16 -3
- package/dist/features/tui/services/websocket-client.js.map +2 -2
- package/dist/features/tui/terminal-compat.js +33 -18
- 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 +31 -12
- 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 +24 -14
- package/dist/integrations/linear/sync-service.js.map +2 -2
- package/dist/integrations/linear/sync.js +196 -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 +29 -19
- 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 +1 -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 +6 -7
- package/dist/services/config-service.js.map +2 -2
- package/dist/services/context-service.js +11 -12
- package/dist/services/context-service.js.map +2 -2
- package/dist/skills/claude-skills.js +108 -3
- 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/env.js +46 -0
- package/dist/utils/env.js.map +7 -0
- package/dist/utils/logger.js +1 -1
- package/dist/utils/logger.js.map +2 -2
- package/package.json +5 -1
|
@@ -91,7 +91,7 @@ class AgentTaskManager {
|
|
|
91
91
|
action,
|
|
92
92
|
result: feedback,
|
|
93
93
|
verificationPassed: success,
|
|
94
|
-
contextAdjustment: this.suggestContextAdjustment(verificationResults)
|
|
94
|
+
contextAdjustment: this.suggestContextAdjustment(verificationResults) || void 0
|
|
95
95
|
});
|
|
96
96
|
const shouldContinue = success && session.turnCount < session.maxTurns;
|
|
97
97
|
if (!shouldContinue && success) {
|
|
@@ -129,16 +129,16 @@ class AgentTaskManager {
|
|
|
129
129
|
*/
|
|
130
130
|
getApplicableVerifiers(context) {
|
|
131
131
|
const verifiers = [];
|
|
132
|
-
if (context
|
|
132
|
+
if (context["codeChange"]) {
|
|
133
133
|
verifiers.push("formatter", "linter", "type-checker");
|
|
134
134
|
}
|
|
135
|
-
if (context
|
|
135
|
+
if (context["testsPresent"]) {
|
|
136
136
|
verifiers.push("test-runner");
|
|
137
137
|
}
|
|
138
|
-
if (context
|
|
138
|
+
if (context["hasDocumentation"]) {
|
|
139
139
|
verifiers.push("doc-validator");
|
|
140
140
|
}
|
|
141
|
-
if (context
|
|
141
|
+
if (context["performanceCritical"]) {
|
|
142
142
|
verifiers.push("performance-analyzer");
|
|
143
143
|
}
|
|
144
144
|
verifiers.push("semantic-validator");
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/agents/core/agent-task-manager.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Agent Task Manager - Spotify-inspired task handling for StackMemory\n *\n * Integrates Spotify's background coding agent strategies:\n * - 10-turn session limits with automatic task breakdown\n * - Strong verification loops with incremental feedback\n * - Context-aware task prioritization\n * - LLM judge for semantic validation\n */\n\nimport {\n PebblesTaskStore,\n PebblesTask,\n TaskStatus,\n TaskPriority,\n} from '../../features/tasks/pebbles-task-store.js';\nimport { logger } from '../../core/monitoring/logger.js';\nimport { FrameManager } from '../../core/context/frame-manager.js';\nimport { TaskError, ErrorCode } from '../../core/errors/index.js';\n\nexport interface AgentTaskSession {\n id: string;\n frameId: string;\n taskId: string;\n turnCount: number;\n maxTurns: number;\n status: 'active' | 'completed' | 'failed' | 'timeout';\n startedAt: Date;\n completedAt?: Date;\n verificationResults: VerificationResult[];\n contextWindow: string[];\n feedbackLoop: FeedbackEntry[];\n}\n\nexport interface VerificationResult {\n verifierId: string;\n passed: boolean;\n message: string;\n severity: 'error' | 'warning' | 'info';\n timestamp: Date;\n autoFix?: string;\n}\n\nexport interface FeedbackEntry {\n turn: number;\n action: string;\n result: string;\n verificationPassed: boolean;\n contextAdjustment?: string;\n}\n\nexport interface TaskBreakdown {\n parentTaskId: string;\n subtasks: SubtaskDefinition[];\n dependencies: Map<string, string[]>;\n estimatedTurns: number;\n}\n\nexport interface SubtaskDefinition {\n title: string;\n description: string;\n acceptanceCriteria: string[];\n estimatedTurns: number;\n verifiers: string[];\n}\n\n/**\n * Spotify-inspired Agent Task Manager\n */\nexport class AgentTaskManager {\n private taskStore: PebblesTaskStore;\n private frameManager: FrameManager;\n private activeSessions: Map<string, AgentTaskSession> = new Map();\n private sessionTimeouts: Map<string, NodeJS.Timeout> = new Map();\n\n // Spotify strategy constants\n private readonly MAX_TURNS_PER_SESSION = 10;\n private readonly MAX_SESSION_RETRIES = 3;\n private readonly SESSION_TIMEOUT_MS = 30 * 60 * 1000; // 30 minutes\n private readonly CONTEXT_WINDOW_SIZE = 5; // Last 5 significant events\n\n constructor(taskStore: PebblesTaskStore, frameManager: FrameManager) {\n this.taskStore = taskStore;\n this.frameManager = frameManager;\n }\n\n /**\n * Start a new agent task session with Spotify's 10-turn limit\n */\n async startTaskSession(\n taskId: string,\n frameId: string\n ): Promise<AgentTaskSession> {\n const task = this.taskStore.getTask(taskId);\n if (!task) {\n throw new TaskError(\n `Task ${taskId} not found`,\n ErrorCode.TASK_NOT_FOUND,\n { taskId }\n );\n }\n\n // Check if task needs breakdown (Spotify strategy)\n if (this.needsBreakdown(task)) {\n const breakdown = await this.breakdownTask(task);\n return this.startMultiTaskSession(breakdown, frameId);\n }\n\n const sessionId = this.generateSessionId(taskId);\n const session: AgentTaskSession = {\n id: sessionId,\n frameId,\n taskId,\n turnCount: 0,\n maxTurns: this.MAX_TURNS_PER_SESSION,\n status: 'active',\n startedAt: new Date(),\n verificationResults: [],\n contextWindow: [],\n feedbackLoop: [],\n };\n\n this.activeSessions.set(sessionId, session);\n this.startSessionTimeout(sessionId);\n\n // Update task status\n this.taskStore.updateTaskStatus(\n taskId,\n 'in_progress',\n 'Agent session started'\n );\n\n logger.info('Started agent task session', {\n sessionId,\n taskId,\n taskTitle: task.title,\n maxTurns: this.MAX_TURNS_PER_SESSION,\n });\n\n return session;\n }\n\n /**\n * Execute a turn in the session with verification\n */\n async executeTurn(\n sessionId: string,\n action: string,\n context: Record<string, any>\n ): Promise<{\n success: boolean;\n feedback: string;\n shouldContinue: boolean;\n verificationResults: VerificationResult[];\n }> {\n const session = this.activeSessions.get(sessionId);\n if (!session || session.status !== 'active') {\n throw new TaskError(\n 'Invalid or inactive session',\n ErrorCode.TASK_INVALID_STATE,\n { sessionId }\n );\n }\n\n session.turnCount++;\n\n // Check turn limit (Spotify strategy)\n if (session.turnCount >= session.maxTurns) {\n return this.handleTurnLimitReached(session);\n }\n\n // Execute action with verification loop\n const verificationResults = await this.runVerificationLoop(\n action,\n context,\n session\n );\n\n // Update context window (keep last N significant events)\n this.updateContextWindow(session, action, verificationResults);\n\n // Generate feedback based on verification\n const feedback = this.generateFeedback(verificationResults);\n const success = verificationResults.every(\n (r) => r.passed || r.severity !== 'error'\n );\n\n // Record in feedback loop\n session.feedbackLoop.push({\n turn: session.turnCount,\n action,\n result: feedback,\n verificationPassed: success,\n contextAdjustment: this.suggestContextAdjustment(verificationResults),\n });\n\n // Determine if should continue\n const shouldContinue = success && session.turnCount < session.maxTurns;\n\n if (!shouldContinue && success) {\n await this.completeSession(session);\n }\n\n return {\n success,\n feedback,\n shouldContinue,\n verificationResults,\n };\n }\n\n /**\n * Run Spotify-style verification loop\n */\n private async runVerificationLoop(\n action: string,\n context: Record<string, any>,\n session: AgentTaskSession\n ): Promise<VerificationResult[]> {\n const results: VerificationResult[] = [];\n\n // Get applicable verifiers based on context\n const verifiers = this.getApplicableVerifiers(context);\n\n for (const verifier of verifiers) {\n const result = await this.runVerifier(verifier, action, context);\n results.push(result);\n session.verificationResults.push(result);\n\n // Stop on critical errors (Spotify strategy)\n if (!result.passed && result.severity === 'error') {\n logger.warn('Verification failed, stopping execution', {\n verifier: result.verifierId,\n message: result.message,\n });\n break;\n }\n }\n\n return results;\n }\n\n /**\n * Get verifiers applicable to current context\n */\n private getApplicableVerifiers(context: Record<string, any>): string[] {\n const verifiers: string[] = [];\n\n // Add verifiers based on context (Spotify's context-aware approach)\n if (context.codeChange) {\n verifiers.push('formatter', 'linter', 'type-checker');\n }\n if (context.testsPresent) {\n verifiers.push('test-runner');\n }\n if (context.hasDocumentation) {\n verifiers.push('doc-validator');\n }\n if (context.performanceCritical) {\n verifiers.push('performance-analyzer');\n }\n\n // Always include semantic validator (LLM judge from Spotify)\n verifiers.push('semantic-validator');\n\n return verifiers;\n }\n\n /**\n * Run a single verifier\n */\n private async runVerifier(\n verifierId: string,\n action: string,\n context: Record<string, any>\n ): Promise<VerificationResult> {\n // This would integrate with actual verifiers\n // For now, return mock result\n const mockResults: Record<string, () => VerificationResult> = {\n formatter: () => ({\n verifierId: 'formatter',\n passed: Math.random() > 0.1,\n message: 'Code formatting check',\n severity: 'warning',\n timestamp: new Date(),\n autoFix: 'prettier --write',\n }),\n linter: () => ({\n verifierId: 'linter',\n passed: Math.random() > 0.2,\n message: 'Linting check',\n severity: 'error',\n timestamp: new Date(),\n }),\n 'test-runner': () => ({\n verifierId: 'test-runner',\n passed: Math.random() > 0.3,\n message: 'Test execution',\n severity: 'error',\n timestamp: new Date(),\n }),\n 'semantic-validator': () => ({\n verifierId: 'semantic-validator',\n passed: Math.random() > 0.25, // ~75% pass rate like Spotify\n message: 'Semantic validation against original requirements',\n severity: 'error',\n timestamp: new Date(),\n }),\n };\n\n const verifierFn =\n mockResults[verifierId] ||\n (() => ({\n verifierId,\n passed: true,\n message: 'Unknown verifier',\n severity: 'info' as const,\n timestamp: new Date(),\n }));\n\n return verifierFn();\n }\n\n /**\n * Check if task needs breakdown (Spotify strategy for complex tasks)\n */\n private needsBreakdown(task: PebblesTask): boolean {\n // Heuristics for determining if task is too complex\n const indicators = {\n hasMultipleComponents:\n (task.description?.match(/\\band\\b/gi)?.length || 0) > 2,\n longDescription: (task.description?.length || 0) > 500,\n highComplexityTags: task.tags.some((tag) =>\n ['refactor', 'migration', 'architecture', 'redesign'].includes(\n tag.toLowerCase()\n )\n ),\n hasManydependencies: task.depends_on.length > 3,\n };\n\n const complexityScore = Object.values(indicators).filter(Boolean).length;\n return complexityScore >= 2;\n }\n\n /**\n * Break down complex task into subtasks\n */\n private async breakdownTask(task: PebblesTask): Promise<TaskBreakdown> {\n // This would use LLM to intelligently break down the task\n // For now, return a simple breakdown\n const subtasks: SubtaskDefinition[] = [\n {\n title: `Analyze requirements for ${task.title}`,\n description: 'Understand and document requirements',\n acceptanceCriteria: [\n 'Requirements documented',\n 'Constraints identified',\n ],\n estimatedTurns: 2,\n verifiers: ['semantic-validator'],\n },\n {\n title: `Implement core functionality for ${task.title}`,\n description: 'Build the main implementation',\n acceptanceCriteria: ['Core logic implemented', 'Tests passing'],\n estimatedTurns: 5,\n verifiers: ['linter', 'test-runner'],\n },\n {\n title: `Verify and refine ${task.title}`,\n description: 'Final verification and improvements',\n acceptanceCriteria: ['All tests passing', 'Documentation complete'],\n estimatedTurns: 3,\n verifiers: ['formatter', 'linter', 'test-runner', 'semantic-validator'],\n },\n ];\n\n return {\n parentTaskId: task.id,\n subtasks,\n dependencies: new Map([\n [subtasks[1].title, [subtasks[0].title]],\n [subtasks[2].title, [subtasks[1].title]],\n ]),\n estimatedTurns: subtasks.reduce((sum, st) => sum + st.estimatedTurns, 0),\n };\n }\n\n /**\n * Start multi-task session for complex tasks\n */\n private async startMultiTaskSession(\n breakdown: TaskBreakdown,\n frameId: string\n ): Promise<AgentTaskSession> {\n // Create subtasks in task store\n const subtaskIds: string[] = [];\n\n for (const subtask of breakdown.subtasks) {\n const subtaskId = this.taskStore.createTask({\n title: subtask.title,\n description: subtask.description,\n frameId,\n parentId: breakdown.parentTaskId,\n tags: ['agent-subtask', ...subtask.verifiers],\n estimatedEffort: subtask.estimatedTurns * 5, // Rough conversion to minutes\n });\n subtaskIds.push(subtaskId);\n }\n\n // Add dependencies\n const titleToId = new Map(\n breakdown.subtasks.map((st, i) => [st.title, subtaskIds[i]])\n );\n\n for (const [title, deps] of breakdown.dependencies) {\n const taskId = titleToId.get(title);\n if (taskId) {\n for (const dep of deps) {\n const depId = titleToId.get(dep);\n if (depId) {\n this.taskStore.addDependency(taskId, depId);\n }\n }\n }\n }\n\n // Start session for first subtask\n return this.startTaskSession(subtaskIds[0], frameId);\n }\n\n /**\n * Update context window with significant events\n */\n private updateContextWindow(\n session: AgentTaskSession,\n action: string,\n verificationResults: VerificationResult[]\n ): void {\n const significantEvent = {\n turn: session.turnCount,\n action: action.substring(0, 100),\n verificationSummary: verificationResults.map((r) => ({\n verifier: r.verifierId,\n passed: r.passed,\n })),\n timestamp: new Date().toISOString(),\n };\n\n session.contextWindow.push(JSON.stringify(significantEvent));\n\n // Keep only last N events (Spotify's context window optimization)\n if (session.contextWindow.length > this.CONTEXT_WINDOW_SIZE) {\n session.contextWindow = session.contextWindow.slice(\n -this.CONTEXT_WINDOW_SIZE\n );\n }\n }\n\n /**\n * Generate feedback from verification results\n */\n private generateFeedback(results: VerificationResult[]): string {\n const failed = results.filter((r) => !r.passed);\n const warnings = results.filter(\n (r) => !r.passed && r.severity === 'warning'\n );\n const errors = results.filter((r) => !r.passed && r.severity === 'error');\n\n if (errors.length > 0) {\n const errorMessages = errors.map((e) => `- ${e.message}`).join('\\n');\n return `Verification failed with ${errors.length} error(s):\\n${errorMessages}`;\n }\n\n if (warnings.length > 0) {\n const warningMessages = warnings.map((w) => `- ${w.message}`).join('\\n');\n return `Verification passed with ${warnings.length} warning(s):\\n${warningMessages}`;\n }\n\n return 'All verifications passed successfully';\n }\n\n /**\n * Suggest context adjustment based on verification results\n */\n private suggestContextAdjustment(\n results: VerificationResult[]\n ): string | undefined {\n const failed = results.filter((r) => !r.passed && r.severity === 'error');\n\n if (failed.length === 0) {\n return undefined;\n }\n\n // Generate suggestions based on failure patterns\n const suggestions: string[] = [];\n\n if (failed.some((r) => r.verifierId === 'test-runner')) {\n suggestions.push('Focus on fixing failing tests');\n }\n if (failed.some((r) => r.verifierId === 'linter')) {\n suggestions.push('Address linting errors before proceeding');\n }\n if (failed.some((r) => r.verifierId === 'semantic-validator')) {\n suggestions.push('Review original requirements and adjust approach');\n }\n\n return suggestions.length > 0 ? suggestions.join('; ') : undefined;\n }\n\n /**\n * Handle turn limit reached\n */\n private async handleTurnLimitReached(session: AgentTaskSession): Promise<{\n success: boolean;\n feedback: string;\n shouldContinue: boolean;\n verificationResults: VerificationResult[];\n }> {\n logger.warn('Session reached turn limit', {\n sessionId: session.id,\n taskId: session.taskId,\n turnCount: session.turnCount,\n });\n\n // Check if task can be considered complete\n const task = this.taskStore.getTask(session.taskId);\n const isComplete = this.assessTaskCompletion(session);\n\n if (isComplete) {\n await this.completeSession(session);\n return {\n success: true,\n feedback: 'Task completed successfully within turn limit',\n shouldContinue: false,\n verificationResults: [],\n };\n }\n\n // Mark session as timeout\n session.status = 'timeout';\n this.taskStore.updateTaskStatus(\n session.taskId,\n 'blocked',\n 'Session timeout - manual review needed'\n );\n\n return {\n success: false,\n feedback: `Session reached ${this.MAX_TURNS_PER_SESSION} turn limit. Task requires manual review or retry.`,\n shouldContinue: false,\n verificationResults: [],\n };\n }\n\n /**\n * Assess if task is complete enough\n */\n private assessTaskCompletion(session: AgentTaskSession): boolean {\n // Check if recent verifications are passing\n const recentResults = session.verificationResults.slice(-5);\n const recentPassRate =\n recentResults.filter((r) => r.passed).length / recentResults.length;\n\n // Check if semantic validator passed recently (Spotify's LLM judge)\n const semanticPassed = recentResults.some(\n (r) => r.verifierId === 'semantic-validator' && r.passed\n );\n\n return recentPassRate >= 0.8 && semanticPassed;\n }\n\n /**\n * Complete a session\n */\n private async completeSession(session: AgentTaskSession): Promise<void> {\n session.status = 'completed';\n session.completedAt = new Date();\n\n // Update task status\n this.taskStore.updateTaskStatus(\n session.taskId,\n 'completed',\n 'Agent session completed'\n );\n\n // Clear timeout\n const timeout = this.sessionTimeouts.get(session.id);\n if (timeout) {\n clearTimeout(timeout);\n this.sessionTimeouts.delete(session.id);\n }\n\n // Generate and save session summary to frame\n const summary = this.generateSessionSummary(session);\n this.frameManager.addEvent('observation', {\n type: 'session_summary',\n frameId: session.frameId,\n summary,\n });\n\n logger.info('Session completed', {\n sessionId: session.id,\n taskId: session.taskId,\n turnCount: session.turnCount,\n duration: session.completedAt.getTime() - session.startedAt.getTime(),\n });\n }\n\n /**\n * Generate session summary for frame digest\n */\n private generateSessionSummary(\n session: AgentTaskSession\n ): Record<string, any> {\n const verificationStats = {\n total: session.verificationResults.length,\n passed: session.verificationResults.filter((r) => r.passed).length,\n failed: session.verificationResults.filter((r) => !r.passed).length,\n };\n\n return {\n sessionId: session.id,\n taskId: session.taskId,\n status: session.status,\n turnCount: session.turnCount,\n duration: session.completedAt\n ? session.completedAt.getTime() - session.startedAt.getTime()\n : 0,\n verificationStats,\n feedbackLoop: session.feedbackLoop.slice(-3), // Last 3 feedback entries\n contextWindow: session.contextWindow.slice(-2), // Last 2 context entries\n };\n }\n\n /**\n * Start timeout for session\n */\n private startSessionTimeout(sessionId: string): void {\n const timeout = setTimeout(() => {\n const session = this.activeSessions.get(sessionId);\n if (session && session.status === 'active') {\n session.status = 'timeout';\n this.taskStore.updateTaskStatus(\n session.taskId,\n 'blocked',\n 'Session timeout - no activity'\n );\n logger.warn('Session timed out due to inactivity', { sessionId });\n }\n }, this.SESSION_TIMEOUT_MS);\n\n this.sessionTimeouts.set(sessionId, timeout);\n }\n\n /**\n * Generate unique session ID\n */\n private generateSessionId(taskId: string): string {\n return `session-${taskId}-${Date.now()}`;\n }\n\n /**\n * Get active sessions summary\n */\n getActiveSessions(): Array<{\n sessionId: string;\n taskId: string;\n turnCount: number;\n status: string;\n startedAt: Date;\n }> {\n return Array.from(this.activeSessions.values()).map((session) => ({\n sessionId: session.id,\n taskId: session.taskId,\n turnCount: session.turnCount,\n status: session.status,\n startedAt: session.startedAt,\n }));\n }\n\n /**\n * Retry a failed session (Spotify's 3-retry strategy)\n */\n async retrySession(sessionId: string): Promise<AgentTaskSession | null> {\n const session = this.activeSessions.get(sessionId);\n if (!session || session.status === 'active') {\n return null;\n }\n\n // Count previous retries\n const retryCount = Array.from(this.activeSessions.values()).filter(\n (s) => s.taskId === session.taskId && s.status === 'failed'\n ).length;\n\n if (retryCount >= this.MAX_SESSION_RETRIES) {\n logger.warn('Max retries reached for task', {\n taskId: session.taskId,\n retries: retryCount,\n });\n return null;\n }\n\n // Start new session with learned context\n const newSession = await this.startTaskSession(\n session.taskId,\n session.frameId\n );\n\n // Transfer learned context from previous session\n newSession.contextWindow = session.contextWindow.slice(-3);\n newSession.feedbackLoop = [\n {\n turn: 0,\n action: 'Session retry with learned context',\n result: `Retrying after ${retryCount} previous attempts`,\n verificationPassed: true,\n contextAdjustment: session.feedbackLoop\n .filter((f) => f.contextAdjustment)\n .map((f) => f.contextAdjustment)\n .join('; '),\n },\n ];\n\n return newSession;\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["/**\n * Agent Task Manager - Spotify-inspired task handling for StackMemory\n *\n * Integrates Spotify's background coding agent strategies:\n * - 10-turn session limits with automatic task breakdown\n * - Strong verification loops with incremental feedback\n * - Context-aware task prioritization\n * - LLM judge for semantic validation\n */\n\nimport {\n PebblesTaskStore,\n PebblesTask,\n TaskStatus,\n TaskPriority,\n} from '../../features/tasks/pebbles-task-store.js';\nimport { logger } from '../../core/monitoring/logger.js';\nimport { FrameManager } from '../../core/context/frame-manager.js';\nimport { TaskError, ErrorCode } from '../../core/errors/index.js';\n\nexport interface AgentTaskSession {\n id: string;\n frameId: string;\n taskId: string;\n turnCount: number;\n maxTurns: number;\n status: 'active' | 'completed' | 'failed' | 'timeout';\n startedAt: Date;\n completedAt?: Date;\n verificationResults: VerificationResult[];\n contextWindow: string[];\n feedbackLoop: FeedbackEntry[];\n}\n\nexport interface VerificationResult {\n verifierId: string;\n passed: boolean;\n message: string;\n severity: 'error' | 'warning' | 'info';\n timestamp: Date;\n autoFix?: string;\n}\n\nexport interface FeedbackEntry {\n turn: number;\n action: string;\n result: string;\n verificationPassed: boolean;\n contextAdjustment?: string;\n}\n\nexport interface TaskBreakdown {\n parentTaskId: string;\n subtasks: SubtaskDefinition[];\n dependencies: Map<string, string[]>;\n estimatedTurns: number;\n}\n\nexport interface SubtaskDefinition {\n title: string;\n description: string;\n acceptanceCriteria: string[];\n estimatedTurns: number;\n verifiers: string[];\n}\n\n/**\n * Spotify-inspired Agent Task Manager\n */\nexport class AgentTaskManager {\n private taskStore: PebblesTaskStore;\n private frameManager: FrameManager;\n private activeSessions: Map<string, AgentTaskSession> = new Map();\n private sessionTimeouts: Map<string, NodeJS.Timeout> = new Map();\n\n // Spotify strategy constants\n private readonly MAX_TURNS_PER_SESSION = 10;\n private readonly MAX_SESSION_RETRIES = 3;\n private readonly SESSION_TIMEOUT_MS = 30 * 60 * 1000; // 30 minutes\n private readonly CONTEXT_WINDOW_SIZE = 5; // Last 5 significant events\n\n constructor(taskStore: PebblesTaskStore, frameManager: FrameManager) {\n this.taskStore = taskStore;\n this.frameManager = frameManager;\n }\n\n /**\n * Start a new agent task session with Spotify's 10-turn limit\n */\n async startTaskSession(\n taskId: string,\n frameId: string\n ): Promise<AgentTaskSession> {\n const task = this.taskStore.getTask(taskId);\n if (!task) {\n throw new TaskError(\n `Task ${taskId} not found`,\n ErrorCode.TASK_NOT_FOUND,\n { taskId }\n );\n }\n\n // Check if task needs breakdown (Spotify strategy)\n if (this.needsBreakdown(task)) {\n const breakdown = await this.breakdownTask(task);\n return this.startMultiTaskSession(breakdown, frameId);\n }\n\n const sessionId = this.generateSessionId(taskId);\n const session: AgentTaskSession = {\n id: sessionId,\n frameId,\n taskId,\n turnCount: 0,\n maxTurns: this.MAX_TURNS_PER_SESSION,\n status: 'active',\n startedAt: new Date(),\n verificationResults: [],\n contextWindow: [],\n feedbackLoop: [],\n };\n\n this.activeSessions.set(sessionId, session);\n this.startSessionTimeout(sessionId);\n\n // Update task status\n this.taskStore.updateTaskStatus(\n taskId,\n 'in_progress',\n 'Agent session started'\n );\n\n logger.info('Started agent task session', {\n sessionId,\n taskId,\n taskTitle: task.title,\n maxTurns: this.MAX_TURNS_PER_SESSION,\n });\n\n return session;\n }\n\n /**\n * Execute a turn in the session with verification\n */\n async executeTurn(\n sessionId: string,\n action: string,\n context: Record<string, any>\n ): Promise<{\n success: boolean;\n feedback: string;\n shouldContinue: boolean;\n verificationResults: VerificationResult[];\n }> {\n const session = this.activeSessions.get(sessionId);\n if (!session || session.status !== 'active') {\n throw new TaskError(\n 'Invalid or inactive session',\n ErrorCode.TASK_INVALID_STATE,\n { sessionId }\n );\n }\n\n session.turnCount++;\n\n // Check turn limit (Spotify strategy)\n if (session.turnCount >= session.maxTurns) {\n return this.handleTurnLimitReached(session);\n }\n\n // Execute action with verification loop\n const verificationResults = await this.runVerificationLoop(\n action,\n context,\n session\n );\n\n // Update context window (keep last N significant events)\n this.updateContextWindow(session, action, verificationResults);\n\n // Generate feedback based on verification\n const feedback = this.generateFeedback(verificationResults);\n const success = verificationResults.every(\n (r) => r.passed || r.severity !== 'error'\n );\n\n // Record in feedback loop\n session.feedbackLoop.push({\n turn: session.turnCount,\n action,\n result: feedback,\n verificationPassed: success,\n contextAdjustment:\n this.suggestContextAdjustment(verificationResults) || undefined,\n });\n\n // Determine if should continue\n const shouldContinue = success && session.turnCount < session.maxTurns;\n\n if (!shouldContinue && success) {\n await this.completeSession(session);\n }\n\n return {\n success,\n feedback,\n shouldContinue,\n verificationResults,\n };\n }\n\n /**\n * Run Spotify-style verification loop\n */\n private async runVerificationLoop(\n action: string,\n context: Record<string, any>,\n session: AgentTaskSession\n ): Promise<VerificationResult[]> {\n const results: VerificationResult[] = [];\n\n // Get applicable verifiers based on context\n const verifiers = this.getApplicableVerifiers(context);\n\n for (const verifier of verifiers) {\n const result = await this.runVerifier(verifier, action, context);\n results.push(result);\n session.verificationResults.push(result);\n\n // Stop on critical errors (Spotify strategy)\n if (!result.passed && result.severity === 'error') {\n logger.warn('Verification failed, stopping execution', {\n verifier: result.verifierId,\n message: result.message,\n });\n break;\n }\n }\n\n return results;\n }\n\n /**\n * Get verifiers applicable to current context\n */\n private getApplicableVerifiers(context: Record<string, any>): string[] {\n const verifiers: string[] = [];\n\n // Add verifiers based on context (Spotify's context-aware approach)\n if (context['codeChange']) {\n verifiers.push('formatter', 'linter', 'type-checker');\n }\n if (context['testsPresent']) {\n verifiers.push('test-runner');\n }\n if (context['hasDocumentation']) {\n verifiers.push('doc-validator');\n }\n if (context['performanceCritical']) {\n verifiers.push('performance-analyzer');\n }\n\n // Always include semantic validator (LLM judge from Spotify)\n verifiers.push('semantic-validator');\n\n return verifiers;\n }\n\n /**\n * Run a single verifier\n */\n private async runVerifier(\n verifierId: string,\n action: string,\n context: Record<string, any>\n ): Promise<VerificationResult> {\n // This would integrate with actual verifiers\n // For now, return mock result\n const mockResults: Record<string, () => VerificationResult> = {\n formatter: () => ({\n verifierId: 'formatter',\n passed: Math.random() > 0.1,\n message: 'Code formatting check',\n severity: 'warning',\n timestamp: new Date(),\n autoFix: 'prettier --write',\n }),\n linter: () => ({\n verifierId: 'linter',\n passed: Math.random() > 0.2,\n message: 'Linting check',\n severity: 'error',\n timestamp: new Date(),\n }),\n 'test-runner': () => ({\n verifierId: 'test-runner',\n passed: Math.random() > 0.3,\n message: 'Test execution',\n severity: 'error',\n timestamp: new Date(),\n }),\n 'semantic-validator': () => ({\n verifierId: 'semantic-validator',\n passed: Math.random() > 0.25, // ~75% pass rate like Spotify\n message: 'Semantic validation against original requirements',\n severity: 'error',\n timestamp: new Date(),\n }),\n };\n\n const verifierFn =\n mockResults[verifierId] ||\n (() => ({\n verifierId,\n passed: true,\n message: 'Unknown verifier',\n severity: 'info' as const,\n timestamp: new Date(),\n }));\n\n return verifierFn();\n }\n\n /**\n * Check if task needs breakdown (Spotify strategy for complex tasks)\n */\n private needsBreakdown(task: PebblesTask): boolean {\n // Heuristics for determining if task is too complex\n const indicators = {\n hasMultipleComponents:\n (task.description?.match(/\\band\\b/gi)?.length || 0) > 2,\n longDescription: (task.description?.length || 0) > 500,\n highComplexityTags: task.tags.some((tag) =>\n ['refactor', 'migration', 'architecture', 'redesign'].includes(\n tag.toLowerCase()\n )\n ),\n hasManydependencies: task.depends_on.length > 3,\n };\n\n const complexityScore = Object.values(indicators).filter(Boolean).length;\n return complexityScore >= 2;\n }\n\n /**\n * Break down complex task into subtasks\n */\n private async breakdownTask(task: PebblesTask): Promise<TaskBreakdown> {\n // This would use LLM to intelligently break down the task\n // For now, return a simple breakdown\n const subtasks: SubtaskDefinition[] = [\n {\n title: `Analyze requirements for ${task.title}`,\n description: 'Understand and document requirements',\n acceptanceCriteria: [\n 'Requirements documented',\n 'Constraints identified',\n ],\n estimatedTurns: 2,\n verifiers: ['semantic-validator'],\n },\n {\n title: `Implement core functionality for ${task.title}`,\n description: 'Build the main implementation',\n acceptanceCriteria: ['Core logic implemented', 'Tests passing'],\n estimatedTurns: 5,\n verifiers: ['linter', 'test-runner'],\n },\n {\n title: `Verify and refine ${task.title}`,\n description: 'Final verification and improvements',\n acceptanceCriteria: ['All tests passing', 'Documentation complete'],\n estimatedTurns: 3,\n verifiers: ['formatter', 'linter', 'test-runner', 'semantic-validator'],\n },\n ];\n\n return {\n parentTaskId: task.id,\n subtasks,\n dependencies: new Map([\n [subtasks[1]!.title, [subtasks[0]!.title]],\n [subtasks[2]!.title, [subtasks[1]!.title]],\n ]),\n estimatedTurns: subtasks.reduce((sum, st) => sum + st.estimatedTurns, 0),\n };\n }\n\n /**\n * Start multi-task session for complex tasks\n */\n private async startMultiTaskSession(\n breakdown: TaskBreakdown,\n frameId: string\n ): Promise<AgentTaskSession> {\n // Create subtasks in task store\n const subtaskIds: string[] = [];\n\n for (const subtask of breakdown.subtasks) {\n const subtaskId = this.taskStore.createTask({\n title: subtask.title,\n description: subtask.description,\n frameId,\n parentId: breakdown.parentTaskId,\n tags: ['agent-subtask', ...subtask.verifiers],\n estimatedEffort: subtask.estimatedTurns * 5, // Rough conversion to minutes\n });\n subtaskIds.push(subtaskId);\n }\n\n // Add dependencies\n const titleToId = new Map(\n breakdown.subtasks.map((st, i) => [st.title, subtaskIds[i]])\n );\n\n for (const [title, deps] of breakdown.dependencies) {\n const taskId = titleToId.get(title);\n if (taskId) {\n for (const dep of deps) {\n const depId = titleToId.get(dep);\n if (depId) {\n this.taskStore.addDependency(taskId, depId);\n }\n }\n }\n }\n\n // Start session for first subtask\n return this.startTaskSession(subtaskIds[0]!, frameId);\n }\n\n /**\n * Update context window with significant events\n */\n private updateContextWindow(\n session: AgentTaskSession,\n action: string,\n verificationResults: VerificationResult[]\n ): void {\n const significantEvent = {\n turn: session.turnCount,\n action: action.substring(0, 100),\n verificationSummary: verificationResults.map((r) => ({\n verifier: r.verifierId,\n passed: r.passed,\n })),\n timestamp: new Date().toISOString(),\n };\n\n session.contextWindow.push(JSON.stringify(significantEvent));\n\n // Keep only last N events (Spotify's context window optimization)\n if (session.contextWindow.length > this.CONTEXT_WINDOW_SIZE) {\n session.contextWindow = session.contextWindow.slice(\n -this.CONTEXT_WINDOW_SIZE\n );\n }\n }\n\n /**\n * Generate feedback from verification results\n */\n private generateFeedback(results: VerificationResult[]): string {\n const failed = results.filter((r) => !r.passed);\n const warnings = results.filter(\n (r) => !r.passed && r.severity === 'warning'\n );\n const errors = results.filter((r) => !r.passed && r.severity === 'error');\n\n if (errors.length > 0) {\n const errorMessages = errors.map((e) => `- ${e.message}`).join('\\n');\n return `Verification failed with ${errors.length} error(s):\\n${errorMessages}`;\n }\n\n if (warnings.length > 0) {\n const warningMessages = warnings.map((w) => `- ${w.message}`).join('\\n');\n return `Verification passed with ${warnings.length} warning(s):\\n${warningMessages}`;\n }\n\n return 'All verifications passed successfully';\n }\n\n /**\n * Suggest context adjustment based on verification results\n */\n private suggestContextAdjustment(\n results: VerificationResult[]\n ): string | undefined {\n const failed = results.filter((r) => !r.passed && r.severity === 'error');\n\n if (failed.length === 0) {\n return undefined;\n }\n\n // Generate suggestions based on failure patterns\n const suggestions: string[] = [];\n\n if (failed.some((r) => r.verifierId === 'test-runner')) {\n suggestions.push('Focus on fixing failing tests');\n }\n if (failed.some((r) => r.verifierId === 'linter')) {\n suggestions.push('Address linting errors before proceeding');\n }\n if (failed.some((r) => r.verifierId === 'semantic-validator')) {\n suggestions.push('Review original requirements and adjust approach');\n }\n\n return suggestions.length > 0 ? suggestions.join('; ') : undefined;\n }\n\n /**\n * Handle turn limit reached\n */\n private async handleTurnLimitReached(session: AgentTaskSession): Promise<{\n success: boolean;\n feedback: string;\n shouldContinue: boolean;\n verificationResults: VerificationResult[];\n }> {\n logger.warn('Session reached turn limit', {\n sessionId: session.id,\n taskId: session.taskId,\n turnCount: session.turnCount,\n });\n\n // Check if task can be considered complete\n const task = this.taskStore.getTask(session.taskId);\n const isComplete = this.assessTaskCompletion(session);\n\n if (isComplete) {\n await this.completeSession(session);\n return {\n success: true,\n feedback: 'Task completed successfully within turn limit',\n shouldContinue: false,\n verificationResults: [],\n };\n }\n\n // Mark session as timeout\n session.status = 'timeout';\n this.taskStore.updateTaskStatus(\n session.taskId,\n 'blocked',\n 'Session timeout - manual review needed'\n );\n\n return {\n success: false,\n feedback: `Session reached ${this.MAX_TURNS_PER_SESSION} turn limit. Task requires manual review or retry.`,\n shouldContinue: false,\n verificationResults: [],\n };\n }\n\n /**\n * Assess if task is complete enough\n */\n private assessTaskCompletion(session: AgentTaskSession): boolean {\n // Check if recent verifications are passing\n const recentResults = session.verificationResults.slice(-5);\n const recentPassRate =\n recentResults.filter((r) => r.passed).length / recentResults.length;\n\n // Check if semantic validator passed recently (Spotify's LLM judge)\n const semanticPassed = recentResults.some(\n (r) => r.verifierId === 'semantic-validator' && r.passed\n );\n\n return recentPassRate >= 0.8 && semanticPassed;\n }\n\n /**\n * Complete a session\n */\n private async completeSession(session: AgentTaskSession): Promise<void> {\n session.status = 'completed';\n session.completedAt = new Date();\n\n // Update task status\n this.taskStore.updateTaskStatus(\n session.taskId,\n 'completed',\n 'Agent session completed'\n );\n\n // Clear timeout\n const timeout = this.sessionTimeouts.get(session.id);\n if (timeout) {\n clearTimeout(timeout);\n this.sessionTimeouts.delete(session.id);\n }\n\n // Generate and save session summary to frame\n const summary = this.generateSessionSummary(session);\n this.frameManager.addEvent('observation', {\n type: 'session_summary',\n frameId: session.frameId,\n summary,\n });\n\n logger.info('Session completed', {\n sessionId: session.id,\n taskId: session.taskId,\n turnCount: session.turnCount,\n duration: session.completedAt.getTime() - session.startedAt.getTime(),\n });\n }\n\n /**\n * Generate session summary for frame digest\n */\n private generateSessionSummary(\n session: AgentTaskSession\n ): Record<string, any> {\n const verificationStats = {\n total: session.verificationResults.length,\n passed: session.verificationResults.filter((r) => r.passed).length,\n failed: session.verificationResults.filter((r) => !r.passed).length,\n };\n\n return {\n sessionId: session.id,\n taskId: session.taskId,\n status: session.status,\n turnCount: session.turnCount,\n duration: session.completedAt\n ? session.completedAt.getTime() - session.startedAt.getTime()\n : 0,\n verificationStats,\n feedbackLoop: session.feedbackLoop.slice(-3), // Last 3 feedback entries\n contextWindow: session.contextWindow.slice(-2), // Last 2 context entries\n };\n }\n\n /**\n * Start timeout for session\n */\n private startSessionTimeout(sessionId: string): void {\n const timeout = setTimeout(() => {\n const session = this.activeSessions.get(sessionId);\n if (session && session.status === 'active') {\n session.status = 'timeout';\n this.taskStore.updateTaskStatus(\n session.taskId,\n 'blocked',\n 'Session timeout - no activity'\n );\n logger.warn('Session timed out due to inactivity', { sessionId });\n }\n }, this.SESSION_TIMEOUT_MS);\n\n this.sessionTimeouts.set(sessionId, timeout);\n }\n\n /**\n * Generate unique session ID\n */\n private generateSessionId(taskId: string): string {\n return `session-${taskId}-${Date.now()}`;\n }\n\n /**\n * Get active sessions summary\n */\n getActiveSessions(): Array<{\n sessionId: string;\n taskId: string;\n turnCount: number;\n status: string;\n startedAt: Date;\n }> {\n return Array.from(this.activeSessions.values()).map((session) => ({\n sessionId: session.id,\n taskId: session.taskId,\n turnCount: session.turnCount,\n status: session.status,\n startedAt: session.startedAt,\n }));\n }\n\n /**\n * Retry a failed session (Spotify's 3-retry strategy)\n */\n async retrySession(sessionId: string): Promise<AgentTaskSession | null> {\n const session = this.activeSessions.get(sessionId);\n if (!session || session.status === 'active') {\n return null;\n }\n\n // Count previous retries\n const retryCount = Array.from(this.activeSessions.values()).filter(\n (s) => s.taskId === session.taskId && s.status === 'failed'\n ).length;\n\n if (retryCount >= this.MAX_SESSION_RETRIES) {\n logger.warn('Max retries reached for task', {\n taskId: session.taskId,\n retries: retryCount,\n });\n return null;\n }\n\n // Start new session with learned context\n const newSession = await this.startTaskSession(\n session.taskId,\n session.frameId\n );\n\n // Transfer learned context from previous session\n newSession.contextWindow = session.contextWindow.slice(-3);\n newSession.feedbackLoop = [\n {\n turn: 0,\n action: 'Session retry with learned context',\n result: `Retrying after ${retryCount} previous attempts`,\n verificationPassed: true,\n contextAdjustment: session.feedbackLoop\n .filter((f) => f.contextAdjustment)\n .map((f) => f.contextAdjustment)\n .join('; '),\n },\n ];\n\n return newSession;\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/agents/verifiers/base-verifier.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Base Verifier Interface - Spotify-inspired verification infrastructure\n *\n * Implements the strong verification loop pattern from Spotify's approach:\n * - Component-aware activation\n * - Incremental feedback\n * - Abstract complexity from agents\n */\n\nimport { logger } from '../../core/monitoring/logger.js';\n\nexport type VerifierSeverity = 'error' | 'warning' | 'info';\nexport type VerifierType =\n | 'syntax'\n | 'semantic'\n | 'performance'\n | 'security'\n | 'style';\n\nexport interface VerifierContext {\n filePath?: string;\n language?: string;\n framework?: string;\n hasTests?: boolean;\n hasDocumentation?: boolean;\n isProduction?: boolean;\n customRules?: Record<string, any>;\n}\n\nexport interface VerifierResult {\n verifierId: string;\n verifierType: VerifierType;\n passed: boolean;\n message: string;\n severity: VerifierSeverity;\n timestamp: Date;\n details?: VerifierDetails;\n autoFix?: VerifierAutoFix;\n confidence?: number; // 0-1, for probabilistic verifiers like LLM judge\n}\n\nexport interface VerifierDetails {\n location?: {\n file?: string;\n line?: number;\n column?: number;\n };\n code?: string;\n expected?: string;\n actual?: string;\n suggestion?: string;\n relatedLinks?: string[];\n}\n\nexport interface VerifierAutoFix {\n command: string;\n description: string;\n safe: boolean; // Whether fix can be applied automatically\n confidence: number; // 0-1\n}\n\nexport interface VerifierConfig {\n id: string;\n name: string;\n type: VerifierType;\n enabled: boolean;\n stopOnError: boolean; // Spotify's stop hook pattern\n maxRetries?: number;\n timeout?: number; // milliseconds\n customConfig?: Record<string, any>;\n}\n\n/**\n * Abstract base class for all verifiers\n */\nexport abstract class BaseVerifier {\n protected config: VerifierConfig;\n protected retryCount: Map<string, number> = new Map();\n\n constructor(config: VerifierConfig) {\n this.config = config;\n }\n\n /**\n * Check if verifier should be activated for given context\n * Implements Spotify's context-aware activation\n */\n abstract shouldActivate(context: VerifierContext): boolean;\n\n /**\n * Run verification on the given input\n */\n abstract verify(\n input: string | Buffer,\n context: VerifierContext\n ): Promise<VerifierResult>;\n\n /**\n * Extract most relevant error messages (Spotify pattern)\n */\n protected extractRelevantErrors(\n output: string,\n patterns: RegExp[]\n ): string[] {\n const errors: string[] = [];\n const lines = output.split('\\n');\n\n for (const line of lines) {\n for (const pattern of patterns) {\n const match = line.match(pattern);\n if (match) {\n errors.push(match[0]);\n break;\n }\n }\n }\n\n // Limit to most relevant errors (Spotify's approach)\n return errors.slice(0, 5);\n }\n\n /**\n * Generate incremental feedback\n */\n protected generateFeedback(\n errors: string[],\n context: VerifierContext\n ): string {\n if (errors.length === 0) {\n return `${this.config.name} verification passed`;\n }\n\n const prefix = context.filePath ? `In ${context.filePath}: ` : '';\n const errorList = errors.map((e) => ` - ${e}`).join('\\n');\n\n return `${prefix}${this.config.name} found ${errors.length} issue(s):\\n${errorList}`;\n }\n\n /**\n * Retry logic for transient failures\n */\n protected async withRetry<T>(\n operation: () => Promise<T>,\n key: string\n ): Promise<T> {\n const maxRetries = this.config.maxRetries || 0;\n const currentRetries = this.retryCount.get(key) || 0;\n\n try {\n const result = await operation();\n this.retryCount.delete(key); // Clear on success\n return result;\n } catch (error) {\n if (currentRetries < maxRetries) {\n this.retryCount.set(key, currentRetries + 1);\n logger.warn(`Retrying ${this.config.name} verification`, {\n attempt: currentRetries + 1,\n maxRetries,\n error: error instanceof Error ? error.message : String(error),\n });\n\n // Exponential backoff\n await this.delay(Math.pow(2, currentRetries) * 1000);\n return this.withRetry(operation, key);\n }\n\n this.retryCount.delete(key);\n throw error;\n }\n }\n\n /**\n * Apply timeout to verification\n */\n protected async withTimeout<T>(operation: () => Promise<T>): Promise<T> {\n if (!this.config.timeout) {\n return operation();\n }\n\n return Promise.race([\n operation(),\n new Promise<T>((_, reject) =>\n setTimeout(\n () =>\n reject(\n new Error(\n `${this.config.name} timeout after ${this.config.timeout}ms`\n )\n ),\n this.config.timeout\n )\n ),\n ]);\n }\n\n /**\n * Helper to create a standard result\n */\n protected createResult(\n passed: boolean,\n message: string,\n severity: VerifierSeverity = 'info',\n details?: VerifierDetails,\n autoFix?: VerifierAutoFix\n ): VerifierResult {\n return {\n verifierId: this.config.id,\n verifierType: this.config.type,\n passed,\n message,\n severity,\n timestamp: new Date(),\n details,\n autoFix,\n };\n }\n\n /**\n * Delay helper for retries\n */\n private delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n\n /**\n * Get verifier configuration\n */\n getConfig(): VerifierConfig {\n return { ...this.config };\n }\n\n /**\n * Check if verifier should stop execution on error\n */\n shouldStopOnError(): boolean {\n return this.config.stopOnError;\n }\n\n /**\n * Update verifier configuration\n */\n updateConfig(updates: Partial<VerifierConfig>): void {\n this.config = { ...this.config, ...updates };\n logger.info(`Updated ${this.config.name} configuration`, {\n updates,\n });\n }\n}\n"],
|
|
5
|
-
"mappings": "AASA,SAAS,cAAc;AAkEhB,MAAe,aAAa;AAAA,EACvB;AAAA,EACA,aAAkC,oBAAI,IAAI;AAAA,EAEpD,YAAY,QAAwB;AAClC,SAAK,SAAS;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA,EAmBU,sBACR,QACA,UACU;AACV,UAAM,SAAmB,CAAC;AAC1B,UAAM,QAAQ,OAAO,MAAM,IAAI;AAE/B,eAAW,QAAQ,OAAO;AACxB,iBAAW,WAAW,UAAU;AAC9B,cAAM,QAAQ,KAAK,MAAM,OAAO;AAChC,YAAI,OAAO;AACT,iBAAO,KAAK,MAAM,CAAC,CAAC;AACpB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,WAAO,OAAO,MAAM,GAAG,CAAC;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA,EAKU,iBACR,QACA,SACQ;AACR,QAAI,OAAO,WAAW,GAAG;AACvB,aAAO,GAAG,KAAK,OAAO,IAAI;AAAA,IAC5B;AAEA,UAAM,SAAS,QAAQ,WAAW,MAAM,QAAQ,QAAQ,OAAO;AAC/D,UAAM,YAAY,OAAO,IAAI,CAAC,MAAM,OAAO,CAAC,EAAE,EAAE,KAAK,IAAI;AAEzD,WAAO,GAAG,MAAM,GAAG,KAAK,OAAO,IAAI,UAAU,OAAO,MAAM;AAAA,EAAe,SAAS;AAAA,EACpF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAgB,UACd,WACA,KACY;AACZ,UAAM,aAAa,KAAK,OAAO,cAAc;AAC7C,UAAM,iBAAiB,KAAK,WAAW,IAAI,GAAG,KAAK;AAEnD,QAAI;AACF,YAAM,SAAS,MAAM,UAAU;AAC/B,WAAK,WAAW,OAAO,GAAG;AAC1B,aAAO;AAAA,IACT,SAAS,
|
|
4
|
+
"sourcesContent": ["/**\n * Base Verifier Interface - Spotify-inspired verification infrastructure\n *\n * Implements the strong verification loop pattern from Spotify's approach:\n * - Component-aware activation\n * - Incremental feedback\n * - Abstract complexity from agents\n */\n\nimport { logger } from '../../core/monitoring/logger.js';\n\nexport type VerifierSeverity = 'error' | 'warning' | 'info';\nexport type VerifierType =\n | 'syntax'\n | 'semantic'\n | 'performance'\n | 'security'\n | 'style';\n\nexport interface VerifierContext {\n filePath?: string;\n language?: string;\n framework?: string;\n hasTests?: boolean;\n hasDocumentation?: boolean;\n isProduction?: boolean;\n customRules?: Record<string, any>;\n}\n\nexport interface VerifierResult {\n verifierId: string;\n verifierType: VerifierType;\n passed: boolean;\n message: string;\n severity: VerifierSeverity;\n timestamp: Date;\n details?: VerifierDetails;\n autoFix?: VerifierAutoFix;\n confidence?: number; // 0-1, for probabilistic verifiers like LLM judge\n}\n\nexport interface VerifierDetails {\n location?: {\n file?: string;\n line?: number;\n column?: number;\n };\n code?: string;\n expected?: string;\n actual?: string;\n suggestion?: string;\n relatedLinks?: string[];\n}\n\nexport interface VerifierAutoFix {\n command: string;\n description: string;\n safe: boolean; // Whether fix can be applied automatically\n confidence: number; // 0-1\n}\n\nexport interface VerifierConfig {\n id: string;\n name: string;\n type: VerifierType;\n enabled: boolean;\n stopOnError: boolean; // Spotify's stop hook pattern\n maxRetries?: number;\n timeout?: number; // milliseconds\n customConfig?: Record<string, any>;\n}\n\n/**\n * Abstract base class for all verifiers\n */\nexport abstract class BaseVerifier {\n protected config: VerifierConfig;\n protected retryCount: Map<string, number> = new Map();\n\n constructor(config: VerifierConfig) {\n this.config = config;\n }\n\n /**\n * Check if verifier should be activated for given context\n * Implements Spotify's context-aware activation\n */\n abstract shouldActivate(context: VerifierContext): boolean;\n\n /**\n * Run verification on the given input\n */\n abstract verify(\n input: string | Buffer,\n context: VerifierContext\n ): Promise<VerifierResult>;\n\n /**\n * Extract most relevant error messages (Spotify pattern)\n */\n protected extractRelevantErrors(\n output: string,\n patterns: RegExp[]\n ): string[] {\n const errors: string[] = [];\n const lines = output.split('\\n');\n\n for (const line of lines) {\n for (const pattern of patterns) {\n const match = line.match(pattern);\n if (match) {\n errors.push(match[0]);\n break;\n }\n }\n }\n\n // Limit to most relevant errors (Spotify's approach)\n return errors.slice(0, 5);\n }\n\n /**\n * Generate incremental feedback\n */\n protected generateFeedback(\n errors: string[],\n context: VerifierContext\n ): string {\n if (errors.length === 0) {\n return `${this.config.name} verification passed`;\n }\n\n const prefix = context.filePath ? `In ${context.filePath}: ` : '';\n const errorList = errors.map((e) => ` - ${e}`).join('\\n');\n\n return `${prefix}${this.config.name} found ${errors.length} issue(s):\\n${errorList}`;\n }\n\n /**\n * Retry logic for transient failures\n */\n protected async withRetry<T>(\n operation: () => Promise<T>,\n key: string\n ): Promise<T> {\n const maxRetries = this.config.maxRetries || 0;\n const currentRetries = this.retryCount.get(key) || 0;\n\n try {\n const result = await operation();\n this.retryCount.delete(key); // Clear on success\n return result;\n } catch (error: unknown) {\n if (currentRetries < maxRetries) {\n this.retryCount.set(key, currentRetries + 1);\n logger.warn(`Retrying ${this.config.name} verification`, {\n attempt: currentRetries + 1,\n maxRetries,\n error: error instanceof Error ? error.message : String(error),\n });\n\n // Exponential backoff\n await this.delay(Math.pow(2, currentRetries) * 1000);\n return this.withRetry(operation, key);\n }\n\n this.retryCount.delete(key);\n throw error;\n }\n }\n\n /**\n * Apply timeout to verification\n */\n protected async withTimeout<T>(operation: () => Promise<T>): Promise<T> {\n if (!this.config.timeout) {\n return operation();\n }\n\n return Promise.race([\n operation(),\n new Promise<T>((_, reject) =>\n setTimeout(\n () =>\n reject(\n new Error(\n `${this.config.name} timeout after ${this.config.timeout}ms`\n )\n ),\n this.config.timeout\n )\n ),\n ]);\n }\n\n /**\n * Helper to create a standard result\n */\n protected createResult(\n passed: boolean,\n message: string,\n severity: VerifierSeverity = 'info',\n details?: VerifierDetails,\n autoFix?: VerifierAutoFix\n ): VerifierResult {\n return {\n verifierId: this.config.id,\n verifierType: this.config.type,\n passed,\n message,\n severity,\n timestamp: new Date(),\n details: details || undefined,\n autoFix: autoFix || undefined,\n };\n }\n\n /**\n * Delay helper for retries\n */\n private delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n\n /**\n * Get verifier configuration\n */\n getConfig(): VerifierConfig {\n return { ...this.config };\n }\n\n /**\n * Check if verifier should stop execution on error\n */\n shouldStopOnError(): boolean {\n return this.config.stopOnError;\n }\n\n /**\n * Update verifier configuration\n */\n updateConfig(updates: Partial<VerifierConfig>): void {\n this.config = { ...this.config, ...updates };\n logger.info(`Updated ${this.config.name} configuration`, {\n updates,\n });\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/agents/verifiers/formatter-verifier.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Formatter Verifier - Code formatting verification\n * Based on Spotify's formatting verifier pattern\n */\n\nimport { exec } from 'child_process';\nimport { promisify } from 'util';\nimport {\n BaseVerifier,\n VerifierContext,\n VerifierResult,\n VerifierConfig,\n} from './base-verifier.js';\nimport { logger } from '../../core/monitoring/logger.js';\n\nconst execAsync = promisify(exec);\n\nexport class FormatterVerifier extends BaseVerifier {\n private formatters: Map<string, FormatterCommand> = new Map();\n\n constructor(config?: Partial<VerifierConfig>) {\n super({\n id: 'formatter',\n name: 'Code Formatter',\n type: 'style',\n enabled: true,\n stopOnError: false,\n timeout: 10000,\n ...config,\n });\n\n this.initializeFormatters();\n }\n\n private initializeFormatters() {\n // Common formatters for different languages\n this.formatters.set('typescript', {\n checkCommand: 'npx prettier --check',\n fixCommand: 'npx prettier --write',\n patterns: [/\\[error\\]/gi, /File not formatted/gi],\n });\n\n this.formatters.set('javascript', {\n checkCommand: 'npx prettier --check',\n fixCommand: 'npx prettier --write',\n patterns: [/\\[error\\]/gi, /File not formatted/gi],\n });\n\n this.formatters.set('python', {\n checkCommand: 'black --check',\n fixCommand: 'black',\n patterns: [/would reformat/gi, /File not formatted/gi],\n });\n\n this.formatters.set('rust', {\n checkCommand: 'cargo fmt -- --check',\n fixCommand: 'cargo fmt',\n patterns: [/Diff in/gi, /File not formatted/gi],\n });\n\n this.formatters.set('go', {\n checkCommand: 'gofmt -l',\n fixCommand: 'gofmt -w',\n patterns: [/.+\\.go$/gm], // gofmt lists unformatted files\n });\n }\n\n shouldActivate(context: VerifierContext): boolean {\n // Activate for supported languages with code files\n if (!context.language || !context.filePath) {\n return false;\n }\n\n return this.formatters.has(context.language.toLowerCase());\n }\n\n async verify(\n input: string | Buffer,\n context: VerifierContext\n ): Promise<VerifierResult> {\n if (!context.language || !context.filePath) {\n return this.createResult(\n false,\n 'Missing language or file path in context',\n 'error'\n );\n }\n\n const formatter = this.formatters.get(context.language.toLowerCase());\n if (!formatter) {\n return this.createResult(\n true,\n `No formatter configured for ${context.language}`,\n 'info'\n );\n }\n\n try {\n return await this.withTimeout(async () => {\n return await this.withRetry(\n () => this.runFormatter(formatter, context),\n context.filePath!\n );\n });\n } catch (error) {\n logger.error(\n 'Formatter verification failed',\n error instanceof Error ? error : undefined\n );\n return this.createResult(\n false,\n `Formatter error: ${error instanceof Error ? error.message : String(error)}`,\n 'error'\n );\n }\n }\n\n private async runFormatter(\n formatter: FormatterCommand,\n context: VerifierContext\n ): Promise<VerifierResult> {\n const command = `${formatter.checkCommand} \"${context.filePath}\"`;\n\n try {\n const { stdout, stderr } = await execAsync(command, {\n cwd: process.cwd(),\n timeout: this.config.timeout,\n });\n\n // Formatter passed\n return this.createResult(true, 'Code is properly formatted', 'info');\n } catch (error: any) {\n // Check if it's a formatting issue (exit code 1) vs actual error\n if (error.code === 1) {\n const output = error.stdout + error.stderr;\n const errors = this.extractRelevantErrors(output, formatter.patterns);\n\n return this.createResult(\n false,\n this.generateFeedback(errors, context),\n 'warning',\n {\n code: output.substring(0, 500),\n suggestion: 'Run formatter to fix issues',\n },\n {\n command: `${formatter.fixCommand} \"${context.filePath}\"`,\n description: 'Auto-format the file',\n safe: true,\n confidence: 0.95,\n }\n );\n }\n\n // Actual error running formatter\n throw error;\n }\n }\n}\n\ninterface FormatterCommand {\n checkCommand: string;\n fixCommand: string;\n patterns: RegExp[];\n}\n"],
|
|
5
|
-
"mappings": "AAKA,SAAS,YAAY;AACrB,SAAS,iBAAiB;AAC1B;AAAA,EACE;AAAA,OAIK;AACP,SAAS,cAAc;AAEvB,MAAM,YAAY,UAAU,IAAI;AAEzB,MAAM,0BAA0B,aAAa;AAAA,EAC1C,aAA4C,oBAAI,IAAI;AAAA,EAE5D,YAAY,QAAkC;AAC5C,UAAM;AAAA,MACJ,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,aAAa;AAAA,MACb,SAAS;AAAA,MACT,GAAG;AAAA,IACL,CAAC;AAED,SAAK,qBAAqB;AAAA,EAC5B;AAAA,EAEQ,uBAAuB;AAE7B,SAAK,WAAW,IAAI,cAAc;AAAA,MAChC,cAAc;AAAA,MACd,YAAY;AAAA,MACZ,UAAU,CAAC,eAAe,sBAAsB;AAAA,IAClD,CAAC;AAED,SAAK,WAAW,IAAI,cAAc;AAAA,MAChC,cAAc;AAAA,MACd,YAAY;AAAA,MACZ,UAAU,CAAC,eAAe,sBAAsB;AAAA,IAClD,CAAC;AAED,SAAK,WAAW,IAAI,UAAU;AAAA,MAC5B,cAAc;AAAA,MACd,YAAY;AAAA,MACZ,UAAU,CAAC,oBAAoB,sBAAsB;AAAA,IACvD,CAAC;AAED,SAAK,WAAW,IAAI,QAAQ;AAAA,MAC1B,cAAc;AAAA,MACd,YAAY;AAAA,MACZ,UAAU,CAAC,aAAa,sBAAsB;AAAA,IAChD,CAAC;AAED,SAAK,WAAW,IAAI,MAAM;AAAA,MACxB,cAAc;AAAA,MACd,YAAY;AAAA,MACZ,UAAU,CAAC,WAAW;AAAA;AAAA,IACxB,CAAC;AAAA,EACH;AAAA,EAEA,eAAe,SAAmC;AAEhD,QAAI,CAAC,QAAQ,YAAY,CAAC,QAAQ,UAAU;AAC1C,aAAO;AAAA,IACT;AAEA,WAAO,KAAK,WAAW,IAAI,QAAQ,SAAS,YAAY,CAAC;AAAA,EAC3D;AAAA,EAEA,MAAM,OACJ,OACA,SACyB;AACzB,QAAI,CAAC,QAAQ,YAAY,CAAC,QAAQ,UAAU;AAC1C,aAAO,KAAK;AAAA,QACV;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,UAAM,YAAY,KAAK,WAAW,IAAI,QAAQ,SAAS,YAAY,CAAC;AACpE,QAAI,CAAC,WAAW;AACd,aAAO,KAAK;AAAA,QACV;AAAA,QACA,+BAA+B,QAAQ,QAAQ;AAAA,QAC/C;AAAA,MACF;AAAA,IACF;AAEA,QAAI;AACF,aAAO,MAAM,KAAK,YAAY,YAAY;AACxC,eAAO,MAAM,KAAK;AAAA,UAChB,MAAM,KAAK,aAAa,WAAW,OAAO;AAAA,UAC1C,QAAQ;AAAA,QACV;AAAA,MACF,CAAC;AAAA,IACH,SAAS,
|
|
4
|
+
"sourcesContent": ["/**\n * Formatter Verifier - Code formatting verification\n * Based on Spotify's formatting verifier pattern\n */\n\nimport { exec } from 'child_process';\nimport { promisify } from 'util';\nimport {\n BaseVerifier,\n VerifierContext,\n VerifierResult,\n VerifierConfig,\n} from './base-verifier.js';\nimport { logger } from '../../core/monitoring/logger.js';\n\nconst execAsync = promisify(exec);\n\nexport class FormatterVerifier extends BaseVerifier {\n private formatters: Map<string, FormatterCommand> = new Map();\n\n constructor(config?: Partial<VerifierConfig>) {\n super({\n id: 'formatter',\n name: 'Code Formatter',\n type: 'style',\n enabled: true,\n stopOnError: false,\n timeout: 10000,\n ...config,\n });\n\n this.initializeFormatters();\n }\n\n private initializeFormatters() {\n // Common formatters for different languages\n this.formatters.set('typescript', {\n checkCommand: 'npx prettier --check',\n fixCommand: 'npx prettier --write',\n patterns: [/\\[error\\]/gi, /File not formatted/gi],\n });\n\n this.formatters.set('javascript', {\n checkCommand: 'npx prettier --check',\n fixCommand: 'npx prettier --write',\n patterns: [/\\[error\\]/gi, /File not formatted/gi],\n });\n\n this.formatters.set('python', {\n checkCommand: 'black --check',\n fixCommand: 'black',\n patterns: [/would reformat/gi, /File not formatted/gi],\n });\n\n this.formatters.set('rust', {\n checkCommand: 'cargo fmt -- --check',\n fixCommand: 'cargo fmt',\n patterns: [/Diff in/gi, /File not formatted/gi],\n });\n\n this.formatters.set('go', {\n checkCommand: 'gofmt -l',\n fixCommand: 'gofmt -w',\n patterns: [/.+\\.go$/gm], // gofmt lists unformatted files\n });\n }\n\n shouldActivate(context: VerifierContext): boolean {\n // Activate for supported languages with code files\n if (!context.language || !context.filePath) {\n return false;\n }\n\n return this.formatters.has(context.language.toLowerCase());\n }\n\n async verify(\n input: string | Buffer,\n context: VerifierContext\n ): Promise<VerifierResult> {\n if (!context.language || !context.filePath) {\n return this.createResult(\n false,\n 'Missing language or file path in context',\n 'error'\n );\n }\n\n const formatter = this.formatters.get(context.language.toLowerCase());\n if (!formatter) {\n return this.createResult(\n true,\n `No formatter configured for ${context.language}`,\n 'info'\n );\n }\n\n try {\n return await this.withTimeout(async () => {\n return await this.withRetry(\n () => this.runFormatter(formatter, context),\n context.filePath!\n );\n });\n } catch (error: unknown) {\n logger.error(\n 'Formatter verification failed',\n error instanceof Error ? error : undefined\n );\n return this.createResult(\n false,\n `Formatter error: ${error instanceof Error ? error.message : String(error)}`,\n 'error'\n );\n }\n }\n\n private async runFormatter(\n formatter: FormatterCommand,\n context: VerifierContext\n ): Promise<VerifierResult> {\n const command = `${formatter.checkCommand} \"${context.filePath}\"`;\n\n try {\n const { stdout, stderr } = await execAsync(command, {\n cwd: process.cwd(),\n timeout: this.config.timeout,\n });\n\n // Formatter passed\n return this.createResult(true, 'Code is properly formatted', 'info');\n } catch (error: any) {\n // Check if it's a formatting issue (exit code 1) vs actual error\n if (error.code === 1) {\n const output = error.stdout + error.stderr;\n const errors = this.extractRelevantErrors(output, formatter.patterns);\n\n return this.createResult(\n false,\n this.generateFeedback(errors, context),\n 'warning',\n {\n code: output.substring(0, 500),\n suggestion: 'Run formatter to fix issues',\n },\n {\n command: `${formatter.fixCommand} \"${context.filePath}\"`,\n description: 'Auto-format the file',\n safe: true,\n confidence: 0.95,\n }\n );\n }\n\n // Actual error running formatter\n throw error;\n }\n }\n}\n\ninterface FormatterCommand {\n checkCommand: string;\n fixCommand: string;\n patterns: RegExp[];\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/agents/verifiers/llm-judge.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * LLM Judge - Semantic validation using LLM\n * Implements Spotify's LLM judge pattern that \"vetoes about a quarter of agent sessions\"\n */\n\nimport {\n BaseVerifier,\n VerifierContext,\n VerifierResult,\n VerifierConfig,\n} from './base-verifier.js';\nimport { logger } from '../../core/monitoring/logger.js';\n\nexport interface LLMJudgeContext extends VerifierContext {\n originalPrompt: string;\n proposedChanges: string;\n acceptanceCriteria?: string[];\n previousFeedback?: string[];\n}\n\nexport interface JudgementCriteria {\n adherenceToRequirements: number; // 0-1\n codeQuality: number; // 0-1\n safety: number; // 0-1\n completeness: number; // 0-1\n semanticCorrectness: number; // 0-1\n}\n\nexport class LLMJudge extends BaseVerifier {\n // Spotify reports ~75% pass rate (25% veto rate)\n private readonly VETO_THRESHOLD = 0.7;\n private readonly CRITERIA_WEIGHTS = {\n adherenceToRequirements: 0.3,\n codeQuality: 0.2,\n safety: 0.2,\n completeness: 0.15,\n semanticCorrectness: 0.15,\n };\n\n constructor(config?: Partial<VerifierConfig>) {\n super({\n id: 'llm-judge',\n name: 'LLM Semantic Judge',\n type: 'semantic',\n enabled: true,\n stopOnError: true, // Stop on semantic failures (Spotify pattern)\n timeout: 30000,\n ...config,\n });\n }\n\n shouldActivate(context: VerifierContext): boolean {\n // Always activate for semantic validation (Spotify always includes this)\n return true;\n }\n\n async verify(\n input: string | Buffer,\n context: VerifierContext\n ): Promise<VerifierResult> {\n const llmContext = context as LLMJudgeContext;\n\n if (!llmContext.originalPrompt) {\n return this.createResult(\n false,\n 'Missing original prompt for semantic validation',\n 'error'\n );\n }\n\n try {\n return await this.withTimeout(async () => {\n const judgement = await this.performJudgement(\n input.toString(),\n llmContext\n );\n return this.createJudgementResult(judgement, llmContext);\n });\n } catch (error) {\n logger.error(\n 'LLM Judge failed',\n error instanceof Error ? error : undefined\n );\n return this.createResult(\n false,\n `Semantic validation error: ${error instanceof Error ? error.message : String(error)}`,\n 'error'\n );\n }\n }\n\n private async performJudgement(\n proposedChanges: string,\n context: LLMJudgeContext\n ): Promise<JudgementCriteria> {\n // In production, this would call an actual LLM API\n // For now, simulate judgement with realistic patterns\n\n const criteria: JudgementCriteria = {\n adherenceToRequirements: this.evaluateAdherence(proposedChanges, context),\n codeQuality: this.evaluateCodeQuality(proposedChanges),\n safety: this.evaluateSafety(proposedChanges),\n completeness: this.evaluateCompleteness(proposedChanges, context),\n semanticCorrectness: this.evaluateSemanticCorrectness(\n proposedChanges,\n context\n ),\n };\n\n // Log judgement for analysis (Spotify's trace collection)\n logger.info('LLM Judge evaluation', {\n criteria,\n overallScore: this.calculateOverallScore(criteria),\n willVeto: this.calculateOverallScore(criteria) < this.VETO_THRESHOLD,\n });\n\n return criteria;\n }\n\n private evaluateAdherence(\n proposedChanges: string,\n context: LLMJudgeContext\n ): number {\n // Simulate checking if changes match original requirements\n const hasKeywords = context.originalPrompt\n .toLowerCase()\n .split(' ')\n .filter((word) => word.length > 4)\n .some((keyword) => proposedChanges.toLowerCase().includes(keyword));\n\n // Check acceptance criteria if provided\n if (context.acceptanceCriteria) {\n const metCriteria = context.acceptanceCriteria.filter((criterion) =>\n this.checkCriterion(criterion, proposedChanges)\n ).length;\n const criteriaScore = metCriteria / context.acceptanceCriteria.length;\n return hasKeywords ? Math.min(1, criteriaScore + 0.2) : criteriaScore;\n }\n\n // Simulate realistic pass rate (~75%)\n return hasKeywords ? 0.75 + Math.random() * 0.2 : 0.4 + Math.random() * 0.3;\n }\n\n private evaluateCodeQuality(proposedChanges: string): number {\n // Simple heuristics for code quality\n const indicators = {\n hasComments:\n proposedChanges.includes('//') || proposedChanges.includes('/*'),\n hasErrorHandling:\n proposedChanges.includes('try') || proposedChanges.includes('catch'),\n hasTests:\n proposedChanges.includes('test') || proposedChanges.includes('expect'),\n properNaming: !/[a-z]{20,}|[A-Z]{10,}/.test(proposedChanges), // No extremely long names\n reasonable_length:\n proposedChanges.length > 50 && proposedChanges.length < 5000,\n };\n\n const score =\n Object.values(indicators).filter(Boolean).length /\n Object.keys(indicators).length;\n return Math.min(1, score + 0.2); // Boost slightly\n }\n\n private evaluateSafety(proposedChanges: string): number {\n // Check for dangerous patterns\n const dangerousPatterns = [\n /eval\\s*\\(/,\n /exec\\s*\\(/,\n /rm\\s+-rf/,\n /DROP\\s+TABLE/i,\n /DELETE\\s+FROM/i,\n /<script>/i,\n /document\\.write/,\n /innerHTML\\s*=/,\n ];\n\n const hasDangerousPattern = dangerousPatterns.some((pattern) =>\n pattern.test(proposedChanges)\n );\n\n return hasDangerousPattern ? 0.3 : 0.9 + Math.random() * 0.1;\n }\n\n private evaluateCompleteness(\n proposedChanges: string,\n context: LLMJudgeContext\n ): number {\n // Check if the solution seems complete\n const hasImplementation = proposedChanges.length > 100;\n const hasStructure =\n proposedChanges.includes('function') ||\n proposedChanges.includes('class') ||\n proposedChanges.includes('const') ||\n proposedChanges.includes('def');\n\n if (context.acceptanceCriteria) {\n const addressedCriteria = context.acceptanceCriteria.filter((criterion) =>\n proposedChanges\n .toLowerCase()\n .includes(criterion.toLowerCase().split(' ')[0])\n ).length;\n return addressedCriteria / context.acceptanceCriteria.length;\n }\n\n return hasImplementation && hasStructure ? 0.8 + Math.random() * 0.15 : 0.4;\n }\n\n private evaluateSemanticCorrectness(\n proposedChanges: string,\n context: LLMJudgeContext\n ): number {\n // Simulate semantic analysis\n // In production, this would use embeddings and semantic similarity\n\n // Check if previous feedback was addressed\n if (context.previousFeedback && context.previousFeedback.length > 0) {\n const addressedFeedback = context.previousFeedback.filter((feedback) => {\n const keywords = feedback\n .toLowerCase()\n .split(' ')\n .filter((w) => w.length > 4);\n return keywords.some((keyword) =>\n proposedChanges.toLowerCase().includes(keyword)\n );\n }).length;\n\n if (addressedFeedback > 0) {\n return Math.min(\n 1,\n 0.7 + (addressedFeedback / context.previousFeedback.length) * 0.3\n );\n }\n }\n\n // Default semantic score (realistic distribution)\n return 0.65 + Math.random() * 0.25;\n }\n\n private checkCriterion(criterion: string, proposedChanges: string): boolean {\n // Simple keyword matching for criteria\n const keywords = criterion\n .toLowerCase()\n .split(' ')\n .filter((word) => word.length > 3);\n const matchedKeywords = keywords.filter((keyword) =>\n proposedChanges.toLowerCase().includes(keyword)\n );\n return matchedKeywords.length >= keywords.length * 0.5;\n }\n\n private calculateOverallScore(criteria: JudgementCriteria): number {\n let score = 0;\n for (const [key, weight] of Object.entries(this.CRITERIA_WEIGHTS)) {\n score += criteria[key as keyof JudgementCriteria] * weight;\n }\n return score;\n }\n\n private createJudgementResult(\n criteria: JudgementCriteria,\n context: LLMJudgeContext\n ): VerifierResult {\n const overallScore = this.calculateOverallScore(criteria);\n const passed = overallScore >= this.VETO_THRESHOLD;\n\n // Generate detailed feedback\n const feedback = this.generateJudgementFeedback(\n criteria,\n overallScore,\n context\n );\n\n // Determine severity based on score\n const severity =\n overallScore < 0.5\n ? 'error'\n : overallScore < this.VETO_THRESHOLD\n ? 'warning'\n : 'info';\n\n return this.createResult(\n passed,\n feedback,\n severity,\n {\n expected: 'Changes that fully address the original requirements',\n actual: `Score: ${(overallScore * 100).toFixed(1)}%`,\n suggestion: this.generateSuggestions(criteria),\n },\n passed\n ? undefined\n : {\n command: 'Review and adjust approach based on feedback',\n description: 'Manual review required',\n safe: false,\n confidence: overallScore,\n }\n );\n }\n\n private generateJudgementFeedback(\n criteria: JudgementCriteria,\n overallScore: number,\n context: LLMJudgeContext\n ): string {\n if (overallScore >= this.VETO_THRESHOLD) {\n return (\n `Semantic validation PASSED (${(overallScore * 100).toFixed(1)}% confidence). ` +\n `Changes adequately address the requirements.`\n );\n }\n\n // Identify weakest areas\n const weakAreas: string[] = [];\n if (criteria.adherenceToRequirements < 0.6) {\n weakAreas.push('requirements adherence');\n }\n if (criteria.codeQuality < 0.6) {\n weakAreas.push('code quality');\n }\n if (criteria.safety < 0.7) {\n weakAreas.push('safety concerns');\n }\n if (criteria.completeness < 0.6) {\n weakAreas.push('completeness');\n }\n if (criteria.semanticCorrectness < 0.6) {\n weakAreas.push('semantic correctness');\n }\n\n return (\n `Semantic validation VETOED (${(overallScore * 100).toFixed(1)}% confidence). ` +\n `Issues found with: ${weakAreas.join(', ')}. ` +\n `Agent should course-correct based on this feedback.`\n );\n }\n\n private generateSuggestions(criteria: JudgementCriteria): string {\n const suggestions: string[] = [];\n\n if (criteria.adherenceToRequirements < 0.7) {\n suggestions.push(\n 'Review original requirements and ensure all are addressed'\n );\n }\n if (criteria.codeQuality < 0.7) {\n suggestions.push(\n 'Improve code structure, add error handling and comments'\n );\n }\n if (criteria.safety < 0.8) {\n suggestions.push(\n 'Review code for security vulnerabilities and unsafe patterns'\n );\n }\n if (criteria.completeness < 0.7) {\n suggestions.push('Ensure solution is complete and handles edge cases');\n }\n if (criteria.semanticCorrectness < 0.7) {\n suggestions.push('Verify logic correctness and alignment with intent');\n }\n\n return suggestions.length > 0\n ? suggestions.join('; ')\n : 'Continue with current approach';\n }\n\n /**\n * Get veto statistics (for monitoring)\n */\n getVetoRate(): number {\n // In production, this would track actual veto rate\n // Spotify reports ~25% veto rate\n return 0.25;\n }\n\n /**\n * Check if agent can course-correct after veto\n * Spotify: \"When vetoed, agents can course correct half the time\"\n */\n canCourseCorrect(previousAttempts: number): boolean {\n // 50% chance of successful course correction\n return previousAttempts < 2 && Math.random() > 0.5;\n }\n}\n"],
|
|
5
|
-
"mappings": "AAKA;AAAA,EACE;AAAA,OAIK;AACP,SAAS,cAAc;AAiBhB,MAAM,iBAAiB,aAAa;AAAA;AAAA,EAExB,iBAAiB;AAAA,EACjB,mBAAmB;AAAA,IAClC,yBAAyB;AAAA,IACzB,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,cAAc;AAAA,IACd,qBAAqB;AAAA,EACvB;AAAA,EAEA,YAAY,QAAkC;AAC5C,UAAM;AAAA,MACJ,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,aAAa;AAAA;AAAA,MACb,SAAS;AAAA,MACT,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA,EAEA,eAAe,SAAmC;AAEhD,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,OACJ,OACA,SACyB;AACzB,UAAM,aAAa;AAEnB,QAAI,CAAC,WAAW,gBAAgB;AAC9B,aAAO,KAAK;AAAA,QACV;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,QAAI;AACF,aAAO,MAAM,KAAK,YAAY,YAAY;AACxC,cAAM,YAAY,MAAM,KAAK;AAAA,UAC3B,MAAM,SAAS;AAAA,UACf;AAAA,QACF;AACA,eAAO,KAAK,sBAAsB,WAAW,UAAU;AAAA,MACzD,CAAC;AAAA,IACH,SAAS,
|
|
4
|
+
"sourcesContent": ["/**\n * LLM Judge - Semantic validation using LLM\n * Implements Spotify's LLM judge pattern that \"vetoes about a quarter of agent sessions\"\n */\n\nimport {\n BaseVerifier,\n VerifierContext,\n VerifierResult,\n VerifierConfig,\n} from './base-verifier.js';\nimport { logger } from '../../core/monitoring/logger.js';\n\nexport interface LLMJudgeContext extends VerifierContext {\n originalPrompt: string;\n proposedChanges: string;\n acceptanceCriteria?: string[];\n previousFeedback?: string[];\n}\n\nexport interface JudgementCriteria {\n adherenceToRequirements: number; // 0-1\n codeQuality: number; // 0-1\n safety: number; // 0-1\n completeness: number; // 0-1\n semanticCorrectness: number; // 0-1\n}\n\nexport class LLMJudge extends BaseVerifier {\n // Spotify reports ~75% pass rate (25% veto rate)\n private readonly VETO_THRESHOLD = 0.7;\n private readonly CRITERIA_WEIGHTS = {\n adherenceToRequirements: 0.3,\n codeQuality: 0.2,\n safety: 0.2,\n completeness: 0.15,\n semanticCorrectness: 0.15,\n };\n\n constructor(config?: Partial<VerifierConfig>) {\n super({\n id: 'llm-judge',\n name: 'LLM Semantic Judge',\n type: 'semantic',\n enabled: true,\n stopOnError: true, // Stop on semantic failures (Spotify pattern)\n timeout: 30000,\n ...config,\n });\n }\n\n shouldActivate(context: VerifierContext): boolean {\n // Always activate for semantic validation (Spotify always includes this)\n return true;\n }\n\n async verify(\n input: string | Buffer,\n context: VerifierContext\n ): Promise<VerifierResult> {\n const llmContext = context as LLMJudgeContext;\n\n if (!llmContext.originalPrompt) {\n return this.createResult(\n false,\n 'Missing original prompt for semantic validation',\n 'error'\n );\n }\n\n try {\n return await this.withTimeout(async () => {\n const judgement = await this.performJudgement(\n input.toString(),\n llmContext\n );\n return this.createJudgementResult(judgement, llmContext);\n });\n } catch (error: unknown) {\n logger.error(\n 'LLM Judge failed',\n error instanceof Error ? error : undefined\n );\n return this.createResult(\n false,\n `Semantic validation error: ${error instanceof Error ? error.message : String(error)}`,\n 'error'\n );\n }\n }\n\n private async performJudgement(\n proposedChanges: string,\n context: LLMJudgeContext\n ): Promise<JudgementCriteria> {\n // In production, this would call an actual LLM API\n // For now, simulate judgement with realistic patterns\n\n const criteria: JudgementCriteria = {\n adherenceToRequirements: this.evaluateAdherence(proposedChanges, context),\n codeQuality: this.evaluateCodeQuality(proposedChanges),\n safety: this.evaluateSafety(proposedChanges),\n completeness: this.evaluateCompleteness(proposedChanges, context),\n semanticCorrectness: this.evaluateSemanticCorrectness(\n proposedChanges,\n context\n ),\n };\n\n // Log judgement for analysis (Spotify's trace collection)\n logger.info('LLM Judge evaluation', {\n criteria,\n overallScore: this.calculateOverallScore(criteria),\n willVeto: this.calculateOverallScore(criteria) < this.VETO_THRESHOLD,\n });\n\n return criteria;\n }\n\n private evaluateAdherence(\n proposedChanges: string,\n context: LLMJudgeContext\n ): number {\n // Simulate checking if changes match original requirements\n const hasKeywords = context.originalPrompt\n .toLowerCase()\n .split(' ')\n .filter((word) => word.length > 4)\n .some((keyword) => proposedChanges.toLowerCase().includes(keyword));\n\n // Check acceptance criteria if provided\n if (context.acceptanceCriteria) {\n const metCriteria = context.acceptanceCriteria.filter((criterion) =>\n this.checkCriterion(criterion, proposedChanges)\n ).length;\n const criteriaScore = metCriteria / context.acceptanceCriteria.length;\n return hasKeywords ? Math.min(1, criteriaScore + 0.2) : criteriaScore;\n }\n\n // Simulate realistic pass rate (~75%)\n return hasKeywords ? 0.75 + Math.random() * 0.2 : 0.4 + Math.random() * 0.3;\n }\n\n private evaluateCodeQuality(proposedChanges: string): number {\n // Simple heuristics for code quality\n const indicators = {\n hasComments:\n proposedChanges.includes('//') || proposedChanges.includes('/*'),\n hasErrorHandling:\n proposedChanges.includes('try') || proposedChanges.includes('catch'),\n hasTests:\n proposedChanges.includes('test') || proposedChanges.includes('expect'),\n properNaming: !/[a-z]{20,}|[A-Z]{10,}/.test(proposedChanges), // No extremely long names\n reasonable_length:\n proposedChanges.length > 50 && proposedChanges.length < 5000,\n };\n\n const score =\n Object.values(indicators).filter(Boolean).length /\n Object.keys(indicators).length;\n return Math.min(1, score + 0.2); // Boost slightly\n }\n\n private evaluateSafety(proposedChanges: string): number {\n // Check for dangerous patterns\n const dangerousPatterns = [\n /eval\\s*\\(/,\n /exec\\s*\\(/,\n /rm\\s+-rf/,\n /DROP\\s+TABLE/i,\n /DELETE\\s+FROM/i,\n /<script>/i,\n /document\\.write/,\n /innerHTML\\s*=/,\n ];\n\n const hasDangerousPattern = dangerousPatterns.some((pattern) =>\n pattern.test(proposedChanges)\n );\n\n return hasDangerousPattern ? 0.3 : 0.9 + Math.random() * 0.1;\n }\n\n private evaluateCompleteness(\n proposedChanges: string,\n context: LLMJudgeContext\n ): number {\n // Check if the solution seems complete\n const hasImplementation = proposedChanges.length > 100;\n const hasStructure =\n proposedChanges.includes('function') ||\n proposedChanges.includes('class') ||\n proposedChanges.includes('const') ||\n proposedChanges.includes('def');\n\n if (context.acceptanceCriteria) {\n const addressedCriteria = context.acceptanceCriteria.filter((criterion) =>\n proposedChanges\n .toLowerCase()\n .includes(criterion.toLowerCase().split(' ')[0])\n ).length;\n return addressedCriteria / context.acceptanceCriteria.length;\n }\n\n return hasImplementation && hasStructure ? 0.8 + Math.random() * 0.15 : 0.4;\n }\n\n private evaluateSemanticCorrectness(\n proposedChanges: string,\n context: LLMJudgeContext\n ): number {\n // Simulate semantic analysis\n // In production, this would use embeddings and semantic similarity\n\n // Check if previous feedback was addressed\n if (context.previousFeedback && context.previousFeedback.length > 0) {\n const addressedFeedback = context.previousFeedback.filter((feedback) => {\n const keywords = feedback\n .toLowerCase()\n .split(' ')\n .filter((w) => w.length > 4);\n return keywords.some((keyword) =>\n proposedChanges.toLowerCase().includes(keyword)\n );\n }).length;\n\n if (addressedFeedback > 0) {\n return Math.min(\n 1,\n 0.7 + (addressedFeedback / context.previousFeedback.length) * 0.3\n );\n }\n }\n\n // Default semantic score (realistic distribution)\n return 0.65 + Math.random() * 0.25;\n }\n\n private checkCriterion(criterion: string, proposedChanges: string): boolean {\n // Simple keyword matching for criteria\n const keywords = criterion\n .toLowerCase()\n .split(' ')\n .filter((word) => word.length > 3);\n const matchedKeywords = keywords.filter((keyword) =>\n proposedChanges.toLowerCase().includes(keyword)\n );\n return matchedKeywords.length >= keywords.length * 0.5;\n }\n\n private calculateOverallScore(criteria: JudgementCriteria): number {\n let score = 0;\n for (const [key, weight] of Object.entries(this.CRITERIA_WEIGHTS)) {\n score += criteria[key as keyof JudgementCriteria] * weight;\n }\n return score;\n }\n\n private createJudgementResult(\n criteria: JudgementCriteria,\n context: LLMJudgeContext\n ): VerifierResult {\n const overallScore = this.calculateOverallScore(criteria);\n const passed = overallScore >= this.VETO_THRESHOLD;\n\n // Generate detailed feedback\n const feedback = this.generateJudgementFeedback(\n criteria,\n overallScore,\n context\n );\n\n // Determine severity based on score\n const severity =\n overallScore < 0.5\n ? 'error'\n : overallScore < this.VETO_THRESHOLD\n ? 'warning'\n : 'info';\n\n return this.createResult(\n passed,\n feedback,\n severity,\n {\n expected: 'Changes that fully address the original requirements',\n actual: `Score: ${(overallScore * 100).toFixed(1)}%`,\n suggestion: this.generateSuggestions(criteria),\n },\n passed\n ? undefined\n : {\n command: 'Review and adjust approach based on feedback',\n description: 'Manual review required',\n safe: false,\n confidence: overallScore,\n }\n );\n }\n\n private generateJudgementFeedback(\n criteria: JudgementCriteria,\n overallScore: number,\n context: LLMJudgeContext\n ): string {\n if (overallScore >= this.VETO_THRESHOLD) {\n return (\n `Semantic validation PASSED (${(overallScore * 100).toFixed(1)}% confidence). ` +\n `Changes adequately address the requirements.`\n );\n }\n\n // Identify weakest areas\n const weakAreas: string[] = [];\n if (criteria.adherenceToRequirements < 0.6) {\n weakAreas.push('requirements adherence');\n }\n if (criteria.codeQuality < 0.6) {\n weakAreas.push('code quality');\n }\n if (criteria.safety < 0.7) {\n weakAreas.push('safety concerns');\n }\n if (criteria.completeness < 0.6) {\n weakAreas.push('completeness');\n }\n if (criteria.semanticCorrectness < 0.6) {\n weakAreas.push('semantic correctness');\n }\n\n return (\n `Semantic validation VETOED (${(overallScore * 100).toFixed(1)}% confidence). ` +\n `Issues found with: ${weakAreas.join(', ')}. ` +\n `Agent should course-correct based on this feedback.`\n );\n }\n\n private generateSuggestions(criteria: JudgementCriteria): string {\n const suggestions: string[] = [];\n\n if (criteria.adherenceToRequirements < 0.7) {\n suggestions.push(\n 'Review original requirements and ensure all are addressed'\n );\n }\n if (criteria.codeQuality < 0.7) {\n suggestions.push(\n 'Improve code structure, add error handling and comments'\n );\n }\n if (criteria.safety < 0.8) {\n suggestions.push(\n 'Review code for security vulnerabilities and unsafe patterns'\n );\n }\n if (criteria.completeness < 0.7) {\n suggestions.push('Ensure solution is complete and handles edge cases');\n }\n if (criteria.semanticCorrectness < 0.7) {\n suggestions.push('Verify logic correctness and alignment with intent');\n }\n\n return suggestions.length > 0\n ? suggestions.join('; ')\n : 'Continue with current approach';\n }\n\n /**\n * Get veto statistics (for monitoring)\n */\n getVetoRate(): number {\n // In production, this would track actual veto rate\n // Spotify reports ~25% veto rate\n return 0.25;\n }\n\n /**\n * Check if agent can course-correct after veto\n * Spotify: \"When vetoed, agents can course correct half the time\"\n */\n canCourseCorrect(previousAttempts: number): boolean {\n // 50% chance of successful course correction\n return previousAttempts < 2 && Math.random() > 0.5;\n }\n}\n"],
|
|
5
|
+
"mappings": "AAKA;AAAA,EACE;AAAA,OAIK;AACP,SAAS,cAAc;AAiBhB,MAAM,iBAAiB,aAAa;AAAA;AAAA,EAExB,iBAAiB;AAAA,EACjB,mBAAmB;AAAA,IAClC,yBAAyB;AAAA,IACzB,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,cAAc;AAAA,IACd,qBAAqB;AAAA,EACvB;AAAA,EAEA,YAAY,QAAkC;AAC5C,UAAM;AAAA,MACJ,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,aAAa;AAAA;AAAA,MACb,SAAS;AAAA,MACT,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA,EAEA,eAAe,SAAmC;AAEhD,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,OACJ,OACA,SACyB;AACzB,UAAM,aAAa;AAEnB,QAAI,CAAC,WAAW,gBAAgB;AAC9B,aAAO,KAAK;AAAA,QACV;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,QAAI;AACF,aAAO,MAAM,KAAK,YAAY,YAAY;AACxC,cAAM,YAAY,MAAM,KAAK;AAAA,UAC3B,MAAM,SAAS;AAAA,UACf;AAAA,QACF;AACA,eAAO,KAAK,sBAAsB,WAAW,UAAU;AAAA,MACzD,CAAC;AAAA,IACH,SAAS,OAAgB;AACvB,aAAO;AAAA,QACL;AAAA,QACA,iBAAiB,QAAQ,QAAQ;AAAA,MACnC;AACA,aAAO,KAAK;AAAA,QACV;AAAA,QACA,8BAA8B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,QACpF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,iBACZ,iBACA,SAC4B;AAI5B,UAAM,WAA8B;AAAA,MAClC,yBAAyB,KAAK,kBAAkB,iBAAiB,OAAO;AAAA,MACxE,aAAa,KAAK,oBAAoB,eAAe;AAAA,MACrD,QAAQ,KAAK,eAAe,eAAe;AAAA,MAC3C,cAAc,KAAK,qBAAqB,iBAAiB,OAAO;AAAA,MAChE,qBAAqB,KAAK;AAAA,QACxB;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAGA,WAAO,KAAK,wBAAwB;AAAA,MAClC;AAAA,MACA,cAAc,KAAK,sBAAsB,QAAQ;AAAA,MACjD,UAAU,KAAK,sBAAsB,QAAQ,IAAI,KAAK;AAAA,IACxD,CAAC;AAED,WAAO;AAAA,EACT;AAAA,EAEQ,kBACN,iBACA,SACQ;AAER,UAAM,cAAc,QAAQ,eACzB,YAAY,EACZ,MAAM,GAAG,EACT,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC,EAChC,KAAK,CAAC,YAAY,gBAAgB,YAAY,EAAE,SAAS,OAAO,CAAC;AAGpE,QAAI,QAAQ,oBAAoB;AAC9B,YAAM,cAAc,QAAQ,mBAAmB;AAAA,QAAO,CAAC,cACrD,KAAK,eAAe,WAAW,eAAe;AAAA,MAChD,EAAE;AACF,YAAM,gBAAgB,cAAc,QAAQ,mBAAmB;AAC/D,aAAO,cAAc,KAAK,IAAI,GAAG,gBAAgB,GAAG,IAAI;AAAA,IAC1D;AAGA,WAAO,cAAc,OAAO,KAAK,OAAO,IAAI,MAAM,MAAM,KAAK,OAAO,IAAI;AAAA,EAC1E;AAAA,EAEQ,oBAAoB,iBAAiC;AAE3D,UAAM,aAAa;AAAA,MACjB,aACE,gBAAgB,SAAS,IAAI,KAAK,gBAAgB,SAAS,IAAI;AAAA,MACjE,kBACE,gBAAgB,SAAS,KAAK,KAAK,gBAAgB,SAAS,OAAO;AAAA,MACrE,UACE,gBAAgB,SAAS,MAAM,KAAK,gBAAgB,SAAS,QAAQ;AAAA,MACvE,cAAc,CAAC,wBAAwB,KAAK,eAAe;AAAA;AAAA,MAC3D,mBACE,gBAAgB,SAAS,MAAM,gBAAgB,SAAS;AAAA,IAC5D;AAEA,UAAM,QACJ,OAAO,OAAO,UAAU,EAAE,OAAO,OAAO,EAAE,SAC1C,OAAO,KAAK,UAAU,EAAE;AAC1B,WAAO,KAAK,IAAI,GAAG,QAAQ,GAAG;AAAA,EAChC;AAAA,EAEQ,eAAe,iBAAiC;AAEtD,UAAM,oBAAoB;AAAA,MACxB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,UAAM,sBAAsB,kBAAkB;AAAA,MAAK,CAAC,YAClD,QAAQ,KAAK,eAAe;AAAA,IAC9B;AAEA,WAAO,sBAAsB,MAAM,MAAM,KAAK,OAAO,IAAI;AAAA,EAC3D;AAAA,EAEQ,qBACN,iBACA,SACQ;AAER,UAAM,oBAAoB,gBAAgB,SAAS;AACnD,UAAM,eACJ,gBAAgB,SAAS,UAAU,KACnC,gBAAgB,SAAS,OAAO,KAChC,gBAAgB,SAAS,OAAO,KAChC,gBAAgB,SAAS,KAAK;AAEhC,QAAI,QAAQ,oBAAoB;AAC9B,YAAM,oBAAoB,QAAQ,mBAAmB;AAAA,QAAO,CAAC,cAC3D,gBACG,YAAY,EACZ,SAAS,UAAU,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC,CAAC;AAAA,MACnD,EAAE;AACF,aAAO,oBAAoB,QAAQ,mBAAmB;AAAA,IACxD;AAEA,WAAO,qBAAqB,eAAe,MAAM,KAAK,OAAO,IAAI,OAAO;AAAA,EAC1E;AAAA,EAEQ,4BACN,iBACA,SACQ;AAKR,QAAI,QAAQ,oBAAoB,QAAQ,iBAAiB,SAAS,GAAG;AACnE,YAAM,oBAAoB,QAAQ,iBAAiB,OAAO,CAAC,aAAa;AACtE,cAAM,WAAW,SACd,YAAY,EACZ,MAAM,GAAG,EACT,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC;AAC7B,eAAO,SAAS;AAAA,UAAK,CAAC,YACpB,gBAAgB,YAAY,EAAE,SAAS,OAAO;AAAA,QAChD;AAAA,MACF,CAAC,EAAE;AAEH,UAAI,oBAAoB,GAAG;AACzB,eAAO,KAAK;AAAA,UACV;AAAA,UACA,MAAO,oBAAoB,QAAQ,iBAAiB,SAAU;AAAA,QAChE;AAAA,MACF;AAAA,IACF;AAGA,WAAO,OAAO,KAAK,OAAO,IAAI;AAAA,EAChC;AAAA,EAEQ,eAAe,WAAmB,iBAAkC;AAE1E,UAAM,WAAW,UACd,YAAY,EACZ,MAAM,GAAG,EACT,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC;AACnC,UAAM,kBAAkB,SAAS;AAAA,MAAO,CAAC,YACvC,gBAAgB,YAAY,EAAE,SAAS,OAAO;AAAA,IAChD;AACA,WAAO,gBAAgB,UAAU,SAAS,SAAS;AAAA,EACrD;AAAA,EAEQ,sBAAsB,UAAqC;AACjE,QAAI,QAAQ;AACZ,eAAW,CAAC,KAAK,MAAM,KAAK,OAAO,QAAQ,KAAK,gBAAgB,GAAG;AACjE,eAAS,SAAS,GAA8B,IAAI;AAAA,IACtD;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,sBACN,UACA,SACgB;AAChB,UAAM,eAAe,KAAK,sBAAsB,QAAQ;AACxD,UAAM,SAAS,gBAAgB,KAAK;AAGpC,UAAM,WAAW,KAAK;AAAA,MACpB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAGA,UAAM,WACJ,eAAe,MACX,UACA,eAAe,KAAK,iBAClB,YACA;AAER,WAAO,KAAK;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,QACE,UAAU;AAAA,QACV,QAAQ,WAAW,eAAe,KAAK,QAAQ,CAAC,CAAC;AAAA,QACjD,YAAY,KAAK,oBAAoB,QAAQ;AAAA,MAC/C;AAAA,MACA,SACI,SACA;AAAA,QACE,SAAS;AAAA,QACT,aAAa;AAAA,QACb,MAAM;AAAA,QACN,YAAY;AAAA,MACd;AAAA,IACN;AAAA,EACF;AAAA,EAEQ,0BACN,UACA,cACA,SACQ;AACR,QAAI,gBAAgB,KAAK,gBAAgB;AACvC,aACE,gCAAgC,eAAe,KAAK,QAAQ,CAAC,CAAC;AAAA,IAGlE;AAGA,UAAM,YAAsB,CAAC;AAC7B,QAAI,SAAS,0BAA0B,KAAK;AAC1C,gBAAU,KAAK,wBAAwB;AAAA,IACzC;AACA,QAAI,SAAS,cAAc,KAAK;AAC9B,gBAAU,KAAK,cAAc;AAAA,IAC/B;AACA,QAAI,SAAS,SAAS,KAAK;AACzB,gBAAU,KAAK,iBAAiB;AAAA,IAClC;AACA,QAAI,SAAS,eAAe,KAAK;AAC/B,gBAAU,KAAK,cAAc;AAAA,IAC/B;AACA,QAAI,SAAS,sBAAsB,KAAK;AACtC,gBAAU,KAAK,sBAAsB;AAAA,IACvC;AAEA,WACE,gCAAgC,eAAe,KAAK,QAAQ,CAAC,CAAC,qCACxC,UAAU,KAAK,IAAI,CAAC;AAAA,EAG9C;AAAA,EAEQ,oBAAoB,UAAqC;AAC/D,UAAM,cAAwB,CAAC;AAE/B,QAAI,SAAS,0BAA0B,KAAK;AAC1C,kBAAY;AAAA,QACV;AAAA,MACF;AAAA,IACF;AACA,QAAI,SAAS,cAAc,KAAK;AAC9B,kBAAY;AAAA,QACV;AAAA,MACF;AAAA,IACF;AACA,QAAI,SAAS,SAAS,KAAK;AACzB,kBAAY;AAAA,QACV;AAAA,MACF;AAAA,IACF;AACA,QAAI,SAAS,eAAe,KAAK;AAC/B,kBAAY,KAAK,oDAAoD;AAAA,IACvE;AACA,QAAI,SAAS,sBAAsB,KAAK;AACtC,kBAAY,KAAK,oDAAoD;AAAA,IACvE;AAEA,WAAO,YAAY,SAAS,IACxB,YAAY,KAAK,IAAI,IACrB;AAAA,EACN;AAAA;AAAA;AAAA;AAAA,EAKA,cAAsB;AAGpB,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,iBAAiB,kBAAmC;AAElD,WAAO,mBAAmB,KAAK,KAAK,OAAO,IAAI;AAAA,EACjD;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/cli/claude-sm.js
CHANGED
|
@@ -241,19 +241,19 @@ class ClaudeSM {
|
|
|
241
241
|
i++;
|
|
242
242
|
}
|
|
243
243
|
if (this.config.tracingEnabled) {
|
|
244
|
-
process.env
|
|
245
|
-
process.env
|
|
246
|
-
process.env
|
|
247
|
-
process.env
|
|
244
|
+
process.env["DEBUG_TRACE"] = "true";
|
|
245
|
+
process.env["STACKMEMORY_DEBUG"] = "true";
|
|
246
|
+
process.env["TRACE_OUTPUT"] = "file";
|
|
247
|
+
process.env["TRACE_MASK_SENSITIVE"] = "true";
|
|
248
248
|
if (this.config.verboseTracing) {
|
|
249
|
-
process.env
|
|
250
|
-
process.env
|
|
251
|
-
process.env
|
|
252
|
-
process.env
|
|
249
|
+
process.env["TRACE_VERBOSITY"] = "full";
|
|
250
|
+
process.env["TRACE_PARAMS"] = "true";
|
|
251
|
+
process.env["TRACE_RESULTS"] = "true";
|
|
252
|
+
process.env["TRACE_MEMORY"] = "true";
|
|
253
253
|
} else {
|
|
254
|
-
process.env
|
|
255
|
-
process.env
|
|
256
|
-
process.env
|
|
254
|
+
process.env["TRACE_VERBOSITY"] = "summary";
|
|
255
|
+
process.env["TRACE_PARAMS"] = "true";
|
|
256
|
+
process.env["TRACE_RESULTS"] = "false";
|
|
257
257
|
}
|
|
258
258
|
initializeTracing();
|
|
259
259
|
trace.command(
|
|
@@ -292,9 +292,9 @@ class ClaudeSM {
|
|
|
292
292
|
}
|
|
293
293
|
}
|
|
294
294
|
this.loadContext();
|
|
295
|
-
process.env
|
|
295
|
+
process.env["CLAUDE_INSTANCE_ID"] = this.config.instanceId;
|
|
296
296
|
if (this.config.worktreePath) {
|
|
297
|
-
process.env
|
|
297
|
+
process.env["CLAUDE_WORKTREE_PATH"] = this.config.worktreePath;
|
|
298
298
|
}
|
|
299
299
|
console.log(chalk.gray(`\u{1F916} Instance ID: ${this.config.instanceId}`));
|
|
300
300
|
console.log(chalk.gray(`\u{1F4C1} Working in: ${process.cwd()}`));
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/cli/claude-sm.ts"],
|
|
4
|
-
"sourcesContent": ["#!/usr/bin/env node\n\n/**\n * claude-sm: Claude wrapper with StackMemory and worktree integration\n * Automatically manages context persistence and instance isolation\n */\n\nimport { spawn, execSync } from 'child_process';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as os from 'os';\nimport { program } from 'commander';\nimport { v4 as uuidv4 } from 'uuid';\nimport chalk from 'chalk';\nimport { initializeTracing, trace } from '../core/trace/index.js';\n\ninterface ClaudeConfig {\n instanceId: string;\n worktreePath?: string;\n useSandbox: boolean;\n useChrome: boolean;\n useWorktree: boolean;\n contextEnabled: boolean;\n branch?: string;\n task?: string;\n tracingEnabled: boolean;\n verboseTracing: boolean;\n}\n\nclass ClaudeSM {\n private config: ClaudeConfig;\n private stackmemoryPath: string;\n private worktreeScriptPath: string;\n private claudeConfigDir: string;\n\n constructor() {\n this.config = {\n instanceId: this.generateInstanceId(),\n useSandbox: false,\n useChrome: false,\n useWorktree: false,\n contextEnabled: true,\n tracingEnabled: true, // Enable tracing by default for claude-sm\n verboseTracing: false,\n };\n\n this.stackmemoryPath = this.findStackMemory();\n this.worktreeScriptPath = path.join(\n __dirname,\n '../../scripts/claude-worktree-manager.sh'\n );\n this.claudeConfigDir = path.join(os.homedir(), '.claude');\n\n // Ensure config directory exists\n if (!fs.existsSync(this.claudeConfigDir)) {\n fs.mkdirSync(this.claudeConfigDir, { recursive: true });\n }\n }\n\n private generateInstanceId(): string {\n return uuidv4().substring(0, 8);\n }\n\n private findStackMemory(): string {\n // Check multiple possible locations\n const possiblePaths = [\n path.join(os.homedir(), '.stackmemory', 'bin', 'stackmemory'),\n '/usr/local/bin/stackmemory',\n '/opt/homebrew/bin/stackmemory',\n 'stackmemory', // Rely on PATH\n ];\n\n for (const smPath of possiblePaths) {\n try {\n execSync(`which ${smPath}`, { stdio: 'ignore' });\n return smPath;\n } catch {\n // Continue searching\n }\n }\n\n return 'stackmemory'; // Fallback to PATH\n }\n\n private isGitRepo(): boolean {\n try {\n execSync('git rev-parse --git-dir', { stdio: 'ignore' });\n return true;\n } catch {\n return false;\n }\n }\n\n private getCurrentBranch(): string {\n try {\n return execSync('git rev-parse --abbrev-ref HEAD', {\n encoding: 'utf8',\n }).trim();\n } catch {\n return 'main';\n }\n }\n\n private hasUncommittedChanges(): boolean {\n try {\n const status = execSync('git status --porcelain', { encoding: 'utf8' });\n return status.length > 0;\n } catch {\n return false;\n }\n }\n\n private setupWorktree(): string | null {\n if (!this.config.useWorktree || !this.isGitRepo()) {\n return null;\n }\n\n console.log(chalk.blue('\uD83C\uDF33 Setting up isolated worktree...'));\n\n const timestamp = new Date()\n .toISOString()\n .replace(/[:.]/g, '-')\n .substring(0, 19);\n const branch =\n this.config.branch ||\n `claude-${this.config.task || 'work'}-${timestamp}-${this.config.instanceId}`;\n const repoName = path.basename(process.cwd());\n const worktreePath = path.join(\n path.dirname(process.cwd()),\n `${repoName}--${branch}`\n );\n\n try {\n // Create worktree\n const flags = [];\n if (this.config.useSandbox) flags.push('--sandbox');\n if (this.config.useChrome) flags.push('--chrome');\n\n const cmd = `git worktree add -b \"${branch}\" \"${worktreePath}\"`;\n execSync(cmd, { stdio: 'inherit' });\n\n console.log(chalk.green(`\u2705 Worktree created: ${worktreePath}`));\n console.log(chalk.gray(` Branch: ${branch}`));\n\n // Save worktree config\n const configPath = path.join(worktreePath, '.claude-instance.json');\n const configData = {\n instanceId: this.config.instanceId,\n worktreePath,\n branch,\n task: this.config.task,\n sandboxEnabled: this.config.useSandbox,\n chromeEnabled: this.config.useChrome,\n created: new Date().toISOString(),\n parentRepo: process.cwd(),\n };\n fs.writeFileSync(configPath, JSON.stringify(configData, null, 2));\n\n // Copy environment files\n const envFiles = ['.env', '.env.local', '.mise.toml', '.tool-versions'];\n for (const file of envFiles) {\n const srcPath = path.join(process.cwd(), file);\n if (fs.existsSync(srcPath)) {\n fs.copyFileSync(srcPath, path.join(worktreePath, file));\n }\n }\n\n return worktreePath;\n } catch (err) {\n console.error(chalk.red('\u274C Failed to create worktree:'), err);\n return null;\n }\n }\n\n private saveContext(\n message: string,\n metadata: Record<string, unknown> = {}\n ): void {\n if (!this.config.contextEnabled) return;\n\n try {\n const contextData = {\n message,\n metadata: {\n ...metadata,\n instanceId: this.config.instanceId,\n worktree: this.config.worktreePath,\n timestamp: new Date().toISOString(),\n },\n };\n\n const cmd = `${this.stackmemoryPath} context save --json '${JSON.stringify(contextData)}'`;\n execSync(cmd, { stdio: 'ignore' });\n } catch {\n // Silently fail - don't interrupt Claude\n }\n }\n\n private loadContext(): void {\n if (!this.config.contextEnabled) return;\n\n try {\n console.log(chalk.blue('\uD83D\uDCDA Loading previous context...'));\n\n const cmd = `${this.stackmemoryPath} context list --limit 5 --format json`;\n const output = execSync(cmd, { encoding: 'utf8' });\n const contexts = JSON.parse(output);\n\n if (contexts.length > 0) {\n console.log(chalk.gray('Recent context loaded:'));\n contexts.forEach(\n (ctx: { message: string; metadata?: { timestamp?: string } }) => {\n console.log(\n chalk.gray(` - ${ctx.message} (${ctx.metadata?.timestamp})`)\n );\n }\n );\n }\n } catch {\n // Silently continue\n }\n }\n\n private detectMultipleInstances(): boolean {\n try {\n const lockDir = path.join(process.cwd(), '.claude-worktree-locks');\n if (!fs.existsSync(lockDir)) return false;\n\n const locks = fs.readdirSync(lockDir).filter((f) => f.endsWith('.lock'));\n const activeLocks = locks.filter((lockFile) => {\n const lockPath = path.join(lockDir, lockFile);\n const lockData = JSON.parse(fs.readFileSync(lockPath, 'utf8'));\n const lockAge = Date.now() - new Date(lockData.created).getTime();\n return lockAge < 24 * 60 * 60 * 1000; // Less than 24 hours old\n });\n\n return activeLocks.length > 0;\n } catch {\n return false;\n }\n }\n\n private suggestWorktreeMode(): void {\n if (this.hasUncommittedChanges()) {\n console.log(chalk.yellow('\u26A0\uFE0F Uncommitted changes detected'));\n console.log(\n chalk.gray(' Consider using --worktree to work in isolation')\n );\n }\n\n if (this.detectMultipleInstances()) {\n console.log(chalk.yellow('\u26A0\uFE0F Other Claude instances detected'));\n console.log(\n chalk.gray(' Using --worktree is recommended to avoid conflicts')\n );\n }\n }\n\n public async run(args: string[]): Promise<void> {\n // Parse arguments\n const claudeArgs: string[] = [];\n let i = 0;\n\n while (i < args.length) {\n const arg = args[i];\n\n switch (arg) {\n case '--worktree':\n case '-w':\n this.config.useWorktree = true;\n break;\n case '--sandbox':\n case '-s':\n this.config.useSandbox = true;\n claudeArgs.push('--sandbox');\n break;\n case '--chrome':\n case '-c':\n this.config.useChrome = true;\n claudeArgs.push('--chrome');\n break;\n case '--no-context':\n this.config.contextEnabled = false;\n break;\n case '--no-trace':\n this.config.tracingEnabled = false;\n break;\n case '--verbose-trace':\n this.config.verboseTracing = true;\n break;\n case '--branch':\n case '-b':\n i++;\n this.config.branch = args[i];\n break;\n case '--task':\n case '-t':\n i++;\n this.config.task = args[i];\n break;\n case '--auto':\n case '-a':\n // Auto mode: detect and apply best settings\n if (this.isGitRepo()) {\n this.config.useWorktree =\n this.hasUncommittedChanges() || this.detectMultipleInstances();\n }\n break;\n default:\n claudeArgs.push(arg);\n }\n i++;\n }\n\n // Initialize tracing system if enabled\n if (this.config.tracingEnabled) {\n // Set up environment for tracing\n process.env.DEBUG_TRACE = 'true';\n process.env.STACKMEMORY_DEBUG = 'true';\n process.env.TRACE_OUTPUT = 'file'; // Write to file to not clutter Claude output\n process.env.TRACE_MASK_SENSITIVE = 'true'; // Always mask sensitive data\n\n if (this.config.verboseTracing) {\n process.env.TRACE_VERBOSITY = 'full';\n process.env.TRACE_PARAMS = 'true';\n process.env.TRACE_RESULTS = 'true';\n process.env.TRACE_MEMORY = 'true';\n } else {\n process.env.TRACE_VERBOSITY = 'summary';\n process.env.TRACE_PARAMS = 'true';\n process.env.TRACE_RESULTS = 'false';\n }\n\n // Initialize the tracing system\n initializeTracing();\n\n // Start tracing this Claude session\n trace.command(\n 'claude-sm',\n {\n instanceId: this.config.instanceId,\n worktree: this.config.useWorktree,\n sandbox: this.config.useSandbox,\n task: this.config.task,\n },\n async () => {\n // Session tracing will wrap the entire Claude execution\n }\n );\n }\n\n // Show header\n console.log(chalk.blue('\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557'));\n console.log(chalk.blue('\u2551 Claude + StackMemory + Worktree \u2551'));\n console.log(chalk.blue('\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D'));\n console.log();\n\n // Check Git repo status\n if (this.isGitRepo()) {\n const branch = this.getCurrentBranch();\n console.log(chalk.gray(`\uD83D\uDCCD Current branch: ${branch}`));\n\n if (!this.config.useWorktree) {\n this.suggestWorktreeMode();\n }\n }\n\n // Setup worktree if requested\n if (this.config.useWorktree) {\n const worktreePath = this.setupWorktree();\n if (worktreePath) {\n this.config.worktreePath = worktreePath;\n process.chdir(worktreePath);\n\n // Save context about worktree creation\n this.saveContext('Created worktree for Claude instance', {\n action: 'worktree_created',\n path: worktreePath,\n branch: this.config.branch,\n });\n }\n }\n\n // Load previous context\n this.loadContext();\n\n // Setup environment\n process.env.CLAUDE_INSTANCE_ID = this.config.instanceId;\n if (this.config.worktreePath) {\n process.env.CLAUDE_WORKTREE_PATH = this.config.worktreePath;\n }\n\n console.log(chalk.gray(`\uD83E\uDD16 Instance ID: ${this.config.instanceId}`));\n console.log(chalk.gray(`\uD83D\uDCC1 Working in: ${process.cwd()}`));\n\n if (this.config.useSandbox) {\n console.log(chalk.yellow('\uD83D\uDD12 Sandbox mode enabled'));\n }\n if (this.config.useChrome) {\n console.log(chalk.yellow('\uD83C\uDF10 Chrome automation enabled'));\n }\n if (this.config.tracingEnabled) {\n console.log(\n chalk.gray(`\uD83D\uDD0D Debug tracing enabled (logs to ~/.stackmemory/traces/)`)\n );\n if (this.config.verboseTracing) {\n console.log(\n chalk.gray(` Verbose mode: capturing all execution details`)\n );\n }\n }\n\n console.log();\n console.log(chalk.gray('Starting Claude...'));\n console.log(chalk.gray('\u2500'.repeat(42)));\n\n // Launch Claude\n const claude = spawn('claude', claudeArgs, {\n stdio: 'inherit',\n env: process.env,\n });\n\n // Handle exit\n claude.on('exit', (code) => {\n // Save final context\n this.saveContext('Claude session ended', {\n action: 'session_end',\n exitCode: code,\n });\n\n // End tracing and show summary if enabled\n if (this.config.tracingEnabled) {\n const summary = trace.getExecutionSummary();\n console.log();\n console.log(chalk.gray('\u2500'.repeat(42)));\n console.log(chalk.blue('Debug Trace Summary:'));\n console.log(chalk.gray(summary));\n }\n\n // Offer to clean up worktree\n if (this.config.worktreePath) {\n console.log();\n console.log(chalk.gray('\u2500'.repeat(42)));\n console.log(chalk.blue('Session ended in worktree:'));\n console.log(chalk.gray(` ${this.config.worktreePath}`));\n console.log();\n console.log(chalk.gray('To remove worktree: gd_claude'));\n console.log(chalk.gray('To merge to main: cwm'));\n }\n\n process.exit(code || 0);\n });\n\n // Handle signals\n process.on('SIGINT', () => {\n this.saveContext('Claude session interrupted', {\n action: 'session_interrupt',\n });\n claude.kill('SIGINT');\n });\n\n process.on('SIGTERM', () => {\n this.saveContext('Claude session terminated', {\n action: 'session_terminate',\n });\n claude.kill('SIGTERM');\n });\n }\n}\n\n// CLI interface\nprogram\n .name('claude-sm')\n .description('Claude with StackMemory context and worktree isolation')\n .version('1.0.0')\n .option('-w, --worktree', 'Create isolated worktree for this instance')\n .option('-s, --sandbox', 'Enable sandbox mode (file/network restrictions)')\n .option('-c, --chrome', 'Enable Chrome automation')\n .option('-a, --auto', 'Automatically detect and apply best settings')\n .option('-b, --branch <name>', 'Specify branch name for worktree')\n .option('-t, --task <desc>', 'Task description for context')\n .option('--no-context', 'Disable StackMemory context integration')\n .option('--no-trace', 'Disable debug tracing (enabled by default)')\n .option('--verbose-trace', 'Enable verbose debug tracing with full details')\n .helpOption('-h, --help', 'Display help')\n .allowUnknownOption(true)\n .action(async (_options) => {\n const claudeSM = new ClaudeSM();\n const args = process.argv.slice(2);\n await claudeSM.run(args);\n });\n\n// Handle direct execution\nif (require.main === module) {\n program.parse(process.argv);\n}\n"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["#!/usr/bin/env node\n\n/**\n * claude-sm: Claude wrapper with StackMemory and worktree integration\n * Automatically manages context persistence and instance isolation\n */\n\nimport { spawn, execSync } from 'child_process';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as os from 'os';\nimport { program } from 'commander';\nimport { v4 as uuidv4 } from 'uuid';\nimport chalk from 'chalk';\nimport { initializeTracing, trace } from '../core/trace/index.js';\n\ninterface ClaudeConfig {\n instanceId: string;\n worktreePath?: string;\n useSandbox: boolean;\n useChrome: boolean;\n useWorktree: boolean;\n contextEnabled: boolean;\n branch?: string;\n task?: string;\n tracingEnabled: boolean;\n verboseTracing: boolean;\n}\n\nclass ClaudeSM {\n private config: ClaudeConfig;\n private stackmemoryPath: string;\n private worktreeScriptPath: string;\n private claudeConfigDir: string;\n\n constructor() {\n this.config = {\n instanceId: this.generateInstanceId(),\n useSandbox: false,\n useChrome: false,\n useWorktree: false,\n contextEnabled: true,\n tracingEnabled: true, // Enable tracing by default for claude-sm\n verboseTracing: false,\n };\n\n this.stackmemoryPath = this.findStackMemory();\n this.worktreeScriptPath = path.join(\n __dirname,\n '../../scripts/claude-worktree-manager.sh'\n );\n this.claudeConfigDir = path.join(os.homedir(), '.claude');\n\n // Ensure config directory exists\n if (!fs.existsSync(this.claudeConfigDir)) {\n fs.mkdirSync(this.claudeConfigDir, { recursive: true });\n }\n }\n\n private generateInstanceId(): string {\n return uuidv4().substring(0, 8);\n }\n\n private findStackMemory(): string {\n // Check multiple possible locations\n const possiblePaths = [\n path.join(os.homedir(), '.stackmemory', 'bin', 'stackmemory'),\n '/usr/local/bin/stackmemory',\n '/opt/homebrew/bin/stackmemory',\n 'stackmemory', // Rely on PATH\n ];\n\n for (const smPath of possiblePaths) {\n try {\n execSync(`which ${smPath}`, { stdio: 'ignore' });\n return smPath;\n } catch {\n // Continue searching\n }\n }\n\n return 'stackmemory'; // Fallback to PATH\n }\n\n private isGitRepo(): boolean {\n try {\n execSync('git rev-parse --git-dir', { stdio: 'ignore' });\n return true;\n } catch {\n return false;\n }\n }\n\n private getCurrentBranch(): string {\n try {\n return execSync('git rev-parse --abbrev-ref HEAD', {\n encoding: 'utf8',\n }).trim();\n } catch {\n return 'main';\n }\n }\n\n private hasUncommittedChanges(): boolean {\n try {\n const status = execSync('git status --porcelain', { encoding: 'utf8' });\n return status.length > 0;\n } catch {\n return false;\n }\n }\n\n private setupWorktree(): string | null {\n if (!this.config.useWorktree || !this.isGitRepo()) {\n return null;\n }\n\n console.log(chalk.blue('\uD83C\uDF33 Setting up isolated worktree...'));\n\n const timestamp = new Date()\n .toISOString()\n .replace(/[:.]/g, '-')\n .substring(0, 19);\n const branch =\n this.config.branch ||\n `claude-${this.config.task || 'work'}-${timestamp}-${this.config.instanceId}`;\n const repoName = path.basename(process.cwd());\n const worktreePath = path.join(\n path.dirname(process.cwd()),\n `${repoName}--${branch}`\n );\n\n try {\n // Create worktree\n const flags = [];\n if (this.config.useSandbox) flags.push('--sandbox');\n if (this.config.useChrome) flags.push('--chrome');\n\n const cmd = `git worktree add -b \"${branch}\" \"${worktreePath}\"`;\n execSync(cmd, { stdio: 'inherit' });\n\n console.log(chalk.green(`\u2705 Worktree created: ${worktreePath}`));\n console.log(chalk.gray(` Branch: ${branch}`));\n\n // Save worktree config\n const configPath = path.join(worktreePath, '.claude-instance.json');\n const configData = {\n instanceId: this.config.instanceId,\n worktreePath,\n branch,\n task: this.config.task,\n sandboxEnabled: this.config.useSandbox,\n chromeEnabled: this.config.useChrome,\n created: new Date().toISOString(),\n parentRepo: process.cwd(),\n };\n fs.writeFileSync(configPath, JSON.stringify(configData, null, 2));\n\n // Copy environment files\n const envFiles = ['.env', '.env.local', '.mise.toml', '.tool-versions'];\n for (const file of envFiles) {\n const srcPath = path.join(process.cwd(), file);\n if (fs.existsSync(srcPath)) {\n fs.copyFileSync(srcPath, path.join(worktreePath, file));\n }\n }\n\n return worktreePath;\n } catch (err: unknown) {\n console.error(chalk.red('\u274C Failed to create worktree:'), err);\n return null;\n }\n }\n\n private saveContext(\n message: string,\n metadata: Record<string, unknown> = {}\n ): void {\n if (!this.config.contextEnabled) return;\n\n try {\n const contextData = {\n message,\n metadata: {\n ...metadata,\n instanceId: this.config.instanceId,\n worktree: this.config.worktreePath,\n timestamp: new Date().toISOString(),\n },\n };\n\n const cmd = `${this.stackmemoryPath} context save --json '${JSON.stringify(contextData)}'`;\n execSync(cmd, { stdio: 'ignore' });\n } catch {\n // Silently fail - don't interrupt Claude\n }\n }\n\n private loadContext(): void {\n if (!this.config.contextEnabled) return;\n\n try {\n console.log(chalk.blue('\uD83D\uDCDA Loading previous context...'));\n\n const cmd = `${this.stackmemoryPath} context list --limit 5 --format json`;\n const output = execSync(cmd, { encoding: 'utf8' });\n const contexts = JSON.parse(output);\n\n if (contexts.length > 0) {\n console.log(chalk.gray('Recent context loaded:'));\n contexts.forEach(\n (ctx: { message: string; metadata?: { timestamp?: string } }) => {\n console.log(\n chalk.gray(` - ${ctx.message} (${ctx.metadata?.timestamp})`)\n );\n }\n );\n }\n } catch {\n // Silently continue\n }\n }\n\n private detectMultipleInstances(): boolean {\n try {\n const lockDir = path.join(process.cwd(), '.claude-worktree-locks');\n if (!fs.existsSync(lockDir)) return false;\n\n const locks = fs.readdirSync(lockDir).filter((f) => f.endsWith('.lock'));\n const activeLocks = locks.filter((lockFile) => {\n const lockPath = path.join(lockDir, lockFile);\n const lockData = JSON.parse(fs.readFileSync(lockPath, 'utf8'));\n const lockAge = Date.now() - new Date(lockData.created).getTime();\n return lockAge < 24 * 60 * 60 * 1000; // Less than 24 hours old\n });\n\n return activeLocks.length > 0;\n } catch {\n return false;\n }\n }\n\n private suggestWorktreeMode(): void {\n if (this.hasUncommittedChanges()) {\n console.log(chalk.yellow('\u26A0\uFE0F Uncommitted changes detected'));\n console.log(\n chalk.gray(' Consider using --worktree to work in isolation')\n );\n }\n\n if (this.detectMultipleInstances()) {\n console.log(chalk.yellow('\u26A0\uFE0F Other Claude instances detected'));\n console.log(\n chalk.gray(' Using --worktree is recommended to avoid conflicts')\n );\n }\n }\n\n public async run(args: string[]): Promise<void> {\n // Parse arguments\n const claudeArgs: string[] = [];\n let i = 0;\n\n while (i < args.length) {\n const arg = args[i];\n\n switch (arg) {\n case '--worktree':\n case '-w':\n this.config.useWorktree = true;\n break;\n case '--sandbox':\n case '-s':\n this.config.useSandbox = true;\n claudeArgs.push('--sandbox');\n break;\n case '--chrome':\n case '-c':\n this.config.useChrome = true;\n claudeArgs.push('--chrome');\n break;\n case '--no-context':\n this.config.contextEnabled = false;\n break;\n case '--no-trace':\n this.config.tracingEnabled = false;\n break;\n case '--verbose-trace':\n this.config.verboseTracing = true;\n break;\n case '--branch':\n case '-b':\n i++;\n this.config.branch = args[i];\n break;\n case '--task':\n case '-t':\n i++;\n this.config.task = args[i];\n break;\n case '--auto':\n case '-a':\n // Auto mode: detect and apply best settings\n if (this.isGitRepo()) {\n this.config.useWorktree =\n this.hasUncommittedChanges() || this.detectMultipleInstances();\n }\n break;\n default:\n claudeArgs.push(arg);\n }\n i++;\n }\n\n // Initialize tracing system if enabled\n if (this.config.tracingEnabled) {\n // Set up environment for tracing\n process.env['DEBUG_TRACE'] = 'true';\n process.env['STACKMEMORY_DEBUG'] = 'true';\n process.env['TRACE_OUTPUT'] = 'file'; // Write to file to not clutter Claude output\n process.env['TRACE_MASK_SENSITIVE'] = 'true'; // Always mask sensitive data\n\n if (this.config.verboseTracing) {\n process.env['TRACE_VERBOSITY'] = 'full';\n process.env['TRACE_PARAMS'] = 'true';\n process.env['TRACE_RESULTS'] = 'true';\n process.env['TRACE_MEMORY'] = 'true';\n } else {\n process.env['TRACE_VERBOSITY'] = 'summary';\n process.env['TRACE_PARAMS'] = 'true';\n process.env['TRACE_RESULTS'] = 'false';\n }\n\n // Initialize the tracing system\n initializeTracing();\n\n // Start tracing this Claude session\n trace.command(\n 'claude-sm',\n {\n instanceId: this.config.instanceId,\n worktree: this.config.useWorktree,\n sandbox: this.config.useSandbox,\n task: this.config.task,\n },\n async () => {\n // Session tracing will wrap the entire Claude execution\n }\n );\n }\n\n // Show header\n console.log(chalk.blue('\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557'));\n console.log(chalk.blue('\u2551 Claude + StackMemory + Worktree \u2551'));\n console.log(chalk.blue('\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D'));\n console.log();\n\n // Check Git repo status\n if (this.isGitRepo()) {\n const branch = this.getCurrentBranch();\n console.log(chalk.gray(`\uD83D\uDCCD Current branch: ${branch}`));\n\n if (!this.config.useWorktree) {\n this.suggestWorktreeMode();\n }\n }\n\n // Setup worktree if requested\n if (this.config.useWorktree) {\n const worktreePath = this.setupWorktree();\n if (worktreePath) {\n this.config.worktreePath = worktreePath;\n process.chdir(worktreePath);\n\n // Save context about worktree creation\n this.saveContext('Created worktree for Claude instance', {\n action: 'worktree_created',\n path: worktreePath,\n branch: this.config.branch,\n });\n }\n }\n\n // Load previous context\n this.loadContext();\n\n // Setup environment\n process.env['CLAUDE_INSTANCE_ID'] = this.config.instanceId;\n if (this.config.worktreePath) {\n process.env['CLAUDE_WORKTREE_PATH'] = this.config.worktreePath;\n }\n\n console.log(chalk.gray(`\uD83E\uDD16 Instance ID: ${this.config.instanceId}`));\n console.log(chalk.gray(`\uD83D\uDCC1 Working in: ${process.cwd()}`));\n\n if (this.config.useSandbox) {\n console.log(chalk.yellow('\uD83D\uDD12 Sandbox mode enabled'));\n }\n if (this.config.useChrome) {\n console.log(chalk.yellow('\uD83C\uDF10 Chrome automation enabled'));\n }\n if (this.config.tracingEnabled) {\n console.log(\n chalk.gray(`\uD83D\uDD0D Debug tracing enabled (logs to ~/.stackmemory/traces/)`)\n );\n if (this.config.verboseTracing) {\n console.log(\n chalk.gray(` Verbose mode: capturing all execution details`)\n );\n }\n }\n\n console.log();\n console.log(chalk.gray('Starting Claude...'));\n console.log(chalk.gray('\u2500'.repeat(42)));\n\n // Launch Claude\n const claude = spawn('claude', claudeArgs, {\n stdio: 'inherit',\n env: process.env,\n });\n\n // Handle exit\n claude.on('exit', (code) => {\n // Save final context\n this.saveContext('Claude session ended', {\n action: 'session_end',\n exitCode: code,\n });\n\n // End tracing and show summary if enabled\n if (this.config.tracingEnabled) {\n const summary = trace.getExecutionSummary();\n console.log();\n console.log(chalk.gray('\u2500'.repeat(42)));\n console.log(chalk.blue('Debug Trace Summary:'));\n console.log(chalk.gray(summary));\n }\n\n // Offer to clean up worktree\n if (this.config.worktreePath) {\n console.log();\n console.log(chalk.gray('\u2500'.repeat(42)));\n console.log(chalk.blue('Session ended in worktree:'));\n console.log(chalk.gray(` ${this.config.worktreePath}`));\n console.log();\n console.log(chalk.gray('To remove worktree: gd_claude'));\n console.log(chalk.gray('To merge to main: cwm'));\n }\n\n process.exit(code || 0);\n });\n\n // Handle signals\n process.on('SIGINT', () => {\n this.saveContext('Claude session interrupted', {\n action: 'session_interrupt',\n });\n claude.kill('SIGINT');\n });\n\n process.on('SIGTERM', () => {\n this.saveContext('Claude session terminated', {\n action: 'session_terminate',\n });\n claude.kill('SIGTERM');\n });\n }\n}\n\n// CLI interface\nprogram\n .name('claude-sm')\n .description('Claude with StackMemory context and worktree isolation')\n .version('1.0.0')\n .option('-w, --worktree', 'Create isolated worktree for this instance')\n .option('-s, --sandbox', 'Enable sandbox mode (file/network restrictions)')\n .option('-c, --chrome', 'Enable Chrome automation')\n .option('-a, --auto', 'Automatically detect and apply best settings')\n .option('-b, --branch <name>', 'Specify branch name for worktree')\n .option('-t, --task <desc>', 'Task description for context')\n .option('--no-context', 'Disable StackMemory context integration')\n .option('--no-trace', 'Disable debug tracing (enabled by default)')\n .option('--verbose-trace', 'Enable verbose debug tracing with full details')\n .helpOption('-h, --help', 'Display help')\n .allowUnknownOption(true)\n .action(async (_options) => {\n const claudeSM = new ClaudeSM();\n const args = process.argv.slice(2);\n await claudeSM.run(args);\n });\n\n// Handle direct execution\nif (require.main === module) {\n program.parse(process.argv);\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|