@salesforce/mcp 0.15.4 → 0.16.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/lib/assets.d.ts +44 -0
- package/lib/assets.js +126 -0
- package/lib/index.d.ts +1 -1
- package/lib/index.js +3 -0
- package/lib/scripts/build-index.d.ts +1 -0
- package/lib/scripts/build-index.js +124 -0
- package/lib/scripts/create-embedding-text.d.ts +29 -0
- package/lib/scripts/create-embedding-text.js +468 -0
- package/lib/shared/tools.js +1 -1
- package/lib/tools/core/index.d.ts +1 -0
- package/lib/tools/core/index.js +1 -0
- package/lib/tools/core/sf-resume.d.ts +1 -1
- package/lib/tools/core/sf-suggest-cli-command.d.ts +5 -0
- package/lib/tools/core/sf-suggest-cli-command.js +78 -0
- package/lib/tools/dynamic/sf-enable-tool.js +2 -1
- package/lib/tools/dynamic/sf-list-tools.js +9 -4
- package/lib/tools/metadata/sf-deploy-metadata.d.ts +4 -4
- package/lib/tools/orgs/sf-create-org-snapshot.d.ts +1 -1
- package/lib/tools/orgs/sf-create-scratch-org.d.ts +10 -10
- package/lib/tools/testing/sf-test-agents.d.ts +1 -1
- package/lib/tools/testing/sf-test-apex.d.ts +2 -2
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -2
|
@@ -0,0 +1,468 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025, Salesforce, Inc.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Action words - verbs that describe what a command does
|
|
18
|
+
* These should get the highest weight (3x) in embedding text
|
|
19
|
+
*/
|
|
20
|
+
export const SF_ACTION_WORDS = [
|
|
21
|
+
// Core CRUD operations
|
|
22
|
+
'create',
|
|
23
|
+
'generate',
|
|
24
|
+
'delete',
|
|
25
|
+
'update',
|
|
26
|
+
'upsert',
|
|
27
|
+
'get',
|
|
28
|
+
'set',
|
|
29
|
+
'unset',
|
|
30
|
+
// Deployment & sync operations
|
|
31
|
+
'deploy',
|
|
32
|
+
'retrieve',
|
|
33
|
+
'push',
|
|
34
|
+
'pull',
|
|
35
|
+
'sync',
|
|
36
|
+
'convert',
|
|
37
|
+
'validate',
|
|
38
|
+
'preview',
|
|
39
|
+
// Execution operations
|
|
40
|
+
'run',
|
|
41
|
+
'execute',
|
|
42
|
+
'test',
|
|
43
|
+
'start',
|
|
44
|
+
'stop',
|
|
45
|
+
'resume',
|
|
46
|
+
'cancel',
|
|
47
|
+
'quick',
|
|
48
|
+
// Information operations
|
|
49
|
+
'list',
|
|
50
|
+
'display',
|
|
51
|
+
'show',
|
|
52
|
+
'describe',
|
|
53
|
+
'query',
|
|
54
|
+
'search',
|
|
55
|
+
'audit',
|
|
56
|
+
'check',
|
|
57
|
+
// Management operations
|
|
58
|
+
'assign',
|
|
59
|
+
'open',
|
|
60
|
+
'login',
|
|
61
|
+
'logout',
|
|
62
|
+
'install',
|
|
63
|
+
'uninstall',
|
|
64
|
+
'enable',
|
|
65
|
+
'disable',
|
|
66
|
+
'publish',
|
|
67
|
+
'report',
|
|
68
|
+
// Data operations
|
|
69
|
+
'import',
|
|
70
|
+
'export',
|
|
71
|
+
'bulk',
|
|
72
|
+
'tree',
|
|
73
|
+
'results',
|
|
74
|
+
// Package operations
|
|
75
|
+
'promote',
|
|
76
|
+
'demote',
|
|
77
|
+
'version',
|
|
78
|
+
];
|
|
79
|
+
/**
|
|
80
|
+
* Domain words - nouns that represent Salesforce concepts and objects
|
|
81
|
+
* These should get medium weight (2x) in embedding text
|
|
82
|
+
*/
|
|
83
|
+
export const SF_DOMAIN_WORDS = [
|
|
84
|
+
// Core Salesforce concepts
|
|
85
|
+
'org',
|
|
86
|
+
'metadata',
|
|
87
|
+
'project',
|
|
88
|
+
'package',
|
|
89
|
+
'source',
|
|
90
|
+
'data',
|
|
91
|
+
'user',
|
|
92
|
+
'permission',
|
|
93
|
+
'permset',
|
|
94
|
+
'permsetlicense',
|
|
95
|
+
// Development concepts
|
|
96
|
+
'apex',
|
|
97
|
+
'flow',
|
|
98
|
+
'trigger',
|
|
99
|
+
'class',
|
|
100
|
+
'component',
|
|
101
|
+
'lwc',
|
|
102
|
+
'aura',
|
|
103
|
+
'lightning',
|
|
104
|
+
'visualforce',
|
|
105
|
+
'app',
|
|
106
|
+
'tab',
|
|
107
|
+
'field',
|
|
108
|
+
'object',
|
|
109
|
+
'record',
|
|
110
|
+
'sobject',
|
|
111
|
+
// Org types
|
|
112
|
+
'scratch',
|
|
113
|
+
'sandbox',
|
|
114
|
+
'production',
|
|
115
|
+
'devhub',
|
|
116
|
+
'shape',
|
|
117
|
+
'snapshot',
|
|
118
|
+
// Metadata types
|
|
119
|
+
'layout',
|
|
120
|
+
'workflow',
|
|
121
|
+
'validation',
|
|
122
|
+
'rule',
|
|
123
|
+
'profile',
|
|
124
|
+
'role',
|
|
125
|
+
'queue',
|
|
126
|
+
'group',
|
|
127
|
+
'territory',
|
|
128
|
+
'sharing',
|
|
129
|
+
// Testing & analysis
|
|
130
|
+
'test',
|
|
131
|
+
'coverage',
|
|
132
|
+
'log',
|
|
133
|
+
'debug',
|
|
134
|
+
'trace',
|
|
135
|
+
'analyzer',
|
|
136
|
+
'doctor',
|
|
137
|
+
// AI & Agents
|
|
138
|
+
'agent',
|
|
139
|
+
'bot',
|
|
140
|
+
'template',
|
|
141
|
+
'spec',
|
|
142
|
+
'topic',
|
|
143
|
+
'action',
|
|
144
|
+
'evaluation',
|
|
145
|
+
// Data management
|
|
146
|
+
'bulk',
|
|
147
|
+
'tree',
|
|
148
|
+
'query',
|
|
149
|
+
'soql',
|
|
150
|
+
'sosl',
|
|
151
|
+
'csv',
|
|
152
|
+
'json',
|
|
153
|
+
'xml',
|
|
154
|
+
// Package management
|
|
155
|
+
'managed',
|
|
156
|
+
'unlocked',
|
|
157
|
+
'unmanaged',
|
|
158
|
+
'installed',
|
|
159
|
+
'subscriber',
|
|
160
|
+
// Community & Experience
|
|
161
|
+
'community',
|
|
162
|
+
'experience',
|
|
163
|
+
'site',
|
|
164
|
+
'portal',
|
|
165
|
+
// Custom metadata
|
|
166
|
+
'cmdt',
|
|
167
|
+
'custom',
|
|
168
|
+
'standard',
|
|
169
|
+
// Development tools
|
|
170
|
+
'plugin',
|
|
171
|
+
'command',
|
|
172
|
+
'flag',
|
|
173
|
+
'config',
|
|
174
|
+
'alias',
|
|
175
|
+
'autocomplete',
|
|
176
|
+
'help',
|
|
177
|
+
'interactive',
|
|
178
|
+
// API & Integration
|
|
179
|
+
'api',
|
|
180
|
+
'rest',
|
|
181
|
+
'graphql',
|
|
182
|
+
'soap',
|
|
183
|
+
'request',
|
|
184
|
+
'response',
|
|
185
|
+
'endpoint',
|
|
186
|
+
// Analytics
|
|
187
|
+
'analytics',
|
|
188
|
+
'dashboard',
|
|
189
|
+
'report',
|
|
190
|
+
'dataset',
|
|
191
|
+
// DevOps & Pipeline
|
|
192
|
+
'pipeline',
|
|
193
|
+
'devops',
|
|
194
|
+
'branch',
|
|
195
|
+
'git',
|
|
196
|
+
'repository',
|
|
197
|
+
'manifest',
|
|
198
|
+
// File types
|
|
199
|
+
'file',
|
|
200
|
+
'directory',
|
|
201
|
+
'path',
|
|
202
|
+
'zip',
|
|
203
|
+
'archive',
|
|
204
|
+
];
|
|
205
|
+
/**
|
|
206
|
+
* Modifier words - adjectives and adverbs that modify actions
|
|
207
|
+
* These should get light weight (1.5x) in embedding text
|
|
208
|
+
*/
|
|
209
|
+
export const SF_MODIFIER_WORDS = [
|
|
210
|
+
// Action modifiers
|
|
211
|
+
'quick',
|
|
212
|
+
'async',
|
|
213
|
+
'sync',
|
|
214
|
+
'force',
|
|
215
|
+
'dry',
|
|
216
|
+
'preview',
|
|
217
|
+
'validate',
|
|
218
|
+
'check',
|
|
219
|
+
'watch',
|
|
220
|
+
'tail',
|
|
221
|
+
'poll',
|
|
222
|
+
// Scope modifiers
|
|
223
|
+
'all',
|
|
224
|
+
'local',
|
|
225
|
+
'remote',
|
|
226
|
+
'global',
|
|
227
|
+
'default',
|
|
228
|
+
'target',
|
|
229
|
+
'source',
|
|
230
|
+
'current',
|
|
231
|
+
'recent',
|
|
232
|
+
'latest',
|
|
233
|
+
'specific',
|
|
234
|
+
// State modifiers
|
|
235
|
+
'active',
|
|
236
|
+
'inactive',
|
|
237
|
+
'enabled',
|
|
238
|
+
'disabled',
|
|
239
|
+
'tracked',
|
|
240
|
+
'untracked',
|
|
241
|
+
'deployed',
|
|
242
|
+
'pending',
|
|
243
|
+
'failed',
|
|
244
|
+
'successful',
|
|
245
|
+
// Type modifiers
|
|
246
|
+
'managed',
|
|
247
|
+
'unmanaged',
|
|
248
|
+
'unlocked',
|
|
249
|
+
'locked',
|
|
250
|
+
'protected',
|
|
251
|
+
'public',
|
|
252
|
+
'private',
|
|
253
|
+
'shared',
|
|
254
|
+
// Format modifiers
|
|
255
|
+
'formatted',
|
|
256
|
+
'raw',
|
|
257
|
+
'pretty',
|
|
258
|
+
'compact',
|
|
259
|
+
'verbose',
|
|
260
|
+
'concise',
|
|
261
|
+
'detailed',
|
|
262
|
+
'summary',
|
|
263
|
+
];
|
|
264
|
+
/**
|
|
265
|
+
* Context words - structural terms that provide context
|
|
266
|
+
* These should get normal weight (1x) in embedding text
|
|
267
|
+
*/
|
|
268
|
+
export const SF_CONTEXT_WORDS = [
|
|
269
|
+
// Structural
|
|
270
|
+
'force',
|
|
271
|
+
'sf',
|
|
272
|
+
'sfdx',
|
|
273
|
+
'cli',
|
|
274
|
+
'salesforce',
|
|
275
|
+
// Directories
|
|
276
|
+
'app',
|
|
277
|
+
'main',
|
|
278
|
+
'default',
|
|
279
|
+
'classes',
|
|
280
|
+
'objects',
|
|
281
|
+
'layouts',
|
|
282
|
+
'tabs',
|
|
283
|
+
'flows',
|
|
284
|
+
'triggers',
|
|
285
|
+
'components',
|
|
286
|
+
'static',
|
|
287
|
+
'resources',
|
|
288
|
+
// File extensions (without dots)
|
|
289
|
+
'cls',
|
|
290
|
+
'trigger',
|
|
291
|
+
'page',
|
|
292
|
+
'component',
|
|
293
|
+
'app',
|
|
294
|
+
'evt',
|
|
295
|
+
'intf',
|
|
296
|
+
'cmp',
|
|
297
|
+
'design',
|
|
298
|
+
'svg',
|
|
299
|
+
'css',
|
|
300
|
+
'js',
|
|
301
|
+
'xml',
|
|
302
|
+
'meta',
|
|
303
|
+
// Common patterns
|
|
304
|
+
'scratch',
|
|
305
|
+
'def',
|
|
306
|
+
'definition',
|
|
307
|
+
'configuration',
|
|
308
|
+
'settings',
|
|
309
|
+
'preferences',
|
|
310
|
+
'options',
|
|
311
|
+
'parameters',
|
|
312
|
+
'arguments',
|
|
313
|
+
'flags',
|
|
314
|
+
'values',
|
|
315
|
+
];
|
|
316
|
+
/**
|
|
317
|
+
* Synonym mappings for expanding keywords with related terms
|
|
318
|
+
* This helps match user queries that use different but related terminology
|
|
319
|
+
*/
|
|
320
|
+
const SYNONYM_MAP = {
|
|
321
|
+
// Action synonyms
|
|
322
|
+
deploy: ['deployment', 'deploying', 'push', 'upload', 'send'],
|
|
323
|
+
retrieve: ['pull', 'download', 'fetch', 'get', 'sync'],
|
|
324
|
+
list: ['show', 'display', 'enumerate', 'ls', 'view'],
|
|
325
|
+
create: ['make', 'generate', 'new', 'add', 'build'],
|
|
326
|
+
delete: ['remove', 'destroy', 'rm', 'drop', 'erase'],
|
|
327
|
+
update: ['modify', 'change', 'edit', 'alter', 'refresh'],
|
|
328
|
+
run: ['execute', 'start', 'launch', 'invoke'],
|
|
329
|
+
query: ['search', 'find', 'select', 'lookup'],
|
|
330
|
+
open: ['launch', 'start', 'view', 'access'],
|
|
331
|
+
login: ['authenticate', 'auth', 'signin', 'connect'],
|
|
332
|
+
logout: ['disconnect', 'signout', 'unauthenticate'],
|
|
333
|
+
install: ['add', 'setup', 'configure'],
|
|
334
|
+
uninstall: ['remove', 'delete', 'unsetup'],
|
|
335
|
+
convert: ['transform', 'migrate', 'change', 'translate'],
|
|
336
|
+
validate: ['verify', 'check', 'confirm', 'test'],
|
|
337
|
+
preview: ['view', 'show', 'display', 'check'],
|
|
338
|
+
report: ['status', 'info', 'summary', 'details'],
|
|
339
|
+
resume: ['continue', 'restart', 'proceed'],
|
|
340
|
+
cancel: ['stop', 'abort', 'terminate', 'halt'],
|
|
341
|
+
// Domain synonyms
|
|
342
|
+
org: ['organization', 'environment', 'instance', 'tenant'],
|
|
343
|
+
metadata: ['meta', 'components', 'definitions', 'config'],
|
|
344
|
+
scratch: ['dev', 'development', 'temp', 'temporary', 'trial'],
|
|
345
|
+
sandbox: ['test', 'staging', 'non-prod', 'development'],
|
|
346
|
+
production: ['prod', 'live', 'main', 'release'],
|
|
347
|
+
apex: ['code', 'classes', 'triggers', 'programming'],
|
|
348
|
+
flow: ['workflow', 'process', 'automation'],
|
|
349
|
+
component: ['comp', 'lwc', 'aura', 'element'],
|
|
350
|
+
lightning: ['lwc', 'aura', 'web-component'],
|
|
351
|
+
object: ['sobject', 'entity', 'table', 'record-type'],
|
|
352
|
+
field: ['column', 'attribute', 'property'],
|
|
353
|
+
record: ['row', 'data', 'entry', 'item'],
|
|
354
|
+
user: ['person', 'account', 'profile', 'identity'],
|
|
355
|
+
permission: ['access', 'rights', 'privileges', 'security'],
|
|
356
|
+
permset: ['permission-set', 'permissions', 'access-set'],
|
|
357
|
+
package: ['app', 'bundle', 'module', 'extension'],
|
|
358
|
+
source: ['code', 'files', 'project-files'],
|
|
359
|
+
data: ['records', 'information', 'content'],
|
|
360
|
+
test: ['testing', 'tests', 'verification', 'validation'],
|
|
361
|
+
log: ['logs', 'debug', 'trace', 'output'],
|
|
362
|
+
agent: ['bot', 'assistant', 'ai', 'chatbot'],
|
|
363
|
+
template: ['spec', 'blueprint', 'pattern', 'example'],
|
|
364
|
+
manifest: ['package-xml', 'config', 'definition'],
|
|
365
|
+
bulk: ['batch', 'mass', 'multiple', 'many'],
|
|
366
|
+
api: ['service', 'endpoint', 'interface', 'web-service'],
|
|
367
|
+
devhub: ['dev-hub', 'development-hub', 'hub'],
|
|
368
|
+
// Format synonyms
|
|
369
|
+
json: ['javascript-object-notation', 'data'],
|
|
370
|
+
xml: ['markup', 'config', 'meta'],
|
|
371
|
+
csv: ['comma-separated', 'spreadsheet', 'data'],
|
|
372
|
+
// Common user terms
|
|
373
|
+
setup: ['configure', 'install', 'create', 'initialize'],
|
|
374
|
+
config: ['configuration', 'settings', 'preferences'],
|
|
375
|
+
info: ['information', 'details', 'data', 'summary'],
|
|
376
|
+
help: ['assistance', 'documentation', 'guide', 'support'],
|
|
377
|
+
};
|
|
378
|
+
/**
|
|
379
|
+
* Expand a list of keywords with their synonyms
|
|
380
|
+
*/
|
|
381
|
+
function expandWithSynonyms(keywords) {
|
|
382
|
+
const expanded = new Set(keywords);
|
|
383
|
+
keywords.forEach((keyword) => {
|
|
384
|
+
const synonyms = SYNONYM_MAP[keyword];
|
|
385
|
+
if (synonyms) {
|
|
386
|
+
synonyms.forEach((synonym) => expanded.add(synonym));
|
|
387
|
+
}
|
|
388
|
+
});
|
|
389
|
+
return Array.from(expanded);
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Extract keywords from a command string and categorize them
|
|
393
|
+
*/
|
|
394
|
+
function extractKeywords(command) {
|
|
395
|
+
const words = command
|
|
396
|
+
.toLowerCase()
|
|
397
|
+
.split(/[\s:-]+/)
|
|
398
|
+
.filter((word) => word.length > 0);
|
|
399
|
+
return {
|
|
400
|
+
actions: words.filter((word) => SF_ACTION_WORDS.includes(word)),
|
|
401
|
+
domains: words.filter((word) => SF_DOMAIN_WORDS.includes(word)),
|
|
402
|
+
modifiers: words.filter((word) => SF_MODIFIER_WORDS.includes(word)),
|
|
403
|
+
context: words.filter((word) => SF_CONTEXT_WORDS.includes(word)),
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
|
+
/**
|
|
407
|
+
* Create weighted embedding text for a command
|
|
408
|
+
*/
|
|
409
|
+
export function createWeightedEmbeddingText({ command, summary, description, examples, }) {
|
|
410
|
+
const keywords = extractKeywords(command);
|
|
411
|
+
// Expand keywords with synonyms for better matching
|
|
412
|
+
const expandedActions = expandWithSynonyms(keywords.actions);
|
|
413
|
+
const expandedDomains = expandWithSynonyms(keywords.domains);
|
|
414
|
+
const expandedModifiers = expandWithSynonyms(keywords.modifiers);
|
|
415
|
+
// Build weighted sections with cleaner formatting
|
|
416
|
+
const weightedSections = [];
|
|
417
|
+
// Primary actions (3x weight) - space-separated repetitions
|
|
418
|
+
if (keywords.actions.length > 0) {
|
|
419
|
+
const actionWords = keywords.actions.join(' ');
|
|
420
|
+
weightedSections.push(`${actionWords} ${actionWords} ${actionWords}`);
|
|
421
|
+
// Add synonyms (2x weight)
|
|
422
|
+
const synonyms = expandedActions.filter((word) => !keywords.actions.includes(word));
|
|
423
|
+
if (synonyms.length > 0) {
|
|
424
|
+
const synonymText = synonyms.join(' ');
|
|
425
|
+
weightedSections.push(`${synonymText} ${synonymText}`);
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
// Domain objects (2x weight) - space-separated repetitions
|
|
429
|
+
if (keywords.domains.length > 0) {
|
|
430
|
+
const domainWords = keywords.domains.join(' ');
|
|
431
|
+
weightedSections.push(`${domainWords} ${domainWords}`);
|
|
432
|
+
// Add synonyms (1x weight)
|
|
433
|
+
const synonyms = expandedDomains.filter((word) => !keywords.domains.includes(word));
|
|
434
|
+
if (synonyms.length > 0) {
|
|
435
|
+
weightedSections.push(synonyms.join(' '));
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
// Modifiers (1.5x weight - approximate with 1.5 repetitions)
|
|
439
|
+
if (keywords.modifiers.length > 0) {
|
|
440
|
+
const modifierWords = keywords.modifiers.join(' ');
|
|
441
|
+
weightedSections.push(`${modifierWords} ${modifierWords}`);
|
|
442
|
+
// Add modifier synonyms
|
|
443
|
+
const synonyms = expandedModifiers.filter((word) => !keywords.modifiers.includes(word));
|
|
444
|
+
if (synonyms.length > 0) {
|
|
445
|
+
weightedSections.push(synonyms.join(' '));
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
// Natural language expansion
|
|
449
|
+
if (keywords.actions.length > 0 && keywords.domains.length > 0) {
|
|
450
|
+
const primaryAction = keywords.actions[0];
|
|
451
|
+
const primaryDomain = keywords.domains[0];
|
|
452
|
+
// Core action-domain pairs
|
|
453
|
+
weightedSections.push(`${primaryAction} ${primaryDomain}`);
|
|
454
|
+
weightedSections.push(`how to ${primaryAction} ${primaryDomain}`);
|
|
455
|
+
// Add top synonym variations for better natural language matching
|
|
456
|
+
const actionSynonyms = SYNONYM_MAP[primaryAction];
|
|
457
|
+
const domainSynonyms = SYNONYM_MAP[primaryDomain];
|
|
458
|
+
if (actionSynonyms && actionSynonyms.length > 0) {
|
|
459
|
+
weightedSections.push(`${actionSynonyms[0]} ${primaryDomain}`);
|
|
460
|
+
}
|
|
461
|
+
if (domainSynonyms && domainSynonyms.length > 0) {
|
|
462
|
+
weightedSections.push(`${primaryAction} ${domainSynonyms[0]}`);
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
// Include natural content for semantic understanding
|
|
466
|
+
return `${weightedSections.join(' ')}\n\nCommand: ${command}\nSummary: ${summary}\n\nDescription: ${description}\n\nExamples:\n${examples?.join('\n') ?? 'No examples available'}`;
|
|
467
|
+
}
|
|
468
|
+
//# sourceMappingURL=create-embedding-text.js.map
|
package/lib/shared/tools.js
CHANGED
|
@@ -18,7 +18,7 @@ export const TOOLSETS = ['orgs', 'data', 'users', 'metadata', 'testing', 'experi
|
|
|
18
18
|
/*
|
|
19
19
|
* These are tools that are always enabled at startup. They cannot be disabled and they cannot be dynamically enabled.
|
|
20
20
|
*/
|
|
21
|
-
export const CORE_TOOLS = ['sf-get-username', 'sf-resume', 'sf-enable-tool', 'sf-list-tools'];
|
|
21
|
+
export const CORE_TOOLS = ['sf-get-username', 'sf-resume', 'sf-enable-tool', 'sf-list-tools', 'sf-suggest-cli-command'];
|
|
22
22
|
/**
|
|
23
23
|
* Determines which toolsets should be enabled based on the provided toolsets array and dynamic tools flag.
|
|
24
24
|
*
|
package/lib/tools/core/index.js
CHANGED
|
@@ -6,9 +6,9 @@ export declare const resumeParamsSchema: z.ZodObject<{
|
|
|
6
6
|
usernameOrAlias: z.ZodString;
|
|
7
7
|
directory: z.ZodEffects<z.ZodString, string, string>;
|
|
8
8
|
}, "strip", z.ZodTypeAny, {
|
|
9
|
-
wait: number;
|
|
10
9
|
directory: string;
|
|
11
10
|
jobId: string;
|
|
11
|
+
wait: number;
|
|
12
12
|
usernameOrAlias: string;
|
|
13
13
|
}, {
|
|
14
14
|
directory: string;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025, Salesforce, Inc.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
import { z } from 'zod';
|
|
17
|
+
import { getAssets } from '../../assets.js';
|
|
18
|
+
import { textResponse } from '../../shared/utils.js';
|
|
19
|
+
const suggestCliCommandParamsSchema = z.object({
|
|
20
|
+
query: z.string().describe('The natural language query to suggest an `sf` command'),
|
|
21
|
+
});
|
|
22
|
+
/**
|
|
23
|
+
* Suggest a Salesforce CLI (sf) command based on user input.
|
|
24
|
+
*/
|
|
25
|
+
export const registerToolSuggestCliCommand = (server) => {
|
|
26
|
+
server.tool('sf-suggest-cli-command', "Suggests an `sf` CLI command based on a natural language query. It finds relevant commands from a local index and uses an LLM to construct the final, precise command to fulfill the user's request. Use this tool whenever a user asks for guidance on how to use the Salesforce CLI (`sf` or `sfdx`), needs help with command syntax, wants to know what command to run for a specific task, or asks questions like 'how do I...', 'what command...', or 'how to...' related to Salesforce development operations.", suggestCliCommandParamsSchema.shape, {
|
|
27
|
+
readOnlyHint: true,
|
|
28
|
+
}, async ({ query }) => {
|
|
29
|
+
const assets = await getAssets();
|
|
30
|
+
// Embed the user query
|
|
31
|
+
const queryEmbedding = await assets.embedder(query, {
|
|
32
|
+
pooling: 'mean',
|
|
33
|
+
normalize: true,
|
|
34
|
+
});
|
|
35
|
+
// Perform Semantic Search (FAISS)
|
|
36
|
+
const searchResults = assets.faissIndex.search(
|
|
37
|
+
// Convert the embedding tensor data to a flat array of numbers
|
|
38
|
+
Array.from(queryEmbedding.data), 5);
|
|
39
|
+
const topCandidateIds = searchResults.labels.slice(0, 5);
|
|
40
|
+
const contextCommands = topCandidateIds.map((id) => {
|
|
41
|
+
const command = assets.commands.find((c) => c.id === id);
|
|
42
|
+
// Remove the embedding text to avoid sending it to the LLM
|
|
43
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
44
|
+
const { embeddingText, ...commandWithoutEmbeddingText } = command;
|
|
45
|
+
return commandWithoutEmbeddingText;
|
|
46
|
+
});
|
|
47
|
+
contextCommands.forEach((command, index) => {
|
|
48
|
+
// eslint-disable-next-line no-console
|
|
49
|
+
console.error(`Command: ${command.command}, Score: ${searchResults.distances[index]}`);
|
|
50
|
+
});
|
|
51
|
+
const prompt = `System: You are a precise expert on the Salesforce CLI (sf). Your sole purpose is to construct a single, valid sf command based on the user's request and the Command Reference provided.
|
|
52
|
+
- Base your answer STRICTLY on the user's request and the Command Reference.
|
|
53
|
+
- If there is no command that matches the user's request, tell the user that you cannot find a command.
|
|
54
|
+
- Do not use any flags or commands not listed in the reference.
|
|
55
|
+
|
|
56
|
+
User Request:
|
|
57
|
+
"${query}"
|
|
58
|
+
|
|
59
|
+
Command Reference:
|
|
60
|
+
${JSON.stringify(contextCommands, null, 2)}
|
|
61
|
+
|
|
62
|
+
Notes about Flag Properties:
|
|
63
|
+
- multiple: Flags that support multiple values should be specified with the '--flag value1 --flag value2' syntax.
|
|
64
|
+
- dependsOn: If a flag depends on another flag, ensure that the dependent flag is included in the command.
|
|
65
|
+
- atLeastOne: If a flag requires at least one of a set of flags, ensure that at least one of those flags is included in the command.
|
|
66
|
+
- exactlyOne: If a flag requires exactly one of a set of flags, ensure that exactly one of those flags is included in the command.
|
|
67
|
+
- exclusive: If a flag is exclusive with another flag, ensure that only one of those flags is included in the command.
|
|
68
|
+
- required: If a flag is required, ensure that it is included in the command unless it has a default value.
|
|
69
|
+
- relationships: If a flag has relationships with other flags, ensure that those relationships are respected in the command.
|
|
70
|
+
- options: If a flag has options, ensure that one of those options is used
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
Synthesize the single "sf" command that best fulfills the user's request.
|
|
74
|
+
`;
|
|
75
|
+
return textResponse(prompt);
|
|
76
|
+
});
|
|
77
|
+
};
|
|
78
|
+
//# sourceMappingURL=sf-suggest-cli-command.js.map
|
|
@@ -23,7 +23,8 @@ export function registerToolEnableTool(server) {
|
|
|
23
23
|
server.tool('sf-enable-tool', `Enable one of the tools the Salesforce MCP server provides.
|
|
24
24
|
|
|
25
25
|
AGENT INSTRUCTIONS:
|
|
26
|
-
|
|
26
|
+
Use sf-list-all-tools first to learn what tools are available for enabling.
|
|
27
|
+
Once you have enabled the tool, you MUST invoke that tool to accomplish the user's original request - DO NOT USE A DIFFERENT TOOL OR THE COMMAND LINE.`, enableToolParamsSchema.shape, {
|
|
27
28
|
title: 'Enable an individual tool',
|
|
28
29
|
readOnlyHint: true,
|
|
29
30
|
openWorldHint: false,
|
|
@@ -19,10 +19,15 @@ export function registerToolListTools(server) {
|
|
|
19
19
|
server.tool('sf-list-tools', `List all available tools this Salesforce MCP server can offer, providing the enabled status and description of each.
|
|
20
20
|
|
|
21
21
|
AGENT INSTRUCTIONS:
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
DO NOT USE THIS TOOL if you already know what tool you need - try to call the tool directly first.
|
|
23
|
+
ONLY use this tool if:
|
|
24
|
+
1. You tried to call a tool and got an error that it doesn't exist or isn't enabled
|
|
25
|
+
2. You genuinely don't know what tools are available for a specific task
|
|
26
|
+
3. You need to discover new tools for an unfamiliar use case
|
|
27
|
+
|
|
28
|
+
If you find a tool you want to enable, call sf-enable-tool with the tool name.
|
|
29
|
+
Once you have enabled the tool, you MUST invoke that tool to accomplish the user's original request - DO NOT USE A DIFFERENT TOOL OR THE COMMAND LINE.
|
|
30
|
+
Once a tool has been enabled, you do not need to call sf-list-tools again - instead, invoke the desired tool directly.`, {
|
|
26
31
|
title: 'List all individual tools',
|
|
27
32
|
readOnlyHint: true,
|
|
28
33
|
openWorldHint: false,
|
|
@@ -10,16 +10,16 @@ declare const deployMetadataParams: z.ZodObject<{
|
|
|
10
10
|
}, "strip", z.ZodTypeAny, {
|
|
11
11
|
directory: string;
|
|
12
12
|
usernameOrAlias: string;
|
|
13
|
-
manifest?: string | undefined;
|
|
14
13
|
sourceDir?: string[] | undefined;
|
|
15
|
-
|
|
14
|
+
manifest?: string | undefined;
|
|
15
|
+
apexTestLevel?: "NoTestRun" | "RunLocalTests" | "RunAllTestsInOrg" | undefined;
|
|
16
16
|
apexTests?: string[] | undefined;
|
|
17
17
|
}, {
|
|
18
18
|
directory: string;
|
|
19
19
|
usernameOrAlias: string;
|
|
20
|
-
manifest?: string | undefined;
|
|
21
20
|
sourceDir?: string[] | undefined;
|
|
22
|
-
|
|
21
|
+
manifest?: string | undefined;
|
|
22
|
+
apexTestLevel?: "NoTestRun" | "RunLocalTests" | "RunAllTestsInOrg" | undefined;
|
|
23
23
|
apexTests?: string[] | undefined;
|
|
24
24
|
}>;
|
|
25
25
|
export type DeployMetadata = z.infer<typeof deployMetadataParams>;
|
|
@@ -16,8 +16,8 @@ export declare const createOrgSnapshotParams: z.ZodObject<{
|
|
|
16
16
|
directory: string;
|
|
17
17
|
devHub: string;
|
|
18
18
|
sourceOrg: string;
|
|
19
|
-
description?: string | undefined;
|
|
20
19
|
name?: string | undefined;
|
|
20
|
+
description?: string | undefined;
|
|
21
21
|
}>;
|
|
22
22
|
export type CreateOrgSnapshotOptions = z.infer<typeof createOrgSnapshotParams>;
|
|
23
23
|
export declare const registerToolCreateOrgSnapshot: (server: McpServer) => void;
|