@neurynae/toolcairn-mcp 0.1.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/bin/toolpilot-mcp.js +5 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +45 -0
- package/dist/index.js.map +1 -0
- package/dist/middleware/event-logger.d.ts +19 -0
- package/dist/middleware/event-logger.d.ts.map +1 -0
- package/dist/middleware/event-logger.js +138 -0
- package/dist/middleware/event-logger.js.map +1 -0
- package/dist/schemas.d.ts +2 -0
- package/dist/schemas.d.ts.map +1 -0
- package/dist/schemas.js +3 -0
- package/dist/schemas.js.map +1 -0
- package/dist/server.d.ts +3 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +116 -0
- package/dist/server.js.map +1 -0
- package/dist/server.prod.d.ts +14 -0
- package/dist/server.prod.d.ts.map +1 -0
- package/dist/server.prod.js +127 -0
- package/dist/server.prod.js.map +1 -0
- package/dist/templates/agent-instructions.d.ts +22 -0
- package/dist/templates/agent-instructions.d.ts.map +1 -0
- package/dist/templates/agent-instructions.js +155 -0
- package/dist/templates/agent-instructions.js.map +1 -0
- package/dist/tools/check-compatibility.d.ts +100 -0
- package/dist/tools/check-compatibility.d.ts.map +1 -0
- package/dist/tools/check-compatibility.js +103 -0
- package/dist/tools/check-compatibility.js.map +1 -0
- package/dist/tools/check-issue.d.ts +126 -0
- package/dist/tools/check-issue.d.ts.map +1 -0
- package/dist/tools/check-issue.js +248 -0
- package/dist/tools/check-issue.js.map +1 -0
- package/dist/tools/classify-prompt.d.ts +101 -0
- package/dist/tools/classify-prompt.d.ts.map +1 -0
- package/dist/tools/classify-prompt.js +64 -0
- package/dist/tools/classify-prompt.js.map +1 -0
- package/dist/tools/compare-tools.d.ts +102 -0
- package/dist/tools/compare-tools.d.ts.map +1 -0
- package/dist/tools/compare-tools.js +178 -0
- package/dist/tools/compare-tools.js.map +1 -0
- package/dist/tools/format-results.d.ts +44 -0
- package/dist/tools/format-results.d.ts.map +1 -0
- package/dist/tools/format-results.js +114 -0
- package/dist/tools/format-results.js.map +1 -0
- package/dist/tools/generate-tracker.d.ts +7 -0
- package/dist/tools/generate-tracker.d.ts.map +1 -0
- package/dist/tools/generate-tracker.js +408 -0
- package/dist/tools/generate-tracker.js.map +1 -0
- package/dist/tools/get-stack.d.ts +105 -0
- package/dist/tools/get-stack.d.ts.map +1 -0
- package/dist/tools/get-stack.js +156 -0
- package/dist/tools/get-stack.js.map +1 -0
- package/dist/tools/init-project-config.d.ts +107 -0
- package/dist/tools/init-project-config.d.ts.map +1 -0
- package/dist/tools/init-project-config.js +52 -0
- package/dist/tools/init-project-config.js.map +1 -0
- package/dist/tools/read-project-config.d.ts +99 -0
- package/dist/tools/read-project-config.d.ts.map +1 -0
- package/dist/tools/read-project-config.js +78 -0
- package/dist/tools/read-project-config.js.map +1 -0
- package/dist/tools/refine-requirement.d.ts +105 -0
- package/dist/tools/refine-requirement.d.ts.map +1 -0
- package/dist/tools/refine-requirement.js +77 -0
- package/dist/tools/refine-requirement.js.map +1 -0
- package/dist/tools/report-outcome.d.ts +104 -0
- package/dist/tools/report-outcome.d.ts.map +1 -0
- package/dist/tools/report-outcome.js +108 -0
- package/dist/tools/report-outcome.js.map +1 -0
- package/dist/tools/search-tools-respond.d.ts +103 -0
- package/dist/tools/search-tools-respond.d.ts.map +1 -0
- package/dist/tools/search-tools-respond.js +91 -0
- package/dist/tools/search-tools-respond.js.map +1 -0
- package/dist/tools/search-tools.d.ts +104 -0
- package/dist/tools/search-tools.d.ts.map +1 -0
- package/dist/tools/search-tools.js +77 -0
- package/dist/tools/search-tools.js.map +1 -0
- package/dist/tools/suggest-graph-update.d.ts +117 -0
- package/dist/tools/suggest-graph-update.d.ts.map +1 -0
- package/dist/tools/suggest-graph-update.js +177 -0
- package/dist/tools/suggest-graph-update.js.map +1 -0
- package/dist/tools/toolpilot-init.d.ts +103 -0
- package/dist/tools/toolpilot-init.d.ts.map +1 -0
- package/dist/tools/toolpilot-init.js +115 -0
- package/dist/tools/toolpilot-init.js.map +1 -0
- package/dist/tools/update-project-config.d.ts +104 -0
- package/dist/tools/update-project-config.d.ts.map +1 -0
- package/dist/tools/update-project-config.js +117 -0
- package/dist/tools/update-project-config.js.map +1 -0
- package/dist/tools/verify-suggestion.d.ts +113 -0
- package/dist/tools/verify-suggestion.d.ts.map +1 -0
- package/dist/tools/verify-suggestion.js +223 -0
- package/dist/tools/verify-suggestion.js.map +1 -0
- package/dist/transport.d.ts +5 -0
- package/dist/transport.d.ts.map +1 -0
- package/dist/transport.js +13 -0
- package/dist/transport.js.map +1 -0
- package/dist/utils.d.ts +4 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +12 -0
- package/dist/utils.js.map +1 -0
- package/package.json +54 -0
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { PrismaClient } from '@toolpilot/db';
|
|
2
|
+
import { MemgraphToolRepository } from '@toolpilot/graph';
|
|
3
|
+
import { enqueueIndexJob } from '@toolpilot/queue';
|
|
4
|
+
import pino from 'pino';
|
|
5
|
+
import { errResult, okResult } from '../utils.js';
|
|
6
|
+
const logger = pino({ name: '@toolpilot/mcp-server:suggest-graph-update' });
|
|
7
|
+
const prisma = new PrismaClient();
|
|
8
|
+
const repo = new MemgraphToolRepository();
|
|
9
|
+
// Confidence threshold for auto-graduating edges to the graph (without human review)
|
|
10
|
+
const AUTO_GRADUATE_THRESHOLD = 0.8;
|
|
11
|
+
const VALID_EDGE_TYPES = new Set([
|
|
12
|
+
'SOLVES',
|
|
13
|
+
'REQUIRES',
|
|
14
|
+
'INTEGRATES_WITH',
|
|
15
|
+
'REPLACES',
|
|
16
|
+
'CONFLICTS_WITH',
|
|
17
|
+
'POPULAR_WITH',
|
|
18
|
+
'BREAKS_FROM',
|
|
19
|
+
'COMPATIBLE_WITH',
|
|
20
|
+
]);
|
|
21
|
+
export async function handleSuggestGraphUpdate(args) {
|
|
22
|
+
try {
|
|
23
|
+
logger.info({ suggestion_type: args.suggestion_type }, 'suggest_graph_update called');
|
|
24
|
+
const confidence = args.confidence ?? 0.5;
|
|
25
|
+
const queryIds = args.query_id ? [args.query_id] : [];
|
|
26
|
+
switch (args.suggestion_type) {
|
|
27
|
+
case 'new_tool': {
|
|
28
|
+
const toolName = args.data.tool_name;
|
|
29
|
+
if (!toolName) {
|
|
30
|
+
return errResult('missing_field', 'data.tool_name is required for new_tool suggestions');
|
|
31
|
+
}
|
|
32
|
+
// Stage the new tool for human review
|
|
33
|
+
const staged = await prisma.stagedNode.create({
|
|
34
|
+
data: {
|
|
35
|
+
node_type: 'Tool',
|
|
36
|
+
node_data: {
|
|
37
|
+
name: toolName,
|
|
38
|
+
github_url: args.data.github_url ?? null,
|
|
39
|
+
description: args.data.description ?? null,
|
|
40
|
+
},
|
|
41
|
+
confidence,
|
|
42
|
+
source: 'ai_generated',
|
|
43
|
+
supporting_queries: queryIds,
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
// Also enqueue async indexing if github_url provided
|
|
47
|
+
let indexQueued = false;
|
|
48
|
+
if (args.data.github_url) {
|
|
49
|
+
const indexResult = await enqueueIndexJob(args.data.github_url, 2);
|
|
50
|
+
indexQueued = indexResult.ok;
|
|
51
|
+
}
|
|
52
|
+
logger.info({ staged_id: staged.id, toolName }, 'New tool staged');
|
|
53
|
+
return okResult({
|
|
54
|
+
staged: true,
|
|
55
|
+
staged_id: staged.id,
|
|
56
|
+
auto_graduated: false,
|
|
57
|
+
index_queued: indexQueued,
|
|
58
|
+
message: `Tool "${toolName}" staged for review. ${indexQueued ? 'Indexing queued — full data available in ~2 minutes.' : 'Provide github_url for automatic indexing.'}`,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
case 'new_edge': {
|
|
62
|
+
const rel = args.data.relationship;
|
|
63
|
+
if (!rel) {
|
|
64
|
+
return errResult('missing_field', 'data.relationship is required for new_edge suggestions');
|
|
65
|
+
}
|
|
66
|
+
if (!VALID_EDGE_TYPES.has(rel.edge_type)) {
|
|
67
|
+
return errResult('invalid_edge_type', `Edge type "${rel.edge_type}" is not valid. Must be one of: ${Array.from(VALID_EDGE_TYPES).join(', ')}`);
|
|
68
|
+
}
|
|
69
|
+
// Check if both tools exist in Memgraph
|
|
70
|
+
const [existsSource, existsTarget] = await Promise.all([
|
|
71
|
+
repo.toolExists(rel.source_tool),
|
|
72
|
+
repo.toolExists(rel.target_tool),
|
|
73
|
+
]);
|
|
74
|
+
const bothExist = existsSource.ok && existsSource.data && existsTarget.ok && existsTarget.data;
|
|
75
|
+
// Auto-graduate if both tools exist AND confidence is high enough
|
|
76
|
+
if (bothExist && confidence >= AUTO_GRADUATE_THRESHOLD) {
|
|
77
|
+
const now = new Date().toISOString();
|
|
78
|
+
const edgeResult = await repo.upsertEdge({
|
|
79
|
+
type: rel.edge_type,
|
|
80
|
+
source_id: rel.source_tool,
|
|
81
|
+
target_id: rel.target_tool,
|
|
82
|
+
properties: {
|
|
83
|
+
weight: confidence * 0.8,
|
|
84
|
+
confidence,
|
|
85
|
+
last_verified: now,
|
|
86
|
+
source: 'ai_generated',
|
|
87
|
+
decay_rate: 0.05,
|
|
88
|
+
evidence_count: 1,
|
|
89
|
+
evidence_links: rel.evidence ? [rel.evidence] : [],
|
|
90
|
+
},
|
|
91
|
+
});
|
|
92
|
+
if (edgeResult.ok) {
|
|
93
|
+
logger.info({ source: rel.source_tool, target: rel.target_tool }, 'Edge auto-graduated');
|
|
94
|
+
return okResult({
|
|
95
|
+
staged: false,
|
|
96
|
+
auto_graduated: true,
|
|
97
|
+
message: `Edge ${rel.source_tool} → ${rel.target_tool} (${rel.edge_type}) written directly to graph (confidence ${confidence} ≥ ${AUTO_GRADUATE_THRESHOLD}).`,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
// Stage for review
|
|
102
|
+
const staged = await prisma.stagedEdge.create({
|
|
103
|
+
data: {
|
|
104
|
+
edge_type: rel.edge_type,
|
|
105
|
+
source_node_id: rel.source_tool,
|
|
106
|
+
target_node_id: rel.target_tool,
|
|
107
|
+
edge_data: {
|
|
108
|
+
evidence: rel.evidence ?? null,
|
|
109
|
+
both_tools_indexed: bothExist,
|
|
110
|
+
},
|
|
111
|
+
confidence,
|
|
112
|
+
source: 'ai_generated',
|
|
113
|
+
supporting_queries: queryIds,
|
|
114
|
+
},
|
|
115
|
+
});
|
|
116
|
+
logger.info({ staged_id: staged.id }, 'Edge staged for review');
|
|
117
|
+
return okResult({
|
|
118
|
+
staged: true,
|
|
119
|
+
staged_id: staged.id,
|
|
120
|
+
auto_graduated: false,
|
|
121
|
+
reason: confidence < AUTO_GRADUATE_THRESHOLD
|
|
122
|
+
? `Confidence ${confidence} < ${AUTO_GRADUATE_THRESHOLD} threshold — queued for human review`
|
|
123
|
+
: 'One or both tools not yet in graph — queued for review',
|
|
124
|
+
message: `Edge ${rel.source_tool} → ${rel.target_tool} (${rel.edge_type}) staged for review.`,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
case 'update_health': {
|
|
128
|
+
const toolName = args.data.tool_name;
|
|
129
|
+
if (!toolName) {
|
|
130
|
+
return errResult('missing_field', 'data.tool_name is required for update_health');
|
|
131
|
+
}
|
|
132
|
+
const indexResult = await enqueueIndexJob(toolName, 1);
|
|
133
|
+
if (!indexResult.ok) {
|
|
134
|
+
return errResult('queue_error', `Failed to enqueue re-index: ${indexResult.error}`);
|
|
135
|
+
}
|
|
136
|
+
logger.info({ tool: toolName }, 'Re-index job enqueued for health update');
|
|
137
|
+
return okResult({
|
|
138
|
+
staged: false,
|
|
139
|
+
auto_graduated: false,
|
|
140
|
+
index_queued: true,
|
|
141
|
+
message: `Re-indexing queued for "${toolName}". Updated health signals will be available in ~2 minutes.`,
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
case 'new_use_case': {
|
|
145
|
+
const uc = args.data.use_case;
|
|
146
|
+
if (!uc) {
|
|
147
|
+
return errResult('missing_field', 'data.use_case is required for new_use_case suggestions');
|
|
148
|
+
}
|
|
149
|
+
const staged = await prisma.stagedNode.create({
|
|
150
|
+
data: {
|
|
151
|
+
node_type: 'UseCase',
|
|
152
|
+
node_data: {
|
|
153
|
+
name: uc.name,
|
|
154
|
+
description: uc.description,
|
|
155
|
+
tools: uc.tools ?? [],
|
|
156
|
+
},
|
|
157
|
+
confidence,
|
|
158
|
+
source: 'ai_generated',
|
|
159
|
+
supporting_queries: queryIds,
|
|
160
|
+
},
|
|
161
|
+
});
|
|
162
|
+
logger.info({ staged_id: staged.id, name: uc.name }, 'UseCase staged');
|
|
163
|
+
return okResult({
|
|
164
|
+
staged: true,
|
|
165
|
+
staged_id: staged.id,
|
|
166
|
+
auto_graduated: false,
|
|
167
|
+
message: `UseCase "${uc.name}" staged for review.`,
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
catch (e) {
|
|
173
|
+
logger.error({ err: e }, 'suggest_graph_update failed');
|
|
174
|
+
return errResult('suggest_error', e instanceof Error ? e.message : String(e));
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=suggest-graph-update.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"suggest-graph-update.js","sourceRoot":"","sources":["../../src/tools/suggest-graph-update.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAElD,MAAM,MAAM,GAAG,IAAI,CAAC,EAAE,IAAI,EAAE,4CAA4C,EAAE,CAAC,CAAC;AAC5E,MAAM,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;AAClC,MAAM,IAAI,GAAG,IAAI,sBAAsB,EAAE,CAAC;AAE1C,qFAAqF;AACrF,MAAM,uBAAuB,GAAG,GAAG,CAAC;AAEpC,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAW;IACzC,QAAQ;IACR,UAAU;IACV,iBAAiB;IACjB,UAAU;IACV,gBAAgB;IAChB,cAAc;IACd,aAAa;IACb,iBAAiB;CAClB,CAAC,CAAC;AAEH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,IAoB9C;IACC,IAAI,CAAC;QACH,MAAM,CAAC,IAAI,CAAC,EAAE,eAAe,EAAE,IAAI,CAAC,eAAe,EAAE,EAAE,6BAA6B,CAAC,CAAC;QAEtF,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,IAAI,GAAG,CAAC;QAC1C,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAEtD,QAAQ,IAAI,CAAC,eAAe,EAAE,CAAC;YAC7B,KAAK,UAAU,CAAC,CAAC,CAAC;gBAChB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC;gBACrC,IAAI,CAAC,QAAQ,EAAE,CAAC;oBACd,OAAO,SAAS,CAAC,eAAe,EAAE,qDAAqD,CAAC,CAAC;gBAC3F,CAAC;gBAED,sCAAsC;gBACtC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC;oBAC5C,IAAI,EAAE;wBACJ,SAAS,EAAE,MAAM;wBACjB,SAAS,EAAE;4BACT,IAAI,EAAE,QAAQ;4BACd,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,UAAU,IAAI,IAAI;4BACxC,WAAW,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,IAAI;yBAC3C;wBACD,UAAU;wBACV,MAAM,EAAE,cAAc;wBACtB,kBAAkB,EAAE,QAAQ;qBAC7B;iBACF,CAAC,CAAC;gBAEH,qDAAqD;gBACrD,IAAI,WAAW,GAAG,KAAK,CAAC;gBACxB,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;oBACzB,MAAM,WAAW,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;oBACnE,WAAW,GAAG,WAAW,CAAC,EAAE,CAAC;gBAC/B,CAAC;gBAED,MAAM,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,EAAE,EAAE,QAAQ,EAAE,EAAE,iBAAiB,CAAC,CAAC;gBACnE,OAAO,QAAQ,CAAC;oBACd,MAAM,EAAE,IAAI;oBACZ,SAAS,EAAE,MAAM,CAAC,EAAE;oBACpB,cAAc,EAAE,KAAK;oBACrB,YAAY,EAAE,WAAW;oBACzB,OAAO,EAAE,SAAS,QAAQ,wBAAwB,WAAW,CAAC,CAAC,CAAC,sDAAsD,CAAC,CAAC,CAAC,4CAA4C,EAAE;iBACxK,CAAC,CAAC;YACL,CAAC;YAED,KAAK,UAAU,CAAC,CAAC,CAAC;gBAChB,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC;gBACnC,IAAI,CAAC,GAAG,EAAE,CAAC;oBACT,OAAO,SAAS,CACd,eAAe,EACf,wDAAwD,CACzD,CAAC;gBACJ,CAAC;gBACD,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,SAAqB,CAAC,EAAE,CAAC;oBACrD,OAAO,SAAS,CACd,mBAAmB,EACnB,cAAc,GAAG,CAAC,SAAS,mCAAmC,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACxG,CAAC;gBACJ,CAAC;gBAED,wCAAwC;gBACxC,MAAM,CAAC,YAAY,EAAE,YAAY,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;oBACrD,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,WAAW,CAAC;oBAChC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,WAAW,CAAC;iBACjC,CAAC,CAAC;gBAEH,MAAM,SAAS,GACb,YAAY,CAAC,EAAE,IAAI,YAAY,CAAC,IAAI,IAAI,YAAY,CAAC,EAAE,IAAI,YAAY,CAAC,IAAI,CAAC;gBAE/E,kEAAkE;gBAClE,IAAI,SAAS,IAAI,UAAU,IAAI,uBAAuB,EAAE,CAAC;oBACvD,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;oBACrC,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC;wBACvC,IAAI,EAAE,GAAG,CAAC,SAAqB;wBAC/B,SAAS,EAAE,GAAG,CAAC,WAAW;wBAC1B,SAAS,EAAE,GAAG,CAAC,WAAW;wBAC1B,UAAU,EAAE;4BACV,MAAM,EAAE,UAAU,GAAG,GAAG;4BACxB,UAAU;4BACV,aAAa,EAAE,GAAG;4BAClB,MAAM,EAAE,cAAc;4BACtB,UAAU,EAAE,IAAI;4BAChB,cAAc,EAAE,CAAC;4BACjB,cAAc,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE;yBACnD;qBACF,CAAC,CAAC;oBAEH,IAAI,UAAU,CAAC,EAAE,EAAE,CAAC;wBAClB,MAAM,CAAC,IAAI,CACT,EAAE,MAAM,EAAE,GAAG,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,CAAC,WAAW,EAAE,EACpD,qBAAqB,CACtB,CAAC;wBACF,OAAO,QAAQ,CAAC;4BACd,MAAM,EAAE,KAAK;4BACb,cAAc,EAAE,IAAI;4BACpB,OAAO,EAAE,QAAQ,GAAG,CAAC,WAAW,MAAM,GAAG,CAAC,WAAW,KAAK,GAAG,CAAC,SAAS,2CAA2C,UAAU,MAAM,uBAAuB,IAAI;yBAC9J,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;gBAED,mBAAmB;gBACnB,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC;oBAC5C,IAAI,EAAE;wBACJ,SAAS,EAAE,GAAG,CAAC,SAAS;wBACxB,cAAc,EAAE,GAAG,CAAC,WAAW;wBAC/B,cAAc,EAAE,GAAG,CAAC,WAAW;wBAC/B,SAAS,EAAE;4BACT,QAAQ,EAAE,GAAG,CAAC,QAAQ,IAAI,IAAI;4BAC9B,kBAAkB,EAAE,SAAS;yBAC9B;wBACD,UAAU;wBACV,MAAM,EAAE,cAAc;wBACtB,kBAAkB,EAAE,QAAQ;qBAC7B;iBACF,CAAC,CAAC;gBAEH,MAAM,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,wBAAwB,CAAC,CAAC;gBAChE,OAAO,QAAQ,CAAC;oBACd,MAAM,EAAE,IAAI;oBACZ,SAAS,EAAE,MAAM,CAAC,EAAE;oBACpB,cAAc,EAAE,KAAK;oBACrB,MAAM,EACJ,UAAU,GAAG,uBAAuB;wBAClC,CAAC,CAAC,cAAc,UAAU,MAAM,uBAAuB,sCAAsC;wBAC7F,CAAC,CAAC,wDAAwD;oBAC9D,OAAO,EAAE,QAAQ,GAAG,CAAC,WAAW,MAAM,GAAG,CAAC,WAAW,KAAK,GAAG,CAAC,SAAS,sBAAsB;iBAC9F,CAAC,CAAC;YACL,CAAC;YAED,KAAK,eAAe,CAAC,CAAC,CAAC;gBACrB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC;gBACrC,IAAI,CAAC,QAAQ,EAAE,CAAC;oBACd,OAAO,SAAS,CAAC,eAAe,EAAE,8CAA8C,CAAC,CAAC;gBACpF,CAAC;gBAED,MAAM,WAAW,GAAG,MAAM,eAAe,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;gBACvD,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,CAAC;oBACpB,OAAO,SAAS,CAAC,aAAa,EAAE,+BAA+B,WAAW,CAAC,KAAK,EAAE,CAAC,CAAC;gBACtF,CAAC;gBAED,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,yCAAyC,CAAC,CAAC;gBAC3E,OAAO,QAAQ,CAAC;oBACd,MAAM,EAAE,KAAK;oBACb,cAAc,EAAE,KAAK;oBACrB,YAAY,EAAE,IAAI;oBAClB,OAAO,EAAE,2BAA2B,QAAQ,4DAA4D;iBACzG,CAAC,CAAC;YACL,CAAC;YAED,KAAK,cAAc,CAAC,CAAC,CAAC;gBACpB,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC;gBAC9B,IAAI,CAAC,EAAE,EAAE,CAAC;oBACR,OAAO,SAAS,CACd,eAAe,EACf,wDAAwD,CACzD,CAAC;gBACJ,CAAC;gBAED,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC;oBAC5C,IAAI,EAAE;wBACJ,SAAS,EAAE,SAAS;wBACpB,SAAS,EAAE;4BACT,IAAI,EAAE,EAAE,CAAC,IAAI;4BACb,WAAW,EAAE,EAAE,CAAC,WAAW;4BAC3B,KAAK,EAAE,EAAE,CAAC,KAAK,IAAI,EAAE;yBACtB;wBACD,UAAU;wBACV,MAAM,EAAE,cAAc;wBACtB,kBAAkB,EAAE,QAAQ;qBAC7B;iBACF,CAAC,CAAC;gBAEH,MAAM,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,gBAAgB,CAAC,CAAC;gBACvE,OAAO,QAAQ,CAAC;oBACd,MAAM,EAAE,IAAI;oBACZ,SAAS,EAAE,MAAM,CAAC,EAAE;oBACpB,cAAc,EAAE,KAAK;oBACrB,OAAO,EAAE,YAAY,EAAE,CAAC,IAAI,sBAAsB;iBACnD,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE,6BAA6B,CAAC,CAAC;QACxD,OAAO,SAAS,CAAC,eAAe,EAAE,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IAChF,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { type AgentType } from '../templates/agent-instructions.js';
|
|
2
|
+
export declare function handleToolpilotInit(args: {
|
|
3
|
+
agent: AgentType;
|
|
4
|
+
project_root: string;
|
|
5
|
+
server_path?: string;
|
|
6
|
+
detected_files?: string[];
|
|
7
|
+
}): Promise<{
|
|
8
|
+
[x: string]: unknown;
|
|
9
|
+
content: ({
|
|
10
|
+
type: "text";
|
|
11
|
+
text: string;
|
|
12
|
+
annotations?: {
|
|
13
|
+
audience?: ("user" | "assistant")[] | undefined;
|
|
14
|
+
priority?: number | undefined;
|
|
15
|
+
lastModified?: string | undefined;
|
|
16
|
+
} | undefined;
|
|
17
|
+
_meta?: {
|
|
18
|
+
[x: string]: unknown;
|
|
19
|
+
} | undefined;
|
|
20
|
+
} | {
|
|
21
|
+
type: "image";
|
|
22
|
+
data: string;
|
|
23
|
+
mimeType: string;
|
|
24
|
+
annotations?: {
|
|
25
|
+
audience?: ("user" | "assistant")[] | undefined;
|
|
26
|
+
priority?: number | undefined;
|
|
27
|
+
lastModified?: string | undefined;
|
|
28
|
+
} | undefined;
|
|
29
|
+
_meta?: {
|
|
30
|
+
[x: string]: unknown;
|
|
31
|
+
} | undefined;
|
|
32
|
+
} | {
|
|
33
|
+
type: "audio";
|
|
34
|
+
data: string;
|
|
35
|
+
mimeType: string;
|
|
36
|
+
annotations?: {
|
|
37
|
+
audience?: ("user" | "assistant")[] | undefined;
|
|
38
|
+
priority?: number | undefined;
|
|
39
|
+
lastModified?: string | undefined;
|
|
40
|
+
} | undefined;
|
|
41
|
+
_meta?: {
|
|
42
|
+
[x: string]: unknown;
|
|
43
|
+
} | undefined;
|
|
44
|
+
} | {
|
|
45
|
+
uri: string;
|
|
46
|
+
name: string;
|
|
47
|
+
type: "resource_link";
|
|
48
|
+
description?: string | undefined;
|
|
49
|
+
mimeType?: string | undefined;
|
|
50
|
+
annotations?: {
|
|
51
|
+
audience?: ("user" | "assistant")[] | undefined;
|
|
52
|
+
priority?: number | undefined;
|
|
53
|
+
lastModified?: string | undefined;
|
|
54
|
+
} | undefined;
|
|
55
|
+
_meta?: {
|
|
56
|
+
[x: string]: unknown;
|
|
57
|
+
} | undefined;
|
|
58
|
+
icons?: {
|
|
59
|
+
src: string;
|
|
60
|
+
mimeType?: string | undefined;
|
|
61
|
+
sizes?: string[] | undefined;
|
|
62
|
+
theme?: "light" | "dark" | undefined;
|
|
63
|
+
}[] | undefined;
|
|
64
|
+
title?: string | undefined;
|
|
65
|
+
} | {
|
|
66
|
+
type: "resource";
|
|
67
|
+
resource: {
|
|
68
|
+
uri: string;
|
|
69
|
+
text: string;
|
|
70
|
+
mimeType?: string | undefined;
|
|
71
|
+
_meta?: {
|
|
72
|
+
[x: string]: unknown;
|
|
73
|
+
} | undefined;
|
|
74
|
+
} | {
|
|
75
|
+
uri: string;
|
|
76
|
+
blob: string;
|
|
77
|
+
mimeType?: string | undefined;
|
|
78
|
+
_meta?: {
|
|
79
|
+
[x: string]: unknown;
|
|
80
|
+
} | undefined;
|
|
81
|
+
};
|
|
82
|
+
annotations?: {
|
|
83
|
+
audience?: ("user" | "assistant")[] | undefined;
|
|
84
|
+
priority?: number | undefined;
|
|
85
|
+
lastModified?: string | undefined;
|
|
86
|
+
} | undefined;
|
|
87
|
+
_meta?: {
|
|
88
|
+
[x: string]: unknown;
|
|
89
|
+
} | undefined;
|
|
90
|
+
})[];
|
|
91
|
+
_meta?: {
|
|
92
|
+
[x: string]: unknown;
|
|
93
|
+
progressToken?: string | number | undefined;
|
|
94
|
+
"io.modelcontextprotocol/related-task"?: {
|
|
95
|
+
taskId: string;
|
|
96
|
+
} | undefined;
|
|
97
|
+
} | undefined;
|
|
98
|
+
structuredContent?: {
|
|
99
|
+
[x: string]: unknown;
|
|
100
|
+
} | undefined;
|
|
101
|
+
isError?: boolean | undefined;
|
|
102
|
+
}>;
|
|
103
|
+
//# sourceMappingURL=toolpilot-init.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toolpilot-init.d.ts","sourceRoot":"","sources":["../../src/tools/toolpilot-init.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,SAAS,EAIf,MAAM,oCAAoC,CAAC;AAM5C,wBAAsB,mBAAmB,CAAC,IAAI,EAAE;IAC9C,KAAK,EAAE,SAAS,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiIA"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import pino from 'pino';
|
|
2
|
+
import { getInstructionsForAgent, getMcpConfigEntry, getOpenCodeMcpEntry, } from '../templates/agent-instructions.js';
|
|
3
|
+
import { errResult, okResult } from '../utils.js';
|
|
4
|
+
import { generateTrackerHtml } from './generate-tracker.js';
|
|
5
|
+
const logger = pino({ name: '@toolpilot/mcp-server:toolpilot-init' });
|
|
6
|
+
export async function handleToolpilotInit(args) {
|
|
7
|
+
try {
|
|
8
|
+
logger.info({ agent: args.agent, project_root: args.project_root }, 'toolpilot_init called');
|
|
9
|
+
const instructions = getInstructionsForAgent(args.agent);
|
|
10
|
+
// OpenCode uses opencode.json "mcp" key format; all other agents use .mcp.json
|
|
11
|
+
const isOpenCode = args.agent === 'opencode';
|
|
12
|
+
const mcpConfigEntry = isOpenCode
|
|
13
|
+
? getOpenCodeMcpEntry(args.server_path)
|
|
14
|
+
: getMcpConfigEntry(args.server_path);
|
|
15
|
+
const mcpConfigFile = isOpenCode ? 'opencode.json' : '.mcp.json';
|
|
16
|
+
// Determine if the agent's MCP config file already exists based on detected files
|
|
17
|
+
const hasMcpJson = args.detected_files?.some((f) => f === mcpConfigFile || f.endsWith(`/${mcpConfigFile}`));
|
|
18
|
+
const hasInstructionFile = args.detected_files?.some((f) => f.endsWith(instructions.file_path));
|
|
19
|
+
const hasToolpilotConfig = args.detected_files?.some((f) => f.includes('.toolpilot/config.json'));
|
|
20
|
+
const hasTrackerHtml = args.detected_files?.some((f) => f.includes('.toolpilot/tracker.html'));
|
|
21
|
+
// Default events path: <project_root>/.toolpilot/events.jsonl
|
|
22
|
+
const eventsPath = `${args.project_root}/.toolpilot/events.jsonl`;
|
|
23
|
+
const setupSteps = [];
|
|
24
|
+
let step = 1;
|
|
25
|
+
// Step 1: Instruction file
|
|
26
|
+
setupSteps.push({
|
|
27
|
+
step: step++,
|
|
28
|
+
action: hasInstructionFile ? 'append' : 'create',
|
|
29
|
+
file: instructions.file_path,
|
|
30
|
+
content: instructions.content,
|
|
31
|
+
note: hasInstructionFile
|
|
32
|
+
? `Append the content to your existing ${instructions.file_path}`
|
|
33
|
+
: `Create ${instructions.file_path} with the content`,
|
|
34
|
+
});
|
|
35
|
+
// Step 2: MCP config
|
|
36
|
+
const mcpContent = isOpenCode
|
|
37
|
+
? JSON.stringify({ mcp: mcpConfigEntry }, null, 2)
|
|
38
|
+
: JSON.stringify({ mcpServers: mcpConfigEntry }, null, 2);
|
|
39
|
+
const mcpMergeNote = isOpenCode
|
|
40
|
+
? `Merge the toolpilot entry into your existing ${mcpConfigFile} under "mcp"`
|
|
41
|
+
: `Merge the toolpilot entry into your existing ${mcpConfigFile} under "mcpServers"`;
|
|
42
|
+
const mcpCreateNote = isOpenCode
|
|
43
|
+
? `Create ${mcpConfigFile} with this content (OpenCode MCP config format)`
|
|
44
|
+
: `Create ${mcpConfigFile} with this content`;
|
|
45
|
+
setupSteps.push({
|
|
46
|
+
step: step++,
|
|
47
|
+
action: hasMcpJson ? 'merge' : 'create',
|
|
48
|
+
file: mcpConfigFile,
|
|
49
|
+
content: mcpContent,
|
|
50
|
+
note: hasMcpJson ? mcpMergeNote : mcpCreateNote,
|
|
51
|
+
});
|
|
52
|
+
// Step 3: Project config
|
|
53
|
+
if (!hasToolpilotConfig) {
|
|
54
|
+
setupSteps.push({
|
|
55
|
+
step: step++,
|
|
56
|
+
action: 'create',
|
|
57
|
+
file: '.toolpilot/config.json',
|
|
58
|
+
note: 'Call init_project_config to generate the config content, then write to .toolpilot/config.json',
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
// Step 4: Tracker dashboard
|
|
62
|
+
if (!hasTrackerHtml) {
|
|
63
|
+
setupSteps.push({
|
|
64
|
+
step: step++,
|
|
65
|
+
action: 'create',
|
|
66
|
+
file: '.toolpilot/tracker.html',
|
|
67
|
+
content: generateTrackerHtml(eventsPath),
|
|
68
|
+
note: `Open .toolpilot/tracker.html in your browser to monitor MCP tool calls in real time. Set TOOLPILOT_EVENTS_PATH=${eventsPath} in your MCP server environment to enable event logging.`,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
// Step 5: Gitignore
|
|
72
|
+
setupSteps.push({
|
|
73
|
+
step: step++,
|
|
74
|
+
action: 'append',
|
|
75
|
+
file: '.gitignore',
|
|
76
|
+
content: '\n# ToolPilot\n.toolpilot/events.jsonl\n',
|
|
77
|
+
note: 'Add .toolpilot/events.jsonl to .gitignore (the tracker event log)',
|
|
78
|
+
});
|
|
79
|
+
const agentFileLabel = {
|
|
80
|
+
claude: 'CLAUDE.md',
|
|
81
|
+
cursor: '.cursorrules',
|
|
82
|
+
windsurf: '.windsurfrules',
|
|
83
|
+
copilot: '.github/copilot-instructions.md',
|
|
84
|
+
'copilot-cli': '.github/copilot-instructions.md',
|
|
85
|
+
opencode: 'AGENTS.md',
|
|
86
|
+
generic: 'AI_INSTRUCTIONS.md',
|
|
87
|
+
};
|
|
88
|
+
return okResult({
|
|
89
|
+
agent: args.agent,
|
|
90
|
+
instruction_file: agentFileLabel[args.agent],
|
|
91
|
+
setup_steps: setupSteps,
|
|
92
|
+
mcp_config_entry: mcpConfigEntry,
|
|
93
|
+
events_path: eventsPath,
|
|
94
|
+
summary: [
|
|
95
|
+
`ToolPilot setup for ${args.agent} agent in ${args.project_root}`,
|
|
96
|
+
`Instructions will be added to: ${instructions.file_path}`,
|
|
97
|
+
'MCP server entry: toolpilot → .mcp.json',
|
|
98
|
+
hasToolpilotConfig
|
|
99
|
+
? '.toolpilot/config.json already exists — skipping init'
|
|
100
|
+
: 'Run init_project_config next to generate .toolpilot/config.json',
|
|
101
|
+
hasTrackerHtml
|
|
102
|
+
? '.toolpilot/tracker.html already exists — skipping'
|
|
103
|
+
: `Tracker dashboard: open .toolpilot/tracker.html in browser (set TOOLPILOT_EVENTS_PATH=${eventsPath})`,
|
|
104
|
+
].join('\n'),
|
|
105
|
+
next_steps: hasToolpilotConfig
|
|
106
|
+
? 'Setup complete. Open .toolpilot/tracker.html to monitor tool calls.'
|
|
107
|
+
: 'After completing setup steps, call init_project_config to initialize .toolpilot/config.json.',
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
catch (e) {
|
|
111
|
+
logger.error({ err: e }, 'toolpilot_init failed');
|
|
112
|
+
return errResult('init_error', e instanceof Error ? e.message : String(e));
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=toolpilot-init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toolpilot-init.js","sourceRoot":"","sources":["../../src/tools/toolpilot-init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
type UpdateAction = 'add_tool' | 'remove_tool' | 'update_tool' | 'add_evaluation';
|
|
2
|
+
export declare function handleUpdateProjectConfig(args: {
|
|
3
|
+
current_config: string;
|
|
4
|
+
action: UpdateAction;
|
|
5
|
+
tool_name: string;
|
|
6
|
+
data?: Record<string, unknown>;
|
|
7
|
+
}): Promise<{
|
|
8
|
+
[x: string]: unknown;
|
|
9
|
+
content: ({
|
|
10
|
+
type: "text";
|
|
11
|
+
text: string;
|
|
12
|
+
annotations?: {
|
|
13
|
+
audience?: ("user" | "assistant")[] | undefined;
|
|
14
|
+
priority?: number | undefined;
|
|
15
|
+
lastModified?: string | undefined;
|
|
16
|
+
} | undefined;
|
|
17
|
+
_meta?: {
|
|
18
|
+
[x: string]: unknown;
|
|
19
|
+
} | undefined;
|
|
20
|
+
} | {
|
|
21
|
+
type: "image";
|
|
22
|
+
data: string;
|
|
23
|
+
mimeType: string;
|
|
24
|
+
annotations?: {
|
|
25
|
+
audience?: ("user" | "assistant")[] | undefined;
|
|
26
|
+
priority?: number | undefined;
|
|
27
|
+
lastModified?: string | undefined;
|
|
28
|
+
} | undefined;
|
|
29
|
+
_meta?: {
|
|
30
|
+
[x: string]: unknown;
|
|
31
|
+
} | undefined;
|
|
32
|
+
} | {
|
|
33
|
+
type: "audio";
|
|
34
|
+
data: string;
|
|
35
|
+
mimeType: string;
|
|
36
|
+
annotations?: {
|
|
37
|
+
audience?: ("user" | "assistant")[] | undefined;
|
|
38
|
+
priority?: number | undefined;
|
|
39
|
+
lastModified?: string | undefined;
|
|
40
|
+
} | undefined;
|
|
41
|
+
_meta?: {
|
|
42
|
+
[x: string]: unknown;
|
|
43
|
+
} | undefined;
|
|
44
|
+
} | {
|
|
45
|
+
uri: string;
|
|
46
|
+
name: string;
|
|
47
|
+
type: "resource_link";
|
|
48
|
+
description?: string | undefined;
|
|
49
|
+
mimeType?: string | undefined;
|
|
50
|
+
annotations?: {
|
|
51
|
+
audience?: ("user" | "assistant")[] | undefined;
|
|
52
|
+
priority?: number | undefined;
|
|
53
|
+
lastModified?: string | undefined;
|
|
54
|
+
} | undefined;
|
|
55
|
+
_meta?: {
|
|
56
|
+
[x: string]: unknown;
|
|
57
|
+
} | undefined;
|
|
58
|
+
icons?: {
|
|
59
|
+
src: string;
|
|
60
|
+
mimeType?: string | undefined;
|
|
61
|
+
sizes?: string[] | undefined;
|
|
62
|
+
theme?: "light" | "dark" | undefined;
|
|
63
|
+
}[] | undefined;
|
|
64
|
+
title?: string | undefined;
|
|
65
|
+
} | {
|
|
66
|
+
type: "resource";
|
|
67
|
+
resource: {
|
|
68
|
+
uri: string;
|
|
69
|
+
text: string;
|
|
70
|
+
mimeType?: string | undefined;
|
|
71
|
+
_meta?: {
|
|
72
|
+
[x: string]: unknown;
|
|
73
|
+
} | undefined;
|
|
74
|
+
} | {
|
|
75
|
+
uri: string;
|
|
76
|
+
blob: string;
|
|
77
|
+
mimeType?: string | undefined;
|
|
78
|
+
_meta?: {
|
|
79
|
+
[x: string]: unknown;
|
|
80
|
+
} | undefined;
|
|
81
|
+
};
|
|
82
|
+
annotations?: {
|
|
83
|
+
audience?: ("user" | "assistant")[] | undefined;
|
|
84
|
+
priority?: number | undefined;
|
|
85
|
+
lastModified?: string | undefined;
|
|
86
|
+
} | undefined;
|
|
87
|
+
_meta?: {
|
|
88
|
+
[x: string]: unknown;
|
|
89
|
+
} | undefined;
|
|
90
|
+
})[];
|
|
91
|
+
_meta?: {
|
|
92
|
+
[x: string]: unknown;
|
|
93
|
+
progressToken?: string | number | undefined;
|
|
94
|
+
"io.modelcontextprotocol/related-task"?: {
|
|
95
|
+
taskId: string;
|
|
96
|
+
} | undefined;
|
|
97
|
+
} | undefined;
|
|
98
|
+
structuredContent?: {
|
|
99
|
+
[x: string]: unknown;
|
|
100
|
+
} | undefined;
|
|
101
|
+
isError?: boolean | undefined;
|
|
102
|
+
}>;
|
|
103
|
+
export {};
|
|
104
|
+
//# sourceMappingURL=update-project-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-project-config.d.ts","sourceRoot":"","sources":["../../src/tools/update-project-config.ts"],"names":[],"mappings":"AAWA,KAAK,YAAY,GAAG,UAAU,GAAG,aAAa,GAAG,aAAa,GAAG,gBAAgB,CAAC;AAElF,wBAAsB,yBAAyB,CAAC,IAAI,EAAE;IACpD,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,YAAY,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8HA"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import pino from 'pino';
|
|
2
|
+
import { errResult, okResult } from '../utils.js';
|
|
3
|
+
const logger = pino({ name: '@toolpilot/mcp-server:update-project-config' });
|
|
4
|
+
export async function handleUpdateProjectConfig(args) {
|
|
5
|
+
try {
|
|
6
|
+
logger.info({ action: args.action, tool: args.tool_name }, 'update_project_config called');
|
|
7
|
+
let config;
|
|
8
|
+
try {
|
|
9
|
+
config = JSON.parse(args.current_config);
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
return errResult('parse_error', 'current_config is not valid JSON');
|
|
13
|
+
}
|
|
14
|
+
const now = new Date().toISOString();
|
|
15
|
+
const data = args.data ?? {};
|
|
16
|
+
switch (args.action) {
|
|
17
|
+
case 'add_tool': {
|
|
18
|
+
// Remove from pending if present
|
|
19
|
+
config.tools.pending_evaluation = config.tools.pending_evaluation.filter((t) => t.name !== args.tool_name);
|
|
20
|
+
// Avoid duplicates
|
|
21
|
+
if (!config.tools.confirmed.some((t) => t.name === args.tool_name)) {
|
|
22
|
+
const newTool = {
|
|
23
|
+
name: args.tool_name,
|
|
24
|
+
source: data.source ?? 'toolpilot',
|
|
25
|
+
github_url: data.github_url,
|
|
26
|
+
version: data.version,
|
|
27
|
+
chosen_at: now,
|
|
28
|
+
chosen_reason: data.chosen_reason ?? 'Selected via ToolPilot',
|
|
29
|
+
alternatives_considered: data.alternatives_considered ?? [],
|
|
30
|
+
query_id: data.query_id,
|
|
31
|
+
notes: data.notes,
|
|
32
|
+
};
|
|
33
|
+
config.tools.confirmed.push(newTool);
|
|
34
|
+
}
|
|
35
|
+
config.audit_log.push({
|
|
36
|
+
action: 'add_tool',
|
|
37
|
+
tool: args.tool_name,
|
|
38
|
+
timestamp: now,
|
|
39
|
+
reason: data.chosen_reason ?? 'Added via ToolPilot recommendation',
|
|
40
|
+
});
|
|
41
|
+
break;
|
|
42
|
+
}
|
|
43
|
+
case 'remove_tool': {
|
|
44
|
+
config.tools.confirmed = config.tools.confirmed.filter((t) => t.name !== args.tool_name);
|
|
45
|
+
config.tools.pending_evaluation = config.tools.pending_evaluation.filter((t) => t.name !== args.tool_name);
|
|
46
|
+
config.audit_log.push({
|
|
47
|
+
action: 'remove_tool',
|
|
48
|
+
tool: args.tool_name,
|
|
49
|
+
timestamp: now,
|
|
50
|
+
reason: data.reason ?? 'Removed from project',
|
|
51
|
+
});
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
case 'update_tool': {
|
|
55
|
+
const idx = config.tools.confirmed.findIndex((t) => t.name === args.tool_name);
|
|
56
|
+
if (idx === -1) {
|
|
57
|
+
return errResult('not_found', `Tool "${args.tool_name}" not found in confirmed tools`);
|
|
58
|
+
}
|
|
59
|
+
const existing = config.tools.confirmed[idx];
|
|
60
|
+
if (!existing) {
|
|
61
|
+
return errResult('not_found', `Tool "${args.tool_name}" not found`);
|
|
62
|
+
}
|
|
63
|
+
config.tools.confirmed[idx] = {
|
|
64
|
+
...existing,
|
|
65
|
+
...(data.version !== undefined ? { version: data.version } : {}),
|
|
66
|
+
...(data.notes !== undefined ? { notes: data.notes } : {}),
|
|
67
|
+
...(data.chosen_reason !== undefined
|
|
68
|
+
? { chosen_reason: data.chosen_reason }
|
|
69
|
+
: {}),
|
|
70
|
+
...(data.alternatives_considered !== undefined
|
|
71
|
+
? { alternatives_considered: data.alternatives_considered }
|
|
72
|
+
: {}),
|
|
73
|
+
};
|
|
74
|
+
config.audit_log.push({
|
|
75
|
+
action: 'update_tool',
|
|
76
|
+
tool: args.tool_name,
|
|
77
|
+
timestamp: now,
|
|
78
|
+
reason: data.reason ?? 'Tool details updated',
|
|
79
|
+
});
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
case 'add_evaluation': {
|
|
83
|
+
if (!config.tools.pending_evaluation.some((t) => t.name === args.tool_name) &&
|
|
84
|
+
!config.tools.confirmed.some((t) => t.name === args.tool_name)) {
|
|
85
|
+
const pending = {
|
|
86
|
+
name: args.tool_name,
|
|
87
|
+
category: data.category ?? 'other',
|
|
88
|
+
added_at: now,
|
|
89
|
+
};
|
|
90
|
+
config.tools.pending_evaluation.push(pending);
|
|
91
|
+
}
|
|
92
|
+
config.audit_log.push({
|
|
93
|
+
action: 'add_evaluation',
|
|
94
|
+
tool: args.tool_name,
|
|
95
|
+
timestamp: now,
|
|
96
|
+
reason: data.reason ?? 'Added for evaluation',
|
|
97
|
+
});
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
const updated_config_json = JSON.stringify(config, null, 2);
|
|
102
|
+
return okResult({
|
|
103
|
+
updated_config_json,
|
|
104
|
+
file_path: '.toolpilot/config.json',
|
|
105
|
+
action_applied: args.action,
|
|
106
|
+
tool_name: args.tool_name,
|
|
107
|
+
confirmed_count: config.tools.confirmed.length,
|
|
108
|
+
pending_count: config.tools.pending_evaluation.length,
|
|
109
|
+
instructions: 'Write updated_config_json to .toolpilot/config.json to persist this change.',
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
catch (e) {
|
|
113
|
+
logger.error({ err: e }, 'update_project_config failed');
|
|
114
|
+
return errResult('update_config_error', e instanceof Error ? e.message : String(e));
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=update-project-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-project-config.js","sourceRoot":"","sources":["../../src/tools/update-project-config.ts"],"names":[],"mappings":"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"}
|