@salesforce/mcp 0.15.3 → 0.16.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/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/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
package/README.md
CHANGED
|
@@ -55,7 +55,7 @@ But you're not limited to using only VS Code and Copilot! You can [configure man
|
|
|
55
55
|
|
|
56
56
|
For the best getting-started experience, make sure that you have a Salesforce DX environment set up on your computer. In particular:
|
|
57
57
|
|
|
58
|
-
- [Install Salesforce CLI](https://developer.salesforce.com/docs/atlas.en-us.sfdx_setup.meta/sfdx_setup/sfdx_setup_intro.htm) on your computer.
|
|
58
|
+
- [Install Salesforce CLI](https://developer.salesforce.com/docs/atlas.en-us.sfdx_setup.meta/sfdx_setup/sfdx_setup_intro.htm) on your computer.
|
|
59
59
|
- [Install VS Code](https://code.visualstudio.com/docs) on your computer.
|
|
60
60
|
- [Create a Salesforce DX project](https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_ws_create_new.htm) and open it in VS Code. You can also clone an example repo, such as [dreamhouse-lwc](https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_intro_sample_repo.htm), which is a ready-to-use DX project that contains a simple Salesforce application, with metadata and test data.
|
|
61
61
|
- [Authorize at least one Salesforce org](https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_auth_web_flow.htm) to use with your DX project. You can also create a scratch org.
|
package/lib/assets.d.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import faiss from 'faiss-node';
|
|
2
|
+
import { FeatureExtractionPipeline } from '@huggingface/transformers';
|
|
3
|
+
type CommandData = {
|
|
4
|
+
id: number;
|
|
5
|
+
command: string;
|
|
6
|
+
summary: string;
|
|
7
|
+
description: string;
|
|
8
|
+
examples?: string[];
|
|
9
|
+
flags?: Array<{
|
|
10
|
+
name: string;
|
|
11
|
+
description: string;
|
|
12
|
+
type?: string;
|
|
13
|
+
required?: boolean;
|
|
14
|
+
options?: string[];
|
|
15
|
+
atLeastOne?: boolean;
|
|
16
|
+
exactlyOne?: boolean;
|
|
17
|
+
relationships?: string[];
|
|
18
|
+
default?: string | boolean | number | string[];
|
|
19
|
+
}>;
|
|
20
|
+
embeddingText: string;
|
|
21
|
+
};
|
|
22
|
+
type Assets = {
|
|
23
|
+
commands: CommandData[];
|
|
24
|
+
commandNames: string[];
|
|
25
|
+
faissIndex: faiss.IndexFlatL2;
|
|
26
|
+
embedder: FeatureExtractionPipeline;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Conditionally builds or rebuilds a FAISS index based on its existence and age.
|
|
30
|
+
*
|
|
31
|
+
* This function checks if a FAISS index file exists in the specified output directory.
|
|
32
|
+
* If the index exists but is older than one week, it triggers a rebuild. If the index
|
|
33
|
+
* doesn't exist, it initiates the initial build process. The build process can run as a
|
|
34
|
+
* detached child process or in the same process depending on the detached parameter.
|
|
35
|
+
*
|
|
36
|
+
* @param outputDir - The directory path where the FAISS index should be located or created
|
|
37
|
+
* @param detached - Whether to run the build process detached (default: true)
|
|
38
|
+
*
|
|
39
|
+
* @remarks
|
|
40
|
+
* - Sets the global CACHED_DATA_DIR variable to the provided outputDir. This is used to locate the index file.
|
|
41
|
+
*/
|
|
42
|
+
export declare function maybeBuildIndex(outputDir: string, detached?: boolean): Promise<void>;
|
|
43
|
+
export declare function getAssets(): Promise<Assets>;
|
|
44
|
+
export {};
|
package/lib/assets.js
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
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 fs from 'node:fs';
|
|
17
|
+
import { resolve, join } from 'node:path';
|
|
18
|
+
import { spawn } from 'node:child_process';
|
|
19
|
+
import faiss from 'faiss-node';
|
|
20
|
+
import { pipeline } from '@huggingface/transformers';
|
|
21
|
+
import { ux } from '@oclif/core';
|
|
22
|
+
let CACHED_DATA_DIR = null;
|
|
23
|
+
/**
|
|
24
|
+
* Conditionally builds or rebuilds a FAISS index based on its existence and age.
|
|
25
|
+
*
|
|
26
|
+
* This function checks if a FAISS index file exists in the specified output directory.
|
|
27
|
+
* If the index exists but is older than one week, it triggers a rebuild. If the index
|
|
28
|
+
* doesn't exist, it initiates the initial build process. The build process can run as a
|
|
29
|
+
* detached child process or in the same process depending on the detached parameter.
|
|
30
|
+
*
|
|
31
|
+
* @param outputDir - The directory path where the FAISS index should be located or created
|
|
32
|
+
* @param detached - Whether to run the build process detached (default: true)
|
|
33
|
+
*
|
|
34
|
+
* @remarks
|
|
35
|
+
* - Sets the global CACHED_DATA_DIR variable to the provided outputDir. This is used to locate the index file.
|
|
36
|
+
*/
|
|
37
|
+
export async function maybeBuildIndex(outputDir, detached = true) {
|
|
38
|
+
CACHED_DATA_DIR = outputDir;
|
|
39
|
+
const faissIndexPath = join(outputDir, 'faiss-index.bin');
|
|
40
|
+
try {
|
|
41
|
+
const stats = fs.statSync(faissIndexPath);
|
|
42
|
+
const oneWeekAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000);
|
|
43
|
+
ux.stderr(`Checking FAISS index in ${outputDir}...`);
|
|
44
|
+
ux.stderr(`Last modified: ${stats.mtime.toString()}`);
|
|
45
|
+
if (stats.mtime < oneWeekAgo) {
|
|
46
|
+
ux.stderr(`FAISS index is more than 1 week old - rebuilding in ${outputDir}...`);
|
|
47
|
+
await spawnBuildScript(outputDir, detached);
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
ux.stderr(`FAISS index is up to date in ${outputDir}. No rebuild needed.`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
// File doesn't exist, so build the index
|
|
55
|
+
ux.stderr(`Building FAISS index in ${outputDir}...`);
|
|
56
|
+
await spawnBuildScript(outputDir, detached);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function spawnBuildScript(outputDir, detached) {
|
|
60
|
+
const scriptPath = resolve(import.meta.dirname, 'scripts', 'build-index.js');
|
|
61
|
+
const args = [scriptPath, outputDir];
|
|
62
|
+
if (detached) {
|
|
63
|
+
spawn('node', args, {
|
|
64
|
+
detached: true,
|
|
65
|
+
stdio: 'ignore',
|
|
66
|
+
}).unref();
|
|
67
|
+
return Promise.resolve();
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
return new Promise((res, reject) => {
|
|
71
|
+
const childProcess = spawn('node', args, {
|
|
72
|
+
stdio: 'inherit',
|
|
73
|
+
});
|
|
74
|
+
childProcess.on('close', (code) => {
|
|
75
|
+
if (code === 0) {
|
|
76
|
+
res();
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
reject(new Error(`Build script exited with code ${code ?? 'UNKNOWN'}`));
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
childProcess.on('error', (error) => {
|
|
83
|
+
reject(error);
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
export async function getAssets() {
|
|
89
|
+
if (!CACHED_DATA_DIR) {
|
|
90
|
+
throw new Error('Data directory not set. Please call maybeBuildIndex first.');
|
|
91
|
+
}
|
|
92
|
+
// Ensure the index is built or rebuilt if necessary
|
|
93
|
+
await maybeBuildIndex(CACHED_DATA_DIR, false);
|
|
94
|
+
const commandsPath = join(CACHED_DATA_DIR, 'sf-commands.json');
|
|
95
|
+
const faissIndexPath = join(CACHED_DATA_DIR, 'faiss-index.bin');
|
|
96
|
+
try {
|
|
97
|
+
await fs.promises.access(commandsPath);
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
throw new Error(`Commands file not found at ${commandsPath}. Please run maybeBuildIndex to build the index.`);
|
|
101
|
+
}
|
|
102
|
+
try {
|
|
103
|
+
await fs.promises.access(faissIndexPath);
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
throw new Error(`FAISS index not found at ${faissIndexPath}. Please run maybeBuildIndex to build the index.`);
|
|
107
|
+
}
|
|
108
|
+
try {
|
|
109
|
+
const commandsData = await fs.promises.readFile(commandsPath, 'utf-8');
|
|
110
|
+
const commands = JSON.parse(commandsData);
|
|
111
|
+
const faissIndex = faiss.IndexFlatL2.read(faissIndexPath);
|
|
112
|
+
const embedder = await pipeline('feature-extraction', 'Xenova/all-MiniLM-L6-v2', {
|
|
113
|
+
dtype: 'fp32',
|
|
114
|
+
});
|
|
115
|
+
return {
|
|
116
|
+
commands,
|
|
117
|
+
commandNames: commands.map((cmd) => cmd.command),
|
|
118
|
+
faissIndex,
|
|
119
|
+
embedder,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
throw new Error(`Failed to load assets: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=assets.js.map
|
package/lib/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ export default class McpServerCommand extends Command {
|
|
|
4
4
|
static description: string;
|
|
5
5
|
static flags: {
|
|
6
6
|
orgs: import("@oclif/core/interfaces").OptionFlag<string[], import("@oclif/core/interfaces").CustomOptions>;
|
|
7
|
-
toolsets: import("@oclif/core/interfaces").OptionFlag<("
|
|
7
|
+
toolsets: import("@oclif/core/interfaces").OptionFlag<("all" | "users" | "data" | "orgs" | "metadata" | "testing" | "experimental")[] | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
8
|
version: import("@oclif/core/interfaces").BooleanFlag<void>;
|
|
9
9
|
'no-telemetry': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
10
|
debug: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
package/lib/index.js
CHANGED
|
@@ -26,6 +26,7 @@ import * as dynamic from './tools/dynamic/index.js';
|
|
|
26
26
|
import Cache from './shared/cache.js';
|
|
27
27
|
import { Telemetry } from './telemetry.js';
|
|
28
28
|
import { SfMcpServer } from './sf-mcp-server.js';
|
|
29
|
+
import { maybeBuildIndex } from './assets.js';
|
|
29
30
|
import { determineToolsetsToEnable, TOOLSETS } from './shared/tools.js';
|
|
30
31
|
/**
|
|
31
32
|
* Sanitizes an array of org usernames by replacing specific orgs with a placeholder.
|
|
@@ -138,6 +139,7 @@ You can also use special values to control access to orgs:
|
|
|
138
139
|
telemetry: this.telemetry,
|
|
139
140
|
dynamicTools: flags['dynamic-tools'] ?? false,
|
|
140
141
|
});
|
|
142
|
+
await maybeBuildIndex(this.config.dataDir);
|
|
141
143
|
const toolsetsToEnable = determineToolsetsToEnable(flags.toolsets ?? ['all'], flags['dynamic-tools'] ?? false);
|
|
142
144
|
// ************************
|
|
143
145
|
// CORE TOOLS (always on)
|
|
@@ -150,6 +152,7 @@ You can also use special values to control access to orgs:
|
|
|
150
152
|
// get username
|
|
151
153
|
core.registerToolGetUsername(server);
|
|
152
154
|
core.registerToolResume(server);
|
|
155
|
+
core.registerToolSuggestCliCommand(server);
|
|
153
156
|
// DYNAMIC TOOLSETS
|
|
154
157
|
// ************************
|
|
155
158
|
if (toolsetsToEnable.dynamic) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,124 @@
|
|
|
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 { execSync } from 'node:child_process';
|
|
17
|
+
import fs from 'node:fs';
|
|
18
|
+
import path from 'node:path';
|
|
19
|
+
import { Args, Parser, ux } from '@oclif/core';
|
|
20
|
+
import { pipeline } from '@huggingface/transformers';
|
|
21
|
+
import faiss from 'faiss-node';
|
|
22
|
+
import { createWeightedEmbeddingText } from './create-embedding-text.js';
|
|
23
|
+
const normalizeCommandName = (command) => (command ?? '').split(':').join(' ');
|
|
24
|
+
const main = async () => {
|
|
25
|
+
const { args: { outputDir }, } = await Parser.parse(process.argv.slice(2), {
|
|
26
|
+
args: {
|
|
27
|
+
outputDir: Args.string({
|
|
28
|
+
description: 'Directory to save the output files',
|
|
29
|
+
required: true,
|
|
30
|
+
}),
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
if (!outputDir) {
|
|
34
|
+
ux.stderr('Output directory not specified. Please provide a path as the first argument.');
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
37
|
+
// Define the output file paths
|
|
38
|
+
const commandsPath = path.join(outputDir, 'sf-commands.json');
|
|
39
|
+
const faissIndexPath = path.join(outputDir, 'faiss-index.bin');
|
|
40
|
+
ux.stderr('Starting offline data preparation...');
|
|
41
|
+
// 1. Ensure output directory exists
|
|
42
|
+
if (!fs.existsSync(outputDir)) {
|
|
43
|
+
fs.mkdirSync(outputDir);
|
|
44
|
+
}
|
|
45
|
+
// 2. Get Command Data from Salesforce CLI
|
|
46
|
+
ux.stderr('Fetching commands from sf CLI...');
|
|
47
|
+
const rawCommandsJson = execSync('sf commands --json').toString();
|
|
48
|
+
const rawCommands = JSON.parse(rawCommandsJson);
|
|
49
|
+
// 3. Process and Clean the Data
|
|
50
|
+
ux.stderr('Processing and cleaning command data...');
|
|
51
|
+
const commandsData = rawCommands.map((cmd, index) => ({
|
|
52
|
+
id: index, // Use our own sequential ID for FAISS
|
|
53
|
+
command: normalizeCommandName(cmd.id),
|
|
54
|
+
summary: cmd.summary ?? 'No summary available.',
|
|
55
|
+
description: cmd.description ?? 'No description available.',
|
|
56
|
+
examples: cmd.examples ?? [],
|
|
57
|
+
flags: Object.values(cmd.flags ?? {})
|
|
58
|
+
.filter((flag) => !flag.hidden)
|
|
59
|
+
.map((flag) => ({
|
|
60
|
+
name: flag.name,
|
|
61
|
+
summary: flag.summary ?? 'No summary available.',
|
|
62
|
+
description: flag.description ?? 'No description available.',
|
|
63
|
+
type: flag.type ?? 'string',
|
|
64
|
+
required: flag.required ?? false,
|
|
65
|
+
// @ts-expect-error because options doesn't exist on boolean flags
|
|
66
|
+
options: (flag.options ?? []),
|
|
67
|
+
// @ts-expect-error because multiple doesn't exist on boolean flags
|
|
68
|
+
multiple: !!flag.multiple,
|
|
69
|
+
dependsOn: flag.dependsOn,
|
|
70
|
+
exclusive: flag.exclusive,
|
|
71
|
+
atLeastOne: flag.atLeastOne,
|
|
72
|
+
exactlyOne: flag.exactlyOne,
|
|
73
|
+
relationships: flag.relationships,
|
|
74
|
+
default: flag.default,
|
|
75
|
+
})),
|
|
76
|
+
// Create a more descriptive text for better embedding quality
|
|
77
|
+
// This will be stripped from the final output sent to the LLM to save token count
|
|
78
|
+
embeddingText: createWeightedEmbeddingText({
|
|
79
|
+
command: normalizeCommandName(cmd.id),
|
|
80
|
+
summary: cmd.summary ?? '',
|
|
81
|
+
description: cmd.description ?? '',
|
|
82
|
+
examples: cmd.examples ?? [],
|
|
83
|
+
}),
|
|
84
|
+
}));
|
|
85
|
+
if (commandsData.length === 0) {
|
|
86
|
+
ux.stderr('No command data could be processed. Is `sf` CLI installed and working?');
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
ux.stderr(`Processed ${commandsData.length} commands.`);
|
|
90
|
+
// 4. Generate Embeddings
|
|
91
|
+
ux.stderr('Loading embedding model... (This may take a moment)');
|
|
92
|
+
const embedder = await pipeline('feature-extraction', 'Xenova/all-MiniLM-L6-v2', {
|
|
93
|
+
dtype: 'fp32',
|
|
94
|
+
});
|
|
95
|
+
ux.stderr('Generating embeddings for all commands...');
|
|
96
|
+
const embeddings = await Promise.all(commandsData.map((cmd) => embedder(cmd.embeddingText, { pooling: 'mean', normalize: true })));
|
|
97
|
+
// The output tensor needs to be converted to a flat Float32Array for FAISS
|
|
98
|
+
const embeddingDimension = embeddings[0].dims[1];
|
|
99
|
+
const flattenedEmbeddings = new Float32Array(commandsData.length * embeddingDimension);
|
|
100
|
+
embeddings.forEach((tensor, i) => {
|
|
101
|
+
flattenedEmbeddings.set(tensor.data, i * embeddingDimension);
|
|
102
|
+
});
|
|
103
|
+
ux.stderr(`Generated embeddings with dimension: ${embeddingDimension}`);
|
|
104
|
+
// 5. Build and Save the FAISS Index
|
|
105
|
+
ux.stderr('Building FAISS index...');
|
|
106
|
+
const index = new faiss.IndexFlatL2(embeddingDimension);
|
|
107
|
+
// Convert Float32Array to regular array for faiss-node
|
|
108
|
+
const embeddingsArray = Array.from(flattenedEmbeddings);
|
|
109
|
+
index.add(embeddingsArray);
|
|
110
|
+
const vectorCount = index.ntotal();
|
|
111
|
+
ux.stderr(`FAISS index built with ${String(vectorCount)} vectors.`);
|
|
112
|
+
// Use the correct method name for faiss-node
|
|
113
|
+
index.write(faissIndexPath);
|
|
114
|
+
ux.stderr(`FAISS index saved to: ${faissIndexPath}`);
|
|
115
|
+
// 6. Save the Processed Command Data
|
|
116
|
+
fs.writeFileSync(commandsPath, JSON.stringify(commandsData, null, 2));
|
|
117
|
+
ux.stderr(`Command data saved to: ${commandsPath}`);
|
|
118
|
+
ux.stderr('Offline preparation complete!');
|
|
119
|
+
};
|
|
120
|
+
main().catch((error) => {
|
|
121
|
+
// eslint-disable-next-line no-console
|
|
122
|
+
console.error(error);
|
|
123
|
+
});
|
|
124
|
+
//# sourceMappingURL=build-index.js.map
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Action words - verbs that describe what a command does
|
|
3
|
+
* These should get the highest weight (3x) in embedding text
|
|
4
|
+
*/
|
|
5
|
+
export declare const SF_ACTION_WORDS: readonly string[];
|
|
6
|
+
/**
|
|
7
|
+
* Domain words - nouns that represent Salesforce concepts and objects
|
|
8
|
+
* These should get medium weight (2x) in embedding text
|
|
9
|
+
*/
|
|
10
|
+
export declare const SF_DOMAIN_WORDS: readonly string[];
|
|
11
|
+
/**
|
|
12
|
+
* Modifier words - adjectives and adverbs that modify actions
|
|
13
|
+
* These should get light weight (1.5x) in embedding text
|
|
14
|
+
*/
|
|
15
|
+
export declare const SF_MODIFIER_WORDS: readonly string[];
|
|
16
|
+
/**
|
|
17
|
+
* Context words - structural terms that provide context
|
|
18
|
+
* These should get normal weight (1x) in embedding text
|
|
19
|
+
*/
|
|
20
|
+
export declare const SF_CONTEXT_WORDS: readonly string[];
|
|
21
|
+
/**
|
|
22
|
+
* Create weighted embedding text for a command
|
|
23
|
+
*/
|
|
24
|
+
export declare function createWeightedEmbeddingText({ command, summary, description, examples, }: {
|
|
25
|
+
command: string;
|
|
26
|
+
summary: string;
|
|
27
|
+
description: string;
|
|
28
|
+
examples: string[];
|
|
29
|
+
}): string;
|