@stackmemoryai/stackmemory 1.10.5 → 1.14.0

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 (225) hide show
  1. package/LICENSE +131 -64
  2. package/README.md +107 -24
  3. package/bin/claude-sm +16 -1
  4. package/bin/claude-smd +16 -1
  5. package/bin/codex-smd +16 -1
  6. package/bin/gemini-sm +16 -1
  7. package/bin/hermes-sm +21 -0
  8. package/bin/hermes-smd +21 -0
  9. package/bin/opencode-sm +16 -1
  10. package/dist/src/cli/claude-sm.js +266 -84
  11. package/dist/src/cli/codex-sm.js +225 -33
  12. package/dist/src/cli/commands/bench.js +209 -2
  13. package/dist/src/cli/commands/brain.js +206 -0
  14. package/dist/src/cli/commands/cache.js +126 -0
  15. package/dist/src/cli/commands/company-os.js +184 -0
  16. package/dist/src/cli/commands/context.js +5 -0
  17. package/dist/src/cli/commands/daemon.js +41 -0
  18. package/dist/src/cli/commands/handoff.js +40 -9
  19. package/dist/src/cli/commands/onboard.js +70 -3
  20. package/dist/src/cli/commands/operator.js +127 -0
  21. package/dist/src/cli/commands/optimize.js +117 -0
  22. package/dist/src/cli/commands/orchestrate.js +232 -5
  23. package/dist/src/cli/commands/orchestrator.js +315 -26
  24. package/dist/src/cli/commands/pack.js +322 -0
  25. package/dist/src/cli/commands/patterns.js +254 -0
  26. package/dist/src/cli/commands/portal.js +161 -0
  27. package/dist/src/cli/commands/scaffold.js +92 -0
  28. package/dist/src/cli/commands/search.js +40 -1
  29. package/dist/src/cli/commands/setup.js +178 -11
  30. package/dist/src/cli/commands/skills.js +10 -1
  31. package/dist/src/cli/commands/state.js +265 -0
  32. package/dist/src/cli/commands/sync.js +253 -0
  33. package/dist/src/cli/commands/tasks.js +130 -1
  34. package/dist/src/cli/commands/vision.js +221 -0
  35. package/dist/src/cli/gemini-sm.js +19 -29
  36. package/dist/src/cli/hermes-sm.js +224 -0
  37. package/dist/src/cli/index.js +105 -39
  38. package/dist/src/cli/opencode-sm.js +38 -21
  39. package/dist/src/cli/utils/determinism-watcher.js +66 -0
  40. package/dist/src/cli/utils/real-cli-bin.js +116 -0
  41. package/dist/src/core/brain/brain-store.js +187 -0
  42. package/dist/src/core/brain/brain-sync.js +193 -0
  43. package/dist/src/core/brain/index.js +78 -0
  44. package/dist/src/core/brain/types.js +10 -0
  45. package/dist/src/core/cache/content-cache.js +238 -0
  46. package/dist/src/{integrations/diffmem → core/cache}/index.js +5 -5
  47. package/dist/src/core/cache/token-estimator.js +39 -0
  48. package/dist/src/core/config/feature-flags.js +2 -6
  49. package/dist/src/core/context/frame-database.js +79 -27
  50. package/dist/src/core/context/recursive-context-manager.js +1 -1
  51. package/dist/src/core/context/rehydration.js +2 -1
  52. package/dist/src/core/cross-search/cross-project-search.js +269 -0
  53. package/dist/src/core/cross-search/index.js +10 -0
  54. package/dist/src/core/database/sqlite-adapter.js +14 -84
  55. package/dist/src/core/extensions/provider-adapter.js +5 -0
  56. package/dist/src/core/models/model-router.js +54 -2
  57. package/dist/src/core/models/provider-pricing.js +58 -4
  58. package/dist/src/core/monitoring/logger.js +2 -1
  59. package/dist/src/core/optimization/trace-optimizer.js +413 -0
  60. package/dist/src/core/patterns/index.js +22 -0
  61. package/dist/src/core/patterns/pattern-applier.js +39 -0
  62. package/dist/src/core/patterns/pattern-observer.js +157 -0
  63. package/dist/src/core/patterns/pattern-store.js +259 -0
  64. package/dist/src/core/patterns/types.js +19 -0
  65. package/dist/src/core/provenance/confidence-scorer.js +128 -0
  66. package/dist/src/core/provenance/index.js +40 -0
  67. package/dist/src/core/provenance/provenance-store.js +194 -0
  68. package/dist/src/core/provenance/types.js +82 -0
  69. package/dist/src/core/retrieval/llm-context-retrieval.js +5 -4
  70. package/dist/src/core/retrieval/unified-context-assembler.js +11 -66
  71. package/dist/src/core/session/project-handoff.js +64 -0
  72. package/dist/src/core/session/session-manager.js +28 -0
  73. package/dist/src/core/shared-state/canonical-store.js +564 -0
  74. package/dist/src/core/skill-packs/index.js +18 -0
  75. package/dist/src/core/skill-packs/parser.js +42 -0
  76. package/dist/src/core/skill-packs/registry.js +224 -0
  77. package/dist/src/core/skill-packs/types.js +79 -0
  78. package/dist/src/core/storage/cloud-sync-manager.js +116 -0
  79. package/dist/src/core/storage/cloud-sync.js +574 -0
  80. package/dist/src/core/storage/two-tier-storage.js +5 -1
  81. package/dist/src/core/tasks/master-tasks-template.js +43 -0
  82. package/dist/src/core/tasks/md-task-parser.js +138 -0
  83. package/dist/src/core/trace/trace-event-store.js +282 -0
  84. package/dist/src/core/vision/index.js +27 -0
  85. package/dist/src/core/vision/signals.js +79 -0
  86. package/dist/src/core/vision/types.js +22 -0
  87. package/dist/src/core/vision/vision-file.js +146 -0
  88. package/dist/src/core/vision/vision-loop.js +220 -0
  89. package/dist/src/core/wiki/wiki-compiler.js +103 -1
  90. package/dist/src/daemon/daemon-config.js +52 -0
  91. package/dist/src/daemon/services/desire-path-service.js +566 -0
  92. package/dist/src/daemon/services/github-service.js +126 -0
  93. package/dist/src/daemon/services/research-stream-service.js +320 -0
  94. package/dist/src/daemon/services/telemetry-service.js +192 -0
  95. package/dist/src/daemon/unified-daemon.js +58 -1
  96. package/dist/src/features/browser/cli-browser-agent.js +417 -0
  97. package/dist/src/features/browser/stagehand-workflows.js +578 -0
  98. package/dist/src/features/operator/adapter-factory.js +62 -0
  99. package/dist/src/features/operator/browser-adapter.js +109 -0
  100. package/dist/src/features/operator/desktop-adapter.js +125 -0
  101. package/dist/src/features/operator/index.js +39 -0
  102. package/dist/src/features/operator/llm-decision.js +137 -0
  103. package/dist/src/features/operator/operator-logger.js +92 -0
  104. package/dist/src/features/operator/overnight-runner.js +327 -0
  105. package/dist/src/features/operator/screen-adapter.js +91 -0
  106. package/dist/src/features/operator/session-manager.js +127 -0
  107. package/dist/src/features/operator/state-machine.js +227 -0
  108. package/dist/src/features/operator/task-queue.js +81 -0
  109. package/dist/src/features/portal/index.js +26 -0
  110. package/dist/src/features/portal/server.js +240 -0
  111. package/dist/src/features/portal/types.js +14 -0
  112. package/dist/src/features/portal/ui.js +195 -0
  113. package/dist/src/features/sweep/pty-wrapper.js +13 -5
  114. package/dist/src/features/tasks/task-aware-context.js +2 -1
  115. package/dist/src/features/tui/simple-monitor.js +0 -23
  116. package/dist/src/features/tui/swarm-monitor.js +8 -66
  117. package/dist/src/features/web/client/hooks/use-socket.js +12 -0
  118. package/dist/src/{core/merge/index.js → features/web/client/lib/utils.js} +8 -4
  119. package/dist/src/features/web/client/next-env.d.js +4 -0
  120. package/dist/src/features/web/client/stores/session-store.js +12 -0
  121. package/dist/src/features/web/server/gcp-billing.js +76 -0
  122. package/dist/src/features/web/server/index.js +10 -0
  123. package/dist/src/features/web/server/spend-calculator.js +228 -0
  124. package/dist/src/hooks/schemas.js +6 -1
  125. package/dist/src/integrations/anthropic/client.js +3 -2
  126. package/dist/src/integrations/claude-code/agent-bridge.js +0 -3
  127. package/dist/src/integrations/claude-code/subagent-client.js +307 -11
  128. package/dist/src/integrations/claude-code/task-coordinator.js +2 -1
  129. package/dist/src/integrations/github/pr-state.js +158 -0
  130. package/dist/src/integrations/linear/client.js +4 -1
  131. package/dist/src/integrations/linear/webhook-retry.js +196 -0
  132. package/dist/src/integrations/linear/webhook-server.js +18 -22
  133. package/dist/src/integrations/mcp/handlers/cloud-sync-handlers.js +101 -0
  134. package/dist/src/integrations/mcp/handlers/index.js +40 -84
  135. package/dist/src/integrations/mcp/server.js +542 -641
  136. package/dist/src/integrations/mcp/tool-alias-registry.js +297 -0
  137. package/dist/src/integrations/mcp/tool-definitions.js +152 -682
  138. package/dist/src/mcp/stackmemory-mcp-server.js +571 -231
  139. package/dist/src/orchestrators/multimodal/determinism.js +244 -0
  140. package/dist/src/orchestrators/multimodal/harness.js +149 -78
  141. package/dist/src/orchestrators/multimodal/providers.js +44 -3
  142. package/dist/src/skills/recursive-agent-orchestrator.js +2 -4
  143. package/dist/src/utils/hook-installer.js +0 -8
  144. package/dist/src/utils/process-cleanup.js +1 -7
  145. package/docs/README.md +42 -0
  146. package/docs/guides/README_INSTALL.md +208 -0
  147. package/package.json +27 -9
  148. package/packs/coding/python-fastapi/instructions.md +60 -0
  149. package/packs/coding/python-fastapi/pack.yaml +28 -0
  150. package/packs/coding/typescript-react/instructions.md +47 -0
  151. package/packs/coding/typescript-react/pack.yaml +28 -0
  152. package/packs/core/commands/capture.md +32 -0
  153. package/packs/core/commands/learn.md +73 -0
  154. package/packs/core/commands/next.md +36 -0
  155. package/packs/core/commands/restart.md +58 -0
  156. package/packs/core/commands/restore.md +29 -0
  157. package/packs/core/commands/start.md +57 -0
  158. package/packs/core/commands/stop.md +65 -0
  159. package/packs/core/commands/summary.md +40 -0
  160. package/packs/core/manifest.json +24 -0
  161. package/packs/ops/decision-recovery/instructions.md +65 -0
  162. package/packs/ops/decision-recovery/pack.yaml +89 -0
  163. package/scripts/claude-code-wrapper.sh +11 -0
  164. package/scripts/claude-sm-setup.sh +12 -1
  165. package/scripts/codex-wrapper.sh +11 -0
  166. package/scripts/git-hooks/branch-context-manager.sh +11 -0
  167. package/scripts/git-hooks/post-checkout-stackmemory.sh +11 -0
  168. package/scripts/git-hooks/post-commit-stackmemory.sh +11 -0
  169. package/scripts/git-hooks/pre-commit-stackmemory.sh +11 -0
  170. package/scripts/hooks/cleanup-shell.sh +12 -1
  171. package/scripts/hooks/task-complete.sh +12 -1
  172. package/scripts/install-code-execution-hooks.sh +12 -1
  173. package/scripts/install-sweep-hook.sh +12 -0
  174. package/scripts/install.sh +11 -0
  175. package/scripts/opencode-wrapper.sh +11 -0
  176. package/scripts/portal/cloud-init.yaml +69 -0
  177. package/scripts/portal/setup.sh +69 -0
  178. package/scripts/portal/stackmemory-portal.service +34 -0
  179. package/scripts/setup-claude-integration.sh +12 -1
  180. package/scripts/smoke-init-db.sh +23 -0
  181. package/scripts/stackmemory-daemon.sh +11 -0
  182. package/scripts/verify-dist.cjs +11 -4
  183. package/dist/src/cli/commands/ralph.js +0 -1053
  184. package/dist/src/cli/commands/team.js +0 -168
  185. package/dist/src/core/context/shared-context-layer.js +0 -620
  186. package/dist/src/core/context/stack-merge-resolver.js +0 -748
  187. package/dist/src/core/merge/conflict-detector.js +0 -430
  188. package/dist/src/core/merge/resolution-engine.js +0 -557
  189. package/dist/src/core/merge/stack-diff.js +0 -531
  190. package/dist/src/core/merge/unified-merge-resolver.js +0 -302
  191. package/dist/src/hooks/diffmem-hooks.js +0 -376
  192. package/dist/src/integrations/diffmem/client.js +0 -208
  193. package/dist/src/integrations/diffmem/config.js +0 -14
  194. package/dist/src/integrations/greptile/client.js +0 -101
  195. package/dist/src/integrations/greptile/config.js +0 -14
  196. package/dist/src/integrations/greptile/index.js +0 -11
  197. package/dist/src/integrations/mcp/handlers/cord-handlers.js +0 -397
  198. package/dist/src/integrations/mcp/handlers/diffmem-handlers.js +0 -455
  199. package/dist/src/integrations/mcp/handlers/greptile-handlers.js +0 -456
  200. package/dist/src/integrations/mcp/handlers/provider-handlers.js +0 -227
  201. package/dist/src/integrations/mcp/handlers/team-handlers.js +0 -211
  202. package/dist/src/integrations/ralph/bridge/ralph-stackmemory-bridge.js +0 -863
  203. package/dist/src/integrations/ralph/context/context-budget-manager.js +0 -308
  204. package/dist/src/integrations/ralph/context/stackmemory-context-loader.js +0 -391
  205. package/dist/src/integrations/ralph/index.js +0 -17
  206. package/dist/src/integrations/ralph/learning/pattern-learner.js +0 -435
  207. package/dist/src/integrations/ralph/lifecycle/iteration-lifecycle.js +0 -448
  208. package/dist/src/integrations/ralph/loopmax.js +0 -488
  209. package/dist/src/integrations/ralph/monitoring/swarm-dashboard.js +0 -293
  210. package/dist/src/integrations/ralph/monitoring/swarm-registry.js +0 -107
  211. package/dist/src/integrations/ralph/orchestration/multi-loop-orchestrator.js +0 -508
  212. package/dist/src/integrations/ralph/patterns/compounding-engineering-pattern.js +0 -407
  213. package/dist/src/integrations/ralph/patterns/extended-coherence-sessions.js +0 -495
  214. package/dist/src/integrations/ralph/patterns/oracle-worker-pattern.js +0 -387
  215. package/dist/src/integrations/ralph/performance/performance-optimizer.js +0 -357
  216. package/dist/src/integrations/ralph/recovery/crash-recovery.js +0 -461
  217. package/dist/src/integrations/ralph/state/state-reconciler.js +0 -420
  218. package/dist/src/integrations/ralph/swarm/git-workflow-manager.js +0 -444
  219. package/dist/src/integrations/ralph/swarm/swarm-coordinator.js +0 -1007
  220. package/dist/src/integrations/ralph/visualization/ralph-debugger.js +0 -635
  221. package/scripts/ralph-loop-implementation.js +0 -404
  222. /package/dist/src/core/{merge → cache}/types.js +0 -0
  223. /package/dist/src/{integrations/diffmem/types.js → core/storage/cloud-sync-types.js} +0 -0
  224. /package/dist/src/{integrations/greptile/types.js → core/trace/trace-event.js} +0 -0
  225. /package/dist/src/{integrations/ralph → features/operator}/types.js +0 -0
@@ -1,456 +0,0 @@
1
- import { fileURLToPath as __fileURLToPath } from 'url';
2
- import { dirname as __pathDirname } from 'path';
3
- const __filename = __fileURLToPath(import.meta.url);
4
- const __dirname = __pathDirname(__filename);
5
- import { DEFAULT_GREPTILE_CONFIG } from "../../greptile/config.js";
6
- import { GreptileClient, GreptileClientError } from "../../greptile/client.js";
7
- import { logger } from "../../../core/monitoring/logger.js";
8
- class GreptileHandlers {
9
- config;
10
- client = null;
11
- constructor(deps) {
12
- this.config = { ...DEFAULT_GREPTILE_CONFIG, ...deps?.config };
13
- if (this.config.enabled && this.config.apiKey) {
14
- try {
15
- this.client = new GreptileClient(this.config);
16
- } catch {
17
- this.client = null;
18
- }
19
- }
20
- }
21
- getToolDefinitions() {
22
- return [
23
- {
24
- name: "greptile_pr_comments",
25
- description: "Get PR review comments from Greptile. Returns unaddressed comments with suggestedCode for auto-fix workflows.",
26
- inputSchema: {
27
- type: "object",
28
- properties: {
29
- name: {
30
- type: "string",
31
- description: 'Repository full name (e.g., "owner/repo")'
32
- },
33
- remote: {
34
- type: "string",
35
- enum: ["github", "gitlab", "azure", "bitbucket"],
36
- description: "Remote provider"
37
- },
38
- defaultBranch: {
39
- type: "string",
40
- description: 'Default branch (e.g., "main")'
41
- },
42
- prNumber: {
43
- type: "number",
44
- description: "Pull request number"
45
- },
46
- greptileGenerated: {
47
- type: "boolean",
48
- description: "Filter for only Greptile review comments"
49
- },
50
- addressed: {
51
- type: "boolean",
52
- description: "Filter by comment addressed status"
53
- }
54
- },
55
- required: ["name", "remote", "defaultBranch", "prNumber"]
56
- }
57
- },
58
- {
59
- name: "greptile_pr_details",
60
- description: "Get detailed PR information including metadata, statistics, and review analysis from Greptile.",
61
- inputSchema: {
62
- type: "object",
63
- properties: {
64
- name: {
65
- type: "string",
66
- description: 'Repository full name (e.g., "owner/repo")'
67
- },
68
- remote: {
69
- type: "string",
70
- enum: ["github", "gitlab", "azure", "bitbucket"],
71
- description: "Remote provider"
72
- },
73
- defaultBranch: {
74
- type: "string",
75
- description: "Default branch"
76
- },
77
- prNumber: {
78
- type: "number",
79
- description: "Pull request number"
80
- }
81
- },
82
- required: ["name", "remote", "defaultBranch", "prNumber"]
83
- }
84
- },
85
- {
86
- name: "greptile_list_prs",
87
- description: "List pull requests. Filter by repository, branch, author, or state.",
88
- inputSchema: {
89
- type: "object",
90
- properties: {
91
- name: {
92
- type: "string",
93
- description: 'Repository full name (e.g., "owner/repo")'
94
- },
95
- remote: {
96
- type: "string",
97
- enum: ["github", "gitlab", "azure", "bitbucket"],
98
- description: "Remote provider"
99
- },
100
- defaultBranch: {
101
- type: "string",
102
- description: "Default branch"
103
- },
104
- sourceBranch: {
105
- type: "string",
106
- description: "Filter by source branch name"
107
- },
108
- authorLogin: {
109
- type: "string",
110
- description: "Filter by PR author username"
111
- },
112
- state: {
113
- type: "string",
114
- enum: ["open", "closed", "merged"],
115
- description: "Filter by PR state"
116
- },
117
- limit: {
118
- type: "number",
119
- description: "Max results (default 20)"
120
- }
121
- }
122
- }
123
- },
124
- {
125
- name: "greptile_trigger_review",
126
- description: "Trigger a Greptile code review for a pull request.",
127
- inputSchema: {
128
- type: "object",
129
- properties: {
130
- name: {
131
- type: "string",
132
- description: 'Repository full name (e.g., "owner/repo")'
133
- },
134
- remote: {
135
- type: "string",
136
- enum: ["github", "gitlab", "azure", "bitbucket"],
137
- description: "Remote provider"
138
- },
139
- defaultBranch: {
140
- type: "string",
141
- description: "Default branch"
142
- },
143
- prNumber: {
144
- type: "number",
145
- description: "Pull request number"
146
- },
147
- branch: {
148
- type: "string",
149
- description: "Current working branch"
150
- }
151
- },
152
- required: ["name", "remote", "prNumber"]
153
- }
154
- },
155
- {
156
- name: "greptile_search_patterns",
157
- description: "Search custom coding patterns and instructions in Greptile.",
158
- inputSchema: {
159
- type: "object",
160
- properties: {
161
- query: {
162
- type: "string",
163
- description: "Search query for pattern content"
164
- },
165
- limit: {
166
- type: "number",
167
- description: "Max results (default 10)"
168
- }
169
- },
170
- required: ["query"]
171
- }
172
- },
173
- {
174
- name: "greptile_create_pattern",
175
- description: "Create a new custom coding pattern or instruction in Greptile.",
176
- inputSchema: {
177
- type: "object",
178
- properties: {
179
- body: {
180
- type: "string",
181
- description: "Pattern content"
182
- },
183
- type: {
184
- type: "string",
185
- enum: ["CUSTOM_INSTRUCTION", "PATTERN"],
186
- description: "Context type (default: CUSTOM_INSTRUCTION)"
187
- },
188
- scopes: {
189
- type: "object",
190
- description: "Boolean expression defining where this pattern applies"
191
- }
192
- },
193
- required: ["body"]
194
- }
195
- },
196
- {
197
- name: "greptile_status",
198
- description: "Check Greptile integration connection status.",
199
- inputSchema: {
200
- type: "object",
201
- properties: {}
202
- }
203
- }
204
- ];
205
- }
206
- async handleListPRComments(args) {
207
- if (!this.client) return this.disabledResponse();
208
- try {
209
- const toolArgs = {
210
- name: args.name,
211
- remote: args.remote,
212
- defaultBranch: args.defaultBranch,
213
- prNumber: args.prNumber
214
- };
215
- if (args.greptileGenerated !== void 0)
216
- toolArgs.greptileGenerated = args.greptileGenerated;
217
- if (args.addressed !== void 0) toolArgs.addressed = args.addressed;
218
- const result = await this.client.callTool(
219
- "list_merge_request_comments",
220
- toolArgs
221
- );
222
- let actionableCount = 0;
223
- if (Array.isArray(result)) {
224
- actionableCount = result.filter(
225
- (c) => !c.addressed && (c.suggestedCode || typeof c.body === "string" && c.body.includes("```suggestion"))
226
- ).length;
227
- }
228
- return {
229
- content: [
230
- {
231
- type: "text",
232
- text: typeof result === "string" ? result : JSON.stringify(result, null, 2)
233
- }
234
- ],
235
- metadata: { actionableCount, tool: "list_merge_request_comments" }
236
- };
237
- } catch (error) {
238
- return this.handleError("listPRComments", error);
239
- }
240
- }
241
- async handleGetMergeRequest(args) {
242
- if (!this.client) return this.disabledResponse();
243
- try {
244
- const result = await this.client.callTool("get_merge_request", {
245
- name: args.name,
246
- remote: args.remote,
247
- defaultBranch: args.defaultBranch,
248
- prNumber: args.prNumber
249
- });
250
- return {
251
- content: [
252
- {
253
- type: "text",
254
- text: typeof result === "string" ? result : JSON.stringify(result, null, 2)
255
- }
256
- ],
257
- metadata: { tool: "get_merge_request" }
258
- };
259
- } catch (error) {
260
- return this.handleError("getMergeRequest", error);
261
- }
262
- }
263
- async handleListPullRequests(args) {
264
- if (!this.client) return this.disabledResponse();
265
- try {
266
- const toolArgs = {};
267
- if (args.name) toolArgs.name = args.name;
268
- if (args.remote) toolArgs.remote = args.remote;
269
- if (args.defaultBranch) toolArgs.defaultBranch = args.defaultBranch;
270
- if (args.sourceBranch) toolArgs.sourceBranch = args.sourceBranch;
271
- if (args.authorLogin) toolArgs.authorLogin = args.authorLogin;
272
- if (args.state) toolArgs.state = args.state;
273
- if (args.limit) toolArgs.limit = args.limit;
274
- const result = await this.client.callTool("list_pull_requests", toolArgs);
275
- return {
276
- content: [
277
- {
278
- type: "text",
279
- text: typeof result === "string" ? result : JSON.stringify(result, null, 2)
280
- }
281
- ],
282
- metadata: { tool: "list_pull_requests" }
283
- };
284
- } catch (error) {
285
- return this.handleError("listPullRequests", error);
286
- }
287
- }
288
- async handleTriggerCodeReview(args) {
289
- if (!this.client) return this.disabledResponse();
290
- try {
291
- const toolArgs = {
292
- name: args.name,
293
- remote: args.remote,
294
- prNumber: args.prNumber
295
- };
296
- if (args.defaultBranch) toolArgs.defaultBranch = args.defaultBranch;
297
- if (args.branch) toolArgs.branch = args.branch;
298
- const result = await this.client.callTool(
299
- "trigger_code_review",
300
- toolArgs
301
- );
302
- return {
303
- content: [
304
- {
305
- type: "text",
306
- text: typeof result === "string" ? result : JSON.stringify(result, null, 2)
307
- }
308
- ],
309
- metadata: { tool: "trigger_code_review" }
310
- };
311
- } catch (error) {
312
- return this.handleError("triggerCodeReview", error);
313
- }
314
- }
315
- async handleSearchPatterns(args) {
316
- if (!this.client) return this.disabledResponse();
317
- try {
318
- const toolArgs = { query: args.query };
319
- if (args.limit) toolArgs.limit = args.limit;
320
- const result = await this.client.callTool(
321
- "search_custom_context",
322
- toolArgs
323
- );
324
- return {
325
- content: [
326
- {
327
- type: "text",
328
- text: typeof result === "string" ? result : JSON.stringify(result, null, 2)
329
- }
330
- ],
331
- metadata: { tool: "search_custom_context" }
332
- };
333
- } catch (error) {
334
- return this.handleError("searchPatterns", error);
335
- }
336
- }
337
- async handleCreatePattern(args) {
338
- if (!this.client) return this.disabledResponse();
339
- try {
340
- const toolArgs = { body: args.body };
341
- if (args.type) toolArgs.type = args.type;
342
- if (args.scopes) toolArgs.scopes = args.scopes;
343
- const result = await this.client.callTool(
344
- "create_custom_context",
345
- toolArgs
346
- );
347
- return {
348
- content: [
349
- {
350
- type: "text",
351
- text: typeof result === "string" ? result : JSON.stringify(result, null, 2)
352
- }
353
- ],
354
- metadata: { tool: "create_custom_context" }
355
- };
356
- } catch (error) {
357
- return this.handleError("createPattern", error);
358
- }
359
- }
360
- async handleStatus() {
361
- if (!this.client) {
362
- return {
363
- content: [
364
- {
365
- type: "text",
366
- text: JSON.stringify(
367
- {
368
- connected: false,
369
- message: "Greptile integration disabled (GREPTILE_API_KEY not set)"
370
- },
371
- null,
372
- 2
373
- )
374
- }
375
- ],
376
- metadata: { connected: false }
377
- };
378
- }
379
- try {
380
- await this.client.callTool("list_pull_requests", { limit: 1 });
381
- return {
382
- content: [
383
- {
384
- type: "text",
385
- text: JSON.stringify(
386
- {
387
- connected: true,
388
- endpoint: this.config.mcpEndpoint
389
- },
390
- null,
391
- 2
392
- )
393
- }
394
- ],
395
- metadata: { connected: true }
396
- };
397
- } catch (error) {
398
- const msg = error instanceof Error ? error.message : String(error);
399
- return {
400
- content: [
401
- {
402
- type: "text",
403
- text: JSON.stringify(
404
- {
405
- connected: false,
406
- error: msg,
407
- endpoint: this.config.mcpEndpoint
408
- },
409
- null,
410
- 2
411
- )
412
- }
413
- ],
414
- metadata: { connected: false, error: msg }
415
- };
416
- }
417
- }
418
- disabledResponse() {
419
- return {
420
- content: [
421
- {
422
- type: "text",
423
- text: "Greptile integration disabled (GREPTILE_API_KEY not set)"
424
- }
425
- ]
426
- };
427
- }
428
- handleError(operation, error) {
429
- const msg = error instanceof Error ? error.message : String(error);
430
- const isConnectionError = msg.includes("ECONNREFUSED") || msg.includes("fetch failed") || msg.includes("network") || error instanceof GreptileClientError;
431
- logger.debug(`Greptile ${operation} failed`, { error: msg });
432
- if (isConnectionError) {
433
- return {
434
- content: [
435
- {
436
- type: "text",
437
- text: `Greptile unavailable (${operation}). The service may be temporarily unreachable.`
438
- }
439
- ],
440
- metadata: { error: true, unavailable: true, operation }
441
- };
442
- }
443
- return {
444
- content: [
445
- {
446
- type: "text",
447
- text: `Greptile ${operation} error: ${msg}`
448
- }
449
- ],
450
- metadata: { error: true, operation, message: msg }
451
- };
452
- }
453
- }
454
- export {
455
- GreptileHandlers
456
- };
@@ -1,227 +0,0 @@
1
- import { fileURLToPath as __fileURLToPath } from 'url';
2
- import { dirname as __pathDirname } from 'path';
3
- const __filename = __fileURLToPath(import.meta.url);
4
- const __dirname = __pathDirname(__filename);
5
- import { logger } from "../../../core/monitoring/logger.js";
6
- import { isFeatureEnabled } from "../../../core/config/feature-flags.js";
7
- import {
8
- createProvider
9
- } from "../../../core/extensions/provider-adapter.js";
10
- import {
11
- getOptimalProvider
12
- } from "../../../core/models/model-router.js";
13
- import { scoreComplexity } from "../../../core/models/complexity-scorer.js";
14
- import {
15
- AnthropicBatchClient
16
- } from "../../anthropic/batch-client.js";
17
- function errorResponse(err) {
18
- return {
19
- content: [{ type: "text", text: JSON.stringify(err, null, 2) }]
20
- };
21
- }
22
- function classifyApiError(error, provider) {
23
- const msg = error.message || String(error);
24
- const status = error.status || (msg.match(/(\d{3})/)?.[1] ? parseInt(msg.match(/(\d{3})/)[1]) : void 0);
25
- if (status === 429) {
26
- return {
27
- errorType: "rate_limit",
28
- message: msg,
29
- recommendation: `Rate limited by ${provider}. Retry after a delay or switch to a different provider.`,
30
- provider
31
- };
32
- }
33
- if (status && status >= 500) {
34
- return {
35
- errorType: "server_error",
36
- message: msg,
37
- recommendation: `${provider} returned a server error. Try a different provider or retry later.`,
38
- provider
39
- };
40
- }
41
- return {
42
- errorType: "api_error",
43
- message: msg,
44
- recommendation: `API call to ${provider} failed. Check the model name, API key, and base URL.`,
45
- provider
46
- };
47
- }
48
- class ProviderHandlers {
49
- batchClient;
50
- constructor(_deps) {
51
- }
52
- getBatchClient() {
53
- if (!this.batchClient) {
54
- this.batchClient = new AnthropicBatchClient();
55
- }
56
- return this.batchClient;
57
- }
58
- /**
59
- * delegate_to_model — route a prompt to a specific provider+model
60
- */
61
- async handleDelegateToModel(args) {
62
- if (!isFeatureEnabled("multiProvider")) {
63
- return errorResponse({
64
- errorType: "feature_disabled",
65
- message: "Multi-provider routing is disabled.",
66
- recommendation: "Set STACKMEMORY_MULTI_PROVIDER=true to enable multi-provider routing."
67
- });
68
- }
69
- const taskType = args.taskType || "default";
70
- const preference = args.provider;
71
- const complexity = scoreComplexity(args.prompt);
72
- const optimal = getOptimalProvider(taskType, preference, {
73
- task: args.prompt
74
- });
75
- logger.info("delegate_to_model routing", {
76
- taskType,
77
- complexity: complexity.tier,
78
- score: complexity.score,
79
- provider: optimal.provider
80
- });
81
- const providerModel = args.model || optimal.model;
82
- const apiKey = process.env[optimal.apiKeyEnv] || "";
83
- if (!apiKey) {
84
- return errorResponse({
85
- errorType: "missing_api_key",
86
- message: `No API key found for ${optimal.provider} (env: ${optimal.apiKeyEnv})`,
87
- recommendation: `Set the ${optimal.apiKeyEnv} environment variable or choose a different provider.`,
88
- provider: optimal.provider
89
- });
90
- }
91
- try {
92
- const adapter = createProvider(optimal.provider, {
93
- apiKey,
94
- baseUrl: optimal.baseUrl
95
- });
96
- const messages = [{ role: "user", content: args.prompt }];
97
- const result = await adapter.complete(messages, {
98
- model: providerModel,
99
- maxTokens: args.maxTokens || 4096,
100
- temperature: args.temperature,
101
- system: args.system
102
- });
103
- const text = result.content.filter((c) => c.type === "text").map((c) => c.text).join("");
104
- return {
105
- content: [
106
- {
107
- type: "text",
108
- text: JSON.stringify(
109
- {
110
- provider: optimal.provider,
111
- model: providerModel,
112
- response: text,
113
- usage: result.usage
114
- },
115
- null,
116
- 2
117
- )
118
- }
119
- ]
120
- };
121
- } catch (error) {
122
- logger.error("delegate_to_model failed", { error: error.message });
123
- return errorResponse(classifyApiError(error, optimal.provider));
124
- }
125
- }
126
- /**
127
- * batch_submit — submit prompts to Anthropic Batch API
128
- */
129
- async handleBatchSubmit(args) {
130
- if (!isFeatureEnabled("multiProvider")) {
131
- return errorResponse({
132
- errorType: "feature_disabled",
133
- message: "Multi-provider routing is disabled.",
134
- recommendation: "Set STACKMEMORY_MULTI_PROVIDER=true to enable multi-provider routing."
135
- });
136
- }
137
- try {
138
- const batchClient = this.getBatchClient();
139
- const requests = args.prompts.map((p) => ({
140
- custom_id: p.id,
141
- params: {
142
- model: p.model || "claude-sonnet-4-5-20250929",
143
- max_tokens: p.maxTokens || 4096,
144
- messages: [{ role: "user", content: p.prompt }],
145
- system: p.system
146
- }
147
- }));
148
- const batchId = await batchClient.submit(requests, args.description);
149
- return {
150
- content: [
151
- {
152
- type: "text",
153
- text: JSON.stringify(
154
- {
155
- batchId,
156
- status: "submitted",
157
- requestCount: requests.length
158
- },
159
- null,
160
- 2
161
- )
162
- }
163
- ]
164
- };
165
- } catch (error) {
166
- return errorResponse({
167
- errorType: "batch_error",
168
- message: error.message,
169
- recommendation: "Check ANTHROPIC_API_KEY and batch request format."
170
- });
171
- }
172
- }
173
- /**
174
- * batch_check — poll status / retrieve results
175
- */
176
- async handleBatchCheck(args) {
177
- if (!isFeatureEnabled("multiProvider")) {
178
- return errorResponse({
179
- errorType: "feature_disabled",
180
- message: "Multi-provider routing is disabled.",
181
- recommendation: "Set STACKMEMORY_MULTI_PROVIDER=true to enable multi-provider routing."
182
- });
183
- }
184
- try {
185
- const batchClient = this.getBatchClient();
186
- const job = await batchClient.poll(args.batchId);
187
- if (args.retrieve && job.processing_status === "ended") {
188
- const results = await batchClient.retrieve(args.batchId);
189
- return {
190
- content: [
191
- {
192
- type: "text",
193
- text: JSON.stringify({ job, results }, null, 2)
194
- }
195
- ]
196
- };
197
- }
198
- return {
199
- content: [
200
- {
201
- type: "text",
202
- text: JSON.stringify(
203
- {
204
- batchId: args.batchId,
205
- status: job.processing_status,
206
- counts: job.request_counts,
207
- createdAt: job.created_at,
208
- endedAt: job.ended_at
209
- },
210
- null,
211
- 2
212
- )
213
- }
214
- ]
215
- };
216
- } catch (error) {
217
- return errorResponse({
218
- errorType: "batch_error",
219
- message: error.message,
220
- recommendation: "Check the batchId is valid and ANTHROPIC_API_KEY is set."
221
- });
222
- }
223
- }
224
- }
225
- export {
226
- ProviderHandlers
227
- };