@stackmemoryai/stackmemory 0.5.52 → 0.5.53
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/cli/commands/handoff.js +191 -50
- package/dist/cli/commands/handoff.js.map +2 -2
- package/package.json +1 -1
- package/dist/core/context/compaction-handler.js +0 -330
- package/dist/core/context/compaction-handler.js.map +0 -7
- package/dist/core/context/context-bridge.js +0 -238
- package/dist/core/context/context-bridge.js.map +0 -7
- package/scripts/testing/scripts/testing/ab-test-runner.js +0 -363
- package/scripts/testing/scripts/testing/collect-metrics.js +0 -292
- package/scripts/testing/src/core/context/context-bridge.js +0 -253
- package/scripts/testing/src/core/context/frame-manager.js +0 -746
- package/scripts/testing/src/core/context/shared-context-layer.js +0 -437
- package/scripts/testing/src/core/database/database-adapter.js +0 -54
- package/scripts/testing/src/core/errors/index.js +0 -291
- package/scripts/testing/src/core/errors/recovery.js +0 -268
- package/scripts/testing/src/core/monitoring/logger.js +0 -145
- package/scripts/testing/src/core/retrieval/context-retriever.js +0 -516
- package/scripts/testing/src/core/session/index.js +0 -1
- package/scripts/testing/src/core/session/session-manager.js +0 -323
- package/scripts/testing/src/core/trace/cli-trace-wrapper.js +0 -140
- package/scripts/testing/src/core/trace/db-trace-wrapper.js +0 -251
- package/scripts/testing/src/core/trace/debug-trace.js +0 -398
- package/scripts/testing/src/core/trace/index.js +0 -120
- package/scripts/testing/src/core/trace/linear-api-wrapper.js +0 -204
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Trace Module Export
|
|
3
|
-
* Central export for all tracing functionality
|
|
4
|
-
*/
|
|
5
|
-
export { trace, TraceContext, Trace, TraceClass, TraceCritical, } from './debug-trace.js';
|
|
6
|
-
export { wrapCommand, wrapProgram, traceStep, traceQuery, traceAPI, } from './cli-trace-wrapper.js';
|
|
7
|
-
export { createTracedDatabase, wrapDatabase, getQueryStatistics, createTracedTransaction, } from './db-trace-wrapper.js';
|
|
8
|
-
export { TraceLinearAPI, createTracedFetch, wrapGraphQLClient, } from './linear-api-wrapper.js';
|
|
9
|
-
/**
|
|
10
|
-
* Initialize tracing based on environment configuration
|
|
11
|
-
*/
|
|
12
|
-
export function initializeTracing() {
|
|
13
|
-
const config = {
|
|
14
|
-
// Main control
|
|
15
|
-
DEBUG_TRACE: process.env.DEBUG_TRACE === 'true',
|
|
16
|
-
STACKMEMORY_DEBUG: process.env.STACKMEMORY_DEBUG === 'true',
|
|
17
|
-
// Output control
|
|
18
|
-
TRACE_OUTPUT: process.env.TRACE_OUTPUT || 'console', // console|file|both
|
|
19
|
-
TRACE_VERBOSITY: process.env.TRACE_VERBOSITY || 'full', // full|errors|summary
|
|
20
|
-
// Content control
|
|
21
|
-
TRACE_PARAMS: process.env.TRACE_PARAMS !== 'false', // Include parameters
|
|
22
|
-
TRACE_RESULTS: process.env.TRACE_RESULTS !== 'false', // Include results
|
|
23
|
-
TRACE_MASK_SENSITIVE: process.env.TRACE_MASK_SENSITIVE !== 'false', // Mask sensitive data
|
|
24
|
-
// Performance
|
|
25
|
-
TRACE_PERF_THRESHOLD: parseInt(process.env.TRACE_PERF_THRESHOLD || '100'), // ms
|
|
26
|
-
TRACE_MEMORY: process.env.TRACE_MEMORY === 'true', // Track memory usage
|
|
27
|
-
TRACE_MAX_DEPTH: parseInt(process.env.TRACE_MAX_DEPTH || '20'), // Max call depth
|
|
28
|
-
// Database specific
|
|
29
|
-
TRACE_DB: process.env.TRACE_DB === 'true', // Enable database tracing
|
|
30
|
-
TRACE_DB_SLOW: parseInt(process.env.TRACE_DB_SLOW || '100'), // Slow query threshold
|
|
31
|
-
// API specific
|
|
32
|
-
TRACE_API: process.env.TRACE_API === 'true', // Enable API tracing
|
|
33
|
-
TRACE_API_SLOW: parseInt(process.env.TRACE_API_SLOW || '1000'), // Slow API threshold
|
|
34
|
-
};
|
|
35
|
-
// Log configuration if debugging is enabled
|
|
36
|
-
if (config.DEBUG_TRACE || config.STACKMEMORY_DEBUG) {
|
|
37
|
-
console.log('🔍 Trace Configuration:', {
|
|
38
|
-
enabled: true,
|
|
39
|
-
output: config.TRACE_OUTPUT,
|
|
40
|
-
verbosity: config.TRACE_VERBOSITY,
|
|
41
|
-
includeParams: config.TRACE_PARAMS,
|
|
42
|
-
includeResults: config.TRACE_RESULTS,
|
|
43
|
-
maskSensitive: config.TRACE_MASK_SENSITIVE,
|
|
44
|
-
performanceThreshold: config.TRACE_PERF_THRESHOLD,
|
|
45
|
-
captureMemory: config.TRACE_MEMORY,
|
|
46
|
-
maxDepth: config.TRACE_MAX_DEPTH,
|
|
47
|
-
database: {
|
|
48
|
-
enabled: config.TRACE_DB,
|
|
49
|
-
slowThreshold: config.TRACE_DB_SLOW,
|
|
50
|
-
},
|
|
51
|
-
api: {
|
|
52
|
-
enabled: config.TRACE_API,
|
|
53
|
-
slowThreshold: config.TRACE_API_SLOW,
|
|
54
|
-
},
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* Helper to enable tracing for a specific scope
|
|
60
|
-
*/
|
|
61
|
-
export function withTracing(fn, options) {
|
|
62
|
-
const originalEnv = process.env.DEBUG_TRACE;
|
|
63
|
-
try {
|
|
64
|
-
// Temporarily enable tracing
|
|
65
|
-
process.env.DEBUG_TRACE = 'true';
|
|
66
|
-
// Apply custom options if provided
|
|
67
|
-
if (options) {
|
|
68
|
-
if (options.output)
|
|
69
|
-
process.env.TRACE_OUTPUT = options.output;
|
|
70
|
-
if (options.verbosity)
|
|
71
|
-
process.env.TRACE_VERBOSITY = options.verbosity;
|
|
72
|
-
if (options.includeParams !== undefined) {
|
|
73
|
-
process.env.TRACE_PARAMS = String(options.includeParams);
|
|
74
|
-
}
|
|
75
|
-
if (options.includeResults !== undefined) {
|
|
76
|
-
process.env.TRACE_RESULTS = String(options.includeResults);
|
|
77
|
-
}
|
|
78
|
-
if (options.performanceThreshold !== undefined) {
|
|
79
|
-
process.env.TRACE_PERF_THRESHOLD = String(options.performanceThreshold);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
return fn();
|
|
83
|
-
}
|
|
84
|
-
finally {
|
|
85
|
-
// Restore original environment
|
|
86
|
-
if (originalEnv === undefined) {
|
|
87
|
-
delete process.env.DEBUG_TRACE;
|
|
88
|
-
}
|
|
89
|
-
else {
|
|
90
|
-
process.env.DEBUG_TRACE = originalEnv;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* Quick enable/disable functions for debugging
|
|
96
|
-
*/
|
|
97
|
-
export const enableTracing = () => {
|
|
98
|
-
process.env.DEBUG_TRACE = 'true';
|
|
99
|
-
console.log('✅ Tracing enabled');
|
|
100
|
-
};
|
|
101
|
-
export const disableTracing = () => {
|
|
102
|
-
delete process.env.DEBUG_TRACE;
|
|
103
|
-
console.log('❌ Tracing disabled');
|
|
104
|
-
};
|
|
105
|
-
export const enableVerboseTracing = () => {
|
|
106
|
-
process.env.DEBUG_TRACE = 'true';
|
|
107
|
-
process.env.TRACE_VERBOSITY = 'full';
|
|
108
|
-
process.env.TRACE_PARAMS = 'true';
|
|
109
|
-
process.env.TRACE_RESULTS = 'true';
|
|
110
|
-
process.env.TRACE_MEMORY = 'true';
|
|
111
|
-
console.log('✅ Verbose tracing enabled');
|
|
112
|
-
};
|
|
113
|
-
export const enableMinimalTracing = () => {
|
|
114
|
-
process.env.DEBUG_TRACE = 'true';
|
|
115
|
-
process.env.TRACE_VERBOSITY = 'summary';
|
|
116
|
-
process.env.TRACE_PARAMS = 'false';
|
|
117
|
-
process.env.TRACE_RESULTS = 'false';
|
|
118
|
-
process.env.TRACE_MEMORY = 'false';
|
|
119
|
-
console.log('✅ Minimal tracing enabled');
|
|
120
|
-
};
|
|
@@ -1,204 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Linear API Trace Wrapper
|
|
3
|
-
* Wraps Linear API client with comprehensive tracing for debugging
|
|
4
|
-
*/
|
|
5
|
-
import { trace } from './debug-trace.js';
|
|
6
|
-
import { logger } from '../monitoring/logger.js';
|
|
7
|
-
/**
|
|
8
|
-
* Decorator to trace Linear API GraphQL calls
|
|
9
|
-
*/
|
|
10
|
-
export function TraceLinearAPI(target, propertyKey, descriptor) {
|
|
11
|
-
const originalMethod = descriptor.value;
|
|
12
|
-
const isAsync = originalMethod.constructor.name === 'AsyncFunction';
|
|
13
|
-
if (isAsync) {
|
|
14
|
-
descriptor.value = async function (...args) {
|
|
15
|
-
const className = target.constructor.name;
|
|
16
|
-
const methodName = `${className}.${propertyKey}`;
|
|
17
|
-
// Extract meaningful context from arguments
|
|
18
|
-
const context = extractAPIContext(propertyKey, args);
|
|
19
|
-
return trace.traceAsync('api', methodName, context, async () => {
|
|
20
|
-
const startTime = Date.now();
|
|
21
|
-
try {
|
|
22
|
-
// Log API call start
|
|
23
|
-
logger.debug(`Linear API Call: ${methodName}`, context);
|
|
24
|
-
const result = await originalMethod.apply(this, args);
|
|
25
|
-
const duration = Date.now() - startTime;
|
|
26
|
-
// Log successful completion with timing
|
|
27
|
-
logger.info(`Linear API Success: ${methodName}`, {
|
|
28
|
-
duration,
|
|
29
|
-
resultType: Array.isArray(result) ? `array[${result.length}]` : typeof result,
|
|
30
|
-
hasData: result != null,
|
|
31
|
-
});
|
|
32
|
-
// Warn about slow API calls
|
|
33
|
-
if (duration > 1000) {
|
|
34
|
-
logger.warn(`Slow Linear API call: ${methodName} took ${duration}ms`, {
|
|
35
|
-
...context,
|
|
36
|
-
duration,
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
return result;
|
|
40
|
-
}
|
|
41
|
-
catch (error) {
|
|
42
|
-
const duration = Date.now() - startTime;
|
|
43
|
-
// Enhanced error logging for API failures
|
|
44
|
-
logger.error(`Linear API Failed: ${methodName}`, error, {
|
|
45
|
-
...context,
|
|
46
|
-
duration,
|
|
47
|
-
errorCode: error.code,
|
|
48
|
-
statusCode: error.statusCode,
|
|
49
|
-
graphQLErrors: error.errors,
|
|
50
|
-
});
|
|
51
|
-
// Add debugging hints based on error type
|
|
52
|
-
if (error.message?.includes('rate limit')) {
|
|
53
|
-
logger.warn('Rate limit hit - consider implementing backoff', {
|
|
54
|
-
method: methodName,
|
|
55
|
-
suggestion: 'Implement exponential backoff or request queuing',
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
else if (error.message?.includes('network')) {
|
|
59
|
-
logger.warn('Network error - check connectivity', {
|
|
60
|
-
method: methodName,
|
|
61
|
-
suggestion: 'Verify API endpoint and network connectivity',
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
else if (error.message?.includes('unauthorized')) {
|
|
65
|
-
logger.warn('Authorization error - check API key', {
|
|
66
|
-
method: methodName,
|
|
67
|
-
suggestion: 'Verify LINEAR_API_KEY is set and valid',
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
throw error;
|
|
71
|
-
}
|
|
72
|
-
});
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
else {
|
|
76
|
-
descriptor.value = function (...args) {
|
|
77
|
-
const className = target.constructor.name;
|
|
78
|
-
const methodName = `${className}.${propertyKey}`;
|
|
79
|
-
const context = extractAPIContext(propertyKey, args);
|
|
80
|
-
return trace.traceSync('api', methodName, context, () => {
|
|
81
|
-
return originalMethod.apply(this, args);
|
|
82
|
-
});
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
return descriptor;
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Extract meaningful context from API method arguments
|
|
89
|
-
*/
|
|
90
|
-
function extractAPIContext(methodName, args) {
|
|
91
|
-
const context = {};
|
|
92
|
-
// Handle different Linear API methods
|
|
93
|
-
if (methodName === 'createIssue' && args[0]) {
|
|
94
|
-
context.title = args[0].title;
|
|
95
|
-
context.teamId = args[0].teamId;
|
|
96
|
-
context.priority = args[0].priority;
|
|
97
|
-
}
|
|
98
|
-
else if (methodName === 'updateIssue' && args[0]) {
|
|
99
|
-
context.issueId = args[0];
|
|
100
|
-
context.updates = Object.keys(args[1] || {});
|
|
101
|
-
}
|
|
102
|
-
else if (methodName === 'getIssue') {
|
|
103
|
-
context.issueId = args[0];
|
|
104
|
-
}
|
|
105
|
-
else if (methodName === 'getIssues' && args[0]) {
|
|
106
|
-
context.filter = args[0];
|
|
107
|
-
}
|
|
108
|
-
else if (methodName === 'graphql') {
|
|
109
|
-
// For raw GraphQL queries
|
|
110
|
-
const query = args[0];
|
|
111
|
-
if (query) {
|
|
112
|
-
// Extract operation name from query
|
|
113
|
-
const match = query.match(/(?:query|mutation)\s+(\w+)/);
|
|
114
|
-
context.operation = match ? match[1] : 'unknown';
|
|
115
|
-
context.queryLength = query.length;
|
|
116
|
-
context.variables = args[1] ? Object.keys(args[1]) : [];
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
return context;
|
|
120
|
-
}
|
|
121
|
-
/**
|
|
122
|
-
* Wrap fetch with tracing for HTTP-level debugging
|
|
123
|
-
*/
|
|
124
|
-
export function createTracedFetch(baseFetch = fetch) {
|
|
125
|
-
return async function tracedFetch(input, init) {
|
|
126
|
-
const url = typeof input === 'string' ? input : input.toString();
|
|
127
|
-
const method = init?.method || 'GET';
|
|
128
|
-
// Mask sensitive headers
|
|
129
|
-
const headers = init?.headers ? { ...init.headers } : {};
|
|
130
|
-
if (headers.Authorization) {
|
|
131
|
-
headers.Authorization = headers.Authorization.substring(0, 20) + '...[MASKED]';
|
|
132
|
-
}
|
|
133
|
-
const context = {
|
|
134
|
-
method,
|
|
135
|
-
url: url.length > 100 ? url.substring(0, 100) + '...' : url,
|
|
136
|
-
headers: Object.keys(headers),
|
|
137
|
-
bodySize: init?.body ? JSON.stringify(init.body).length : 0,
|
|
138
|
-
};
|
|
139
|
-
return trace.api(method, url, context, async () => {
|
|
140
|
-
const startTime = Date.now();
|
|
141
|
-
try {
|
|
142
|
-
const response = await baseFetch(input, init);
|
|
143
|
-
const duration = Date.now() - startTime;
|
|
144
|
-
// Log response details
|
|
145
|
-
logger.debug(`HTTP ${method} ${response.status}`, {
|
|
146
|
-
url: url.substring(0, 100),
|
|
147
|
-
status: response.status,
|
|
148
|
-
duration,
|
|
149
|
-
headers: {
|
|
150
|
-
'content-type': response.headers.get('content-type'),
|
|
151
|
-
'x-ratelimit-remaining': response.headers.get('x-ratelimit-remaining'),
|
|
152
|
-
'x-ratelimit-reset': response.headers.get('x-ratelimit-reset'),
|
|
153
|
-
},
|
|
154
|
-
});
|
|
155
|
-
// Warn about rate limiting
|
|
156
|
-
const remaining = response.headers.get('x-ratelimit-remaining');
|
|
157
|
-
if (remaining && parseInt(remaining) < 10) {
|
|
158
|
-
logger.warn(`Low rate limit remaining: ${remaining}`, {
|
|
159
|
-
url: url.substring(0, 100),
|
|
160
|
-
resetAt: response.headers.get('x-ratelimit-reset'),
|
|
161
|
-
});
|
|
162
|
-
}
|
|
163
|
-
// Warn about slow responses
|
|
164
|
-
if (duration > 2000) {
|
|
165
|
-
logger.warn(`Slow HTTP response: ${duration}ms`, {
|
|
166
|
-
method,
|
|
167
|
-
url: url.substring(0, 100),
|
|
168
|
-
status: response.status,
|
|
169
|
-
});
|
|
170
|
-
}
|
|
171
|
-
return response;
|
|
172
|
-
}
|
|
173
|
-
catch (error) {
|
|
174
|
-
const duration = Date.now() - startTime;
|
|
175
|
-
logger.error(`HTTP ${method} failed`, error, {
|
|
176
|
-
url: url.substring(0, 100),
|
|
177
|
-
duration,
|
|
178
|
-
errorType: error.constructor.name,
|
|
179
|
-
errno: error.errno,
|
|
180
|
-
code: error.code,
|
|
181
|
-
});
|
|
182
|
-
throw error;
|
|
183
|
-
}
|
|
184
|
-
});
|
|
185
|
-
};
|
|
186
|
-
}
|
|
187
|
-
/**
|
|
188
|
-
* Create a traced GraphQL client wrapper
|
|
189
|
-
*/
|
|
190
|
-
export function wrapGraphQLClient(client) {
|
|
191
|
-
const prototype = Object.getPrototypeOf(client);
|
|
192
|
-
const propertyNames = Object.getOwnPropertyNames(prototype);
|
|
193
|
-
for (const propertyName of propertyNames) {
|
|
194
|
-
if (propertyName === 'constructor')
|
|
195
|
-
continue;
|
|
196
|
-
const descriptor = Object.getOwnPropertyDescriptor(prototype, propertyName);
|
|
197
|
-
if (!descriptor || typeof descriptor.value !== 'function')
|
|
198
|
-
continue;
|
|
199
|
-
// Apply tracing to all methods
|
|
200
|
-
TraceLinearAPI(prototype, propertyName, descriptor);
|
|
201
|
-
Object.defineProperty(prototype, propertyName, descriptor);
|
|
202
|
-
}
|
|
203
|
-
return client;
|
|
204
|
-
}
|