ucn 3.8.11 → 3.8.12
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/.github/workflows/ci.yml +33 -0
- package/.github/workflows/publish.yml +67 -0
- package/README.md +5 -2
- package/core/project.js +30 -9
- package/languages/go.js +249 -216
- package/languages/java.js +303 -250
- package/languages/javascript.js +463 -412
- package/languages/python.js +189 -148
- package/languages/rust.js +394 -337
- package/languages/utils.js +89 -10
- package/mcp/server.js +43 -33
- package/package.json +1 -1
- package/.claude/scheduled_tasks.lock +0 -1
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
strategy:
|
|
13
|
+
matrix:
|
|
14
|
+
node-version: [18, 20, 22]
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
|
|
18
|
+
- name: Configure git identity for tests
|
|
19
|
+
run: |
|
|
20
|
+
git config --global user.email "ci@github.com"
|
|
21
|
+
git config --global user.name "CI"
|
|
22
|
+
|
|
23
|
+
- name: Use Node.js ${{ matrix.node-version }}
|
|
24
|
+
uses: actions/setup-node@v4
|
|
25
|
+
with:
|
|
26
|
+
node-version: ${{ matrix.node-version }}
|
|
27
|
+
cache: npm
|
|
28
|
+
|
|
29
|
+
- name: Install dependencies
|
|
30
|
+
run: npm ci
|
|
31
|
+
|
|
32
|
+
- name: Run tests
|
|
33
|
+
run: npm test
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
name: Publish
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags: ['v*']
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
id-token: write # Required for MCP Registry OIDC authentication
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
test:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
|
|
18
|
+
- name: Configure git identity for tests
|
|
19
|
+
run: |
|
|
20
|
+
git config --global user.email "ci@github.com"
|
|
21
|
+
git config --global user.name "CI"
|
|
22
|
+
|
|
23
|
+
- uses: actions/setup-node@v4
|
|
24
|
+
with:
|
|
25
|
+
node-version: 22
|
|
26
|
+
cache: npm
|
|
27
|
+
|
|
28
|
+
- run: npm ci
|
|
29
|
+
- run: npm test
|
|
30
|
+
|
|
31
|
+
publish-npm:
|
|
32
|
+
needs: test
|
|
33
|
+
runs-on: ubuntu-latest
|
|
34
|
+
steps:
|
|
35
|
+
- uses: actions/checkout@v4
|
|
36
|
+
|
|
37
|
+
- uses: actions/setup-node@v4
|
|
38
|
+
with:
|
|
39
|
+
node-version: 22
|
|
40
|
+
registry-url: https://registry.npmjs.org
|
|
41
|
+
|
|
42
|
+
- run: npm ci
|
|
43
|
+
- run: npm publish
|
|
44
|
+
env:
|
|
45
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
46
|
+
|
|
47
|
+
publish-mcp:
|
|
48
|
+
needs: publish-npm
|
|
49
|
+
runs-on: ubuntu-latest
|
|
50
|
+
permissions:
|
|
51
|
+
contents: read
|
|
52
|
+
id-token: write
|
|
53
|
+
steps:
|
|
54
|
+
- uses: actions/checkout@v4
|
|
55
|
+
|
|
56
|
+
- uses: actions/setup-node@v4
|
|
57
|
+
with:
|
|
58
|
+
node-version: 22
|
|
59
|
+
|
|
60
|
+
- name: Install mcp-publisher
|
|
61
|
+
run: npm install -g mcp-publisher
|
|
62
|
+
|
|
63
|
+
- name: Authenticate with MCP Registry via OIDC
|
|
64
|
+
run: mcp-publisher login github-oidc
|
|
65
|
+
|
|
66
|
+
- name: Publish to MCP Registry
|
|
67
|
+
run: mcp-publisher publish
|
package/README.md
CHANGED
|
@@ -188,7 +188,7 @@ function compareNames(a, b) {
|
|
|
188
188
|
|
|
189
189
|
## Testing and reliability
|
|
190
190
|
|
|
191
|
-
- **Fast** -
|
|
191
|
+
- **Fast** - uses incremental cache for optimal performance
|
|
192
192
|
- **Discipline** - every bug fix gets a regression test, test code is ~3x the source
|
|
193
193
|
- **Coverage** - every command, every supported language, every surface (CLI, MCP, interactive)
|
|
194
194
|
- **Systematic** - a harness exercises all command and flag combinations against real multi-language fixtures
|
|
@@ -345,7 +345,7 @@ Common Flags:
|
|
|
345
345
|
--class-name=X Scope to specific class (e.g., --class-name=Repository)
|
|
346
346
|
--include-methods Include method calls (obj.fn) in caller/callee analysis
|
|
347
347
|
--include-uncertain Include ambiguous/uncertain matches
|
|
348
|
-
--
|
|
348
|
+
--no-confidence Hide confidence scores (shown by default)
|
|
349
349
|
--min-confidence=N Filter edges below confidence threshold (0.0-1.0)
|
|
350
350
|
--include-exported Include exported symbols in deadcode
|
|
351
351
|
--no-regex Force plain text search (regex is default)
|
|
@@ -361,6 +361,9 @@ Common Flags:
|
|
|
361
361
|
--no-cache Disable caching
|
|
362
362
|
--clear-cache Clear cache before running
|
|
363
363
|
--base=<ref> Git ref for diff-impact (default: HEAD)
|
|
364
|
+
--staged Analyze staged changes (diff-impact)
|
|
365
|
+
--no-follow-symlinks Don't follow symbolic links
|
|
366
|
+
-i, --interactive Keep index in memory for multiple queries
|
|
364
367
|
```
|
|
365
368
|
|
|
366
369
|
---
|
package/core/project.js
CHANGED
|
@@ -306,17 +306,32 @@ class ProjectIndex {
|
|
|
306
306
|
|
|
307
307
|
// Detect bundled/minified files (webpack bundles, minified code)
|
|
308
308
|
// These are build artifacts, not user-written source code
|
|
309
|
-
|
|
309
|
+
// Count lines without splitting: count newlines + 1 (avoids allocating array)
|
|
310
|
+
let lineCount = 1;
|
|
311
|
+
let maxLineLen = 0;
|
|
312
|
+
let longLineCount = 0;
|
|
313
|
+
let lineStart = 0;
|
|
314
|
+
for (let ci = 0; ci < content.length; ci++) {
|
|
315
|
+
if (content.charCodeAt(ci) === 10) { // '\n'
|
|
316
|
+
const lineLen = ci - lineStart;
|
|
317
|
+
if (lineLen > maxLineLen) maxLineLen = lineLen;
|
|
318
|
+
if (lineLen > 1000) longLineCount++;
|
|
319
|
+
lineStart = ci + 1;
|
|
320
|
+
lineCount++;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
// Handle last line (no trailing newline)
|
|
324
|
+
const lastLineLen = content.length - lineStart;
|
|
325
|
+
if (lastLineLen > maxLineLen) maxLineLen = lastLineLen;
|
|
326
|
+
if (lastLineLen > 1000) longLineCount++;
|
|
327
|
+
|
|
310
328
|
const isBundled = (() => {
|
|
311
329
|
// Webpack bundles contain __webpack_require__ or __webpack_modules__
|
|
312
330
|
if (content.includes('__webpack_require__') || content.includes('__webpack_modules__')) return true;
|
|
313
331
|
// Minified files: very few lines but large content (avg > 500 chars/line)
|
|
314
|
-
if (
|
|
332
|
+
if (lineCount > 0 && lineCount < 50 && content.length / lineCount > 500) return true;
|
|
315
333
|
// Very long single lines (> 1000 chars) in most of the file suggest minification
|
|
316
|
-
if (
|
|
317
|
-
const longLines = contentLines.filter(l => l.length > 1000).length;
|
|
318
|
-
if (longLines > 0 && longLines / contentLines.length > 0.3) return true;
|
|
319
|
-
}
|
|
334
|
+
if (lineCount > 0 && longLineCount > 0 && longLineCount / lineCount > 0.3) return true;
|
|
320
335
|
return false;
|
|
321
336
|
})();
|
|
322
337
|
|
|
@@ -324,7 +339,7 @@ class ProjectIndex {
|
|
|
324
339
|
path: filePath,
|
|
325
340
|
relativePath: path.relative(this.root, filePath),
|
|
326
341
|
language,
|
|
327
|
-
lines:
|
|
342
|
+
lines: lineCount,
|
|
328
343
|
hash,
|
|
329
344
|
mtime: stat.mtimeMs,
|
|
330
345
|
size: stat.size,
|
|
@@ -1778,8 +1793,14 @@ class ProjectIndex {
|
|
|
1778
1793
|
getLineContent(filePath, lineNum) {
|
|
1779
1794
|
try {
|
|
1780
1795
|
const content = this._readFile(filePath);
|
|
1781
|
-
|
|
1782
|
-
|
|
1796
|
+
// Find the Nth line without splitting the entire file
|
|
1797
|
+
let start = 0;
|
|
1798
|
+
for (let i = 1; i < lineNum; i++) {
|
|
1799
|
+
start = content.indexOf('\n', start) + 1;
|
|
1800
|
+
if (start === 0) return '';
|
|
1801
|
+
}
|
|
1802
|
+
const end = content.indexOf('\n', start);
|
|
1803
|
+
return end === -1 ? content.slice(start) : content.slice(start, end);
|
|
1783
1804
|
} catch (e) {
|
|
1784
1805
|
return '';
|
|
1785
1806
|
}
|