@copilotkit/pathfinder 1.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/.env.example +20 -0
- package/.superpowers/brainstorm/47098-1775507869/content/homepage-mockup.html +324 -0
- package/.superpowers/brainstorm/47098-1775507869/state/server-stopped +1 -0
- package/.superpowers/brainstorm/47098-1775507869/state/server.log +13 -0
- package/.superpowers/brainstorm/47098-1775507869/state/server.pid +1 -0
- package/.superpowers/brainstorm/82141-1775511032/content/migration-v2.html +340 -0
- package/.superpowers/brainstorm/82141-1775511032/content/migration.html +340 -0
- package/.superpowers/brainstorm/82141-1775511032/state/server-stopped +1 -0
- package/.superpowers/brainstorm/82141-1775511032/state/server.log +4 -0
- package/.superpowers/brainstorm/82141-1775511032/state/server.pid +1 -0
- package/CHANGELOG.md +26 -0
- package/LICENSE +21 -0
- package/README.md +284 -0
- package/dist/config.d.ts +32 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +180 -0
- package/dist/config.js.map +1 -0
- package/dist/db/client.d.ts +22 -0
- package/dist/db/client.d.ts.map +1 -0
- package/dist/db/client.js +134 -0
- package/dist/db/client.js.map +1 -0
- package/dist/db/queries.d.ts +51 -0
- package/dist/db/queries.d.ts.map +1 -0
- package/dist/db/queries.js +271 -0
- package/dist/db/queries.js.map +1 -0
- package/dist/db/schema.d.ts +11 -0
- package/dist/db/schema.d.ts.map +1 -0
- package/dist/db/schema.js +63 -0
- package/dist/db/schema.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +366 -0
- package/dist/index.js.map +1 -0
- package/dist/indexing/chunking/code.d.ts +17 -0
- package/dist/indexing/chunking/code.d.ts.map +1 -0
- package/dist/indexing/chunking/code.js +277 -0
- package/dist/indexing/chunking/code.js.map +1 -0
- package/dist/indexing/chunking/index.d.ts +6 -0
- package/dist/indexing/chunking/index.d.ts.map +1 -0
- package/dist/indexing/chunking/index.js +19 -0
- package/dist/indexing/chunking/index.js.map +1 -0
- package/dist/indexing/chunking/markdown.d.ts +16 -0
- package/dist/indexing/chunking/markdown.d.ts.map +1 -0
- package/dist/indexing/chunking/markdown.js +283 -0
- package/dist/indexing/chunking/markdown.js.map +1 -0
- package/dist/indexing/chunking/raw-text.d.ts +11 -0
- package/dist/indexing/chunking/raw-text.d.ts.map +1 -0
- package/dist/indexing/chunking/raw-text.js +59 -0
- package/dist/indexing/chunking/raw-text.js.map +1 -0
- package/dist/indexing/embeddings.d.ts +10 -0
- package/dist/indexing/embeddings.d.ts.map +1 -0
- package/dist/indexing/embeddings.js +78 -0
- package/dist/indexing/embeddings.js.map +1 -0
- package/dist/indexing/orchestrator.d.ts +69 -0
- package/dist/indexing/orchestrator.d.ts.map +1 -0
- package/dist/indexing/orchestrator.js +387 -0
- package/dist/indexing/orchestrator.js.map +1 -0
- package/dist/indexing/source-indexer.d.ts +68 -0
- package/dist/indexing/source-indexer.d.ts.map +1 -0
- package/dist/indexing/source-indexer.js +379 -0
- package/dist/indexing/source-indexer.js.map +1 -0
- package/dist/indexing/url-derivation.d.ts +7 -0
- package/dist/indexing/url-derivation.d.ts.map +1 -0
- package/dist/indexing/url-derivation.js +31 -0
- package/dist/indexing/url-derivation.js.map +1 -0
- package/dist/mcp/server.d.ts +10 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +67 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools/bash-fs.d.ts +19 -0
- package/dist/mcp/tools/bash-fs.d.ts.map +1 -0
- package/dist/mcp/tools/bash-fs.js +134 -0
- package/dist/mcp/tools/bash-fs.js.map +1 -0
- package/dist/mcp/tools/bash-grep.d.ts +29 -0
- package/dist/mcp/tools/bash-grep.d.ts.map +1 -0
- package/dist/mcp/tools/bash-grep.js +153 -0
- package/dist/mcp/tools/bash-grep.js.map +1 -0
- package/dist/mcp/tools/bash-related.d.ts +14 -0
- package/dist/mcp/tools/bash-related.d.ts.map +1 -0
- package/dist/mcp/tools/bash-related.js +54 -0
- package/dist/mcp/tools/bash-related.js.map +1 -0
- package/dist/mcp/tools/bash-session.d.ts +23 -0
- package/dist/mcp/tools/bash-session.d.ts.map +1 -0
- package/dist/mcp/tools/bash-session.js +60 -0
- package/dist/mcp/tools/bash-session.js.map +1 -0
- package/dist/mcp/tools/bash-telemetry.d.ts +26 -0
- package/dist/mcp/tools/bash-telemetry.d.ts.map +1 -0
- package/dist/mcp/tools/bash-telemetry.js +53 -0
- package/dist/mcp/tools/bash-telemetry.js.map +1 -0
- package/dist/mcp/tools/bash-virtual-files.d.ts +3 -0
- package/dist/mcp/tools/bash-virtual-files.d.ts.map +1 -0
- package/dist/mcp/tools/bash-virtual-files.js +65 -0
- package/dist/mcp/tools/bash-virtual-files.js.map +1 -0
- package/dist/mcp/tools/bash.d.ts +25 -0
- package/dist/mcp/tools/bash.d.ts.map +1 -0
- package/dist/mcp/tools/bash.js +140 -0
- package/dist/mcp/tools/bash.js.map +1 -0
- package/dist/mcp/tools/collect.d.ts +13 -0
- package/dist/mcp/tools/collect.d.ts.map +1 -0
- package/dist/mcp/tools/collect.js +56 -0
- package/dist/mcp/tools/collect.js.map +1 -0
- package/dist/mcp/tools/search.d.ts +5 -0
- package/dist/mcp/tools/search.d.ts.map +1 -0
- package/dist/mcp/tools/search.js +68 -0
- package/dist/mcp/tools/search.js.map +1 -0
- package/dist/types.d.ts +1237 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +163 -0
- package/dist/types.js.map +1 -0
- package/dist/webhooks/github.d.ts +12 -0
- package/dist/webhooks/github.d.ts.map +1 -0
- package/dist/webhooks/github.js +117 -0
- package/dist/webhooks/github.js.map +1 -0
- package/package.json +48 -0
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { Bash } from 'just-bash';
|
|
4
|
+
import { matchesPatterns } from '../../indexing/source-indexer.js';
|
|
5
|
+
import { generateIndexMd, generateSearchTipsMd } from './bash-virtual-files.js';
|
|
6
|
+
const DEFAULT_SKIP_DIRS = new Set(['node_modules', 'dist', 'build', '.git']);
|
|
7
|
+
const DEFAULT_MAX_FILE_SIZE = 102400; // 100KB
|
|
8
|
+
async function walkFiles(dir, skipDirs, maxFileSize) {
|
|
9
|
+
const results = [];
|
|
10
|
+
let entries;
|
|
11
|
+
try {
|
|
12
|
+
entries = await fs.promises.readdir(dir, { withFileTypes: true });
|
|
13
|
+
}
|
|
14
|
+
catch (err) {
|
|
15
|
+
console.warn(`[bash-fs] Failed to read directory ${dir}:`, err);
|
|
16
|
+
return results;
|
|
17
|
+
}
|
|
18
|
+
for (const entry of entries) {
|
|
19
|
+
if (skipDirs.has(entry.name))
|
|
20
|
+
continue;
|
|
21
|
+
const fullPath = path.join(dir, entry.name);
|
|
22
|
+
if (entry.isDirectory()) {
|
|
23
|
+
results.push(...await walkFiles(fullPath, skipDirs, maxFileSize));
|
|
24
|
+
}
|
|
25
|
+
else if (entry.isFile()) {
|
|
26
|
+
try {
|
|
27
|
+
const stat = await fs.promises.stat(fullPath);
|
|
28
|
+
if (stat.size <= maxFileSize)
|
|
29
|
+
results.push(fullPath);
|
|
30
|
+
}
|
|
31
|
+
catch (err) {
|
|
32
|
+
console.warn(`[bash-fs] Failed to stat ${fullPath}:`, err);
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return results;
|
|
38
|
+
}
|
|
39
|
+
export async function buildBashFilesMap(sources, options) {
|
|
40
|
+
const files = {};
|
|
41
|
+
const multiSource = sources.length > 1;
|
|
42
|
+
for (const source of sources) {
|
|
43
|
+
let rootDir;
|
|
44
|
+
if (source.repo && options?.cloneDir) {
|
|
45
|
+
// Git-based source: the orchestrator clones into cloneDir/<repoName>/
|
|
46
|
+
const repoName = source.repo.replace(/\.git$/, '').split('/').pop();
|
|
47
|
+
rootDir = path.join(options.cloneDir, repoName, source.path);
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
rootDir = path.resolve(source.path);
|
|
51
|
+
}
|
|
52
|
+
if (!fs.existsSync(rootDir)) {
|
|
53
|
+
console.warn(`[bash-fs] Source "${source.name}" path does not exist: ${rootDir}`);
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
const skipDirs = new Set([...DEFAULT_SKIP_DIRS, ...(source.skip_dirs ?? [])]);
|
|
57
|
+
const maxFileSize = source.max_file_size ?? DEFAULT_MAX_FILE_SIZE;
|
|
58
|
+
const allFiles = await walkFiles(rootDir, skipDirs, maxFileSize);
|
|
59
|
+
for (const absPath of allFiles) {
|
|
60
|
+
const relPath = path.relative(rootDir, absPath);
|
|
61
|
+
if (!matchesPatterns(relPath, source))
|
|
62
|
+
continue;
|
|
63
|
+
let content;
|
|
64
|
+
try {
|
|
65
|
+
content = await fs.promises.readFile(absPath, 'utf-8');
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
console.warn(`[bash-fs] Failed to read ${absPath}, skipping:`, err);
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
const virtualPath = multiSource
|
|
72
|
+
? `/${source.name}/${relPath}`
|
|
73
|
+
: `/${relPath}`;
|
|
74
|
+
files[virtualPath] = content;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
if (options?.virtualFiles) {
|
|
78
|
+
files['/INDEX.md'] = generateIndexMd(files);
|
|
79
|
+
files['/SEARCH_TIPS.md'] = generateSearchTipsMd(options.searchToolNames ?? []);
|
|
80
|
+
}
|
|
81
|
+
return files;
|
|
82
|
+
}
|
|
83
|
+
export function buildFileMetadata(files) {
|
|
84
|
+
const meta = {};
|
|
85
|
+
for (const [path, content] of Object.entries(files)) {
|
|
86
|
+
const size = Buffer.byteLength(content, 'utf-8');
|
|
87
|
+
const lines = content === '' ? 0 : content.endsWith('\n')
|
|
88
|
+
? content.split('\n').length - 1
|
|
89
|
+
: content.split('\n').length;
|
|
90
|
+
meta[path] = { size, lines };
|
|
91
|
+
}
|
|
92
|
+
return meta;
|
|
93
|
+
}
|
|
94
|
+
export function formatLsLong(dir, allPaths, metadata) {
|
|
95
|
+
const normalizedDir = dir.endsWith('/') ? dir : dir + '/';
|
|
96
|
+
const files = [];
|
|
97
|
+
const subdirs = new Set();
|
|
98
|
+
for (const p of allPaths) {
|
|
99
|
+
if (!p.startsWith(normalizedDir))
|
|
100
|
+
continue;
|
|
101
|
+
const rest = p.slice(normalizedDir.length);
|
|
102
|
+
const slashIdx = rest.indexOf('/');
|
|
103
|
+
if (slashIdx === -1) {
|
|
104
|
+
files.push(p);
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
subdirs.add(rest.slice(0, slashIdx));
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
const lines = [];
|
|
111
|
+
for (const d of [...subdirs].sort()) {
|
|
112
|
+
lines.push(`drwxr-xr-x ${d}/`);
|
|
113
|
+
}
|
|
114
|
+
for (const f of files.sort()) {
|
|
115
|
+
const name = f.slice(normalizedDir.length);
|
|
116
|
+
const meta = metadata[f];
|
|
117
|
+
if (meta) {
|
|
118
|
+
const sizeStr = String(meta.size).padStart(8);
|
|
119
|
+
lines.push(`-rw-r--r-- ${sizeStr} ${meta.lines} lines ${name}`);
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
lines.push(`-rw-r--r-- ${name}`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return lines.join('\n') + '\n';
|
|
126
|
+
}
|
|
127
|
+
export async function rebuildBashInstance(sources, options) {
|
|
128
|
+
const filesMap = await buildBashFilesMap(sources, { ...options });
|
|
129
|
+
return {
|
|
130
|
+
bash: new Bash({ files: filesMap, cwd: '/' }),
|
|
131
|
+
fileCount: Object.keys(filesMap).length,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=bash-fs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bash-fs.js","sourceRoot":"","sources":["../../../src/mcp/tools/bash-fs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { EmbeddingClient } from '../../indexing/embeddings.js';
|
|
2
|
+
import type { ChunkResult } from '../../types.js';
|
|
3
|
+
export interface ParsedGrep {
|
|
4
|
+
isGrep: boolean;
|
|
5
|
+
pattern: string;
|
|
6
|
+
flags: string[];
|
|
7
|
+
paths: string[];
|
|
8
|
+
}
|
|
9
|
+
export declare function parseGrepCommand(command: string): ParsedGrep;
|
|
10
|
+
export interface ParsedQmd {
|
|
11
|
+
isQmd: boolean;
|
|
12
|
+
query: string;
|
|
13
|
+
}
|
|
14
|
+
export declare function parseQmdCommand(command: string): ParsedQmd;
|
|
15
|
+
export interface VectorGrepOptions {
|
|
16
|
+
pattern: string;
|
|
17
|
+
sourceName?: string;
|
|
18
|
+
embeddingClient: EmbeddingClient;
|
|
19
|
+
searchChunksFn: (embedding: number[], limit: number, sourceName?: string) => Promise<ChunkResult[]>;
|
|
20
|
+
textSearchFn: (pattern: string, limit: number, sourceName?: string) => Promise<ChunkResult[]>;
|
|
21
|
+
limit?: number;
|
|
22
|
+
}
|
|
23
|
+
export interface GrepResult {
|
|
24
|
+
stdout: string;
|
|
25
|
+
stderr: string;
|
|
26
|
+
exitCode: number;
|
|
27
|
+
}
|
|
28
|
+
export declare function vectorGrep(options: VectorGrepOptions): Promise<GrepResult>;
|
|
29
|
+
//# sourceMappingURL=bash-grep.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bash-grep.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/bash-grep.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD,MAAM,WAAW,UAAU;IACvB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,EAAE,MAAM,EAAE,CAAC;CACnB;AAKD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,CA6C5D;AAED,MAAM,WAAW,SAAS;IACtB,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAoB1D;AAED,MAAM,WAAW,iBAAiB;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,eAAe,CAAC;IACjC,cAAc,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IACpG,YAAY,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IAC9F,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,UAAU;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CACpB;AAMD,wBAAsB,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,UAAU,CAAC,CAoDhF"}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/** Flags that consume the next token as their argument. */
|
|
2
|
+
const FLAGS_WITH_ARGS = new Set(['-e', '-m', '-f', '-A', '-B', '-C']);
|
|
3
|
+
export function parseGrepCommand(command) {
|
|
4
|
+
const trimmed = command.trim();
|
|
5
|
+
if (trimmed.includes('|') || trimmed.includes(';') || trimmed.includes('&&')) {
|
|
6
|
+
return { isGrep: false, pattern: '', flags: [], paths: [] };
|
|
7
|
+
}
|
|
8
|
+
if (!trimmed.startsWith('grep ') && trimmed !== 'grep') {
|
|
9
|
+
return { isGrep: false, pattern: '', flags: [], paths: [] };
|
|
10
|
+
}
|
|
11
|
+
const tokens = [];
|
|
12
|
+
let i = 5;
|
|
13
|
+
while (i < trimmed.length) {
|
|
14
|
+
while (i < trimmed.length && trimmed[i] === ' ')
|
|
15
|
+
i++;
|
|
16
|
+
if (i >= trimmed.length)
|
|
17
|
+
break;
|
|
18
|
+
if (trimmed[i] === '"' || trimmed[i] === "'") {
|
|
19
|
+
const quote = trimmed[i];
|
|
20
|
+
i++;
|
|
21
|
+
let token = '';
|
|
22
|
+
while (i < trimmed.length && trimmed[i] !== quote) {
|
|
23
|
+
token += trimmed[i];
|
|
24
|
+
i++;
|
|
25
|
+
}
|
|
26
|
+
i++;
|
|
27
|
+
tokens.push(token);
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
let token = '';
|
|
31
|
+
while (i < trimmed.length && trimmed[i] !== ' ') {
|
|
32
|
+
token += trimmed[i];
|
|
33
|
+
i++;
|
|
34
|
+
}
|
|
35
|
+
tokens.push(token);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const flags = [];
|
|
39
|
+
let pattern = '';
|
|
40
|
+
const paths = [];
|
|
41
|
+
let patternFound = false;
|
|
42
|
+
for (let t = 0; t < tokens.length; t++) {
|
|
43
|
+
const token = tokens[t];
|
|
44
|
+
if (token.startsWith('-') && !patternFound) {
|
|
45
|
+
flags.push(token);
|
|
46
|
+
// If this flag takes an argument, consume the next token too
|
|
47
|
+
if (FLAGS_WITH_ARGS.has(token) && t + 1 < tokens.length) {
|
|
48
|
+
t++;
|
|
49
|
+
flags.push(tokens[t]);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
else if (!patternFound) {
|
|
53
|
+
pattern = token;
|
|
54
|
+
patternFound = true;
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
paths.push(token);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
if (!pattern)
|
|
61
|
+
return { isGrep: false, pattern: '', flags: [], paths: [] };
|
|
62
|
+
if (paths.length === 0)
|
|
63
|
+
paths.push('/');
|
|
64
|
+
return { isGrep: true, pattern, flags, paths };
|
|
65
|
+
}
|
|
66
|
+
export function parseQmdCommand(command) {
|
|
67
|
+
const trimmed = command.trim();
|
|
68
|
+
// Reject piped/chained commands
|
|
69
|
+
if (trimmed.includes('|') || trimmed.includes(';') || trimmed.includes('&&')) {
|
|
70
|
+
return { isQmd: false, query: '' };
|
|
71
|
+
}
|
|
72
|
+
if (!trimmed.startsWith('qmd ') && trimmed !== 'qmd') {
|
|
73
|
+
return { isQmd: false, query: '' };
|
|
74
|
+
}
|
|
75
|
+
// Extract the query after "qmd "
|
|
76
|
+
const rest = trimmed.slice(4).trim();
|
|
77
|
+
if (!rest)
|
|
78
|
+
return { isQmd: false, query: '' };
|
|
79
|
+
// Handle quoted query: qmd "query" or qmd 'query'
|
|
80
|
+
if ((rest.startsWith('"') && rest.endsWith('"')) || (rest.startsWith("'") && rest.endsWith("'"))) {
|
|
81
|
+
const query = rest.slice(1, -1);
|
|
82
|
+
if (!query)
|
|
83
|
+
return { isQmd: false, query: '' };
|
|
84
|
+
return { isQmd: true, query };
|
|
85
|
+
}
|
|
86
|
+
// Unquoted: qmd query words here
|
|
87
|
+
return { isQmd: true, query: rest };
|
|
88
|
+
}
|
|
89
|
+
function escapeRegex(str) {
|
|
90
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
91
|
+
}
|
|
92
|
+
export async function vectorGrep(options) {
|
|
93
|
+
const { pattern, sourceName, embeddingClient, searchChunksFn, textSearchFn, limit = 20 } = options;
|
|
94
|
+
let semanticResults = [];
|
|
95
|
+
let semanticError = null;
|
|
96
|
+
try {
|
|
97
|
+
const embedding = await embeddingClient.embed(pattern);
|
|
98
|
+
semanticResults = await searchChunksFn(embedding, limit, sourceName);
|
|
99
|
+
}
|
|
100
|
+
catch (err) {
|
|
101
|
+
semanticError = err instanceof Error ? err.message : String(err);
|
|
102
|
+
console.warn(`[bash-grep] Semantic search failed: ${semanticError}`);
|
|
103
|
+
}
|
|
104
|
+
let textResults = [];
|
|
105
|
+
let textError = null;
|
|
106
|
+
try {
|
|
107
|
+
textResults = await textSearchFn(pattern, limit, sourceName);
|
|
108
|
+
}
|
|
109
|
+
catch (err) {
|
|
110
|
+
textError = err instanceof Error ? err.message : String(err);
|
|
111
|
+
console.warn(`[bash-grep] Text search failed: ${textError}`);
|
|
112
|
+
}
|
|
113
|
+
if (semanticResults.length === 0 && textResults.length === 0 && semanticError && textError) {
|
|
114
|
+
return {
|
|
115
|
+
stdout: '',
|
|
116
|
+
stderr: `grep: search unavailable (semantic: ${semanticError}, text: ${textError})\n`,
|
|
117
|
+
exitCode: 2,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
const seenIds = new Set();
|
|
121
|
+
const allResults = [];
|
|
122
|
+
for (const r of [...semanticResults, ...textResults]) {
|
|
123
|
+
if (!seenIds.has(r.id)) {
|
|
124
|
+
seenIds.add(r.id);
|
|
125
|
+
allResults.push(r);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
const regex = new RegExp(escapeRegex(pattern), 'i');
|
|
129
|
+
const matching = allResults.filter(r => regex.test(r.content));
|
|
130
|
+
let warnings = '';
|
|
131
|
+
if (semanticError && !textError) {
|
|
132
|
+
warnings = `[warning: semantic search unavailable: ${semanticError}]\n`;
|
|
133
|
+
}
|
|
134
|
+
else if (!semanticError && textError) {
|
|
135
|
+
warnings = `[warning: text search unavailable: ${textError}]\n`;
|
|
136
|
+
}
|
|
137
|
+
if (matching.length === 0)
|
|
138
|
+
return { stdout: '', stderr: warnings, exitCode: 1 };
|
|
139
|
+
const lines = [];
|
|
140
|
+
for (const r of matching) {
|
|
141
|
+
const contentLines = r.content.split('\n');
|
|
142
|
+
const startLine = r.start_line ?? 1;
|
|
143
|
+
for (let i = 0; i < contentLines.length; i++) {
|
|
144
|
+
if (regex.test(contentLines[i])) {
|
|
145
|
+
lines.push(`/${r.file_path}:${startLine + i}:${contentLines[i]}`);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
if (lines.length === 0)
|
|
150
|
+
return { stdout: '', stderr: warnings, exitCode: 1 };
|
|
151
|
+
return { stdout: lines.join('\n') + '\n', stderr: warnings, exitCode: 0 };
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=bash-grep.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bash-grep.js","sourceRoot":"","sources":["../../../src/mcp/tools/bash-grep.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { EmbeddingClient } from '../../indexing/embeddings.js';
|
|
2
|
+
import type { ChunkResult } from '../../types.js';
|
|
3
|
+
export interface RelatedResult {
|
|
4
|
+
stdout: string;
|
|
5
|
+
stderr: string;
|
|
6
|
+
exitCode: number;
|
|
7
|
+
}
|
|
8
|
+
export declare function parseRelatedCommand(command: string): {
|
|
9
|
+
isRelated: boolean;
|
|
10
|
+
path: string;
|
|
11
|
+
};
|
|
12
|
+
export declare function handleRelatedCommand(filePath: string, fileContent: string | undefined, embeddingClient: EmbeddingClient, searchChunksFn: (embedding: number[], limit: number) => Promise<ChunkResult[]>, limit?: number): Promise<RelatedResult>;
|
|
13
|
+
export declare function formatGrepMissSuggestion(searchToolNames: string[]): string;
|
|
14
|
+
//# sourceMappingURL=bash-related.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bash-related.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/bash-related.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD,MAAM,WAAW,aAAa;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,SAAS,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAKzF;AAED,wBAAsB,oBAAoB,CACtC,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,eAAe,EAAE,eAAe,EAChC,cAAc,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,WAAW,EAAE,CAAC,EAC9E,KAAK,GAAE,MAAW,GACnB,OAAO,CAAC,aAAa,CAAC,CAyCxB;AAED,wBAAgB,wBAAwB,CAAC,eAAe,EAAE,MAAM,EAAE,GAAG,MAAM,CAI1E"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
export function parseRelatedCommand(command) {
|
|
2
|
+
const trimmed = command.trim();
|
|
3
|
+
const match = trimmed.match(/^related\s+(\S+)\s*$/);
|
|
4
|
+
if (match)
|
|
5
|
+
return { isRelated: true, path: match[1] };
|
|
6
|
+
return { isRelated: false, path: '' };
|
|
7
|
+
}
|
|
8
|
+
export async function handleRelatedCommand(filePath, fileContent, embeddingClient, searchChunksFn, limit = 10) {
|
|
9
|
+
if (!fileContent) {
|
|
10
|
+
return {
|
|
11
|
+
stdout: '',
|
|
12
|
+
stderr: `related: ${filePath}: No such file\n`,
|
|
13
|
+
exitCode: 1,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
try {
|
|
17
|
+
// Embed the file's content (truncate to reasonable length for embedding)
|
|
18
|
+
const contentForEmbedding = fileContent.slice(0, 8000);
|
|
19
|
+
const embedding = await embeddingClient.embed(contentForEmbedding);
|
|
20
|
+
const results = await searchChunksFn(embedding, limit);
|
|
21
|
+
// Deduplicate by file_path (keep highest similarity)
|
|
22
|
+
const byFile = new Map();
|
|
23
|
+
for (const r of results) {
|
|
24
|
+
const vPath = r.source_name ? `/${r.source_name}/${r.file_path}` : `/${r.file_path}`;
|
|
25
|
+
if (vPath === filePath)
|
|
26
|
+
continue; // skip self — exact match only
|
|
27
|
+
const existing = byFile.get(vPath);
|
|
28
|
+
if (!existing || r.similarity > existing.similarity) {
|
|
29
|
+
byFile.set(vPath, { path: vPath, similarity: r.similarity });
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
if (byFile.size === 0) {
|
|
33
|
+
return { stdout: 'No related files found.\n', stderr: '', exitCode: 0 };
|
|
34
|
+
}
|
|
35
|
+
const sorted = [...byFile.values()].sort((a, b) => b.similarity - a.similarity);
|
|
36
|
+
const lines = [`Semantically related files for ${filePath}:\n`];
|
|
37
|
+
for (const { path, similarity } of sorted) {
|
|
38
|
+
lines.push(` ${similarity.toFixed(2)} ${path}`);
|
|
39
|
+
}
|
|
40
|
+
return { stdout: lines.join('\n') + '\n', stderr: '', exitCode: 0 };
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
44
|
+
console.error(`[bash-related] Error: ${msg}`);
|
|
45
|
+
return { stdout: '', stderr: `related: error: ${msg}\n`, exitCode: 1 };
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
export function formatGrepMissSuggestion(searchToolNames) {
|
|
49
|
+
if (searchToolNames.length === 0)
|
|
50
|
+
return '';
|
|
51
|
+
const tools = searchToolNames.join(', ');
|
|
52
|
+
return `\nNo matches found. Try semantic search: qmd "your query" or ${tools}("your query")\n`;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=bash-related.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bash-related.js","sourceRoot":"","sources":["../../../src/mcp/tools/bash-related.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export declare class BashSessionState {
|
|
2
|
+
private cwd;
|
|
3
|
+
getCwd(): string;
|
|
4
|
+
setCwd(dir: string): void;
|
|
5
|
+
resolvePath(target: string): string;
|
|
6
|
+
}
|
|
7
|
+
export declare class SessionStateManager {
|
|
8
|
+
private sessions;
|
|
9
|
+
getOrCreate(sessionId: string): BashSessionState;
|
|
10
|
+
cleanup(sessionId: string): void;
|
|
11
|
+
cleanupAll(): void;
|
|
12
|
+
get size(): number;
|
|
13
|
+
}
|
|
14
|
+
export declare class WorkspaceTracker {
|
|
15
|
+
private usedBytes;
|
|
16
|
+
private maxBytes;
|
|
17
|
+
constructor(maxBytes?: number);
|
|
18
|
+
getUsedBytes(): number;
|
|
19
|
+
getMaxBytes(): number;
|
|
20
|
+
trackWrite(bytes: number): boolean;
|
|
21
|
+
reset(): void;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=bash-session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bash-session.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/bash-session.ts"],"names":[],"mappings":"AAEA,qBAAa,gBAAgB;IACzB,OAAO,CAAC,GAAG,CAAe;IAE1B,MAAM,IAAI,MAAM;IAIhB,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAIzB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;CAMtC;AAED,qBAAa,mBAAmB;IAC5B,OAAO,CAAC,QAAQ,CAAuC;IAEvD,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,gBAAgB;IAShD,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAIhC,UAAU,IAAI,IAAI;IAIlB,IAAI,IAAI,IAAI,MAAM,CAEjB;CACJ;AAID,qBAAa,gBAAgB;IACzB,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,QAAQ,CAAS;gBAEb,QAAQ,GAAE,MAAoC;IAI1D,YAAY,IAAI,MAAM;IAItB,WAAW,IAAI,MAAM;IAIrB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAMlC,KAAK,IAAI,IAAI;CAGhB"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
export class BashSessionState {
|
|
3
|
+
cwd = '/';
|
|
4
|
+
getCwd() {
|
|
5
|
+
return this.cwd;
|
|
6
|
+
}
|
|
7
|
+
setCwd(dir) {
|
|
8
|
+
this.cwd = dir === '/' ? '/' : dir.replace(/\/+$/, '');
|
|
9
|
+
}
|
|
10
|
+
resolvePath(target) {
|
|
11
|
+
const resolved = target.startsWith('/')
|
|
12
|
+
? path.posix.normalize(target)
|
|
13
|
+
: path.posix.normalize(path.posix.join(this.cwd, target));
|
|
14
|
+
return resolved === '/' ? '/' : resolved.replace(/\/+$/, '');
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export class SessionStateManager {
|
|
18
|
+
sessions = new Map();
|
|
19
|
+
getOrCreate(sessionId) {
|
|
20
|
+
let state = this.sessions.get(sessionId);
|
|
21
|
+
if (!state) {
|
|
22
|
+
state = new BashSessionState();
|
|
23
|
+
this.sessions.set(sessionId, state);
|
|
24
|
+
}
|
|
25
|
+
return state;
|
|
26
|
+
}
|
|
27
|
+
cleanup(sessionId) {
|
|
28
|
+
this.sessions.delete(sessionId);
|
|
29
|
+
}
|
|
30
|
+
cleanupAll() {
|
|
31
|
+
this.sessions.clear();
|
|
32
|
+
}
|
|
33
|
+
get size() {
|
|
34
|
+
return this.sessions.size;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
const DEFAULT_WORKSPACE_MAX_BYTES = 1024 * 1024; // 1MB
|
|
38
|
+
export class WorkspaceTracker {
|
|
39
|
+
usedBytes = 0;
|
|
40
|
+
maxBytes;
|
|
41
|
+
constructor(maxBytes = DEFAULT_WORKSPACE_MAX_BYTES) {
|
|
42
|
+
this.maxBytes = maxBytes;
|
|
43
|
+
}
|
|
44
|
+
getUsedBytes() {
|
|
45
|
+
return this.usedBytes;
|
|
46
|
+
}
|
|
47
|
+
getMaxBytes() {
|
|
48
|
+
return this.maxBytes;
|
|
49
|
+
}
|
|
50
|
+
trackWrite(bytes) {
|
|
51
|
+
if (this.usedBytes + bytes > this.maxBytes)
|
|
52
|
+
return false;
|
|
53
|
+
this.usedBytes += bytes;
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
reset() {
|
|
57
|
+
this.usedBytes = 0;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=bash-session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bash-session.js","sourceRoot":"","sources":["../../../src/mcp/tools/bash-session.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,OAAO,gBAAgB;IACjB,GAAG,GAAW,GAAG,CAAC;IAE1B,MAAM;QACF,OAAO,IAAI,CAAC,GAAG,CAAC;IACpB,CAAC;IAED,MAAM,CAAC,GAAW;QACd,IAAI,CAAC,GAAG,GAAG,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC3D,CAAC;IAED,WAAW,CAAC,MAAc;QACtB,MAAM,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC;YACnC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC;YAC9B,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC;QAC9D,OAAO,QAAQ,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACjE,CAAC;CACJ;AAED,MAAM,OAAO,mBAAmB;IACpB,QAAQ,GAAG,IAAI,GAAG,EAA4B,CAAC;IAEvD,WAAW,CAAC,SAAiB;QACzB,IAAI,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACzC,IAAI,CAAC,KAAK,EAAE,CAAC;YACT,KAAK,GAAG,IAAI,gBAAgB,EAAE,CAAC;YAC/B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QACxC,CAAC;QACD,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,OAAO,CAAC,SAAiB;QACrB,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACpC,CAAC;IAED,UAAU;QACN,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;IAC1B,CAAC;IAED,IAAI,IAAI;QACJ,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;IAC9B,CAAC;CACJ;AAED,MAAM,2BAA2B,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,MAAM;AAEvD,MAAM,OAAO,gBAAgB;IACjB,SAAS,GAAG,CAAC,CAAC;IACd,QAAQ,CAAS;IAEzB,YAAY,WAAmB,2BAA2B;QACtD,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC7B,CAAC;IAED,YAAY;QACR,OAAO,IAAI,CAAC,SAAS,CAAC;IAC1B,CAAC;IAED,WAAW;QACP,OAAO,IAAI,CAAC,QAAQ,CAAC;IACzB,CAAC;IAED,UAAU,CAAC,KAAa;QACpB,IAAI,IAAI,CAAC,SAAS,GAAG,KAAK,GAAG,IAAI,CAAC,QAAQ;YAAE,OAAO,KAAK,CAAC;QACzD,IAAI,CAAC,SAAS,IAAI,KAAK,CAAC;QACxB,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,KAAK;QACD,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC;IACvB,CAAC;CACJ"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export interface TelemetryEvent {
|
|
2
|
+
type: 'file_access' | 'grep_miss' | 'command';
|
|
3
|
+
timestamp: string;
|
|
4
|
+
path?: string;
|
|
5
|
+
pattern?: string;
|
|
6
|
+
command?: string;
|
|
7
|
+
}
|
|
8
|
+
type InsertFn = (toolName: string, data: Record<string, unknown>) => Promise<void>;
|
|
9
|
+
export declare class BashTelemetry {
|
|
10
|
+
private events;
|
|
11
|
+
private insertFn;
|
|
12
|
+
constructor(insertFn: InsertFn);
|
|
13
|
+
private addEvent;
|
|
14
|
+
recordFileAccess(path: string, command: string): void;
|
|
15
|
+
recordGrepMiss(pattern: string, command: string): void;
|
|
16
|
+
recordCommand(command: string): void;
|
|
17
|
+
getEvents(): TelemetryEvent[];
|
|
18
|
+
getStats(): {
|
|
19
|
+
totalCommands: number;
|
|
20
|
+
fileAccesses: number;
|
|
21
|
+
grepMisses: number;
|
|
22
|
+
};
|
|
23
|
+
flush(): Promise<void>;
|
|
24
|
+
}
|
|
25
|
+
export {};
|
|
26
|
+
//# sourceMappingURL=bash-telemetry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bash-telemetry.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/bash-telemetry.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC3B,IAAI,EAAE,aAAa,GAAG,WAAW,GAAG,SAAS,CAAC;IAC9C,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,KAAK,QAAQ,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAInF,qBAAa,aAAa;IACtB,OAAO,CAAC,MAAM,CAAwB;IACtC,OAAO,CAAC,QAAQ,CAAW;gBAEf,QAAQ,EAAE,QAAQ;IAI9B,OAAO,CAAC,QAAQ;IAShB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAIrD,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAItD,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAIpC,SAAS,IAAI,cAAc,EAAE;IAI7B,QAAQ,IAAI;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE;IAUzE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAW/B"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
const MAX_BUFFER_SIZE = 10000;
|
|
2
|
+
export class BashTelemetry {
|
|
3
|
+
events = [];
|
|
4
|
+
insertFn;
|
|
5
|
+
constructor(insertFn) {
|
|
6
|
+
this.insertFn = insertFn;
|
|
7
|
+
}
|
|
8
|
+
addEvent(event) {
|
|
9
|
+
this.events.push(event);
|
|
10
|
+
if (this.events.length > MAX_BUFFER_SIZE) {
|
|
11
|
+
const dropped = this.events.length - MAX_BUFFER_SIZE;
|
|
12
|
+
this.events = this.events.slice(dropped);
|
|
13
|
+
console.warn(`[bash-telemetry] Buffer overflow: dropped ${dropped} oldest events`);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
recordFileAccess(path, command) {
|
|
17
|
+
this.addEvent({ type: 'file_access', timestamp: new Date().toISOString(), path, command });
|
|
18
|
+
}
|
|
19
|
+
recordGrepMiss(pattern, command) {
|
|
20
|
+
this.addEvent({ type: 'grep_miss', timestamp: new Date().toISOString(), pattern, command });
|
|
21
|
+
}
|
|
22
|
+
recordCommand(command) {
|
|
23
|
+
this.addEvent({ type: 'command', timestamp: new Date().toISOString(), command });
|
|
24
|
+
}
|
|
25
|
+
getEvents() {
|
|
26
|
+
return [...this.events];
|
|
27
|
+
}
|
|
28
|
+
getStats() {
|
|
29
|
+
let fileAccesses = 0;
|
|
30
|
+
let grepMisses = 0;
|
|
31
|
+
for (const e of this.events) {
|
|
32
|
+
if (e.type === 'file_access')
|
|
33
|
+
fileAccesses++;
|
|
34
|
+
if (e.type === 'grep_miss')
|
|
35
|
+
grepMisses++;
|
|
36
|
+
}
|
|
37
|
+
return { totalCommands: this.events.length, fileAccesses, grepMisses };
|
|
38
|
+
}
|
|
39
|
+
async flush() {
|
|
40
|
+
if (this.events.length === 0)
|
|
41
|
+
return;
|
|
42
|
+
const batch = [...this.events];
|
|
43
|
+
this.events = [];
|
|
44
|
+
try {
|
|
45
|
+
await this.insertFn('_telemetry', { events: batch, flushed_at: new Date().toISOString() });
|
|
46
|
+
}
|
|
47
|
+
catch (err) {
|
|
48
|
+
this.events.unshift(...batch);
|
|
49
|
+
console.error('[bash-telemetry] Flush failed:', err instanceof Error ? err.message : String(err));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=bash-telemetry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bash-telemetry.js","sourceRoot":"","sources":["../../../src/mcp/tools/bash-telemetry.ts"],"names":[],"mappings":"AAUA,MAAM,eAAe,GAAG,KAAK,CAAC;AAE9B,MAAM,OAAO,aAAa;IACd,MAAM,GAAqB,EAAE,CAAC;IAC9B,QAAQ,CAAW;IAE3B,YAAY,QAAkB;QAC1B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC7B,CAAC;IAEO,QAAQ,CAAC,KAAqB;QAClC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACxB,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,eAAe,EAAE,CAAC;YACvC,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,eAAe,CAAC;YACrD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACzC,OAAO,CAAC,IAAI,CAAC,6CAA6C,OAAO,gBAAgB,CAAC,CAAC;QACvF,CAAC;IACL,CAAC;IAED,gBAAgB,CAAC,IAAY,EAAE,OAAe;QAC1C,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;IAC/F,CAAC;IAED,cAAc,CAAC,OAAe,EAAE,OAAe;QAC3C,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;IAChG,CAAC;IAED,aAAa,CAAC,OAAe;QACzB,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;IACrF,CAAC;IAED,SAAS;QACL,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;IAC5B,CAAC;IAED,QAAQ;QACJ,IAAI,YAAY,GAAG,CAAC,CAAC;QACrB,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAC1B,IAAI,CAAC,CAAC,IAAI,KAAK,aAAa;gBAAE,YAAY,EAAE,CAAC;YAC7C,IAAI,CAAC,CAAC,IAAI,KAAK,WAAW;gBAAE,UAAU,EAAE,CAAC;QAC7C,CAAC;QACD,OAAO,EAAE,aAAa,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,YAAY,EAAE,UAAU,EAAE,CAAC;IAC3E,CAAC;IAED,KAAK,CAAC,KAAK;QACP,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QACrC,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;QAC/B,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;QACjB,IAAI,CAAC;YACD,MAAM,IAAI,CAAC,QAAQ,CAAC,YAAY,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QAC/F,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC;YAC9B,OAAO,CAAC,KAAK,CAAC,gCAAgC,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QACtG,CAAC;IACL,CAAC;CACJ"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bash-virtual-files.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/bash-virtual-files.ts"],"names":[],"mappings":"AAAA,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CA8BxE;AAED,wBAAgB,oBAAoB,CAAC,eAAe,EAAE,MAAM,EAAE,GAAG,MAAM,CA4BtE"}
|