@copilotkit/pathfinder 1.4.0 → 1.6.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/CHANGELOG.md +35 -0
- package/LICENSE +106 -21
- package/README.md +14 -3
- package/dist/cli.js +11 -1
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +9 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +64 -5
- package/dist/config.js.map +1 -1
- package/dist/db/queries.d.ts +12 -1
- package/dist/db/queries.d.ts.map +1 -1
- package/dist/db/queries.js +64 -0
- package/dist/db/queries.js.map +1 -1
- package/dist/faq-txt.d.ts +12 -0
- package/dist/faq-txt.d.ts.map +1 -0
- package/dist/faq-txt.js +37 -0
- package/dist/faq-txt.js.map +1 -0
- package/dist/indexing/chunking/index.js +4 -0
- package/dist/indexing/chunking/index.js.map +1 -1
- package/dist/indexing/chunking/qa.d.ts +8 -0
- package/dist/indexing/chunking/qa.d.ts.map +1 -0
- package/dist/indexing/chunking/qa.js +22 -0
- package/dist/indexing/chunking/qa.js.map +1 -0
- package/dist/indexing/distiller.d.ts +29 -0
- package/dist/indexing/distiller.d.ts.map +1 -0
- package/dist/indexing/distiller.js +104 -0
- package/dist/indexing/distiller.js.map +1 -0
- package/dist/indexing/orchestrator.d.ts +8 -3
- package/dist/indexing/orchestrator.d.ts.map +1 -1
- package/dist/indexing/orchestrator.js +99 -93
- package/dist/indexing/orchestrator.js.map +1 -1
- package/dist/indexing/pipeline.d.ts +18 -0
- package/dist/indexing/pipeline.d.ts.map +1 -0
- package/dist/indexing/pipeline.js +68 -0
- package/dist/indexing/pipeline.js.map +1 -0
- package/dist/indexing/providers/discord-api.d.ts +79 -0
- package/dist/indexing/providers/discord-api.d.ts.map +1 -0
- package/dist/indexing/providers/discord-api.js +167 -0
- package/dist/indexing/providers/discord-api.js.map +1 -0
- package/dist/indexing/providers/discord.d.ts +25 -0
- package/dist/indexing/providers/discord.d.ts.map +1 -0
- package/dist/indexing/providers/discord.js +282 -0
- package/dist/indexing/providers/discord.js.map +1 -0
- package/dist/indexing/providers/file.d.ts +18 -0
- package/dist/indexing/providers/file.d.ts.map +1 -0
- package/dist/indexing/providers/file.js +262 -0
- package/dist/indexing/providers/file.js.map +1 -0
- package/dist/indexing/providers/index.d.ts +5 -0
- package/dist/indexing/providers/index.d.ts.map +1 -0
- package/dist/indexing/providers/index.js +24 -0
- package/dist/indexing/providers/index.js.map +1 -0
- package/dist/indexing/providers/notion-api.d.ts +101 -0
- package/dist/indexing/providers/notion-api.d.ts.map +1 -0
- package/dist/indexing/providers/notion-api.js +419 -0
- package/dist/indexing/providers/notion-api.js.map +1 -0
- package/dist/indexing/providers/notion.d.ts +29 -0
- package/dist/indexing/providers/notion.d.ts.map +1 -0
- package/dist/indexing/providers/notion.js +236 -0
- package/dist/indexing/providers/notion.js.map +1 -0
- package/dist/indexing/providers/slack-api.d.ts +62 -0
- package/dist/indexing/providers/slack-api.d.ts.map +1 -0
- package/dist/indexing/providers/slack-api.js +167 -0
- package/dist/indexing/providers/slack-api.js.map +1 -0
- package/dist/indexing/providers/slack.d.ts +21 -0
- package/dist/indexing/providers/slack.d.ts.map +1 -0
- package/dist/indexing/providers/slack.js +192 -0
- package/dist/indexing/providers/slack.js.map +1 -0
- package/dist/indexing/providers/types.d.ts +57 -0
- package/dist/indexing/providers/types.d.ts.map +1 -0
- package/dist/indexing/providers/types.js +3 -0
- package/dist/indexing/providers/types.js.map +1 -0
- package/dist/indexing/url-derivation.d.ts +2 -2
- package/dist/indexing/url-derivation.d.ts.map +1 -1
- package/dist/indexing/url-derivation.js.map +1 -1
- package/dist/indexing/utils.d.ts +19 -0
- package/dist/indexing/utils.d.ts.map +1 -0
- package/dist/indexing/utils.js +63 -0
- package/dist/indexing/utils.js.map +1 -0
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +4 -0
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tools/bash-fs.d.ts.map +1 -1
- package/dist/mcp/tools/bash-fs.js +4 -1
- package/dist/mcp/tools/bash-fs.js.map +1 -1
- package/dist/mcp/tools/knowledge.d.ts +13 -0
- package/dist/mcp/tools/knowledge.d.ts.map +1 -0
- package/dist/mcp/tools/knowledge.js +92 -0
- package/dist/mcp/tools/knowledge.js.map +1 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +111 -8
- package/dist/server.js.map +1 -1
- package/dist/types.d.ts +1075 -79
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +94 -4
- package/dist/types.js.map +1 -1
- package/dist/validate.d.ts +29 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +197 -0
- package/dist/validate.js.map +1 -0
- package/dist/webhooks/discord.d.ts +13 -0
- package/dist/webhooks/discord.d.ts.map +1 -0
- package/dist/webhooks/discord.js +57 -0
- package/dist/webhooks/discord.js.map +1 -0
- package/dist/webhooks/slack.d.ts +13 -0
- package/dist/webhooks/slack.d.ts.map +1 -0
- package/dist/webhooks/slack.js +106 -0
- package/dist/webhooks/slack.js.map +1 -0
- package/package.json +17 -3
- package/dist/indexing/source-indexer.d.ts +0 -68
- package/dist/indexing/source-indexer.d.ts.map +0 -1
- package/dist/indexing/source-indexer.js +0 -380
- package/dist/indexing/source-indexer.js.map +0 -1
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
// Slack Events API webhook handler for emoji-triggered reindexing.
|
|
2
|
+
// Handles URL verification challenges and reaction_added events.
|
|
3
|
+
import crypto from 'node:crypto';
|
|
4
|
+
import { getConfig, getServerConfig } from '../config.js';
|
|
5
|
+
import { isSlackSourceConfig } from '../types.js';
|
|
6
|
+
// ── Signature verification ───────────────────────────────────────────────────
|
|
7
|
+
export function verifySlackSignature(rawBody, timestamp, signature, signingSecret) {
|
|
8
|
+
if (!timestamp || !signature)
|
|
9
|
+
return false;
|
|
10
|
+
// Reject requests older than 5 minutes (replay protection)
|
|
11
|
+
const now = Math.floor(Date.now() / 1000);
|
|
12
|
+
if (Math.abs(now - parseInt(timestamp, 10)) > 300)
|
|
13
|
+
return false;
|
|
14
|
+
const sigBasestring = `v0:${timestamp}:${rawBody.toString('utf-8')}`;
|
|
15
|
+
const expected = 'v0=' + crypto
|
|
16
|
+
.createHmac('sha256', signingSecret)
|
|
17
|
+
.update(sigBasestring)
|
|
18
|
+
.digest('hex');
|
|
19
|
+
if (signature.length !== expected.length)
|
|
20
|
+
return false;
|
|
21
|
+
return crypto.timingSafeEqual(Buffer.from(signature, 'utf-8'), Buffer.from(expected, 'utf-8'));
|
|
22
|
+
}
|
|
23
|
+
// ── Factory ──────────────────────────────────────────────────────────────────
|
|
24
|
+
/**
|
|
25
|
+
* Create a Slack webhook handler wired to a specific orchestrator instance.
|
|
26
|
+
*/
|
|
27
|
+
export function createSlackWebhookHandler(orchestrator) {
|
|
28
|
+
return async function handleSlackWebhook(req, res) {
|
|
29
|
+
const cfg = getConfig();
|
|
30
|
+
// -- Raw body check ------------------------------------------------
|
|
31
|
+
const rawBody = Buffer.isBuffer(req.body) ? req.body : null;
|
|
32
|
+
if (!rawBody) {
|
|
33
|
+
console.error('[slack-webhook] req.body is not a Buffer — ensure the route uses express.raw()');
|
|
34
|
+
res.status(500).json({ error: 'Server misconfiguration: raw body not available' });
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
// -- Parse payload -------------------------------------------------
|
|
38
|
+
let payload;
|
|
39
|
+
try {
|
|
40
|
+
payload = JSON.parse(rawBody.toString('utf-8'));
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
res.status(400).json({ error: 'Malformed JSON payload' });
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
// -- URL verification challenge ------------------------------------
|
|
47
|
+
// Slack sends this during app setup; no signature verification needed
|
|
48
|
+
if (payload.type === 'url_verification') {
|
|
49
|
+
res.status(200).json({ challenge: payload.challenge });
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
// -- Signature verification ----------------------------------------
|
|
53
|
+
if (!cfg.slackSigningSecret?.trim()) {
|
|
54
|
+
console.log('[slack-webhook] Rejecting request — signing secret not configured');
|
|
55
|
+
res.status(403).json({ error: 'Forbidden' });
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
const timestamp = req.headers['x-slack-request-timestamp'];
|
|
59
|
+
const signature = req.headers['x-slack-signature'];
|
|
60
|
+
if (!verifySlackSignature(rawBody, timestamp, signature, cfg.slackSigningSecret)) {
|
|
61
|
+
res.status(401).json({ error: 'Invalid or missing Slack signature' });
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
// -- Event routing -------------------------------------------------
|
|
65
|
+
if (payload.type !== 'event_callback' || !payload.event) {
|
|
66
|
+
res.status(200).json({ ok: true, ignored: true, reason: 'not an event_callback' });
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
const event = payload.event;
|
|
70
|
+
if (event.type === 'reaction_added') {
|
|
71
|
+
const reactionEvent = event;
|
|
72
|
+
handleReactionAdded(reactionEvent, orchestrator);
|
|
73
|
+
// Respond immediately (Slack requires <3s)
|
|
74
|
+
res.status(200).json({ ok: true });
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
// Unknown event type — acknowledge but ignore
|
|
78
|
+
res.status(200).json({ ok: true, ignored: true, reason: `unhandled event type: ${event.type}` });
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
// ── Event handlers ───────────────────────────────────────────────────────────
|
|
82
|
+
function handleReactionAdded(event, orchestrator) {
|
|
83
|
+
const serverCfg = getServerConfig();
|
|
84
|
+
// Find Slack sources where this reaction matches the trigger emoji
|
|
85
|
+
// and the channel is in the configured channel list
|
|
86
|
+
const matchingSources = serverCfg.sources.filter(s => {
|
|
87
|
+
if (!isSlackSourceConfig(s))
|
|
88
|
+
return false;
|
|
89
|
+
if (s.trigger_emoji !== event.reaction)
|
|
90
|
+
return false;
|
|
91
|
+
if (!s.channels.includes(event.item.channel))
|
|
92
|
+
return false;
|
|
93
|
+
return true;
|
|
94
|
+
});
|
|
95
|
+
if (matchingSources.length === 0) {
|
|
96
|
+
console.log(`[slack-webhook] Reaction :${event.reaction}: on ${event.item.channel} ` +
|
|
97
|
+
`— no matching Slack source configured, ignoring`);
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
for (const source of matchingSources) {
|
|
101
|
+
console.log(`[slack-webhook] Reaction :${event.reaction}: on ${event.item.channel} ` +
|
|
102
|
+
`— queuing reindex for source "${source.name}"`);
|
|
103
|
+
orchestrator.queueSourceReindex(source.name);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=slack.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slack.js","sourceRoot":"","sources":["../../src/webhooks/slack.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@copilotkit/pathfinder",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "Agentic docs retrieval for AI agents — semantic search and filesystem exploration over your documentation and code via MCP.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -8,8 +8,17 @@
|
|
|
8
8
|
"url": "https://github.com/CopilotKit/pathfinder"
|
|
9
9
|
},
|
|
10
10
|
"homepage": "https://pathfinder.copilotkit.dev",
|
|
11
|
-
"keywords": [
|
|
12
|
-
|
|
11
|
+
"keywords": [
|
|
12
|
+
"mcp",
|
|
13
|
+
"ai",
|
|
14
|
+
"agents",
|
|
15
|
+
"documentation",
|
|
16
|
+
"search",
|
|
17
|
+
"rag",
|
|
18
|
+
"embeddings",
|
|
19
|
+
"copilotkit"
|
|
20
|
+
],
|
|
21
|
+
"license": "Elastic-2.0",
|
|
13
22
|
"main": "dist/index.js",
|
|
14
23
|
"bin": {
|
|
15
24
|
"pathfinder": "dist/cli.js"
|
|
@@ -33,10 +42,15 @@
|
|
|
33
42
|
"test": "vitest run"
|
|
34
43
|
},
|
|
35
44
|
"dependencies": {
|
|
45
|
+
"@discordjs/rest": "^2.6.1",
|
|
36
46
|
"@modelcontextprotocol/sdk": "^1.25.2",
|
|
47
|
+
"@notionhq/client": "^5.17.0",
|
|
48
|
+
"@slack/web-api": "^7.15.0",
|
|
37
49
|
"cheerio": "^1.2.0",
|
|
38
50
|
"commander": "^14.0.3",
|
|
39
51
|
"cors": "^2.8.5",
|
|
52
|
+
"discord-api-types": "^0.38.44",
|
|
53
|
+
"discord-interactions": "^4.4.0",
|
|
40
54
|
"dotenv": "^17.3.1",
|
|
41
55
|
"express": "^5.2.1",
|
|
42
56
|
"just-bash": "^2.14.0",
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import { EmbeddingClient } from './embeddings.js';
|
|
2
|
-
import type { SourceConfig } from '../types.js';
|
|
3
|
-
/**
|
|
4
|
-
* Check if file content has low semantic value (SVG paths, base64, minified code).
|
|
5
|
-
* Samples the first 8KB and checks the ratio of digits, dots, commas, semicolons,
|
|
6
|
-
* and equals signs. If >30% of characters are these low-value tokens, the file
|
|
7
|
-
* is likely SVG path data, base64, or minified code with no search value.
|
|
8
|
-
*/
|
|
9
|
-
export declare function hasLowSemanticValue(content: string): boolean;
|
|
10
|
-
/**
|
|
11
|
-
* Convert a glob pattern to a RegExp.
|
|
12
|
-
* Supports: ** (any path), * (any segment), ? (any char)
|
|
13
|
-
*/
|
|
14
|
-
export declare function globToRegex(pattern: string): RegExp;
|
|
15
|
-
/**
|
|
16
|
-
* Check if a relative file path matches the source's file_patterns (include)
|
|
17
|
-
* and does not match exclude_patterns.
|
|
18
|
-
*/
|
|
19
|
-
export declare function matchesPatterns(relPath: string, sourceConfig: SourceConfig): boolean;
|
|
20
|
-
export declare class SourceIndexer {
|
|
21
|
-
private sourceConfig;
|
|
22
|
-
private embeddingClient;
|
|
23
|
-
private cloneDir;
|
|
24
|
-
private githubToken?;
|
|
25
|
-
private logPrefix;
|
|
26
|
-
private skipDirs;
|
|
27
|
-
private maxFileSize;
|
|
28
|
-
constructor(sourceConfig: SourceConfig, embeddingClient: EmbeddingClient, cloneDir: string, githubToken?: string);
|
|
29
|
-
private isLocal;
|
|
30
|
-
/**
|
|
31
|
-
* Full re-index: for git-backed sources, clone/pull the repo; for local
|
|
32
|
-
* sources, read directly from the configured path. Then walk matching
|
|
33
|
-
* files, chunk, embed, and upsert.
|
|
34
|
-
*/
|
|
35
|
-
fullIndex(): Promise<void>;
|
|
36
|
-
/**
|
|
37
|
-
* Incremental index: re-index only files changed since lastCommitSha.
|
|
38
|
-
* Local sources always fall back to a full reindex.
|
|
39
|
-
*/
|
|
40
|
-
incrementalIndex(lastCommitSha: string): Promise<void>;
|
|
41
|
-
/**
|
|
42
|
-
* Get the current HEAD SHA of the cloned repo.
|
|
43
|
-
* For local sources, returns a deterministic hash based on the file
|
|
44
|
-
* listing and modification times, so unchanged content produces the
|
|
45
|
-
* same SHA across restarts.
|
|
46
|
-
*/
|
|
47
|
-
getHeadSha(): Promise<string>;
|
|
48
|
-
/**
|
|
49
|
-
* Compute a deterministic SHA for a local source directory based on
|
|
50
|
-
* the sorted list of file paths and their modification times.
|
|
51
|
-
* Note: uses mtimes, not file content — a fresh deploy with identical
|
|
52
|
-
* files but new mtimes will produce a different SHA and trigger reindex.
|
|
53
|
-
*/
|
|
54
|
-
private computeLocalSha;
|
|
55
|
-
/**
|
|
56
|
-
* Clone or pull the repo. Returns a SimpleGit instance pointed at the repo dir.
|
|
57
|
-
*/
|
|
58
|
-
private ensureRepo;
|
|
59
|
-
/**
|
|
60
|
-
* Recursively walk a directory for files, respecting skip_dirs and max_file_size.
|
|
61
|
-
*/
|
|
62
|
-
private walkFiles;
|
|
63
|
-
/**
|
|
64
|
-
* Read, chunk, embed, and upsert a single file.
|
|
65
|
-
*/
|
|
66
|
-
private indexFile;
|
|
67
|
-
}
|
|
68
|
-
//# sourceMappingURL=source-indexer.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"source-indexer.d.ts","sourceRoot":"","sources":["../../src/indexing/source-indexer.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAKlD,OAAO,KAAK,EAAsB,YAAY,EAAE,MAAM,aAAa,CAAC;AAEpE;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAqB5D;AA4BD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAWnD;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,GAAG,OAAO,CAmBpF;AAED,qBAAa,aAAa;IACtB,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,WAAW,CAAC,CAAS;IAE7B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,QAAQ,CAAc;IAC9B,OAAO,CAAC,WAAW,CAAS;gBAGxB,YAAY,EAAE,YAAY,EAC1B,eAAe,EAAE,eAAe,EAChC,QAAQ,EAAE,MAAM,EAChB,WAAW,CAAC,EAAE,MAAM;IAYxB,OAAO,CAAC,OAAO;IAIf;;;;OAIG;IACG,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAmDhC;;;OAGG;IACG,gBAAgB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA8F5D;;;;;OAKG;IACG,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IAWnC;;;;;OAKG;YACW,eAAe;IAc7B;;OAEG;YACW,UAAU;IA2BxB;;OAEG;YACW,SAAS;IAoCvB;;OAEG;YACW,SAAS;CA4C1B"}
|
|
@@ -1,380 +0,0 @@
|
|
|
1
|
-
// Unified source indexer — handles any source type (markdown, code, raw-text)
|
|
2
|
-
// by delegating to the chunker registry and URL derivation config.
|
|
3
|
-
import fs from 'node:fs';
|
|
4
|
-
import path from 'node:path';
|
|
5
|
-
import { createHash } from 'node:crypto';
|
|
6
|
-
import { simpleGit } from 'simple-git';
|
|
7
|
-
import { getChunker } from './chunking/index.js';
|
|
8
|
-
import { deriveUrl } from './url-derivation.js';
|
|
9
|
-
import { upsertChunks, deleteChunksByFile, } from '../db/queries.js';
|
|
10
|
-
/**
|
|
11
|
-
* Check if file content has low semantic value (SVG paths, base64, minified code).
|
|
12
|
-
* Samples the first 8KB and checks the ratio of digits, dots, commas, semicolons,
|
|
13
|
-
* and equals signs. If >30% of characters are these low-value tokens, the file
|
|
14
|
-
* is likely SVG path data, base64, or minified code with no search value.
|
|
15
|
-
*/
|
|
16
|
-
export function hasLowSemanticValue(content) {
|
|
17
|
-
if (content.length < 500)
|
|
18
|
-
return false;
|
|
19
|
-
const sample = content.slice(0, 8192);
|
|
20
|
-
let lowValueChars = 0;
|
|
21
|
-
for (let i = 0; i < sample.length; i++) {
|
|
22
|
-
const c = sample.charCodeAt(i);
|
|
23
|
-
if ((c >= 48 && c <= 57) || // 0-9
|
|
24
|
-
c === 46 || // .
|
|
25
|
-
c === 44 || // ,
|
|
26
|
-
c === 59 || // ;
|
|
27
|
-
c === 61 // =
|
|
28
|
-
) {
|
|
29
|
-
lowValueChars++;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
const ratio = lowValueChars / sample.length;
|
|
33
|
-
return ratio > 0.3;
|
|
34
|
-
}
|
|
35
|
-
const DEFAULT_SKIP_DIRS = new Set(['node_modules', 'dist', 'build', '.git']);
|
|
36
|
-
const DEFAULT_MAX_FILE_SIZE = 102400; // 100KB
|
|
37
|
-
/**
|
|
38
|
-
* Extract a directory-friendly repo name from a clone URL.
|
|
39
|
-
* https://github.com/CopilotKit/CopilotKit.git → CopilotKit
|
|
40
|
-
*/
|
|
41
|
-
function repoNameFromUrl(repoUrl) {
|
|
42
|
-
const last = repoUrl.split('/').pop() ?? '';
|
|
43
|
-
return last.replace(/\.git$/, '');
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Construct the authenticated (or plain) clone URL.
|
|
47
|
-
*/
|
|
48
|
-
function authenticatedUrl(repoUrl, githubToken) {
|
|
49
|
-
if (githubToken) {
|
|
50
|
-
return repoUrl.replace('https://github.com/', `https://x-access-token:${githubToken}@github.com/`);
|
|
51
|
-
}
|
|
52
|
-
return repoUrl;
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* Convert a glob pattern to a RegExp.
|
|
56
|
-
* Supports: ** (any path), * (any segment), ? (any char)
|
|
57
|
-
*/
|
|
58
|
-
export function globToRegex(pattern) {
|
|
59
|
-
let re = pattern
|
|
60
|
-
.replace(/[.+^${}()|[\]\\]/g, '\\$&') // escape regex chars (except * and ?)
|
|
61
|
-
.replace(/\*\*\//g, '{{GLOBSTAR_SLASH}}') // **/ = any path prefix (including empty)
|
|
62
|
-
.replace(/\*\*/g, '{{GLOBSTAR}}') // ** alone = anything
|
|
63
|
-
.replace(/\*/g, '[^/]*') // * = anything except /
|
|
64
|
-
.replace(/\?/g, '[^/]') // ? = single char except /
|
|
65
|
-
.replace(/\{\{GLOBSTAR_SLASH\}\}/g, '(?:.*/)?') // **/ = optional path prefix
|
|
66
|
-
.replace(/\{\{GLOBSTAR\}\}/g, '.*'); // ** = anything including /
|
|
67
|
-
return new RegExp(`^${re}$`);
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Check if a relative file path matches the source's file_patterns (include)
|
|
71
|
-
* and does not match exclude_patterns.
|
|
72
|
-
*/
|
|
73
|
-
export function matchesPatterns(relPath, sourceConfig) {
|
|
74
|
-
const normalized = relPath.replace(/\\/g, '/');
|
|
75
|
-
// Check excludes first (takes precedence)
|
|
76
|
-
const excludes = sourceConfig.exclude_patterns ?? [];
|
|
77
|
-
for (const pattern of excludes) {
|
|
78
|
-
if (globToRegex(pattern).test(normalized)) {
|
|
79
|
-
return false;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
// Must match at least one include pattern
|
|
83
|
-
for (const pattern of sourceConfig.file_patterns) {
|
|
84
|
-
if (globToRegex(pattern).test(normalized)) {
|
|
85
|
-
return true;
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
return false;
|
|
89
|
-
}
|
|
90
|
-
export class SourceIndexer {
|
|
91
|
-
sourceConfig;
|
|
92
|
-
embeddingClient;
|
|
93
|
-
cloneDir;
|
|
94
|
-
githubToken;
|
|
95
|
-
logPrefix;
|
|
96
|
-
skipDirs;
|
|
97
|
-
maxFileSize;
|
|
98
|
-
constructor(sourceConfig, embeddingClient, cloneDir, githubToken) {
|
|
99
|
-
this.sourceConfig = sourceConfig;
|
|
100
|
-
this.embeddingClient = embeddingClient;
|
|
101
|
-
this.cloneDir = cloneDir;
|
|
102
|
-
this.githubToken = githubToken;
|
|
103
|
-
this.logPrefix = `[source-indexer:${sourceConfig.name}]`;
|
|
104
|
-
this.skipDirs = new Set([...DEFAULT_SKIP_DIRS, ...(sourceConfig.skip_dirs ?? [])]);
|
|
105
|
-
this.maxFileSize = sourceConfig.max_file_size ?? DEFAULT_MAX_FILE_SIZE;
|
|
106
|
-
}
|
|
107
|
-
isLocal() {
|
|
108
|
-
return !this.sourceConfig.repo;
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* Full re-index: for git-backed sources, clone/pull the repo; for local
|
|
112
|
-
* sources, read directly from the configured path. Then walk matching
|
|
113
|
-
* files, chunk, embed, and upsert.
|
|
114
|
-
*/
|
|
115
|
-
async fullIndex() {
|
|
116
|
-
let repoDir;
|
|
117
|
-
let headSha;
|
|
118
|
-
if (this.isLocal()) {
|
|
119
|
-
repoDir = path.resolve(this.sourceConfig.path);
|
|
120
|
-
if (!fs.existsSync(repoDir)) {
|
|
121
|
-
throw new Error(`Local source path does not exist: ${repoDir}`);
|
|
122
|
-
}
|
|
123
|
-
headSha = await this.computeLocalSha(repoDir);
|
|
124
|
-
}
|
|
125
|
-
else {
|
|
126
|
-
const repoName = repoNameFromUrl(this.sourceConfig.repo);
|
|
127
|
-
repoDir = path.join(this.cloneDir, repoName);
|
|
128
|
-
const git = await this.ensureRepo(repoDir, repoName);
|
|
129
|
-
headSha = await git.revparse(['HEAD']);
|
|
130
|
-
}
|
|
131
|
-
const walkRoot = this.isLocal()
|
|
132
|
-
? repoDir
|
|
133
|
-
: path.join(repoDir, this.sourceConfig.path);
|
|
134
|
-
if (!fs.existsSync(walkRoot)) {
|
|
135
|
-
console.warn(`${this.logPrefix} Walk root not found at ${walkRoot}, skipping`);
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
138
|
-
const allFiles = await this.walkFiles(walkRoot);
|
|
139
|
-
const matchingFiles = allFiles.filter((absPath) => {
|
|
140
|
-
const relPath = path.relative(repoDir, absPath);
|
|
141
|
-
return matchesPatterns(relPath, this.sourceConfig);
|
|
142
|
-
});
|
|
143
|
-
const skipped = allFiles.length - matchingFiles.length;
|
|
144
|
-
console.log(`${this.logPrefix} Found ${matchingFiles.length} files for full index` +
|
|
145
|
-
(skipped > 0 ? ` (${skipped} excluded by patterns)` : ''));
|
|
146
|
-
for (const absPath of matchingFiles) {
|
|
147
|
-
const relPath = path.relative(repoDir, absPath);
|
|
148
|
-
try {
|
|
149
|
-
await this.indexFile(absPath, relPath, headSha);
|
|
150
|
-
}
|
|
151
|
-
catch (err) {
|
|
152
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
153
|
-
console.error(`${this.logPrefix} Failed to index ${relPath}: ${msg}`);
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
console.log(`${this.logPrefix} Full index complete (${matchingFiles.length} files)`);
|
|
157
|
-
}
|
|
158
|
-
/**
|
|
159
|
-
* Incremental index: re-index only files changed since lastCommitSha.
|
|
160
|
-
* Local sources always fall back to a full reindex.
|
|
161
|
-
*/
|
|
162
|
-
async incrementalIndex(lastCommitSha) {
|
|
163
|
-
if (this.isLocal()) {
|
|
164
|
-
console.log(`${this.logPrefix} Local source — falling back to full reindex`);
|
|
165
|
-
await this.fullIndex();
|
|
166
|
-
return;
|
|
167
|
-
}
|
|
168
|
-
const repoName = repoNameFromUrl(this.sourceConfig.repo);
|
|
169
|
-
const repoDir = path.join(this.cloneDir, repoName);
|
|
170
|
-
const git = await this.ensureRepo(repoDir, repoName);
|
|
171
|
-
const headSha = await git.revparse(['HEAD']);
|
|
172
|
-
if (headSha === lastCommitSha) {
|
|
173
|
-
console.log(`${this.logPrefix} No new commits, skipping incremental index`);
|
|
174
|
-
return;
|
|
175
|
-
}
|
|
176
|
-
// Unshallow the clone so git diff can see the old commit SHA
|
|
177
|
-
try {
|
|
178
|
-
await git.fetch(['--unshallow']);
|
|
179
|
-
}
|
|
180
|
-
catch (err) {
|
|
181
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
182
|
-
if (!msg.includes('unshallow') && !msg.includes('does not make sense')) {
|
|
183
|
-
console.warn(`${this.logPrefix} git fetch --unshallow failed:`, msg);
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
// Get list of changed files between last indexed commit and HEAD
|
|
187
|
-
let diffOutput;
|
|
188
|
-
try {
|
|
189
|
-
diffOutput = await git.diff(['--name-only', `${lastCommitSha}..HEAD`]);
|
|
190
|
-
}
|
|
191
|
-
catch (err) {
|
|
192
|
-
console.warn(`${this.logPrefix} git diff failed (shallow clone?), falling back to full reindex:`, err);
|
|
193
|
-
await this.fullIndex();
|
|
194
|
-
return;
|
|
195
|
-
}
|
|
196
|
-
const changedFiles = diffOutput
|
|
197
|
-
.split('\n')
|
|
198
|
-
.map((f) => f.trim())
|
|
199
|
-
.filter((f) => f.length > 0);
|
|
200
|
-
// Filter to files matching this source's patterns
|
|
201
|
-
const matchingChanged = changedFiles.filter((f) => matchesPatterns(f, this.sourceConfig));
|
|
202
|
-
if (matchingChanged.length === 0) {
|
|
203
|
-
console.log(`${this.logPrefix} No matching changes detected, skipping`);
|
|
204
|
-
return;
|
|
205
|
-
}
|
|
206
|
-
console.log(`${this.logPrefix} Incremental index: ${matchingChanged.length} changed files`);
|
|
207
|
-
// Get deleted files via diff with status
|
|
208
|
-
const diffStatusOutput = await git.diff([
|
|
209
|
-
'--name-status',
|
|
210
|
-
`${lastCommitSha}..HEAD`,
|
|
211
|
-
]);
|
|
212
|
-
const deletedFiles = diffStatusOutput
|
|
213
|
-
.split('\n')
|
|
214
|
-
.filter((line) => line.startsWith('D\t'))
|
|
215
|
-
.map((line) => line.slice(2).trim())
|
|
216
|
-
.filter((f) => matchesPatterns(f, this.sourceConfig));
|
|
217
|
-
// Delete chunks for removed files
|
|
218
|
-
if (deletedFiles.length > 0) {
|
|
219
|
-
console.log(`${this.logPrefix} Removing ${deletedFiles.length} deleted files from index`);
|
|
220
|
-
}
|
|
221
|
-
for (const relPath of deletedFiles) {
|
|
222
|
-
await deleteChunksByFile(this.sourceConfig.name, relPath);
|
|
223
|
-
}
|
|
224
|
-
// Re-index changed (non-deleted) files
|
|
225
|
-
const filesToIndex = matchingChanged.filter((f) => !deletedFiles.includes(f));
|
|
226
|
-
for (const relPath of filesToIndex) {
|
|
227
|
-
const absPath = path.join(repoDir, relPath);
|
|
228
|
-
if (fs.existsSync(absPath)) {
|
|
229
|
-
try {
|
|
230
|
-
const stat = await fs.promises.stat(absPath);
|
|
231
|
-
if (stat.size <= this.maxFileSize) {
|
|
232
|
-
await this.indexFile(absPath, relPath, headSha);
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
catch (err) {
|
|
236
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
237
|
-
console.error(`${this.logPrefix} Failed to index ${relPath}: ${msg}`);
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
console.log(`${this.logPrefix} Incremental index complete`);
|
|
242
|
-
}
|
|
243
|
-
/**
|
|
244
|
-
* Get the current HEAD SHA of the cloned repo.
|
|
245
|
-
* For local sources, returns a deterministic hash based on the file
|
|
246
|
-
* listing and modification times, so unchanged content produces the
|
|
247
|
-
* same SHA across restarts.
|
|
248
|
-
*/
|
|
249
|
-
async getHeadSha() {
|
|
250
|
-
if (this.isLocal()) {
|
|
251
|
-
const walkRoot = path.resolve(this.sourceConfig.path);
|
|
252
|
-
return this.computeLocalSha(walkRoot);
|
|
253
|
-
}
|
|
254
|
-
const repoName = repoNameFromUrl(this.sourceConfig.repo);
|
|
255
|
-
const repoDir = path.join(this.cloneDir, repoName);
|
|
256
|
-
const git = simpleGit(repoDir);
|
|
257
|
-
return git.revparse(['HEAD']);
|
|
258
|
-
}
|
|
259
|
-
/**
|
|
260
|
-
* Compute a deterministic SHA for a local source directory based on
|
|
261
|
-
* the sorted list of file paths and their modification times.
|
|
262
|
-
* Note: uses mtimes, not file content — a fresh deploy with identical
|
|
263
|
-
* files but new mtimes will produce a different SHA and trigger reindex.
|
|
264
|
-
*/
|
|
265
|
-
async computeLocalSha(walkRoot) {
|
|
266
|
-
const files = await this.walkFiles(walkRoot);
|
|
267
|
-
const hash = createHash('sha256');
|
|
268
|
-
for (const f of files.sort()) {
|
|
269
|
-
const stat = await fs.promises.stat(f);
|
|
270
|
-
hash.update(`${f}:${stat.mtimeMs}\n`);
|
|
271
|
-
}
|
|
272
|
-
return `local-${hash.digest('hex').slice(0, 12)}`;
|
|
273
|
-
}
|
|
274
|
-
// -----------------------------------------------------------------------
|
|
275
|
-
// Private helpers
|
|
276
|
-
// -----------------------------------------------------------------------
|
|
277
|
-
/**
|
|
278
|
-
* Clone or pull the repo. Returns a SimpleGit instance pointed at the repo dir.
|
|
279
|
-
*/
|
|
280
|
-
async ensureRepo(repoDir, repoName) {
|
|
281
|
-
await fs.promises.mkdir(this.cloneDir, { recursive: true });
|
|
282
|
-
const gitDir = path.join(repoDir, '.git');
|
|
283
|
-
if (fs.existsSync(gitDir)) {
|
|
284
|
-
console.log(`${this.logPrefix} Pulling latest changes for ${repoName}`);
|
|
285
|
-
const git = simpleGit(repoDir);
|
|
286
|
-
try {
|
|
287
|
-
await git.pull();
|
|
288
|
-
return git;
|
|
289
|
-
}
|
|
290
|
-
catch (err) {
|
|
291
|
-
console.warn(`${this.logPrefix} Corrupted repo at ${repoDir}, re-cloning:`, err);
|
|
292
|
-
await fs.promises.rm(repoDir, { recursive: true, force: true });
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
const authUrl = authenticatedUrl(this.sourceConfig.repo, this.githubToken);
|
|
296
|
-
console.log(`${this.logPrefix} Cloning ${this.sourceConfig.repo} into ${repoDir}`);
|
|
297
|
-
const git = simpleGit(this.cloneDir);
|
|
298
|
-
const cloneOpts = ['--depth=1'];
|
|
299
|
-
if (this.sourceConfig.branch) {
|
|
300
|
-
cloneOpts.push('--branch', this.sourceConfig.branch);
|
|
301
|
-
}
|
|
302
|
-
await git.clone(authUrl, repoName, cloneOpts);
|
|
303
|
-
return simpleGit(repoDir);
|
|
304
|
-
}
|
|
305
|
-
/**
|
|
306
|
-
* Recursively walk a directory for files, respecting skip_dirs and max_file_size.
|
|
307
|
-
*/
|
|
308
|
-
async walkFiles(dir) {
|
|
309
|
-
const results = [];
|
|
310
|
-
let entries;
|
|
311
|
-
try {
|
|
312
|
-
entries = await fs.promises.readdir(dir, { withFileTypes: true });
|
|
313
|
-
}
|
|
314
|
-
catch (err) {
|
|
315
|
-
console.warn(`${this.logPrefix} Unable to read directory ${dir}:`, err);
|
|
316
|
-
return results;
|
|
317
|
-
}
|
|
318
|
-
for (const entry of entries) {
|
|
319
|
-
if (this.skipDirs.has(entry.name))
|
|
320
|
-
continue;
|
|
321
|
-
const fullPath = path.join(dir, entry.name);
|
|
322
|
-
if (entry.isDirectory()) {
|
|
323
|
-
const nested = await this.walkFiles(fullPath);
|
|
324
|
-
results.push(...nested);
|
|
325
|
-
}
|
|
326
|
-
else if (entry.isFile()) {
|
|
327
|
-
// Skip files larger than max_file_size
|
|
328
|
-
try {
|
|
329
|
-
const stat = await fs.promises.stat(fullPath);
|
|
330
|
-
if (stat.size > this.maxFileSize)
|
|
331
|
-
continue;
|
|
332
|
-
}
|
|
333
|
-
catch (err) {
|
|
334
|
-
console.warn(`${this.logPrefix} Unable to stat ${fullPath}:`, err);
|
|
335
|
-
continue;
|
|
336
|
-
}
|
|
337
|
-
results.push(fullPath);
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
return results;
|
|
341
|
-
}
|
|
342
|
-
/**
|
|
343
|
-
* Read, chunk, embed, and upsert a single file.
|
|
344
|
-
*/
|
|
345
|
-
async indexFile(absPath, relPath, commitSha) {
|
|
346
|
-
const content = await fs.promises.readFile(absPath, 'utf-8');
|
|
347
|
-
if (hasLowSemanticValue(content)) {
|
|
348
|
-
return;
|
|
349
|
-
}
|
|
350
|
-
const chunker = getChunker(this.sourceConfig.type);
|
|
351
|
-
const chunkOutputs = chunker(content, relPath, this.sourceConfig);
|
|
352
|
-
if (chunkOutputs.length === 0) {
|
|
353
|
-
return;
|
|
354
|
-
}
|
|
355
|
-
const texts = chunkOutputs.map((c) => c.content);
|
|
356
|
-
const embeddings = await this.embeddingClient.embedBatch(texts);
|
|
357
|
-
const sourceUrl = deriveUrl(relPath, this.sourceConfig);
|
|
358
|
-
const chunks = chunkOutputs.map((chunk, i) => ({
|
|
359
|
-
source_name: this.sourceConfig.name,
|
|
360
|
-
source_url: sourceUrl,
|
|
361
|
-
title: chunk.title ?? null,
|
|
362
|
-
content: chunk.content,
|
|
363
|
-
embedding: embeddings[i],
|
|
364
|
-
repo_url: this.sourceConfig.repo ?? null,
|
|
365
|
-
file_path: relPath,
|
|
366
|
-
start_line: chunk.startLine ?? null,
|
|
367
|
-
end_line: chunk.endLine ?? null,
|
|
368
|
-
language: chunk.language ?? null,
|
|
369
|
-
chunk_index: chunk.chunkIndex,
|
|
370
|
-
metadata: chunk.headingPath ? { headingPath: chunk.headingPath } : {},
|
|
371
|
-
commit_sha: commitSha,
|
|
372
|
-
version: this.sourceConfig.version ?? null,
|
|
373
|
-
}));
|
|
374
|
-
// Delete existing chunks for this file first to remove stale entries
|
|
375
|
-
// (e.g., file shortened from 5 chunks to 3 — old chunks 3-4 would persist)
|
|
376
|
-
await deleteChunksByFile(this.sourceConfig.name, relPath);
|
|
377
|
-
await upsertChunks(chunks);
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
//# sourceMappingURL=source-indexer.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"source-indexer.js","sourceRoot":"","sources":["../../src/indexing/source-indexer.ts"],"names":[],"mappings":"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"}
|