@stackmemoryai/stackmemory 0.3.7 → 0.3.9

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.
Files changed (202) hide show
  1. package/dist/agents/core/agent-task-manager.js +5 -5
  2. package/dist/agents/core/agent-task-manager.js.map +2 -2
  3. package/dist/agents/verifiers/base-verifier.js +2 -2
  4. package/dist/agents/verifiers/base-verifier.js.map +2 -2
  5. package/dist/cli/claude-sm.js +0 -11
  6. package/dist/cli/claude-sm.js.map +2 -2
  7. package/dist/cli/codex-sm.js +0 -11
  8. package/dist/cli/codex-sm.js.map +2 -2
  9. package/dist/cli/commands/chromadb.js +64 -34
  10. package/dist/cli/commands/chromadb.js.map +2 -2
  11. package/dist/cli/commands/clear.js +9 -13
  12. package/dist/cli/commands/clear.js.map +2 -2
  13. package/dist/cli/commands/config.js +43 -33
  14. package/dist/cli/commands/config.js.map +2 -2
  15. package/dist/cli/commands/context.js.map +2 -2
  16. package/dist/cli/commands/dashboard.js +41 -13
  17. package/dist/cli/commands/dashboard.js.map +2 -2
  18. package/dist/cli/commands/gc.js +69 -20
  19. package/dist/cli/commands/gc.js.map +2 -2
  20. package/dist/cli/commands/handoff.js.map +2 -2
  21. package/dist/cli/commands/infinite-storage.js +60 -19
  22. package/dist/cli/commands/infinite-storage.js.map +2 -2
  23. package/dist/cli/commands/linear-create.js +36 -8
  24. package/dist/cli/commands/linear-create.js.map +2 -2
  25. package/dist/cli/commands/linear-list.js +33 -10
  26. package/dist/cli/commands/linear-list.js.map +2 -2
  27. package/dist/cli/commands/linear-migrate.js +17 -4
  28. package/dist/cli/commands/linear-migrate.js.map +2 -2
  29. package/dist/cli/commands/linear-test.js +14 -6
  30. package/dist/cli/commands/linear-test.js.map +2 -2
  31. package/dist/cli/commands/linear-unified.js +123 -35
  32. package/dist/cli/commands/linear-unified.js.map +2 -2
  33. package/dist/cli/commands/linear.js.map +2 -2
  34. package/dist/cli/commands/monitor.js.map +2 -2
  35. package/dist/cli/commands/onboard.js +35 -8
  36. package/dist/cli/commands/onboard.js.map +2 -2
  37. package/dist/cli/commands/quality.js +2 -7
  38. package/dist/cli/commands/quality.js.map +2 -2
  39. package/dist/cli/commands/session.js +23 -6
  40. package/dist/cli/commands/session.js.map +2 -2
  41. package/dist/cli/commands/skills.js +72 -27
  42. package/dist/cli/commands/skills.js.map +2 -2
  43. package/dist/cli/commands/storage.js +108 -38
  44. package/dist/cli/commands/storage.js.map +2 -2
  45. package/dist/cli/commands/tui.js.map +2 -2
  46. package/dist/cli/commands/webhook.js +57 -18
  47. package/dist/cli/commands/webhook.js.map +2 -2
  48. package/dist/cli/commands/workflow.js +8 -15
  49. package/dist/cli/commands/workflow.js.map +2 -2
  50. package/dist/cli/commands/worktree.js +34 -13
  51. package/dist/cli/commands/worktree.js.map +2 -2
  52. package/dist/cli/index.js +0 -11
  53. package/dist/cli/index.js.map +2 -2
  54. package/dist/core/config/types.js.map +1 -1
  55. package/dist/core/context/auto-context.js +10 -6
  56. package/dist/core/context/auto-context.js.map +2 -2
  57. package/dist/core/context/context-bridge.js.map +2 -2
  58. package/dist/core/context/frame-database.js +13 -3
  59. package/dist/core/context/frame-database.js.map +2 -2
  60. package/dist/core/context/frame-digest.js +7 -5
  61. package/dist/core/context/frame-digest.js.map +2 -2
  62. package/dist/core/context/frame-manager.js.map +2 -2
  63. package/dist/core/context/frame-stack.js +16 -5
  64. package/dist/core/context/frame-stack.js.map +2 -2
  65. package/dist/core/context/incremental-gc.js +10 -3
  66. package/dist/core/context/incremental-gc.js.map +2 -2
  67. package/dist/core/context/index.js.map +1 -1
  68. package/dist/core/context/permission-manager.js.map +2 -2
  69. package/dist/core/context/recursive-context-manager.js +582 -0
  70. package/dist/core/context/recursive-context-manager.js.map +7 -0
  71. package/dist/core/context/refactored-frame-manager.js +12 -3
  72. package/dist/core/context/refactored-frame-manager.js.map +2 -2
  73. package/dist/core/context/shared-context-layer.js +4 -2
  74. package/dist/core/context/shared-context-layer.js.map +2 -2
  75. package/dist/core/database/batch-operations.js +112 -86
  76. package/dist/core/database/batch-operations.js.map +2 -2
  77. package/dist/core/database/query-cache.js +19 -9
  78. package/dist/core/database/query-cache.js.map +2 -2
  79. package/dist/core/database/sqlite-adapter.js +1 -1
  80. package/dist/core/database/sqlite-adapter.js.map +2 -2
  81. package/dist/core/digest/enhanced-hybrid-digest.js +8 -2
  82. package/dist/core/digest/enhanced-hybrid-digest.js.map +2 -2
  83. package/dist/core/errors/recovery.js +9 -2
  84. package/dist/core/errors/recovery.js.map +2 -2
  85. package/dist/core/execution/parallel-executor.js +254 -0
  86. package/dist/core/execution/parallel-executor.js.map +7 -0
  87. package/dist/core/frame/workflow-templates-stub.js.map +1 -1
  88. package/dist/core/frame/workflow-templates.js +40 -1
  89. package/dist/core/frame/workflow-templates.js.map +2 -2
  90. package/dist/core/monitoring/logger.js +6 -1
  91. package/dist/core/monitoring/logger.js.map +2 -2
  92. package/dist/core/monitoring/metrics.js.map +2 -2
  93. package/dist/core/monitoring/progress-tracker.js.map +2 -2
  94. package/dist/core/performance/context-cache.js.map +2 -2
  95. package/dist/core/performance/lazy-context-loader.js +24 -20
  96. package/dist/core/performance/lazy-context-loader.js.map +2 -2
  97. package/dist/core/performance/optimized-frame-context.js +27 -12
  98. package/dist/core/performance/optimized-frame-context.js.map +2 -2
  99. package/dist/core/performance/performance-benchmark.js +10 -6
  100. package/dist/core/performance/performance-benchmark.js.map +2 -2
  101. package/dist/core/performance/performance-profiler.js +51 -14
  102. package/dist/core/performance/performance-profiler.js.map +2 -2
  103. package/dist/core/performance/streaming-jsonl-parser.js +5 -1
  104. package/dist/core/performance/streaming-jsonl-parser.js.map +2 -2
  105. package/dist/core/projects/project-manager.js +14 -20
  106. package/dist/core/projects/project-manager.js.map +2 -2
  107. package/dist/core/retrieval/context-retriever.js.map +1 -1
  108. package/dist/core/retrieval/llm-context-retrieval.js.map +2 -2
  109. package/dist/core/session/clear-survival-stub.js +5 -1
  110. package/dist/core/session/clear-survival-stub.js.map +2 -2
  111. package/dist/core/session/clear-survival.js +35 -0
  112. package/dist/core/session/clear-survival.js.map +2 -2
  113. package/dist/core/session/index.js.map +1 -1
  114. package/dist/core/session/session-manager.js.map +2 -2
  115. package/dist/core/storage/chromadb-adapter.js +6 -2
  116. package/dist/core/storage/chromadb-adapter.js.map +2 -2
  117. package/dist/core/storage/chromadb-simple.js +17 -5
  118. package/dist/core/storage/chromadb-simple.js.map +2 -2
  119. package/dist/core/storage/infinite-storage.js +109 -46
  120. package/dist/core/storage/infinite-storage.js.map +2 -2
  121. package/dist/core/storage/railway-optimized-storage.js +48 -22
  122. package/dist/core/storage/railway-optimized-storage.js.map +2 -2
  123. package/dist/core/storage/remote-storage.js +41 -23
  124. package/dist/core/storage/remote-storage.js.map +2 -2
  125. package/dist/core/trace/cli-trace-wrapper.js +9 -2
  126. package/dist/core/trace/cli-trace-wrapper.js.map +2 -2
  127. package/dist/core/trace/db-trace-wrapper.js +96 -68
  128. package/dist/core/trace/db-trace-wrapper.js.map +2 -2
  129. package/dist/core/trace/debug-trace.js +25 -8
  130. package/dist/core/trace/debug-trace.js.map +2 -2
  131. package/dist/core/trace/index.js +6 -2
  132. package/dist/core/trace/index.js.map +2 -2
  133. package/dist/core/trace/linear-api-wrapper.js +10 -5
  134. package/dist/core/trace/linear-api-wrapper.js.map +2 -2
  135. package/dist/core/trace/trace-demo.js +14 -10
  136. package/dist/core/trace/trace-demo.js.map +2 -2
  137. package/dist/core/trace/trace-detector.js +9 -2
  138. package/dist/core/trace/trace-detector.js.map +2 -2
  139. package/dist/core/trace/types.js.map +1 -1
  140. package/dist/core/utils/compression.js.map +1 -1
  141. package/dist/core/utils/update-checker.js.map +1 -1
  142. package/dist/core/worktree/worktree-manager.js +18 -7
  143. package/dist/core/worktree/worktree-manager.js.map +2 -2
  144. package/dist/features/analytics/core/analytics-service.js.map +2 -2
  145. package/dist/features/analytics/queries/metrics-queries.js +1 -1
  146. package/dist/features/analytics/queries/metrics-queries.js.map +2 -2
  147. package/dist/features/tasks/pebbles-task-store.js.map +1 -1
  148. package/dist/features/tui/components/analytics-panel.js +36 -15
  149. package/dist/features/tui/components/analytics-panel.js.map +2 -2
  150. package/dist/features/tui/components/pr-tracker.js +19 -7
  151. package/dist/features/tui/components/pr-tracker.js.map +2 -2
  152. package/dist/features/tui/components/session-monitor.js +22 -9
  153. package/dist/features/tui/components/session-monitor.js.map +2 -2
  154. package/dist/features/tui/components/subagent-fleet.js +20 -13
  155. package/dist/features/tui/components/subagent-fleet.js.map +2 -2
  156. package/dist/features/tui/components/task-board.js +26 -10
  157. package/dist/features/tui/components/task-board.js.map +2 -2
  158. package/dist/features/tui/index.js.map +2 -2
  159. package/dist/features/tui/services/data-service.js +6 -2
  160. package/dist/features/tui/services/data-service.js.map +2 -2
  161. package/dist/features/tui/services/linear-task-reader.js +3 -1
  162. package/dist/features/tui/services/linear-task-reader.js.map +2 -2
  163. package/dist/features/tui/services/websocket-client.js +3 -1
  164. package/dist/features/tui/services/websocket-client.js.map +2 -2
  165. package/dist/features/tui/terminal-compat.js +6 -2
  166. package/dist/features/tui/terminal-compat.js.map +2 -2
  167. package/dist/features/web/client/stores/task-store.js.map +2 -2
  168. package/dist/features/web/server/index.js +18 -10
  169. package/dist/features/web/server/index.js.map +2 -2
  170. package/dist/integrations/anthropic/client.js +259 -0
  171. package/dist/integrations/anthropic/client.js.map +7 -0
  172. package/dist/integrations/claude-code/subagent-client.js +404 -0
  173. package/dist/integrations/claude-code/subagent-client.js.map +7 -0
  174. package/dist/integrations/linear/sync-service.js +12 -13
  175. package/dist/integrations/linear/sync-service.js.map +2 -2
  176. package/dist/integrations/linear/sync.js +174 -12
  177. package/dist/integrations/linear/sync.js.map +2 -2
  178. package/dist/integrations/linear/unified-sync.js +1 -1
  179. package/dist/integrations/linear/unified-sync.js.map +1 -1
  180. package/dist/integrations/linear/webhook-server.js +15 -16
  181. package/dist/integrations/linear/webhook-server.js.map +2 -2
  182. package/dist/mcp/stackmemory-mcp-server.js +0 -11
  183. package/dist/mcp/stackmemory-mcp-server.js.map +2 -2
  184. package/dist/servers/production/auth-middleware.js.map +2 -2
  185. package/dist/servers/railway/index.js.map +2 -2
  186. package/dist/services/config-service.js +6 -7
  187. package/dist/services/config-service.js.map +2 -2
  188. package/dist/services/context-service.js +11 -12
  189. package/dist/services/context-service.js.map +2 -2
  190. package/dist/skills/claude-skills.js +101 -2
  191. package/dist/skills/claude-skills.js.map +2 -2
  192. package/dist/skills/dashboard-launcher.js.map +2 -2
  193. package/dist/skills/recursive-agent-orchestrator.js +559 -0
  194. package/dist/skills/recursive-agent-orchestrator.js.map +7 -0
  195. package/dist/skills/repo-ingestion-skill.js.map +2 -2
  196. package/dist/skills/security-secrets-scanner.js +265 -0
  197. package/dist/skills/security-secrets-scanner.js.map +7 -0
  198. package/dist/utils/env.js +46 -0
  199. package/dist/utils/env.js.map +7 -0
  200. package/dist/utils/logger.js +0 -11
  201. package/dist/utils/logger.js.map +2 -2
  202. package/package.json +1 -1
@@ -0,0 +1,259 @@
1
+ import { logger } from "../../core/monitoring/logger.js";
2
+ class AnthropicClient {
3
+ apiKey;
4
+ baseURL;
5
+ maxRetries;
6
+ timeout;
7
+ // Rate limiting
8
+ requestCount = 0;
9
+ lastResetTime = Date.now();
10
+ rateLimitPerMinute = 60;
11
+ constructor(config) {
12
+ this.apiKey = config?.apiKey || process.env["ANTHROPIC_API_KEY"] || "";
13
+ this.baseURL = config?.baseURL || "https://api.anthropic.com";
14
+ this.maxRetries = config?.maxRetries || 3;
15
+ this.timeout = config?.timeout || 6e4;
16
+ if (!this.apiKey) {
17
+ logger.warn("Anthropic API key not configured. Using mock mode.");
18
+ }
19
+ logger.info("Anthropic client initialized", {
20
+ baseURL: this.baseURL,
21
+ maxRetries: this.maxRetries,
22
+ timeout: this.timeout,
23
+ mockMode: !this.apiKey
24
+ });
25
+ }
26
+ /**
27
+ * Send completion request to Claude
28
+ */
29
+ async complete(request) {
30
+ await this.checkRateLimit();
31
+ logger.debug("Sending completion request", {
32
+ model: request.model,
33
+ promptLength: request.prompt.length,
34
+ maxTokens: request.maxTokens
35
+ });
36
+ if (!this.apiKey) {
37
+ return this.mockComplete(request);
38
+ }
39
+ try {
40
+ const response = await this.sendRequest(request);
41
+ return response.content;
42
+ } catch (error) {
43
+ logger.error("Anthropic API error", { error });
44
+ throw error;
45
+ }
46
+ }
47
+ /**
48
+ * Send request with retry logic
49
+ */
50
+ async sendRequest(request, attempt = 1) {
51
+ try {
52
+ return this.createMockResponse(request);
53
+ } catch (error) {
54
+ if (attempt < this.maxRetries) {
55
+ const delay = Math.pow(2, attempt) * 1e3;
56
+ logger.warn(`Retrying after ${delay}ms (attempt ${attempt}/${this.maxRetries})`);
57
+ await this.delay(delay);
58
+ return this.sendRequest(request, attempt + 1);
59
+ }
60
+ throw error;
61
+ }
62
+ }
63
+ /**
64
+ * Mock completion for development/testing
65
+ */
66
+ async mockComplete(request) {
67
+ await this.delay(500 + Math.random() * 1500);
68
+ if (request.systemPrompt.includes("Planning Agent")) {
69
+ return this.mockPlanningResponse(request.prompt);
70
+ } else if (request.systemPrompt.includes("Code Agent")) {
71
+ return this.mockCodeResponse(request.prompt);
72
+ } else if (request.systemPrompt.includes("Testing Agent")) {
73
+ return this.mockTestingResponse(request.prompt);
74
+ } else if (request.systemPrompt.includes("Review Agent")) {
75
+ return this.mockReviewResponse(request.prompt);
76
+ } else {
77
+ return `Mock response for: ${request.prompt.slice(0, 100)}...`;
78
+ }
79
+ }
80
+ /**
81
+ * Mock response generators
82
+ */
83
+ mockPlanningResponse(prompt) {
84
+ return JSON.stringify({
85
+ plan: {
86
+ type: "sequential",
87
+ tasks: [
88
+ {
89
+ id: "task-1",
90
+ description: "Analyze requirements",
91
+ agent: "context",
92
+ dependencies: []
93
+ },
94
+ {
95
+ id: "task-2",
96
+ type: "parallel",
97
+ description: "Implementation phase",
98
+ children: [
99
+ {
100
+ id: "task-2a",
101
+ description: "Write core logic",
102
+ agent: "code",
103
+ dependencies: ["task-1"]
104
+ },
105
+ {
106
+ id: "task-2b",
107
+ description: "Write tests",
108
+ agent: "testing",
109
+ dependencies: ["task-1"]
110
+ }
111
+ ]
112
+ },
113
+ {
114
+ id: "task-3",
115
+ description: "Review and improve",
116
+ agent: "review",
117
+ dependencies: ["task-2"]
118
+ }
119
+ ]
120
+ }
121
+ }, null, 2);
122
+ }
123
+ mockCodeResponse(prompt) {
124
+ return `
125
+ // Mock implementation
126
+ export function processTask(input: string): string {
127
+ // TODO: Implement actual logic
128
+ console.log('Processing:', input);
129
+ return \`Processed: \${input}\`;
130
+ }
131
+
132
+ export function validateInput(input: unknown): boolean {
133
+ return typeof input === 'string' && input.length > 0;
134
+ }
135
+ `.trim();
136
+ }
137
+ mockTestingResponse(prompt) {
138
+ return `
139
+ import { describe, test, expect } from 'vitest';
140
+ import { processTask, validateInput } from './implementation';
141
+
142
+ describe('processTask', () => {
143
+ test('should process valid input', () => {
144
+ const result = processTask('test input');
145
+ expect(result).toBe('Processed: test input');
146
+ });
147
+
148
+ test('should handle empty input', () => {
149
+ const result = processTask('');
150
+ expect(result).toBe('Processed: ');
151
+ });
152
+ });
153
+
154
+ describe('validateInput', () => {
155
+ test('should validate string input', () => {
156
+ expect(validateInput('valid')).toBe(true);
157
+ expect(validateInput('')).toBe(false);
158
+ expect(validateInput(123)).toBe(false);
159
+ expect(validateInput(null)).toBe(false);
160
+ });
161
+ });
162
+ `.trim();
163
+ }
164
+ mockReviewResponse(prompt) {
165
+ return JSON.stringify({
166
+ quality: 0.75,
167
+ issues: [
168
+ "Missing error handling in processTask function",
169
+ "No input validation before processing",
170
+ "Tests could cover more edge cases"
171
+ ],
172
+ suggestions: [
173
+ "Add try-catch block in processTask",
174
+ "Validate input length and type",
175
+ "Add tests for special characters and long inputs",
176
+ "Consider adding performance tests"
177
+ ],
178
+ improvements: [
179
+ {
180
+ file: "implementation.ts",
181
+ line: 3,
182
+ suggestion: "Add input validation",
183
+ priority: "high"
184
+ },
185
+ {
186
+ file: "tests.ts",
187
+ line: 15,
188
+ suggestion: "Add edge case tests",
189
+ priority: "medium"
190
+ }
191
+ ]
192
+ }, null, 2);
193
+ }
194
+ /**
195
+ * Create mock response object
196
+ */
197
+ createMockResponse(request) {
198
+ const content = this.mockComplete(request).toString();
199
+ return {
200
+ content,
201
+ stopReason: "stop_sequence",
202
+ model: request.model,
203
+ usage: {
204
+ inputTokens: Math.ceil(request.prompt.length / 4),
205
+ outputTokens: Math.ceil(content.length / 4)
206
+ }
207
+ };
208
+ }
209
+ /**
210
+ * Check rate limiting
211
+ */
212
+ async checkRateLimit() {
213
+ const now = Date.now();
214
+ const timeSinceReset = now - this.lastResetTime;
215
+ if (timeSinceReset >= 6e4) {
216
+ this.requestCount = 0;
217
+ this.lastResetTime = now;
218
+ }
219
+ if (this.requestCount >= this.rateLimitPerMinute) {
220
+ const waitTime = 6e4 - timeSinceReset;
221
+ logger.warn(`Rate limit reached, waiting ${waitTime}ms`);
222
+ await this.delay(waitTime);
223
+ this.requestCount = 0;
224
+ this.lastResetTime = Date.now();
225
+ }
226
+ this.requestCount++;
227
+ }
228
+ /**
229
+ * Stream completion response
230
+ */
231
+ async *streamComplete(request) {
232
+ const response = await this.complete(request);
233
+ const words = response.split(" ");
234
+ for (const word of words) {
235
+ yield word + " ";
236
+ await this.delay(50);
237
+ }
238
+ }
239
+ /**
240
+ * Utility delay function
241
+ */
242
+ delay(ms) {
243
+ return new Promise((resolve) => setTimeout(resolve, ms));
244
+ }
245
+ /**
246
+ * Get API usage statistics
247
+ */
248
+ getUsageStats() {
249
+ return {
250
+ requestCount: this.requestCount,
251
+ rateLimitRemaining: this.rateLimitPerMinute - this.requestCount,
252
+ resetTime: new Date(this.lastResetTime + 6e4).toISOString()
253
+ };
254
+ }
255
+ }
256
+ export {
257
+ AnthropicClient
258
+ };
259
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/integrations/anthropic/client.ts"],
4
+ "sourcesContent": ["/**\n * Anthropic API Client for Claude Integration\n * \n * Manages API calls to Claude with retry logic, rate limiting,\n * and response streaming\n */\n\nimport { logger } from '../../core/monitoring/logger.js';\n\nexport interface CompletionRequest {\n model: string;\n systemPrompt: string;\n prompt: string;\n maxTokens: number;\n temperature: number;\n stream?: boolean;\n}\n\nexport interface CompletionResponse {\n content: string;\n stopReason: string;\n model: string;\n usage: {\n inputTokens: number;\n outputTokens: number;\n };\n}\n\nexport interface AnthropicClientConfig {\n apiKey?: string;\n baseURL?: string;\n maxRetries?: number;\n timeout?: number;\n}\n\n/**\n * Anthropic API Client\n * \n * NOTE: This is a mock implementation. In production, you would:\n * 1. Install @anthropic-ai/sdk: npm install @anthropic-ai/sdk\n * 2. Use the actual SDK methods\n * 3. Handle real API responses\n */\nexport class AnthropicClient {\n private apiKey: string;\n private baseURL: string;\n private maxRetries: number;\n private timeout: number;\n \n // Rate limiting\n private requestCount: number = 0;\n private lastResetTime: number = Date.now();\n private rateLimitPerMinute: number = 60;\n \n constructor(config?: AnthropicClientConfig) {\n this.apiKey = config?.apiKey || process.env['ANTHROPIC_API_KEY'] || '';\n this.baseURL = config?.baseURL || 'https://api.anthropic.com';\n this.maxRetries = config?.maxRetries || 3;\n this.timeout = config?.timeout || 60000;\n \n if (!this.apiKey) {\n logger.warn('Anthropic API key not configured. Using mock mode.');\n }\n \n logger.info('Anthropic client initialized', {\n baseURL: this.baseURL,\n maxRetries: this.maxRetries,\n timeout: this.timeout,\n mockMode: !this.apiKey,\n });\n }\n \n /**\n * Send completion request to Claude\n */\n async complete(request: CompletionRequest): Promise<string> {\n // Rate limiting check\n await this.checkRateLimit();\n \n logger.debug('Sending completion request', {\n model: request.model,\n promptLength: request.prompt.length,\n maxTokens: request.maxTokens,\n });\n \n // Mock implementation for development\n if (!this.apiKey) {\n return this.mockComplete(request);\n }\n \n // Real implementation would use Anthropic SDK\n try {\n const response = await this.sendRequest(request);\n return response.content;\n } catch (error) {\n logger.error('Anthropic API error', { error });\n throw error;\n }\n }\n \n /**\n * Send request with retry logic\n */\n private async sendRequest(\n request: CompletionRequest,\n attempt: number = 1\n ): Promise<CompletionResponse> {\n try {\n // In production, use actual Anthropic SDK:\n /*\n import Anthropic from '@anthropic-ai/sdk';\n \n const anthropic = new Anthropic({\n apiKey: this.apiKey,\n });\n \n const response = await anthropic.messages.create({\n model: request.model,\n system: request.systemPrompt,\n messages: [{ role: 'user', content: request.prompt }],\n max_tokens: request.maxTokens,\n temperature: request.temperature,\n });\n \n return {\n content: response.content[0].text,\n stopReason: response.stop_reason,\n model: response.model,\n usage: {\n inputTokens: response.usage.input_tokens,\n outputTokens: response.usage.output_tokens,\n },\n };\n */\n \n // Mock response for now\n return this.createMockResponse(request);\n \n } catch (error: any) {\n if (attempt < this.maxRetries) {\n const delay = Math.pow(2, attempt) * 1000;\n logger.warn(`Retrying after ${delay}ms (attempt ${attempt}/${this.maxRetries})`);\n await this.delay(delay);\n return this.sendRequest(request, attempt + 1);\n }\n throw error;\n }\n }\n \n /**\n * Mock completion for development/testing\n */\n private async mockComplete(request: CompletionRequest): Promise<string> {\n // Simulate API delay\n await this.delay(500 + Math.random() * 1500);\n \n // Generate mock response based on agent type\n if (request.systemPrompt.includes('Planning Agent')) {\n return this.mockPlanningResponse(request.prompt);\n } else if (request.systemPrompt.includes('Code Agent')) {\n return this.mockCodeResponse(request.prompt);\n } else if (request.systemPrompt.includes('Testing Agent')) {\n return this.mockTestingResponse(request.prompt);\n } else if (request.systemPrompt.includes('Review Agent')) {\n return this.mockReviewResponse(request.prompt);\n } else {\n return `Mock response for: ${request.prompt.slice(0, 100)}...`;\n }\n }\n \n /**\n * Mock response generators\n */\n \n private mockPlanningResponse(prompt: string): string {\n return JSON.stringify({\n plan: {\n type: 'sequential',\n tasks: [\n {\n id: 'task-1',\n description: 'Analyze requirements',\n agent: 'context',\n dependencies: [],\n },\n {\n id: 'task-2',\n type: 'parallel',\n description: 'Implementation phase',\n children: [\n {\n id: 'task-2a',\n description: 'Write core logic',\n agent: 'code',\n dependencies: ['task-1'],\n },\n {\n id: 'task-2b',\n description: 'Write tests',\n agent: 'testing',\n dependencies: ['task-1'],\n },\n ],\n },\n {\n id: 'task-3',\n description: 'Review and improve',\n agent: 'review',\n dependencies: ['task-2'],\n },\n ],\n },\n }, null, 2);\n }\n \n private mockCodeResponse(prompt: string): string {\n return `\n// Mock implementation\nexport function processTask(input: string): string {\n // TODO: Implement actual logic\n console.log('Processing:', input);\n return \\`Processed: \\${input}\\`;\n}\n\nexport function validateInput(input: unknown): boolean {\n return typeof input === 'string' && input.length > 0;\n}\n `.trim();\n }\n \n private mockTestingResponse(prompt: string): string {\n return `\nimport { describe, test, expect } from 'vitest';\nimport { processTask, validateInput } from './implementation';\n\ndescribe('processTask', () => {\n test('should process valid input', () => {\n const result = processTask('test input');\n expect(result).toBe('Processed: test input');\n });\n \n test('should handle empty input', () => {\n const result = processTask('');\n expect(result).toBe('Processed: ');\n });\n});\n\ndescribe('validateInput', () => {\n test('should validate string input', () => {\n expect(validateInput('valid')).toBe(true);\n expect(validateInput('')).toBe(false);\n expect(validateInput(123)).toBe(false);\n expect(validateInput(null)).toBe(false);\n });\n});\n `.trim();\n }\n \n private mockReviewResponse(prompt: string): string {\n return JSON.stringify({\n quality: 0.75,\n issues: [\n 'Missing error handling in processTask function',\n 'No input validation before processing',\n 'Tests could cover more edge cases',\n ],\n suggestions: [\n 'Add try-catch block in processTask',\n 'Validate input length and type',\n 'Add tests for special characters and long inputs',\n 'Consider adding performance tests',\n ],\n improvements: [\n {\n file: 'implementation.ts',\n line: 3,\n suggestion: 'Add input validation',\n priority: 'high',\n },\n {\n file: 'tests.ts',\n line: 15,\n suggestion: 'Add edge case tests',\n priority: 'medium',\n },\n ],\n }, null, 2);\n }\n \n /**\n * Create mock response object\n */\n private createMockResponse(request: CompletionRequest): CompletionResponse {\n const content = this.mockComplete(request).toString();\n \n return {\n content,\n stopReason: 'stop_sequence',\n model: request.model,\n usage: {\n inputTokens: Math.ceil(request.prompt.length / 4),\n outputTokens: Math.ceil(content.length / 4),\n },\n };\n }\n \n /**\n * Check rate limiting\n */\n private async checkRateLimit(): Promise<void> {\n const now = Date.now();\n const timeSinceReset = now - this.lastResetTime;\n \n if (timeSinceReset >= 60000) {\n this.requestCount = 0;\n this.lastResetTime = now;\n }\n \n if (this.requestCount >= this.rateLimitPerMinute) {\n const waitTime = 60000 - timeSinceReset;\n logger.warn(`Rate limit reached, waiting ${waitTime}ms`);\n await this.delay(waitTime);\n this.requestCount = 0;\n this.lastResetTime = Date.now();\n }\n \n this.requestCount++;\n }\n \n /**\n * Stream completion response\n */\n async *streamComplete(request: CompletionRequest): AsyncGenerator<string> {\n // Mock streaming implementation\n const response = await this.complete(request);\n const words = response.split(' ');\n \n for (const word of words) {\n yield word + ' ';\n await this.delay(50); // Simulate streaming delay\n }\n }\n \n /**\n * Utility delay function\n */\n private delay(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n }\n \n /**\n * Get API usage statistics\n */\n getUsageStats() {\n return {\n requestCount: this.requestCount,\n rateLimitRemaining: this.rateLimitPerMinute - this.requestCount,\n resetTime: new Date(this.lastResetTime + 60000).toISOString(),\n };\n }\n}"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,404 @@
1
+ import { logger } from "../../core/monitoring/logger.js";
2
+ import { exec } from "child_process";
3
+ import { promisify } from "util";
4
+ import * as fs from "fs";
5
+ import * as path from "path";
6
+ import * as os from "os";
7
+ const execAsync = promisify(exec);
8
+ class ClaudeCodeSubagentClient {
9
+ tempDir;
10
+ activeSubagents = /* @__PURE__ */ new Map();
11
+ constructor() {
12
+ this.tempDir = path.join(os.tmpdir(), "stackmemory-rlm");
13
+ if (!fs.existsSync(this.tempDir)) {
14
+ fs.mkdirSync(this.tempDir, { recursive: true });
15
+ }
16
+ logger.info("Claude Code Subagent Client initialized", {
17
+ tempDir: this.tempDir
18
+ });
19
+ }
20
+ /**
21
+ * Execute a subagent task using Claude Code's Task tool
22
+ * This will spawn a new Claude instance with specific instructions
23
+ */
24
+ async executeSubagent(request) {
25
+ const startTime = Date.now();
26
+ const subagentId = `${request.type}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
27
+ logger.info(`Spawning ${request.type} subagent`, {
28
+ subagentId,
29
+ task: request.task.slice(0, 100)
30
+ });
31
+ try {
32
+ const prompt = this.buildSubagentPrompt(request);
33
+ const contextFile = path.join(this.tempDir, `${subagentId}-context.json`);
34
+ await fs.promises.writeFile(
35
+ contextFile,
36
+ JSON.stringify(request.context, null, 2)
37
+ );
38
+ const resultFile = path.join(this.tempDir, `${subagentId}-result.json`);
39
+ const taskCommand = this.buildTaskCommand(request, prompt, contextFile, resultFile);
40
+ const result = await this.executeTaskTool(taskCommand, request.timeout);
41
+ let subagentResult = {};
42
+ if (fs.existsSync(resultFile)) {
43
+ const resultContent = await fs.promises.readFile(resultFile, "utf-8");
44
+ try {
45
+ subagentResult = JSON.parse(resultContent);
46
+ } catch (e) {
47
+ subagentResult = { rawOutput: resultContent };
48
+ }
49
+ }
50
+ this.cleanup(subagentId);
51
+ return {
52
+ success: true,
53
+ result: subagentResult,
54
+ output: result.stdout,
55
+ duration: Date.now() - startTime,
56
+ subagentType: request.type,
57
+ tokens: this.estimateTokens(prompt + JSON.stringify(subagentResult))
58
+ };
59
+ } catch (error) {
60
+ logger.error(`Subagent execution failed: ${request.type}`, { error, subagentId });
61
+ return {
62
+ success: false,
63
+ result: null,
64
+ error: error.message,
65
+ duration: Date.now() - startTime,
66
+ subagentType: request.type
67
+ };
68
+ }
69
+ }
70
+ /**
71
+ * Execute multiple subagents in parallel
72
+ */
73
+ async executeParallel(requests) {
74
+ logger.info(`Executing ${requests.length} subagents in parallel`);
75
+ const promises = requests.map((request) => this.executeSubagent(request));
76
+ const results = await Promise.allSettled(promises);
77
+ return results.map((result, index) => {
78
+ if (result.status === "fulfilled") {
79
+ return result.value;
80
+ } else {
81
+ return {
82
+ success: false,
83
+ result: null,
84
+ error: result.reason?.message || "Unknown error",
85
+ duration: 0,
86
+ subagentType: requests[index].type
87
+ };
88
+ }
89
+ });
90
+ }
91
+ /**
92
+ * Build subagent prompt based on type
93
+ */
94
+ buildSubagentPrompt(request) {
95
+ const prompts = {
96
+ planning: `You are a Planning Subagent. Your role is to decompose complex tasks into manageable subtasks.
97
+
98
+ Task: ${request.task}
99
+
100
+ Instructions:
101
+ 1. Analyze the task and identify all components
102
+ 2. Create a dependency graph of subtasks
103
+ 3. Assign appropriate agent types to each subtask
104
+ 4. Consider parallel execution opportunities
105
+ 5. Include comprehensive testing at each stage
106
+
107
+ Context is available in the provided file.
108
+
109
+ Output a JSON structure with the task decomposition.`,
110
+ code: `You are a Code Generation Subagent. Your role is to implement high-quality, production-ready code.
111
+
112
+ Task: ${request.task}
113
+
114
+ Instructions:
115
+ 1. Write clean, maintainable code
116
+ 2. Follow project conventions (check context)
117
+ 3. Include comprehensive error handling
118
+ 4. Add clear comments for complex logic
119
+ 5. Ensure code is testable
120
+
121
+ Context and requirements are in the provided file.
122
+
123
+ Output the implementation code.`,
124
+ testing: `You are a Testing Subagent specializing in comprehensive test generation.
125
+
126
+ Task: ${request.task}
127
+
128
+ Instructions:
129
+ 1. Generate unit tests for all functions/methods
130
+ 2. Create integration tests for API endpoints
131
+ 3. Add E2E tests for critical user flows
132
+ 4. Include edge cases and error scenarios
133
+ 5. Ensure high code coverage (aim for 100%)
134
+ 6. Validate that all tests pass
135
+
136
+ Context and code to test are in the provided file.
137
+
138
+ Output a complete test suite.`,
139
+ linting: `You are a Linting Subagent ensuring code quality and standards.
140
+
141
+ Task: ${request.task}
142
+
143
+ Instructions:
144
+ 1. Check for syntax errors and type issues
145
+ 2. Verify code formatting and style
146
+ 3. Identify security vulnerabilities
147
+ 4. Find performance anti-patterns
148
+ 5. Detect unused imports and dead code
149
+ 6. Provide specific fixes for each issue
150
+
151
+ Code to analyze is in the context file.
152
+
153
+ Output a JSON report with issues and fixes.`,
154
+ review: `You are a Code Review Subagent performing thorough multi-stage reviews.
155
+
156
+ Task: ${request.task}
157
+
158
+ Instructions:
159
+ 1. Evaluate architecture and design patterns
160
+ 2. Assess code quality and maintainability
161
+ 3. Check performance implications
162
+ 4. Review security considerations
163
+ 5. Verify test coverage adequacy
164
+ 6. Suggest specific improvements with examples
165
+ 7. Rate quality on a 0-1 scale
166
+
167
+ Code and context are in the provided file.
168
+
169
+ Output a detailed review with quality score and improvements.`,
170
+ improve: `You are an Improvement Subagent enhancing code based on reviews.
171
+
172
+ Task: ${request.task}
173
+
174
+ Instructions:
175
+ 1. Implement all suggested improvements
176
+ 2. Refactor for better architecture
177
+ 3. Optimize performance bottlenecks
178
+ 4. Enhance error handling
179
+ 5. Improve code clarity and documentation
180
+ 6. Add missing test cases
181
+ 7. Ensure backward compatibility
182
+
183
+ Review feedback and code are in the context file.
184
+
185
+ Output the improved code.`,
186
+ context: `You are a Context Retrieval Subagent finding relevant information.
187
+
188
+ Task: ${request.task}
189
+
190
+ Instructions:
191
+ 1. Search project codebase for relevant code
192
+ 2. Find similar implementations
193
+ 3. Locate relevant documentation
194
+ 4. Identify dependencies and patterns
195
+ 5. Retrieve best practices
196
+
197
+ Search parameters are in the context file.
198
+
199
+ Output relevant context snippets.`,
200
+ publish: `You are a Publishing Subagent handling releases and deployments.
201
+
202
+ Task: ${request.task}
203
+
204
+ Instructions:
205
+ 1. Prepare package for publishing
206
+ 2. Update version numbers
207
+ 3. Generate changelog
208
+ 4. Create GitHub release
209
+ 5. Publish to NPM if applicable
210
+ 6. Update documentation
211
+
212
+ Release details are in the context file.
213
+
214
+ Output the release plan and commands.`
215
+ };
216
+ return request.systemPrompt || prompts[request.type] || prompts.planning;
217
+ }
218
+ /**
219
+ * Build Task tool command
220
+ * This creates a command that Claude Code's Task tool can execute
221
+ */
222
+ buildTaskCommand(request, prompt, contextFile, resultFile) {
223
+ const scriptContent = `
224
+ #!/bin/bash
225
+ # Subagent execution script for ${request.type}
226
+
227
+ # Read context
228
+ CONTEXT=$(cat "${contextFile}")
229
+
230
+ # Execute task based on type
231
+ case "${request.type}" in
232
+ "testing")
233
+ # For testing subagent, actually run tests
234
+ echo "Generating and running tests..."
235
+ # The subagent will generate test files and run them
236
+ ;;
237
+ "linting")
238
+ # For linting subagent, run actual linters
239
+ echo "Running linters..."
240
+ npm run lint || true
241
+ ;;
242
+ "code")
243
+ # For code generation, create implementation files
244
+ echo "Generating implementation..."
245
+ ;;
246
+ *)
247
+ # Default behavior
248
+ echo "Executing ${request.type} task..."
249
+ ;;
250
+ esac
251
+
252
+ # Write result
253
+ echo '{"status": "completed", "type": "${request.type}"}' > "${resultFile}"
254
+ `;
255
+ const scriptFile = path.join(this.tempDir, `${request.type}-script.sh`);
256
+ fs.writeFileSync(scriptFile, scriptContent);
257
+ fs.chmodSync(scriptFile, "755");
258
+ return scriptFile;
259
+ }
260
+ /**
261
+ * Execute via Task tool (simulated for now)
262
+ * In production, this would use Claude Code's actual Task tool API
263
+ */
264
+ async executeTaskTool(command, timeout) {
265
+ try {
266
+ const result = await execAsync(command, {
267
+ timeout: timeout || 3e5,
268
+ // 5 minutes default
269
+ maxBuffer: 10 * 1024 * 1024
270
+ // 10MB buffer
271
+ });
272
+ return result;
273
+ } catch (error) {
274
+ if (error.killed || error.signal === "SIGTERM") {
275
+ throw new Error(`Subagent timeout after ${timeout}ms`);
276
+ }
277
+ throw error;
278
+ }
279
+ }
280
+ /**
281
+ * Estimate token usage
282
+ */
283
+ estimateTokens(text) {
284
+ return Math.ceil(text.length / 4);
285
+ }
286
+ /**
287
+ * Cleanup temporary files
288
+ */
289
+ cleanup(subagentId) {
290
+ const patterns = [
291
+ `${subagentId}-context.json`,
292
+ `${subagentId}-result.json`,
293
+ `${subagentId}-script.sh`
294
+ ];
295
+ for (const pattern of patterns) {
296
+ const filePath = path.join(this.tempDir, pattern);
297
+ if (fs.existsSync(filePath)) {
298
+ try {
299
+ fs.unlinkSync(filePath);
300
+ } catch (e) {
301
+ }
302
+ }
303
+ }
304
+ }
305
+ /**
306
+ * Create a mock Task tool response for development
307
+ * This simulates what Claude Code's Task tool would return
308
+ */
309
+ async mockTaskToolExecution(request) {
310
+ const startTime = Date.now();
311
+ await new Promise((resolve) => setTimeout(resolve, 1e3 + Math.random() * 2e3));
312
+ const mockResponses = {
313
+ planning: {
314
+ tasks: [
315
+ { id: "1", type: "analyze", description: "Analyze requirements" },
316
+ { id: "2", type: "implement", description: "Implement solution" },
317
+ { id: "3", type: "test", description: "Test implementation" },
318
+ { id: "4", type: "review", description: "Review and improve" }
319
+ ],
320
+ dependencies: { "2": ["1"], "3": ["2"], "4": ["3"] }
321
+ },
322
+ code: {
323
+ implementation: `
324
+ export class Solution {
325
+ constructor(private config: any) {}
326
+
327
+ async execute(input: string): Promise<string> {
328
+ // Implementation generated by Code subagent
329
+ return this.process(input);
330
+ }
331
+
332
+ private process(input: string): string {
333
+ return \`Processed: \${input}\`;
334
+ }
335
+ }`,
336
+ files: ["src/solution.ts"]
337
+ },
338
+ testing: {
339
+ tests: `
340
+ describe('Solution', () => {
341
+ it('should process input correctly', () => {
342
+ const solution = new Solution({});
343
+ const result = solution.execute('test');
344
+ expect(result).toBe('Processed: test');
345
+ });
346
+
347
+ it('should handle edge cases', () => {
348
+ // Edge case tests
349
+ });
350
+ });`,
351
+ coverage: { lines: 95, branches: 88, functions: 100 }
352
+ },
353
+ review: {
354
+ quality: 0.82,
355
+ issues: [
356
+ { severity: "high", message: "Missing error handling" },
357
+ { severity: "medium", message: "Could improve type safety" }
358
+ ],
359
+ suggestions: [
360
+ "Add try-catch blocks",
361
+ "Use stricter TypeScript types",
362
+ "Add input validation"
363
+ ]
364
+ }
365
+ };
366
+ return {
367
+ success: true,
368
+ result: mockResponses[request.type] || { status: "completed" },
369
+ output: `Mock ${request.type} subagent completed successfully`,
370
+ duration: Date.now() - startTime,
371
+ subagentType: request.type,
372
+ tokens: Math.floor(Math.random() * 5e3) + 1e3
373
+ };
374
+ }
375
+ /**
376
+ * Get active subagent statistics
377
+ */
378
+ getStats() {
379
+ return {
380
+ activeSubagents: this.activeSubagents.size,
381
+ tempDir: this.tempDir
382
+ };
383
+ }
384
+ /**
385
+ * Cleanup all resources
386
+ */
387
+ async cleanupAll() {
388
+ for (const [id, controller] of this.activeSubagents) {
389
+ controller.abort();
390
+ }
391
+ this.activeSubagents.clear();
392
+ if (fs.existsSync(this.tempDir)) {
393
+ const files = await fs.promises.readdir(this.tempDir);
394
+ for (const file of files) {
395
+ await fs.promises.unlink(path.join(this.tempDir, file));
396
+ }
397
+ }
398
+ logger.info("Claude Code Subagent Client cleaned up");
399
+ }
400
+ }
401
+ export {
402
+ ClaudeCodeSubagentClient
403
+ };
404
+ //# sourceMappingURL=subagent-client.js.map