@stackmemoryai/stackmemory 0.3.9 → 0.3.11
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/README.md +54 -0
- package/dist/agents/core/agent-task-manager.js +12 -1
- package/dist/agents/core/agent-task-manager.js.map +3 -3
- package/dist/agents/testing-agent.js +610 -0
- package/dist/agents/testing-agent.js.map +7 -0
- package/dist/cli/browser-test.js +4 -4
- package/dist/cli/browser-test.js.map +2 -2
- package/dist/cli/claude-sm.js +2 -2
- package/dist/cli/claude-sm.js.map +2 -2
- package/dist/cli/codex-sm.js +5 -5
- package/dist/cli/codex-sm.js.map +2 -2
- package/dist/cli/commands/agent.js +3 -3
- package/dist/cli/commands/agent.js.map +2 -2
- package/dist/cli/commands/handoff.js +67 -20
- package/dist/cli/commands/handoff.js.map +3 -3
- package/dist/cli/commands/linear-unified.js +3 -3
- package/dist/cli/commands/linear-unified.js.map +2 -2
- package/dist/cli/commands/linear.js +2 -2
- package/dist/cli/commands/linear.js.map +2 -2
- package/dist/cli/commands/onboard.js +3 -3
- package/dist/cli/commands/onboard.js.map +2 -2
- package/dist/cli/commands/quality.js +2 -2
- package/dist/cli/commands/quality.js.map +2 -2
- package/dist/cli/commands/skills.js +113 -28
- package/dist/cli/commands/skills.js.map +2 -2
- package/dist/cli/commands/tasks.js +3 -3
- package/dist/cli/commands/tasks.js.map +2 -2
- package/dist/cli/commands/test.js +282 -0
- package/dist/cli/commands/test.js.map +7 -0
- package/dist/cli/commands/worktree.js +28 -10
- package/dist/cli/commands/worktree.js.map +2 -2
- package/dist/cli/index.js +5 -3
- package/dist/cli/index.js.map +2 -2
- package/dist/cli/utils/viewer.js +9 -9
- package/dist/cli/utils/viewer.js.map +2 -2
- package/dist/core/config/config-manager.js +26 -0
- package/dist/core/config/config-manager.js.map +3 -3
- package/dist/core/context/frame-handoff-manager.js +4 -4
- package/dist/core/context/frame-handoff-manager.js.map +1 -1
- package/dist/core/context/frame-manager.js +139 -0
- package/dist/core/context/frame-manager.js.map +2 -2
- package/dist/core/context/refactored-frame-manager.js +180 -1
- package/dist/core/context/refactored-frame-manager.js.map +2 -2
- package/dist/core/projects/project-isolation.js +197 -0
- package/dist/core/projects/project-isolation.js.map +7 -0
- package/dist/core/trace/debug-trace.js +1 -1
- package/dist/core/trace/debug-trace.js.map +2 -2
- package/dist/core/trace/index.js +4 -4
- package/dist/core/trace/index.js.map +2 -2
- package/dist/core/trace/trace-demo.js +8 -8
- package/dist/core/trace/trace-demo.js.map +2 -2
- package/dist/core/trace/trace-detector.demo.js +5 -5
- package/dist/core/trace/trace-detector.demo.js.map +2 -2
- package/dist/core/utils/update-checker.js +2 -2
- package/dist/core/utils/update-checker.js.map +2 -2
- package/dist/features/analytics/core/analytics-service.js +2 -2
- package/dist/features/analytics/core/analytics-service.js.map +2 -2
- package/dist/features/tasks/linear-task-manager.js +483 -0
- package/dist/features/tasks/linear-task-manager.js.map +7 -0
- package/dist/integrations/claude-code/subagent-client-stub.js +16 -0
- package/dist/integrations/claude-code/subagent-client-stub.js.map +7 -0
- package/dist/integrations/linear/auto-sync.js +2 -2
- package/dist/integrations/linear/auto-sync.js.map +2 -2
- package/dist/integrations/linear/config.js +12 -1
- package/dist/integrations/linear/config.js.map +2 -2
- package/dist/integrations/linear/sync-manager.js.map +1 -1
- package/dist/integrations/linear/sync.js.map +1 -1
- package/dist/integrations/linear/unified-sync.js.map +1 -1
- package/dist/integrations/linear/webhook-handler.js.map +2 -2
- package/dist/integrations/linear/webhook.js.map +2 -2
- package/dist/integrations/mcp/handlers/linear-handlers.js.map +1 -1
- package/dist/integrations/mcp/handlers/task-handlers.js.map +1 -1
- package/dist/integrations/mcp/refactored-server.js +2 -2
- package/dist/integrations/mcp/refactored-server.js.map +2 -2
- package/dist/integrations/mcp/server.js +3 -3
- package/dist/integrations/mcp/server.js.map +2 -2
- package/dist/mcp/stackmemory-mcp-server.js +3 -3
- package/dist/mcp/stackmemory-mcp-server.js.map +2 -2
- package/dist/skills/claude-skills.js +99 -5
- package/dist/skills/claude-skills.js.map +2 -2
- package/dist/skills/recursive-agent-orchestrator.js.map +1 -1
- package/dist/skills/security-secrets-scanner.js +21 -6
- package/dist/skills/security-secrets-scanner.js.map +2 -2
- package/dist/skills/unified-rlm-orchestrator.js +400 -0
- package/dist/skills/unified-rlm-orchestrator.js.map +7 -0
- package/package.json +4 -5
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { execSync } from "child_process";
|
|
2
|
+
import { createHash } from "crypto";
|
|
3
|
+
import { logger } from "../monitoring/logger.js";
|
|
4
|
+
class ProjectIsolationManager {
|
|
5
|
+
static instance;
|
|
6
|
+
projectCache = /* @__PURE__ */ new Map();
|
|
7
|
+
static getInstance() {
|
|
8
|
+
if (!ProjectIsolationManager.instance) {
|
|
9
|
+
ProjectIsolationManager.instance = new ProjectIsolationManager();
|
|
10
|
+
}
|
|
11
|
+
return ProjectIsolationManager.instance;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Get stable project identification based on git remote URL
|
|
15
|
+
*/
|
|
16
|
+
getProjectIdentification(projectRoot) {
|
|
17
|
+
const cacheKey = projectRoot;
|
|
18
|
+
if (this.projectCache.has(cacheKey)) {
|
|
19
|
+
return this.projectCache.get(cacheKey);
|
|
20
|
+
}
|
|
21
|
+
try {
|
|
22
|
+
const remoteUrl = this.getGitRemoteUrl(projectRoot);
|
|
23
|
+
const gitInfo = this.parseGitRemote(remoteUrl);
|
|
24
|
+
const projectId = this.createStableProjectId(gitInfo.organization, gitInfo.repository);
|
|
25
|
+
const workspaceFilter = this.createWorkspaceFilter(gitInfo.organization, gitInfo.repository, projectRoot);
|
|
26
|
+
const linearConfig = this.getLinearConfiguration(gitInfo.organization, gitInfo.repository, projectRoot);
|
|
27
|
+
const identification = {
|
|
28
|
+
projectId,
|
|
29
|
+
organization: gitInfo.organization,
|
|
30
|
+
repository: gitInfo.repository,
|
|
31
|
+
workspaceFilter,
|
|
32
|
+
linearTeamId: linearConfig.teamId,
|
|
33
|
+
linearOrganization: linearConfig.organization,
|
|
34
|
+
projectPrefix: linearConfig.prefix
|
|
35
|
+
};
|
|
36
|
+
this.projectCache.set(cacheKey, identification);
|
|
37
|
+
logger.info("Project identification created", {
|
|
38
|
+
projectId: identification.projectId,
|
|
39
|
+
workspaceFilter: identification.workspaceFilter,
|
|
40
|
+
linearTeam: identification.linearTeamId
|
|
41
|
+
});
|
|
42
|
+
return identification;
|
|
43
|
+
} catch (error) {
|
|
44
|
+
logger.warn("Could not determine git remote, using fallback identification", { error });
|
|
45
|
+
const fallback = this.createFallbackIdentification(projectRoot);
|
|
46
|
+
this.projectCache.set(cacheKey, fallback);
|
|
47
|
+
return fallback;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Find git repository root and get remote URL
|
|
52
|
+
*/
|
|
53
|
+
getGitRemoteUrl(projectRoot) {
|
|
54
|
+
try {
|
|
55
|
+
const gitRoot = execSync("git rev-parse --show-toplevel", {
|
|
56
|
+
cwd: projectRoot,
|
|
57
|
+
encoding: "utf8",
|
|
58
|
+
timeout: 5e3
|
|
59
|
+
}).trim();
|
|
60
|
+
const result = execSync("git config --get remote.origin.url", {
|
|
61
|
+
cwd: gitRoot,
|
|
62
|
+
encoding: "utf8",
|
|
63
|
+
timeout: 5e3
|
|
64
|
+
});
|
|
65
|
+
return result.trim();
|
|
66
|
+
} catch (error) {
|
|
67
|
+
throw new Error(`Failed to get git remote URL: ${error}`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Get project name from git repository root directory
|
|
72
|
+
*/
|
|
73
|
+
getProjectNameFromGitRoot(projectRoot) {
|
|
74
|
+
try {
|
|
75
|
+
const gitRoot = execSync("git rev-parse --show-toplevel", {
|
|
76
|
+
cwd: projectRoot,
|
|
77
|
+
encoding: "utf8",
|
|
78
|
+
timeout: 5e3
|
|
79
|
+
}).trim();
|
|
80
|
+
return gitRoot.split("/").pop() || "unknown";
|
|
81
|
+
} catch (error) {
|
|
82
|
+
return projectRoot.split("/").pop() || "unknown";
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Parse git remote URL to extract organization and repository
|
|
87
|
+
*/
|
|
88
|
+
parseGitRemote(remoteUrl) {
|
|
89
|
+
let match = remoteUrl.match(/github\.com[/:]([\w-]+)\/([\w-]+)(?:\.git)?/);
|
|
90
|
+
if (match) {
|
|
91
|
+
return {
|
|
92
|
+
organization: match[1],
|
|
93
|
+
repository: match[2]
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
match = remoteUrl.match(/[:/]([\w-]+)\/([\w-]+)(?:\.git)?$/);
|
|
97
|
+
if (match) {
|
|
98
|
+
return {
|
|
99
|
+
organization: match[1],
|
|
100
|
+
repository: match[2]
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
throw new Error(`Could not parse git remote URL: ${remoteUrl}`);
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Create stable project ID from organization and repository
|
|
107
|
+
*/
|
|
108
|
+
createStableProjectId(organization, repository) {
|
|
109
|
+
const content = `${organization}/${repository}`;
|
|
110
|
+
const hash = createHash("sha256").update(content).digest("hex");
|
|
111
|
+
return `proj-${hash.substring(0, 12)}`;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Create stable workspace filter using git root folder name
|
|
115
|
+
*/
|
|
116
|
+
createWorkspaceFilter(organization, repository, projectRoot) {
|
|
117
|
+
const projectName = this.getProjectNameFromGitRoot(projectRoot);
|
|
118
|
+
return `${projectName}:${organization}`;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Get Linear configuration based on project
|
|
122
|
+
*/
|
|
123
|
+
getLinearConfiguration(organization, repository, projectRoot) {
|
|
124
|
+
const projectName = projectRoot ? this.getProjectNameFromGitRoot(projectRoot) : repository;
|
|
125
|
+
const projectConfigs = {
|
|
126
|
+
"jonathanpeterwu/stackmemory": {
|
|
127
|
+
teamId: process.env.LINEAR_TEAM_ID || "stackmemory",
|
|
128
|
+
organization: process.env.LINEAR_ORGANIZATION || "stackmemoryai",
|
|
129
|
+
prefix: "SM"
|
|
130
|
+
},
|
|
131
|
+
"Lift-Coefficient/*": {
|
|
132
|
+
teamId: "STA",
|
|
133
|
+
organization: "lift-cl",
|
|
134
|
+
prefix: "STA"
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
const exactKey = `${organization}/${repository}`;
|
|
138
|
+
if (projectConfigs[exactKey]) {
|
|
139
|
+
return projectConfigs[exactKey];
|
|
140
|
+
}
|
|
141
|
+
const wildcardKey = `${organization}/*`;
|
|
142
|
+
if (projectConfigs[wildcardKey]) {
|
|
143
|
+
return projectConfigs[wildcardKey];
|
|
144
|
+
}
|
|
145
|
+
const sanitizedProjectName = projectName.replace(/[^a-zA-Z0-9]/g, "");
|
|
146
|
+
return {
|
|
147
|
+
teamId: sanitizedProjectName.toLowerCase(),
|
|
148
|
+
organization: `${organization.toLowerCase()}ai`,
|
|
149
|
+
prefix: sanitizedProjectName.substring(0, 3).toUpperCase()
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Create fallback identification for non-git projects
|
|
154
|
+
*/
|
|
155
|
+
createFallbackIdentification(projectRoot) {
|
|
156
|
+
const folderName = projectRoot.split("/").pop() || "unknown";
|
|
157
|
+
const projectId = this.createStableProjectId("local", folderName);
|
|
158
|
+
return {
|
|
159
|
+
projectId,
|
|
160
|
+
organization: "local",
|
|
161
|
+
repository: folderName,
|
|
162
|
+
workspaceFilter: `local:${folderName}`,
|
|
163
|
+
linearTeamId: folderName.toLowerCase().replace(/[^a-z0-9]/g, ""),
|
|
164
|
+
linearOrganization: "local",
|
|
165
|
+
projectPrefix: folderName.substring(0, 3).toUpperCase()
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Validate that current project isolation is working
|
|
170
|
+
*/
|
|
171
|
+
validateProjectIsolation(projectRoot) {
|
|
172
|
+
try {
|
|
173
|
+
const identification = this.getProjectIdentification(projectRoot);
|
|
174
|
+
if (!identification.projectId || !identification.workspaceFilter) {
|
|
175
|
+
return false;
|
|
176
|
+
}
|
|
177
|
+
const secondCall = this.getProjectIdentification(projectRoot);
|
|
178
|
+
if (identification.workspaceFilter !== secondCall.workspaceFilter) {
|
|
179
|
+
return false;
|
|
180
|
+
}
|
|
181
|
+
return true;
|
|
182
|
+
} catch (error) {
|
|
183
|
+
logger.error("Project isolation validation failed", { error });
|
|
184
|
+
return false;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Clear project cache (for testing)
|
|
189
|
+
*/
|
|
190
|
+
clearCache() {
|
|
191
|
+
this.projectCache.clear();
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
export {
|
|
195
|
+
ProjectIsolationManager
|
|
196
|
+
};
|
|
197
|
+
//# sourceMappingURL=project-isolation.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/core/projects/project-isolation.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Project Isolation System\n * Ensures data separation between different projects/organizations\n */\n\nimport { execSync } from 'child_process';\nimport { createHash } from 'crypto';\nimport { logger } from '../monitoring/logger.js';\n\nexport interface ProjectIdentification {\n projectId: string;\n organization: string;\n repository: string;\n workspaceFilter: string;\n linearTeamId?: string;\n linearOrganization?: string;\n projectPrefix: string;\n}\n\nexport class ProjectIsolationManager {\n private static instance: ProjectIsolationManager;\n private projectCache = new Map<string, ProjectIdentification>();\n\n static getInstance(): ProjectIsolationManager {\n if (!ProjectIsolationManager.instance) {\n ProjectIsolationManager.instance = new ProjectIsolationManager();\n }\n return ProjectIsolationManager.instance;\n }\n\n /**\n * Get stable project identification based on git remote URL\n */\n getProjectIdentification(projectRoot: string): ProjectIdentification {\n const cacheKey = projectRoot;\n \n if (this.projectCache.has(cacheKey)) {\n return this.projectCache.get(cacheKey)!;\n }\n\n try {\n // Get git remote URL\n const remoteUrl = this.getGitRemoteUrl(projectRoot);\n const gitInfo = this.parseGitRemote(remoteUrl);\n \n // Create stable project ID from git remote\n const projectId = this.createStableProjectId(gitInfo.organization, gitInfo.repository);\n \n // Create workspace filter (stable across sessions)\n const workspaceFilter = this.createWorkspaceFilter(gitInfo.organization, gitInfo.repository, projectRoot);\n \n // Determine Linear configuration\n const linearConfig = this.getLinearConfiguration(gitInfo.organization, gitInfo.repository, projectRoot);\n \n const identification: ProjectIdentification = {\n projectId,\n organization: gitInfo.organization,\n repository: gitInfo.repository,\n workspaceFilter,\n linearTeamId: linearConfig.teamId,\n linearOrganization: linearConfig.organization,\n projectPrefix: linearConfig.prefix,\n };\n\n this.projectCache.set(cacheKey, identification);\n logger.info('Project identification created', {\n projectId: identification.projectId,\n workspaceFilter: identification.workspaceFilter,\n linearTeam: identification.linearTeamId,\n });\n\n return identification;\n\n } catch (error) {\n // Fallback for non-git projects\n logger.warn('Could not determine git remote, using fallback identification', { error });\n const fallback = this.createFallbackIdentification(projectRoot);\n this.projectCache.set(cacheKey, fallback);\n return fallback;\n }\n }\n\n /**\n * Find git repository root and get remote URL\n */\n private getGitRemoteUrl(projectRoot: string): string {\n try {\n // Find the git root directory (may be parent of current directory)\n const gitRoot = execSync('git rev-parse --show-toplevel', {\n cwd: projectRoot,\n encoding: 'utf8',\n timeout: 5000,\n }).trim();\n\n // Get remote URL from git root\n const result = execSync('git config --get remote.origin.url', {\n cwd: gitRoot,\n encoding: 'utf8',\n timeout: 5000,\n });\n \n return result.trim();\n } catch (error) {\n throw new Error(`Failed to get git remote URL: ${error}`);\n }\n }\n\n /**\n * Get project name from git repository root directory\n */\n private getProjectNameFromGitRoot(projectRoot: string): string {\n try {\n const gitRoot = execSync('git rev-parse --show-toplevel', {\n cwd: projectRoot,\n encoding: 'utf8',\n timeout: 5000,\n }).trim();\n\n // Get the folder name of the git root\n return gitRoot.split('/').pop() || 'unknown';\n } catch (error) {\n // Fallback to current directory name\n return projectRoot.split('/').pop() || 'unknown';\n }\n }\n\n /**\n * Parse git remote URL to extract organization and repository\n */\n private parseGitRemote(remoteUrl: string): { organization: string; repository: string } {\n // Handle GitHub URLs (https and ssh)\n let match = remoteUrl.match(/github\\.com[/:]([\\w-]+)\\/([\\w-]+)(?:\\.git)?/);\n if (match) {\n return {\n organization: match[1],\n repository: match[2],\n };\n }\n\n // Handle other git URLs\n match = remoteUrl.match(/[:/]([\\w-]+)\\/([\\w-]+)(?:\\.git)?$/);\n if (match) {\n return {\n organization: match[1],\n repository: match[2],\n };\n }\n\n throw new Error(`Could not parse git remote URL: ${remoteUrl}`);\n }\n\n /**\n * Create stable project ID from organization and repository\n */\n private createStableProjectId(organization: string, repository: string): string {\n const content = `${organization}/${repository}`;\n const hash = createHash('sha256').update(content).digest('hex');\n return `proj-${hash.substring(0, 12)}`;\n }\n\n /**\n * Create stable workspace filter using git root folder name\n */\n private createWorkspaceFilter(organization: string, repository: string, projectRoot: string): string {\n // Get dynamic project name from git root\n const projectName = this.getProjectNameFromGitRoot(projectRoot);\n \n // Use project name as primary filter, with organization fallback for uniqueness\n return `${projectName}:${organization}`;\n }\n\n /**\n * Get Linear configuration based on project\n */\n private getLinearConfiguration(organization: string, repository: string, projectRoot?: string): {\n teamId?: string;\n organization?: string;\n prefix: string;\n } {\n // Get dynamic project name from git root\n const projectName = projectRoot ? this.getProjectNameFromGitRoot(projectRoot) : repository;\n \n // Project-specific Linear configurations\n const projectConfigs: Record<string, { teamId?: string; organization?: string; prefix: string }> = {\n 'jonathanpeterwu/stackmemory': {\n teamId: process.env.LINEAR_TEAM_ID || 'stackmemory',\n organization: process.env.LINEAR_ORGANIZATION || 'stackmemoryai',\n prefix: 'SM',\n },\n 'Lift-Coefficient/*': {\n teamId: 'STA',\n organization: 'lift-cl',\n prefix: 'STA',\n },\n };\n\n // Check for exact match\n const exactKey = `${organization}/${repository}`;\n if (projectConfigs[exactKey]) {\n return projectConfigs[exactKey];\n }\n\n // Check for organization wildcard match\n const wildcardKey = `${organization}/*`;\n if (projectConfigs[wildcardKey]) {\n return projectConfigs[wildcardKey];\n }\n\n // Default configuration using dynamic project name\n const sanitizedProjectName = projectName.replace(/[^a-zA-Z0-9]/g, '');\n return {\n teamId: sanitizedProjectName.toLowerCase(),\n organization: `${organization.toLowerCase()}ai`,\n prefix: sanitizedProjectName.substring(0, 3).toUpperCase(),\n };\n }\n\n /**\n * Create fallback identification for non-git projects\n */\n private createFallbackIdentification(projectRoot: string): ProjectIdentification {\n const folderName = projectRoot.split('/').pop() || 'unknown';\n const projectId = this.createStableProjectId('local', folderName);\n\n return {\n projectId,\n organization: 'local',\n repository: folderName,\n workspaceFilter: `local:${folderName}`,\n linearTeamId: folderName.toLowerCase().replace(/[^a-z0-9]/g, ''),\n linearOrganization: 'local',\n projectPrefix: folderName.substring(0, 3).toUpperCase(),\n };\n }\n\n /**\n * Validate that current project isolation is working\n */\n validateProjectIsolation(projectRoot: string): boolean {\n try {\n const identification = this.getProjectIdentification(projectRoot);\n \n // Check that we have required fields\n if (!identification.projectId || !identification.workspaceFilter) {\n return false;\n }\n\n // Check that workspace filter is stable\n const secondCall = this.getProjectIdentification(projectRoot);\n if (identification.workspaceFilter !== secondCall.workspaceFilter) {\n return false;\n }\n\n return true;\n } catch (error) {\n logger.error('Project isolation validation failed', { error });\n return false;\n }\n }\n\n /**\n * Clear project cache (for testing)\n */\n clearCache(): void {\n this.projectCache.clear();\n }\n}"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -140,7 +140,7 @@ ${indent} \u25C2 Result: [${typeof maskedResult}] ${resultStr.substring(0, 100)
|
|
|
140
140
|
}
|
|
141
141
|
if (entry.duration && entry.duration > this.config.performanceThreshold) {
|
|
142
142
|
output += `
|
|
143
|
-
${indent}
|
|
143
|
+
${indent} WARNING: Exceeded ${this.config.performanceThreshold}ms threshold`;
|
|
144
144
|
}
|
|
145
145
|
if (includeChildren && entry.children.length > 0) {
|
|
146
146
|
for (const child of entry.children) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/core/trace/debug-trace.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Debug Trace Module - Comprehensive execution tracing for LLM debugging\n *\n * This module provides detailed execution tracing to help LLMs understand\n * exactly what happened during code execution, making debugging much easier.\n */\n\nimport { performance } from 'perf_hooks';\nimport { logger } from '../monitoring/logger.js';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { v4 as uuidv4 } from 'uuid';\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\nexport interface TraceConfig {\n enabled: boolean;\n verbosity: 'full' | 'errors' | 'summary';\n output: 'console' | 'file' | 'both';\n includeParams: boolean;\n includeResults: boolean;\n maskSensitive: boolean;\n performanceThreshold: number; // ms\n maxDepth: number;\n captureMemory: boolean;\n}\n\ninterface TraceEntry {\n id: string;\n parentId?: string;\n type: 'command' | 'function' | 'step' | 'query' | 'api' | 'error';\n name: string;\n startTime: number;\n endTime?: number;\n duration?: number;\n depth: number;\n params?: any;\n result?: any;\n error?: any;\n memory?: {\n before: NodeJS.MemoryUsage;\n after?: NodeJS.MemoryUsage;\n delta?: {\n rss: number;\n heapUsed: number;\n };\n };\n metadata?: Record<string, any>;\n children: TraceEntry[];\n}\n\nexport class TraceContext {\n private static instance: TraceContext;\n private config: TraceConfig;\n private currentTrace: TraceEntry | null = null;\n private traceStack: TraceEntry[] = [];\n private allTraces: TraceEntry[] = [];\n private outputFile?: string;\n private startTime: number = Date.now();\n private sensitivePatterns: RegExp[] = [\n /api[_-]?key/i,\n /token/i,\n /secret/i,\n /password/i,\n /bearer/i,\n /authorization/i,\n /client[_-]?id/i,\n /client[_-]?secret/i,\n ];\n\n private constructor() {\n this.config = this.loadConfig();\n if (this.config.output === 'file' || this.config.output === 'both') {\n this.initializeOutputFile();\n }\n }\n\n static getInstance(): TraceContext {\n if (!TraceContext.instance) {\n TraceContext.instance = new TraceContext();\n }\n return TraceContext.instance;\n }\n\n private loadConfig(): TraceConfig {\n return {\n enabled:\n process.env['DEBUG_TRACE'] === 'true' ||\n process.env['STACKMEMORY_DEBUG'] === 'true',\n verbosity: (process.env['TRACE_VERBOSITY'] as any) || 'full',\n output: (process.env['TRACE_OUTPUT'] as any) || 'console',\n includeParams: process.env['TRACE_PARAMS'] !== 'false',\n includeResults: process.env['TRACE_RESULTS'] !== 'false',\n maskSensitive: process.env['TRACE_MASK_SENSITIVE'] !== 'false',\n performanceThreshold: parseInt(\n process.env['TRACE_PERF_THRESHOLD'] || '100'\n ),\n maxDepth: parseInt(process.env['TRACE_MAX_DEPTH'] || '20'),\n captureMemory: process.env['TRACE_MEMORY'] === 'true',\n };\n }\n\n private initializeOutputFile(): void {\n const traceDir = path.join(\n process.env['HOME'] || '.',\n '.stackmemory',\n 'traces'\n );\n if (!fs.existsSync(traceDir)) {\n fs.mkdirSync(traceDir, { recursive: true });\n }\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n this.outputFile = path.join(traceDir, `trace-${timestamp}.jsonl`);\n }\n\n private maskSensitiveData(obj: any): any {\n if (!this.config.maskSensitive) return obj;\n if (typeof obj !== 'object' || obj === null) return obj;\n\n const masked = Array.isArray(obj) ? [...obj] : { ...obj };\n\n for (const key in masked) {\n if (typeof key === 'string') {\n // Check if key matches sensitive patterns\n const isSensitive = this.sensitivePatterns.some((pattern) =>\n pattern.test(key)\n );\n if (isSensitive) {\n masked[key] = '[MASKED]';\n } else if (typeof masked[key] === 'object') {\n masked[key] = this.maskSensitiveData(masked[key]);\n } else if (typeof masked[key] === 'string' && masked[key].length > 20) {\n // Check if value looks like a token/key\n if (/^[a-zA-Z0-9_-]{20,}$/.test(masked[key])) {\n masked[key] = masked[key].substring(0, 8) + '...[MASKED]';\n }\n }\n }\n }\n\n return masked;\n }\n\n private captureMemory(): NodeJS.MemoryUsage | undefined {\n if (!this.config.captureMemory) return undefined;\n return process.memoryUsage();\n }\n\n private formatDuration(ms: number): string {\n if (ms < 1000) return `${ms.toFixed(0)}ms`;\n if (ms < 60000) return `${(ms / 1000).toFixed(2)}s`;\n return `${(ms / 60000).toFixed(2)}m`;\n }\n\n private formatMemory(bytes: number): string {\n const mb = bytes / 1024 / 1024;\n return `${mb.toFixed(2)}MB`;\n }\n\n private getIndent(depth: number): string {\n return ' '.repeat(depth);\n }\n\n private formatTraceEntry(entry: TraceEntry, includeChildren = true): string {\n const indent = this.getIndent(entry.depth);\n const duration = entry.duration\n ? ` [${this.formatDuration(entry.duration)}]`\n : '';\n const memory = entry.memory?.delta\n ? ` (\u0394mem: ${this.formatMemory(entry.memory.delta.heapUsed)})`\n : '';\n\n let output = `${indent}\u2192 [${entry.type.toUpperCase()}:${entry.id.substring(0, 8)}] ${entry.name}${duration}${memory}`;\n\n if (entry.error) {\n output += `\\n${indent} \u2717 ERROR: ${entry.error.message || entry.error}`;\n if (entry.error.stack && this.config.verbosity === 'full') {\n output += `\\n${indent} Stack: ${entry.error.stack.split('\\n')[1]?.trim()}`;\n }\n }\n\n if (\n this.config.includeParams &&\n entry.params &&\n Object.keys(entry.params).length > 0\n ) {\n const maskedParams = this.maskSensitiveData(entry.params);\n output += `\\n${indent} \u25B8 Params: ${JSON.stringify(maskedParams, null, 2).replace(/\\n/g, '\\n' + indent + ' ')}`;\n }\n\n if (\n this.config.includeResults &&\n entry.result !== undefined &&\n !entry.error\n ) {\n const maskedResult = this.maskSensitiveData(entry.result);\n const resultStr = JSON.stringify(maskedResult, null, 2);\n if (resultStr.length < 200) {\n output += `\\n${indent} \u25C2 Result: ${resultStr.replace(/\\n/g, '\\n' + indent + ' ')}`;\n } else {\n output += `\\n${indent} \u25C2 Result: [${typeof maskedResult}] ${resultStr.substring(0, 100)}...`;\n }\n }\n\n if (entry.duration && entry.duration > this.config.performanceThreshold) {\n output += `\\n${indent} \u26A0 SLOW: Exceeded ${this.config.performanceThreshold}ms threshold`;\n }\n\n if (includeChildren && entry.children.length > 0) {\n for (const child of entry.children) {\n output += '\\n' + this.formatTraceEntry(child, true);\n }\n }\n\n if (entry.endTime && entry.depth > 0) {\n output += `\\n${indent}\u2190 [${entry.type.toUpperCase()}:${entry.id.substring(0, 8)}] completed`;\n }\n\n return output;\n }\n\n private outputTrace(entry: TraceEntry): void {\n if (!this.config.enabled) return;\n\n const formatted = this.formatTraceEntry(entry, false);\n\n if (this.config.output === 'console' || this.config.output === 'both') {\n console.log(formatted);\n }\n\n if (\n (this.config.output === 'file' || this.config.output === 'both') &&\n this.outputFile\n ) {\n const jsonLine =\n JSON.stringify({\n ...entry,\n formatted,\n timestamp: new Date().toISOString(),\n }) + '\\n';\n fs.appendFileSync(this.outputFile, jsonLine);\n }\n }\n\n startTrace(\n type: TraceEntry['type'],\n name: string,\n params?: any,\n metadata?: Record<string, any>\n ): string {\n if (!this.config.enabled) return '';\n\n const id = uuidv4();\n const parentId = this.currentTrace?.id;\n const depth = this.traceStack.length;\n\n if (depth > this.config.maxDepth) {\n return id; // Prevent infinite recursion\n }\n\n const entry: TraceEntry = {\n id,\n parentId,\n type,\n name,\n startTime: performance.now(),\n depth,\n params: this.config.includeParams ? params : undefined,\n metadata,\n children: [],\n memory: this.captureMemory()\n ? { before: this.captureMemory()! }\n : undefined,\n };\n\n if (this.currentTrace) {\n this.currentTrace.children.push(entry);\n } else {\n this.allTraces.push(entry);\n }\n\n this.traceStack.push(entry);\n this.currentTrace = entry;\n\n this.outputTrace(entry);\n\n return id;\n }\n\n endTrace(id: string, result?: any, error?: any): void {\n if (!this.config.enabled) return;\n\n const index = this.traceStack.findIndex((t) => t.id === id);\n if (index === -1) return;\n\n const entry = this.traceStack[index];\n entry.endTime = performance.now();\n entry.duration = entry.endTime - entry.startTime;\n entry.result = this.config.includeResults && !error ? result : undefined;\n entry.error = error;\n\n if (entry.memory?.before) {\n entry.memory.after = this.captureMemory();\n if (entry.memory.after) {\n entry.memory.delta = {\n rss: entry.memory.after.rss - entry.memory.before.rss,\n heapUsed: entry.memory.after.heapUsed - entry.memory.before.heapUsed,\n };\n }\n }\n\n this.outputTrace(entry);\n\n // Remove from stack and update current\n this.traceStack.splice(index);\n this.currentTrace = this.traceStack[this.traceStack.length - 1] || null;\n }\n\n async traceAsync<T>(\n type: TraceEntry['type'],\n name: string,\n params: any,\n fn: () => Promise<T>\n ): Promise<T> {\n const id = this.startTrace(type, name, params);\n try {\n const result = await fn();\n this.endTrace(id, result);\n return result;\n } catch (error: unknown) {\n this.endTrace(id, undefined, error);\n throw error;\n }\n }\n\n traceSync<T>(\n type: TraceEntry['type'],\n name: string,\n params: any,\n fn: () => T\n ): T {\n const id = this.startTrace(type, name, params);\n try {\n const result = fn();\n this.endTrace(id, result);\n return result;\n } catch (error: unknown) {\n this.endTrace(id, undefined, error);\n throw error;\n }\n }\n\n async command<T>(\n name: string,\n options: any,\n fn: () => Promise<T>\n ): Promise<T> {\n return this.traceAsync('command', name, options, fn);\n }\n\n async step<T>(name: string, fn: () => Promise<T>): Promise<T> {\n return this.traceAsync('step', name, undefined, fn);\n }\n\n async query<T>(sql: string, params: any, fn: () => Promise<T>): Promise<T> {\n return this.traceAsync('query', sql.substring(0, 50), params, fn);\n }\n\n async api<T>(\n method: string,\n url: string,\n body: any,\n fn: () => Promise<T>\n ): Promise<T> {\n return this.traceAsync('api', `${method} ${url}`, { body }, fn);\n }\n\n getExecutionSummary(): string {\n if (!this.config.enabled) return 'Tracing disabled';\n\n const totalDuration = Date.now() - this.startTime;\n const errorCount = this.countErrors(this.allTraces);\n const slowCount = this.countSlowOperations(this.allTraces);\n\n let summary = `\\n${'='.repeat(80)}\\n`;\n summary += `EXECUTION SUMMARY\\n`;\n summary += `${'='.repeat(80)}\\n`;\n summary += `Total Duration: ${this.formatDuration(totalDuration)}\\n`;\n summary += `Total Operations: ${this.countOperations(this.allTraces)}\\n`;\n summary += `Errors: ${errorCount}\\n`;\n summary += `Slow Operations (>${this.config.performanceThreshold}ms): ${slowCount}\\n`;\n\n if (this.config.captureMemory) {\n const memUsage = process.memoryUsage();\n summary += `Final Memory: RSS=${this.formatMemory(memUsage.rss)}, Heap=${this.formatMemory(memUsage.heapUsed)}\\n`;\n }\n\n if (this.outputFile) {\n summary += `Trace Log: ${this.outputFile}\\n`;\n }\n\n summary += `${'='.repeat(80)}`;\n\n return summary;\n }\n\n private countOperations(traces: TraceEntry[]): number {\n let count = traces.length;\n for (const trace of traces) {\n count += this.countOperations(trace.children);\n }\n return count;\n }\n\n private countErrors(traces: TraceEntry[]): number {\n let count = 0;\n for (const trace of traces) {\n if (trace.error) count++;\n count += this.countErrors(trace.children);\n }\n return count;\n }\n\n private countSlowOperations(traces: TraceEntry[]): number {\n let count = 0;\n for (const trace of traces) {\n if (trace.duration && trace.duration > this.config.performanceThreshold)\n count++;\n count += this.countSlowOperations(trace.children);\n }\n return count;\n }\n\n getLastError(): TraceEntry | null {\n const findLastError = (traces: TraceEntry[]): TraceEntry | null => {\n for (let i = traces.length - 1; i >= 0; i--) {\n const trace = traces[i];\n if (trace.error) return trace;\n const childError = findLastError(trace.children);\n if (childError) return childError;\n }\n return null;\n };\n return findLastError(this.allTraces);\n }\n\n exportTraces(): TraceEntry[] {\n return this.allTraces;\n }\n\n reset(): void {\n this.currentTrace = null;\n this.traceStack = [];\n this.allTraces = [];\n this.startTime = Date.now();\n }\n}\n\n// Singleton instance\nexport const trace = TraceContext.getInstance();\n\n// Decorator for tracing class methods\nexport function Trace(type: TraceEntry['type'] = 'function') {\n return function (\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 return trace.traceAsync(type, methodName, args, async () => {\n return originalMethod.apply(this, args);\n });\n };\n } else {\n descriptor.value = function (...args: any[]) {\n const className = target.constructor.name;\n const methodName = `${className}.${propertyKey}`;\n return trace.traceSync(type, methodName, args, () => {\n return originalMethod.apply(this, args);\n });\n };\n }\n\n return descriptor;\n };\n}\n\n// Decorator for tracing entire classes\nexport function TraceClass(type: TraceEntry['type'] = 'function') {\n return function <T extends { new (...args: any[]): {} }>(constructor: T) {\n const prototype = constructor.prototype;\n const propertyNames = Object.getOwnPropertyNames(prototype);\n\n for (const propertyName of propertyNames) {\n if (propertyName === 'constructor') continue;\n\n const descriptor = Object.getOwnPropertyDescriptor(\n prototype,\n propertyName\n );\n if (!descriptor || typeof descriptor.value !== 'function') continue;\n\n Trace(type)(prototype, propertyName, descriptor);\n Object.defineProperty(prototype, propertyName, descriptor);\n }\n\n return constructor;\n };\n}\n\n// Helper for critical operations\nexport function TraceCritical(\n target: any,\n propertyKey: string,\n descriptor: PropertyDescriptor\n) {\n const originalMethod = descriptor.value;\n\n descriptor.value = async function (...args: any[]) {\n const className = target.constructor.name;\n const methodName = `${className}.${propertyKey} [CRITICAL]`;\n\n // Store context before execution\n const contextBefore = {\n memory: process.memoryUsage(),\n timestamp: new Date().toISOString(),\n args: trace['maskSensitiveData'](args),\n };\n\n try {\n return await trace.traceAsync(\n 'function',\n methodName,\n contextBefore,\n async () => {\n return originalMethod.apply(this, args);\n }\n );\n } catch (error: any) {\n // Enhanced error logging for critical operations\n logger.error(`Critical operation failed: ${methodName}`, error, {\n context: contextBefore,\n stack: error.stack,\n });\n throw error;\n }\n };\n\n return descriptor;\n}\n"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["/**\n * Debug Trace Module - Comprehensive execution tracing for LLM debugging\n *\n * This module provides detailed execution tracing to help LLMs understand\n * exactly what happened during code execution, making debugging much easier.\n */\n\nimport { performance } from 'perf_hooks';\nimport { logger } from '../monitoring/logger.js';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { v4 as uuidv4 } from 'uuid';\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\nexport interface TraceConfig {\n enabled: boolean;\n verbosity: 'full' | 'errors' | 'summary';\n output: 'console' | 'file' | 'both';\n includeParams: boolean;\n includeResults: boolean;\n maskSensitive: boolean;\n performanceThreshold: number; // ms\n maxDepth: number;\n captureMemory: boolean;\n}\n\ninterface TraceEntry {\n id: string;\n parentId?: string;\n type: 'command' | 'function' | 'step' | 'query' | 'api' | 'error';\n name: string;\n startTime: number;\n endTime?: number;\n duration?: number;\n depth: number;\n params?: any;\n result?: any;\n error?: any;\n memory?: {\n before: NodeJS.MemoryUsage;\n after?: NodeJS.MemoryUsage;\n delta?: {\n rss: number;\n heapUsed: number;\n };\n };\n metadata?: Record<string, any>;\n children: TraceEntry[];\n}\n\nexport class TraceContext {\n private static instance: TraceContext;\n private config: TraceConfig;\n private currentTrace: TraceEntry | null = null;\n private traceStack: TraceEntry[] = [];\n private allTraces: TraceEntry[] = [];\n private outputFile?: string;\n private startTime: number = Date.now();\n private sensitivePatterns: RegExp[] = [\n /api[_-]?key/i,\n /token/i,\n /secret/i,\n /password/i,\n /bearer/i,\n /authorization/i,\n /client[_-]?id/i,\n /client[_-]?secret/i,\n ];\n\n private constructor() {\n this.config = this.loadConfig();\n if (this.config.output === 'file' || this.config.output === 'both') {\n this.initializeOutputFile();\n }\n }\n\n static getInstance(): TraceContext {\n if (!TraceContext.instance) {\n TraceContext.instance = new TraceContext();\n }\n return TraceContext.instance;\n }\n\n private loadConfig(): TraceConfig {\n return {\n enabled:\n process.env['DEBUG_TRACE'] === 'true' ||\n process.env['STACKMEMORY_DEBUG'] === 'true',\n verbosity: (process.env['TRACE_VERBOSITY'] as any) || 'full',\n output: (process.env['TRACE_OUTPUT'] as any) || 'console',\n includeParams: process.env['TRACE_PARAMS'] !== 'false',\n includeResults: process.env['TRACE_RESULTS'] !== 'false',\n maskSensitive: process.env['TRACE_MASK_SENSITIVE'] !== 'false',\n performanceThreshold: parseInt(\n process.env['TRACE_PERF_THRESHOLD'] || '100'\n ),\n maxDepth: parseInt(process.env['TRACE_MAX_DEPTH'] || '20'),\n captureMemory: process.env['TRACE_MEMORY'] === 'true',\n };\n }\n\n private initializeOutputFile(): void {\n const traceDir = path.join(\n process.env['HOME'] || '.',\n '.stackmemory',\n 'traces'\n );\n if (!fs.existsSync(traceDir)) {\n fs.mkdirSync(traceDir, { recursive: true });\n }\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n this.outputFile = path.join(traceDir, `trace-${timestamp}.jsonl`);\n }\n\n private maskSensitiveData(obj: any): any {\n if (!this.config.maskSensitive) return obj;\n if (typeof obj !== 'object' || obj === null) return obj;\n\n const masked = Array.isArray(obj) ? [...obj] : { ...obj };\n\n for (const key in masked) {\n if (typeof key === 'string') {\n // Check if key matches sensitive patterns\n const isSensitive = this.sensitivePatterns.some((pattern) =>\n pattern.test(key)\n );\n if (isSensitive) {\n masked[key] = '[MASKED]';\n } else if (typeof masked[key] === 'object') {\n masked[key] = this.maskSensitiveData(masked[key]);\n } else if (typeof masked[key] === 'string' && masked[key].length > 20) {\n // Check if value looks like a token/key\n if (/^[a-zA-Z0-9_-]{20,}$/.test(masked[key])) {\n masked[key] = masked[key].substring(0, 8) + '...[MASKED]';\n }\n }\n }\n }\n\n return masked;\n }\n\n private captureMemory(): NodeJS.MemoryUsage | undefined {\n if (!this.config.captureMemory) return undefined;\n return process.memoryUsage();\n }\n\n private formatDuration(ms: number): string {\n if (ms < 1000) return `${ms.toFixed(0)}ms`;\n if (ms < 60000) return `${(ms / 1000).toFixed(2)}s`;\n return `${(ms / 60000).toFixed(2)}m`;\n }\n\n private formatMemory(bytes: number): string {\n const mb = bytes / 1024 / 1024;\n return `${mb.toFixed(2)}MB`;\n }\n\n private getIndent(depth: number): string {\n return ' '.repeat(depth);\n }\n\n private formatTraceEntry(entry: TraceEntry, includeChildren = true): string {\n const indent = this.getIndent(entry.depth);\n const duration = entry.duration\n ? ` [${this.formatDuration(entry.duration)}]`\n : '';\n const memory = entry.memory?.delta\n ? ` (\u0394mem: ${this.formatMemory(entry.memory.delta.heapUsed)})`\n : '';\n\n let output = `${indent}\u2192 [${entry.type.toUpperCase()}:${entry.id.substring(0, 8)}] ${entry.name}${duration}${memory}`;\n\n if (entry.error) {\n output += `\\n${indent} \u2717 ERROR: ${entry.error.message || entry.error}`;\n if (entry.error.stack && this.config.verbosity === 'full') {\n output += `\\n${indent} Stack: ${entry.error.stack.split('\\n')[1]?.trim()}`;\n }\n }\n\n if (\n this.config.includeParams &&\n entry.params &&\n Object.keys(entry.params).length > 0\n ) {\n const maskedParams = this.maskSensitiveData(entry.params);\n output += `\\n${indent} \u25B8 Params: ${JSON.stringify(maskedParams, null, 2).replace(/\\n/g, '\\n' + indent + ' ')}`;\n }\n\n if (\n this.config.includeResults &&\n entry.result !== undefined &&\n !entry.error\n ) {\n const maskedResult = this.maskSensitiveData(entry.result);\n const resultStr = JSON.stringify(maskedResult, null, 2);\n if (resultStr.length < 200) {\n output += `\\n${indent} \u25C2 Result: ${resultStr.replace(/\\n/g, '\\n' + indent + ' ')}`;\n } else {\n output += `\\n${indent} \u25C2 Result: [${typeof maskedResult}] ${resultStr.substring(0, 100)}...`;\n }\n }\n\n if (entry.duration && entry.duration > this.config.performanceThreshold) {\n output += `\\n${indent} WARNING: Exceeded ${this.config.performanceThreshold}ms threshold`;\n }\n\n if (includeChildren && entry.children.length > 0) {\n for (const child of entry.children) {\n output += '\\n' + this.formatTraceEntry(child, true);\n }\n }\n\n if (entry.endTime && entry.depth > 0) {\n output += `\\n${indent}\u2190 [${entry.type.toUpperCase()}:${entry.id.substring(0, 8)}] completed`;\n }\n\n return output;\n }\n\n private outputTrace(entry: TraceEntry): void {\n if (!this.config.enabled) return;\n\n const formatted = this.formatTraceEntry(entry, false);\n\n if (this.config.output === 'console' || this.config.output === 'both') {\n console.log(formatted);\n }\n\n if (\n (this.config.output === 'file' || this.config.output === 'both') &&\n this.outputFile\n ) {\n const jsonLine =\n JSON.stringify({\n ...entry,\n formatted,\n timestamp: new Date().toISOString(),\n }) + '\\n';\n fs.appendFileSync(this.outputFile, jsonLine);\n }\n }\n\n startTrace(\n type: TraceEntry['type'],\n name: string,\n params?: any,\n metadata?: Record<string, any>\n ): string {\n if (!this.config.enabled) return '';\n\n const id = uuidv4();\n const parentId = this.currentTrace?.id;\n const depth = this.traceStack.length;\n\n if (depth > this.config.maxDepth) {\n return id; // Prevent infinite recursion\n }\n\n const entry: TraceEntry = {\n id,\n parentId,\n type,\n name,\n startTime: performance.now(),\n depth,\n params: this.config.includeParams ? params : undefined,\n metadata,\n children: [],\n memory: this.captureMemory()\n ? { before: this.captureMemory()! }\n : undefined,\n };\n\n if (this.currentTrace) {\n this.currentTrace.children.push(entry);\n } else {\n this.allTraces.push(entry);\n }\n\n this.traceStack.push(entry);\n this.currentTrace = entry;\n\n this.outputTrace(entry);\n\n return id;\n }\n\n endTrace(id: string, result?: any, error?: any): void {\n if (!this.config.enabled) return;\n\n const index = this.traceStack.findIndex((t) => t.id === id);\n if (index === -1) return;\n\n const entry = this.traceStack[index];\n entry.endTime = performance.now();\n entry.duration = entry.endTime - entry.startTime;\n entry.result = this.config.includeResults && !error ? result : undefined;\n entry.error = error;\n\n if (entry.memory?.before) {\n entry.memory.after = this.captureMemory();\n if (entry.memory.after) {\n entry.memory.delta = {\n rss: entry.memory.after.rss - entry.memory.before.rss,\n heapUsed: entry.memory.after.heapUsed - entry.memory.before.heapUsed,\n };\n }\n }\n\n this.outputTrace(entry);\n\n // Remove from stack and update current\n this.traceStack.splice(index);\n this.currentTrace = this.traceStack[this.traceStack.length - 1] || null;\n }\n\n async traceAsync<T>(\n type: TraceEntry['type'],\n name: string,\n params: any,\n fn: () => Promise<T>\n ): Promise<T> {\n const id = this.startTrace(type, name, params);\n try {\n const result = await fn();\n this.endTrace(id, result);\n return result;\n } catch (error: unknown) {\n this.endTrace(id, undefined, error);\n throw error;\n }\n }\n\n traceSync<T>(\n type: TraceEntry['type'],\n name: string,\n params: any,\n fn: () => T\n ): T {\n const id = this.startTrace(type, name, params);\n try {\n const result = fn();\n this.endTrace(id, result);\n return result;\n } catch (error: unknown) {\n this.endTrace(id, undefined, error);\n throw error;\n }\n }\n\n async command<T>(\n name: string,\n options: any,\n fn: () => Promise<T>\n ): Promise<T> {\n return this.traceAsync('command', name, options, fn);\n }\n\n async step<T>(name: string, fn: () => Promise<T>): Promise<T> {\n return this.traceAsync('step', name, undefined, fn);\n }\n\n async query<T>(sql: string, params: any, fn: () => Promise<T>): Promise<T> {\n return this.traceAsync('query', sql.substring(0, 50), params, fn);\n }\n\n async api<T>(\n method: string,\n url: string,\n body: any,\n fn: () => Promise<T>\n ): Promise<T> {\n return this.traceAsync('api', `${method} ${url}`, { body }, fn);\n }\n\n getExecutionSummary(): string {\n if (!this.config.enabled) return 'Tracing disabled';\n\n const totalDuration = Date.now() - this.startTime;\n const errorCount = this.countErrors(this.allTraces);\n const slowCount = this.countSlowOperations(this.allTraces);\n\n let summary = `\\n${'='.repeat(80)}\\n`;\n summary += `EXECUTION SUMMARY\\n`;\n summary += `${'='.repeat(80)}\\n`;\n summary += `Total Duration: ${this.formatDuration(totalDuration)}\\n`;\n summary += `Total Operations: ${this.countOperations(this.allTraces)}\\n`;\n summary += `Errors: ${errorCount}\\n`;\n summary += `Slow Operations (>${this.config.performanceThreshold}ms): ${slowCount}\\n`;\n\n if (this.config.captureMemory) {\n const memUsage = process.memoryUsage();\n summary += `Final Memory: RSS=${this.formatMemory(memUsage.rss)}, Heap=${this.formatMemory(memUsage.heapUsed)}\\n`;\n }\n\n if (this.outputFile) {\n summary += `Trace Log: ${this.outputFile}\\n`;\n }\n\n summary += `${'='.repeat(80)}`;\n\n return summary;\n }\n\n private countOperations(traces: TraceEntry[]): number {\n let count = traces.length;\n for (const trace of traces) {\n count += this.countOperations(trace.children);\n }\n return count;\n }\n\n private countErrors(traces: TraceEntry[]): number {\n let count = 0;\n for (const trace of traces) {\n if (trace.error) count++;\n count += this.countErrors(trace.children);\n }\n return count;\n }\n\n private countSlowOperations(traces: TraceEntry[]): number {\n let count = 0;\n for (const trace of traces) {\n if (trace.duration && trace.duration > this.config.performanceThreshold)\n count++;\n count += this.countSlowOperations(trace.children);\n }\n return count;\n }\n\n getLastError(): TraceEntry | null {\n const findLastError = (traces: TraceEntry[]): TraceEntry | null => {\n for (let i = traces.length - 1; i >= 0; i--) {\n const trace = traces[i];\n if (trace.error) return trace;\n const childError = findLastError(trace.children);\n if (childError) return childError;\n }\n return null;\n };\n return findLastError(this.allTraces);\n }\n\n exportTraces(): TraceEntry[] {\n return this.allTraces;\n }\n\n reset(): void {\n this.currentTrace = null;\n this.traceStack = [];\n this.allTraces = [];\n this.startTime = Date.now();\n }\n}\n\n// Singleton instance\nexport const trace = TraceContext.getInstance();\n\n// Decorator for tracing class methods\nexport function Trace(type: TraceEntry['type'] = 'function') {\n return function (\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 return trace.traceAsync(type, methodName, args, async () => {\n return originalMethod.apply(this, args);\n });\n };\n } else {\n descriptor.value = function (...args: any[]) {\n const className = target.constructor.name;\n const methodName = `${className}.${propertyKey}`;\n return trace.traceSync(type, methodName, args, () => {\n return originalMethod.apply(this, args);\n });\n };\n }\n\n return descriptor;\n };\n}\n\n// Decorator for tracing entire classes\nexport function TraceClass(type: TraceEntry['type'] = 'function') {\n return function <T extends { new (...args: any[]): {} }>(constructor: T) {\n const prototype = constructor.prototype;\n const propertyNames = Object.getOwnPropertyNames(prototype);\n\n for (const propertyName of propertyNames) {\n if (propertyName === 'constructor') continue;\n\n const descriptor = Object.getOwnPropertyDescriptor(\n prototype,\n propertyName\n );\n if (!descriptor || typeof descriptor.value !== 'function') continue;\n\n Trace(type)(prototype, propertyName, descriptor);\n Object.defineProperty(prototype, propertyName, descriptor);\n }\n\n return constructor;\n };\n}\n\n// Helper for critical operations\nexport function TraceCritical(\n target: any,\n propertyKey: string,\n descriptor: PropertyDescriptor\n) {\n const originalMethod = descriptor.value;\n\n descriptor.value = async function (...args: any[]) {\n const className = target.constructor.name;\n const methodName = `${className}.${propertyKey} [CRITICAL]`;\n\n // Store context before execution\n const contextBefore = {\n memory: process.memoryUsage(),\n timestamp: new Date().toISOString(),\n args: trace['maskSensitiveData'](args),\n };\n\n try {\n return await trace.traceAsync(\n 'function',\n methodName,\n contextBefore,\n async () => {\n return originalMethod.apply(this, args);\n }\n );\n } catch (error: any) {\n // Enhanced error logging for critical operations\n logger.error(`Critical operation failed: ${methodName}`, error, {\n context: contextBefore,\n stack: error.stack,\n });\n throw error;\n }\n };\n\n return descriptor;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["trace"]
|
|
7
7
|
}
|
package/dist/core/trace/index.js
CHANGED
|
@@ -72,7 +72,7 @@ function initializeTracing() {
|
|
|
72
72
|
// Slow API threshold
|
|
73
73
|
};
|
|
74
74
|
if (config.DEBUG_TRACE || config.STACKMEMORY_DEBUG) {
|
|
75
|
-
console.log("
|
|
75
|
+
console.log("Trace Configuration:", {
|
|
76
76
|
enabled: true,
|
|
77
77
|
output: config.TRACE_OUTPUT,
|
|
78
78
|
verbosity: config.TRACE_VERBOSITY,
|
|
@@ -123,11 +123,11 @@ function withTracing(fn, options) {
|
|
|
123
123
|
}
|
|
124
124
|
const enableTracing = () => {
|
|
125
125
|
process.env["DEBUG_TRACE"] = "true";
|
|
126
|
-
console.log("
|
|
126
|
+
console.log("Tracing enabled");
|
|
127
127
|
};
|
|
128
128
|
const disableTracing = () => {
|
|
129
129
|
delete process.env["DEBUG_TRACE"];
|
|
130
|
-
console.log("
|
|
130
|
+
console.log("Tracing disabled");
|
|
131
131
|
};
|
|
132
132
|
const enableVerboseTracing = () => {
|
|
133
133
|
process.env["DEBUG_TRACE"] = "true";
|
|
@@ -135,7 +135,7 @@ const enableVerboseTracing = () => {
|
|
|
135
135
|
process.env["TRACE_PARAMS"] = "true";
|
|
136
136
|
process.env["TRACE_RESULTS"] = "true";
|
|
137
137
|
process.env["TRACE_MEMORY"] = "true";
|
|
138
|
-
console.log("
|
|
138
|
+
console.log("Verbose tracing enabled");
|
|
139
139
|
};
|
|
140
140
|
const enableMinimalTracing = () => {
|
|
141
141
|
process.env["DEBUG_TRACE"] = "true";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/core/trace/index.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Trace Module Export\n * Central export for all tracing functionality\n */\n\nimport type { TraceConfig } from './debug-trace.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\nexport {\n trace,\n TraceContext,\n Trace,\n TraceClass,\n TraceCritical,\n type TraceConfig,\n} from './debug-trace.js';\n\nexport {\n wrapCommand,\n wrapProgram,\n traceStep,\n traceQuery,\n traceAPI,\n} from './cli-trace-wrapper.js';\n\nexport {\n createTracedDatabase,\n wrapDatabase,\n getQueryStatistics,\n createTracedTransaction,\n} from './db-trace-wrapper.js';\n\nexport {\n TraceLinearAPI,\n createTracedFetch,\n wrapGraphQLClient,\n} from './linear-api-wrapper.js';\n\n/**\n * Initialize tracing based on environment configuration\n */\nexport function initializeTracing(): void {\n const config = {\n // Main control\n DEBUG_TRACE: process.env['DEBUG_TRACE'] === 'true',\n STACKMEMORY_DEBUG: process.env['STACKMEMORY_DEBUG'] === 'true',\n\n // Output control\n TRACE_OUTPUT: process.env['TRACE_OUTPUT'] || 'console', // console|file|both\n TRACE_VERBOSITY: process.env['TRACE_VERBOSITY'] || 'full', // full|errors|summary\n\n // Content control\n TRACE_PARAMS: process.env['TRACE_PARAMS'] !== 'false', // Include parameters\n TRACE_RESULTS: process.env['TRACE_RESULTS'] !== 'false', // Include results\n TRACE_MASK_SENSITIVE: process.env['TRACE_MASK_SENSITIVE'] !== 'false', // Mask sensitive data\n\n // Performance\n TRACE_PERF_THRESHOLD: parseInt(\n process.env['TRACE_PERF_THRESHOLD'] || '100'\n ), // ms\n TRACE_MEMORY: process.env['TRACE_MEMORY'] === 'true', // Track memory usage\n TRACE_MAX_DEPTH: parseInt(process.env['TRACE_MAX_DEPTH'] || '20'), // Max call depth\n\n // Database specific\n TRACE_DB: process.env['TRACE_DB'] === 'true', // Enable database tracing\n TRACE_DB_SLOW: parseInt(process.env['TRACE_DB_SLOW'] || '100'), // Slow query threshold\n\n // API specific\n TRACE_API: process.env['TRACE_API'] === 'true', // Enable API tracing\n TRACE_API_SLOW: parseInt(process.env['TRACE_API_SLOW'] || '1000'), // Slow API threshold\n };\n\n // Log configuration if debugging is enabled\n if (config.DEBUG_TRACE || config.STACKMEMORY_DEBUG) {\n console.log('
|
|
5
|
-
"mappings": "AAOA,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;AAEA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AAEP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAKA,SAAS,oBAA0B;AACxC,QAAM,SAAS;AAAA;AAAA,IAEb,aAAa,QAAQ,IAAI,aAAa,MAAM;AAAA,IAC5C,mBAAmB,QAAQ,IAAI,mBAAmB,MAAM;AAAA;AAAA,IAGxD,cAAc,QAAQ,IAAI,cAAc,KAAK;AAAA;AAAA,IAC7C,iBAAiB,QAAQ,IAAI,iBAAiB,KAAK;AAAA;AAAA;AAAA,IAGnD,cAAc,QAAQ,IAAI,cAAc,MAAM;AAAA;AAAA,IAC9C,eAAe,QAAQ,IAAI,eAAe,MAAM;AAAA;AAAA,IAChD,sBAAsB,QAAQ,IAAI,sBAAsB,MAAM;AAAA;AAAA;AAAA,IAG9D,sBAAsB;AAAA,MACpB,QAAQ,IAAI,sBAAsB,KAAK;AAAA,IACzC;AAAA;AAAA,IACA,cAAc,QAAQ,IAAI,cAAc,MAAM;AAAA;AAAA,IAC9C,iBAAiB,SAAS,QAAQ,IAAI,iBAAiB,KAAK,IAAI;AAAA;AAAA;AAAA,IAGhE,UAAU,QAAQ,IAAI,UAAU,MAAM;AAAA;AAAA,IACtC,eAAe,SAAS,QAAQ,IAAI,eAAe,KAAK,KAAK;AAAA;AAAA;AAAA,IAG7D,WAAW,QAAQ,IAAI,WAAW,MAAM;AAAA;AAAA,IACxC,gBAAgB,SAAS,QAAQ,IAAI,gBAAgB,KAAK,MAAM;AAAA;AAAA,EAClE;AAGA,MAAI,OAAO,eAAe,OAAO,mBAAmB;AAClD,YAAQ,IAAI,
|
|
4
|
+
"sourcesContent": ["/**\n * Trace Module Export\n * Central export for all tracing functionality\n */\n\nimport type { TraceConfig } from './debug-trace.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\nexport {\n trace,\n TraceContext,\n Trace,\n TraceClass,\n TraceCritical,\n type TraceConfig,\n} from './debug-trace.js';\n\nexport {\n wrapCommand,\n wrapProgram,\n traceStep,\n traceQuery,\n traceAPI,\n} from './cli-trace-wrapper.js';\n\nexport {\n createTracedDatabase,\n wrapDatabase,\n getQueryStatistics,\n createTracedTransaction,\n} from './db-trace-wrapper.js';\n\nexport {\n TraceLinearAPI,\n createTracedFetch,\n wrapGraphQLClient,\n} from './linear-api-wrapper.js';\n\n/**\n * Initialize tracing based on environment configuration\n */\nexport function initializeTracing(): void {\n const config = {\n // Main control\n DEBUG_TRACE: process.env['DEBUG_TRACE'] === 'true',\n STACKMEMORY_DEBUG: process.env['STACKMEMORY_DEBUG'] === 'true',\n\n // Output control\n TRACE_OUTPUT: process.env['TRACE_OUTPUT'] || 'console', // console|file|both\n TRACE_VERBOSITY: process.env['TRACE_VERBOSITY'] || 'full', // full|errors|summary\n\n // Content control\n TRACE_PARAMS: process.env['TRACE_PARAMS'] !== 'false', // Include parameters\n TRACE_RESULTS: process.env['TRACE_RESULTS'] !== 'false', // Include results\n TRACE_MASK_SENSITIVE: process.env['TRACE_MASK_SENSITIVE'] !== 'false', // Mask sensitive data\n\n // Performance\n TRACE_PERF_THRESHOLD: parseInt(\n process.env['TRACE_PERF_THRESHOLD'] || '100'\n ), // ms\n TRACE_MEMORY: process.env['TRACE_MEMORY'] === 'true', // Track memory usage\n TRACE_MAX_DEPTH: parseInt(process.env['TRACE_MAX_DEPTH'] || '20'), // Max call depth\n\n // Database specific\n TRACE_DB: process.env['TRACE_DB'] === 'true', // Enable database tracing\n TRACE_DB_SLOW: parseInt(process.env['TRACE_DB_SLOW'] || '100'), // Slow query threshold\n\n // API specific\n TRACE_API: process.env['TRACE_API'] === 'true', // Enable API tracing\n TRACE_API_SLOW: parseInt(process.env['TRACE_API_SLOW'] || '1000'), // Slow API threshold\n };\n\n // Log configuration if debugging is enabled\n if (config.DEBUG_TRACE || config.STACKMEMORY_DEBUG) {\n console.log('Trace Configuration:', {\n enabled: true,\n output: config.TRACE_OUTPUT,\n verbosity: config.TRACE_VERBOSITY,\n includeParams: config.TRACE_PARAMS,\n includeResults: config.TRACE_RESULTS,\n maskSensitive: config.TRACE_MASK_SENSITIVE,\n performanceThreshold: config.TRACE_PERF_THRESHOLD,\n captureMemory: config.TRACE_MEMORY,\n maxDepth: config.TRACE_MAX_DEPTH,\n database: {\n enabled: config.TRACE_DB,\n slowThreshold: config.TRACE_DB_SLOW,\n },\n api: {\n enabled: config.TRACE_API,\n slowThreshold: config.TRACE_API_SLOW,\n },\n });\n }\n}\n\n/**\n * Helper to enable tracing for a specific scope\n */\nexport function withTracing<T>(fn: () => T, options?: Partial<TraceConfig>): T {\n const originalEnv = process.env['DEBUG_TRACE'];\n\n try {\n // Temporarily enable tracing\n process.env['DEBUG_TRACE'] = 'true';\n\n // Apply custom options if provided\n if (options) {\n if (options.output) process.env['TRACE_OUTPUT'] = options.output;\n if (options.verbosity) process.env['TRACE_VERBOSITY'] = options.verbosity;\n if (options.includeParams !== undefined) {\n process.env['TRACE_PARAMS'] = String(options.includeParams);\n }\n if (options.includeResults !== undefined) {\n process.env['TRACE_RESULTS'] = String(options.includeResults);\n }\n if (options.performanceThreshold !== undefined) {\n process.env['TRACE_PERF_THRESHOLD'] = String(\n options.performanceThreshold\n );\n }\n }\n\n return fn();\n } finally {\n // Restore original environment\n if (originalEnv === undefined) {\n delete process.env['DEBUG_TRACE'];\n } else {\n process.env['DEBUG_TRACE'] = originalEnv;\n }\n }\n}\n\n/**\n * Quick enable/disable functions for debugging\n */\nexport const enableTracing = () => {\n process.env['DEBUG_TRACE'] = 'true';\n console.log('Tracing enabled');\n};\n\nexport const disableTracing = () => {\n delete process.env['DEBUG_TRACE'];\n console.log('Tracing disabled');\n};\n\nexport const enableVerboseTracing = () => {\n process.env['DEBUG_TRACE'] = 'true';\n process.env['TRACE_VERBOSITY'] = 'full';\n process.env['TRACE_PARAMS'] = 'true';\n process.env['TRACE_RESULTS'] = 'true';\n process.env['TRACE_MEMORY'] = 'true';\n console.log('Verbose tracing enabled');\n};\n\nexport const enableMinimalTracing = () => {\n process.env['DEBUG_TRACE'] = 'true';\n process.env['TRACE_VERBOSITY'] = 'summary';\n process.env['TRACE_PARAMS'] = 'false';\n process.env['TRACE_RESULTS'] = 'false';\n process.env['TRACE_MEMORY'] = 'false';\n console.log('\u2705 Minimal tracing enabled');\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -85,7 +85,7 @@ async function runDemo() {
|
|
|
85
85
|
console.log("STACKMEMORY DEBUG TRACE DEMO");
|
|
86
86
|
console.log("=".repeat(80) + "\n");
|
|
87
87
|
if (process.env["DEBUG_TRACE"] !== "true") {
|
|
88
|
-
console.log("
|
|
88
|
+
console.log("Enabling verbose tracing for this demo...\n");
|
|
89
89
|
enableVerboseTracing();
|
|
90
90
|
}
|
|
91
91
|
try {
|
|
@@ -95,12 +95,12 @@ async function runDemo() {
|
|
|
95
95
|
const data = await service.fetchData("test-1");
|
|
96
96
|
const processed = await service.processData(data);
|
|
97
97
|
service.cacheData("test-1", processed);
|
|
98
|
-
console.log("
|
|
98
|
+
console.log("Service operation completed\n");
|
|
99
99
|
});
|
|
100
100
|
await trace.command("demo:database", { example: "database" }, async () => {
|
|
101
101
|
console.log("\n--- Example 2: Database Operations ---\n");
|
|
102
102
|
const results = await databaseExample();
|
|
103
|
-
console.log("
|
|
103
|
+
console.log("Database operations completed");
|
|
104
104
|
console.log(" Found user:", results.user);
|
|
105
105
|
console.log(" Query results:", results.results);
|
|
106
106
|
});
|
|
@@ -110,7 +110,7 @@ async function runDemo() {
|
|
|
110
110
|
try {
|
|
111
111
|
await service.fetchData("error");
|
|
112
112
|
} catch (error) {
|
|
113
|
-
console.log("
|
|
113
|
+
console.log("Error properly traced and handled\n");
|
|
114
114
|
}
|
|
115
115
|
});
|
|
116
116
|
await trace.command(
|
|
@@ -126,18 +126,18 @@ async function runDemo() {
|
|
|
126
126
|
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
127
127
|
});
|
|
128
128
|
}
|
|
129
|
-
console.log("
|
|
129
|
+
console.log("Performance tracking completed\n");
|
|
130
130
|
}
|
|
131
131
|
);
|
|
132
132
|
} catch (error) {
|
|
133
|
-
console.error("
|
|
133
|
+
console.error("Demo failed:", error);
|
|
134
134
|
}
|
|
135
135
|
console.log("\n" + trace.getExecutionSummary());
|
|
136
136
|
const traces = trace.exportTraces();
|
|
137
137
|
console.log(`
|
|
138
|
-
|
|
138
|
+
Total traces collected: ${traces.length}`);
|
|
139
139
|
if (traces.length > 0) {
|
|
140
|
-
console.log("\
|
|
140
|
+
console.log("\nExample trace entry:");
|
|
141
141
|
console.log(JSON.stringify(traces[0], null, 2));
|
|
142
142
|
}
|
|
143
143
|
}
|
|
@@ -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 {\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('
|
|
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;AAIA,MAAM,eAAe;AAAA,EACX,OAAyB,oBAAI,IAAI;AAAA,EAEzC,MAAM,UAAU,IAA0B;AAExC,UAAM,KAAK,MAAM,EAAE;AAEnB,QAAI,OAAO,SAAS;AAClB,YAAM,IAAI,MAAM,qBAAqB;AAAA,IACvC;AAEA,WAAO,EAAE,IAAI,OAAO,KAAK,OAAO,EAAE;AAAA,EACpC;AAAA,EAEA,MAAM,YAAY,MAAyB;AACzC,WAAO,UAAU,mBAAmB,YAAY;AAC9C,YAAM,KAAK,MAAM,EAAE;AAEnB,UAAI,CAAC,KAAK,IAAI;AACZ,cAAM,IAAI,MAAM,0BAA0B;AAAA,MAC5C;AAEA,aAAO,UAAU,uBAAuB,YAAY;AAClD,cAAM,KAAK,MAAM,EAAE;AACnB,eAAO;AAAA,UACL,GAAG;AAAA,UACH,WAAW;AAAA,UACX,WAAW,KAAK,IAAI;AAAA,QACtB;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEA,UAAU,KAAa,OAAkB;AACvC,UAAM,UAAU,YAAY,aAAa,EAAE,KAAK,MAAM,GAAG,MAAM;AAC7D,WAAK,KAAK,IAAI,KAAK,KAAK;AAAA,IAC1B,CAAC;AAAA,EACH;AAAA,EAEQ,MAAM,IAA2B;AACvC,WAAO,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,EAAE,CAAC;AAAA,EACzD;AACF;AAGA,eAAe,kBAAkB;AAC/B,SAAO,MAAM,KAAK,+BAA+B,YAAY;AAC3D,UAAM,KAAK,qBAAqB,UAAU;AAG1C,OAAG,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,KAOP;AAGD,UAAM,SAAS,GAAG,QAAQ,+CAA+C;AACzE,WAAO,IAAI,SAAS,mBAAmB;AACvC,WAAO,IAAI,OAAO,iBAAiB;AAGnC,UAAM,SAAS,GAAG,QAAQ,oCAAoC;AAC9D,UAAM,OAAO,OAAO,IAAI,OAAO;AAG/B,UAAM,UAAU,GAAG,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,KAQ1B;AACD,UAAM,UAAU,QAAQ,IAAI;AAE5B,OAAG,MAAM;AAET,WAAO,EAAE,MAAM,QAAQ;AAAA,EACzB,CAAC;AACH;AAGA,eAAe,UAAU;AACvB,UAAQ,IAAI,OAAO,IAAI,OAAO,EAAE,CAAC;AACjC,UAAQ,IAAI,8BAA8B;AAC1C,UAAQ,IAAI,IAAI,OAAO,EAAE,IAAI,IAAI;AAGjC,MAAI,QAAQ,IAAI,aAAa,MAAM,QAAQ;AACzC,YAAQ,IAAI,
|
|
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('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('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('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('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('Performance tracking completed\\n');\n }\n );\n } catch (error: unknown) {\n console.error('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(`\\nTotal traces collected: ${traces.length}`);\n\n // Show example trace entry\n if (traces.length > 0) {\n console.log('\\nExample 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
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { TraceDetector } from "./trace-detector.js";
|
|
2
2
|
import { v4 as uuidv4 } from "uuid";
|
|
3
3
|
const detector = new TraceDetector();
|
|
4
|
-
console.log("
|
|
4
|
+
console.log("Trace Detection Demo\n");
|
|
5
5
|
console.log("=".repeat(50));
|
|
6
6
|
console.log("\n\u{1F4CB} Simulating Search-Driven Modification:");
|
|
7
7
|
const baseTime = Date.now();
|
|
@@ -35,7 +35,7 @@ searchDrivenTools.forEach((tool) => {
|
|
|
35
35
|
detector.addToolCall(tool);
|
|
36
36
|
console.log(` Added: ${tool.tool}`);
|
|
37
37
|
});
|
|
38
|
-
console.log("\
|
|
38
|
+
console.log("\nSimulating Error Recovery:");
|
|
39
39
|
const errorTime = baseTime + 4e4;
|
|
40
40
|
const errorRecoveryTools = [
|
|
41
41
|
{
|
|
@@ -90,7 +90,7 @@ featureTools.forEach((tool) => {
|
|
|
90
90
|
console.log(` Added: ${tool.tool}`);
|
|
91
91
|
});
|
|
92
92
|
detector.flush();
|
|
93
|
-
console.log("\
|
|
93
|
+
console.log("\nTrace Statistics:");
|
|
94
94
|
console.log("=".repeat(50));
|
|
95
95
|
const stats = detector.getStatistics();
|
|
96
96
|
console.log(`Total Traces: ${stats.totalTraces}`);
|
|
@@ -101,7 +101,7 @@ console.log("\nTrace Types:");
|
|
|
101
101
|
Object.entries(stats.tracesByType).forEach(([type, count]) => {
|
|
102
102
|
console.log(` ${type}: ${count}`);
|
|
103
103
|
});
|
|
104
|
-
console.log("\
|
|
104
|
+
console.log("\nDetected Traces:");
|
|
105
105
|
console.log("=".repeat(50));
|
|
106
106
|
const traces = detector.getTraces();
|
|
107
107
|
traces.forEach((trace, index) => {
|
|
@@ -134,5 +134,5 @@ highImportance.forEach((trace) => {
|
|
|
134
134
|
console.log("\n\u{1F4BE} Exporting traces to JSON...");
|
|
135
135
|
const exported = detector.exportTraces();
|
|
136
136
|
console.log(`Exported ${exported.length} characters of JSON data`);
|
|
137
|
-
console.log("\
|
|
137
|
+
console.log("\nDemo complete!");
|
|
138
138
|
//# sourceMappingURL=trace-detector.demo.js.map
|