@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,34 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tinypool worker entry point for parallel AST entity extraction.
|
|
3
|
-
*
|
|
4
|
-
* Runs in a worker thread — must not import native main-thread-only modules.
|
|
5
|
-
* Receives file path + content, returns extracted entities.
|
|
6
|
-
*
|
|
7
|
-
* Uses dynamic import with fallback to handle both production (.js) and
|
|
8
|
-
* development (.ts) environments since worker threads don't inherit
|
|
9
|
-
* TypeScript loaders.
|
|
10
|
-
*/
|
|
11
|
-
let _extractEntities = null;
|
|
12
|
-
async function loadExtractor() {
|
|
13
|
-
if (_extractEntities)
|
|
14
|
-
return _extractEntities;
|
|
15
|
-
try {
|
|
16
|
-
const mod = await import("./ast-extractor.js");
|
|
17
|
-
_extractEntities = mod.extractEntities;
|
|
18
|
-
}
|
|
19
|
-
catch {
|
|
20
|
-
// @ts-expect-error .ts import used as runtime fallback in non-compiled environments
|
|
21
|
-
const mod = await import("./ast-extractor.ts");
|
|
22
|
-
_extractEntities = mod.extractEntities;
|
|
23
|
-
}
|
|
24
|
-
return _extractEntities;
|
|
25
|
-
}
|
|
26
|
-
export default async function parse(input) {
|
|
27
|
-
try {
|
|
28
|
-
const extractEntities = await loadExtractor();
|
|
29
|
-
return extractEntities(input.content, input.filePath);
|
|
30
|
-
}
|
|
31
|
-
catch {
|
|
32
|
-
return [];
|
|
33
|
-
}
|
|
34
|
-
}
|
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Background Index Runner — Sprint L11.1
|
|
3
|
-
*
|
|
4
|
-
* Non-blocking wrapper around `indexLocalProject()` that runs indexing
|
|
5
|
-
* as an async task. Exposes observable progress state that the proxy,
|
|
6
|
-
* query router, and ora spinner can poll at any time.
|
|
7
|
-
*
|
|
8
|
-
* Contract TL-25: MCP server starts within 2 seconds of boot.
|
|
9
|
-
* Contract TL-26: Background indexing never blocks the MCP event loop.
|
|
10
|
-
* Contract TL-30: Zero LLM calls during indexing (tree-sitter only).
|
|
11
|
-
*/
|
|
12
|
-
// ── BackgroundIndexer ────────────────────────────────────────────
|
|
13
|
-
export class BackgroundIndexer {
|
|
14
|
-
_status = "idle";
|
|
15
|
-
_processed = 0;
|
|
16
|
-
_total = 0;
|
|
17
|
-
_phase = "";
|
|
18
|
-
_currentFile = null;
|
|
19
|
-
_result = null;
|
|
20
|
-
_error = null;
|
|
21
|
-
_startedAt = null;
|
|
22
|
-
_completedAt = null;
|
|
23
|
-
/**
|
|
24
|
-
* Start background indexing. Returns immediately — indexing runs
|
|
25
|
-
* as an async microtask that yields to the event loop between files.
|
|
26
|
-
*
|
|
27
|
-
* @param projectRoot - Absolute path to the project root
|
|
28
|
-
* @param graphStore - CozoGraphStore instance (schema already initialized)
|
|
29
|
-
* @param repoId - Repository ID for entity key generation
|
|
30
|
-
* @param onComplete - Called when indexing finishes successfully
|
|
31
|
-
* @param onError - Called if indexing fails (proxy continues with empty graph)
|
|
32
|
-
*/
|
|
33
|
-
start(projectRoot, graphStore, repoId, onComplete, onError) {
|
|
34
|
-
if (this._status === "indexing")
|
|
35
|
-
return; // Already running
|
|
36
|
-
this._status = "indexing";
|
|
37
|
-
this._startedAt = Date.now();
|
|
38
|
-
this._processed = 0;
|
|
39
|
-
this._total = 0;
|
|
40
|
-
this._phase = "discovering";
|
|
41
|
-
this._currentFile = null;
|
|
42
|
-
this._result = null;
|
|
43
|
-
this._error = null;
|
|
44
|
-
this._completedAt = null;
|
|
45
|
-
// Fire-and-forget async — does not block the caller
|
|
46
|
-
this.runIndexing(projectRoot, graphStore, repoId, onComplete, onError);
|
|
47
|
-
}
|
|
48
|
-
/** Whether indexing is currently in progress. */
|
|
49
|
-
isIndexing() {
|
|
50
|
-
return this._status === "indexing";
|
|
51
|
-
}
|
|
52
|
-
/** Whether indexing has completed successfully. */
|
|
53
|
-
isComplete() {
|
|
54
|
-
return this._status === "complete";
|
|
55
|
-
}
|
|
56
|
-
/** Current status. */
|
|
57
|
-
getStatus() {
|
|
58
|
-
return this._status;
|
|
59
|
-
}
|
|
60
|
-
/** Current progress snapshot (safe to poll from any module). */
|
|
61
|
-
getProgress() {
|
|
62
|
-
const pct = this._total > 0 ? Math.round((this._processed / this._total) * 100) : 0;
|
|
63
|
-
return {
|
|
64
|
-
processed: this._processed,
|
|
65
|
-
total: this._total,
|
|
66
|
-
phase: this._phase,
|
|
67
|
-
pct,
|
|
68
|
-
currentFile: this._currentFile,
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
/** Full state snapshot. */
|
|
72
|
-
getState() {
|
|
73
|
-
return {
|
|
74
|
-
status: this._status,
|
|
75
|
-
progress: this.getProgress(),
|
|
76
|
-
result: this._result,
|
|
77
|
-
error: this._error,
|
|
78
|
-
startedAt: this._startedAt,
|
|
79
|
-
completedAt: this._completedAt,
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
/** Index result (null if not yet complete). */
|
|
83
|
-
getResult() {
|
|
84
|
-
return this._result;
|
|
85
|
-
}
|
|
86
|
-
/** Error (null if no error). */
|
|
87
|
-
getError() {
|
|
88
|
-
return this._error;
|
|
89
|
-
}
|
|
90
|
-
/** Elapsed time in milliseconds since indexing started. */
|
|
91
|
-
getElapsedMs() {
|
|
92
|
-
if (!this._startedAt)
|
|
93
|
-
return 0;
|
|
94
|
-
const end = this._completedAt ?? Date.now();
|
|
95
|
-
return end - this._startedAt;
|
|
96
|
-
}
|
|
97
|
-
// ── Internal ──────────────────────────────────────────────────
|
|
98
|
-
async runIndexing(projectRoot, graphStore, repoId, onComplete, onError) {
|
|
99
|
-
try {
|
|
100
|
-
const { indexLocalProject } = await import("./local-indexer.js");
|
|
101
|
-
const result = await indexLocalProject(projectRoot, graphStore, repoId, {
|
|
102
|
-
onProgress: (event) => {
|
|
103
|
-
this._processed = event.processed;
|
|
104
|
-
this._total = event.total;
|
|
105
|
-
this._phase = event.phase;
|
|
106
|
-
this._currentFile = event.currentFile;
|
|
107
|
-
},
|
|
108
|
-
});
|
|
109
|
-
this._status = "complete";
|
|
110
|
-
this._result = result;
|
|
111
|
-
this._completedAt = Date.now();
|
|
112
|
-
onComplete(result);
|
|
113
|
-
}
|
|
114
|
-
catch (err) {
|
|
115
|
-
this._status = "error";
|
|
116
|
-
this._error = err instanceof Error ? err : new Error(String(err));
|
|
117
|
-
this._completedAt = Date.now();
|
|
118
|
-
onError(this._error);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
}
|
|
@@ -1,200 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Blast Radius Engine — N-hop traversal + risk assessment.
|
|
3
|
-
*
|
|
4
|
-
* N.1: Datalog-style N-hop traversal (1, 2, 3 hops from target entity)
|
|
5
|
-
* N.2: Result assembly (callers, files, communities, risk per hop)
|
|
6
|
-
* N.3: Suggestion generation (risk → human-readable guidance)
|
|
7
|
-
* N.4: File-level blast radius (given file change → affected entities in other files)
|
|
8
|
-
* N.5: Performance optimization (adjacency-list cached traversal, <5ms target)
|
|
9
|
-
*
|
|
10
|
-
* Performance: all queries <5ms on 10K entity graphs via in-memory adjacency.
|
|
11
|
-
*/
|
|
12
|
-
/**
|
|
13
|
-
* Build a reverse adjacency index (callees → callers) for fast traversal.
|
|
14
|
-
*/
|
|
15
|
-
export function buildReverseAdjacency(edges) {
|
|
16
|
-
const adj = new Map();
|
|
17
|
-
for (const edge of edges) {
|
|
18
|
-
if (edge.type !== "calls")
|
|
19
|
-
continue;
|
|
20
|
-
if (!adj.has(edge.to_key))
|
|
21
|
-
adj.set(edge.to_key, new Set());
|
|
22
|
-
adj.get(edge.to_key)?.add(edge.from_key);
|
|
23
|
-
}
|
|
24
|
-
return adj;
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* Compute blast radius via N-hop BFS traversal on the reverse call graph.
|
|
28
|
-
* Returns all entities that transitively depend on the target.
|
|
29
|
-
*/
|
|
30
|
-
export function computeBlastRadius(targetKey, entities, reverseAdj, options = {}) {
|
|
31
|
-
const start = performance.now();
|
|
32
|
-
const maxHops = options.maxHops ?? 3;
|
|
33
|
-
const maxResults = options.maxResults ?? 500;
|
|
34
|
-
const target = entities.get(targetKey);
|
|
35
|
-
const hops = new Map();
|
|
36
|
-
const visited = new Set([targetKey]);
|
|
37
|
-
let frontier = new Set([targetKey]);
|
|
38
|
-
for (let hop = 1; hop <= maxHops; hop++) {
|
|
39
|
-
const nextFrontier = new Set();
|
|
40
|
-
const hopEntities = [];
|
|
41
|
-
for (const nodeKey of frontier) {
|
|
42
|
-
const callers = reverseAdj.get(nodeKey);
|
|
43
|
-
if (!callers)
|
|
44
|
-
continue;
|
|
45
|
-
for (const callerKey of callers) {
|
|
46
|
-
if (visited.has(callerKey))
|
|
47
|
-
continue;
|
|
48
|
-
visited.add(callerKey);
|
|
49
|
-
const entity = entities.get(callerKey);
|
|
50
|
-
if (entity) {
|
|
51
|
-
hopEntities.push({
|
|
52
|
-
key: entity.key,
|
|
53
|
-
name: entity.name,
|
|
54
|
-
kind: entity.kind,
|
|
55
|
-
file_path: entity.file_path,
|
|
56
|
-
risk_level: entity.risk_level ??
|
|
57
|
-
"normal",
|
|
58
|
-
community: entity.community ?? -1,
|
|
59
|
-
hop,
|
|
60
|
-
});
|
|
61
|
-
nextFrontier.add(callerKey);
|
|
62
|
-
}
|
|
63
|
-
if (visited.size > maxResults)
|
|
64
|
-
break;
|
|
65
|
-
}
|
|
66
|
-
if (visited.size > maxResults)
|
|
67
|
-
break;
|
|
68
|
-
}
|
|
69
|
-
if (hopEntities.length > 0) {
|
|
70
|
-
hops.set(hop, hopEntities);
|
|
71
|
-
}
|
|
72
|
-
frontier = nextFrontier;
|
|
73
|
-
if (frontier.size === 0)
|
|
74
|
-
break;
|
|
75
|
-
}
|
|
76
|
-
const allAffected = [...hops.values()].flat();
|
|
77
|
-
const affectedFiles = [...new Set(allAffected.map((e) => e.file_path))];
|
|
78
|
-
const affectedCommunities = [
|
|
79
|
-
...new Set(allAffected.map((e) => e.community).filter((c) => c >= 0)),
|
|
80
|
-
];
|
|
81
|
-
const riskSummary = { critical: 0, high: 0, medium: 0, normal: 0 };
|
|
82
|
-
for (const entity of allAffected) {
|
|
83
|
-
const level = entity.risk_level;
|
|
84
|
-
if (level in riskSummary)
|
|
85
|
-
riskSummary[level]++;
|
|
86
|
-
}
|
|
87
|
-
const suggestions = generateSuggestions(allAffected, riskSummary, target);
|
|
88
|
-
return {
|
|
89
|
-
target: {
|
|
90
|
-
key: targetKey,
|
|
91
|
-
name: target?.name ?? targetKey,
|
|
92
|
-
file_path: target?.file_path ?? "",
|
|
93
|
-
},
|
|
94
|
-
hops,
|
|
95
|
-
totalAffected: allAffected.length,
|
|
96
|
-
affectedFiles,
|
|
97
|
-
affectedCommunities,
|
|
98
|
-
riskSummary,
|
|
99
|
-
suggestions,
|
|
100
|
-
resolvedInMs: performance.now() - start,
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
/**
|
|
104
|
-
* File-level blast radius — given a file path, find all entities in OTHER files
|
|
105
|
-
* that are affected by changes to any entity in the target file.
|
|
106
|
-
*/
|
|
107
|
-
export function computeFileBlastRadius(filePath, entities, reverseAdj, options = {}) {
|
|
108
|
-
const fileEntities = [...entities.values()].filter((e) => e.file_path === filePath);
|
|
109
|
-
if (fileEntities.length === 0) {
|
|
110
|
-
return emptyResult(filePath);
|
|
111
|
-
}
|
|
112
|
-
const start = performance.now();
|
|
113
|
-
const maxHops = options.maxHops ?? 2;
|
|
114
|
-
const visited = new Set(fileEntities.map((e) => e.key));
|
|
115
|
-
const hops = new Map();
|
|
116
|
-
let frontier = new Set(fileEntities.map((e) => e.key));
|
|
117
|
-
for (let hop = 1; hop <= maxHops; hop++) {
|
|
118
|
-
const nextFrontier = new Set();
|
|
119
|
-
const hopEntities = [];
|
|
120
|
-
for (const nodeKey of frontier) {
|
|
121
|
-
const callers = reverseAdj.get(nodeKey);
|
|
122
|
-
if (!callers)
|
|
123
|
-
continue;
|
|
124
|
-
for (const callerKey of callers) {
|
|
125
|
-
if (visited.has(callerKey))
|
|
126
|
-
continue;
|
|
127
|
-
visited.add(callerKey);
|
|
128
|
-
const entity = entities.get(callerKey);
|
|
129
|
-
if (entity && entity.file_path !== filePath) {
|
|
130
|
-
hopEntities.push({
|
|
131
|
-
key: entity.key,
|
|
132
|
-
name: entity.name,
|
|
133
|
-
kind: entity.kind,
|
|
134
|
-
file_path: entity.file_path,
|
|
135
|
-
risk_level: entity.risk_level ??
|
|
136
|
-
"normal",
|
|
137
|
-
community: entity.community ?? -1,
|
|
138
|
-
hop,
|
|
139
|
-
});
|
|
140
|
-
nextFrontier.add(callerKey);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
if (hopEntities.length > 0)
|
|
145
|
-
hops.set(hop, hopEntities);
|
|
146
|
-
frontier = nextFrontier;
|
|
147
|
-
if (frontier.size === 0)
|
|
148
|
-
break;
|
|
149
|
-
}
|
|
150
|
-
const allAffected = [...hops.values()].flat();
|
|
151
|
-
const affectedFiles = [...new Set(allAffected.map((e) => e.file_path))];
|
|
152
|
-
const affectedCommunities = [
|
|
153
|
-
...new Set(allAffected.map((e) => e.community).filter((c) => c >= 0)),
|
|
154
|
-
];
|
|
155
|
-
const riskSummary = { critical: 0, high: 0, medium: 0, normal: 0 };
|
|
156
|
-
for (const e of allAffected) {
|
|
157
|
-
const level = e.risk_level;
|
|
158
|
-
if (level in riskSummary)
|
|
159
|
-
riskSummary[level]++;
|
|
160
|
-
}
|
|
161
|
-
return {
|
|
162
|
-
target: { key: filePath, name: filePath, file_path: filePath },
|
|
163
|
-
hops,
|
|
164
|
-
totalAffected: allAffected.length,
|
|
165
|
-
affectedFiles,
|
|
166
|
-
affectedCommunities,
|
|
167
|
-
riskSummary,
|
|
168
|
-
suggestions: generateSuggestions(allAffected, riskSummary, null),
|
|
169
|
-
resolvedInMs: performance.now() - start,
|
|
170
|
-
};
|
|
171
|
-
}
|
|
172
|
-
function generateSuggestions(affected, riskSummary, target) {
|
|
173
|
-
const suggestions = [];
|
|
174
|
-
if (riskSummary.critical > 0) {
|
|
175
|
-
suggestions.push(`${riskSummary.critical} critical entity(ies) affected — consider adding overload/adapter pattern to isolate changes.`);
|
|
176
|
-
}
|
|
177
|
-
if (affected.length > 20) {
|
|
178
|
-
suggestions.push(`Wide blast radius (${affected.length} entities). Consider extracting an interface to reduce coupling.`);
|
|
179
|
-
}
|
|
180
|
-
const communities = new Set(affected.map((e) => e.community).filter((c) => c >= 0));
|
|
181
|
-
if (communities.size > 2) {
|
|
182
|
-
suggestions.push(`Change spans ${communities.size} communities — verify cross-team contracts are maintained.`);
|
|
183
|
-
}
|
|
184
|
-
if (affected.length > 0 && suggestions.length === 0) {
|
|
185
|
-
suggestions.push(`${affected.length} dependent(s) affected. Review callers before modifying.`);
|
|
186
|
-
}
|
|
187
|
-
return suggestions;
|
|
188
|
-
}
|
|
189
|
-
function emptyResult(target) {
|
|
190
|
-
return {
|
|
191
|
-
target: { key: target, name: target, file_path: target },
|
|
192
|
-
hops: new Map(),
|
|
193
|
-
totalAffected: 0,
|
|
194
|
-
affectedFiles: [],
|
|
195
|
-
affectedCommunities: [],
|
|
196
|
-
riskSummary: { critical: 0, high: 0, medium: 0, normal: 0 },
|
|
197
|
-
suggestions: [],
|
|
198
|
-
resolvedInMs: 0,
|
|
199
|
-
};
|
|
200
|
-
}
|