dsh-plugin-codegraph-tree-sitter 0.5.1 → 0.5.3
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/lib/index.d.ts +13 -0
- package/lib/index.js +75 -5
- package/package.json +2 -2
package/lib/index.d.ts
CHANGED
|
@@ -73,6 +73,17 @@ export declare const DEFAULT_EXCLUDE: string[];
|
|
|
73
73
|
export declare const DEFAULT_MAX_FILE_BYTES = 2000000;
|
|
74
74
|
/** Default ceiling on how many files one run indexes. */
|
|
75
75
|
export declare const DEFAULT_MAX_FILES = 50000;
|
|
76
|
+
/**
|
|
77
|
+
* How many candidate source files a workspace may contain before a **session-start** index declines
|
|
78
|
+
* to run (default 8,000).
|
|
79
|
+
*
|
|
80
|
+
* `maxFiles` above is the bound for a run someone asked for; this one guards the run nobody asked
|
|
81
|
+
* for. A session opened with `cwd` pointing at a home directory or a tool's own data directory can
|
|
82
|
+
* cover tens of thousands of files — a real case reached 21,752 under `~/.dsh`, under the 50,000
|
|
83
|
+
* ceiling, and the Tree-sitter WASM heap died mid-parse while the desktop froze. Declining early
|
|
84
|
+
* costs one `readdir` pass; declining late costs the whole machine.
|
|
85
|
+
*/
|
|
86
|
+
export declare const DEFAULT_AUTO_INDEX_MAX_FILES = 8000;
|
|
76
87
|
/** Default number of files parsed concurrently. */
|
|
77
88
|
export declare const DEFAULT_CONCURRENCY = 4;
|
|
78
89
|
/** Default quiet period after the last change before a watch-triggered refresh runs. */
|
|
@@ -175,6 +186,8 @@ export interface Config {
|
|
|
175
186
|
* Requires the host's `jobs` service: the build is never run synchronously inside session creation,
|
|
176
187
|
* so a composition without background jobs simply schedules nothing.
|
|
177
188
|
*/
|
|
189
|
+
/** Cap on candidate source files a session-start scan may find before it declines to index. */
|
|
190
|
+
autoIndexMaxFiles?: number;
|
|
178
191
|
autoIndexOnSession?: boolean;
|
|
179
192
|
/**
|
|
180
193
|
* How stale an existing index may be before a new session refreshes it in the background (default
|
package/lib/index.js
CHANGED
|
@@ -28,12 +28,13 @@
|
|
|
28
28
|
* @module dsh-plugin-codegraph-tree-sitter
|
|
29
29
|
*/
|
|
30
30
|
import { readFileSync } from 'node:fs';
|
|
31
|
+
import { readdir } from 'node:fs/promises';
|
|
31
32
|
import { stat } from 'node:fs/promises';
|
|
32
|
-
import { join } from 'node:path';
|
|
33
|
+
import { join, posix } from 'node:path';
|
|
33
34
|
import z from '@deepseek-ai/schemastery';
|
|
34
35
|
import { CodegraphIndexerId, INDEX_STATUS_RELATIVE_PATH } from 'dsh-plugin-codegraph-service';
|
|
35
|
-
import { LANGUAGE_TABLE } from "./languages.js";
|
|
36
|
-
import { walkAndExtract } from "./walk.js";
|
|
36
|
+
import { LANGUAGE_TABLE, languageFor } from "./languages.js";
|
|
37
|
+
import { isExcluded, walkAndExtract } from "./walk.js";
|
|
37
38
|
import { writeParseCache } from "./cache.js";
|
|
38
39
|
import { resolveWorkspace } from "./resolve.js";
|
|
39
40
|
import { writeGraph } from "./schema.js";
|
|
@@ -77,6 +78,17 @@ export const DEFAULT_EXCLUDE = ['node_modules', 'dist', 'build', 'coverage', '.g
|
|
|
77
78
|
export const DEFAULT_MAX_FILE_BYTES = 2_000_000;
|
|
78
79
|
/** Default ceiling on how many files one run indexes. */
|
|
79
80
|
export const DEFAULT_MAX_FILES = 50_000;
|
|
81
|
+
/**
|
|
82
|
+
* How many candidate source files a workspace may contain before a **session-start** index declines
|
|
83
|
+
* to run (default 8,000).
|
|
84
|
+
*
|
|
85
|
+
* `maxFiles` above is the bound for a run someone asked for; this one guards the run nobody asked
|
|
86
|
+
* for. A session opened with `cwd` pointing at a home directory or a tool's own data directory can
|
|
87
|
+
* cover tens of thousands of files — a real case reached 21,752 under `~/.dsh`, under the 50,000
|
|
88
|
+
* ceiling, and the Tree-sitter WASM heap died mid-parse while the desktop froze. Declining early
|
|
89
|
+
* costs one `readdir` pass; declining late costs the whole machine.
|
|
90
|
+
*/
|
|
91
|
+
export const DEFAULT_AUTO_INDEX_MAX_FILES = 8_000;
|
|
80
92
|
/** Default number of files parsed concurrently. */
|
|
81
93
|
export const DEFAULT_CONCURRENCY = 4;
|
|
82
94
|
/** Default quiet period after the last change before a watch-triggered refresh runs. */
|
|
@@ -100,6 +112,8 @@ export const Config = z.object({
|
|
|
100
112
|
watch: z.boolean().default(true),
|
|
101
113
|
watchDebounceMs: z.number().default(DEFAULT_WATCH_DEBOUNCE_MS),
|
|
102
114
|
maxWatchedDirectories: z.number().default(DEFAULT_MAX_WATCHED_DIRECTORIES),
|
|
115
|
+
/** Cap on candidate source files a session-start scan may find before it declines to index. */
|
|
116
|
+
autoIndexMaxFiles: z.number().default(DEFAULT_AUTO_INDEX_MAX_FILES),
|
|
103
117
|
autoIndexOnSession: z.boolean().default(true),
|
|
104
118
|
autoRefreshAfterMs: z.number().default(DEFAULT_AUTO_REFRESH_AFTER_MS),
|
|
105
119
|
});
|
|
@@ -248,7 +262,7 @@ function autoIndexOnSession(ctx, config, lastAutoRun, payload) {
|
|
|
248
262
|
owner: agent.id,
|
|
249
263
|
kind: AUTO_INDEX_JOB_KIND,
|
|
250
264
|
label: `codegraph auto index ${root}`,
|
|
251
|
-
run: handle => runAutoIndexJob(ctx, root, handle),
|
|
265
|
+
run: handle => runAutoIndexJob(ctx, root, config, handle),
|
|
252
266
|
});
|
|
253
267
|
// Marked only after the registry accepted the job, so a transient refusal leaves the workspace
|
|
254
268
|
// eligible for the next session that opens in it.
|
|
@@ -260,6 +274,53 @@ function autoIndexOnSession(ctx, config, lastAutoRun, payload) {
|
|
|
260
274
|
console.error(`codegraph-tree-sitter: automatic indexing for a new session failed: ${String(error)}`);
|
|
261
275
|
}
|
|
262
276
|
}
|
|
277
|
+
/**
|
|
278
|
+
* How many candidate source files `root` holds, when that is past the session-start limit.
|
|
279
|
+
*
|
|
280
|
+
* Deliberately a **bounded directory walk that never reads a file**: it counts what `discover` would
|
|
281
|
+
* hand the parser and stops one past the limit. The alternative — starting the real run and bailing
|
|
282
|
+
* when memory runs out — is what froze the machine this guard exists to prevent.
|
|
283
|
+
* @param root - absolute workspace path.
|
|
284
|
+
* @param config - the resolved plugin configuration (for the limit and the exclude list).
|
|
285
|
+
* @param signal - aborts the walk.
|
|
286
|
+
* @returns the count once it exceeds the limit, or `undefined` when the workspace is small enough.
|
|
287
|
+
*/
|
|
288
|
+
async function exceedsAutoIndexLimit(root, config, signal) {
|
|
289
|
+
const excluded = new Set(config.exclude);
|
|
290
|
+
const limit = config.autoIndexMaxFiles;
|
|
291
|
+
let count = 0;
|
|
292
|
+
async function scan(relativeDir) {
|
|
293
|
+
signal.throwIfAborted();
|
|
294
|
+
let entries;
|
|
295
|
+
try {
|
|
296
|
+
entries = await readdir(posix.join(root, relativeDir), { withFileTypes: true });
|
|
297
|
+
}
|
|
298
|
+
catch {
|
|
299
|
+
// An unreadable directory contributes nothing to a count that exists to protect against size.
|
|
300
|
+
return false;
|
|
301
|
+
}
|
|
302
|
+
for (const entry of entries) {
|
|
303
|
+
const relativePath = relativeDir === '' ? entry.name : `${relativeDir}/${entry.name}`;
|
|
304
|
+
if (isExcluded(entry.name, relativePath, entry.isDirectory(), excluded, []))
|
|
305
|
+
continue;
|
|
306
|
+
if (entry.isDirectory()) {
|
|
307
|
+
if (await scan(relativePath))
|
|
308
|
+
return true;
|
|
309
|
+
continue;
|
|
310
|
+
}
|
|
311
|
+
if (!entry.isFile())
|
|
312
|
+
continue;
|
|
313
|
+
const spec = languageFor(posix.extname(entry.name));
|
|
314
|
+
if (spec === undefined)
|
|
315
|
+
continue;
|
|
316
|
+
count += 1;
|
|
317
|
+
if (count > limit)
|
|
318
|
+
return true;
|
|
319
|
+
}
|
|
320
|
+
return false;
|
|
321
|
+
}
|
|
322
|
+
return (await scan('')) ? count : undefined;
|
|
323
|
+
}
|
|
263
324
|
/**
|
|
264
325
|
* When the workspace's sidecar says its index was built.
|
|
265
326
|
* @param root - the workspace root.
|
|
@@ -289,10 +350,19 @@ function readStatusIndexedAt(root) {
|
|
|
289
350
|
* @param handle - the job's producer face, for the job's live log.
|
|
290
351
|
* @returns the job's cancellation hook and settlement promise.
|
|
291
352
|
*/
|
|
292
|
-
function runAutoIndexJob(ctx, root, handle) {
|
|
353
|
+
function runAutoIndexJob(ctx, root, config, handle) {
|
|
293
354
|
const controller = new AbortController();
|
|
294
355
|
const done = (async () => {
|
|
295
356
|
try {
|
|
357
|
+
const oversized = await exceedsAutoIndexLimit(root, config, controller.signal);
|
|
358
|
+
if (oversized !== undefined) {
|
|
359
|
+
// Declining here is the whole point of the check: parsing this workspace would exhaust the
|
|
360
|
+
// WASM heap and take the desktop down with it, and an automatic index is a convenience.
|
|
361
|
+
handle.append(`Skipped automatic indexing of ${root}: it holds at least ${String(oversized)} candidate ` +
|
|
362
|
+
`source files, past the ${String(config.autoIndexMaxFiles)}-file session-start limit. ` +
|
|
363
|
+
`Run codegraph_index yourself if you want a graph for it.\n`);
|
|
364
|
+
return { status: 'failed', detail: 'workspace too large for automatic indexing' };
|
|
365
|
+
}
|
|
296
366
|
const report = await ctx.codegraph.index(root, controller.signal);
|
|
297
367
|
handle.append(`Indexed ${root}: ${report.filesIndexed} files, ${report.nodeCount} symbols, ` +
|
|
298
368
|
`${report.edgeCount} relationships.\n`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-plugin-codegraph-tree-sitter",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.3",
|
|
4
4
|
"description": "Self-built code-graph indexer for DeepSeek Harness — parses a workspace with web-tree-sitter and writes schema version 4 to .codegraph/codegraph.db, the same on-disk format the codegraph CLI writes, so no external indexer is required",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"dsh",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"@deepseek-ai/schemastery": "^3.18.1",
|
|
52
52
|
"tree-sitter-wasms": "^0.1.13",
|
|
53
53
|
"web-tree-sitter": "^0.25.10",
|
|
54
|
-
"dsh-plugin-codegraph-service": "^0.5.
|
|
54
|
+
"dsh-plugin-codegraph-service": "^0.5.3"
|
|
55
55
|
},
|
|
56
56
|
"peerDependencies": {
|
|
57
57
|
"@deepseek-ai/cordis": ">=4.0.1",
|