wavescope-mcp 1.0.2
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 +131 -0
- package/dist/context.d.ts +97 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +429 -0
- package/dist/context.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +216 -0
- package/dist/index.js.map +1 -0
- package/dist/language.d.ts +41 -0
- package/dist/language.d.ts.map +1 -0
- package/dist/language.js +398 -0
- package/dist/language.js.map +1 -0
- package/dist/project.d.ts +34 -0
- package/dist/project.d.ts.map +1 -0
- package/dist/project.js +343 -0
- package/dist/project.js.map +1 -0
- package/dist/signal.d.ts +9 -0
- package/dist/signal.d.ts.map +1 -0
- package/dist/signal.js +267 -0
- package/dist/signal.js.map +1 -0
- package/dist/wavelet.d.ts +46 -0
- package/dist/wavelet.d.ts.map +1 -0
- package/dist/wavelet.js +141 -0
- package/dist/wavelet.js.map +1 -0
- package/package.json +43 -0
package/dist/project.js
ADDED
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
import { readdir, readFile, lstat, stat, realpath } from "node:fs/promises";
|
|
2
|
+
import { open } from "node:fs/promises";
|
|
3
|
+
import { join, basename, extname, relative, resolve, sep } from "node:path";
|
|
4
|
+
import { FileContext } from "./context.js";
|
|
5
|
+
import { configs } from "./language.js";
|
|
6
|
+
const CODE_EXTENSIONS = new Set(configs.flatMap((c) => c.extensions));
|
|
7
|
+
const SKIP_DIRS = new Set([
|
|
8
|
+
"node_modules",
|
|
9
|
+
".git",
|
|
10
|
+
"__pycache__",
|
|
11
|
+
".venv",
|
|
12
|
+
"venv",
|
|
13
|
+
"dist",
|
|
14
|
+
"build",
|
|
15
|
+
"target",
|
|
16
|
+
".next",
|
|
17
|
+
".turbo",
|
|
18
|
+
"coverage",
|
|
19
|
+
".pytest_cache",
|
|
20
|
+
".cache",
|
|
21
|
+
".idea",
|
|
22
|
+
".vscode",
|
|
23
|
+
"vendor",
|
|
24
|
+
"out",
|
|
25
|
+
"obj",
|
|
26
|
+
".gradle",
|
|
27
|
+
".tox",
|
|
28
|
+
".mypy_cache",
|
|
29
|
+
".ruff_cache",
|
|
30
|
+
"bower_components",
|
|
31
|
+
".serverless",
|
|
32
|
+
".terraform",
|
|
33
|
+
".eggs",
|
|
34
|
+
"site-packages",
|
|
35
|
+
".yarn",
|
|
36
|
+
".parcel-cache",
|
|
37
|
+
"__snapshots__",
|
|
38
|
+
]);
|
|
39
|
+
export const MAX_FILE_BYTES = 2_000_000;
|
|
40
|
+
export const MAX_FILES = 5_000;
|
|
41
|
+
const BINARY_SNIFF_BYTES = 4096;
|
|
42
|
+
// ─── Project cache (TTL + LRU eviction) ─────────────────────
|
|
43
|
+
const CACHE_TTL_MS = 60_000;
|
|
44
|
+
const MAX_PROJECT_CACHE = 20;
|
|
45
|
+
const projectCache = new Map();
|
|
46
|
+
const pendingLoads = new Map();
|
|
47
|
+
function evictProjectCache() {
|
|
48
|
+
if (projectCache.size > MAX_PROJECT_CACHE) {
|
|
49
|
+
const entries = [...projectCache.entries()].sort((a, b) => a[1].timestamp - b[1].timestamp);
|
|
50
|
+
const toDelete = entries.slice(0, projectCache.size - MAX_PROJECT_CACHE);
|
|
51
|
+
for (const [key] of toDelete)
|
|
52
|
+
projectCache.delete(key);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// ─── ProjectIndex ───────────────────────────────────────────
|
|
56
|
+
/**
|
|
57
|
+
* Project-level wavelet index across multiple files.
|
|
58
|
+
*
|
|
59
|
+
* Results are cached with a 60-second TTL to avoid expensive
|
|
60
|
+
* re-indexing on repeated calls.
|
|
61
|
+
*/
|
|
62
|
+
export class ProjectIndex {
|
|
63
|
+
root;
|
|
64
|
+
files;
|
|
65
|
+
/** True when discovery stopped at MAX_FILES — index is incomplete. */
|
|
66
|
+
truncated;
|
|
67
|
+
fileMap;
|
|
68
|
+
constructor(root, files, truncated) {
|
|
69
|
+
this.root = root;
|
|
70
|
+
this.files = files;
|
|
71
|
+
this.truncated = truncated;
|
|
72
|
+
this.fileMap = new Map(files.map((f) => {
|
|
73
|
+
const relPath = relative(root, f.path);
|
|
74
|
+
return [relPath, f.context];
|
|
75
|
+
}));
|
|
76
|
+
}
|
|
77
|
+
static async load(root) {
|
|
78
|
+
const resolved = resolve(root);
|
|
79
|
+
const cached = projectCache.get(resolved);
|
|
80
|
+
if (cached && Date.now() - cached.timestamp < CACHE_TTL_MS) {
|
|
81
|
+
return cached.project;
|
|
82
|
+
}
|
|
83
|
+
const pending = pendingLoads.get(resolved);
|
|
84
|
+
if (pending)
|
|
85
|
+
return pending;
|
|
86
|
+
const loadPromise = (async () => {
|
|
87
|
+
try {
|
|
88
|
+
const { files, truncated } = await discoverFiles(resolved);
|
|
89
|
+
const project = new ProjectIndex(resolved, files, truncated);
|
|
90
|
+
evictProjectCache();
|
|
91
|
+
projectCache.set(resolved, { project, timestamp: Date.now() });
|
|
92
|
+
return project;
|
|
93
|
+
}
|
|
94
|
+
finally {
|
|
95
|
+
pendingLoads.delete(resolved);
|
|
96
|
+
}
|
|
97
|
+
})();
|
|
98
|
+
pendingLoads.set(resolved, loadPromise);
|
|
99
|
+
return loadPromise;
|
|
100
|
+
}
|
|
101
|
+
getFile(relPath) {
|
|
102
|
+
return this.fileMap.get(relPath) ?? null;
|
|
103
|
+
}
|
|
104
|
+
listFiles() {
|
|
105
|
+
return this.files.map((f) => relative(this.root, f.path));
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Project-wide important positions across all files.
|
|
109
|
+
*
|
|
110
|
+
* Uses raw absolute wavelet coefficients (same semantics as
|
|
111
|
+
* single-file `FileContext.getImportantPositions`) so that
|
|
112
|
+
* `minCoefficient` means the same thing in both modes.
|
|
113
|
+
*/
|
|
114
|
+
getImportantPositions(minCoefficient = 0.3, limit = 20) {
|
|
115
|
+
const allPeaks = [];
|
|
116
|
+
for (const file of this.files) {
|
|
117
|
+
const peaks = file.context.getImportantPositions(minCoefficient, Math.max(limit, 30));
|
|
118
|
+
if (peaks.length === 0)
|
|
119
|
+
continue;
|
|
120
|
+
const fileRelPath = relative(this.root, file.path);
|
|
121
|
+
for (const p of peaks) {
|
|
122
|
+
allPeaks.push({
|
|
123
|
+
...p,
|
|
124
|
+
label: `${p.label} (${fileRelPath})`,
|
|
125
|
+
filename: fileRelPath,
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
allPeaks.sort((a, b) => Math.abs(b.coefficient) - Math.abs(a.coefficient));
|
|
130
|
+
return allPeaks.slice(0, limit);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
async function loadGitignore(root) {
|
|
134
|
+
const path = join(root, ".gitignore");
|
|
135
|
+
let raw;
|
|
136
|
+
try {
|
|
137
|
+
raw = await readFile(path, "utf8");
|
|
138
|
+
}
|
|
139
|
+
catch {
|
|
140
|
+
return [];
|
|
141
|
+
}
|
|
142
|
+
const rules = [];
|
|
143
|
+
for (const lineRaw of raw.split("\n")) {
|
|
144
|
+
const line = lineRaw.trim();
|
|
145
|
+
if (!line || line.startsWith("#") || line.startsWith("!"))
|
|
146
|
+
continue;
|
|
147
|
+
const dirOnly = line.endsWith("/");
|
|
148
|
+
const pat = dirOnly ? line.slice(0, -1) : line;
|
|
149
|
+
rules.push({ regex: compileGlob(pat), dirOnly });
|
|
150
|
+
}
|
|
151
|
+
return rules;
|
|
152
|
+
}
|
|
153
|
+
function compileGlob(pat) {
|
|
154
|
+
// Anchor: leading `/` means root-relative; otherwise match any depth.
|
|
155
|
+
const anchored = pat.startsWith("/");
|
|
156
|
+
const body = anchored ? pat.slice(1) : pat;
|
|
157
|
+
let regex = "";
|
|
158
|
+
let i = 0;
|
|
159
|
+
while (i < body.length) {
|
|
160
|
+
const c = body[i];
|
|
161
|
+
if (c === "*" && body[i + 1] === "*") {
|
|
162
|
+
regex += ".*";
|
|
163
|
+
i += 2;
|
|
164
|
+
if (body[i] === "/")
|
|
165
|
+
i++;
|
|
166
|
+
}
|
|
167
|
+
else if (c === "*") {
|
|
168
|
+
regex += "[^/]*";
|
|
169
|
+
i++;
|
|
170
|
+
}
|
|
171
|
+
else if (c === "?") {
|
|
172
|
+
regex += "[^/]";
|
|
173
|
+
i++;
|
|
174
|
+
}
|
|
175
|
+
else if (".+()[]{}^$|\\".includes(c)) {
|
|
176
|
+
regex += "\\" + c;
|
|
177
|
+
i++;
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
regex += c;
|
|
181
|
+
i++;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
const prefix = anchored ? "^" : "(^|/)";
|
|
185
|
+
return new RegExp(`${prefix}${regex}(/|$)`);
|
|
186
|
+
}
|
|
187
|
+
function isIgnored(relPath, isDir, rules) {
|
|
188
|
+
const normalized = relPath.split(sep).join("/");
|
|
189
|
+
for (const rule of rules) {
|
|
190
|
+
if (rule.dirOnly && !isDir)
|
|
191
|
+
continue;
|
|
192
|
+
if (rule.regex.test(normalized))
|
|
193
|
+
return true;
|
|
194
|
+
// Also test path with trailing slash for dir-only rules
|
|
195
|
+
if (rule.dirOnly && rule.regex.test(normalized + "/"))
|
|
196
|
+
return true;
|
|
197
|
+
}
|
|
198
|
+
return false;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Sniff the first BINARY_SNIFF_BYTES for NUL bytes — the standard
|
|
202
|
+
* heuristic for distinguishing text from binary files.
|
|
203
|
+
*/
|
|
204
|
+
async function isBinary(fullPath) {
|
|
205
|
+
let fh;
|
|
206
|
+
try {
|
|
207
|
+
fh = await open(fullPath, "r");
|
|
208
|
+
const buf = Buffer.alloc(BINARY_SNIFF_BYTES);
|
|
209
|
+
const { bytesRead } = await fh.read(buf, 0, BINARY_SNIFF_BYTES, 0);
|
|
210
|
+
for (let i = 0; i < bytesRead; i++) {
|
|
211
|
+
if (buf[i] === 0)
|
|
212
|
+
return true;
|
|
213
|
+
}
|
|
214
|
+
return false;
|
|
215
|
+
}
|
|
216
|
+
catch {
|
|
217
|
+
return true;
|
|
218
|
+
}
|
|
219
|
+
finally {
|
|
220
|
+
await fh?.close();
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
async function discoverFiles(root) {
|
|
224
|
+
const results = [];
|
|
225
|
+
const visitedRealpaths = new Set();
|
|
226
|
+
let rootRealpath;
|
|
227
|
+
try {
|
|
228
|
+
rootRealpath = await realpath(root);
|
|
229
|
+
}
|
|
230
|
+
catch (err) {
|
|
231
|
+
const e = err;
|
|
232
|
+
const wrapped = new Error(`Cannot read directory: ${root}`);
|
|
233
|
+
wrapped.code = e.code;
|
|
234
|
+
throw wrapped;
|
|
235
|
+
}
|
|
236
|
+
visitedRealpaths.add(rootRealpath);
|
|
237
|
+
const gitignore = await loadGitignore(root);
|
|
238
|
+
let truncated = false;
|
|
239
|
+
// Concurrency-bounded file processor
|
|
240
|
+
const pending = [];
|
|
241
|
+
async function walk(dir) {
|
|
242
|
+
if (truncated)
|
|
243
|
+
return;
|
|
244
|
+
let entries;
|
|
245
|
+
try {
|
|
246
|
+
entries = await readdir(dir);
|
|
247
|
+
}
|
|
248
|
+
catch {
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
for (const entry of entries) {
|
|
252
|
+
if (truncated)
|
|
253
|
+
return;
|
|
254
|
+
const fullPath = join(dir, entry);
|
|
255
|
+
const relPath = relative(root, fullPath);
|
|
256
|
+
let entryStat;
|
|
257
|
+
try {
|
|
258
|
+
entryStat = await lstat(fullPath);
|
|
259
|
+
}
|
|
260
|
+
catch {
|
|
261
|
+
continue;
|
|
262
|
+
}
|
|
263
|
+
// Resolve symlinks: follow them, but refuse ones that escape the
|
|
264
|
+
// root. Dedup happens below in the dir/file branches via realpath.
|
|
265
|
+
if (entryStat.isSymbolicLink()) {
|
|
266
|
+
let target;
|
|
267
|
+
try {
|
|
268
|
+
target = await realpath(fullPath);
|
|
269
|
+
}
|
|
270
|
+
catch {
|
|
271
|
+
continue;
|
|
272
|
+
}
|
|
273
|
+
if (!target.startsWith(rootRealpath + sep) && target !== rootRealpath) {
|
|
274
|
+
continue;
|
|
275
|
+
}
|
|
276
|
+
try {
|
|
277
|
+
entryStat = await stat(target);
|
|
278
|
+
}
|
|
279
|
+
catch {
|
|
280
|
+
continue;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
if (entryStat.isDirectory()) {
|
|
284
|
+
if (SKIP_DIRS.has(entry))
|
|
285
|
+
continue;
|
|
286
|
+
if (isIgnored(relPath, true, gitignore))
|
|
287
|
+
continue;
|
|
288
|
+
let dirReal;
|
|
289
|
+
try {
|
|
290
|
+
dirReal = await realpath(fullPath);
|
|
291
|
+
}
|
|
292
|
+
catch {
|
|
293
|
+
continue;
|
|
294
|
+
}
|
|
295
|
+
if (visitedRealpaths.has(dirReal))
|
|
296
|
+
continue;
|
|
297
|
+
visitedRealpaths.add(dirReal);
|
|
298
|
+
await walk(fullPath);
|
|
299
|
+
}
|
|
300
|
+
else if (entryStat.isFile()) {
|
|
301
|
+
if (isIgnored(relPath, false, gitignore))
|
|
302
|
+
continue;
|
|
303
|
+
const ext = extname(entry).toLowerCase();
|
|
304
|
+
if (!CODE_EXTENSIONS.has(ext))
|
|
305
|
+
continue;
|
|
306
|
+
if (entryStat.size > MAX_FILE_BYTES)
|
|
307
|
+
continue;
|
|
308
|
+
if (results.length + pending.length >= MAX_FILES) {
|
|
309
|
+
truncated = true;
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
pending.push({ fullPath, size: entryStat.size });
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
await walk(root);
|
|
317
|
+
// Parallel binary-sniff + read + FileContext construction with bounded pool
|
|
318
|
+
const CONCURRENCY = 8;
|
|
319
|
+
let cursor = 0;
|
|
320
|
+
async function worker() {
|
|
321
|
+
while (cursor < pending.length) {
|
|
322
|
+
const idx = cursor++;
|
|
323
|
+
const { fullPath } = pending[idx];
|
|
324
|
+
if (await isBinary(fullPath))
|
|
325
|
+
continue;
|
|
326
|
+
let content;
|
|
327
|
+
try {
|
|
328
|
+
content = await readFile(fullPath, "utf8");
|
|
329
|
+
}
|
|
330
|
+
catch {
|
|
331
|
+
continue;
|
|
332
|
+
}
|
|
333
|
+
results.push({
|
|
334
|
+
filename: basename(fullPath),
|
|
335
|
+
path: fullPath,
|
|
336
|
+
context: new FileContext(basename(fullPath), content),
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
await Promise.all(Array.from({ length: Math.min(CONCURRENCY, pending.length) }, () => worker()));
|
|
341
|
+
return { files: results, truncated };
|
|
342
|
+
}
|
|
343
|
+
//# sourceMappingURL=project.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project.js","sourceRoot":"","sources":["../src/project.ts"],"names":[],"mappings":"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"}
|
package/dist/signal.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { LanguageConfig } from "./language.js";
|
|
2
|
+
/**
|
|
3
|
+
* NOTE: callers must pass a complete file (all lines), not a slice.
|
|
4
|
+
* `inBlockComment` / `inDocString` state spans lines but is initialized
|
|
5
|
+
* fresh per call, so a partial file would yield incorrect comment
|
|
6
|
+
* classification.
|
|
7
|
+
*/
|
|
8
|
+
export declare function computeSignal(lines: string[], lang: LanguageConfig): number[];
|
|
9
|
+
//# sourceMappingURL=signal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signal.d.ts","sourceRoot":"","sources":["../src/signal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAoC/C;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,MAAM,EAAE,EACf,IAAI,EAAE,cAAc,GACnB,MAAM,EAAE,CAyJV"}
|
package/dist/signal.js
ADDED
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mask the interior of single-line string and char literals with spaces
|
|
3
|
+
* so that downstream comment / token detection ignores their contents.
|
|
4
|
+
* Handles single-quote, double-quote, and backtick (template) literals
|
|
5
|
+
* with backslash escapes. Multi-line strings are out of scope — caller
|
|
6
|
+
* passes a single physical line.
|
|
7
|
+
*/
|
|
8
|
+
function maskStringLiterals(line) {
|
|
9
|
+
const chars = line.split("");
|
|
10
|
+
let i = 0;
|
|
11
|
+
while (i < chars.length) {
|
|
12
|
+
const c = chars[i];
|
|
13
|
+
if (c === '"' || c === "'" || c === "`") {
|
|
14
|
+
const quote = c;
|
|
15
|
+
let j = i + 1;
|
|
16
|
+
while (j < chars.length) {
|
|
17
|
+
if (chars[j] === "\\" && j + 1 < chars.length) {
|
|
18
|
+
chars[j] = " ";
|
|
19
|
+
chars[j + 1] = " ";
|
|
20
|
+
j += 2;
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
if (chars[j] === quote)
|
|
24
|
+
break;
|
|
25
|
+
chars[j] = " ";
|
|
26
|
+
j++;
|
|
27
|
+
}
|
|
28
|
+
i = j + 1;
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
i++;
|
|
32
|
+
}
|
|
33
|
+
return chars.join("");
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* NOTE: callers must pass a complete file (all lines), not a slice.
|
|
37
|
+
* `inBlockComment` / `inDocString` state spans lines but is initialized
|
|
38
|
+
* fresh per call, so a partial file would yield incorrect comment
|
|
39
|
+
* classification.
|
|
40
|
+
*/
|
|
41
|
+
export function computeSignal(lines, lang) {
|
|
42
|
+
const signal = new Array(lines.length);
|
|
43
|
+
let inBlockComment = false;
|
|
44
|
+
let blockCommentDepth = 0;
|
|
45
|
+
let inDocString = false;
|
|
46
|
+
let docStringDelim = null;
|
|
47
|
+
for (let i = 0; i < lines.length; i++) {
|
|
48
|
+
const raw = lines[i];
|
|
49
|
+
const trimmed = raw.trimStart();
|
|
50
|
+
const indent = raw.length - trimmed.length;
|
|
51
|
+
const stripped = trimmed.trimEnd();
|
|
52
|
+
// String-masked version used for comment/keyword detection; original
|
|
53
|
+
// line drives indent/length calculations.
|
|
54
|
+
const masked = maskStringLiterals(stripped);
|
|
55
|
+
// ── Handle multiline comments / docstrings (continued from previous line) ──
|
|
56
|
+
if (inBlockComment) {
|
|
57
|
+
if (lang.blockCommentUsesParenDepth) {
|
|
58
|
+
let depth = blockCommentDepth;
|
|
59
|
+
let closeIdx = -1;
|
|
60
|
+
for (let ci = 0; ci < masked.length; ci++) {
|
|
61
|
+
if (masked[ci] === "(")
|
|
62
|
+
depth++;
|
|
63
|
+
else if (masked[ci] === ")") {
|
|
64
|
+
depth--;
|
|
65
|
+
if (depth === 0) {
|
|
66
|
+
closeIdx = ci;
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
if (closeIdx !== -1) {
|
|
72
|
+
inBlockComment = false;
|
|
73
|
+
blockCommentDepth = 0;
|
|
74
|
+
const after = stripped.slice(closeIdx + 1);
|
|
75
|
+
if (after.trim()) {
|
|
76
|
+
signal[i] = scoreLine(raw, after.trim(), indent, lang);
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
signal[i] = 0;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
blockCommentDepth = depth;
|
|
84
|
+
signal[i] = 0;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
const endIdx = masked.indexOf(lang.blockCommentEnd);
|
|
89
|
+
if (endIdx !== -1) {
|
|
90
|
+
inBlockComment = false;
|
|
91
|
+
const after = stripped.slice(endIdx + lang.blockCommentEnd.length);
|
|
92
|
+
if (after.trim()) {
|
|
93
|
+
signal[i] = scoreLine(raw, after.trim(), indent, lang);
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
signal[i] = 0;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
signal[i] = 0;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
if (inDocString) {
|
|
106
|
+
const endIdx = masked.indexOf(docStringDelim);
|
|
107
|
+
if (endIdx !== -1) {
|
|
108
|
+
inDocString = false;
|
|
109
|
+
docStringDelim = null;
|
|
110
|
+
const after = stripped.slice(endIdx + 3);
|
|
111
|
+
if (after.trim()) {
|
|
112
|
+
signal[i] = scoreLine(raw, after.trim(), indent, lang);
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
signal[i] = 0;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
signal[i] = 0;
|
|
120
|
+
}
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
// ── Detect new Python docstrings (triple quotes) ──
|
|
124
|
+
// Python's triple quotes are scanned on the unmasked stripped line
|
|
125
|
+
// because maskStringLiterals would have consumed them as regular strings.
|
|
126
|
+
if (lang.name === "python") {
|
|
127
|
+
const dqIdx = Math.min(stripped.indexOf('"""') === -1 ? Infinity : stripped.indexOf('"""'), stripped.indexOf("'''") === -1 ? Infinity : stripped.indexOf("'''"));
|
|
128
|
+
if (Number.isFinite(dqIdx)) {
|
|
129
|
+
const delim = stripped.slice(dqIdx, dqIdx + 3);
|
|
130
|
+
const before = stripped.slice(0, dqIdx).trim();
|
|
131
|
+
const after = stripped.slice(dqIdx + 3);
|
|
132
|
+
const hasClosing = after.includes(delim);
|
|
133
|
+
if (hasClosing) {
|
|
134
|
+
const real = [before, after.replaceAll(delim, "").trim()]
|
|
135
|
+
.filter(Boolean).join("; ");
|
|
136
|
+
signal[i] = real ? scoreLine(raw, real, indent, lang) : 0;
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
inDocString = true;
|
|
140
|
+
docStringDelim = delim;
|
|
141
|
+
signal[i] = before ? scoreLine(raw, before, indent, lang) : 0;
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
// ── Detect block comment start (anywhere on line, including inline) ──
|
|
146
|
+
const bcStartIdx = lang.blockCommentAtLineStart
|
|
147
|
+
? (masked.startsWith(lang.blockCommentStart) ? 0 : -1)
|
|
148
|
+
: masked.indexOf(lang.blockCommentStart);
|
|
149
|
+
if (bcStartIdx !== -1) {
|
|
150
|
+
const before = stripped.slice(0, bcStartIdx).trim();
|
|
151
|
+
const afterDelim = masked.slice(bcStartIdx + lang.blockCommentStart.length);
|
|
152
|
+
const afterDelimRaw = stripped.slice(bcStartIdx + lang.blockCommentStart.length);
|
|
153
|
+
let endIdx = -1;
|
|
154
|
+
if (lang.blockCommentUsesParenDepth) {
|
|
155
|
+
let depth = 1;
|
|
156
|
+
for (let ci = 0; ci < afterDelim.length; ci++) {
|
|
157
|
+
if (afterDelim[ci] === "(")
|
|
158
|
+
depth++;
|
|
159
|
+
else if (afterDelim[ci] === ")") {
|
|
160
|
+
depth--;
|
|
161
|
+
if (depth === 0) {
|
|
162
|
+
endIdx = ci;
|
|
163
|
+
break;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
endIdx = afterDelim.indexOf(lang.blockCommentEnd);
|
|
170
|
+
}
|
|
171
|
+
if (endIdx !== -1) {
|
|
172
|
+
const after = afterDelimRaw.slice(endIdx + lang.blockCommentEnd.length).trim();
|
|
173
|
+
const real = [before, after].filter(Boolean).join("; ");
|
|
174
|
+
signal[i] = real ? scoreLine(raw, real, indent, lang) : 0;
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
inBlockComment = true;
|
|
178
|
+
blockCommentDepth = lang.blockCommentUsesParenDepth ? 1 : 0;
|
|
179
|
+
signal[i] = before ? scoreLine(raw, before, indent, lang) : 0;
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
// ── Single-line comments ──
|
|
183
|
+
const isComment = lang.commentPrefixes.some((p) => {
|
|
184
|
+
if (!masked.startsWith(p))
|
|
185
|
+
return false;
|
|
186
|
+
// PHP 8 attributes: `#[...]` is NOT a comment.
|
|
187
|
+
if (p === "#" && masked.startsWith("#["))
|
|
188
|
+
return false;
|
|
189
|
+
return true;
|
|
190
|
+
});
|
|
191
|
+
if (isComment || masked.length === 0) {
|
|
192
|
+
signal[i] = 0;
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
signal[i] = scoreLine(raw, stripped, indent, lang);
|
|
196
|
+
}
|
|
197
|
+
return signal;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Token splitter: splits on whitespace, brackets, braces, parens, commas,
|
|
201
|
+
* semicolons, colons, quotes, backticks, arithmetic, logical, and bitwise
|
|
202
|
+
* operators. Does NOT split on `.`, `-`, `?`, `!` — so:
|
|
203
|
+
* - `obj.class` stays one token (preventing member-access keyword leaks);
|
|
204
|
+
* - `extend-type`, `defmulti`, `defined?` survive as single tokens.
|
|
205
|
+
*/
|
|
206
|
+
function tokenize(line) {
|
|
207
|
+
return line.split(/[\s()[\]{},;:'"`=<>+*/&|^~%@#\\]+/);
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Score a single line of actual code (no comments).
|
|
211
|
+
*/
|
|
212
|
+
function scoreLine(raw, stripped, rawIndent, lang) {
|
|
213
|
+
let score = 0;
|
|
214
|
+
// Strip string literals first so quoted `//` URLs and quoted `/*` don't
|
|
215
|
+
// confuse keyword / inline-comment scanning.
|
|
216
|
+
let codeOnly = maskStringLiterals(stripped);
|
|
217
|
+
// Strip inline single-line comment suffix
|
|
218
|
+
for (const prefix of lang.commentPrefixes) {
|
|
219
|
+
let idx = -1;
|
|
220
|
+
let from = 0;
|
|
221
|
+
while (from < codeOnly.length) {
|
|
222
|
+
const next = codeOnly.indexOf(prefix, from);
|
|
223
|
+
if (next === -1)
|
|
224
|
+
break;
|
|
225
|
+
// PHP 8 attribute: `#[...]` is not a comment
|
|
226
|
+
if (prefix === "#" && codeOnly[next + 1] === "[") {
|
|
227
|
+
from = next + 1;
|
|
228
|
+
continue;
|
|
229
|
+
}
|
|
230
|
+
idx = next;
|
|
231
|
+
break;
|
|
232
|
+
}
|
|
233
|
+
if (idx !== -1) {
|
|
234
|
+
codeOnly = codeOnly.slice(0, idx).trim();
|
|
235
|
+
break;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
// Indent: expand tabs as 4 spaces so tab-indented files (Go, etc.)
|
|
239
|
+
// score comparably to space-indented ones.
|
|
240
|
+
const leading = raw.slice(0, rawIndent);
|
|
241
|
+
let expandedIndent = 0;
|
|
242
|
+
for (const ch of leading)
|
|
243
|
+
expandedIndent += ch === "\t" ? 4 : 1;
|
|
244
|
+
const indentLevel = Math.min(expandedIndent / 4, 8);
|
|
245
|
+
score += indentLevel * lang.indentWeight;
|
|
246
|
+
const tokens = tokenize(codeOnly);
|
|
247
|
+
for (const token of tokens) {
|
|
248
|
+
if (!token)
|
|
249
|
+
continue;
|
|
250
|
+
const kwWeight = lang.structuralKeywords[token];
|
|
251
|
+
if (kwWeight !== undefined)
|
|
252
|
+
score += kwWeight;
|
|
253
|
+
}
|
|
254
|
+
// Decorators / annotations: line-start `@`, Rust `#[...]`, PHP 8 `#[...]`,
|
|
255
|
+
// or inline `@Annotation` (e.g. Java `public @Nullable String foo()`).
|
|
256
|
+
if (lang.decoratorWeight > 0) {
|
|
257
|
+
const startsWithAt = codeOnly.startsWith("@");
|
|
258
|
+
const rustAttr = lang.name === "rust" && codeOnly.startsWith("#[");
|
|
259
|
+
const phpAttr = lang.name === "php" && codeOnly.startsWith("#[");
|
|
260
|
+
const inlineAt = /(^|\s)@[A-Za-z_]/.test(codeOnly);
|
|
261
|
+
if (startsWithAt || rustAttr || phpAttr || inlineAt) {
|
|
262
|
+
score += lang.decoratorWeight;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
return Math.min(score, 2.0);
|
|
266
|
+
}
|
|
267
|
+
//# sourceMappingURL=signal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signal.js","sourceRoot":"","sources":["../src/signal.ts"],"names":[],"mappings":"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"}
|