@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.
- package/LICENSE +131 -64
- package/README.md +107 -24
- package/bin/claude-sm +16 -1
- package/bin/claude-smd +16 -1
- package/bin/codex-smd +16 -1
- package/bin/gemini-sm +16 -1
- package/bin/hermes-sm +21 -0
- package/bin/hermes-smd +21 -0
- package/bin/opencode-sm +16 -1
- package/dist/src/cli/claude-sm.js +266 -84
- package/dist/src/cli/codex-sm.js +225 -33
- package/dist/src/cli/commands/bench.js +209 -2
- package/dist/src/cli/commands/brain.js +206 -0
- package/dist/src/cli/commands/cache.js +126 -0
- package/dist/src/cli/commands/company-os.js +184 -0
- package/dist/src/cli/commands/context.js +5 -0
- package/dist/src/cli/commands/daemon.js +41 -0
- package/dist/src/cli/commands/handoff.js +40 -9
- package/dist/src/cli/commands/onboard.js +70 -3
- package/dist/src/cli/commands/operator.js +127 -0
- package/dist/src/cli/commands/optimize.js +117 -0
- package/dist/src/cli/commands/orchestrate.js +232 -5
- package/dist/src/cli/commands/orchestrator.js +315 -26
- package/dist/src/cli/commands/pack.js +322 -0
- package/dist/src/cli/commands/patterns.js +254 -0
- package/dist/src/cli/commands/portal.js +161 -0
- package/dist/src/cli/commands/scaffold.js +92 -0
- package/dist/src/cli/commands/search.js +40 -1
- package/dist/src/cli/commands/setup.js +178 -11
- package/dist/src/cli/commands/skills.js +10 -1
- package/dist/src/cli/commands/state.js +265 -0
- package/dist/src/cli/commands/sync.js +253 -0
- package/dist/src/cli/commands/tasks.js +130 -1
- package/dist/src/cli/commands/vision.js +221 -0
- package/dist/src/cli/gemini-sm.js +19 -29
- package/dist/src/cli/hermes-sm.js +224 -0
- package/dist/src/cli/index.js +105 -39
- package/dist/src/cli/opencode-sm.js +38 -21
- package/dist/src/cli/utils/determinism-watcher.js +66 -0
- package/dist/src/cli/utils/real-cli-bin.js +116 -0
- package/dist/src/core/brain/brain-store.js +187 -0
- package/dist/src/core/brain/brain-sync.js +193 -0
- package/dist/src/core/brain/index.js +78 -0
- package/dist/src/core/brain/types.js +10 -0
- package/dist/src/core/cache/content-cache.js +238 -0
- package/dist/src/{integrations/diffmem → core/cache}/index.js +5 -5
- package/dist/src/core/cache/token-estimator.js +39 -0
- package/dist/src/core/config/feature-flags.js +2 -6
- package/dist/src/core/context/frame-database.js +79 -27
- package/dist/src/core/context/recursive-context-manager.js +1 -1
- package/dist/src/core/context/rehydration.js +2 -1
- package/dist/src/core/cross-search/cross-project-search.js +269 -0
- package/dist/src/core/cross-search/index.js +10 -0
- package/dist/src/core/database/sqlite-adapter.js +14 -84
- package/dist/src/core/extensions/provider-adapter.js +5 -0
- package/dist/src/core/models/model-router.js +54 -2
- package/dist/src/core/models/provider-pricing.js +58 -4
- package/dist/src/core/monitoring/logger.js +2 -1
- package/dist/src/core/optimization/trace-optimizer.js +413 -0
- package/dist/src/core/patterns/index.js +22 -0
- package/dist/src/core/patterns/pattern-applier.js +39 -0
- package/dist/src/core/patterns/pattern-observer.js +157 -0
- package/dist/src/core/patterns/pattern-store.js +259 -0
- package/dist/src/core/patterns/types.js +19 -0
- package/dist/src/core/provenance/confidence-scorer.js +128 -0
- package/dist/src/core/provenance/index.js +40 -0
- package/dist/src/core/provenance/provenance-store.js +194 -0
- package/dist/src/core/provenance/types.js +82 -0
- package/dist/src/core/retrieval/llm-context-retrieval.js +5 -4
- package/dist/src/core/retrieval/unified-context-assembler.js +11 -66
- package/dist/src/core/session/project-handoff.js +64 -0
- package/dist/src/core/session/session-manager.js +28 -0
- package/dist/src/core/shared-state/canonical-store.js +564 -0
- package/dist/src/core/skill-packs/index.js +18 -0
- package/dist/src/core/skill-packs/parser.js +42 -0
- package/dist/src/core/skill-packs/registry.js +224 -0
- package/dist/src/core/skill-packs/types.js +79 -0
- package/dist/src/core/storage/cloud-sync-manager.js +116 -0
- package/dist/src/core/storage/cloud-sync.js +574 -0
- package/dist/src/core/storage/two-tier-storage.js +5 -1
- package/dist/src/core/tasks/master-tasks-template.js +43 -0
- package/dist/src/core/tasks/md-task-parser.js +138 -0
- package/dist/src/core/trace/trace-event-store.js +282 -0
- package/dist/src/core/vision/index.js +27 -0
- package/dist/src/core/vision/signals.js +79 -0
- package/dist/src/core/vision/types.js +22 -0
- package/dist/src/core/vision/vision-file.js +146 -0
- package/dist/src/core/vision/vision-loop.js +220 -0
- package/dist/src/core/wiki/wiki-compiler.js +103 -1
- package/dist/src/daemon/daemon-config.js +52 -0
- package/dist/src/daemon/services/desire-path-service.js +566 -0
- package/dist/src/daemon/services/github-service.js +126 -0
- package/dist/src/daemon/services/research-stream-service.js +320 -0
- package/dist/src/daemon/services/telemetry-service.js +192 -0
- package/dist/src/daemon/unified-daemon.js +58 -1
- package/dist/src/features/browser/cli-browser-agent.js +417 -0
- package/dist/src/features/browser/stagehand-workflows.js +578 -0
- package/dist/src/features/operator/adapter-factory.js +62 -0
- package/dist/src/features/operator/browser-adapter.js +109 -0
- package/dist/src/features/operator/desktop-adapter.js +125 -0
- package/dist/src/features/operator/index.js +39 -0
- package/dist/src/features/operator/llm-decision.js +137 -0
- package/dist/src/features/operator/operator-logger.js +92 -0
- package/dist/src/features/operator/overnight-runner.js +327 -0
- package/dist/src/features/operator/screen-adapter.js +91 -0
- package/dist/src/features/operator/session-manager.js +127 -0
- package/dist/src/features/operator/state-machine.js +227 -0
- package/dist/src/features/operator/task-queue.js +81 -0
- package/dist/src/features/portal/index.js +26 -0
- package/dist/src/features/portal/server.js +240 -0
- package/dist/src/features/portal/types.js +14 -0
- package/dist/src/features/portal/ui.js +195 -0
- package/dist/src/features/sweep/pty-wrapper.js +13 -5
- package/dist/src/features/tasks/task-aware-context.js +2 -1
- package/dist/src/features/tui/simple-monitor.js +0 -23
- package/dist/src/features/tui/swarm-monitor.js +8 -66
- package/dist/src/features/web/client/hooks/use-socket.js +12 -0
- package/dist/src/{core/merge/index.js → features/web/client/lib/utils.js} +8 -4
- package/dist/src/features/web/client/next-env.d.js +4 -0
- package/dist/src/features/web/client/stores/session-store.js +12 -0
- package/dist/src/features/web/server/gcp-billing.js +76 -0
- package/dist/src/features/web/server/index.js +10 -0
- package/dist/src/features/web/server/spend-calculator.js +228 -0
- package/dist/src/hooks/schemas.js +6 -1
- package/dist/src/integrations/anthropic/client.js +3 -2
- package/dist/src/integrations/claude-code/agent-bridge.js +0 -3
- package/dist/src/integrations/claude-code/subagent-client.js +307 -11
- package/dist/src/integrations/claude-code/task-coordinator.js +2 -1
- package/dist/src/integrations/github/pr-state.js +158 -0
- package/dist/src/integrations/linear/client.js +4 -1
- package/dist/src/integrations/linear/webhook-retry.js +196 -0
- package/dist/src/integrations/linear/webhook-server.js +18 -22
- package/dist/src/integrations/mcp/handlers/cloud-sync-handlers.js +101 -0
- package/dist/src/integrations/mcp/handlers/index.js +40 -84
- package/dist/src/integrations/mcp/server.js +542 -641
- package/dist/src/integrations/mcp/tool-alias-registry.js +297 -0
- package/dist/src/integrations/mcp/tool-definitions.js +152 -682
- package/dist/src/mcp/stackmemory-mcp-server.js +571 -231
- package/dist/src/orchestrators/multimodal/determinism.js +244 -0
- package/dist/src/orchestrators/multimodal/harness.js +149 -78
- package/dist/src/orchestrators/multimodal/providers.js +44 -3
- package/dist/src/skills/recursive-agent-orchestrator.js +2 -4
- package/dist/src/utils/hook-installer.js +0 -8
- package/dist/src/utils/process-cleanup.js +1 -7
- package/docs/README.md +42 -0
- package/docs/guides/README_INSTALL.md +208 -0
- package/package.json +27 -9
- package/packs/coding/python-fastapi/instructions.md +60 -0
- package/packs/coding/python-fastapi/pack.yaml +28 -0
- package/packs/coding/typescript-react/instructions.md +47 -0
- package/packs/coding/typescript-react/pack.yaml +28 -0
- package/packs/core/commands/capture.md +32 -0
- package/packs/core/commands/learn.md +73 -0
- package/packs/core/commands/next.md +36 -0
- package/packs/core/commands/restart.md +58 -0
- package/packs/core/commands/restore.md +29 -0
- package/packs/core/commands/start.md +57 -0
- package/packs/core/commands/stop.md +65 -0
- package/packs/core/commands/summary.md +40 -0
- package/packs/core/manifest.json +24 -0
- package/packs/ops/decision-recovery/instructions.md +65 -0
- package/packs/ops/decision-recovery/pack.yaml +89 -0
- package/scripts/claude-code-wrapper.sh +11 -0
- package/scripts/claude-sm-setup.sh +12 -1
- package/scripts/codex-wrapper.sh +11 -0
- package/scripts/git-hooks/branch-context-manager.sh +11 -0
- package/scripts/git-hooks/post-checkout-stackmemory.sh +11 -0
- package/scripts/git-hooks/post-commit-stackmemory.sh +11 -0
- package/scripts/git-hooks/pre-commit-stackmemory.sh +11 -0
- package/scripts/hooks/cleanup-shell.sh +12 -1
- package/scripts/hooks/task-complete.sh +12 -1
- package/scripts/install-code-execution-hooks.sh +12 -1
- package/scripts/install-sweep-hook.sh +12 -0
- package/scripts/install.sh +11 -0
- package/scripts/opencode-wrapper.sh +11 -0
- package/scripts/portal/cloud-init.yaml +69 -0
- package/scripts/portal/setup.sh +69 -0
- package/scripts/portal/stackmemory-portal.service +34 -0
- package/scripts/setup-claude-integration.sh +12 -1
- package/scripts/smoke-init-db.sh +23 -0
- package/scripts/stackmemory-daemon.sh +11 -0
- package/scripts/verify-dist.cjs +11 -4
- package/dist/src/cli/commands/ralph.js +0 -1053
- package/dist/src/cli/commands/team.js +0 -168
- package/dist/src/core/context/shared-context-layer.js +0 -620
- package/dist/src/core/context/stack-merge-resolver.js +0 -748
- package/dist/src/core/merge/conflict-detector.js +0 -430
- package/dist/src/core/merge/resolution-engine.js +0 -557
- package/dist/src/core/merge/stack-diff.js +0 -531
- package/dist/src/core/merge/unified-merge-resolver.js +0 -302
- package/dist/src/hooks/diffmem-hooks.js +0 -376
- package/dist/src/integrations/diffmem/client.js +0 -208
- package/dist/src/integrations/diffmem/config.js +0 -14
- package/dist/src/integrations/greptile/client.js +0 -101
- package/dist/src/integrations/greptile/config.js +0 -14
- package/dist/src/integrations/greptile/index.js +0 -11
- package/dist/src/integrations/mcp/handlers/cord-handlers.js +0 -397
- package/dist/src/integrations/mcp/handlers/diffmem-handlers.js +0 -455
- package/dist/src/integrations/mcp/handlers/greptile-handlers.js +0 -456
- package/dist/src/integrations/mcp/handlers/provider-handlers.js +0 -227
- package/dist/src/integrations/mcp/handlers/team-handlers.js +0 -211
- package/dist/src/integrations/ralph/bridge/ralph-stackmemory-bridge.js +0 -863
- package/dist/src/integrations/ralph/context/context-budget-manager.js +0 -308
- package/dist/src/integrations/ralph/context/stackmemory-context-loader.js +0 -391
- package/dist/src/integrations/ralph/index.js +0 -17
- package/dist/src/integrations/ralph/learning/pattern-learner.js +0 -435
- package/dist/src/integrations/ralph/lifecycle/iteration-lifecycle.js +0 -448
- package/dist/src/integrations/ralph/loopmax.js +0 -488
- package/dist/src/integrations/ralph/monitoring/swarm-dashboard.js +0 -293
- package/dist/src/integrations/ralph/monitoring/swarm-registry.js +0 -107
- package/dist/src/integrations/ralph/orchestration/multi-loop-orchestrator.js +0 -508
- package/dist/src/integrations/ralph/patterns/compounding-engineering-pattern.js +0 -407
- package/dist/src/integrations/ralph/patterns/extended-coherence-sessions.js +0 -495
- package/dist/src/integrations/ralph/patterns/oracle-worker-pattern.js +0 -387
- package/dist/src/integrations/ralph/performance/performance-optimizer.js +0 -357
- package/dist/src/integrations/ralph/recovery/crash-recovery.js +0 -461
- package/dist/src/integrations/ralph/state/state-reconciler.js +0 -420
- package/dist/src/integrations/ralph/swarm/git-workflow-manager.js +0 -444
- package/dist/src/integrations/ralph/swarm/swarm-coordinator.js +0 -1007
- package/dist/src/integrations/ralph/visualization/ralph-debugger.js +0 -635
- package/scripts/ralph-loop-implementation.js +0 -404
- /package/dist/src/core/{merge → cache}/types.js +0 -0
- /package/dist/src/{integrations/diffmem/types.js → core/storage/cloud-sync-types.js} +0 -0
- /package/dist/src/{integrations/greptile/types.js → core/trace/trace-event.js} +0 -0
- /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
|
-
};
|