@unerr-ai/unerr 0.2.1 → 0.2.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/README.md +36 -45
- package/dist/cli.js +37443 -36022
- package/package.json +2 -1
- package/dist/behaviors/agent-llm-bridge.js +0 -166
- package/dist/behaviors/architecture-guard.js +0 -256
- package/dist/behaviors/auto-doc.js +0 -247
- package/dist/behaviors/cascade-guard.js +0 -289
- package/dist/behaviors/change-narrative.js +0 -270
- package/dist/behaviors/convention-drift.js +0 -290
- package/dist/behaviors/framework.js +0 -235
- package/dist/behaviors/guard-formatter.js +0 -44
- package/dist/behaviors/incomplete-work.js +0 -270
- package/dist/behaviors/loop-breaker.js +0 -300
- package/dist/behaviors/session-continuity.js +0 -208
- package/dist/commands/branches.js +0 -97
- package/dist/commands/check-commit.js +0 -225
- package/dist/commands/compress-output.js +0 -64
- package/dist/commands/config-verify.js +0 -243
- package/dist/commands/daemon.js +0 -905
- package/dist/commands/dashboard.js +0 -52
- package/dist/commands/debug.js +0 -200
- package/dist/commands/enrich.js +0 -184
- package/dist/commands/exec.js +0 -233
- package/dist/commands/gain.js +0 -156
- package/dist/commands/hook.js +0 -88
- package/dist/commands/index.js +0 -88
- package/dist/commands/init.js +0 -74
- package/dist/commands/install.js +0 -505
- package/dist/commands/learn.js +0 -116
- package/dist/commands/manifest.js +0 -193
- package/dist/commands/rewind.js +0 -103
- package/dist/commands/serve.js +0 -19
- package/dist/commands/setup-wizard.js +0 -414
- package/dist/commands/skills.js +0 -64
- package/dist/commands/stats.js +0 -20
- package/dist/commands/status.js +0 -654
- package/dist/commands/timeline.js +0 -139
- package/dist/commands/uninstall.js +0 -230
- package/dist/components/App.js +0 -109
- package/dist/components/Banner.js +0 -12
- package/dist/components/ConfirmPrompt.js +0 -25
- package/dist/components/DriftSummary.js +0 -23
- package/dist/components/GradeBadge.js +0 -15
- package/dist/components/HealthCard.js +0 -18
- package/dist/components/InkSpinner.js +0 -22
- package/dist/components/InputBox.js +0 -17
- package/dist/components/KeyValue.js +0 -13
- package/dist/components/MessageList.js +0 -14
- package/dist/components/ProgressBar.js +0 -26
- package/dist/components/Section.js +0 -16
- package/dist/components/SessionSummaryCard.js +0 -73
- package/dist/components/StartupDisplay.js +0 -24
- package/dist/components/StatusDashboard.js +0 -57
- package/dist/components/StatusLine.js +0 -8
- package/dist/components/StepLine.js +0 -22
- package/dist/components/Theme.js +0 -20
- package/dist/components/ToolProgress.js +0 -8
- package/dist/components/ViolationList.js +0 -21
- package/dist/components/render.js +0 -13
- package/dist/config/agent-registry.js +0 -237
- package/dist/config/claude-settings-hooks.js +0 -304
- package/dist/config/hook-installer.js +0 -65
- package/dist/config/instruction-writer.js +0 -388
- package/dist/config/mcp-config-writer.js +0 -266
- package/dist/config/settings.js +0 -174
- package/dist/config/tool-detector.js +0 -42
- package/dist/config/value-surfacing.js +0 -119
- package/dist/core/context-assembly.js +0 -108
- package/dist/core/conversation.js +0 -33
- package/dist/core/local-chat-provider.js +0 -475
- package/dist/core/provider-factory.js +0 -55
- package/dist/core/providers.js +0 -90
- package/dist/core/query-engine.js +0 -174
- package/dist/daemon/api.js +0 -312
- package/dist/daemon/autostart.js +0 -119
- package/dist/daemon/bootstrap.js +0 -39
- package/dist/daemon/client.js +0 -164
- package/dist/daemon/detect-ci.js +0 -81
- package/dist/daemon/platform-linux.js +0 -146
- package/dist/daemon/platform-macos.js +0 -134
- package/dist/daemon/platform-windows.js +0 -116
- package/dist/daemon/process-manager.js +0 -299
- package/dist/daemon/protocol.js +0 -23
- package/dist/daemon/registry.js +0 -270
- package/dist/daemon/settings-schema.js +0 -72
- package/dist/daemon/system-health.js +0 -134
- package/dist/daemon/version-checker.js +0 -262
- package/dist/daemon/warm-start.js +0 -223
- package/dist/entrypoints/cli.js +0 -1043
- package/dist/entrypoints/daemon.js +0 -380
- package/dist/entrypoints/repl.js +0 -147
- package/dist/hooks/adapters/claude-code.js +0 -90
- package/dist/hooks/adapters/cline.js +0 -100
- package/dist/hooks/adapters/cursor.js +0 -98
- package/dist/hooks/hook-dedup.js +0 -79
- package/dist/hooks/hook-runner.js +0 -113
- package/dist/hooks/navigation-hooks.js +0 -175
- package/dist/hooks/prompt-hooks.js +0 -63
- package/dist/hooks/shell-hooks.js +0 -47
- package/dist/ignore.js +0 -111
- package/dist/intelligence/approach-suggester.js +0 -61
- package/dist/intelligence/ast-extractor.js +0 -2615
- package/dist/intelligence/ast-worker.js +0 -34
- package/dist/intelligence/background-indexer.js +0 -121
- package/dist/intelligence/blast-radius.js +0 -200
- package/dist/intelligence/community-detection.js +0 -691
- package/dist/intelligence/community-detector.js +0 -184
- package/dist/intelligence/computation-scheduler.js +0 -75
- package/dist/intelligence/confidence-propagation.js +0 -47
- package/dist/intelligence/convention-detector.js +0 -242
- package/dist/intelligence/convention-learner.js +0 -205
- package/dist/intelligence/convention-matcher.js +0 -205
- package/dist/intelligence/cozo-schema.js +0 -376
- package/dist/intelligence/decision-point-detector.js +0 -90
- package/dist/intelligence/deep-dive-tools.js +0 -586
- package/dist/intelligence/durability-scorer.js +0 -84
- package/dist/intelligence/exploration-cost.js +0 -204
- package/dist/intelligence/exploration-pattern-tracker.js +0 -61
- package/dist/intelligence/fact-generator.js +0 -322
- package/dist/intelligence/facts-schema.js +0 -90
- package/dist/intelligence/file-intelligence.js +0 -59
- package/dist/intelligence/graph-holder.js +0 -220
- package/dist/intelligence/graph-temporal-joiner.js +0 -238
- package/dist/intelligence/health-grade.js +0 -423
- package/dist/intelligence/health-grader.js +0 -200
- package/dist/intelligence/health-map-data.js +0 -259
- package/dist/intelligence/import-symbols.js +0 -136
- package/dist/intelligence/incremental-indexer.js +0 -658
- package/dist/intelligence/indexer/centrality.js +0 -62
- package/dist/intelligence/indexer/cfg-context.js +0 -95
- package/dist/intelligence/indexer/confidence.js +0 -34
- package/dist/intelligence/indexer/cross-file-resolver.js +0 -104
- package/dist/intelligence/indexer/edge-repair.js +0 -89
- package/dist/intelligence/indexer/entity-key.js +0 -17
- package/dist/intelligence/indexer/export-map.js +0 -132
- package/dist/intelligence/indexer/git-cochange.js +0 -128
- package/dist/intelligence/indexer/graph-patch.js +0 -147
- package/dist/intelligence/indexer/incremental.js +0 -78
- package/dist/intelligence/indexer/ingest.js +0 -160
- package/dist/intelligence/indexer/language-detect.js +0 -226
- package/dist/intelligence/indexer/metadata.js +0 -63
- package/dist/intelligence/indexer/mutation-tracker.js +0 -79
- package/dist/intelligence/indexer/orchestrator.js +0 -155
- package/dist/intelligence/indexer/plugin-interface.js +0 -31
- package/dist/intelligence/indexer/plugins/csharp.js +0 -440
- package/dist/intelligence/indexer/plugins/go.js +0 -335
- package/dist/intelligence/indexer/plugins/java.js +0 -370
- package/dist/intelligence/indexer/plugins/python.js +0 -358
- package/dist/intelligence/indexer/plugins/regex-fallback.js +0 -82
- package/dist/intelligence/indexer/plugins/ruby.js +0 -290
- package/dist/intelligence/indexer/plugins/rust.js +0 -484
- package/dist/intelligence/indexer/plugins/tier2-generic.js +0 -310
- package/dist/intelligence/indexer/plugins/typescript.js +0 -456
- package/dist/intelligence/indexer/resource-monitor.js +0 -93
- package/dist/intelligence/indexer/scip/decoder.js +0 -253
- package/dist/intelligence/indexer/scip/detector.js +0 -232
- package/dist/intelligence/indexer/scip/downloader.js +0 -427
- package/dist/intelligence/indexer/scip/fallback.js +0 -34
- package/dist/intelligence/indexer/scip/merger.js +0 -109
- package/dist/intelligence/indexer/scip/orchestrator.js +0 -433
- package/dist/intelligence/indexer/scip/runner.js +0 -98
- package/dist/intelligence/indexer/snapshot.js +0 -66
- package/dist/intelligence/indexer/test-detector.js +0 -196
- package/dist/intelligence/indexer/watch-integration.js +0 -61
- package/dist/intelligence/indexer/worker.js +0 -85
- package/dist/intelligence/local-convention-detector.js +0 -437
- package/dist/intelligence/local-embeddings.js +0 -190
- package/dist/intelligence/local-graph.js +0 -1946
- package/dist/intelligence/local-indexer.js +0 -1575
- package/dist/intelligence/local-llm.js +0 -163
- package/dist/intelligence/local-rule-generator.js +0 -154
- package/dist/intelligence/local-snapshot.js +0 -213
- package/dist/intelligence/negative-knowledge.js +0 -103
- package/dist/intelligence/persistent-db.js +0 -85
- package/dist/intelligence/query-router.js +0 -2556
- package/dist/intelligence/risk-classifier.js +0 -116
- package/dist/intelligence/rule-evaluator.js +0 -380
- package/dist/intelligence/rule-generator.js +0 -49
- package/dist/intelligence/search-index.js +0 -173
- package/dist/intelligence/semantic/docstring-extractor.js +0 -67
- package/dist/intelligence/semantic/embedding-store.js +0 -52
- package/dist/intelligence/semantic/enrichment-orchestrator.js +0 -48
- package/dist/intelligence/semantic/git-message-miner.js +0 -114
- package/dist/intelligence/semantic/identifier-tokenizer.js +0 -51
- package/dist/intelligence/semantic/node2vec-embeddings.js +0 -71
- package/dist/intelligence/semantic/node2vec-walks.js +0 -103
- package/dist/intelligence/semantic/path-domain-inference.js +0 -112
- package/dist/intelligence/semantic/similarity-engine.js +0 -60
- package/dist/intelligence/semantic/tfidf-vectors.js +0 -88
- package/dist/intelligence/session-brief-builder.js +0 -159
- package/dist/intelligence/session-context.js +0 -221
- package/dist/intelligence/session-health-monitor.js +0 -211
- package/dist/intelligence/session-narrative.js +0 -197
- package/dist/intelligence/session-pattern-analyzer.js +0 -218
- package/dist/intelligence/signal-scorer.js +0 -390
- package/dist/intelligence/signal-show-store.js +0 -182
- package/dist/intelligence/smart-truncate.js +0 -158
- package/dist/intelligence/subgraph-cache.js +0 -88
- package/dist/intelligence/temporal-facts.js +0 -494
- package/dist/intelligence/token-estimator.js +0 -100
- package/dist/intelligence/tool-injector.js +0 -87
- package/dist/intelligence/tree-sitter-loader.js +0 -71
- package/dist/intelligence/worker-pool.js +0 -116
- package/dist/proxy/arg-validator.js +0 -79
- package/dist/proxy/auto-bootstrap.js +0 -167
- package/dist/proxy/bridge.js +0 -147
- package/dist/proxy/budget-enforcer.js +0 -70
- package/dist/proxy/compression-quality-monitor.js +0 -160
- package/dist/proxy/compression-stats.js +0 -51
- package/dist/proxy/context-rot-detector.js +0 -137
- package/dist/proxy/drift-detector.js +0 -139
- package/dist/proxy/efficiency-tracker.js +0 -79
- package/dist/proxy/fact-ranking.js +0 -154
- package/dist/proxy/format-encoder.js +0 -266
- package/dist/proxy/http-transport.js +0 -90
- package/dist/proxy/lifecycle-actor.js +0 -55
- package/dist/proxy/lifecycle-machine.js +0 -187
- package/dist/proxy/log-tailer.js +0 -265
- package/dist/proxy/model-pricing.js +0 -98
- package/dist/proxy/network-firewall.js +0 -141
- package/dist/proxy/nudge-state.js +0 -93
- package/dist/proxy/output-compressor.js +0 -185
- package/dist/proxy/pid-lock.js +0 -291
- package/dist/proxy/proxy-context.js +0 -11
- package/dist/proxy/proxy.js +0 -2633
- package/dist/proxy/response-enrichment.js +0 -32
- package/dist/proxy/response-envelope.js +0 -313
- package/dist/proxy/session-dedup.js +0 -82
- package/dist/proxy/session-legend.js +0 -30
- package/dist/proxy/session-persistence.js +0 -210
- package/dist/proxy/session-resume.js +0 -94
- package/dist/proxy/session-stats.js +0 -513
- package/dist/proxy/shell-classifier.js +0 -1346
- package/dist/proxy/shell-compression-log.js +0 -93
- package/dist/proxy/shell-compressor.js +0 -390
- package/dist/proxy/shell-graph-boost.js +0 -202
- package/dist/proxy/shell-monitor-map.js +0 -18
- package/dist/proxy/shell-stats.js +0 -54
- package/dist/proxy/shell-strategies/cloud.js +0 -215
- package/dist/proxy/shell-strategies/diff.js +0 -159
- package/dist/proxy/shell-strategies/error-diagnostic.js +0 -796
- package/dist/proxy/shell-strategies/filter-dsl.js +0 -358
- package/dist/proxy/shell-strategies/git-status.js +0 -177
- package/dist/proxy/shell-strategies/key-value.js +0 -193
- package/dist/proxy/shell-strategies/log-text.js +0 -154
- package/dist/proxy/shell-strategies/omni.js +0 -188
- package/dist/proxy/shell-strategies/progress.js +0 -55
- package/dist/proxy/shell-strategies/redact.js +0 -76
- package/dist/proxy/shell-strategies/structured.js +0 -241
- package/dist/proxy/shell-strategies/tabular.js +0 -243
- package/dist/proxy/shell-strategies/test-results-types.js +0 -13
- package/dist/proxy/shell-strategies/test-results.js +0 -784
- package/dist/proxy/shell-strategies/tree-paths.js +0 -144
- package/dist/proxy/shell-strategies/yaml.js +0 -182
- package/dist/proxy/shell-tee.js +0 -111
- package/dist/proxy/signal-dedup.js +0 -171
- package/dist/proxy/startup-renderer.js +0 -158
- package/dist/proxy/task-token-display.js +0 -38
- package/dist/proxy/token-counter.js +0 -61
- package/dist/proxy/tool-clusters.js +0 -273
- package/dist/proxy/tool-definitions.js +0 -525
- package/dist/proxy/transport-mux.js +0 -229
- package/dist/proxy/wire-cap.js +0 -268
- package/dist/rules/developer.mozilla.org.json +0 -9
- package/dist/rules/github.com.json +0 -21
- package/dist/schemas/api/skills.js +0 -19
- package/dist/schemas/common/errors.js +0 -7
- package/dist/schemas/common/headers.js +0 -5
- package/dist/schemas/entities/edge.js +0 -25
- package/dist/schemas/entities/entity.js +0 -22
- package/dist/schemas/entities/rule.js +0 -18
- package/dist/schemas/index.js +0 -14
- package/dist/server/event-bus.js +0 -59
- package/dist/server/http.js +0 -156
- package/dist/server/middleware.js +0 -70
- package/dist/server/routes/drift.js +0 -97
- package/dist/server/routes/intelligence.js +0 -1217
- package/dist/server/routes/reasoning-quality.js +0 -444
- package/dist/server/routes/session.js +0 -86
- package/dist/server/routes/stream.js +0 -120
- package/dist/server/routes/system.js +0 -73
- package/dist/server/routes/temporal.js +0 -170
- package/dist/server/routes/timeline.js +0 -232
- package/dist/server/routes/token-flow.js +0 -403
- package/dist/skills/effectiveness-tracker.js +0 -93
- package/dist/skills/local-pack.js +0 -380
- package/dist/skills/resolver.js +0 -495
- package/dist/state-detector.js +0 -83
- package/dist/timeline/intent-detector.js +0 -263
- package/dist/timeline/loop-miner.js +0 -140
- package/dist/timeline/open-threads.js +0 -49
- package/dist/timeline/signal-reinforcer.js +0 -62
- package/dist/timeline/timeline-bootstrap.js +0 -151
- package/dist/timeline/timeline-store.js +0 -618
- package/dist/tools/coding/bash.js +0 -49
- package/dist/tools/coding/file-edit.js +0 -72
- package/dist/tools/coding/file-outline.js +0 -227
- package/dist/tools/coding/file-read-protocol.js +0 -425
- package/dist/tools/coding/file-read.js +0 -35
- package/dist/tools/coding/file-write.js +0 -43
- package/dist/tools/coding/glob-tool.js +0 -109
- package/dist/tools/coding/grep.js +0 -162
- package/dist/tools/coding/index.js +0 -27
- package/dist/tools/intelligence/index.js +0 -269
- package/dist/tools/intelligence/record-fact.js +0 -48
- package/dist/tools/intelligence/timeline-markers.js +0 -130
- package/dist/tools/registry.js +0 -47
- package/dist/tools/types.js +0 -8
- package/dist/tracking/auto-snapshot-triggers.js +0 -246
- package/dist/tracking/branch-context.js +0 -115
- package/dist/tracking/branch-snapshot.js +0 -217
- package/dist/tracking/causal-bridge.js +0 -317
- package/dist/tracking/circuit-breaker.js +0 -147
- package/dist/tracking/commit-watcher.js +0 -114
- package/dist/tracking/context-ledger.js +0 -119
- package/dist/tracking/correction-detector.js +0 -324
- package/dist/tracking/drift-tracker.js +0 -874
- package/dist/tracking/durability-tracker.js +0 -94
- package/dist/tracking/entity-rewind.js +0 -200
- package/dist/tracking/file-hash-state.js +0 -114
- package/dist/tracking/git-attribution.js +0 -132
- package/dist/tracking/git-trailers.js +0 -171
- package/dist/tracking/intelligence-counter.js +0 -46
- package/dist/tracking/intent-correlator.js +0 -202
- package/dist/tracking/intent-encoder.js +0 -52
- package/dist/tracking/intent-token-tracker.js +0 -159
- package/dist/tracking/ledger-archiver.js +0 -94
- package/dist/tracking/ledger-chains.js +0 -245
- package/dist/tracking/metrics-store.js +0 -361
- package/dist/tracking/native-watcher.js +0 -131
- package/dist/tracking/offline-rewind.js +0 -295
- package/dist/tracking/pending-violations.js +0 -74
- package/dist/tracking/persistence-effectiveness.js +0 -167
- package/dist/tracking/prompt-durability.js +0 -202
- package/dist/tracking/quality-signals.js +0 -213
- package/dist/tracking/redactor.js +0 -73
- package/dist/tracking/rewind-engine.js +0 -161
- package/dist/tracking/session-history.js +0 -128
- package/dist/tracking/session-receipt.js +0 -88
- package/dist/tracking/session-summary-writer.js +0 -157
- package/dist/tracking/shadow-ledger.js +0 -321
- package/dist/tracking/stash-manager.js +0 -258
- package/dist/tracking/timeline-fork.js +0 -213
- package/dist/tracking/timeline.js +0 -69
- package/dist/tracking/token-flow.js +0 -276
- package/dist/tracking/turn-segmenter.js +0 -122
- package/dist/tracking/weekly-accumulator.js +0 -179
- package/dist/tracking/working-snapshots.js +0 -188
- package/dist/tracking/workspace-manifest.js +0 -176
- package/dist/transport/http.js +0 -102
- package/dist/utils/counterfactual.js +0 -65
- package/dist/utils/deep-link.js +0 -34
- package/dist/utils/detect.js +0 -193
- package/dist/utils/exec.js +0 -73
- package/dist/utils/file-logger.js +0 -87
- package/dist/utils/format-error.js +0 -29
- package/dist/utils/git.js +0 -181
- package/dist/utils/log.js +0 -57
- package/dist/utils/logger.js +0 -35
- package/dist/utils/mcp-content-json.js +0 -8
- package/dist/utils/session-logger.js +0 -154
- package/dist/utils/startup-log.js +0 -512
- package/dist/utils/ui.js +0 -56
|
@@ -1,427 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SCIP Binary Downloader — auto-downloads SCIP indexer binaries for detected languages.
|
|
3
|
-
*
|
|
4
|
-
* Downloads from GitHub releases, caches in ~/.unerr/bin/ for reuse across projects.
|
|
5
|
-
* Users never need to know about SCIP — it just works during onboarding.
|
|
6
|
-
*
|
|
7
|
-
* Supported auto-download languages:
|
|
8
|
-
* - Go: scip-go binary from scip-code/scip-go releases
|
|
9
|
-
* - Java: scip-java launcher script from sourcegraph/scip-java releases (requires JRE)
|
|
10
|
-
* - Rust: rust-analyzer binary from rust-lang/rust-analyzer releases
|
|
11
|
-
*
|
|
12
|
-
* TypeScript/Python are BUNDLED as npm deps — never downloaded here.
|
|
13
|
-
*/
|
|
14
|
-
import { chmodSync, createWriteStream, existsSync, mkdirSync } from "node:fs";
|
|
15
|
-
import { rename, rm, stat } from "node:fs/promises";
|
|
16
|
-
import { homedir } from "node:os";
|
|
17
|
-
import { join } from "node:path";
|
|
18
|
-
import { pipeline } from "node:stream/promises";
|
|
19
|
-
import { createGunzip } from "node:zlib";
|
|
20
|
-
import { createModuleLogger } from "../../../utils/logger.js";
|
|
21
|
-
const log = createModuleLogger("scip-downloader");
|
|
22
|
-
/** Where downloaded SCIP binaries live — shared across all projects. */
|
|
23
|
-
export function getScipBinDir() {
|
|
24
|
-
return join(homedir(), ".unerr", "bin");
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* Download specs for each language's SCIP indexer.
|
|
28
|
-
* Asset names verified against actual GitHub release assets.
|
|
29
|
-
*/
|
|
30
|
-
const DOWNLOAD_SPECS = {
|
|
31
|
-
go: {
|
|
32
|
-
language: "go",
|
|
33
|
-
binaryName: "scip-go",
|
|
34
|
-
repo: "scip-code/scip-go", // transferred from sourcegraph/scip-go
|
|
35
|
-
tag: "latest",
|
|
36
|
-
// Verified assets: scip-go-darwin-arm64.tar.gz, scip-go-linux-amd64.tar.gz, scip-go-linux-arm64.tar.gz
|
|
37
|
-
// NOTE: No darwin-amd64 (Intel Mac) build available
|
|
38
|
-
resolveAssetName: (p) => {
|
|
39
|
-
const os = p.os;
|
|
40
|
-
const arch = p.nodeArch === "arm64" ? "arm64" : "amd64";
|
|
41
|
-
// No darwin-amd64 build exists
|
|
42
|
-
if (os === "darwin" && arch === "amd64")
|
|
43
|
-
return null;
|
|
44
|
-
if (os === "windows")
|
|
45
|
-
return null;
|
|
46
|
-
return `scip-go-${os}-${arch}.tar.gz`;
|
|
47
|
-
},
|
|
48
|
-
archiveType: "tar.gz",
|
|
49
|
-
archiveBinaryPath: "scip-go",
|
|
50
|
-
manualInstall: "go install github.com/scip-code/scip-go/cmd/scip-go@latest",
|
|
51
|
-
},
|
|
52
|
-
java: {
|
|
53
|
-
language: "java",
|
|
54
|
-
binaryName: "scip-java",
|
|
55
|
-
repo: "sourcegraph/scip-java",
|
|
56
|
-
tag: "latest",
|
|
57
|
-
// Verified assets: scip-java-v{ver} (unix script), scip-java-v{ver}.bat (windows)
|
|
58
|
-
// The script is a Coursier launcher — requires JRE on PATH
|
|
59
|
-
resolveAssetName: (p) => {
|
|
60
|
-
if (p.os === "windows")
|
|
61
|
-
return null; // .bat not supported yet
|
|
62
|
-
return null; // Asset name includes version, resolved dynamically
|
|
63
|
-
},
|
|
64
|
-
archiveType: "raw",
|
|
65
|
-
archiveBinaryPath: null,
|
|
66
|
-
manualInstall: "Download from https://github.com/sourcegraph/scip-java/releases (requires JRE)",
|
|
67
|
-
},
|
|
68
|
-
rust: {
|
|
69
|
-
language: "rust",
|
|
70
|
-
binaryName: "rust-analyzer",
|
|
71
|
-
repo: "rust-lang/rust-analyzer",
|
|
72
|
-
tag: "latest",
|
|
73
|
-
// Verified assets: rust-analyzer-{triple}.gz (darwin, linux), rust-analyzer-{triple}.zip (windows)
|
|
74
|
-
resolveAssetName: (p) => {
|
|
75
|
-
if (p.os === "windows")
|
|
76
|
-
return null; // .zip extraction not implemented
|
|
77
|
-
return `rust-analyzer-${p.rustTriple}.gz`;
|
|
78
|
-
},
|
|
79
|
-
archiveType: "gz",
|
|
80
|
-
archiveBinaryPath: null,
|
|
81
|
-
manualInstall: "rustup component add rust-analyzer",
|
|
82
|
-
},
|
|
83
|
-
ruby: {
|
|
84
|
-
language: "ruby",
|
|
85
|
-
binaryName: "scip-ruby",
|
|
86
|
-
repo: "sourcegraph/scip-ruby",
|
|
87
|
-
tag: "latest",
|
|
88
|
-
// Verified assets: scip-ruby-arm64-darwin, scip-ruby-x86_64-linux (raw binaries)
|
|
89
|
-
// No darwin-x86_64 or linux-arm64 builds available
|
|
90
|
-
resolveAssetName: (p) => {
|
|
91
|
-
if (p.os === "windows")
|
|
92
|
-
return null;
|
|
93
|
-
if (p.os === "darwin" && p.nodeArch !== "arm64")
|
|
94
|
-
return null;
|
|
95
|
-
if (p.os === "linux" && p.nodeArch !== "x64")
|
|
96
|
-
return null;
|
|
97
|
-
const arch = p.os === "darwin" ? "arm64" : "x86_64";
|
|
98
|
-
return `scip-ruby-${arch}-${p.os}`;
|
|
99
|
-
},
|
|
100
|
-
archiveType: "raw",
|
|
101
|
-
archiveBinaryPath: null,
|
|
102
|
-
manualInstall: "Download from https://github.com/sourcegraph/scip-ruby/releases",
|
|
103
|
-
},
|
|
104
|
-
cpp: {
|
|
105
|
-
language: "cpp",
|
|
106
|
-
binaryName: "scip-clang",
|
|
107
|
-
repo: "sourcegraph/scip-clang",
|
|
108
|
-
tag: "latest",
|
|
109
|
-
// Verified assets: scip-clang-arm64-darwin, scip-clang-x86_64-linux (raw binaries)
|
|
110
|
-
// No darwin-x86_64 or linux-arm64 builds available
|
|
111
|
-
resolveAssetName: (p) => {
|
|
112
|
-
if (p.os === "windows")
|
|
113
|
-
return null;
|
|
114
|
-
if (p.os === "darwin" && p.nodeArch !== "arm64")
|
|
115
|
-
return null;
|
|
116
|
-
if (p.os === "linux" && p.nodeArch !== "x64")
|
|
117
|
-
return null;
|
|
118
|
-
const arch = p.os === "darwin" ? "arm64" : "x86_64";
|
|
119
|
-
return `scip-clang-${arch}-${p.os}`;
|
|
120
|
-
},
|
|
121
|
-
archiveType: "raw",
|
|
122
|
-
archiveBinaryPath: null,
|
|
123
|
-
manualInstall: "Download from https://github.com/sourcegraph/scip-clang/releases (requires compile_commands.json)",
|
|
124
|
-
},
|
|
125
|
-
};
|
|
126
|
-
/**
|
|
127
|
-
* Get the cached binary path for a language, or null if not cached.
|
|
128
|
-
*/
|
|
129
|
-
export function getCachedBinaryPath(language) {
|
|
130
|
-
const spec = DOWNLOAD_SPECS[language];
|
|
131
|
-
if (!spec)
|
|
132
|
-
return null;
|
|
133
|
-
const binDir = getScipBinDir();
|
|
134
|
-
const binPath = join(binDir, spec.binaryName);
|
|
135
|
-
if (existsSync(binPath)) {
|
|
136
|
-
return binPath;
|
|
137
|
-
}
|
|
138
|
-
return null;
|
|
139
|
-
}
|
|
140
|
-
/**
|
|
141
|
-
* Get the download spec for a language, if auto-download is supported.
|
|
142
|
-
*/
|
|
143
|
-
export function getDownloadSpec(language) {
|
|
144
|
-
return DOWNLOAD_SPECS[language] ?? null;
|
|
145
|
-
}
|
|
146
|
-
/**
|
|
147
|
-
* Get manual install instructions for a language.
|
|
148
|
-
*/
|
|
149
|
-
export function getManualInstallInstructions(language) {
|
|
150
|
-
return DOWNLOAD_SPECS[language]?.manualInstall ?? null;
|
|
151
|
-
}
|
|
152
|
-
/**
|
|
153
|
-
* Check if auto-download is supported for a language.
|
|
154
|
-
*/
|
|
155
|
-
export function isAutoDownloadSupported(language) {
|
|
156
|
-
return language in DOWNLOAD_SPECS;
|
|
157
|
-
}
|
|
158
|
-
/**
|
|
159
|
-
* Resolve platform identifiers for download URL construction.
|
|
160
|
-
*/
|
|
161
|
-
export function resolvePlatform() {
|
|
162
|
-
const platform = process.platform;
|
|
163
|
-
const arch = process.arch;
|
|
164
|
-
const os = platform === "darwin"
|
|
165
|
-
? "darwin"
|
|
166
|
-
: platform === "win32"
|
|
167
|
-
? "windows"
|
|
168
|
-
: "linux";
|
|
169
|
-
const rustTriple = platform === "darwin"
|
|
170
|
-
? arch === "arm64"
|
|
171
|
-
? "aarch64-apple-darwin"
|
|
172
|
-
: "x86_64-apple-darwin"
|
|
173
|
-
: platform === "win32"
|
|
174
|
-
? "x86_64-pc-windows-msvc"
|
|
175
|
-
: arch === "arm64"
|
|
176
|
-
? "aarch64-unknown-linux-gnu"
|
|
177
|
-
: "x86_64-unknown-linux-gnu";
|
|
178
|
-
return {
|
|
179
|
-
os,
|
|
180
|
-
arch: arch === "arm64" ? "aarch64" : "x86_64",
|
|
181
|
-
nodeArch: arch,
|
|
182
|
-
rustTriple,
|
|
183
|
-
};
|
|
184
|
-
}
|
|
185
|
-
/**
|
|
186
|
-
* Build the download URL for a SCIP binary.
|
|
187
|
-
* Returns null if the platform is not supported for this language.
|
|
188
|
-
*/
|
|
189
|
-
export function buildDownloadUrl(spec, platform, resolvedTag) {
|
|
190
|
-
const assetName = spec.resolveAssetName(platform);
|
|
191
|
-
if (!assetName)
|
|
192
|
-
return null;
|
|
193
|
-
return `https://github.com/${spec.repo}/releases/download/${resolvedTag}/${assetName}`;
|
|
194
|
-
}
|
|
195
|
-
/**
|
|
196
|
-
* Resolve "latest" tag to actual tag name via GitHub API.
|
|
197
|
-
* Follows redirects (repos may have been transferred).
|
|
198
|
-
*/
|
|
199
|
-
async function resolveLatestRelease(repo) {
|
|
200
|
-
try {
|
|
201
|
-
const url = `https://api.github.com/repos/${repo}/releases/latest`;
|
|
202
|
-
const response = await fetch(url, {
|
|
203
|
-
headers: { Accept: "application/vnd.github.v3+json" },
|
|
204
|
-
signal: AbortSignal.timeout(10_000),
|
|
205
|
-
redirect: "follow",
|
|
206
|
-
});
|
|
207
|
-
if (!response.ok) {
|
|
208
|
-
log.warn(`GitHub API returned ${response.status} for ${repo}`);
|
|
209
|
-
return null;
|
|
210
|
-
}
|
|
211
|
-
const data = (await response.json());
|
|
212
|
-
return {
|
|
213
|
-
tag: data.tag_name,
|
|
214
|
-
assets: data.assets.map((a) => ({
|
|
215
|
-
name: a.name,
|
|
216
|
-
url: a.browser_download_url,
|
|
217
|
-
})),
|
|
218
|
-
};
|
|
219
|
-
}
|
|
220
|
-
catch (err) {
|
|
221
|
-
log.warn(`Failed to resolve latest release for ${repo}: ${err instanceof Error ? err.message : String(err)}`);
|
|
222
|
-
return null;
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
/**
|
|
226
|
-
* Download and install a SCIP binary for the given language.
|
|
227
|
-
*
|
|
228
|
-
* Transparent during onboarding — users see progress, not implementation details.
|
|
229
|
-
*/
|
|
230
|
-
export async function downloadScipBinary(language, onProgress) {
|
|
231
|
-
const spec = DOWNLOAD_SPECS[language];
|
|
232
|
-
if (!spec) {
|
|
233
|
-
return {
|
|
234
|
-
success: false,
|
|
235
|
-
binaryPath: null,
|
|
236
|
-
error: `No auto-download available for language: ${language}`,
|
|
237
|
-
fromCache: false,
|
|
238
|
-
};
|
|
239
|
-
}
|
|
240
|
-
// Check cache first
|
|
241
|
-
const cached = getCachedBinaryPath(language);
|
|
242
|
-
if (cached) {
|
|
243
|
-
return { success: true, binaryPath: cached, error: null, fromCache: true };
|
|
244
|
-
}
|
|
245
|
-
const binDir = getScipBinDir();
|
|
246
|
-
if (!existsSync(binDir)) {
|
|
247
|
-
mkdirSync(binDir, { recursive: true });
|
|
248
|
-
}
|
|
249
|
-
const platform = resolvePlatform();
|
|
250
|
-
const destPath = join(binDir, spec.binaryName);
|
|
251
|
-
try {
|
|
252
|
-
// Resolve latest release
|
|
253
|
-
onProgress?.(`Resolving latest ${spec.binaryName} version...`);
|
|
254
|
-
const release = await resolveLatestRelease(spec.repo);
|
|
255
|
-
if (!release) {
|
|
256
|
-
return {
|
|
257
|
-
success: false,
|
|
258
|
-
binaryPath: null,
|
|
259
|
-
error: `Could not resolve latest release for ${spec.repo}. Check your internet connection.`,
|
|
260
|
-
fromCache: false,
|
|
261
|
-
};
|
|
262
|
-
}
|
|
263
|
-
// For Java, the asset name includes the version tag — find it dynamically
|
|
264
|
-
let downloadUrl;
|
|
265
|
-
if (language === "java") {
|
|
266
|
-
const javaAsset = release.assets.find((a) => a.name.startsWith("scip-java-") &&
|
|
267
|
-
!a.name.endsWith(".bat") &&
|
|
268
|
-
!a.name.endsWith(".sha256"));
|
|
269
|
-
if (!javaAsset) {
|
|
270
|
-
return {
|
|
271
|
-
success: false,
|
|
272
|
-
binaryPath: null,
|
|
273
|
-
error: `No compatible scip-java asset found in release ${release.tag}. ${spec.manualInstall}`,
|
|
274
|
-
fromCache: false,
|
|
275
|
-
};
|
|
276
|
-
}
|
|
277
|
-
downloadUrl = javaAsset.url;
|
|
278
|
-
}
|
|
279
|
-
else {
|
|
280
|
-
downloadUrl = buildDownloadUrl(spec, platform, release.tag);
|
|
281
|
-
}
|
|
282
|
-
if (!downloadUrl) {
|
|
283
|
-
return {
|
|
284
|
-
success: false,
|
|
285
|
-
binaryPath: null,
|
|
286
|
-
error: `No ${spec.binaryName} binary available for ${platform.os}/${platform.nodeArch}. ${spec.manualInstall}`,
|
|
287
|
-
fromCache: false,
|
|
288
|
-
};
|
|
289
|
-
}
|
|
290
|
-
onProgress?.(`Downloading ${spec.binaryName} (${release.tag})...`);
|
|
291
|
-
log.info(`Downloading ${downloadUrl}`);
|
|
292
|
-
const response = await fetch(downloadUrl, {
|
|
293
|
-
signal: AbortSignal.timeout(120_000),
|
|
294
|
-
redirect: "follow",
|
|
295
|
-
});
|
|
296
|
-
if (!response.ok || !response.body) {
|
|
297
|
-
return {
|
|
298
|
-
success: false,
|
|
299
|
-
binaryPath: null,
|
|
300
|
-
error: `Download failed (HTTP ${response.status}). Try manually: ${spec.manualInstall}`,
|
|
301
|
-
fromCache: false,
|
|
302
|
-
};
|
|
303
|
-
}
|
|
304
|
-
onProgress?.(`Installing ${spec.binaryName}...`);
|
|
305
|
-
if (spec.archiveType === "tar.gz" && spec.archiveBinaryPath) {
|
|
306
|
-
await extractTarGz(response, spec.archiveBinaryPath, destPath);
|
|
307
|
-
}
|
|
308
|
-
else if (spec.archiveType === "gz") {
|
|
309
|
-
await extractGzSingle(response, destPath);
|
|
310
|
-
}
|
|
311
|
-
else {
|
|
312
|
-
await downloadToFile(response, destPath);
|
|
313
|
-
}
|
|
314
|
-
// Make executable
|
|
315
|
-
chmodSync(destPath, 0o755);
|
|
316
|
-
// Verify it exists and has size
|
|
317
|
-
const fileInfo = await stat(destPath);
|
|
318
|
-
if (fileInfo.size === 0) {
|
|
319
|
-
await rm(destPath, { force: true });
|
|
320
|
-
return {
|
|
321
|
-
success: false,
|
|
322
|
-
binaryPath: null,
|
|
323
|
-
error: `Downloaded binary is empty. Try manually: ${spec.manualInstall}`,
|
|
324
|
-
fromCache: false,
|
|
325
|
-
};
|
|
326
|
-
}
|
|
327
|
-
onProgress?.(`${spec.binaryName} installed successfully`);
|
|
328
|
-
log.info(`SCIP binary installed: ${destPath} (${fileInfo.size} bytes)`);
|
|
329
|
-
return {
|
|
330
|
-
success: true,
|
|
331
|
-
binaryPath: destPath,
|
|
332
|
-
error: null,
|
|
333
|
-
fromCache: false,
|
|
334
|
-
};
|
|
335
|
-
}
|
|
336
|
-
catch (err) {
|
|
337
|
-
// Clean up partial downloads
|
|
338
|
-
await rm(destPath, { force: true }).catch(() => { });
|
|
339
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
340
|
-
log.warn(`Download failed for ${language}: ${message}`);
|
|
341
|
-
return {
|
|
342
|
-
success: false,
|
|
343
|
-
binaryPath: null,
|
|
344
|
-
error: `Download failed: ${message}. Try manually: ${spec.manualInstall}`,
|
|
345
|
-
fromCache: false,
|
|
346
|
-
};
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
/**
|
|
350
|
-
* Extract a .tar.gz archive and pull out a specific binary.
|
|
351
|
-
*/
|
|
352
|
-
async function extractTarGz(response, binaryPath, destPath) {
|
|
353
|
-
const { exec } = await import("../../../utils/exec.js");
|
|
354
|
-
const archivePath = `${destPath}.tar.gz`;
|
|
355
|
-
await downloadToFile(response, archivePath);
|
|
356
|
-
const extractDir = `${destPath}.extract`;
|
|
357
|
-
mkdirSync(extractDir, { recursive: true });
|
|
358
|
-
try {
|
|
359
|
-
const result = await exec("tar", ["xzf", archivePath, "-C", extractDir]);
|
|
360
|
-
if (result.exitCode !== 0) {
|
|
361
|
-
throw new Error(`tar extraction failed: ${result.stderr}`);
|
|
362
|
-
}
|
|
363
|
-
// Find the binary — it might be at root or nested
|
|
364
|
-
const { exec: execFind } = await import("../../../utils/exec.js");
|
|
365
|
-
const findResult = await execFind("find", [
|
|
366
|
-
extractDir,
|
|
367
|
-
"-name",
|
|
368
|
-
binaryPath,
|
|
369
|
-
"-type",
|
|
370
|
-
"f",
|
|
371
|
-
]);
|
|
372
|
-
const foundPath = findResult.stdout.trim().split("\n")[0];
|
|
373
|
-
if (foundPath && existsSync(foundPath)) {
|
|
374
|
-
await rename(foundPath, destPath);
|
|
375
|
-
}
|
|
376
|
-
else {
|
|
377
|
-
const directPath = join(extractDir, binaryPath);
|
|
378
|
-
if (existsSync(directPath)) {
|
|
379
|
-
await rename(directPath, destPath);
|
|
380
|
-
}
|
|
381
|
-
else {
|
|
382
|
-
throw new Error(`Binary '${binaryPath}' not found in archive`);
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
finally {
|
|
387
|
-
await rm(archivePath, { force: true }).catch(() => { });
|
|
388
|
-
await rm(extractDir, { recursive: true, force: true }).catch(() => { });
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
/**
|
|
392
|
-
* Extract a single .gz file (not tar.gz).
|
|
393
|
-
*/
|
|
394
|
-
async function extractGzSingle(response, destPath) {
|
|
395
|
-
const gunzip = createGunzip();
|
|
396
|
-
const dest = createWriteStream(destPath);
|
|
397
|
-
const body = response.body;
|
|
398
|
-
if (!body)
|
|
399
|
-
throw new Error("No response body");
|
|
400
|
-
await pipeline(body, gunzip, dest);
|
|
401
|
-
}
|
|
402
|
-
/**
|
|
403
|
-
* Download response body to a file.
|
|
404
|
-
*/
|
|
405
|
-
async function downloadToFile(response, destPath) {
|
|
406
|
-
const body = response.body;
|
|
407
|
-
if (!body)
|
|
408
|
-
throw new Error("No response body");
|
|
409
|
-
const dest = createWriteStream(destPath);
|
|
410
|
-
await pipeline(body, dest);
|
|
411
|
-
}
|
|
412
|
-
/**
|
|
413
|
-
* Get all languages that support auto-download.
|
|
414
|
-
*/
|
|
415
|
-
export function getAutoDownloadLanguages() {
|
|
416
|
-
return Object.keys(DOWNLOAD_SPECS);
|
|
417
|
-
}
|
|
418
|
-
/**
|
|
419
|
-
* Purge cached SCIP binaries (e.g., for updates or troubleshooting).
|
|
420
|
-
*/
|
|
421
|
-
export async function purgeScipCache() {
|
|
422
|
-
const binDir = getScipBinDir();
|
|
423
|
-
if (existsSync(binDir)) {
|
|
424
|
-
await rm(binDir, { recursive: true, force: true });
|
|
425
|
-
log.info("SCIP binary cache purged");
|
|
426
|
-
}
|
|
427
|
-
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SCIP Graceful Degradation — handles all failure scenarios cleanly.
|
|
3
|
-
*
|
|
4
|
-
* - Binary not found → skip, log info, continue at Tier-2 quality
|
|
5
|
-
* - Binary crashes → partial output → enrich what we have
|
|
6
|
-
* - Timeout exceeded → kill process, use tree-sitter edges only
|
|
7
|
-
* - Protobuf decode error → skip corrupted sections
|
|
8
|
-
*/
|
|
9
|
-
import { createModuleLogger } from "../../../utils/logger.js";
|
|
10
|
-
const log = createModuleLogger("scip-fallback");
|
|
11
|
-
/**
|
|
12
|
-
* Apply graceful degradation to edges when SCIP is unavailable or failed.
|
|
13
|
-
*/
|
|
14
|
-
export function applyScipFallback(existingEdges, reason, level = "unavailable") {
|
|
15
|
-
log.info(`SCIP degradation (${level}): ${reason}`);
|
|
16
|
-
const edges = existingEdges.map((e) => ({
|
|
17
|
-
...e,
|
|
18
|
-
confidence: "structural",
|
|
19
|
-
scipVerified: false,
|
|
20
|
-
}));
|
|
21
|
-
return { level, reason, edges };
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Determine degradation level from error type.
|
|
25
|
-
*/
|
|
26
|
-
export function classifyScipError(error) {
|
|
27
|
-
if (error.includes("not found") || error.includes("ENOENT"))
|
|
28
|
-
return "unavailable";
|
|
29
|
-
if (error.includes("timeout") || error.includes("ETIMEDOUT"))
|
|
30
|
-
return "partial";
|
|
31
|
-
if (error.includes("decode") || error.includes("protobuf"))
|
|
32
|
-
return "partial";
|
|
33
|
-
return "unavailable";
|
|
34
|
-
}
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SCIP → Edge Enrichment Merger — upgrades tree-sitter edges to compiler-verified
|
|
3
|
-
* and discovers new cross-file edges that tree-sitter missed.
|
|
4
|
-
*
|
|
5
|
-
* Matching strategy:
|
|
6
|
-
* SCIP gives us: symbol → (file, line, isDef/isRef)
|
|
7
|
-
* Graph gives us: entity (key, name, file_path) + edge (from_key, to_key, type)
|
|
8
|
-
*
|
|
9
|
-
* We match by: SCIP definition at (file, name) confirms graph entity exists,
|
|
10
|
-
* and SCIP reference at (file, name) → SCIP definition at (other_file, name)
|
|
11
|
-
* confirms a cross-file call/import edge.
|
|
12
|
-
*/
|
|
13
|
-
import { createModuleLogger } from "../../../utils/logger.js";
|
|
14
|
-
const log = createModuleLogger("scip-merger");
|
|
15
|
-
/**
|
|
16
|
-
* Merge SCIP results with existing tree-sitter edges.
|
|
17
|
-
*
|
|
18
|
-
* @param existingEdges - Tree-sitter edges to enrich
|
|
19
|
-
* @param scipResult - Decoded SCIP output
|
|
20
|
-
* @param entities - Entity list for key→(file,name) resolution
|
|
21
|
-
*/
|
|
22
|
-
export function mergeScipResults(existingEdges, scipResult, entities) {
|
|
23
|
-
const start = performance.now();
|
|
24
|
-
// Build SCIP definition index: normalized_name → Set<file_path>
|
|
25
|
-
const scipDefs = new Map();
|
|
26
|
-
for (const doc of scipResult.documents) {
|
|
27
|
-
for (const sym of doc.symbols) {
|
|
28
|
-
if (sym.isDefinition) {
|
|
29
|
-
const name = extractEntityName(sym.symbol);
|
|
30
|
-
if (name) {
|
|
31
|
-
let files = scipDefs.get(name);
|
|
32
|
-
if (!files) {
|
|
33
|
-
files = new Set();
|
|
34
|
-
scipDefs.set(name, files);
|
|
35
|
-
}
|
|
36
|
-
files.add(doc.relativePath);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
// If we have entity data, build key→entity lookup for edge resolution
|
|
42
|
-
const entityByKey = new Map();
|
|
43
|
-
if (entities) {
|
|
44
|
-
for (const e of entities) {
|
|
45
|
-
entityByKey.set(e.key, e);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
let edgesUpgraded = 0;
|
|
49
|
-
let edgesUnchanged = 0;
|
|
50
|
-
const enrichedEdges = existingEdges.map((edge) => {
|
|
51
|
-
if ((edge.type === "calls" || edge.type === "imports") &&
|
|
52
|
-
entityByKey.size > 0) {
|
|
53
|
-
const target = entityByKey.get(edge.to_key);
|
|
54
|
-
if (target) {
|
|
55
|
-
// Check if SCIP confirms this entity exists at this file
|
|
56
|
-
const defFiles = scipDefs.get(target.name);
|
|
57
|
-
if (defFiles?.has(target.file_path)) {
|
|
58
|
-
edgesUpgraded++;
|
|
59
|
-
return {
|
|
60
|
-
...edge,
|
|
61
|
-
confidence: "compiler-verified",
|
|
62
|
-
scipVerified: true,
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
// Also try matching by last segment of name (for Class.method → method)
|
|
66
|
-
const baseName = target.name.split(".").pop();
|
|
67
|
-
if (baseName && baseName !== target.name) {
|
|
68
|
-
const baseDefFiles = scipDefs.get(baseName);
|
|
69
|
-
if (baseDefFiles?.has(target.file_path)) {
|
|
70
|
-
edgesUpgraded++;
|
|
71
|
-
return {
|
|
72
|
-
...edge,
|
|
73
|
-
confidence: "compiler-verified",
|
|
74
|
-
scipVerified: true,
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
edgesUnchanged++;
|
|
81
|
-
return { ...edge, confidence: "structural", scipVerified: false };
|
|
82
|
-
});
|
|
83
|
-
const durationMs = performance.now() - start;
|
|
84
|
-
log.info(`Merge: ${edgesUpgraded} upgraded, ${edgesUnchanged} unchanged (${scipDefs.size} unique SCIP definitions across ${scipResult.documents.length} files)`);
|
|
85
|
-
return {
|
|
86
|
-
edges: enrichedEdges,
|
|
87
|
-
result: {
|
|
88
|
-
edgesUpgraded,
|
|
89
|
-
edgesUnchanged,
|
|
90
|
-
newEdgesFromScip: 0,
|
|
91
|
-
durationMs,
|
|
92
|
-
},
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
/**
|
|
96
|
-
* Extract a human-readable entity name from a SCIP symbol string.
|
|
97
|
-
*
|
|
98
|
-
* Examples:
|
|
99
|
-
* "scip-typescript npm unerr 0.1.0 src/`ignore.ts`/loadIgnore()." → "loadIgnore"
|
|
100
|
-
* "scip-typescript npm unerr 0.1.0 src/`local-graph.ts`/CozoGraphStore#getEntity()." → "getEntity"
|
|
101
|
-
* "scip-typescript npm unerr 0.1.0 src/`local-graph.ts`/CozoGraphStore#" → "CozoGraphStore"
|
|
102
|
-
*/
|
|
103
|
-
function extractEntityName(symbol) {
|
|
104
|
-
// Remove trailing punctuation (., #, ().)
|
|
105
|
-
const cleaned = symbol.replace(/[().]+$/, "").replace(/#$/, "");
|
|
106
|
-
// Get the last segment after / or #
|
|
107
|
-
const match = cleaned.match(/[/#]([^/#`]+)$/);
|
|
108
|
-
return match?.[1] ?? null;
|
|
109
|
-
}
|