@unerr-ai/unerr 0.2.1 → 0.2.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 +6 -0
- package/dist/cli.js +37236 -35793
- package/package.json +1 -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
package/dist/server/event-bus.js
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Layer 7: Process-wide event bus for dashboard SSE transport.
|
|
3
|
-
*
|
|
4
|
-
* Bridges tool_call, drift, violation, circuit_breaker, and intent payloads to
|
|
5
|
-
* the SSE stream. The stream also emits session_stats and ping (not from the
|
|
6
|
-
* buffer). Circular buffer: 100 events for reconnect backfill.
|
|
7
|
-
*/
|
|
8
|
-
const BUFFER_SIZE = 100;
|
|
9
|
-
class EventBus {
|
|
10
|
-
listeners = new Set();
|
|
11
|
-
buffer = [];
|
|
12
|
-
bufferIdx = 0;
|
|
13
|
-
bufferFull = false;
|
|
14
|
-
emit(type, data) {
|
|
15
|
-
const event = { type, data, timestamp: Date.now() };
|
|
16
|
-
// Write to circular buffer
|
|
17
|
-
this.buffer[this.bufferIdx] = event;
|
|
18
|
-
this.bufferIdx = (this.bufferIdx + 1) % BUFFER_SIZE;
|
|
19
|
-
if (this.bufferIdx === 0)
|
|
20
|
-
this.bufferFull = true;
|
|
21
|
-
// Notify all listeners
|
|
22
|
-
for (const listener of this.listeners) {
|
|
23
|
-
try {
|
|
24
|
-
listener(event);
|
|
25
|
-
}
|
|
26
|
-
catch {
|
|
27
|
-
// Never let a listener crash the emitter
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
subscribe(listener) {
|
|
32
|
-
this.listeners.add(listener);
|
|
33
|
-
return () => {
|
|
34
|
-
this.listeners.delete(listener);
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* Return recent events for SSE backfill (oldest first).
|
|
39
|
-
*/
|
|
40
|
-
getRecentEvents(limit = 20) {
|
|
41
|
-
const total = this.bufferFull ? BUFFER_SIZE : this.bufferIdx;
|
|
42
|
-
if (total === 0)
|
|
43
|
-
return [];
|
|
44
|
-
const events = [];
|
|
45
|
-
const start = this.bufferFull ? this.bufferIdx : 0;
|
|
46
|
-
for (let i = 0; i < total; i++) {
|
|
47
|
-
const idx = (start + i) % BUFFER_SIZE;
|
|
48
|
-
const event = this.buffer[idx];
|
|
49
|
-
if (event)
|
|
50
|
-
events.push(event);
|
|
51
|
-
}
|
|
52
|
-
return events.slice(-limit);
|
|
53
|
-
}
|
|
54
|
-
get listenerCount() {
|
|
55
|
-
return this.listeners.size;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
/** Singleton instance — shared across the entire proxy process. */
|
|
59
|
-
export const eventBus = new EventBus();
|
package/dist/server/http.js
DELETED
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Layer 7: Hono HTTP server factory for the intelligence dashboard.
|
|
3
|
-
*
|
|
4
|
-
* Serves:
|
|
5
|
-
* /api/system/* — Proxy status and configuration
|
|
6
|
-
* /api/intelligence/* — Graph, health, entity, causal, durability
|
|
7
|
-
* /api/session/* — Session stats, efficiency, intents, ledger
|
|
8
|
-
* /api/stream — SSE real-time event transport
|
|
9
|
-
* /assets/* — Vite-built SPA static assets (production)
|
|
10
|
-
* /* — SPA fallback (index.html)
|
|
11
|
-
*
|
|
12
|
-
* Bound strictly to 127.0.0.1 — localhost only, no network exposure.
|
|
13
|
-
* Runs inside the same process as the MCP proxy for direct memory access.
|
|
14
|
-
*/
|
|
15
|
-
import { existsSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
|
|
16
|
-
import { createServer } from "node:net";
|
|
17
|
-
import { dirname, join } from "node:path";
|
|
18
|
-
import { fileURLToPath } from "node:url";
|
|
19
|
-
import { serve } from "@hono/node-server";
|
|
20
|
-
import { serveStatic } from "@hono/node-server/serve-static";
|
|
21
|
-
import { Hono } from "hono";
|
|
22
|
-
import { cacheMiddleware, corsMiddleware, errorMiddleware, timingMiddleware, } from "./middleware.js";
|
|
23
|
-
import { createDriftRoutes } from "./routes/drift.js";
|
|
24
|
-
import { createIntelligenceRoutes, } from "./routes/intelligence.js";
|
|
25
|
-
import { createReasoningQualityRoutes, } from "./routes/reasoning-quality.js";
|
|
26
|
-
import { createSessionRoutes, } from "./routes/session.js";
|
|
27
|
-
import { createStreamRoutes } from "./routes/stream.js";
|
|
28
|
-
import { createSystemRoutes } from "./routes/system.js";
|
|
29
|
-
import { createTemporalRoutes, } from "./routes/temporal.js";
|
|
30
|
-
import { createTimelineRoutes, } from "./routes/timeline.js";
|
|
31
|
-
import { createTokenFlowRoutes, } from "./routes/token-flow.js";
|
|
32
|
-
const PORT_START = 7600;
|
|
33
|
-
const PORT_END = 7700;
|
|
34
|
-
/**
|
|
35
|
-
* Find an available port in the 7655-7660 range.
|
|
36
|
-
* Returns 0 if all ports are occupied.
|
|
37
|
-
*/
|
|
38
|
-
async function findAvailablePort() {
|
|
39
|
-
for (let port = PORT_START; port <= PORT_END; port++) {
|
|
40
|
-
const available = await new Promise((resolve) => {
|
|
41
|
-
const server = createServer();
|
|
42
|
-
server.once("error", () => resolve(false));
|
|
43
|
-
server.once("listening", () => {
|
|
44
|
-
server.close(() => resolve(true));
|
|
45
|
-
});
|
|
46
|
-
server.listen(port, "127.0.0.1");
|
|
47
|
-
});
|
|
48
|
-
if (available)
|
|
49
|
-
return port;
|
|
50
|
-
}
|
|
51
|
-
return 0;
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Create and start the dashboard HTTP server.
|
|
55
|
-
* Non-blocking: returns null if no port available (dashboard is non-critical).
|
|
56
|
-
*/
|
|
57
|
-
export async function startDashboardServer(opts) {
|
|
58
|
-
const port = await findAvailablePort();
|
|
59
|
-
if (port === 0) {
|
|
60
|
-
process.stderr.write("[dashboard] All ports 7655-7660 occupied, skipping dashboard server.\n");
|
|
61
|
-
return null;
|
|
62
|
-
}
|
|
63
|
-
// Update the system route deps with the resolved port
|
|
64
|
-
opts.system.dashboardPort = port;
|
|
65
|
-
const app = new Hono();
|
|
66
|
-
// Middleware stack
|
|
67
|
-
app.use("*", corsMiddleware);
|
|
68
|
-
app.use("*", cacheMiddleware);
|
|
69
|
-
app.use("*", timingMiddleware);
|
|
70
|
-
app.use("*", errorMiddleware);
|
|
71
|
-
// API routes
|
|
72
|
-
app.route("/api/system", createSystemRoutes(opts.system));
|
|
73
|
-
app.route("/api/drift", createDriftRoutes({ cwd: opts.system.cwd }));
|
|
74
|
-
app.route("/api/intelligence", createIntelligenceRoutes(opts.intelligence));
|
|
75
|
-
app.route("/api/session", createSessionRoutes(opts.session));
|
|
76
|
-
app.route("/api/stream", createStreamRoutes(opts.stream));
|
|
77
|
-
if (opts.temporal) {
|
|
78
|
-
app.route("", createTemporalRoutes(opts.temporal));
|
|
79
|
-
}
|
|
80
|
-
if (opts.timeline) {
|
|
81
|
-
app.route("/api/timeline", createTimelineRoutes(opts.timeline));
|
|
82
|
-
}
|
|
83
|
-
if (opts.tokenFlow) {
|
|
84
|
-
app.route("/api/token-flow", createTokenFlowRoutes(opts.tokenFlow));
|
|
85
|
-
}
|
|
86
|
-
if (opts.reasoningQuality) {
|
|
87
|
-
app.route("/api/reasoning-quality", createReasoningQualityRoutes(opts.reasoningQuality));
|
|
88
|
-
}
|
|
89
|
-
// SPA serving — skipped for daemon children (supervisor serves UI on :9847)
|
|
90
|
-
if (!opts.apiOnly) {
|
|
91
|
-
const distDir = join(dirname(fileURLToPath(import.meta.url)), "ui");
|
|
92
|
-
const spaIndex = join(distDir, "index.html");
|
|
93
|
-
if (existsSync(spaIndex)) {
|
|
94
|
-
const spaHtml = readFileSync(spaIndex, "utf-8");
|
|
95
|
-
app.use("*", serveStatic({ root: distDir }));
|
|
96
|
-
app.get("*", (c) => {
|
|
97
|
-
const path = c.req.path;
|
|
98
|
-
if (path.startsWith("/api/")) {
|
|
99
|
-
return c.notFound();
|
|
100
|
-
}
|
|
101
|
-
return c.html(spaHtml);
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
else {
|
|
105
|
-
app.get("/", (c) => {
|
|
106
|
-
return c.json({
|
|
107
|
-
message: "unerr dashboard API is running. UI not built yet.",
|
|
108
|
-
hint: "Run 'pnpm run build:ui' to build the dashboard SPA.",
|
|
109
|
-
api: {
|
|
110
|
-
status: "/api/system/status",
|
|
111
|
-
config: "/api/system/config",
|
|
112
|
-
intelligence: "/api/intelligence/{graph-stats,health,top-entities,...}",
|
|
113
|
-
session: "/api/session/{stats,efficiency,intents,ledger}",
|
|
114
|
-
stream: "/api/stream (SSE)",
|
|
115
|
-
},
|
|
116
|
-
});
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
else {
|
|
121
|
-
app.get("/", (c) => c.json({ status: "ok", mode: "api-only" }));
|
|
122
|
-
}
|
|
123
|
-
// Start server
|
|
124
|
-
const server = serve({
|
|
125
|
-
fetch: app.fetch,
|
|
126
|
-
port,
|
|
127
|
-
hostname: "127.0.0.1",
|
|
128
|
-
});
|
|
129
|
-
// Write server.json atomically
|
|
130
|
-
const serverJsonPath = join(opts.stateDir, "server.json");
|
|
131
|
-
const serverInfo = {
|
|
132
|
-
port,
|
|
133
|
-
pid: process.pid,
|
|
134
|
-
startedAt: new Date().toISOString(),
|
|
135
|
-
url: `http://localhost:${port}`,
|
|
136
|
-
};
|
|
137
|
-
const tmpPath = `${serverJsonPath}.tmp.${process.pid}`;
|
|
138
|
-
writeFileSync(tmpPath, JSON.stringify(serverInfo, null, 2));
|
|
139
|
-
const { renameSync } = await import("node:fs");
|
|
140
|
-
renameSync(tmpPath, serverJsonPath);
|
|
141
|
-
const close = () => {
|
|
142
|
-
try {
|
|
143
|
-
server.close();
|
|
144
|
-
}
|
|
145
|
-
catch {
|
|
146
|
-
// Server may already be closed
|
|
147
|
-
}
|
|
148
|
-
try {
|
|
149
|
-
unlinkSync(serverJsonPath);
|
|
150
|
-
}
|
|
151
|
-
catch {
|
|
152
|
-
// File may not exist
|
|
153
|
-
}
|
|
154
|
-
};
|
|
155
|
-
return { port, close };
|
|
156
|
-
}
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Layer 7: Hono middleware stack for the dashboard HTTP server.
|
|
3
|
-
*
|
|
4
|
-
* Order: CORS → Cache-Control → Request ID + Timing → Error Boundary
|
|
5
|
-
*/
|
|
6
|
-
import { createMiddleware } from "hono/factory";
|
|
7
|
-
/**
|
|
8
|
-
* Strict localhost-only CORS. Rejects any origin that isn't
|
|
9
|
-
* http://localhost:* or http://127.0.0.1:*
|
|
10
|
-
*/
|
|
11
|
-
export const corsMiddleware = createMiddleware(async (c, next) => {
|
|
12
|
-
const origin = c.req.header("origin");
|
|
13
|
-
if (origin) {
|
|
14
|
-
const isLocalhost = origin.startsWith("http://localhost") ||
|
|
15
|
-
origin.startsWith("http://127.0.0.1");
|
|
16
|
-
if (!isLocalhost) {
|
|
17
|
-
return c.json({ data: null, error: "CORS: origin not allowed" }, 403);
|
|
18
|
-
}
|
|
19
|
-
c.header("Access-Control-Allow-Origin", origin);
|
|
20
|
-
c.header("Access-Control-Allow-Methods", "GET, OPTIONS");
|
|
21
|
-
c.header("Access-Control-Allow-Headers", "Content-Type");
|
|
22
|
-
}
|
|
23
|
-
if (c.req.method === "OPTIONS") {
|
|
24
|
-
return c.body(null, 204);
|
|
25
|
-
}
|
|
26
|
-
await next();
|
|
27
|
-
});
|
|
28
|
-
/**
|
|
29
|
-
* Cache-Control headers based on path.
|
|
30
|
-
* /assets/* → immutable (content-hashed by Vite)
|
|
31
|
-
* /api/* → no-cache
|
|
32
|
-
*/
|
|
33
|
-
export const cacheMiddleware = createMiddleware(async (c, next) => {
|
|
34
|
-
await next();
|
|
35
|
-
const path = c.req.path;
|
|
36
|
-
if (path.startsWith("/assets/")) {
|
|
37
|
-
c.header("Cache-Control", "public, max-age=31536000, immutable");
|
|
38
|
-
}
|
|
39
|
-
else if (path.startsWith("/api/")) {
|
|
40
|
-
c.header("Cache-Control", "no-cache, no-store, must-revalidate");
|
|
41
|
-
}
|
|
42
|
-
});
|
|
43
|
-
/**
|
|
44
|
-
* Request ID and timing. Adds X-Request-Id and logs to stderr.
|
|
45
|
-
*/
|
|
46
|
-
export const timingMiddleware = createMiddleware(async (c, next) => {
|
|
47
|
-
const reqId = Math.random().toString(36).slice(2, 10);
|
|
48
|
-
const start = performance.now();
|
|
49
|
-
c.set("reqId", reqId);
|
|
50
|
-
c.header("X-Request-Id", reqId);
|
|
51
|
-
await next();
|
|
52
|
-
const ms = (performance.now() - start).toFixed(1);
|
|
53
|
-
process.stderr.write(`[dashboard] ${c.req.method} ${c.req.path} → ${c.res.status} (${ms}ms)\n`);
|
|
54
|
-
});
|
|
55
|
-
/**
|
|
56
|
-
* Global error boundary. Never crash — return structured error envelope.
|
|
57
|
-
*/
|
|
58
|
-
export const errorMiddleware = createMiddleware(async (c, next) => {
|
|
59
|
-
try {
|
|
60
|
-
await next();
|
|
61
|
-
}
|
|
62
|
-
catch (err) {
|
|
63
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
64
|
-
process.stderr.write(`[dashboard] ERROR: ${message}\n`);
|
|
65
|
-
return c.json({
|
|
66
|
-
data: null,
|
|
67
|
-
_meta: { source: "local", latency_ms: 0, error: message },
|
|
68
|
-
}, 500);
|
|
69
|
-
}
|
|
70
|
-
});
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* N10 — Drift metrics endpoint for the Reasoning Quality dashboard pane.
|
|
3
|
-
*
|
|
4
|
-
* Surfaces nudge-v2 session state (Tier-1 emissions per kind, drift count,
|
|
5
|
-
* Tier-2 escalations, last unerr-tool timestamp) so the UI can render a
|
|
6
|
-
* "drift events this session" sparkline and "drift correction rate" KPI.
|
|
7
|
-
*
|
|
8
|
-
* Read-only — no side effects, no DB writes. Reads `.unerr/state/nudge-*.flags`
|
|
9
|
-
* files directly. Falls back to empty data if no sessions have flag files yet.
|
|
10
|
-
*
|
|
11
|
-
* GET /api/drift/sessions — aggregate across all known session flag files
|
|
12
|
-
* GET /api/drift/current — current session only (UNERR_SESSION_ID)
|
|
13
|
-
*/
|
|
14
|
-
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
15
|
-
import { join } from "node:path";
|
|
16
|
-
import { Hono } from "hono";
|
|
17
|
-
function readFlags(path) {
|
|
18
|
-
try {
|
|
19
|
-
if (!existsSync(path))
|
|
20
|
-
return null;
|
|
21
|
-
return JSON.parse(readFileSync(path, "utf8"));
|
|
22
|
-
}
|
|
23
|
-
catch {
|
|
24
|
-
return null;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
function listSessionFiles(stateDir) {
|
|
28
|
-
try {
|
|
29
|
-
if (!existsSync(stateDir))
|
|
30
|
-
return [];
|
|
31
|
-
return readdirSync(stateDir)
|
|
32
|
-
.filter((f) => f.startsWith("nudge-") && f.endsWith(".flags"))
|
|
33
|
-
.map((f) => join(stateDir, f));
|
|
34
|
-
}
|
|
35
|
-
catch {
|
|
36
|
-
return [];
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
function rowFor(file) {
|
|
40
|
-
const flags = readFlags(file);
|
|
41
|
-
if (!flags)
|
|
42
|
-
return null;
|
|
43
|
-
const id = file
|
|
44
|
-
.split("/")
|
|
45
|
-
.pop()
|
|
46
|
-
?.replace(/^nudge-/, "")
|
|
47
|
-
.replace(/\.flags$/, "");
|
|
48
|
-
return {
|
|
49
|
-
session_id: id ?? "",
|
|
50
|
-
tier0_emitted: Boolean(flags.tier0_emitted),
|
|
51
|
-
tier1_kinds: Array.isArray(flags.tier1_emitted_kinds)
|
|
52
|
-
? flags.tier1_emitted_kinds
|
|
53
|
-
: [],
|
|
54
|
-
drift_count: typeof flags.drift_count === "number" ? flags.drift_count : 0,
|
|
55
|
-
tier2_emitted: Boolean(flags.tier2_emitted),
|
|
56
|
-
last_unerr_tool_at: flags.last_unerr_tool_at ?? null,
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
export function createDriftRoutes(deps) {
|
|
60
|
-
const app = new Hono();
|
|
61
|
-
const stateDir = join(deps.cwd, ".unerr", "state");
|
|
62
|
-
app.get("/sessions", (c) => {
|
|
63
|
-
const rows = [];
|
|
64
|
-
for (const file of listSessionFiles(stateDir)) {
|
|
65
|
-
const r = rowFor(file);
|
|
66
|
-
if (r)
|
|
67
|
-
rows.push(r);
|
|
68
|
-
}
|
|
69
|
-
const totalDrift = rows.reduce((s, r) => s + r.drift_count, 0);
|
|
70
|
-
const corrected = rows.filter((r) => r.last_unerr_tool_at).length;
|
|
71
|
-
return c.json({
|
|
72
|
-
data: {
|
|
73
|
-
sessions: rows,
|
|
74
|
-
total_sessions: rows.length,
|
|
75
|
-
total_drift_events: totalDrift,
|
|
76
|
-
sessions_with_correction: corrected,
|
|
77
|
-
correction_rate: rows.length > 0 ? corrected / rows.length : 0,
|
|
78
|
-
},
|
|
79
|
-
});
|
|
80
|
-
});
|
|
81
|
-
app.get("/current", (c) => {
|
|
82
|
-
const id = process.env.UNERR_SESSION_ID ?? `pid-${process.pid}`;
|
|
83
|
-
const file = join(stateDir, `nudge-${id}.flags`);
|
|
84
|
-
const row = rowFor(file);
|
|
85
|
-
return c.json({
|
|
86
|
-
data: row ?? {
|
|
87
|
-
session_id: id,
|
|
88
|
-
tier0_emitted: false,
|
|
89
|
-
tier1_kinds: [],
|
|
90
|
-
drift_count: 0,
|
|
91
|
-
tier2_emitted: false,
|
|
92
|
-
last_unerr_tool_at: null,
|
|
93
|
-
},
|
|
94
|
-
});
|
|
95
|
-
});
|
|
96
|
-
return app;
|
|
97
|
-
}
|