@stackmemoryai/stackmemory 0.3.7 → 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/cli/claude-sm.js +0 -11
- package/dist/cli/claude-sm.js.map +2 -2
- package/dist/cli/codex-sm.js +0 -11
- package/dist/cli/codex-sm.js.map +2 -2
- package/dist/cli/commands/chromadb.js +64 -34
- package/dist/cli/commands/chromadb.js.map +2 -2
- package/dist/cli/commands/clear.js +9 -13
- 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.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 +69 -20
- package/dist/cli/commands/gc.js.map +2 -2
- package/dist/cli/commands/handoff.js.map +2 -2
- package/dist/cli/commands/infinite-storage.js +60 -19
- package/dist/cli/commands/infinite-storage.js.map +2 -2
- package/dist/cli/commands/linear-create.js +36 -8
- package/dist/cli/commands/linear-create.js.map +2 -2
- package/dist/cli/commands/linear-list.js +33 -10
- package/dist/cli/commands/linear-list.js.map +2 -2
- package/dist/cli/commands/linear-migrate.js +17 -4
- package/dist/cli/commands/linear-migrate.js.map +2 -2
- package/dist/cli/commands/linear-test.js +14 -6
- package/dist/cli/commands/linear-test.js.map +2 -2
- package/dist/cli/commands/linear-unified.js +123 -35
- package/dist/cli/commands/linear-unified.js.map +2 -2
- 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/session.js +23 -6
- package/dist/cli/commands/session.js.map +2 -2
- package/dist/cli/commands/skills.js +72 -27
- package/dist/cli/commands/skills.js.map +2 -2
- package/dist/cli/commands/storage.js +108 -38
- package/dist/cli/commands/storage.js.map +2 -2
- package/dist/cli/commands/tui.js.map +2 -2
- package/dist/cli/commands/webhook.js +57 -18
- package/dist/cli/commands/webhook.js.map +2 -2
- package/dist/cli/commands/workflow.js +8 -15
- 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 +0 -11
- package/dist/cli/index.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/context-bridge.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-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 +10 -3
- package/dist/core/context/incremental-gc.js.map +2 -2
- package/dist/core/context/index.js.map +1 -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 +4 -2
- package/dist/core/context/shared-context-layer.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/query-cache.js +19 -9
- package/dist/core/database/query-cache.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/monitoring/logger.js +6 -1
- package/dist/core/monitoring/logger.js.map +2 -2
- package/dist/core/monitoring/metrics.js.map +2 -2
- package/dist/core/monitoring/progress-tracker.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/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 +51 -14
- 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/projects/project-manager.js +14 -20
- package/dist/core/projects/project-manager.js.map +2 -2
- package/dist/core/retrieval/context-retriever.js.map +1 -1
- package/dist/core/retrieval/llm-context-retrieval.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/index.js.map +1 -1
- package/dist/core/session/session-manager.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 +48 -22
- package/dist/core/storage/railway-optimized-storage.js.map +2 -2
- package/dist/core/storage/remote-storage.js +41 -23
- package/dist/core/storage/remote-storage.js.map +2 -2
- package/dist/core/trace/cli-trace-wrapper.js +9 -2
- 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 +25 -8
- package/dist/core/trace/debug-trace.js.map +2 -2
- package/dist/core/trace/index.js +6 -2
- 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 +14 -10
- 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/types.js.map +1 -1
- package/dist/core/utils/compression.js.map +1 -1
- package/dist/core/utils/update-checker.js.map +1 -1
- package/dist/core/worktree/worktree-manager.js +18 -7
- package/dist/core/worktree/worktree-manager.js.map +2 -2
- 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 +1 -1
- 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 +26 -10
- package/dist/features/tui/components/task-board.js.map +2 -2
- package/dist/features/tui/index.js.map +2 -2
- package/dist/features/tui/services/data-service.js +6 -2
- 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 +3 -1
- package/dist/features/tui/services/websocket-client.js.map +2 -2
- package/dist/features/tui/terminal-compat.js +6 -2
- 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 +18 -10
- package/dist/features/web/server/index.js.map +2 -2
- package/dist/integrations/linear/sync-service.js +12 -13
- package/dist/integrations/linear/sync-service.js.map +2 -2
- package/dist/integrations/linear/sync.js +174 -12
- package/dist/integrations/linear/sync.js.map +2 -2
- package/dist/integrations/linear/unified-sync.js +1 -1
- package/dist/integrations/linear/unified-sync.js.map +1 -1
- package/dist/integrations/linear/webhook-server.js +15 -16
- package/dist/integrations/linear/webhook-server.js.map +2 -2
- package/dist/mcp/stackmemory-mcp-server.js +0 -11
- package/dist/mcp/stackmemory-mcp-server.js.map +2 -2
- package/dist/servers/production/auth-middleware.js.map +2 -2
- 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 +4 -2
- package/dist/skills/claude-skills.js.map +2 -2
- package/dist/skills/dashboard-launcher.js.map +2 -2
- package/dist/skills/repo-ingestion-skill.js.map +2 -2
- package/dist/utils/env.js +46 -0
- package/dist/utils/env.js.map +7 -0
- package/dist/utils/logger.js +0 -11
- package/dist/utils/logger.js.map +2 -2
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/core/trace/linear-api-wrapper.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Linear API Trace Wrapper\n * Wraps Linear API client with comprehensive tracing for debugging\n */\n\nimport { trace, Trace } from './debug-trace.js';\nimport { logger } from '../monitoring/logger.js';\n\n/**\n * Decorator to trace Linear API GraphQL calls\n */\nexport function TraceLinearAPI(\n target: any,\n propertyKey: string,\n descriptor: PropertyDescriptor\n) {\n const originalMethod = descriptor.value;\n const isAsync = originalMethod.constructor.name === 'AsyncFunction';\n\n if (isAsync) {\n descriptor.value = async function (...args: any[]) {\n const className = target.constructor.name;\n const methodName = `${className}.${propertyKey}`;\n
|
|
5
|
-
"mappings": "AAKA,SAAS,aAAoB;AAC7B,SAAS,cAAc;AAKhB,SAAS,eACd,QACA,aACA,YACA;AACA,QAAM,iBAAiB,WAAW;AAClC,QAAM,UAAU,eAAe,YAAY,SAAS;AAEpD,MAAI,SAAS;AACX,eAAW,QAAQ,kBAAmB,MAAa;AACjD,YAAM,YAAY,OAAO,YAAY;AACrC,YAAM,aAAa,GAAG,SAAS,IAAI,WAAW;AAG9C,YAAM,UAAU,kBAAkB,aAAa,IAAI;AAEnD,aAAO,MAAM,WAAW,OAAO,YAAY,SAAS,YAAY;AAC9D,cAAM,YAAY,KAAK,IAAI;AAE3B,YAAI;AAEF,iBAAO,MAAM,oBAAoB,UAAU,IAAI,OAAO;AAEtD,gBAAM,SAAS,MAAM,eAAe,MAAM,MAAM,IAAI;AAEpD,gBAAM,WAAW,KAAK,IAAI,IAAI;AAG9B,iBAAO,KAAK,uBAAuB,UAAU,IAAI;AAAA,YAC/C;AAAA,YACA,YAAY,MAAM,QAAQ,MAAM,
|
|
4
|
+
"sourcesContent": ["/**\n * Linear API Trace Wrapper\n * Wraps Linear API client with comprehensive tracing for debugging\n */\n\nimport { trace, Trace } from './debug-trace.js';\nimport { logger } from '../monitoring/logger.js';\n\n/**\n * Decorator to trace Linear API GraphQL calls\n */\nexport function TraceLinearAPI(\n target: any,\n propertyKey: string,\n descriptor: PropertyDescriptor\n) {\n const originalMethod = descriptor.value;\n const isAsync = originalMethod.constructor.name === 'AsyncFunction';\n\n if (isAsync) {\n descriptor.value = async function (...args: any[]) {\n const className = target.constructor.name;\n const methodName = `${className}.${propertyKey}`;\n\n // Extract meaningful context from arguments\n const context = extractAPIContext(propertyKey, args);\n\n return trace.traceAsync('api', methodName, context, async () => {\n const startTime = Date.now();\n\n try {\n // Log API call start\n logger.debug(`Linear API Call: ${methodName}`, context);\n\n const result = await originalMethod.apply(this, args);\n\n const duration = Date.now() - startTime;\n\n // Log successful completion with timing\n logger.info(`Linear API Success: ${methodName}`, {\n duration,\n resultType: Array.isArray(result)\n ? `array[${result.length}]`\n : typeof result,\n hasData: result != null,\n });\n\n // Warn about slow API calls\n if (duration > 1000) {\n logger.warn(\n `Slow Linear API call: ${methodName} took ${duration}ms`,\n {\n ...context,\n duration,\n }\n );\n }\n\n return result;\n } catch (error: any) {\n const duration = Date.now() - startTime;\n\n // Enhanced error logging for API failures\n logger.error(`Linear API Failed: ${methodName}`, error, {\n ...context,\n duration,\n errorCode: error.code,\n statusCode: error.statusCode,\n graphQLErrors: error.errors,\n });\n\n // Add debugging hints based on error type\n if (error.message?.includes('rate limit')) {\n logger.warn('Rate limit hit - consider implementing backoff', {\n method: methodName,\n suggestion: 'Implement exponential backoff or request queuing',\n });\n } else if (error.message?.includes('network')) {\n logger.warn('Network error - check connectivity', {\n method: methodName,\n suggestion: 'Verify API endpoint and network connectivity',\n });\n } else if (error.message?.includes('unauthorized')) {\n logger.warn('Authorization error - check API key', {\n method: methodName,\n suggestion: 'Verify LINEAR_API_KEY is set and valid',\n });\n }\n\n throw error;\n }\n });\n };\n } else {\n descriptor.value = function (...args: any[]) {\n const className = target.constructor.name;\n const methodName = `${className}.${propertyKey}`;\n const context = extractAPIContext(propertyKey, args);\n\n return trace.traceSync('api', methodName, context, () => {\n return originalMethod.apply(this, args);\n });\n };\n }\n\n return descriptor;\n}\n\n/**\n * Extract meaningful context from API method arguments\n */\nfunction extractAPIContext(\n methodName: string,\n args: any[]\n): Record<string, any> {\n const context: Record<string, any> = {};\n\n // Handle different Linear API methods\n if (methodName === 'createIssue' && args[0]) {\n context.title = args[0].title;\n context.teamId = args[0].teamId;\n context.priority = args[0].priority;\n } else if (methodName === 'updateIssue' && args[0]) {\n context.issueId = args[0];\n context.updates = Object.keys(args[1] || {});\n } else if (methodName === 'getIssue') {\n context.issueId = args[0];\n } else if (methodName === 'getIssues' && args[0]) {\n context.filter = args[0];\n } else if (methodName === 'graphql') {\n // For raw GraphQL queries\n const query = args[0];\n if (query) {\n // Extract operation name from query\n const match = query.match(/(?:query|mutation)\\s+(\\w+)/);\n context.operation = match ? match[1] : 'unknown';\n context.queryLength = query.length;\n context.variables = args[1] ? Object.keys(args[1]) : [];\n }\n }\n\n return context;\n}\n\n/**\n * Wrap fetch with tracing for HTTP-level debugging\n */\nexport function createTracedFetch(baseFetch = fetch): typeof fetch {\n return async function tracedFetch(\n input: string | URL | Request,\n init?: RequestInit\n ): Promise<Response> {\n const url = typeof input === 'string' ? input : input.toString();\n const method = init?.method || 'GET';\n\n // Mask sensitive headers\n const headers: any = init?.headers ? { ...init.headers } : {};\n if (headers.Authorization) {\n headers.Authorization =\n headers.Authorization.substring(0, 20) + '...[MASKED]';\n }\n\n const context = {\n method,\n url: url.length > 100 ? url.substring(0, 100) + '...' : url,\n headers: Object.keys(headers),\n bodySize: init?.body ? JSON.stringify(init.body).length : 0,\n };\n\n return trace.api(method, url, context, async () => {\n const startTime = Date.now();\n\n try {\n const response = await baseFetch(input, init);\n const duration = Date.now() - startTime;\n\n // Log response details\n logger.debug(`HTTP ${method} ${response.status}`, {\n url: url.substring(0, 100),\n status: response.status,\n duration,\n headers: {\n 'content-type': response.headers.get('content-type'),\n 'x-ratelimit-remaining': response.headers.get(\n 'x-ratelimit-remaining'\n ),\n 'x-ratelimit-reset': response.headers.get('x-ratelimit-reset'),\n },\n });\n\n // Warn about rate limiting\n const remaining = response.headers.get('x-ratelimit-remaining');\n if (remaining && parseInt(remaining) < 10) {\n logger.warn(`Low rate limit remaining: ${remaining}`, {\n url: url.substring(0, 100),\n resetAt: response.headers.get('x-ratelimit-reset'),\n });\n }\n\n // Warn about slow responses\n if (duration > 2000) {\n logger.warn(`Slow HTTP response: ${duration}ms`, {\n method,\n url: url.substring(0, 100),\n status: response.status,\n });\n }\n\n return response;\n } catch (error: any) {\n const duration = Date.now() - startTime;\n\n logger.error(`HTTP ${method} failed`, error, {\n url: url.substring(0, 100),\n duration,\n errorType: error.constructor.name,\n errno: error.errno,\n code: error.code,\n });\n\n throw error;\n }\n });\n };\n}\n\n/**\n * Create a traced GraphQL client wrapper\n */\nexport function wrapGraphQLClient<T>(client: T): T {\n const prototype = Object.getPrototypeOf(client);\n const propertyNames = Object.getOwnPropertyNames(prototype);\n\n for (const propertyName of propertyNames) {\n if (propertyName === 'constructor') continue;\n\n const descriptor = Object.getOwnPropertyDescriptor(prototype, propertyName);\n if (!descriptor || typeof descriptor.value !== 'function') continue;\n\n // Apply tracing to all methods\n TraceLinearAPI(prototype, propertyName, descriptor);\n Object.defineProperty(prototype, propertyName, descriptor);\n }\n\n return client;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -113,18 +113,22 @@ async function runDemo() {
|
|
|
113
113
|
console.log("\u2705 Error properly traced and handled\n");
|
|
114
114
|
}
|
|
115
115
|
});
|
|
116
|
-
await trace.command(
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
116
|
+
await trace.command(
|
|
117
|
+
"demo:performance",
|
|
118
|
+
{ example: "performance" },
|
|
119
|
+
async () => {
|
|
120
|
+
console.log("\n--- Example 4: Performance Tracking ---\n");
|
|
121
|
+
await trace.step("Slow operation", async () => {
|
|
122
|
+
await new Promise((resolve) => setTimeout(resolve, 150));
|
|
124
123
|
});
|
|
124
|
+
for (let i = 0; i < 3; i++) {
|
|
125
|
+
await trace.step(`Fast operation ${i + 1}`, async () => {
|
|
126
|
+
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
console.log("\u2705 Performance tracking completed\n");
|
|
125
130
|
}
|
|
126
|
-
|
|
127
|
-
});
|
|
131
|
+
);
|
|
128
132
|
} catch (error) {
|
|
129
133
|
console.error("\u274C Demo failed:", error);
|
|
130
134
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/core/trace/trace-demo.ts"],
|
|
4
|
-
"sourcesContent": ["#!/usr/bin/env node\n/**\n * Trace Demo - Shows how the debug tracing works\n * Run with: DEBUG_TRACE=true npx tsx src/core/trace/trace-demo.ts\n */\n\nimport {
|
|
5
|
-
"mappings": ";AAMA;AAAA,EACE;AAAA,EAGA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGP,SAAS,OAAO,KAAa,cAA+B;AAC1D,QAAM,QAAQ,QAAQ,IAAI,GAAG;AAC7B,MAAI,UAAU,QAAW;AACvB,QAAI,iBAAiB,OAAW,QAAO;AACvC,UAAM,IAAI,MAAM,wBAAwB,GAAG,cAAc;AAAA,EAC3D;AACA,SAAO;AACT;AAEA,SAAS,eAAe,KAAiC;AACvD,SAAO,QAAQ,IAAI,GAAG;AACxB;
|
|
4
|
+
"sourcesContent": ["#!/usr/bin/env node\n/**\n * Trace Demo - Shows how the debug tracing works\n * Run with: DEBUG_TRACE=true npx tsx src/core/trace/trace-demo.ts\n */\n\nimport {\n trace,\n Trace,\n TraceClass,\n enableVerboseTracing,\n createTracedDatabase,\n traceStep,\n} from './index.js';\nimport { logger } from '../monitoring/logger.js';\n// Type-safe environment variable access\nfunction getEnv(key: string, defaultValue?: string): string {\n const value = process.env[key];\n if (value === undefined) {\n if (defaultValue !== undefined) return defaultValue;\n throw new Error(`Environment variable ${key} is required`);\n }\n return value;\n}\n\nfunction getOptionalEnv(key: string): string | undefined {\n return process.env[key];\n}\n\n// Example class with tracing\n// @TraceClass() - decorators not enabled in tsconfig\nclass ExampleService {\n private data: Map<string, any> = new Map();\n\n async fetchData(id: string): Promise<any> {\n // Simulate API call\n await this.delay(50);\n\n if (id === 'error') {\n throw new Error('Simulated API error');\n }\n\n return { id, value: Math.random() };\n }\n\n async processData(data: any): Promise<any> {\n return traceStep('Data validation', async () => {\n await this.delay(20);\n\n if (!data.id) {\n throw new Error('Invalid data: missing ID');\n }\n\n return traceStep('Data transformation', async () => {\n await this.delay(30);\n return {\n ...data,\n processed: true,\n timestamp: Date.now(),\n };\n });\n });\n }\n\n cacheData(key: string, value: any): void {\n trace.traceSync('function', 'cacheData', { key, value }, () => {\n this.data.set(key, value);\n });\n }\n\n private delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n}\n\n// Example with database operations\nasync function databaseExample() {\n return trace.step('Database operations example', async () => {\n const db = createTracedDatabase(':memory:');\n\n // Create table\n db.exec(`\n CREATE TABLE users (\n id INTEGER PRIMARY KEY,\n name TEXT NOT NULL,\n email TEXT UNIQUE,\n created_at INTEGER DEFAULT (strftime('%s', 'now'))\n )\n `);\n\n // Insert data\n const insert = db.prepare('INSERT INTO users (name, email) VALUES (?, ?)');\n insert.run('Alice', 'alice@example.com');\n insert.run('Bob', 'bob@example.com');\n\n // Query data\n const select = db.prepare('SELECT * FROM users WHERE name = ?');\n const user = select.get('Alice');\n\n // Complex query (will trigger slow query warning if threshold is low)\n const complex = db.prepare(`\n SELECT \n name,\n COUNT(*) as count,\n MAX(created_at) as latest\n FROM users\n GROUP BY name\n HAVING COUNT(*) > 0\n `);\n const results = complex.all();\n\n db.close();\n\n return { user, results };\n });\n}\n\n// Main demo function\nasync function runDemo() {\n console.log('\\n' + '='.repeat(80));\n console.log('STACKMEMORY DEBUG TRACE DEMO');\n console.log('='.repeat(80) + '\\n');\n\n // Enable verbose tracing for the demo\n if (process.env['DEBUG_TRACE'] !== 'true') {\n console.log('\uD83D\uDCDD Enabling verbose tracing for this demo...\\n');\n enableVerboseTracing();\n }\n\n try {\n // Example 1: Service operations\n await trace.command('demo:service', { example: 'service' }, async () => {\n const service = new ExampleService();\n\n console.log('\\n--- Example 1: Service Operations ---\\n');\n\n // Successful operation\n const data = await service.fetchData('test-1');\n const processed = await service.processData(data);\n service.cacheData('test-1', processed);\n\n console.log('\u2705 Service operation completed\\n');\n });\n\n // Example 2: Database operations\n await trace.command('demo:database', { example: 'database' }, async () => {\n console.log('\\n--- Example 2: Database Operations ---\\n');\n\n const results = await databaseExample();\n\n console.log('\u2705 Database operations completed');\n console.log(' Found user:', results.user);\n console.log(' Query results:', results.results);\n });\n\n // Example 3: Error handling\n await trace.command('demo:errors', { example: 'errors' }, async () => {\n console.log('\\n--- Example 3: Error Handling ---\\n');\n\n const service = new ExampleService();\n\n try {\n await service.fetchData('error');\n } catch (error: unknown) {\n console.log('\u2705 Error properly traced and handled\\n');\n }\n });\n\n // Example 4: Performance tracking\n await trace.command(\n 'demo:performance',\n { example: 'performance' },\n async () => {\n console.log('\\n--- Example 4: Performance Tracking ---\\n');\n\n // Simulate slow operation\n await trace.step('Slow operation', async () => {\n await new Promise((resolve) => setTimeout(resolve, 150));\n });\n\n // Simulate fast operations\n for (let i = 0; i < 3; i++) {\n await trace.step(`Fast operation ${i + 1}`, async () => {\n await new Promise((resolve) => setTimeout(resolve, 10));\n });\n }\n\n console.log('\u2705 Performance tracking completed\\n');\n }\n );\n } catch (error: unknown) {\n console.error('\u274C Demo failed:', error);\n }\n\n // Show execution summary\n console.log('\\n' + trace.getExecutionSummary());\n\n // Export traces for analysis\n const traces = trace.exportTraces();\n console.log(`\\n\uD83D\uDCCA Total traces collected: ${traces.length}`);\n\n // Show example trace entry\n if (traces.length > 0) {\n console.log('\\n\uD83D\uDCCD Example trace entry:');\n console.log(JSON.stringify(traces[0], null, 2));\n }\n}\n\n// Run the demo\nif (import.meta.url === `file://${process.argv[1]}`) {\n runDemo().catch(console.error);\n}\n\nexport { runDemo };\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -465,9 +465,16 @@ class TraceDetector {
|
|
|
465
465
|
compressed++;
|
|
466
466
|
if (this.traceStore) {
|
|
467
467
|
try {
|
|
468
|
-
this.traceStore.updateCompression(
|
|
468
|
+
this.traceStore.updateCompression(
|
|
469
|
+
trace.id,
|
|
470
|
+
trace.compressed,
|
|
471
|
+
strategy
|
|
472
|
+
);
|
|
469
473
|
} catch (error) {
|
|
470
|
-
console.error(
|
|
474
|
+
console.error(
|
|
475
|
+
"Failed to update trace compression in store:",
|
|
476
|
+
error
|
|
477
|
+
);
|
|
471
478
|
}
|
|
472
479
|
}
|
|
473
480
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/core/trace/trace-detector.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Trace Detection and Bundling System\n * Identifies chains of related tool calls and bundles them as single traces\n */\n\nimport { v4 as uuidv4 } from 'uuid';\nimport {\n ToolCall,\n Trace,\n TraceType,\n TraceBoundaryConfig,\n DEFAULT_TRACE_CONFIG,\n TRACE_PATTERNS,\n TraceMetadata,\n TraceScoringFactors,\n CompressedTrace,\n CompressionStrategy,\n} from './types.js';\nimport { ConfigManager } from '../config/config-manager.js';\nimport { TraceStore } from './trace-store.js';\nimport Database from 'better-sqlite3';\n\nexport class TraceDetector {\n private config: TraceBoundaryConfig;\n private activeTrace: ToolCall[] = [];\n private lastToolTime: number = 0;\n private traces: Trace[] = [];\n private configManager: ConfigManager;\n private traceStore?: TraceStore;\n\n constructor(\n config: Partial<TraceBoundaryConfig> = {},\n configManager?: ConfigManager,\n db?: Database.Database\n ) {\n this.config = { ...DEFAULT_TRACE_CONFIG, ...config };\n this.configManager = configManager || new ConfigManager();\n\n if (db) {\n this.traceStore = new TraceStore(db);\n // Load existing traces from database\n this.loadTracesFromStore();\n }\n }\n\n /**\n * Load traces from the database\n */\n private loadTracesFromStore(): void {\n if (!this.traceStore) return;\n\n try {\n // Load recent traces (last 24 hours)\n const recentTraces = this.traceStore.getAllTraces();\n const cutoff = Date.now() - 24 * 60 * 60 * 1000;\n\n this.traces = recentTraces.filter((t) => t.metadata.startTime >= cutoff);\n } catch (error: unknown) {\n // If loading fails, start with empty traces\n console.error('Failed to load traces from store:', error);\n this.traces = [];\n }\n }\n\n /**\n * Add a tool call and check if it belongs to current trace\n */\n addToolCall(tool: ToolCall): void {\n const now = Date.now();\n\n // Check if this tool belongs to the current trace\n if (this.shouldStartNewTrace(tool)) {\n // Finalize current trace if it exists\n if (this.activeTrace.length > 0) {\n this.finalizeTrace();\n }\n // Start new trace\n this.activeTrace = [tool];\n } else {\n // Add to current trace\n this.activeTrace.push(tool);\n }\n\n this.lastToolTime = tool.timestamp;\n\n // Check if trace is getting too large\n if (this.activeTrace.length >= this.config.maxTraceSize) {\n this.finalizeTrace();\n }\n }\n\n /**\n * Determine if a tool call should start a new trace\n */\n private shouldStartNewTrace(tool: ToolCall): boolean {\n // First tool always starts a new trace\n if (this.activeTrace.length === 0) {\n return false;\n }\n\n const lastTool = this.activeTrace[this.activeTrace.length - 1];\n\n // Time proximity check\n const timeDiff = tool.timestamp - lastTool.timestamp;\n if (timeDiff > this.config.timeProximityMs) {\n return true;\n }\n\n // Directory check if enabled\n if (this.config.sameDirThreshold) {\n const lastFiles = lastTool.filesAffected || [];\n const currentFiles = tool.filesAffected || [];\n\n if (lastFiles.length > 0 && currentFiles.length > 0) {\n const lastDirs = lastFiles.map((f) => this.getDirectory(f));\n const currentDirs = currentFiles.map((f) => this.getDirectory(f));\n\n const hasCommonDir = lastDirs.some((d) => currentDirs.includes(d));\n if (!hasCommonDir) {\n return true;\n }\n }\n }\n\n // Causal relationship check\n if (this.config.causalRelationship) {\n // If last tool had an error and current tool is not a fix attempt, start new trace\n if (lastTool.error && !this.isFixAttempt(tool, lastTool)) {\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * Check if a tool is attempting to fix an error from previous tool\n */\n private isFixAttempt(current: ToolCall, previous: ToolCall): boolean {\n // Edit after error is likely a fix\n if (\n previous.error &&\n (current.tool === 'edit' || current.tool === 'write')\n ) {\n return true;\n }\n\n // Test after fix is validation\n if (current.tool === 'test' || current.tool === 'bash') {\n return true;\n }\n\n return false;\n }\n\n /**\n * Finalize current trace and add to traces list\n */\n private finalizeTrace(): void {\n if (this.activeTrace.length === 0) return;\n\n const trace = this.createTrace(this.activeTrace);\n this.traces.push(trace);\n\n // Persist to database if store is available\n if (this.traceStore) {\n try {\n this.traceStore.saveTrace(trace);\n } catch (error: unknown) {\n console.error('Failed to persist trace:', error);\n }\n }\n\n this.activeTrace = [];\n }\n\n /**\n * Create a trace from a sequence of tool calls\n */\n private createTrace(tools: ToolCall[]): Trace {\n const id = uuidv4();\n const type = this.detectTraceType(tools);\n const metadata = this.extractMetadata(tools);\n const score = this.calculateTraceScore(tools, metadata);\n const summary = this.generateSummary(tools, type, metadata);\n\n const trace: Trace = {\n id,\n type,\n tools,\n score,\n summary,\n metadata,\n };\n\n // Check if trace should be compressed\n const ageHours = (Date.now() - metadata.startTime) / (1000 * 60 * 60);\n if (ageHours > this.config.compressionThreshold) {\n trace.compressed = this.compressTrace(trace);\n }\n\n return trace;\n }\n\n /**\n * Detect the type of trace based on tool patterns\n */\n private detectTraceType(tools: ToolCall[]): TraceType {\n const toolSequence = tools.map((t) => t.tool);\n\n // Check against known patterns\n for (const pattern of TRACE_PATTERNS) {\n if (this.matchesPattern(toolSequence, pattern.pattern)) {\n return pattern.type;\n }\n }\n\n // Heuristic detection\n if (toolSequence.includes('search') || toolSequence.includes('grep')) {\n if (toolSequence.includes('edit')) {\n return TraceType.SEARCH_DRIVEN;\n }\n return TraceType.EXPLORATION;\n }\n\n if (tools.some((t) => t.error)) {\n return TraceType.ERROR_RECOVERY;\n }\n\n if (toolSequence.includes('test')) {\n return TraceType.TESTING;\n }\n\n if (toolSequence.includes('write')) {\n return TraceType.FEATURE_IMPLEMENTATION;\n }\n\n return TraceType.UNKNOWN;\n }\n\n /**\n * Check if tool sequence matches a pattern\n */\n private matchesPattern(\n sequence: string[],\n pattern: RegExp | string[]\n ): boolean {\n if (pattern instanceof RegExp) {\n return pattern.test(sequence.join('\u2192'));\n }\n\n if (Array.isArray(pattern)) {\n // Check if pattern is a subsequence\n let patternIndex = 0;\n for (const tool of sequence) {\n if (tool === pattern[patternIndex]) {\n patternIndex++;\n if (patternIndex >= pattern.length) {\n return true;\n }\n }\n }\n }\n\n return false;\n }\n\n /**\n * Extract metadata from tool calls\n */\n private extractMetadata(tools: ToolCall[]): TraceMetadata {\n const startTime = tools[0].timestamp;\n const endTime = tools[tools.length - 1].timestamp;\n\n const filesModified = new Set<string>();\n const errorsEncountered: string[] = [];\n const decisionsRecorded: string[] = [];\n\n let hasCausalChain = false;\n\n for (let i = 0; i < tools.length; i++) {\n const tool = tools[i];\n\n // Collect files\n if (tool.filesAffected) {\n tool.filesAffected.forEach((f) => filesModified.add(f));\n }\n\n // Collect errors\n if (tool.error) {\n errorsEncountered.push(tool.error);\n // Check if next tool is a fix attempt\n if (i < tools.length - 1) {\n const nextTool = tools[i + 1];\n if (this.isFixAttempt(nextTool, tool)) {\n hasCausalChain = true;\n }\n }\n }\n\n // Collect decisions (if tool is decision_recording)\n if (tool.tool === 'decision_recording' && tool.arguments?.decision) {\n decisionsRecorded.push(tool.arguments.decision);\n }\n }\n\n return {\n startTime,\n endTime,\n filesModified: Array.from(filesModified),\n errorsEncountered,\n decisionsRecorded,\n causalChain: hasCausalChain,\n };\n }\n\n /**\n * Calculate importance score for a trace\n */\n private calculateTraceScore(\n tools: ToolCall[],\n metadata: TraceMetadata\n ): number {\n // Get individual tool scores\n const toolScores = tools.map((t) =>\n this.configManager.calculateScore(t.tool, {\n filesAffected: t.filesAffected?.length || 0,\n isPermanent: this.isPermanentChange(t),\n referenceCount: 0, // Would need to track references\n })\n );\n\n // Use MAX strategy for trace scoring (highest tool determines trace importance)\n const maxScore = Math.max(...toolScores);\n\n // Apply bonuses\n let score = maxScore;\n\n // Bonus for causal chains (error\u2192fix\u2192verify)\n if (metadata.causalChain) {\n score = Math.min(score + 0.1, 1.0);\n }\n\n // Bonus for decisions\n if (metadata.decisionsRecorded.length > 0) {\n score = Math.min(score + 0.05 * metadata.decisionsRecorded.length, 1.0);\n }\n\n // Penalty for errors without fixes\n if (metadata.errorsEncountered.length > 0 && !metadata.causalChain) {\n score = Math.max(score - 0.1, 0);\n }\n\n return score;\n }\n\n /**\n * Check if a tool call represents a permanent change\n */\n private isPermanentChange(tool: ToolCall): boolean {\n const permanentTools = ['write', 'edit', 'decision_recording'];\n return permanentTools.includes(tool.tool);\n }\n\n /**\n * Generate a summary for the trace\n */\n private generateSummary(\n tools: ToolCall[],\n type: TraceType,\n metadata: TraceMetadata\n ): string {\n const toolChain = tools.map((t) => t.tool).join('\u2192');\n\n switch (type) {\n case TraceType.SEARCH_DRIVEN:\n return `Search-driven modification: ${toolChain}`;\n\n case TraceType.ERROR_RECOVERY:\n const error = metadata.errorsEncountered[0] || 'unknown error';\n return `Error recovery: ${error} via ${toolChain}`;\n\n case TraceType.FEATURE_IMPLEMENTATION:\n const files = metadata.filesModified.length;\n return `Feature implementation: ${files} files via ${toolChain}`;\n\n case TraceType.REFACTORING:\n return `Code refactoring: ${toolChain}`;\n\n case TraceType.TESTING:\n return `Test execution: ${toolChain}`;\n\n case TraceType.EXPLORATION:\n return `Codebase exploration: ${toolChain}`;\n\n case TraceType.DEBUGGING:\n return `Debugging session: ${toolChain}`;\n\n case TraceType.BUILD_DEPLOY:\n return `Build and deploy: ${toolChain}`;\n\n default:\n return `Tool sequence: ${toolChain}`;\n }\n }\n\n /**\n * Compress a trace for long-term storage using strategy\n */\n private compressTrace(\n trace: Trace, \n strategy: CompressionStrategy = CompressionStrategy.PATTERN_BASED\n ): CompressedTrace {\n switch (strategy) {\n case CompressionStrategy.SUMMARY_ONLY:\n return this.compressSummaryOnly(trace);\n \n case CompressionStrategy.PATTERN_BASED:\n return this.compressPatternBased(trace);\n \n case CompressionStrategy.SELECTIVE:\n return this.compressSelective(trace);\n \n case CompressionStrategy.FULL_COMPRESSION:\n return this.compressMaximal(trace);\n \n default:\n return this.compressPatternBased(trace);\n }\n }\n \n /**\n * Summary-only compression - minimal data retention\n */\n private compressSummaryOnly(trace: Trace): CompressedTrace {\n return {\n pattern: '', // No pattern stored\n summary: trace.summary.substring(0, 100), // Limit summary\n score: trace.score,\n toolCount: trace.tools.length,\n duration: trace.metadata.endTime - trace.metadata.startTime,\n timestamp: trace.metadata.startTime,\n };\n }\n \n /**\n * Pattern-based compression - keep tool sequence\n */\n private compressPatternBased(trace: Trace): CompressedTrace {\n const pattern = trace.tools.map((t) => t.tool).join('\u2192');\n const duration = trace.metadata.endTime - trace.metadata.startTime;\n\n return {\n pattern,\n summary: trace.summary,\n score: trace.score,\n toolCount: trace.tools.length,\n duration,\n timestamp: trace.metadata.startTime,\n };\n }\n \n /**\n * Selective compression - keep high-score tools only\n */\n private compressSelective(trace: Trace, threshold: number = 0.5): CompressedTrace {\n // Calculate individual tool scores\n const significantTools = trace.tools.filter((tool: any) => {\n const score = this.configManager.calculateScore(tool.tool, {\n filesAffected: tool.filesAffected?.length || 0,\n isPermanent: this.isPermanentChange(tool),\n referenceCount: 0,\n });\n return score >= threshold;\n });\n \n const pattern = significantTools.length > 0 \n ? significantTools.map((t: any) => t.tool).join('\u2192')\n : trace.tools.map((t: any) => t.tool).join('\u2192');\n \n return {\n pattern,\n summary: `${trace.summary} [${significantTools.length}/${trace.tools.length} significant]`,\n score: trace.score,\n toolCount: significantTools.length,\n duration: trace.metadata.endTime - trace.metadata.startTime,\n timestamp: trace.metadata.startTime,\n };\n }\n \n /**\n * Maximal compression - absolute minimum data\n */\n private compressMaximal(trace: Trace): CompressedTrace {\n // Compress pattern to type abbreviation\n const typeAbbrev = this.getTraceTypeAbbreviation(trace.type);\n const pattern = `${typeAbbrev}:${trace.tools.length}`;\n \n return {\n pattern,\n summary: trace.type, // Just the type\n score: Math.round(trace.score * 10) / 10, // Round to 1 decimal\n toolCount: trace.tools.length,\n duration: Math.round((trace.metadata.endTime - trace.metadata.startTime) / 1000) * 1000, // Round to seconds\n timestamp: trace.metadata.startTime,\n };\n }\n \n /**\n * Get abbreviated trace type\n */\n private getTraceTypeAbbreviation(type: TraceType): string {\n const abbreviations: Record<TraceType, string> = {\n [TraceType.SEARCH_DRIVEN]: 'SD',\n [TraceType.ERROR_RECOVERY]: 'ER',\n [TraceType.FEATURE_IMPLEMENTATION]: 'FI',\n [TraceType.REFACTORING]: 'RF',\n [TraceType.TESTING]: 'TS',\n [TraceType.EXPLORATION]: 'EX',\n [TraceType.DEBUGGING]: 'DB',\n [TraceType.DOCUMENTATION]: 'DC',\n [TraceType.BUILD_DEPLOY]: 'BD',\n [TraceType.UNKNOWN]: 'UN',\n };\n return abbreviations[type] || 'UN';\n }\n \n /**\n * Choose compression strategy based on trace age and importance\n */\n private selectCompressionStrategy(trace: Trace): CompressionStrategy {\n const ageHours = (Date.now() - trace.metadata.startTime) / (1000 * 60 * 60);\n const score = trace.score;\n \n // Recent and important: pattern-based\n if (ageHours < 24 && score > 0.7) {\n return CompressionStrategy.PATTERN_BASED;\n }\n \n // Recent but less important: selective\n if (ageHours < 24) {\n return CompressionStrategy.SELECTIVE;\n }\n \n // Old and important: selective\n if (ageHours < 168 && score > 0.5) { // 1 week\n return CompressionStrategy.SELECTIVE;\n }\n \n // Old and less important: summary only\n if (ageHours < 720) { // 30 days\n return CompressionStrategy.SUMMARY_ONLY;\n }\n \n // Very old: maximal compression\n return CompressionStrategy.FULL_COMPRESSION;\n }\n\n /**\n * Get directory from file path\n */\n private getDirectory(filePath: string): string {\n const parts = filePath.split('/');\n parts.pop(); // Remove filename\n return parts.join('/');\n }\n\n /**\n * Flush any pending trace\n */\n flush(): void {\n if (this.activeTrace.length > 0) {\n this.finalizeTrace();\n }\n }\n\n /**\n * Get all detected traces\n */\n getTraces(): Trace[] {\n return this.traces;\n }\n\n /**\n * Get traces by type\n */\n getTracesByType(type: TraceType): Trace[] {\n return this.traces.filter((t) => t.type === type);\n }\n\n /**\n * Get high-importance traces\n */\n getHighImportanceTraces(threshold: number = 0.7): Trace[] {\n return this.traces.filter((t) => t.score >= threshold);\n }\n\n /**\n * Compress old traces with intelligent strategy selection\n */\n compressOldTraces(ageHours: number = 24): number {\n let compressed = 0;\n const now = Date.now();\n\n for (const trace of this.traces) {\n const age = (now - trace.metadata.startTime) / (1000 * 60 * 60);\n if (age > ageHours && !trace.compressed) {\n // Select compression strategy based on age and importance\n const strategy = this.selectCompressionStrategy(trace);\n trace.compressed = this.compressTrace(trace, strategy);\n \n // Remove full tool data for older traces to save memory\n if (strategy === CompressionStrategy.FULL_COMPRESSION || \n strategy === CompressionStrategy.SUMMARY_ONLY) {\n trace.tools = []; // Clear tool data for maximum compression\n } else if (strategy === CompressionStrategy.SELECTIVE) {\n // Keep only high-score tools\n trace.tools = trace.tools.filter((tool: any) => {\n const score = this.configManager.calculateScore(tool.tool, {\n filesAffected: tool.filesAffected?.length || 0,\n isPermanent: this.isPermanentChange(tool),\n referenceCount: 0,\n });\n return score >= 0.5;\n });\n }\n \n compressed++;\n \n // Update database if available\n if (this.traceStore) {\n try {\n this.traceStore.updateCompression(trace.id, trace.compressed, strategy);\n } catch (error: unknown) {\n console.error('Failed to update trace compression in store:', error);\n }\n }\n }\n }\n\n return compressed;\n }\n\n /**\n * Export traces for analysis\n */\n exportTraces(): string {\n return JSON.stringify(this.traces, null, 2);\n }\n\n /**\n * Get statistics about traces\n */\n getStatistics() {\n const stats = {\n totalTraces: this.traces.length,\n tracesByType: {} as Record<string, number>,\n averageScore: 0,\n averageLength: 0,\n compressedCount: 0,\n highImportanceCount: 0,\n };\n\n if (this.traces.length === 0) return stats;\n\n let totalScore = 0;\n let totalLength = 0;\n\n for (const trace of this.traces) {\n // Type distribution\n stats.tracesByType[trace.type] =\n (stats.tracesByType[trace.type] || 0) + 1;\n\n // Scores\n totalScore += trace.score;\n\n // Length\n totalLength += trace.tools.length;\n\n // Compressed\n if (trace.compressed) {\n stats.compressedCount++;\n }\n\n // High importance\n if (trace.score >= 0.7) {\n stats.highImportanceCount++;\n }\n }\n\n stats.averageScore = totalScore / this.traces.length;\n stats.averageLength = totalLength / this.traces.length;\n\n return stats;\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["/**\n * Trace Detection and Bundling System\n * Identifies chains of related tool calls and bundles them as single traces\n */\n\nimport { v4 as uuidv4 } from 'uuid';\nimport {\n ToolCall,\n Trace,\n TraceType,\n TraceBoundaryConfig,\n DEFAULT_TRACE_CONFIG,\n TRACE_PATTERNS,\n TraceMetadata,\n TraceScoringFactors,\n CompressedTrace,\n CompressionStrategy,\n} from './types.js';\nimport { ConfigManager } from '../config/config-manager.js';\nimport { TraceStore } from './trace-store.js';\nimport Database from 'better-sqlite3';\n\nexport class TraceDetector {\n private config: TraceBoundaryConfig;\n private activeTrace: ToolCall[] = [];\n private lastToolTime: number = 0;\n private traces: Trace[] = [];\n private configManager: ConfigManager;\n private traceStore?: TraceStore;\n\n constructor(\n config: Partial<TraceBoundaryConfig> = {},\n configManager?: ConfigManager,\n db?: Database.Database\n ) {\n this.config = { ...DEFAULT_TRACE_CONFIG, ...config };\n this.configManager = configManager || new ConfigManager();\n\n if (db) {\n this.traceStore = new TraceStore(db);\n // Load existing traces from database\n this.loadTracesFromStore();\n }\n }\n\n /**\n * Load traces from the database\n */\n private loadTracesFromStore(): void {\n if (!this.traceStore) return;\n\n try {\n // Load recent traces (last 24 hours)\n const recentTraces = this.traceStore.getAllTraces();\n const cutoff = Date.now() - 24 * 60 * 60 * 1000;\n\n this.traces = recentTraces.filter((t) => t.metadata.startTime >= cutoff);\n } catch (error: unknown) {\n // If loading fails, start with empty traces\n console.error('Failed to load traces from store:', error);\n this.traces = [];\n }\n }\n\n /**\n * Add a tool call and check if it belongs to current trace\n */\n addToolCall(tool: ToolCall): void {\n const now = Date.now();\n\n // Check if this tool belongs to the current trace\n if (this.shouldStartNewTrace(tool)) {\n // Finalize current trace if it exists\n if (this.activeTrace.length > 0) {\n this.finalizeTrace();\n }\n // Start new trace\n this.activeTrace = [tool];\n } else {\n // Add to current trace\n this.activeTrace.push(tool);\n }\n\n this.lastToolTime = tool.timestamp;\n\n // Check if trace is getting too large\n if (this.activeTrace.length >= this.config.maxTraceSize) {\n this.finalizeTrace();\n }\n }\n\n /**\n * Determine if a tool call should start a new trace\n */\n private shouldStartNewTrace(tool: ToolCall): boolean {\n // First tool always starts a new trace\n if (this.activeTrace.length === 0) {\n return false;\n }\n\n const lastTool = this.activeTrace[this.activeTrace.length - 1];\n\n // Time proximity check\n const timeDiff = tool.timestamp - lastTool.timestamp;\n if (timeDiff > this.config.timeProximityMs) {\n return true;\n }\n\n // Directory check if enabled\n if (this.config.sameDirThreshold) {\n const lastFiles = lastTool.filesAffected || [];\n const currentFiles = tool.filesAffected || [];\n\n if (lastFiles.length > 0 && currentFiles.length > 0) {\n const lastDirs = lastFiles.map((f) => this.getDirectory(f));\n const currentDirs = currentFiles.map((f) => this.getDirectory(f));\n\n const hasCommonDir = lastDirs.some((d) => currentDirs.includes(d));\n if (!hasCommonDir) {\n return true;\n }\n }\n }\n\n // Causal relationship check\n if (this.config.causalRelationship) {\n // If last tool had an error and current tool is not a fix attempt, start new trace\n if (lastTool.error && !this.isFixAttempt(tool, lastTool)) {\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * Check if a tool is attempting to fix an error from previous tool\n */\n private isFixAttempt(current: ToolCall, previous: ToolCall): boolean {\n // Edit after error is likely a fix\n if (\n previous.error &&\n (current.tool === 'edit' || current.tool === 'write')\n ) {\n return true;\n }\n\n // Test after fix is validation\n if (current.tool === 'test' || current.tool === 'bash') {\n return true;\n }\n\n return false;\n }\n\n /**\n * Finalize current trace and add to traces list\n */\n private finalizeTrace(): void {\n if (this.activeTrace.length === 0) return;\n\n const trace = this.createTrace(this.activeTrace);\n this.traces.push(trace);\n\n // Persist to database if store is available\n if (this.traceStore) {\n try {\n this.traceStore.saveTrace(trace);\n } catch (error: unknown) {\n console.error('Failed to persist trace:', error);\n }\n }\n\n this.activeTrace = [];\n }\n\n /**\n * Create a trace from a sequence of tool calls\n */\n private createTrace(tools: ToolCall[]): Trace {\n const id = uuidv4();\n const type = this.detectTraceType(tools);\n const metadata = this.extractMetadata(tools);\n const score = this.calculateTraceScore(tools, metadata);\n const summary = this.generateSummary(tools, type, metadata);\n\n const trace: Trace = {\n id,\n type,\n tools,\n score,\n summary,\n metadata,\n };\n\n // Check if trace should be compressed\n const ageHours = (Date.now() - metadata.startTime) / (1000 * 60 * 60);\n if (ageHours > this.config.compressionThreshold) {\n trace.compressed = this.compressTrace(trace);\n }\n\n return trace;\n }\n\n /**\n * Detect the type of trace based on tool patterns\n */\n private detectTraceType(tools: ToolCall[]): TraceType {\n const toolSequence = tools.map((t) => t.tool);\n\n // Check against known patterns\n for (const pattern of TRACE_PATTERNS) {\n if (this.matchesPattern(toolSequence, pattern.pattern)) {\n return pattern.type;\n }\n }\n\n // Heuristic detection\n if (toolSequence.includes('search') || toolSequence.includes('grep')) {\n if (toolSequence.includes('edit')) {\n return TraceType.SEARCH_DRIVEN;\n }\n return TraceType.EXPLORATION;\n }\n\n if (tools.some((t) => t.error)) {\n return TraceType.ERROR_RECOVERY;\n }\n\n if (toolSequence.includes('test')) {\n return TraceType.TESTING;\n }\n\n if (toolSequence.includes('write')) {\n return TraceType.FEATURE_IMPLEMENTATION;\n }\n\n return TraceType.UNKNOWN;\n }\n\n /**\n * Check if tool sequence matches a pattern\n */\n private matchesPattern(\n sequence: string[],\n pattern: RegExp | string[]\n ): boolean {\n if (pattern instanceof RegExp) {\n return pattern.test(sequence.join('\u2192'));\n }\n\n if (Array.isArray(pattern)) {\n // Check if pattern is a subsequence\n let patternIndex = 0;\n for (const tool of sequence) {\n if (tool === pattern[patternIndex]) {\n patternIndex++;\n if (patternIndex >= pattern.length) {\n return true;\n }\n }\n }\n }\n\n return false;\n }\n\n /**\n * Extract metadata from tool calls\n */\n private extractMetadata(tools: ToolCall[]): TraceMetadata {\n const startTime = tools[0].timestamp;\n const endTime = tools[tools.length - 1].timestamp;\n\n const filesModified = new Set<string>();\n const errorsEncountered: string[] = [];\n const decisionsRecorded: string[] = [];\n\n let hasCausalChain = false;\n\n for (let i = 0; i < tools.length; i++) {\n const tool = tools[i];\n\n // Collect files\n if (tool.filesAffected) {\n tool.filesAffected.forEach((f) => filesModified.add(f));\n }\n\n // Collect errors\n if (tool.error) {\n errorsEncountered.push(tool.error);\n // Check if next tool is a fix attempt\n if (i < tools.length - 1) {\n const nextTool = tools[i + 1];\n if (this.isFixAttempt(nextTool, tool)) {\n hasCausalChain = true;\n }\n }\n }\n\n // Collect decisions (if tool is decision_recording)\n if (tool.tool === 'decision_recording' && tool.arguments?.decision) {\n decisionsRecorded.push(tool.arguments.decision);\n }\n }\n\n return {\n startTime,\n endTime,\n filesModified: Array.from(filesModified),\n errorsEncountered,\n decisionsRecorded,\n causalChain: hasCausalChain,\n };\n }\n\n /**\n * Calculate importance score for a trace\n */\n private calculateTraceScore(\n tools: ToolCall[],\n metadata: TraceMetadata\n ): number {\n // Get individual tool scores\n const toolScores = tools.map((t) =>\n this.configManager.calculateScore(t.tool, {\n filesAffected: t.filesAffected?.length || 0,\n isPermanent: this.isPermanentChange(t),\n referenceCount: 0, // Would need to track references\n })\n );\n\n // Use MAX strategy for trace scoring (highest tool determines trace importance)\n const maxScore = Math.max(...toolScores);\n\n // Apply bonuses\n let score = maxScore;\n\n // Bonus for causal chains (error\u2192fix\u2192verify)\n if (metadata.causalChain) {\n score = Math.min(score + 0.1, 1.0);\n }\n\n // Bonus for decisions\n if (metadata.decisionsRecorded.length > 0) {\n score = Math.min(score + 0.05 * metadata.decisionsRecorded.length, 1.0);\n }\n\n // Penalty for errors without fixes\n if (metadata.errorsEncountered.length > 0 && !metadata.causalChain) {\n score = Math.max(score - 0.1, 0);\n }\n\n return score;\n }\n\n /**\n * Check if a tool call represents a permanent change\n */\n private isPermanentChange(tool: ToolCall): boolean {\n const permanentTools = ['write', 'edit', 'decision_recording'];\n return permanentTools.includes(tool.tool);\n }\n\n /**\n * Generate a summary for the trace\n */\n private generateSummary(\n tools: ToolCall[],\n type: TraceType,\n metadata: TraceMetadata\n ): string {\n const toolChain = tools.map((t) => t.tool).join('\u2192');\n\n switch (type) {\n case TraceType.SEARCH_DRIVEN:\n return `Search-driven modification: ${toolChain}`;\n\n case TraceType.ERROR_RECOVERY:\n const error = metadata.errorsEncountered[0] || 'unknown error';\n return `Error recovery: ${error} via ${toolChain}`;\n\n case TraceType.FEATURE_IMPLEMENTATION:\n const files = metadata.filesModified.length;\n return `Feature implementation: ${files} files via ${toolChain}`;\n\n case TraceType.REFACTORING:\n return `Code refactoring: ${toolChain}`;\n\n case TraceType.TESTING:\n return `Test execution: ${toolChain}`;\n\n case TraceType.EXPLORATION:\n return `Codebase exploration: ${toolChain}`;\n\n case TraceType.DEBUGGING:\n return `Debugging session: ${toolChain}`;\n\n case TraceType.BUILD_DEPLOY:\n return `Build and deploy: ${toolChain}`;\n\n default:\n return `Tool sequence: ${toolChain}`;\n }\n }\n\n /**\n * Compress a trace for long-term storage using strategy\n */\n private compressTrace(\n trace: Trace,\n strategy: CompressionStrategy = CompressionStrategy.PATTERN_BASED\n ): CompressedTrace {\n switch (strategy) {\n case CompressionStrategy.SUMMARY_ONLY:\n return this.compressSummaryOnly(trace);\n\n case CompressionStrategy.PATTERN_BASED:\n return this.compressPatternBased(trace);\n\n case CompressionStrategy.SELECTIVE:\n return this.compressSelective(trace);\n\n case CompressionStrategy.FULL_COMPRESSION:\n return this.compressMaximal(trace);\n\n default:\n return this.compressPatternBased(trace);\n }\n }\n\n /**\n * Summary-only compression - minimal data retention\n */\n private compressSummaryOnly(trace: Trace): CompressedTrace {\n return {\n pattern: '', // No pattern stored\n summary: trace.summary.substring(0, 100), // Limit summary\n score: trace.score,\n toolCount: trace.tools.length,\n duration: trace.metadata.endTime - trace.metadata.startTime,\n timestamp: trace.metadata.startTime,\n };\n }\n\n /**\n * Pattern-based compression - keep tool sequence\n */\n private compressPatternBased(trace: Trace): CompressedTrace {\n const pattern = trace.tools.map((t) => t.tool).join('\u2192');\n const duration = trace.metadata.endTime - trace.metadata.startTime;\n\n return {\n pattern,\n summary: trace.summary,\n score: trace.score,\n toolCount: trace.tools.length,\n duration,\n timestamp: trace.metadata.startTime,\n };\n }\n\n /**\n * Selective compression - keep high-score tools only\n */\n private compressSelective(\n trace: Trace,\n threshold: number = 0.5\n ): CompressedTrace {\n // Calculate individual tool scores\n const significantTools = trace.tools.filter((tool: any) => {\n const score = this.configManager.calculateScore(tool.tool, {\n filesAffected: tool.filesAffected?.length || 0,\n isPermanent: this.isPermanentChange(tool),\n referenceCount: 0,\n });\n return score >= threshold;\n });\n\n const pattern =\n significantTools.length > 0\n ? significantTools.map((t: any) => t.tool).join('\u2192')\n : trace.tools.map((t: any) => t.tool).join('\u2192');\n\n return {\n pattern,\n summary: `${trace.summary} [${significantTools.length}/${trace.tools.length} significant]`,\n score: trace.score,\n toolCount: significantTools.length,\n duration: trace.metadata.endTime - trace.metadata.startTime,\n timestamp: trace.metadata.startTime,\n };\n }\n\n /**\n * Maximal compression - absolute minimum data\n */\n private compressMaximal(trace: Trace): CompressedTrace {\n // Compress pattern to type abbreviation\n const typeAbbrev = this.getTraceTypeAbbreviation(trace.type);\n const pattern = `${typeAbbrev}:${trace.tools.length}`;\n\n return {\n pattern,\n summary: trace.type, // Just the type\n score: Math.round(trace.score * 10) / 10, // Round to 1 decimal\n toolCount: trace.tools.length,\n duration:\n Math.round((trace.metadata.endTime - trace.metadata.startTime) / 1000) *\n 1000, // Round to seconds\n timestamp: trace.metadata.startTime,\n };\n }\n\n /**\n * Get abbreviated trace type\n */\n private getTraceTypeAbbreviation(type: TraceType): string {\n const abbreviations: Record<TraceType, string> = {\n [TraceType.SEARCH_DRIVEN]: 'SD',\n [TraceType.ERROR_RECOVERY]: 'ER',\n [TraceType.FEATURE_IMPLEMENTATION]: 'FI',\n [TraceType.REFACTORING]: 'RF',\n [TraceType.TESTING]: 'TS',\n [TraceType.EXPLORATION]: 'EX',\n [TraceType.DEBUGGING]: 'DB',\n [TraceType.DOCUMENTATION]: 'DC',\n [TraceType.BUILD_DEPLOY]: 'BD',\n [TraceType.UNKNOWN]: 'UN',\n };\n return abbreviations[type] || 'UN';\n }\n\n /**\n * Choose compression strategy based on trace age and importance\n */\n private selectCompressionStrategy(trace: Trace): CompressionStrategy {\n const ageHours = (Date.now() - trace.metadata.startTime) / (1000 * 60 * 60);\n const score = trace.score;\n\n // Recent and important: pattern-based\n if (ageHours < 24 && score > 0.7) {\n return CompressionStrategy.PATTERN_BASED;\n }\n\n // Recent but less important: selective\n if (ageHours < 24) {\n return CompressionStrategy.SELECTIVE;\n }\n\n // Old and important: selective\n if (ageHours < 168 && score > 0.5) {\n // 1 week\n return CompressionStrategy.SELECTIVE;\n }\n\n // Old and less important: summary only\n if (ageHours < 720) {\n // 30 days\n return CompressionStrategy.SUMMARY_ONLY;\n }\n\n // Very old: maximal compression\n return CompressionStrategy.FULL_COMPRESSION;\n }\n\n /**\n * Get directory from file path\n */\n private getDirectory(filePath: string): string {\n const parts = filePath.split('/');\n parts.pop(); // Remove filename\n return parts.join('/');\n }\n\n /**\n * Flush any pending trace\n */\n flush(): void {\n if (this.activeTrace.length > 0) {\n this.finalizeTrace();\n }\n }\n\n /**\n * Get all detected traces\n */\n getTraces(): Trace[] {\n return this.traces;\n }\n\n /**\n * Get traces by type\n */\n getTracesByType(type: TraceType): Trace[] {\n return this.traces.filter((t) => t.type === type);\n }\n\n /**\n * Get high-importance traces\n */\n getHighImportanceTraces(threshold: number = 0.7): Trace[] {\n return this.traces.filter((t) => t.score >= threshold);\n }\n\n /**\n * Compress old traces with intelligent strategy selection\n */\n compressOldTraces(ageHours: number = 24): number {\n let compressed = 0;\n const now = Date.now();\n\n for (const trace of this.traces) {\n const age = (now - trace.metadata.startTime) / (1000 * 60 * 60);\n if (age > ageHours && !trace.compressed) {\n // Select compression strategy based on age and importance\n const strategy = this.selectCompressionStrategy(trace);\n trace.compressed = this.compressTrace(trace, strategy);\n\n // Remove full tool data for older traces to save memory\n if (\n strategy === CompressionStrategy.FULL_COMPRESSION ||\n strategy === CompressionStrategy.SUMMARY_ONLY\n ) {\n trace.tools = []; // Clear tool data for maximum compression\n } else if (strategy === CompressionStrategy.SELECTIVE) {\n // Keep only high-score tools\n trace.tools = trace.tools.filter((tool: any) => {\n const score = this.configManager.calculateScore(tool.tool, {\n filesAffected: tool.filesAffected?.length || 0,\n isPermanent: this.isPermanentChange(tool),\n referenceCount: 0,\n });\n return score >= 0.5;\n });\n }\n\n compressed++;\n\n // Update database if available\n if (this.traceStore) {\n try {\n this.traceStore.updateCompression(\n trace.id,\n trace.compressed,\n strategy\n );\n } catch (error: unknown) {\n console.error(\n 'Failed to update trace compression in store:',\n error\n );\n }\n }\n }\n }\n\n return compressed;\n }\n\n /**\n * Export traces for analysis\n */\n exportTraces(): string {\n return JSON.stringify(this.traces, null, 2);\n }\n\n /**\n * Get statistics about traces\n */\n getStatistics() {\n const stats = {\n totalTraces: this.traces.length,\n tracesByType: {} as Record<string, number>,\n averageScore: 0,\n averageLength: 0,\n compressedCount: 0,\n highImportanceCount: 0,\n };\n\n if (this.traces.length === 0) return stats;\n\n let totalScore = 0;\n let totalLength = 0;\n\n for (const trace of this.traces) {\n // Type distribution\n stats.tracesByType[trace.type] =\n (stats.tracesByType[trace.type] || 0) + 1;\n\n // Scores\n totalScore += trace.score;\n\n // Length\n totalLength += trace.tools.length;\n\n // Compressed\n if (trace.compressed) {\n stats.compressedCount++;\n }\n\n // High importance\n if (trace.score >= 0.7) {\n stats.highImportanceCount++;\n }\n }\n\n stats.averageScore = totalScore / this.traces.length;\n stats.averageLength = totalLength / this.traces.length;\n\n return stats;\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/core/trace/types.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Types for Trace Detection and Bundling System\n */\n\nexport interface ToolCall {\n id: string;\n tool: string;\n arguments?: Record<string, any>;\n timestamp: number;\n result?: any;\n error?: string;\n filesAffected?: string[];\n duration?: number;\n}\n\nexport interface Trace {\n id: string;\n type: TraceType;\n tools: ToolCall[];\n score: number;\n summary: string;\n compressed?: CompressedTrace;\n metadata: TraceMetadata;\n}\n\nexport interface CompressedTrace {\n pattern: string; // e.g., \"search\u2192read\u2192edit\u2192test\"\n summary: string; // e.g., \"Fixed auth bug via search-driven refactor\"\n score: number;\n toolCount: number;\n duration: number;\n timestamp: number;\n}\n\nexport interface TraceMetadata {\n startTime: number;\n endTime: number;\n frameId?: string;\n userId?: string;\n filesModified: string[];\n errorsEncountered: string[];\n decisionsRecorded: string[];\n causalChain: boolean; // Was this an error\u2192fix\u2192verify chain?\n}\n\nexport enum TraceType {\n SEARCH_DRIVEN = 'search_driven',\n ERROR_RECOVERY = 'error_recovery',\n FEATURE_IMPLEMENTATION = 'feature_implementation',\n REFACTORING = 'refactoring',\n TESTING = 'testing',\n EXPLORATION = 'exploration',\n DEBUGGING = 'debugging',\n DOCUMENTATION = 'documentation',\n BUILD_DEPLOY = 'build_deploy',\n UNKNOWN = 'unknown',\n}\n\nexport interface TraceBoundaryConfig {\n timeProximityMs: number; // Max time between tools to be in same trace\n sameDirThreshold: boolean; // Must operate on same directory?\n causalRelationship: boolean; // Look for error\u2192fix patterns?\n maxTraceSize: number; // Max number of tools in one trace\n compressionThreshold: number; // Compress traces older than X hours\n}\n\nexport const DEFAULT_TRACE_CONFIG: TraceBoundaryConfig = {\n timeProximityMs: 30000, // 30 seconds\n sameDirThreshold: true,\n causalRelationship: true,\n maxTraceSize: 50,\n compressionThreshold: 24, // Compress after 24 hours\n};\n\nexport interface TracePattern {\n pattern: RegExp | string[];\n type: TraceType;\n description: string;\n}\n\n// Common patterns for trace type detection\nexport const TRACE_PATTERNS: TracePattern[] = [\n {\n pattern: ['search', 'grep', 'read', 'edit'],\n type: TraceType.SEARCH_DRIVEN,\n description: 'Search-driven code modification',\n },\n {\n pattern: ['bash', 'error', 'edit', 'bash'],\n type: TraceType.ERROR_RECOVERY,\n description: 'Error recovery sequence',\n },\n {\n pattern: ['write', 'edit', 'test'],\n type: TraceType.FEATURE_IMPLEMENTATION,\n description: 'New feature implementation',\n },\n {\n pattern: ['read', 'edit', 'edit', 'test'],\n type: TraceType.REFACTORING,\n description: 'Code refactoring',\n },\n {\n pattern: ['test', 'bash', 'test'],\n type: TraceType.TESTING,\n description: 'Test execution and validation',\n },\n {\n pattern: ['grep', 'search', 'read'],\n type: TraceType.EXPLORATION,\n description: 'Codebase exploration',\n },\n {\n pattern: ['bash', 'build', 'deploy'],\n type: TraceType.BUILD_DEPLOY,\n description: 'Build and deployment',\n },\n];\n\nexport interface TraceScoringFactors {\n toolScores: number[]; // Individual tool scores\n hasDecisions: boolean;\n hasErrors: boolean;\n filesModifiedCount: number;\n isPermanent: boolean;\n referenceCount: number;\n}\n\n// Trace compression strategies\nexport enum CompressionStrategy {\n SUMMARY_ONLY = 'summary_only', // Keep only summary and score\n PATTERN_BASED = 'pattern_based', // Keep pattern and outcome\n SELECTIVE = 'selective', // Keep high-score tools only\n FULL_COMPRESSION = 'full_compression', // Maximum compression\n}"],
|
|
4
|
+
"sourcesContent": ["/**\n * Types for Trace Detection and Bundling System\n */\n\nexport interface ToolCall {\n id: string;\n tool: string;\n arguments?: Record<string, any>;\n timestamp: number;\n result?: any;\n error?: string;\n filesAffected?: string[];\n duration?: number;\n}\n\nexport interface Trace {\n id: string;\n type: TraceType;\n tools: ToolCall[];\n score: number;\n summary: string;\n compressed?: CompressedTrace;\n metadata: TraceMetadata;\n}\n\nexport interface CompressedTrace {\n pattern: string; // e.g., \"search\u2192read\u2192edit\u2192test\"\n summary: string; // e.g., \"Fixed auth bug via search-driven refactor\"\n score: number;\n toolCount: number;\n duration: number;\n timestamp: number;\n}\n\nexport interface TraceMetadata {\n startTime: number;\n endTime: number;\n frameId?: string;\n userId?: string;\n filesModified: string[];\n errorsEncountered: string[];\n decisionsRecorded: string[];\n causalChain: boolean; // Was this an error\u2192fix\u2192verify chain?\n}\n\nexport enum TraceType {\n SEARCH_DRIVEN = 'search_driven',\n ERROR_RECOVERY = 'error_recovery',\n FEATURE_IMPLEMENTATION = 'feature_implementation',\n REFACTORING = 'refactoring',\n TESTING = 'testing',\n EXPLORATION = 'exploration',\n DEBUGGING = 'debugging',\n DOCUMENTATION = 'documentation',\n BUILD_DEPLOY = 'build_deploy',\n UNKNOWN = 'unknown',\n}\n\nexport interface TraceBoundaryConfig {\n timeProximityMs: number; // Max time between tools to be in same trace\n sameDirThreshold: boolean; // Must operate on same directory?\n causalRelationship: boolean; // Look for error\u2192fix patterns?\n maxTraceSize: number; // Max number of tools in one trace\n compressionThreshold: number; // Compress traces older than X hours\n}\n\nexport const DEFAULT_TRACE_CONFIG: TraceBoundaryConfig = {\n timeProximityMs: 30000, // 30 seconds\n sameDirThreshold: true,\n causalRelationship: true,\n maxTraceSize: 50,\n compressionThreshold: 24, // Compress after 24 hours\n};\n\nexport interface TracePattern {\n pattern: RegExp | string[];\n type: TraceType;\n description: string;\n}\n\n// Common patterns for trace type detection\nexport const TRACE_PATTERNS: TracePattern[] = [\n {\n pattern: ['search', 'grep', 'read', 'edit'],\n type: TraceType.SEARCH_DRIVEN,\n description: 'Search-driven code modification',\n },\n {\n pattern: ['bash', 'error', 'edit', 'bash'],\n type: TraceType.ERROR_RECOVERY,\n description: 'Error recovery sequence',\n },\n {\n pattern: ['write', 'edit', 'test'],\n type: TraceType.FEATURE_IMPLEMENTATION,\n description: 'New feature implementation',\n },\n {\n pattern: ['read', 'edit', 'edit', 'test'],\n type: TraceType.REFACTORING,\n description: 'Code refactoring',\n },\n {\n pattern: ['test', 'bash', 'test'],\n type: TraceType.TESTING,\n description: 'Test execution and validation',\n },\n {\n pattern: ['grep', 'search', 'read'],\n type: TraceType.EXPLORATION,\n description: 'Codebase exploration',\n },\n {\n pattern: ['bash', 'build', 'deploy'],\n type: TraceType.BUILD_DEPLOY,\n description: 'Build and deployment',\n },\n];\n\nexport interface TraceScoringFactors {\n toolScores: number[]; // Individual tool scores\n hasDecisions: boolean;\n hasErrors: boolean;\n filesModifiedCount: number;\n isPermanent: boolean;\n referenceCount: number;\n}\n\n// Trace compression strategies\nexport enum CompressionStrategy {\n SUMMARY_ONLY = 'summary_only', // Keep only summary and score\n PATTERN_BASED = 'pattern_based', // Keep pattern and outcome\n SELECTIVE = 'selective', // Keep high-score tools only\n FULL_COMPRESSION = 'full_compression', // Maximum compression\n}\n"],
|
|
5
5
|
"mappings": "AA6CO,IAAK,YAAL,kBAAKA,eAAL;AACL,EAAAA,WAAA,mBAAgB;AAChB,EAAAA,WAAA,oBAAiB;AACjB,EAAAA,WAAA,4BAAyB;AACzB,EAAAA,WAAA,iBAAc;AACd,EAAAA,WAAA,aAAU;AACV,EAAAA,WAAA,iBAAc;AACd,EAAAA,WAAA,eAAY;AACZ,EAAAA,WAAA,mBAAgB;AAChB,EAAAA,WAAA,kBAAe;AACf,EAAAA,WAAA,aAAU;AAVA,SAAAA;AAAA,GAAA;AAqBL,MAAM,uBAA4C;AAAA,EACvD,iBAAiB;AAAA;AAAA,EACjB,kBAAkB;AAAA,EAClB,oBAAoB;AAAA,EACpB,cAAc;AAAA,EACd,sBAAsB;AAAA;AACxB;AASO,MAAM,iBAAiC;AAAA,EAC5C;AAAA,IACE,SAAS,CAAC,UAAU,QAAQ,QAAQ,MAAM;AAAA,IAC1C,MAAM;AAAA,IACN,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,SAAS,CAAC,QAAQ,SAAS,QAAQ,MAAM;AAAA,IACzC,MAAM;AAAA,IACN,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,SAAS,CAAC,SAAS,QAAQ,MAAM;AAAA,IACjC,MAAM;AAAA,IACN,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,SAAS,CAAC,QAAQ,QAAQ,QAAQ,MAAM;AAAA,IACxC,MAAM;AAAA,IACN,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,SAAS,CAAC,QAAQ,QAAQ,MAAM;AAAA,IAChC,MAAM;AAAA,IACN,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,SAAS,CAAC,QAAQ,UAAU,MAAM;AAAA,IAClC,MAAM;AAAA,IACN,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,SAAS,CAAC,QAAQ,SAAS,QAAQ;AAAA,IACnC,MAAM;AAAA,IACN,aAAa;AAAA,EACf;AACF;AAYO,IAAK,sBAAL,kBAAKC,yBAAL;AACL,EAAAA,qBAAA,kBAAe;AACf,EAAAA,qBAAA,mBAAgB;AAChB,EAAAA,qBAAA,eAAY;AACZ,EAAAA,qBAAA,sBAAmB;AAJT,SAAAA;AAAA,GAAA;",
|
|
6
6
|
"names": ["TraceType", "CompressionStrategy"]
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/core/utils/compression.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Compression utilities for storage optimization\n */\n\nimport zlib from 'zlib';\nimport { promisify } from 'util';\n\nconst gzipAsync = promisify(zlib.gzip);\nconst gunzipAsync = promisify(zlib.gunzip);\nconst brotliCompressAsync = promisify(zlib.brotliCompress);\nconst brotliDecompressAsync = promisify(zlib.brotliDecompress);\n\nexport enum CompressionType {\n NONE = 'none',\n GZIP = 'gzip',\n BROTLI = 'brotli',\n}\n\nexport interface CompressionOptions {\n type?: CompressionType;\n level?: number;\n}\n\n/**\n * Compress data using specified algorithm\n */\nexport async function compress(\n data: string | Buffer,\n options: CompressionOptions = {}\n): Promise<Buffer> {\n const { type = CompressionType.GZIP, level = 6 } = options;\n
|
|
4
|
+
"sourcesContent": ["/**\n * Compression utilities for storage optimization\n */\n\nimport zlib from 'zlib';\nimport { promisify } from 'util';\n\nconst gzipAsync = promisify(zlib.gzip);\nconst gunzipAsync = promisify(zlib.gunzip);\nconst brotliCompressAsync = promisify(zlib.brotliCompress);\nconst brotliDecompressAsync = promisify(zlib.brotliDecompress);\n\nexport enum CompressionType {\n NONE = 'none',\n GZIP = 'gzip',\n BROTLI = 'brotli',\n}\n\nexport interface CompressionOptions {\n type?: CompressionType;\n level?: number;\n}\n\n/**\n * Compress data using specified algorithm\n */\nexport async function compress(\n data: string | Buffer,\n options: CompressionOptions = {}\n): Promise<Buffer> {\n const { type = CompressionType.GZIP, level = 6 } = options;\n\n const input = typeof data === 'string' ? Buffer.from(data, 'utf8') : data;\n\n switch (type) {\n case CompressionType.NONE:\n return input;\n\n case CompressionType.GZIP:\n return gzipAsync(input, { level });\n\n case CompressionType.BROTLI:\n return brotliCompressAsync(input, {\n params: {\n [zlib.constants.BROTLI_PARAM_QUALITY]: level,\n },\n });\n\n default:\n throw new Error(`Unknown compression type: ${type}`);\n }\n}\n\n/**\n * Decompress data\n */\nexport async function decompress(\n data: Buffer,\n type: CompressionType = CompressionType.GZIP\n): Promise<string> {\n let decompressed: Buffer;\n\n switch (type) {\n case CompressionType.NONE:\n decompressed = data;\n break;\n\n case CompressionType.GZIP:\n decompressed = await gunzipAsync(data);\n break;\n\n case CompressionType.BROTLI:\n decompressed = await brotliDecompressAsync(data);\n break;\n\n default:\n throw new Error(`Unknown compression type: ${type}`);\n }\n\n return decompressed.toString('utf8');\n}\n\n/**\n * Calculate compression ratio\n */\nexport function compressionRatio(original: number, compressed: number): number {\n if (original === 0) return 0;\n return (1 - compressed / original) * 100;\n}\n\n/**\n * Auto-detect compression type from buffer\n */\nexport function detectCompressionType(data: Buffer): CompressionType {\n // Check for gzip magic number\n if (data.length >= 2 && data[0] === 0x1f && data[1] === 0x8b) {\n return CompressionType.GZIP;\n }\n\n // Check for brotli\n // Brotli doesn't have a consistent magic number, but we can try to decompress\n // This is a heuristic approach\n if (data.length >= 4 && data[0] === 0xce && data[1] === 0xb2) {\n return CompressionType.BROTLI;\n }\n\n return CompressionType.NONE;\n}\n\n/**\n * Choose optimal compression based on data characteristics\n */\nexport function chooseOptimalCompression(\n data: string | Buffer,\n speedPriority: boolean = false\n): CompressionType {\n const size = typeof data === 'string' ? Buffer.byteLength(data) : data.length;\n\n // Don't compress small data\n if (size < 1024) {\n return CompressionType.NONE;\n }\n\n // Use gzip for speed priority or medium data\n if (speedPriority || size < 100 * 1024) {\n return CompressionType.GZIP;\n }\n\n // Use brotli for large data and better compression\n return CompressionType.BROTLI;\n}\n"],
|
|
5
5
|
"mappings": "AAIA,OAAO,UAAU;AACjB,SAAS,iBAAiB;AAE1B,MAAM,YAAY,UAAU,KAAK,IAAI;AACrC,MAAM,cAAc,UAAU,KAAK,MAAM;AACzC,MAAM,sBAAsB,UAAU,KAAK,cAAc;AACzD,MAAM,wBAAwB,UAAU,KAAK,gBAAgB;AAEtD,IAAK,kBAAL,kBAAKA,qBAAL;AACL,EAAAA,iBAAA,UAAO;AACP,EAAAA,iBAAA,UAAO;AACP,EAAAA,iBAAA,YAAS;AAHC,SAAAA;AAAA,GAAA;AAcZ,eAAsB,SACpB,MACA,UAA8B,CAAC,GACd;AACjB,QAAM,EAAE,OAAO,mBAAsB,QAAQ,EAAE,IAAI;AAEnD,QAAM,QAAQ,OAAO,SAAS,WAAW,OAAO,KAAK,MAAM,MAAM,IAAI;AAErE,UAAQ,MAAM;AAAA,IACZ,KAAK;AACH,aAAO;AAAA,IAET,KAAK;AACH,aAAO,UAAU,OAAO,EAAE,MAAM,CAAC;AAAA,IAEnC,KAAK;AACH,aAAO,oBAAoB,OAAO;AAAA,QAChC,QAAQ;AAAA,UACN,CAAC,KAAK,UAAU,oBAAoB,GAAG;AAAA,QACzC;AAAA,MACF,CAAC;AAAA,IAEH;AACE,YAAM,IAAI,MAAM,6BAA6B,IAAI,EAAE;AAAA,EACvD;AACF;AAKA,eAAsB,WACpB,MACA,OAAwB,mBACP;AACjB,MAAI;AAEJ,UAAQ,MAAM;AAAA,IACZ,KAAK;AACH,qBAAe;AACf;AAAA,IAEF,KAAK;AACH,qBAAe,MAAM,YAAY,IAAI;AACrC;AAAA,IAEF,KAAK;AACH,qBAAe,MAAM,sBAAsB,IAAI;AAC/C;AAAA,IAEF;AACE,YAAM,IAAI,MAAM,6BAA6B,IAAI,EAAE;AAAA,EACvD;AAEA,SAAO,aAAa,SAAS,MAAM;AACrC;AAKO,SAAS,iBAAiB,UAAkB,YAA4B;AAC7E,MAAI,aAAa,EAAG,QAAO;AAC3B,UAAQ,IAAI,aAAa,YAAY;AACvC;AAKO,SAAS,sBAAsB,MAA+B;AAEnE,MAAI,KAAK,UAAU,KAAK,KAAK,CAAC,MAAM,MAAQ,KAAK,CAAC,MAAM,KAAM;AAC5D,WAAO;AAAA,EACT;AAKA,MAAI,KAAK,UAAU,KAAK,KAAK,CAAC,MAAM,OAAQ,KAAK,CAAC,MAAM,KAAM;AAC5D,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAKO,SAAS,yBACd,MACA,gBAAyB,OACR;AACjB,QAAM,OAAO,OAAO,SAAS,WAAW,OAAO,WAAW,IAAI,IAAI,KAAK;AAGvE,MAAI,OAAO,MAAM;AACf,WAAO;AAAA,EACT;AAGA,MAAI,iBAAiB,OAAO,MAAM,MAAM;AACtC,WAAO;AAAA,EACT;AAGA,SAAO;AACT;",
|
|
6
6
|
"names": ["CompressionType"]
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/core/utils/update-checker.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Update checker for StackMemory\n * Checks npm registry for newer versions\n */\n\nimport { execSync } from 'child_process';\nimport { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';\nimport { join } from 'path';\nimport { homedir } from 'os';\nimport { logger } from '../monitoring/logger.js';\nimport {
|
|
4
|
+
"sourcesContent": ["/**\n * Update checker for StackMemory\n * Checks npm registry for newer versions\n */\n\nimport { execSync } from 'child_process';\nimport { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';\nimport { join } from 'path';\nimport { homedir } from 'os';\nimport { logger } from '../monitoring/logger.js';\nimport {\n SystemError,\n ErrorCode,\n getErrorMessage,\n wrapError,\n} from '../errors/index.js';\nimport { withTimeout, gracefulDegrade } from '../errors/recovery.js';\n\ninterface UpdateCache {\n lastChecked: number;\n latestVersion: string;\n currentVersion: string;\n}\n\nexport class UpdateChecker {\n private static CACHE_FILE = join(\n homedir(),\n '.stackmemory',\n 'update-check.json'\n );\n private static CHECK_INTERVAL = 24 * 60 * 60 * 1000; // 24 hours\n private static PACKAGE_NAME = '@stackmemoryai/stackmemory';\n\n /**\n * Check for updates and display notification if needed\n */\n static async checkForUpdates(\n currentVersion: string,\n silent = false\n ): Promise<void> {\n try {\n // Check cache first\n const cache = this.loadCache();\n const now = Date.now();\n\n // Skip check if we checked recently\n if (cache && now - cache.lastChecked < this.CHECK_INTERVAL) {\n if (\n !silent &&\n cache.latestVersion &&\n cache.latestVersion !== currentVersion\n ) {\n this.displayUpdateNotification(currentVersion, cache.latestVersion);\n }\n return;\n }\n\n // Fetch latest version from npm\n const latestVersion = await this.fetchLatestVersion();\n\n // Update cache\n this.saveCache({\n lastChecked: now,\n latestVersion,\n currentVersion,\n });\n\n // Display notification if update available\n if (\n !silent &&\n latestVersion &&\n this.isNewerVersion(currentVersion, latestVersion)\n ) {\n this.displayUpdateNotification(currentVersion, latestVersion);\n }\n } catch (error: unknown) {\n // Log the error with proper context but don't interrupt user workflow\n const wrappedError = wrapError(\n error,\n 'Update check failed',\n ErrorCode.INTERNAL_ERROR,\n { currentVersion, silent }\n );\n logger.debug('Update check failed:', {\n error: getErrorMessage(error),\n context: wrappedError.context,\n });\n }\n }\n\n /**\n * Fetch latest version from npm registry\n */\n private static async fetchLatestVersion(): Promise<string> {\n try {\n // Use timeout to prevent hanging on slow network\n const fetchVersion = async () => {\n const output = execSync(`npm view ${this.PACKAGE_NAME} version`, {\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'ignore'],\n timeout: 5000, // 5 second timeout\n }).trim();\n return output;\n };\n\n // Wrap with timeout and graceful degradation\n return await gracefulDegrade(\n () => withTimeout(fetchVersion, 5000, 'npm registry timeout'),\n '',\n { operation: 'fetchLatestVersion', package: this.PACKAGE_NAME }\n );\n } catch (error: unknown) {\n const wrappedError = wrapError(\n error,\n 'Failed to fetch latest version from npm',\n ErrorCode.SERVICE_UNAVAILABLE,\n { package: this.PACKAGE_NAME }\n );\n logger.debug('Failed to fetch latest version:', {\n error: getErrorMessage(error),\n context: wrappedError.context,\n });\n return '';\n }\n }\n\n /**\n * Compare version strings\n */\n private static isNewerVersion(current: string, latest: string): boolean {\n try {\n const currentParts = current.split('.').map(Number);\n const latestParts = latest.split('.').map(Number);\n\n // Handle malformed version strings\n if (currentParts.some(isNaN) || latestParts.some(isNaN)) {\n logger.debug('Invalid version format:', { current, latest });\n return false;\n }\n\n for (let i = 0; i < 3; i++) {\n const latestPart = latestParts[i] ?? 0;\n const currentPart = currentParts[i] ?? 0;\n if (latestPart > currentPart) return true;\n if (latestPart < currentPart) return false;\n }\n return false;\n } catch (error: unknown) {\n logger.debug('Version comparison failed:', {\n error: getErrorMessage(error),\n current,\n latest,\n });\n return false;\n }\n }\n\n /**\n * Display update notification\n */\n private static displayUpdateNotification(\n current: string,\n latest: string\n ): void {\n console.log('\\n' + '\u2500'.repeat(60));\n console.log('\uD83D\uDCE6 StackMemory Update Available!');\n console.log(` Current: v${current}`);\n console.log(` Latest: v${latest}`);\n console.log('\\n Update with:');\n console.log(' npm install -g @stackmemoryai/stackmemory@latest');\n console.log('\u2500'.repeat(60) + '\\n');\n }\n\n /**\n * Load update cache\n */\n private static loadCache(): UpdateCache | null {\n try {\n if (!existsSync(this.CACHE_FILE)) {\n return null;\n }\n\n const data = readFileSync(this.CACHE_FILE, 'utf-8');\n const cache = JSON.parse(data) as UpdateCache;\n\n // Validate cache structure\n if (\n typeof cache.lastChecked !== 'number' ||\n typeof cache.latestVersion !== 'string' ||\n typeof cache.currentVersion !== 'string'\n ) {\n logger.debug('Invalid cache format, ignoring');\n return null;\n }\n\n return cache;\n } catch (error: unknown) {\n // Cache errors should not interrupt operation\n const wrappedError = wrapError(\n error,\n 'Failed to load update cache',\n ErrorCode.INTERNAL_ERROR,\n { cacheFile: this.CACHE_FILE }\n );\n logger.debug('Failed to load update cache:', {\n error: getErrorMessage(error),\n context: wrappedError.context,\n });\n return null;\n }\n }\n\n /**\n * Save update cache\n */\n private static saveCache(cache: UpdateCache): void {\n try {\n const dir = join(homedir(), '.stackmemory');\n\n // Create directory if it doesn't exist (safer than execSync)\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true, mode: 0o755 });\n }\n\n // Write cache with atomic operation (write to temp, then rename)\n const tempFile = `${this.CACHE_FILE}.tmp`;\n writeFileSync(tempFile, JSON.stringify(cache, null, 2), {\n mode: 0o644,\n });\n\n // Atomic rename\n if (existsSync(this.CACHE_FILE)) {\n writeFileSync(this.CACHE_FILE, JSON.stringify(cache, null, 2));\n } else {\n writeFileSync(this.CACHE_FILE, JSON.stringify(cache, null, 2));\n }\n } catch (error: unknown) {\n // Cache save errors should not interrupt operation\n const wrappedError = wrapError(\n error,\n 'Failed to save update cache',\n ErrorCode.INTERNAL_ERROR,\n { cacheFile: this.CACHE_FILE, cache }\n );\n logger.debug('Failed to save update cache:', {\n error: getErrorMessage(error),\n context: wrappedError.context,\n });\n }\n }\n\n /**\n * Force check for updates (ignores cache)\n */\n static async forceCheck(currentVersion: string): Promise<void> {\n try {\n const latestVersion = await this.fetchLatestVersion();\n\n // Update cache\n this.saveCache({\n lastChecked: Date.now(),\n latestVersion,\n currentVersion,\n });\n\n if (latestVersion) {\n if (this.isNewerVersion(currentVersion, latestVersion)) {\n this.displayUpdateNotification(currentVersion, latestVersion);\n } else {\n console.log(`\u2705 StackMemory is up to date (v${currentVersion})`);\n }\n }\n } catch (error: unknown) {\n console.error('\u274C Update check failed:', (error as Error).message);\n }\n }\n}\n"],
|
|
5
5
|
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -217,7 +217,10 @@ class WorktreeManager {
|
|
|
217
217
|
isBare: partial.isBare || false,
|
|
218
218
|
isDetached: partial.isDetached || false,
|
|
219
219
|
linkedPath: partial.linkedPath,
|
|
220
|
-
contextId: this.generateContextId(
|
|
220
|
+
contextId: this.generateContextId(
|
|
221
|
+
partial.path || "",
|
|
222
|
+
partial.branch || ""
|
|
223
|
+
)
|
|
221
224
|
};
|
|
222
225
|
}
|
|
223
226
|
/**
|
|
@@ -261,7 +264,9 @@ class WorktreeManager {
|
|
|
261
264
|
if (cached) {
|
|
262
265
|
return cached;
|
|
263
266
|
}
|
|
264
|
-
const worktree = this.worktreeCache.get(worktreePath) || this.detectWorktrees(worktreePath).find(
|
|
267
|
+
const worktree = this.worktreeCache.get(worktreePath) || this.detectWorktrees(worktreePath).find(
|
|
268
|
+
(w) => w.path === worktreePath
|
|
269
|
+
);
|
|
265
270
|
if (!worktree) {
|
|
266
271
|
throw new Error(`No worktree found at path: ${worktreePath}`);
|
|
267
272
|
}
|
|
@@ -327,20 +332,24 @@ class WorktreeManager {
|
|
|
327
332
|
const sourceDb = new Database(source.dbPath);
|
|
328
333
|
const targetDb = new Database(target.dbPath);
|
|
329
334
|
try {
|
|
330
|
-
const contexts = sourceDb.prepare(
|
|
335
|
+
const contexts = sourceDb.prepare(
|
|
336
|
+
`
|
|
331
337
|
SELECT * FROM contexts
|
|
332
338
|
WHERE created_at > datetime('now', '-7 days')
|
|
333
339
|
ORDER BY created_at DESC
|
|
334
|
-
`
|
|
340
|
+
`
|
|
341
|
+
).all();
|
|
335
342
|
if (syncType === "push" || syncType === "merge") {
|
|
336
343
|
this.mergeContexts(contexts, targetDb, syncType === "merge");
|
|
337
344
|
}
|
|
338
345
|
if (syncType === "pull") {
|
|
339
|
-
const targetContexts = targetDb.prepare(
|
|
346
|
+
const targetContexts = targetDb.prepare(
|
|
347
|
+
`
|
|
340
348
|
SELECT * FROM contexts
|
|
341
349
|
WHERE created_at > datetime('now', '-7 days')
|
|
342
350
|
ORDER BY created_at DESC
|
|
343
|
-
`
|
|
351
|
+
`
|
|
352
|
+
).all();
|
|
344
353
|
this.mergeContexts(targetContexts, sourceDb, false);
|
|
345
354
|
}
|
|
346
355
|
if (this.db) {
|
|
@@ -413,7 +422,9 @@ class WorktreeManager {
|
|
|
413
422
|
const stmt = this.db.prepare("SELECT * FROM worktrees");
|
|
414
423
|
const stored = stmt.all();
|
|
415
424
|
const deleteStmt = this.db.prepare("DELETE FROM worktrees WHERE id = ?");
|
|
416
|
-
const deleteContextStmt = this.db.prepare(
|
|
425
|
+
const deleteContextStmt = this.db.prepare(
|
|
426
|
+
"DELETE FROM worktree_contexts WHERE worktree_id = ?"
|
|
427
|
+
);
|
|
417
428
|
for (const worktree of stored) {
|
|
418
429
|
if (!activePaths.has(worktree.path)) {
|
|
419
430
|
deleteStmt.run(worktree.id);
|