@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
package/dist/commands/gain.js
DELETED
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* R5 — `unerr gain` / `unerr discover`
|
|
3
|
-
*
|
|
4
|
-
* Two analytics CLI commands that read the token-flow ledger and surface:
|
|
5
|
-
* - `gain`: where compression IS working — top commands by tokens_saved
|
|
6
|
-
* - `discover`: where compression IS NOT working — commands with high raw
|
|
7
|
-
* bytes but <30% reduction. These are untapped opportunities.
|
|
8
|
-
*
|
|
9
|
-
* Both read `.unerr/token-flow.jsonl` for the current repo only; no network,
|
|
10
|
-
* no aggregation across repos.
|
|
11
|
-
*/
|
|
12
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
13
|
-
import { join } from "node:path";
|
|
14
|
-
const PALETTE = {
|
|
15
|
-
reset: "\x1b[0m",
|
|
16
|
-
violet: "\x1b[38;2;139;92;246m",
|
|
17
|
-
cyan: "\x1b[38;2;34;211;238m",
|
|
18
|
-
success: "\x1b[38;2;52;211;153m",
|
|
19
|
-
warn: "\x1b[38;2;251;191;36m",
|
|
20
|
-
red: "\x1b[38;2;248;113;113m",
|
|
21
|
-
dim: "\x1b[38;2;161;161;170m",
|
|
22
|
-
bold: "\x1b[1m",
|
|
23
|
-
};
|
|
24
|
-
function loadFlow(cwd) {
|
|
25
|
-
const path = join(cwd, ".unerr", "token-flow.jsonl");
|
|
26
|
-
if (!existsSync(path))
|
|
27
|
-
return [];
|
|
28
|
-
const raw = readFileSync(path, "utf8");
|
|
29
|
-
const events = [];
|
|
30
|
-
for (const line of raw.split("\n")) {
|
|
31
|
-
if (!line.trim())
|
|
32
|
-
continue;
|
|
33
|
-
try {
|
|
34
|
-
events.push(JSON.parse(line));
|
|
35
|
-
}
|
|
36
|
-
catch {
|
|
37
|
-
// skip malformed
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
return events;
|
|
41
|
-
}
|
|
42
|
-
/** Normalize a command to its leading-token fingerprint ("git diff" → "git diff"). */
|
|
43
|
-
function commandKey(detail) {
|
|
44
|
-
const cmd = (detail?.command ?? detail?.cmd);
|
|
45
|
-
if (!cmd)
|
|
46
|
-
return null;
|
|
47
|
-
const tokens = cmd.trim().split(/\s+/).slice(0, 2).join(" ");
|
|
48
|
-
return tokens || null;
|
|
49
|
-
}
|
|
50
|
-
function aggregateByCommand(events) {
|
|
51
|
-
const map = new Map();
|
|
52
|
-
for (const e of events) {
|
|
53
|
-
if (e.mechanism !== "shell_compression")
|
|
54
|
-
continue;
|
|
55
|
-
const key = commandKey(e.detail);
|
|
56
|
-
if (!key)
|
|
57
|
-
continue;
|
|
58
|
-
let row = map.get(key);
|
|
59
|
-
if (!row) {
|
|
60
|
-
row = {
|
|
61
|
-
command: key,
|
|
62
|
-
invocations: 0,
|
|
63
|
-
rawTokens: 0,
|
|
64
|
-
outTokens: 0,
|
|
65
|
-
savedTokens: 0,
|
|
66
|
-
ratio: 0,
|
|
67
|
-
};
|
|
68
|
-
map.set(key, row);
|
|
69
|
-
}
|
|
70
|
-
row.invocations++;
|
|
71
|
-
row.rawTokens += e.tokens_without;
|
|
72
|
-
row.outTokens += e.tokens_with;
|
|
73
|
-
row.savedTokens += e.tokens_saved;
|
|
74
|
-
}
|
|
75
|
-
for (const row of map.values()) {
|
|
76
|
-
row.ratio = row.rawTokens > 0 ? row.savedTokens / row.rawTokens : 0;
|
|
77
|
-
}
|
|
78
|
-
return [...map.values()];
|
|
79
|
-
}
|
|
80
|
-
function fmtNum(n) {
|
|
81
|
-
if (n >= 1_000_000)
|
|
82
|
-
return `${(n / 1_000_000).toFixed(1)}M`;
|
|
83
|
-
if (n >= 1_000)
|
|
84
|
-
return `${(n / 1_000).toFixed(1)}K`;
|
|
85
|
-
return `${n}`;
|
|
86
|
-
}
|
|
87
|
-
function table(rows, title, kind) {
|
|
88
|
-
const c = PALETTE;
|
|
89
|
-
const out = [];
|
|
90
|
-
out.push("");
|
|
91
|
-
out.push(` ${c.violet}◆${c.reset} ${c.bold}${title}${c.reset}`);
|
|
92
|
-
out.push("");
|
|
93
|
-
if (rows.length === 0) {
|
|
94
|
-
out.push(` ${c.dim}No matching shell compression events yet.${c.reset}`);
|
|
95
|
-
out.push("");
|
|
96
|
-
return out.join("\n");
|
|
97
|
-
}
|
|
98
|
-
out.push(` ${c.dim}${"command".padEnd(28)} ${"invs".padStart(5)} ${"raw".padStart(7)} ${"saved".padStart(7)} ${"ratio".padStart(6)}${c.reset}`);
|
|
99
|
-
out.push(` ${c.dim}${"".padEnd(28, "─")} ${"────".padStart(5)} ${"───".padStart(7)} ${"─────".padStart(7)} ${"─────".padStart(6)}${c.reset}`);
|
|
100
|
-
for (const r of rows) {
|
|
101
|
-
const ratioColor = kind === "discover"
|
|
102
|
-
? r.ratio < 0.3
|
|
103
|
-
? c.red
|
|
104
|
-
: r.ratio < 0.5
|
|
105
|
-
? c.warn
|
|
106
|
-
: c.dim
|
|
107
|
-
: r.ratio >= 0.8
|
|
108
|
-
? c.success
|
|
109
|
-
: r.ratio >= 0.5
|
|
110
|
-
? c.cyan
|
|
111
|
-
: c.warn;
|
|
112
|
-
const cmd = r.command.slice(0, 28).padEnd(28);
|
|
113
|
-
const ratioStr = `${(r.ratio * 100).toFixed(0)}%`.padStart(6);
|
|
114
|
-
out.push(` ${cmd} ${String(r.invocations).padStart(5)} ${fmtNum(r.rawTokens).padStart(7)} ${fmtNum(r.savedTokens).padStart(7)} ${ratioColor}${ratioStr}${c.reset}`);
|
|
115
|
-
}
|
|
116
|
-
out.push("");
|
|
117
|
-
return out.join("\n");
|
|
118
|
-
}
|
|
119
|
-
export function registerGainCommand(program) {
|
|
120
|
-
program
|
|
121
|
-
.command("gain")
|
|
122
|
-
.description("Show top commands by tokens saved through shell compression (this repo)")
|
|
123
|
-
.option("-n, --limit <n>", "Number of rows to show", "20")
|
|
124
|
-
.action((opts) => {
|
|
125
|
-
const limit = Number.parseInt(opts.limit, 10) || 20;
|
|
126
|
-
const cwd = process.cwd();
|
|
127
|
-
const events = loadFlow(cwd);
|
|
128
|
-
const rows = aggregateByCommand(events);
|
|
129
|
-
const top = rows
|
|
130
|
-
.sort((a, b) => b.savedTokens - a.savedTokens)
|
|
131
|
-
.slice(0, limit);
|
|
132
|
-
process.stderr.write(table(top, `unerr gain — top ${limit} by tokens saved`, "gain"));
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
|
-
export function registerDiscoverCommand(program) {
|
|
136
|
-
program
|
|
137
|
-
.command("discover")
|
|
138
|
-
.description("Surface commands that bypass effective compression — untapped savings")
|
|
139
|
-
.option("-n, --limit <n>", "Number of rows to show", "20")
|
|
140
|
-
.option("-t, --threshold <pct>", "Ratio floor (0..100) below which a command is flagged", "30")
|
|
141
|
-
.option("-m, --min-raw <bytes>", "Ignore commands with raw output below this", "2000")
|
|
142
|
-
.action((opts) => {
|
|
143
|
-
const limit = Number.parseInt(opts.limit, 10) || 20;
|
|
144
|
-
const threshold = (Number.parseFloat(opts.threshold) || 30) / 100;
|
|
145
|
-
const minRaw = Number.parseInt(opts.minRaw, 10) || 2000;
|
|
146
|
-
const cwd = process.cwd();
|
|
147
|
-
const events = loadFlow(cwd);
|
|
148
|
-
const rows = aggregateByCommand(events);
|
|
149
|
-
const leaking = rows
|
|
150
|
-
.filter((r) => r.ratio < threshold &&
|
|
151
|
-
r.rawTokens / Math.max(1, r.invocations) >= minRaw)
|
|
152
|
-
.sort((a, b) => b.rawTokens - a.rawTokens)
|
|
153
|
-
.slice(0, limit);
|
|
154
|
-
process.stderr.write(table(leaking, `unerr discover — ${leaking.length} commands below ${Math.round(threshold * 100)}% compression`, "discover"));
|
|
155
|
-
});
|
|
156
|
-
}
|
package/dist/commands/hook.js
DELETED
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* `unerr hook <pre-*|post-*|prompt-submit>` — Hook handlers for all event types.
|
|
3
|
-
*
|
|
4
|
-
* Each subcommand reads stdin JSON and writes stdout JSON.
|
|
5
|
-
* - pre-bash: rewrites Bash commands to route through `unerr exec` (transparent)
|
|
6
|
-
* - pre-read/pre-grep/pre-glob: inject systemMessage nudges suggesting unerr tools
|
|
7
|
-
* - pre-write/pre-edit: blast radius + convention validation before code modifications
|
|
8
|
-
* - post-read/post-grep/post-glob: enrich tool output with graph navigation suggestions
|
|
9
|
-
* - post-write/post-edit: convention check + caller verification after modifications
|
|
10
|
-
* - prompt-submit: inject unerr tool reminder on each user prompt (UserPromptSubmit)
|
|
11
|
-
*/
|
|
12
|
-
import { readFileSync } from "node:fs";
|
|
13
|
-
import { runPostEditHook, runPostGlobHook, runPostGrepHook, runPostReadHook, runPostWriteHook, runPreEditHook, runPreGlobHook, runPreGrepHook, runPreReadHook, runPreWriteHook, } from "../hooks/navigation-hooks.js";
|
|
14
|
-
import { runUserPromptSubmitHook } from "../hooks/prompt-hooks.js";
|
|
15
|
-
import { runPreBashHook } from "../hooks/shell-hooks.js";
|
|
16
|
-
/**
|
|
17
|
-
* Safe hook action wrapper. Reads stdin, runs the handler, writes stdout.
|
|
18
|
-
* On ANY failure (EAGAIN on stdin, handler throw, etc.) outputs valid JSON "{}"
|
|
19
|
-
* so Claude Code never sees a crash/invalid output and reports "hook error".
|
|
20
|
-
*/
|
|
21
|
-
function safeHookAction(handler) {
|
|
22
|
-
return () => {
|
|
23
|
-
try {
|
|
24
|
-
const stdin = readFileSync(0, "utf-8");
|
|
25
|
-
process.stdout.write(handler(stdin));
|
|
26
|
-
}
|
|
27
|
-
catch (e) {
|
|
28
|
-
process.stderr.write(`[unerr] hook error: ${e}\n`);
|
|
29
|
-
process.stdout.write("{}");
|
|
30
|
-
}
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
export function registerHookCommand(program) {
|
|
34
|
-
const hook = program
|
|
35
|
-
.command("hook")
|
|
36
|
-
.description("IDE hook handlers (stdin/stdout JSON)");
|
|
37
|
-
// ── PreToolUse hooks ──────────────────────────────────────────
|
|
38
|
-
hook
|
|
39
|
-
.command("pre-bash")
|
|
40
|
-
.description("Rewrite Bash tool input to pipe through unerr exec")
|
|
41
|
-
.action(safeHookAction(runPreBashHook));
|
|
42
|
-
hook
|
|
43
|
-
.command("pre-read")
|
|
44
|
-
.description("Nudge agent to use file_outline/file_read instead of Read")
|
|
45
|
-
.action(safeHookAction(runPreReadHook));
|
|
46
|
-
hook
|
|
47
|
-
.command("pre-grep")
|
|
48
|
-
.description("Nudge agent to use search_code/get_callers instead of Grep")
|
|
49
|
-
.action(safeHookAction(runPreGrepHook));
|
|
50
|
-
hook
|
|
51
|
-
.command("pre-glob")
|
|
52
|
-
.description("Nudge agent to use search_code instead of Glob")
|
|
53
|
-
.action(safeHookAction(runPreGlobHook));
|
|
54
|
-
hook
|
|
55
|
-
.command("pre-write")
|
|
56
|
-
.description("Blast radius + convention check before Write")
|
|
57
|
-
.action(safeHookAction(runPreWriteHook));
|
|
58
|
-
hook
|
|
59
|
-
.command("pre-edit")
|
|
60
|
-
.description("Blast radius + convention check before Edit")
|
|
61
|
-
.action(safeHookAction(runPreEditHook));
|
|
62
|
-
// ── PostToolUse hooks ─────────────────────────────────────────
|
|
63
|
-
hook
|
|
64
|
-
.command("post-read")
|
|
65
|
-
.description("Enrich Read output with graph navigation suggestions")
|
|
66
|
-
.action(safeHookAction(runPostReadHook));
|
|
67
|
-
hook
|
|
68
|
-
.command("post-grep")
|
|
69
|
-
.description("Enrich Grep output with graph navigation suggestions")
|
|
70
|
-
.action(safeHookAction(runPostGrepHook));
|
|
71
|
-
hook
|
|
72
|
-
.command("post-glob")
|
|
73
|
-
.description("Enrich Glob output with graph navigation suggestions")
|
|
74
|
-
.action(safeHookAction(runPostGlobHook));
|
|
75
|
-
hook
|
|
76
|
-
.command("post-write")
|
|
77
|
-
.description("Post-write convention check + caller verification reminder")
|
|
78
|
-
.action(safeHookAction(runPostWriteHook));
|
|
79
|
-
hook
|
|
80
|
-
.command("post-edit")
|
|
81
|
-
.description("Post-edit convention check + caller verification reminder")
|
|
82
|
-
.action(safeHookAction(runPostEditHook));
|
|
83
|
-
// ── UserPromptSubmit hook ───────────────────────────────────────
|
|
84
|
-
hook
|
|
85
|
-
.command("prompt-submit")
|
|
86
|
-
.description("Inject unerr tool reminder on each user prompt")
|
|
87
|
-
.action(safeHookAction(runUserPromptSubmitHook));
|
|
88
|
-
}
|
package/dist/commands/index.js
DELETED
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* unerr index — Trigger local graph indexing.
|
|
3
|
-
*
|
|
4
|
-
* Scans the current project with tree-sitter AST analysis, extracts
|
|
5
|
-
* entities + edges, populates the persistent CozoDB at .unerr/graph.db,
|
|
6
|
-
* and runs community detection. Data persists across restarts.
|
|
7
|
-
*/
|
|
8
|
-
import { createHash } from "node:crypto";
|
|
9
|
-
import { getRemoteUrl, isGitRepo } from "../utils/git.js";
|
|
10
|
-
// ── Helpers ─────────────────────────────────────────────────
|
|
11
|
-
async function isInsideGitRepo() {
|
|
12
|
-
return isGitRepo(process.cwd());
|
|
13
|
-
}
|
|
14
|
-
async function deriveLocalRepoId(projectRoot) {
|
|
15
|
-
let repoIdentifier = projectRoot;
|
|
16
|
-
const remoteUrl = await getRemoteUrl(projectRoot);
|
|
17
|
-
if (remoteUrl)
|
|
18
|
-
repoIdentifier = remoteUrl;
|
|
19
|
-
return `local-${createHash("sha256").update(repoIdentifier).digest("hex").slice(0, 12)}`;
|
|
20
|
-
}
|
|
21
|
-
// ── Command ─────────────────────────────────────────────────
|
|
22
|
-
export function registerIndexCommand(program) {
|
|
23
|
-
program
|
|
24
|
-
.command("index")
|
|
25
|
-
.description("Build local code intelligence graph (replaces 'pull' in Local Mode)")
|
|
26
|
-
.option("--force", "Re-index even if local snapshot is fresh")
|
|
27
|
-
.option("--verbose", "Show per-file indexing progress")
|
|
28
|
-
.option("--json", "Output results as JSON (to stdout)")
|
|
29
|
-
.action(async (opts) => {
|
|
30
|
-
if (!(await isInsideGitRepo())) {
|
|
31
|
-
process.stderr.write("[unerr] Error: not inside a git repository.\n");
|
|
32
|
-
process.exit(1);
|
|
33
|
-
}
|
|
34
|
-
const projectRoot = process.cwd();
|
|
35
|
-
// Check freshness unless --force
|
|
36
|
-
if (!opts.force) {
|
|
37
|
-
const { shouldReindex } = await import("../intelligence/local-snapshot.js");
|
|
38
|
-
if (!shouldReindex(projectRoot)) {
|
|
39
|
-
if (opts.json) {
|
|
40
|
-
process.stdout.write(JSON.stringify({ status: "fresh", reindexed: false }));
|
|
41
|
-
process.stdout.write("\n");
|
|
42
|
-
}
|
|
43
|
-
else {
|
|
44
|
-
process.stderr.write("[unerr] Local snapshot is fresh. Use --force to re-index.\n");
|
|
45
|
-
}
|
|
46
|
-
process.exit(0);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
// Open persistent CozoDB (SQLite-backed at .unerr/graph.db)
|
|
50
|
-
const { openPersistentDb } = await import("../intelligence/persistent-db.js");
|
|
51
|
-
const { CozoGraphStore } = await import("../intelligence/local-graph.js");
|
|
52
|
-
const { db } = await openPersistentDb(projectRoot);
|
|
53
|
-
const graphStore = await CozoGraphStore.create(db);
|
|
54
|
-
const repoId = await deriveLocalRepoId(projectRoot);
|
|
55
|
-
// Run indexing
|
|
56
|
-
if (!opts.json) {
|
|
57
|
-
process.stderr.write("[unerr] Indexing local project...\n");
|
|
58
|
-
}
|
|
59
|
-
const { indexLocalProject } = await import("../intelligence/local-indexer.js");
|
|
60
|
-
const result = await indexLocalProject(projectRoot, graphStore, repoId, {
|
|
61
|
-
verbose: opts.verbose,
|
|
62
|
-
});
|
|
63
|
-
// Output results
|
|
64
|
-
if (opts.json) {
|
|
65
|
-
process.stdout.write(JSON.stringify({
|
|
66
|
-
status: "indexed",
|
|
67
|
-
reindexed: true,
|
|
68
|
-
fileCount: result.fileCount,
|
|
69
|
-
entityCount: result.entityCount,
|
|
70
|
-
edgeCount: result.edgeCount,
|
|
71
|
-
communityCount: result.communityCount,
|
|
72
|
-
patternCount: result.patternCount,
|
|
73
|
-
ruleCount: result.ruleCount,
|
|
74
|
-
elapsedMs: result.elapsedMs,
|
|
75
|
-
}));
|
|
76
|
-
process.stdout.write("\n");
|
|
77
|
-
}
|
|
78
|
-
else {
|
|
79
|
-
process.stderr.write(`\n[unerr] Indexed ${result.fileCount} files\n`);
|
|
80
|
-
process.stderr.write(` Entities: ${result.entityCount}\n`);
|
|
81
|
-
process.stderr.write(` Edges: ${result.edgeCount}\n`);
|
|
82
|
-
process.stderr.write(` Communities: ${result.communityCount}\n`);
|
|
83
|
-
process.stderr.write(` Conventions: ${result.patternCount} patterns, ${result.ruleCount} rules\n`);
|
|
84
|
-
process.stderr.write(` Time: ${result.elapsedMs}ms\n`);
|
|
85
|
-
process.stderr.write("\n[unerr] Graph persisted to .unerr/graph.db — available instantly on next boot.\n");
|
|
86
|
-
}
|
|
87
|
-
});
|
|
88
|
-
}
|
package/dist/commands/init.js
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* `unerr init` — auto-detect AI tools, install hooks, write MCP config.
|
|
3
|
-
*
|
|
4
|
-
* S6.2+S6.3: Combines tool detection, hook installation, and MCP config
|
|
5
|
-
* writing into a single command. Idempotent — safe to run multiple times.
|
|
6
|
-
*
|
|
7
|
-
* All output to stderr (stdout is MCP-sacred).
|
|
8
|
-
*/
|
|
9
|
-
import { installClaudeHook } from "../config/hook-installer.js";
|
|
10
|
-
import { writeMcpConfig } from "../config/mcp-config-writer.js";
|
|
11
|
-
import { detectTools, formatDetectedTools } from "../config/tool-detector.js";
|
|
12
|
-
export function registerInitCommand(program) {
|
|
13
|
-
program
|
|
14
|
-
.command("init")
|
|
15
|
-
.description("Auto-detect AI tools and configure unerr integration")
|
|
16
|
-
.action(async () => {
|
|
17
|
-
const cwd = process.cwd();
|
|
18
|
-
const result = runInit(cwd);
|
|
19
|
-
if (result.detectedTools.length === 0) {
|
|
20
|
-
process.stderr.write("[unerr] No AI tools detected. Create a .cursor/, .claude/, or .vscode/ directory first.\n");
|
|
21
|
-
process.stderr.write("[unerr] Or run 'unerr' directly — it will start the MCP proxy on stdio.\n");
|
|
22
|
-
return;
|
|
23
|
-
}
|
|
24
|
-
process.stderr.write(`[unerr] Detected: ${result.detectedTools.join(", ")}\n`);
|
|
25
|
-
for (const h of result.hooksInstalled) {
|
|
26
|
-
process.stderr.write(`[unerr] ✓ ${h}\n`);
|
|
27
|
-
}
|
|
28
|
-
for (const c of result.configsWritten) {
|
|
29
|
-
process.stderr.write(`[unerr] ✓ ${c}\n`);
|
|
30
|
-
}
|
|
31
|
-
for (const s of result.skipped) {
|
|
32
|
-
process.stderr.write(`[unerr] · ${s}\n`);
|
|
33
|
-
}
|
|
34
|
-
process.stderr.write("[unerr] Init complete. Run 'unerr' to start.\n");
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* Core init logic — testable without Commander.
|
|
39
|
-
*/
|
|
40
|
-
export function runInit(cwd) {
|
|
41
|
-
const tools = detectTools(cwd);
|
|
42
|
-
const result = {
|
|
43
|
-
detectedTools: [],
|
|
44
|
-
hooksInstalled: [],
|
|
45
|
-
configsWritten: [],
|
|
46
|
-
skipped: [],
|
|
47
|
-
};
|
|
48
|
-
for (const tool of tools) {
|
|
49
|
-
const name = formatDetectedTools([tool]);
|
|
50
|
-
result.detectedTools.push(name);
|
|
51
|
-
// Install hook for Claude Code
|
|
52
|
-
if (tool.ide === "claude-code") {
|
|
53
|
-
const hookResult = installClaudeHook(cwd);
|
|
54
|
-
if (hookResult.action === "installed") {
|
|
55
|
-
result.hooksInstalled.push(`Installed Claude Code hook at ${hookResult.path}`);
|
|
56
|
-
}
|
|
57
|
-
else if (hookResult.action === "already_exists") {
|
|
58
|
-
result.skipped.push("Claude Code hook already installed");
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
// Write MCP config for all detected tools
|
|
62
|
-
const configResult = writeMcpConfig(cwd, tool.ide);
|
|
63
|
-
if (configResult.action === "created") {
|
|
64
|
-
result.configsWritten.push(`Created MCP config at ${configResult.path}`);
|
|
65
|
-
}
|
|
66
|
-
else if (configResult.action === "updated") {
|
|
67
|
-
result.configsWritten.push(`Added unerr to existing config at ${configResult.path}`);
|
|
68
|
-
}
|
|
69
|
-
else {
|
|
70
|
-
result.skipped.push(`MCP config for ${name} already configured`);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
return result;
|
|
74
|
-
}
|