@unerr-ai/unerr 0.1.0 → 0.1.1
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/dist/__tests__/architecture-guard.test.js +122 -0
- package/dist/__tests__/arg-validator.test.js +205 -0
- package/dist/__tests__/ast-extractor.test.js +203 -0
- package/dist/__tests__/auto-bootstrap.test.js +280 -0
- package/dist/__tests__/background-indexer.test.js +228 -0
- package/dist/__tests__/blast-radius-engine.test.js +200 -0
- package/dist/__tests__/bridge-isolation.test.js +37 -0
- package/dist/__tests__/budget-enforcer.test.js +53 -0
- package/dist/__tests__/cfg-test-detection-perf.test.js +82 -0
- package/dist/__tests__/change-narrative.test.js +190 -0
- package/dist/__tests__/check-commit.test.js +258 -0
- package/dist/__tests__/checksum.test.js +34 -0
- package/dist/__tests__/commit-watcher.test.js +154 -0
- package/dist/__tests__/community-detection.test.js +179 -0
- package/dist/__tests__/community-tools.test.js +299 -0
- package/dist/__tests__/components.test.js +449 -0
- package/dist/__tests__/compression-log.test.js +174 -0
- package/dist/__tests__/compression-quality-monitor.test.js +40 -0
- package/dist/__tests__/config-healer.test.js +165 -0
- package/dist/__tests__/context-ledger.test.js +58 -0
- package/dist/__tests__/convention-detector.test.js +99 -0
- package/dist/__tests__/convention-learner.test.js +86 -0
- package/dist/__tests__/correction-detector.test.js +330 -0
- package/dist/__tests__/daemon-autostart-install.test.js +283 -0
- package/dist/__tests__/daemon-bridge.test.js +222 -0
- package/dist/__tests__/daemon-dashboard.test.js +202 -0
- package/dist/__tests__/daemon-registry.test.js +240 -0
- package/dist/__tests__/daemon-supervisor.test.js +318 -0
- package/dist/__tests__/daemon-version-check.test.js +275 -0
- package/dist/__tests__/decision-point-detector.test.js +98 -0
- package/dist/__tests__/deep-link.test.js +143 -0
- package/dist/__tests__/disallowed-tools.test.js +115 -0
- package/dist/__tests__/drift-tracker.test.js +582 -0
- package/dist/__tests__/durability-scorer.test.js +152 -0
- package/dist/__tests__/efficiency-tracker.test.js +65 -0
- package/dist/__tests__/enrich.test.js +144 -0
- package/dist/__tests__/entity-rewind.test.js +248 -0
- package/dist/__tests__/ephemeral.test.js +111 -0
- package/dist/__tests__/exploration-cost.test.js +93 -0
- package/dist/__tests__/fact-generator.test.js +197 -0
- package/dist/__tests__/file-l0-graph.test.js +244 -0
- package/dist/__tests__/file-logger.test.js +82 -0
- package/dist/__tests__/file-outline.test.js +141 -0
- package/dist/__tests__/file-read-protocol.test.js +188 -0
- package/dist/__tests__/format-encoder.test.js +233 -0
- package/dist/__tests__/git-attribution.test.js +259 -0
- package/dist/__tests__/graph-temporal-joiner.test.js +219 -0
- package/dist/__tests__/health-grade-enhanced.test.js +138 -0
- package/dist/__tests__/health-map-data.test.js +173 -0
- package/dist/__tests__/helpers/mcp-harness.js +45 -0
- package/dist/__tests__/helpers/mcp-harness.test.js +68 -0
- package/dist/__tests__/hook-dedup.test.js +112 -0
- package/dist/__tests__/hook-runner.test.js +253 -0
- package/dist/__tests__/indexer-cfg.test.js +185 -0
- package/dist/__tests__/indexer-cross-file.test.js +172 -0
- package/dist/__tests__/indexer-extraction.test.js +245 -0
- package/dist/__tests__/indexer-incremental.test.js +232 -0
- package/dist/__tests__/indexer-language-expansion.test.js +165 -0
- package/dist/__tests__/init-push.test.js +131 -0
- package/dist/__tests__/instruction-writer.test.js +179 -0
- package/dist/__tests__/intelligence-integration.test.js +217 -0
- package/dist/__tests__/intent-correlator.test.js +175 -0
- package/dist/__tests__/intent-detector.test.js +235 -0
- package/dist/__tests__/intent-encoder.test.js +167 -0
- package/dist/__tests__/java-build-tool-detection.test.js +174 -0
- package/dist/__tests__/layer3-sprint-q.test.js +160 -0
- package/dist/__tests__/layer3-sprint-r.test.js +91 -0
- package/dist/__tests__/layer3-sprint-s.test.js +183 -0
- package/dist/__tests__/layer3-sprint-t.test.js +201 -0
- package/dist/__tests__/layer3-sprint-u.test.js +174 -0
- package/dist/__tests__/layer4-sprint-ba2.test.js +354 -0
- package/dist/__tests__/layer4-sprint-ba4.test.js +84 -0
- package/dist/__tests__/layer4-sprint-vs.test.js +105 -0
- package/dist/__tests__/ledger-chains.test.js +162 -0
- package/dist/__tests__/lifecycle-machine.test.js +226 -0
- package/dist/__tests__/local-chat-provider.test.js +170 -0
- package/dist/__tests__/local-convention-detector.test.js +308 -0
- package/dist/__tests__/local-embeddings.test.js +422 -0
- package/dist/__tests__/local-graph.test.js +540 -0
- package/dist/__tests__/local-indexer.test.js +228 -0
- package/dist/__tests__/local-intelligence-l3.test.js +332 -0
- package/dist/__tests__/local-llm.test.js +253 -0
- package/dist/__tests__/local-mode-offline.test.js +187 -0
- package/dist/__tests__/local-mode-stats.test.js +273 -0
- package/dist/__tests__/local-mode-tui.test.js +343 -0
- package/dist/__tests__/local-parse.test.js +199 -0
- package/dist/__tests__/log-tailer.test.js +208 -0
- package/dist/__tests__/loop-breaker.test.js +276 -0
- package/dist/__tests__/loop-miner.test.js +226 -0
- package/dist/__tests__/mcp-config.test.js +126 -0
- package/dist/__tests__/mcp-content-json.test.js +10 -0
- package/dist/__tests__/mcp-envelope.test.js +124 -0
- package/dist/__tests__/metrics-store.test.js +223 -0
- package/dist/__tests__/native-watcher.test.js +191 -0
- package/dist/__tests__/navigation-hooks-agent-aware.test.js +145 -0
- package/dist/__tests__/negative-knowledge.test.js +116 -0
- package/dist/__tests__/network-boundary.test.js +190 -0
- package/dist/__tests__/network-firewall.test.js +112 -0
- package/dist/__tests__/nudge-invariants.test.js +160 -0
- package/dist/__tests__/nudge-v2.test.js +225 -0
- package/dist/__tests__/offline-rewind.test.js +251 -0
- package/dist/__tests__/open-threads.test.js +89 -0
- package/dist/__tests__/output-compressor.test.js +93 -0
- package/dist/__tests__/pending-violations.test.js +112 -0
- package/dist/__tests__/persistence-effectiveness.test.js +143 -0
- package/dist/__tests__/provider-factory.test.js +42 -0
- package/dist/__tests__/providers.test.js +24 -0
- package/dist/__tests__/proxy.test.js +314 -0
- package/dist/__tests__/query-router.test.js +1018 -0
- package/dist/__tests__/reasoning-quality-route.test.js +138 -0
- package/dist/__tests__/redactor.test.js +120 -0
- package/dist/__tests__/resource-monitor.test.js +57 -0
- package/dist/__tests__/response-envelope.test.js +100 -0
- package/dist/__tests__/risk-classifier.test.js +101 -0
- package/dist/__tests__/risk-signal-scope.test.js +75 -0
- package/dist/__tests__/rule-evaluator.test.js +280 -0
- package/dist/__tests__/scip-decoder.test.js +49 -0
- package/dist/__tests__/scip-downloader.test.js +201 -0
- package/dist/__tests__/scip-merger.test.js +103 -0
- package/dist/__tests__/search-index.test.js +422 -0
- package/dist/__tests__/semantic-enrichment.test.js +360 -0
- package/dist/__tests__/session-brief-builder.test.js +187 -0
- package/dist/__tests__/session-context.test.js +221 -0
- package/dist/__tests__/session-continuity.test.js +144 -0
- package/dist/__tests__/session-dedup.test.js +74 -0
- package/dist/__tests__/session-event-wiring.test.js +206 -0
- package/dist/__tests__/session-events.test.js +149 -0
- package/dist/__tests__/session-legend.test.js +20 -0
- package/dist/__tests__/session-persistence.test.js +131 -0
- package/dist/__tests__/session-resume-block.test.js +107 -0
- package/dist/__tests__/session-resume.test.js +97 -0
- package/dist/__tests__/session-summary-writer.test.js +134 -0
- package/dist/__tests__/shadow-ledger.test.js +203 -0
- package/dist/__tests__/shell-classifier.test.js +151 -0
- package/dist/__tests__/shell-compression-floor.test.js +189 -0
- package/dist/__tests__/shell-compression-v2.test.js +339 -0
- package/dist/__tests__/shell-compressor.test.js +35 -0
- package/dist/__tests__/shell-hooks.test.js +128 -0
- package/dist/__tests__/shell-strategies.test.js +644 -0
- package/dist/__tests__/shell-tee.test.js +133 -0
- package/dist/__tests__/signal-dedup.test.js +158 -0
- package/dist/__tests__/signal-reinforcer.test.js +77 -0
- package/dist/__tests__/signal-scorer.test.js +251 -0
- package/dist/__tests__/signal-show-store.test.js +108 -0
- package/dist/__tests__/smart-truncate.test.js +215 -0
- package/dist/__tests__/snapshot-v2.test.js +113 -0
- package/dist/__tests__/sprint-l1-local-mode.test.js +130 -0
- package/dist/__tests__/sprint-l10-boot.test.js +220 -0
- package/dist/__tests__/sprint-l9-offline-commands.test.js +189 -0
- package/dist/__tests__/sprint-q-persistent-context.test.js +198 -0
- package/dist/__tests__/sprint-s1-wiring.test.js +215 -0
- package/dist/__tests__/sprint-s2-wiring.test.js +256 -0
- package/dist/__tests__/sprint-s3-wiring.test.js +195 -0
- package/dist/__tests__/sprint-s4-wiring.test.js +213 -0
- package/dist/__tests__/sprint-s6-hooks.test.js +222 -0
- package/dist/__tests__/sprint-s7-persistent.test.js +263 -0
- package/dist/__tests__/sprint-s8-value.test.js +167 -0
- package/dist/__tests__/sprint-s9-behavioral.test.js +179 -0
- package/dist/__tests__/sprint3-intelligence.test.js +297 -0
- package/dist/__tests__/sprint5-mcp-server.test.js +136 -0
- package/dist/__tests__/startup-display.test.js +302 -0
- package/dist/__tests__/startup-log-file.test.js +97 -0
- package/dist/__tests__/stash-manager.test.js +229 -0
- package/dist/__tests__/state-detector.test.js +92 -0
- package/dist/__tests__/status-dashboard.test.js +142 -0
- package/dist/__tests__/temporal-facts.test.js +292 -0
- package/dist/__tests__/temporal-routes.test.js +142 -0
- package/dist/__tests__/test-detector.test.js +174 -0
- package/dist/__tests__/theme.test.js +72 -0
- package/dist/__tests__/timeline-agents.test.js +122 -0
- package/dist/__tests__/timeline-bootstrap.test.js +176 -0
- package/dist/__tests__/timeline-filters.test.js +193 -0
- package/dist/__tests__/timeline-markers.test.js +151 -0
- package/dist/__tests__/timeline-routes.test.js +156 -0
- package/dist/__tests__/timeline-store.test.js +171 -0
- package/dist/__tests__/token-counter.test.js +86 -0
- package/dist/__tests__/token-estimator.test.js +96 -0
- package/dist/__tests__/token-flow-api.test.js +239 -0
- package/dist/__tests__/token-flow-instrumentation.test.js +437 -0
- package/dist/__tests__/token-flow-persistence.test.js +356 -0
- package/dist/__tests__/token-flow-routes.test.js +199 -0
- package/dist/__tests__/token-flow.test.js +695 -0
- package/dist/__tests__/tool-clusters.test.js +177 -0
- package/dist/__tests__/transport-mux.test.js +283 -0
- package/dist/__tests__/turn-segmenter.test.js +166 -0
- package/dist/__tests__/uninstall.test.js +141 -0
- package/dist/__tests__/warm-start-policy.test.js +271 -0
- package/dist/__tests__/wire-cap-nudge.test.js +77 -0
- package/dist/__tests__/worker-pool.test.js +101 -0
- package/dist/behaviors/agent-llm-bridge.js +166 -0
- package/dist/behaviors/architecture-guard.js +256 -0
- package/dist/behaviors/auto-doc.js +247 -0
- package/dist/behaviors/cascade-guard.js +289 -0
- package/dist/behaviors/change-narrative.js +270 -0
- package/dist/behaviors/convention-drift.js +290 -0
- package/dist/behaviors/framework.js +235 -0
- package/dist/behaviors/guard-formatter.js +44 -0
- package/dist/behaviors/incomplete-work.js +270 -0
- package/dist/behaviors/loop-breaker.js +300 -0
- package/dist/behaviors/session-continuity.js +208 -0
- package/dist/cli.js +992 -706
- package/dist/commands/branches.js +97 -0
- package/dist/commands/check-commit.js +225 -0
- package/dist/commands/compress-output.js +64 -0
- package/dist/commands/config-verify.js +243 -0
- package/dist/commands/daemon.js +905 -0
- package/dist/commands/dashboard.js +52 -0
- package/dist/commands/debug.js +200 -0
- package/dist/commands/enrich.js +184 -0
- package/dist/commands/exec.js +233 -0
- package/dist/commands/gain.js +156 -0
- package/dist/commands/hook.js +88 -0
- package/dist/commands/index.js +88 -0
- package/dist/commands/init.js +74 -0
- package/dist/commands/install.js +505 -0
- package/dist/commands/learn.js +116 -0
- package/dist/commands/manifest.js +193 -0
- package/dist/commands/rewind.js +103 -0
- package/dist/commands/serve.js +19 -0
- package/dist/commands/setup-wizard.js +414 -0
- package/dist/commands/skills.js +64 -0
- package/dist/commands/stats.js +20 -0
- package/dist/commands/status.js +654 -0
- package/dist/commands/timeline.js +139 -0
- package/dist/commands/uninstall.js +230 -0
- package/dist/components/App.js +109 -0
- package/dist/components/Banner.js +12 -0
- package/dist/components/ConfirmPrompt.js +25 -0
- package/dist/components/DriftSummary.js +23 -0
- package/dist/components/GradeBadge.js +15 -0
- package/dist/components/HealthCard.js +18 -0
- package/dist/components/InkSpinner.js +22 -0
- package/dist/components/InputBox.js +17 -0
- package/dist/components/KeyValue.js +13 -0
- package/dist/components/MessageList.js +14 -0
- package/dist/components/ProgressBar.js +26 -0
- package/dist/components/Section.js +16 -0
- package/dist/components/SessionSummaryCard.js +73 -0
- package/dist/components/StartupDisplay.js +24 -0
- package/dist/components/StatusDashboard.js +57 -0
- package/dist/components/StatusLine.js +8 -0
- package/dist/components/StepLine.js +22 -0
- package/dist/components/Theme.js +20 -0
- package/dist/components/ToolProgress.js +8 -0
- package/dist/components/ViolationList.js +21 -0
- package/dist/components/render.js +13 -0
- package/dist/config/agent-registry.js +237 -0
- package/dist/config/claude-settings-hooks.js +304 -0
- package/dist/config/hook-installer.js +65 -0
- package/dist/config/instruction-writer.js +388 -0
- package/dist/config/mcp-config-writer.js +266 -0
- package/dist/config/settings.js +174 -0
- package/dist/config/tool-detector.js +42 -0
- package/dist/config/value-surfacing.js +119 -0
- package/dist/core/context-assembly.js +108 -0
- package/dist/core/conversation.js +33 -0
- package/dist/core/local-chat-provider.js +475 -0
- package/dist/core/provider-factory.js +55 -0
- package/dist/core/providers.js +90 -0
- package/dist/core/query-engine.js +174 -0
- package/dist/daemon/api.js +312 -0
- package/dist/daemon/autostart.js +119 -0
- package/dist/daemon/bootstrap.js +39 -0
- package/dist/daemon/client.js +164 -0
- package/dist/daemon/detect-ci.js +81 -0
- package/dist/daemon/platform-linux.js +146 -0
- package/dist/daemon/platform-macos.js +134 -0
- package/dist/daemon/platform-windows.js +116 -0
- package/dist/daemon/process-manager.js +299 -0
- package/dist/daemon/protocol.js +23 -0
- package/dist/daemon/registry.js +270 -0
- package/dist/daemon/settings-schema.js +72 -0
- package/dist/daemon/system-health.js +134 -0
- package/dist/daemon/version-checker.js +262 -0
- package/dist/daemon/warm-start.js +223 -0
- package/dist/entrypoints/cli.js +1043 -0
- package/dist/entrypoints/daemon.js +380 -0
- package/dist/entrypoints/repl.js +147 -0
- package/dist/hooks/adapters/claude-code.js +90 -0
- package/dist/hooks/adapters/cline.js +100 -0
- package/dist/hooks/adapters/cursor.js +98 -0
- package/dist/hooks/hook-dedup.js +79 -0
- package/dist/hooks/hook-runner.js +113 -0
- package/dist/hooks/navigation-hooks.js +175 -0
- package/dist/hooks/prompt-hooks.js +63 -0
- package/dist/hooks/shell-hooks.js +47 -0
- package/dist/ignore.js +111 -0
- package/dist/intelligence/approach-suggester.js +61 -0
- package/dist/intelligence/ast-extractor.js +2615 -0
- package/dist/intelligence/ast-worker.js +34 -0
- package/dist/intelligence/background-indexer.js +121 -0
- package/dist/intelligence/blast-radius.js +200 -0
- package/dist/intelligence/community-detection.js +691 -0
- package/dist/intelligence/community-detector.js +184 -0
- package/dist/intelligence/computation-scheduler.js +75 -0
- package/dist/intelligence/confidence-propagation.js +47 -0
- package/dist/intelligence/convention-detector.js +242 -0
- package/dist/intelligence/convention-learner.js +205 -0
- package/dist/intelligence/convention-matcher.js +205 -0
- package/dist/intelligence/cozo-schema.js +376 -0
- package/dist/intelligence/decision-point-detector.js +90 -0
- package/dist/intelligence/deep-dive-tools.js +586 -0
- package/dist/intelligence/durability-scorer.js +84 -0
- package/dist/intelligence/exploration-cost.js +204 -0
- package/dist/intelligence/exploration-pattern-tracker.js +61 -0
- package/dist/intelligence/fact-generator.js +322 -0
- package/dist/intelligence/facts-schema.js +90 -0
- package/dist/intelligence/file-intelligence.js +59 -0
- package/dist/intelligence/graph-holder.js +220 -0
- package/dist/intelligence/graph-temporal-joiner.js +238 -0
- package/dist/intelligence/health-grade.js +423 -0
- package/dist/intelligence/health-grader.js +200 -0
- package/dist/intelligence/health-map-data.js +259 -0
- package/dist/intelligence/import-symbols.js +136 -0
- package/dist/intelligence/incremental-indexer.js +658 -0
- package/dist/intelligence/indexer/centrality.js +62 -0
- package/dist/intelligence/indexer/cfg-context.js +95 -0
- package/dist/intelligence/indexer/confidence.js +34 -0
- package/dist/intelligence/indexer/cross-file-resolver.js +104 -0
- package/dist/intelligence/indexer/edge-repair.js +89 -0
- package/dist/intelligence/indexer/entity-key.js +17 -0
- package/dist/intelligence/indexer/export-map.js +132 -0
- package/dist/intelligence/indexer/git-cochange.js +128 -0
- package/dist/intelligence/indexer/graph-patch.js +147 -0
- package/dist/intelligence/indexer/incremental.js +78 -0
- package/dist/intelligence/indexer/ingest.js +160 -0
- package/dist/intelligence/indexer/language-detect.js +226 -0
- package/dist/intelligence/indexer/metadata.js +63 -0
- package/dist/intelligence/indexer/mutation-tracker.js +79 -0
- package/dist/intelligence/indexer/orchestrator.js +155 -0
- package/dist/intelligence/indexer/plugin-interface.js +31 -0
- package/dist/intelligence/indexer/plugins/csharp.js +440 -0
- package/dist/intelligence/indexer/plugins/go.js +335 -0
- package/dist/intelligence/indexer/plugins/java.js +370 -0
- package/dist/intelligence/indexer/plugins/python.js +358 -0
- package/dist/intelligence/indexer/plugins/regex-fallback.js +82 -0
- package/dist/intelligence/indexer/plugins/ruby.js +290 -0
- package/dist/intelligence/indexer/plugins/rust.js +484 -0
- package/dist/intelligence/indexer/plugins/tier2-generic.js +310 -0
- package/dist/intelligence/indexer/plugins/typescript.js +456 -0
- package/dist/intelligence/indexer/resource-monitor.js +93 -0
- package/dist/intelligence/indexer/scip/decoder.js +253 -0
- package/dist/intelligence/indexer/scip/detector.js +232 -0
- package/dist/intelligence/indexer/scip/downloader.js +427 -0
- package/dist/intelligence/indexer/scip/fallback.js +34 -0
- package/dist/intelligence/indexer/scip/merger.js +109 -0
- package/dist/intelligence/indexer/scip/orchestrator.js +433 -0
- package/dist/intelligence/indexer/scip/runner.js +98 -0
- package/dist/intelligence/indexer/snapshot.js +66 -0
- package/dist/intelligence/indexer/test-detector.js +196 -0
- package/dist/intelligence/indexer/watch-integration.js +61 -0
- package/dist/intelligence/indexer/worker.js +85 -0
- package/dist/intelligence/local-convention-detector.js +437 -0
- package/dist/intelligence/local-embeddings.js +190 -0
- package/dist/intelligence/local-graph.js +1946 -0
- package/dist/intelligence/local-indexer.js +1575 -0
- package/dist/intelligence/local-llm.js +163 -0
- package/dist/intelligence/local-rule-generator.js +154 -0
- package/dist/intelligence/local-snapshot.js +213 -0
- package/dist/intelligence/negative-knowledge.js +103 -0
- package/dist/intelligence/persistent-db.js +85 -0
- package/dist/intelligence/query-router.js +2556 -0
- package/dist/intelligence/risk-classifier.js +116 -0
- package/dist/intelligence/rule-evaluator.js +380 -0
- package/dist/intelligence/rule-generator.js +49 -0
- package/dist/intelligence/search-index.js +173 -0
- package/dist/intelligence/semantic/docstring-extractor.js +67 -0
- package/dist/intelligence/semantic/embedding-store.js +52 -0
- package/dist/intelligence/semantic/enrichment-orchestrator.js +48 -0
- package/dist/intelligence/semantic/git-message-miner.js +114 -0
- package/dist/intelligence/semantic/identifier-tokenizer.js +51 -0
- package/dist/intelligence/semantic/node2vec-embeddings.js +71 -0
- package/dist/intelligence/semantic/node2vec-walks.js +103 -0
- package/dist/intelligence/semantic/path-domain-inference.js +112 -0
- package/dist/intelligence/semantic/similarity-engine.js +60 -0
- package/dist/intelligence/semantic/tfidf-vectors.js +88 -0
- package/dist/intelligence/session-brief-builder.js +159 -0
- package/dist/intelligence/session-context.js +221 -0
- package/dist/intelligence/session-health-monitor.js +211 -0
- package/dist/intelligence/session-narrative.js +197 -0
- package/dist/intelligence/session-pattern-analyzer.js +218 -0
- package/dist/intelligence/signal-scorer.js +390 -0
- package/dist/intelligence/signal-show-store.js +182 -0
- package/dist/intelligence/smart-truncate.js +158 -0
- package/dist/intelligence/subgraph-cache.js +88 -0
- package/dist/intelligence/temporal-facts.js +494 -0
- package/dist/intelligence/token-estimator.js +100 -0
- package/dist/intelligence/tool-injector.js +87 -0
- package/dist/intelligence/tree-sitter-loader.js +71 -0
- package/dist/intelligence/worker-pool.js +116 -0
- package/dist/proxy/arg-validator.js +79 -0
- package/dist/proxy/auto-bootstrap.js +167 -0
- package/dist/proxy/bridge.js +147 -0
- package/dist/proxy/budget-enforcer.js +70 -0
- package/dist/proxy/compression-quality-monitor.js +160 -0
- package/dist/proxy/compression-stats.js +51 -0
- package/dist/proxy/context-rot-detector.js +137 -0
- package/dist/proxy/drift-detector.js +139 -0
- package/dist/proxy/efficiency-tracker.js +79 -0
- package/dist/proxy/fact-ranking.js +154 -0
- package/dist/proxy/format-encoder.js +266 -0
- package/dist/proxy/http-transport.js +90 -0
- package/dist/proxy/lifecycle-actor.js +55 -0
- package/dist/proxy/lifecycle-machine.js +187 -0
- package/dist/proxy/log-tailer.js +265 -0
- package/dist/proxy/model-pricing.js +98 -0
- package/dist/proxy/network-firewall.js +141 -0
- package/dist/proxy/nudge-state.js +93 -0
- package/dist/proxy/output-compressor.js +185 -0
- package/dist/proxy/pid-lock.js +291 -0
- package/dist/proxy/proxy-context.js +11 -0
- package/dist/proxy/proxy.js +2633 -0
- package/dist/proxy/response-enrichment.js +32 -0
- package/dist/proxy/response-envelope.js +313 -0
- package/dist/proxy/session-dedup.js +82 -0
- package/dist/proxy/session-legend.js +30 -0
- package/dist/proxy/session-persistence.js +210 -0
- package/dist/proxy/session-resume.js +94 -0
- package/dist/proxy/session-stats.js +513 -0
- package/dist/proxy/shell-classifier.js +1346 -0
- package/dist/proxy/shell-compression-log.js +93 -0
- package/dist/proxy/shell-compressor.js +390 -0
- package/dist/proxy/shell-graph-boost.js +202 -0
- package/dist/proxy/shell-monitor-map.js +18 -0
- package/dist/proxy/shell-stats.js +54 -0
- package/dist/proxy/shell-strategies/cloud.js +215 -0
- package/dist/proxy/shell-strategies/diff.js +159 -0
- package/dist/proxy/shell-strategies/error-diagnostic.js +796 -0
- package/dist/proxy/shell-strategies/filter-dsl.js +358 -0
- package/dist/proxy/shell-strategies/git-status.js +177 -0
- package/dist/proxy/shell-strategies/key-value.js +193 -0
- package/dist/proxy/shell-strategies/log-text.js +154 -0
- package/dist/proxy/shell-strategies/omni.js +188 -0
- package/dist/proxy/shell-strategies/progress.js +55 -0
- package/dist/proxy/shell-strategies/redact.js +76 -0
- package/dist/proxy/shell-strategies/structured.js +241 -0
- package/dist/proxy/shell-strategies/tabular.js +243 -0
- package/dist/proxy/shell-strategies/test-results-types.js +13 -0
- package/dist/proxy/shell-strategies/test-results.js +784 -0
- package/dist/proxy/shell-strategies/tree-paths.js +144 -0
- package/dist/proxy/shell-strategies/yaml.js +182 -0
- package/dist/proxy/shell-tee.js +111 -0
- package/dist/proxy/signal-dedup.js +171 -0
- package/dist/proxy/startup-renderer.js +158 -0
- package/dist/proxy/task-token-display.js +38 -0
- package/dist/proxy/token-counter.js +61 -0
- package/dist/proxy/tool-clusters.js +273 -0
- package/dist/proxy/tool-definitions.js +525 -0
- package/dist/proxy/transport-mux.js +229 -0
- package/dist/proxy/wire-cap.js +268 -0
- package/dist/schemas/api/skills.js +19 -0
- package/dist/schemas/common/errors.js +7 -0
- package/dist/schemas/common/headers.js +5 -0
- package/dist/schemas/entities/edge.js +25 -0
- package/dist/schemas/entities/entity.js +22 -0
- package/dist/schemas/entities/rule.js +18 -0
- package/dist/schemas/index.js +14 -0
- package/dist/server/event-bus.js +59 -0
- package/dist/server/http.js +156 -0
- package/dist/server/middleware.js +70 -0
- package/dist/server/routes/drift.js +97 -0
- package/dist/server/routes/intelligence.js +1217 -0
- package/dist/server/routes/reasoning-quality.js +444 -0
- package/dist/server/routes/session.js +86 -0
- package/dist/server/routes/stream.js +120 -0
- package/dist/server/routes/system.js +73 -0
- package/dist/server/routes/temporal.js +170 -0
- package/dist/server/routes/timeline.js +232 -0
- package/dist/server/routes/token-flow.js +403 -0
- package/dist/skills/effectiveness-tracker.js +93 -0
- package/dist/skills/local-pack.js +380 -0
- package/dist/skills/resolver.js +495 -0
- package/dist/state-detector.js +83 -0
- package/dist/timeline/intent-detector.js +263 -0
- package/dist/timeline/loop-miner.js +140 -0
- package/dist/timeline/open-threads.js +49 -0
- package/dist/timeline/signal-reinforcer.js +62 -0
- package/dist/timeline/timeline-bootstrap.js +151 -0
- package/dist/timeline/timeline-store.js +618 -0
- package/dist/tools/coding/bash.js +49 -0
- package/dist/tools/coding/file-edit.js +72 -0
- package/dist/tools/coding/file-outline.js +227 -0
- package/dist/tools/coding/file-read-protocol.js +425 -0
- package/dist/tools/coding/file-read.js +35 -0
- package/dist/tools/coding/file-write.js +43 -0
- package/dist/tools/coding/glob-tool.js +109 -0
- package/dist/tools/coding/grep.js +162 -0
- package/dist/tools/coding/index.js +27 -0
- package/dist/tools/intelligence/index.js +269 -0
- package/dist/tools/intelligence/record-fact.js +48 -0
- package/dist/tools/intelligence/timeline-markers.js +130 -0
- package/dist/tools/registry.js +47 -0
- package/dist/tools/types.js +8 -0
- package/dist/tracking/auto-snapshot-triggers.js +246 -0
- package/dist/tracking/branch-context.js +115 -0
- package/dist/tracking/branch-snapshot.js +217 -0
- package/dist/tracking/causal-bridge.js +317 -0
- package/dist/tracking/circuit-breaker.js +147 -0
- package/dist/tracking/commit-watcher.js +114 -0
- package/dist/tracking/context-ledger.js +119 -0
- package/dist/tracking/correction-detector.js +324 -0
- package/dist/tracking/drift-tracker.js +874 -0
- package/dist/tracking/durability-tracker.js +94 -0
- package/dist/tracking/entity-rewind.js +200 -0
- package/dist/tracking/file-hash-state.js +114 -0
- package/dist/tracking/git-attribution.js +132 -0
- package/dist/tracking/git-trailers.js +171 -0
- package/dist/tracking/intelligence-counter.js +46 -0
- package/dist/tracking/intent-correlator.js +202 -0
- package/dist/tracking/intent-encoder.js +52 -0
- package/dist/tracking/intent-token-tracker.js +159 -0
- package/dist/tracking/ledger-archiver.js +94 -0
- package/dist/tracking/ledger-chains.js +245 -0
- package/dist/tracking/metrics-store.js +361 -0
- package/dist/tracking/native-watcher.js +131 -0
- package/dist/tracking/offline-rewind.js +295 -0
- package/dist/tracking/pending-violations.js +74 -0
- package/dist/tracking/persistence-effectiveness.js +167 -0
- package/dist/tracking/prompt-durability.js +202 -0
- package/dist/tracking/quality-signals.js +213 -0
- package/dist/tracking/redactor.js +73 -0
- package/dist/tracking/rewind-engine.js +161 -0
- package/dist/tracking/session-history.js +128 -0
- package/dist/tracking/session-receipt.js +88 -0
- package/dist/tracking/session-summary-writer.js +157 -0
- package/dist/tracking/shadow-ledger.js +321 -0
- package/dist/tracking/stash-manager.js +258 -0
- package/dist/tracking/timeline-fork.js +213 -0
- package/dist/tracking/timeline.js +69 -0
- package/dist/tracking/token-flow.js +276 -0
- package/dist/tracking/turn-segmenter.js +122 -0
- package/dist/tracking/weekly-accumulator.js +179 -0
- package/dist/tracking/working-snapshots.js +188 -0
- package/dist/tracking/workspace-manifest.js +176 -0
- package/dist/transport/http.js +102 -0
- package/dist/ui/assets/index-BsMTQdhX.js +10 -0
- package/dist/ui/index.html +1 -1
- package/dist/utils/counterfactual.js +65 -0
- package/dist/utils/deep-link.js +34 -0
- package/dist/utils/detect.js +193 -0
- package/dist/utils/exec.js +73 -0
- package/dist/utils/file-logger.js +87 -0
- package/dist/utils/format-error.js +29 -0
- package/dist/utils/git.js +181 -0
- package/dist/utils/log.js +57 -0
- package/dist/utils/logger.js +35 -0
- package/dist/utils/mcp-content-json.js +8 -0
- package/dist/utils/session-logger.js +154 -0
- package/dist/utils/startup-log.js +512 -0
- package/dist/utils/ui.js +56 -0
- package/package.json +5 -3
- package/scripts/postinstall.mjs +299 -0
- package/dist/ui/assets/index-B-0HTtUR.js +0 -10
package/dist/ui/index.html
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>unerr — intelligence</title>
|
|
7
|
-
<script type="module" crossorigin src="/assets/index-
|
|
7
|
+
<script type="module" crossorigin src="/assets/index-BsMTQdhX.js"></script>
|
|
8
8
|
<link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-S-ySWqyJ.js">
|
|
9
9
|
<link rel="modulepreload" crossorigin href="/assets/vis-network-NIJHUFI3.js">
|
|
10
10
|
<link rel="stylesheet" crossorigin href="/assets/index-7gl3mIuY.css">
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Counterfactual Framing Utility — wraps all savings displays in
|
|
3
|
+
* "without unerr" framing for value perception.
|
|
4
|
+
*
|
|
5
|
+
* VS.8: Every savings display must use counterfactual language:
|
|
6
|
+
* "Without unerr, this session would have cost $X.XX more"
|
|
7
|
+
* "Without unerr, the agent would have explored 15 files to find this"
|
|
8
|
+
*/
|
|
9
|
+
import { formatDollars } from "../proxy/model-pricing.js";
|
|
10
|
+
/**
|
|
11
|
+
* Frame a token savings as a counterfactual statement.
|
|
12
|
+
*/
|
|
13
|
+
export function frameTokenSavings(tokensSaved, dollarsSaved) {
|
|
14
|
+
if (tokensSaved <= 0)
|
|
15
|
+
return "";
|
|
16
|
+
const tokensStr = tokensSaved >= 1000
|
|
17
|
+
? `${(tokensSaved / 1000).toFixed(1)}K`
|
|
18
|
+
: String(tokensSaved);
|
|
19
|
+
return `Without unerr, ${tokensStr} additional tokens (${formatDollars(dollarsSaved)}) would have been consumed.`;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Frame a guard moment (prevented cost).
|
|
23
|
+
*/
|
|
24
|
+
export function frameGuardMoment(description, dollarsPrevented) {
|
|
25
|
+
return `[unerr] ⚠ Prevented: ${description}. Without unerr, est. cost: ${formatDollars(dollarsPrevented)}`;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Frame exploration savings.
|
|
29
|
+
*/
|
|
30
|
+
export function frameExplorationSaving(queryType, filesAvoided) {
|
|
31
|
+
return `Without unerr, the agent would have read ~${filesAvoided} files to get this information.`;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Frame session summary with counterfactual.
|
|
35
|
+
*/
|
|
36
|
+
export function frameSessionSummary(tokensSaved, dollarsSaved, guardsFirered) {
|
|
37
|
+
const parts = [];
|
|
38
|
+
if (tokensSaved > 0) {
|
|
39
|
+
const tokensStr = tokensSaved >= 1000
|
|
40
|
+
? `${(tokensSaved / 1000).toFixed(1)}K`
|
|
41
|
+
: String(tokensSaved);
|
|
42
|
+
parts.push(`${tokensStr} tokens saved (${formatDollars(dollarsSaved)})`);
|
|
43
|
+
}
|
|
44
|
+
if (guardsFirered > 0) {
|
|
45
|
+
parts.push(`${guardsFirered} issue(s) prevented`);
|
|
46
|
+
}
|
|
47
|
+
if (parts.length === 0) {
|
|
48
|
+
return "Graph intelligence active — monitoring for savings opportunities.";
|
|
49
|
+
}
|
|
50
|
+
return `Without unerr: ${parts.join(", ")} would have been wasted.`;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Frame a weekly trend delta.
|
|
54
|
+
*/
|
|
55
|
+
export function frameWeeklyTrend(thisWeekSaved, lastWeekSaved, dollarsSaved) {
|
|
56
|
+
const trend = thisWeekSaved > lastWeekSaved
|
|
57
|
+
? "↑"
|
|
58
|
+
: thisWeekSaved < lastWeekSaved
|
|
59
|
+
? "↓"
|
|
60
|
+
: "→";
|
|
61
|
+
const tokensStr = thisWeekSaved >= 1000
|
|
62
|
+
? `${(thisWeekSaved / 1000).toFixed(1)}K`
|
|
63
|
+
: String(thisWeekSaved);
|
|
64
|
+
return `This week: ${tokensStr} tokens saved (${formatDollars(dollarsSaved)}) ${trend}`;
|
|
65
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deep-link URL generation for bridging CLI → web dashboard.
|
|
3
|
+
*
|
|
4
|
+
* §0.7 Constraint #8: "Every terminal display must include a deep link."
|
|
5
|
+
* Used by: startup display, status command, health check, session summary.
|
|
6
|
+
*/
|
|
7
|
+
const BASE_URL = "https://app.unerr.dev";
|
|
8
|
+
/**
|
|
9
|
+
* Generate a context-aware deep link to the unerr web dashboard.
|
|
10
|
+
*
|
|
11
|
+
* @param repoId - Repository identifier (e.g. "repo_abc123"). If empty/undefined, returns generic landing.
|
|
12
|
+
* @param options - Query parameters for view targeting and analytics.
|
|
13
|
+
* @returns Full URL string with query parameters.
|
|
14
|
+
*/
|
|
15
|
+
export function buildDeepLink(repoId, options) {
|
|
16
|
+
if (!repoId) {
|
|
17
|
+
// Fallback: generic landing when repo context unavailable
|
|
18
|
+
const params = new URLSearchParams();
|
|
19
|
+
params.set("utm_source", options?.utm_source ?? "cli");
|
|
20
|
+
return `${BASE_URL}?${params.toString()}`;
|
|
21
|
+
}
|
|
22
|
+
const base = `${BASE_URL}/r/${repoId}`;
|
|
23
|
+
const params = new URLSearchParams();
|
|
24
|
+
if (options?.view)
|
|
25
|
+
params.set("view", options.view);
|
|
26
|
+
if (options?.branch)
|
|
27
|
+
params.set("branch", options.branch);
|
|
28
|
+
if (options?.entities?.length)
|
|
29
|
+
params.set("entities", options.entities.join(","));
|
|
30
|
+
if (options?.intents?.length)
|
|
31
|
+
params.set("intents", options.intents.join(","));
|
|
32
|
+
params.set("utm_source", options?.utm_source ?? "cli");
|
|
33
|
+
return `${base}?${params.toString()}`;
|
|
34
|
+
}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Smart detection utilities for git host and IDE type.
|
|
3
|
+
*/
|
|
4
|
+
import { existsSync } from "node:fs";
|
|
5
|
+
import { join } from "node:path";
|
|
6
|
+
import { exec } from "./exec.js";
|
|
7
|
+
import { getCurrentBranch, getRemoteUrl, isGitRepo as isGitRepoGit, } from "./git.js";
|
|
8
|
+
/**
|
|
9
|
+
* Classify a git remote URL into a known host or "other".
|
|
10
|
+
*/
|
|
11
|
+
export function classifyHost(remote) {
|
|
12
|
+
const lower = remote.toLowerCase();
|
|
13
|
+
if (lower.includes("github.com"))
|
|
14
|
+
return "github";
|
|
15
|
+
if (lower.includes("gitlab.com") || lower.includes("gitlab."))
|
|
16
|
+
return "gitlab";
|
|
17
|
+
if (lower.includes("bitbucket.org") || lower.includes("bitbucket."))
|
|
18
|
+
return "bitbucket";
|
|
19
|
+
return "other";
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Parse a remote URL into owner/repo format.
|
|
23
|
+
*/
|
|
24
|
+
function parseRemote(remote) {
|
|
25
|
+
// git@github.com:owner/repo.git
|
|
26
|
+
const sshMatch = remote.match(/git@[^:]+:(.+?)(?:\.git)?$/);
|
|
27
|
+
if (sshMatch)
|
|
28
|
+
return sshMatch[1] ?? null;
|
|
29
|
+
// https://github.com/owner/repo.git
|
|
30
|
+
const httpMatch = remote.match(/(?:https?:\/\/)?(?:www\.)?[^/]+\/(.+?)(?:\.git)?$/);
|
|
31
|
+
if (httpMatch)
|
|
32
|
+
return httpMatch[1] ?? null;
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Detect full git context from the current working directory.
|
|
37
|
+
*/
|
|
38
|
+
export async function detectGitContext(cwd) {
|
|
39
|
+
try {
|
|
40
|
+
const dir = cwd ?? process.cwd();
|
|
41
|
+
const remote = await getRemoteUrl(dir);
|
|
42
|
+
if (!remote)
|
|
43
|
+
return null;
|
|
44
|
+
const branch = (await getCurrentBranch(dir)) || "main";
|
|
45
|
+
const fullName = parseRemote(remote);
|
|
46
|
+
if (!fullName)
|
|
47
|
+
return null;
|
|
48
|
+
const parts = fullName.split("/");
|
|
49
|
+
if (parts.length < 2)
|
|
50
|
+
return null;
|
|
51
|
+
return {
|
|
52
|
+
remote,
|
|
53
|
+
branch,
|
|
54
|
+
owner: parts[0] ?? "",
|
|
55
|
+
repo: parts[1] ?? "",
|
|
56
|
+
fullName,
|
|
57
|
+
host: classifyHost(remote),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Check if the current directory is inside a git repository.
|
|
66
|
+
*/
|
|
67
|
+
export async function isGitRepo(cwd) {
|
|
68
|
+
return isGitRepoGit(cwd ?? process.cwd());
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Auto-detect the IDE from project directory and environment.
|
|
72
|
+
*
|
|
73
|
+
* Checks in order:
|
|
74
|
+
* 1. CURSOR_TRACE_ID env → Cursor terminal
|
|
75
|
+
* 2. TERM_PROGRAM=vscode + cursor extensions path → Cursor
|
|
76
|
+
* 3. CLAUDE_CODE env or "claude" process ancestry → Claude Code
|
|
77
|
+
* 4. .cursor/ directory in project → Cursor
|
|
78
|
+
* 5. .windsurf/ directory in project → Windsurf
|
|
79
|
+
* 6. TERM_PROGRAM=vscode → VS Code
|
|
80
|
+
* 7. .vscode/ directory in project → VS Code
|
|
81
|
+
* 8. "unknown" → will be prompted
|
|
82
|
+
*/
|
|
83
|
+
export async function detectIde(cwd) {
|
|
84
|
+
// Cursor sets CURSOR_TRACE_ID in its integrated terminal
|
|
85
|
+
if (process.env.CURSOR_TRACE_ID)
|
|
86
|
+
return "cursor";
|
|
87
|
+
// Claude Code sets CLAUDE_CODE or similar markers
|
|
88
|
+
if (process.env.CLAUDE_CODE === "1" || process.env.CLAUDE_CODE === "true")
|
|
89
|
+
return "claude-code";
|
|
90
|
+
// Check TERM_PROGRAM for VS Code-based editors
|
|
91
|
+
const termProgram = process.env.TERM_PROGRAM ?? "";
|
|
92
|
+
if (termProgram === "vscode") {
|
|
93
|
+
// Could be Cursor (fork of VS Code) — check for Cursor-specific paths
|
|
94
|
+
const cursorExtensions = process.env.VSCODE_CWD ?? "";
|
|
95
|
+
if (cursorExtensions.toLowerCase().includes("cursor"))
|
|
96
|
+
return "cursor";
|
|
97
|
+
}
|
|
98
|
+
// Check for Claude Code in process ancestry
|
|
99
|
+
try {
|
|
100
|
+
const ppid = process.ppid;
|
|
101
|
+
if (ppid) {
|
|
102
|
+
const result = await exec("ps", ["-o", "comm=", "-p", String(ppid)]);
|
|
103
|
+
if (result.exitCode === 0 && result.stdout.includes("claude"))
|
|
104
|
+
return "claude-code";
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
// Ignore — process inspection may not be available
|
|
109
|
+
}
|
|
110
|
+
// Directory-based detection
|
|
111
|
+
if (existsSync(join(cwd, ".cursor")))
|
|
112
|
+
return "cursor";
|
|
113
|
+
if (existsSync(join(cwd, ".windsurf")))
|
|
114
|
+
return "windsurf";
|
|
115
|
+
if (termProgram === "vscode")
|
|
116
|
+
return "vscode";
|
|
117
|
+
if (existsSync(join(cwd, ".vscode")))
|
|
118
|
+
return "vscode";
|
|
119
|
+
// Zed: checks for .zed/ directory or ZED_TERM env
|
|
120
|
+
if (process.env.ZED_TERM === "true" || existsSync(join(cwd, ".zed")))
|
|
121
|
+
return "zed";
|
|
122
|
+
// Antigravity: checks for env vars or .antigravity/ directory
|
|
123
|
+
if (process.env.ANTIGRAVITY_PROJECT_DIR || process.env.ANTIGRAVITY_VERSION)
|
|
124
|
+
return "antigravity";
|
|
125
|
+
if (existsSync(join(cwd, ".antigravity")))
|
|
126
|
+
return "antigravity";
|
|
127
|
+
return "unknown";
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Human-readable IDE name for display.
|
|
131
|
+
*/
|
|
132
|
+
export function ideDisplayName(ide) {
|
|
133
|
+
switch (ide) {
|
|
134
|
+
case "cursor":
|
|
135
|
+
return "Cursor";
|
|
136
|
+
case "claude-code":
|
|
137
|
+
return "Claude Code";
|
|
138
|
+
case "vscode":
|
|
139
|
+
return "VS Code";
|
|
140
|
+
case "windsurf":
|
|
141
|
+
return "Windsurf";
|
|
142
|
+
case "zed":
|
|
143
|
+
return "Zed";
|
|
144
|
+
case "cline":
|
|
145
|
+
return "Cline";
|
|
146
|
+
case "kiro":
|
|
147
|
+
return "Kiro";
|
|
148
|
+
case "gemini-cli":
|
|
149
|
+
return "Gemini CLI";
|
|
150
|
+
case "codex":
|
|
151
|
+
return "Codex";
|
|
152
|
+
case "aider":
|
|
153
|
+
return "Aider";
|
|
154
|
+
case "opencode":
|
|
155
|
+
return "OpenCode";
|
|
156
|
+
case "trae":
|
|
157
|
+
return "Trae";
|
|
158
|
+
case "augment":
|
|
159
|
+
return "Augment";
|
|
160
|
+
case "github-copilot-cli":
|
|
161
|
+
return "GitHub Copilot CLI";
|
|
162
|
+
case "continue":
|
|
163
|
+
return "Continue";
|
|
164
|
+
case "antigravity":
|
|
165
|
+
return "Google Antigravity";
|
|
166
|
+
case "other":
|
|
167
|
+
return "Other";
|
|
168
|
+
case "unknown":
|
|
169
|
+
return "your IDE";
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* All IDE choices for interactive prompt.
|
|
174
|
+
*/
|
|
175
|
+
export const IDE_CHOICES = [
|
|
176
|
+
{ title: "Cursor", value: "cursor" },
|
|
177
|
+
{ title: "Claude Code", value: "claude-code" },
|
|
178
|
+
{ title: "VS Code / Copilot", value: "vscode" },
|
|
179
|
+
{ title: "Windsurf", value: "windsurf" },
|
|
180
|
+
{ title: "Zed", value: "zed" },
|
|
181
|
+
{ title: "Cline", value: "cline" },
|
|
182
|
+
{ title: "Kiro", value: "kiro" },
|
|
183
|
+
{ title: "Gemini CLI", value: "gemini-cli" },
|
|
184
|
+
{ title: "Codex (OpenAI)", value: "codex" },
|
|
185
|
+
{ title: "Aider", value: "aider" },
|
|
186
|
+
{ title: "OpenCode", value: "opencode" },
|
|
187
|
+
{ title: "Trae", value: "trae" },
|
|
188
|
+
{ title: "Augment", value: "augment" },
|
|
189
|
+
{ title: "GitHub Copilot CLI", value: "github-copilot-cli" },
|
|
190
|
+
{ title: "Continue", value: "continue" },
|
|
191
|
+
{ title: "Google Antigravity", value: "antigravity" },
|
|
192
|
+
{ title: "Other (manual MCP setup)", value: "other" },
|
|
193
|
+
];
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shell Execution Utility — tinyexec-based async command runner.
|
|
3
|
+
*
|
|
4
|
+
* Replaces all raw child_process.execSync / exec usage in the codebase.
|
|
5
|
+
* Provides type-safe, async, argument-array-based execution (no shell injection).
|
|
6
|
+
*
|
|
7
|
+
* For git operations specifically, prefer the higher-level helpers in git.ts
|
|
8
|
+
* which wrap simple-git. This module is for arbitrary shell commands and
|
|
9
|
+
* low-level git plumbing where simple-git's API doesn't reach.
|
|
10
|
+
*/
|
|
11
|
+
import { x } from "tinyexec";
|
|
12
|
+
/**
|
|
13
|
+
* Execute a command with args (no shell interpolation — safe by construction).
|
|
14
|
+
* Returns structured result. Throws only if throwOnError is true and exit code != 0.
|
|
15
|
+
*/
|
|
16
|
+
export async function exec(command, args = [], options = {}) {
|
|
17
|
+
const result = await x(command, args, {
|
|
18
|
+
nodeOptions: {
|
|
19
|
+
cwd: options.cwd,
|
|
20
|
+
timeout: options.timeout,
|
|
21
|
+
},
|
|
22
|
+
throwOnError: false,
|
|
23
|
+
});
|
|
24
|
+
const execResult = {
|
|
25
|
+
stdout: result.stdout.trim(),
|
|
26
|
+
stderr: result.stderr.trim(),
|
|
27
|
+
exitCode: result.exitCode ?? 0,
|
|
28
|
+
};
|
|
29
|
+
if (options.throwOnError && execResult.exitCode !== 0) {
|
|
30
|
+
const msg = execResult.stderr ||
|
|
31
|
+
execResult.stdout ||
|
|
32
|
+
`Command failed: ${command} ${args.join(" ")}`;
|
|
33
|
+
throw new Error(msg);
|
|
34
|
+
}
|
|
35
|
+
return execResult;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Execute a git command. Convenience wrapper that prefixes args with the git subcommand.
|
|
39
|
+
*
|
|
40
|
+
* Example: gitExec(["rev-parse", "--is-inside-work-tree"], { cwd })
|
|
41
|
+
*/
|
|
42
|
+
export async function gitExec(args, options = {}) {
|
|
43
|
+
return exec("git", args, options);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Quick git query — returns stdout as trimmed string.
|
|
47
|
+
* Returns null on non-zero exit code instead of throwing.
|
|
48
|
+
*/
|
|
49
|
+
export async function gitQuery(args, cwd) {
|
|
50
|
+
const result = await gitExec(args, { cwd });
|
|
51
|
+
return result.exitCode === 0 ? result.stdout : null;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Open a `http(s):` URL in the system default browser (no shell interpolation).
|
|
55
|
+
* Localhost-only dashboard links use this from `unerr dashboard`.
|
|
56
|
+
*/
|
|
57
|
+
export async function openUrlInDefaultBrowser(url) {
|
|
58
|
+
if (!/^https?:\/\//i.test(url)) {
|
|
59
|
+
throw new Error("openUrlInDefaultBrowser: only http(s) URLs are allowed");
|
|
60
|
+
}
|
|
61
|
+
const platform = process.platform;
|
|
62
|
+
if (platform === "darwin") {
|
|
63
|
+
await exec("open", [url], { throwOnError: true });
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
if (platform === "win32") {
|
|
67
|
+
await exec("rundll32", ["url.dll,FileProtocolHandler", url], {
|
|
68
|
+
throwOnError: true,
|
|
69
|
+
});
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
await exec("xdg-open", [url], { throwOnError: true });
|
|
73
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Layer 12 / DM-0: rotating stderr → file mirror.
|
|
3
|
+
*
|
|
4
|
+
* Tees every `process.stderr.write` call to a `.log` file on disk so the
|
|
5
|
+
* three Layer-12 processes (`unerrd`, `unerr`, `unerr --mcp`) still produce
|
|
6
|
+
* inspectable output when they leave the foreground (auto-spawn from DM-3,
|
|
7
|
+
* stdio-only IDE bridge, etc.).
|
|
8
|
+
*
|
|
9
|
+
* Rotation: when the current file passes `maxBytes`, rename `*.log` →
|
|
10
|
+
* `*.log.1` (shift the rest), keep the last `keep` files, drop the oldest.
|
|
11
|
+
*
|
|
12
|
+
* Independent of `startupLog`: that tool writes structured JSONL events
|
|
13
|
+
* (`unerr.jsonl`); this one mirrors the raw stderr byte stream (`*.log`).
|
|
14
|
+
*/
|
|
15
|
+
import { appendFileSync, existsSync, mkdirSync, renameSync, statSync, unlinkSync, } from "node:fs";
|
|
16
|
+
import { dirname } from "node:path";
|
|
17
|
+
// biome-ignore lint/suspicious/noControlCharactersInRegex: ANSI escape codes are control characters by definition.
|
|
18
|
+
const ANSI_RE = /\x1b\[[0-9;?]*[A-Za-z~]|\x1b\][^\x07]*\x07/g;
|
|
19
|
+
function stripAnsi(s) {
|
|
20
|
+
return s.replace(ANSI_RE, "");
|
|
21
|
+
}
|
|
22
|
+
function rotate(filePath, keep) {
|
|
23
|
+
for (let i = keep; i >= 1; i--) {
|
|
24
|
+
const cur = i === 1 ? filePath : `${filePath}.${i - 1}`;
|
|
25
|
+
const next = `${filePath}.${i}`;
|
|
26
|
+
if (!existsSync(cur))
|
|
27
|
+
continue;
|
|
28
|
+
if (i === keep && existsSync(next)) {
|
|
29
|
+
try {
|
|
30
|
+
unlinkSync(next);
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
/* best effort */
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
try {
|
|
37
|
+
renameSync(cur, next);
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
/* best effort */
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Mirror `process.stderr.write` to `filePath` with ANSI codes stripped.
|
|
46
|
+
* Returns an uninstaller that restores the original `stderr.write`.
|
|
47
|
+
*
|
|
48
|
+
* Side effects: ensures `dirname(filePath)` exists, opens the file in append
|
|
49
|
+
* mode, never closes it (process lifetime). Terminal stderr is unchanged —
|
|
50
|
+
* the original colored bytes still reach the TTY.
|
|
51
|
+
*/
|
|
52
|
+
export function installFileLogger(opts) {
|
|
53
|
+
const { filePath, maxBytes = 5_000_000, keep = 5 } = opts;
|
|
54
|
+
mkdirSync(dirname(filePath), { recursive: true });
|
|
55
|
+
let bytesWritten = 0;
|
|
56
|
+
try {
|
|
57
|
+
bytesWritten = statSync(filePath).size;
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
/* file doesn't exist yet */
|
|
61
|
+
}
|
|
62
|
+
const original = process.stderr.write;
|
|
63
|
+
const bound = original.bind(process.stderr);
|
|
64
|
+
const wrapped = ((chunk, ...rest) => {
|
|
65
|
+
const result = bound(chunk, ...rest);
|
|
66
|
+
try {
|
|
67
|
+
const text = typeof chunk === "string"
|
|
68
|
+
? chunk
|
|
69
|
+
: Buffer.from(chunk).toString("utf-8");
|
|
70
|
+
const clean = stripAnsi(text);
|
|
71
|
+
appendFileSync(filePath, clean);
|
|
72
|
+
bytesWritten += clean.length;
|
|
73
|
+
if (bytesWritten >= maxBytes) {
|
|
74
|
+
rotate(filePath, keep);
|
|
75
|
+
bytesWritten = 0;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
/* file logging is best-effort — never block stderr */
|
|
80
|
+
}
|
|
81
|
+
return result;
|
|
82
|
+
});
|
|
83
|
+
process.stderr.write = wrapped;
|
|
84
|
+
return () => {
|
|
85
|
+
process.stderr.write = original;
|
|
86
|
+
};
|
|
87
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Serialize an unknown caught value into a stable, human-readable string.
|
|
3
|
+
*
|
|
4
|
+
* Why: `String(obj)` returns `"[object Object]"` for plain objects (e.g.,
|
|
5
|
+
* cozo-node driver errors that aren't Error instances), which is useless in
|
|
6
|
+
* logs. `JSON.stringify(obj)` returns `"{}"` when an object's properties
|
|
7
|
+
* are non-enumerable. This helper handles all three shapes deterministically.
|
|
8
|
+
*/
|
|
9
|
+
export function formatUnknownError(err) {
|
|
10
|
+
if (err instanceof Error)
|
|
11
|
+
return err.stack ?? err.message;
|
|
12
|
+
if (typeof err === "object" && err !== null) {
|
|
13
|
+
const obj = err;
|
|
14
|
+
if (typeof obj.display === "string")
|
|
15
|
+
return obj.display;
|
|
16
|
+
if (typeof obj.message === "string")
|
|
17
|
+
return obj.message;
|
|
18
|
+
try {
|
|
19
|
+
const serialized = JSON.stringify(err, Object.getOwnPropertyNames(err));
|
|
20
|
+
if (serialized && serialized !== "{}")
|
|
21
|
+
return serialized;
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
// fall through
|
|
25
|
+
}
|
|
26
|
+
return Object.prototype.toString.call(err);
|
|
27
|
+
}
|
|
28
|
+
return String(err);
|
|
29
|
+
}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Centralized Git Utility — simple-git based.
|
|
3
|
+
*
|
|
4
|
+
* Provides a single factory for creating git instances and typed helpers
|
|
5
|
+
* for common operations used throughout the codebase.
|
|
6
|
+
*
|
|
7
|
+
* Design notes (temporal intelligence foundation):
|
|
8
|
+
* - Git log queries return structured data for bi-temporal edge construction.
|
|
9
|
+
* - Blame/history helpers enable "when did this fact become true?" queries.
|
|
10
|
+
* - Instance caching avoids re-initialization overhead on hot paths.
|
|
11
|
+
*/
|
|
12
|
+
import { simpleGit } from "simple-git";
|
|
13
|
+
const instanceCache = new Map();
|
|
14
|
+
/**
|
|
15
|
+
* Get a simple-git instance for a working directory.
|
|
16
|
+
* Instances are cached per cwd to avoid repeated initialization.
|
|
17
|
+
*/
|
|
18
|
+
export function getGit(cwd) {
|
|
19
|
+
const cached = instanceCache.get(cwd);
|
|
20
|
+
if (cached)
|
|
21
|
+
return cached;
|
|
22
|
+
const opts = {
|
|
23
|
+
baseDir: cwd,
|
|
24
|
+
binary: "git",
|
|
25
|
+
maxConcurrentProcesses: 6,
|
|
26
|
+
trimmed: true,
|
|
27
|
+
};
|
|
28
|
+
const instance = simpleGit(opts);
|
|
29
|
+
instanceCache.set(cwd, instance);
|
|
30
|
+
return instance;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Clear the instance cache (for testing or after cwd changes).
|
|
34
|
+
*/
|
|
35
|
+
export function clearGitCache() {
|
|
36
|
+
instanceCache.clear();
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Check if a directory is inside a git work tree.
|
|
40
|
+
*/
|
|
41
|
+
export async function isGitRepo(cwd) {
|
|
42
|
+
try {
|
|
43
|
+
const git = getGit(cwd);
|
|
44
|
+
await git.revparse(["--is-inside-work-tree"]);
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Get the current HEAD commit SHA.
|
|
53
|
+
*/
|
|
54
|
+
export async function getHeadSha(cwd) {
|
|
55
|
+
try {
|
|
56
|
+
const git = getGit(cwd);
|
|
57
|
+
return await git.revparse(["HEAD"]);
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Get the current branch name.
|
|
65
|
+
*/
|
|
66
|
+
export async function getCurrentBranch(cwd) {
|
|
67
|
+
try {
|
|
68
|
+
const git = getGit(cwd);
|
|
69
|
+
return await git.revparse(["--abbrev-ref", "HEAD"]);
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Get the remote origin URL.
|
|
77
|
+
*/
|
|
78
|
+
export async function getRemoteUrl(cwd) {
|
|
79
|
+
try {
|
|
80
|
+
const git = getGit(cwd);
|
|
81
|
+
const remotes = await git.getRemotes(true);
|
|
82
|
+
const origin = remotes.find((r) => r.name === "origin");
|
|
83
|
+
return origin?.refs.fetch ?? null;
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Get files changed between two refs.
|
|
91
|
+
*/
|
|
92
|
+
export async function getChangedFiles(cwd, fromRef, toRef) {
|
|
93
|
+
try {
|
|
94
|
+
const git = getGit(cwd);
|
|
95
|
+
const diff = await git.diff(["--name-only", `${fromRef}..${toRef}`]);
|
|
96
|
+
return diff
|
|
97
|
+
.split("\n")
|
|
98
|
+
.map((f) => f.trim())
|
|
99
|
+
.filter(Boolean);
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
return [];
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Restore a file to a specific ref's version.
|
|
107
|
+
*/
|
|
108
|
+
export async function checkoutFile(cwd, ref, filePath) {
|
|
109
|
+
const git = getGit(cwd);
|
|
110
|
+
await git.checkout([ref, "--", filePath]);
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Get staged file names (for pre-commit hooks).
|
|
114
|
+
*/
|
|
115
|
+
export async function getStagedFiles(cwd) {
|
|
116
|
+
try {
|
|
117
|
+
const git = getGit(cwd);
|
|
118
|
+
const diff = await git.diff([
|
|
119
|
+
"--cached",
|
|
120
|
+
"--name-only",
|
|
121
|
+
"--diff-filter=ACMR",
|
|
122
|
+
]);
|
|
123
|
+
return diff
|
|
124
|
+
.split("\n")
|
|
125
|
+
.map((f) => f.trim())
|
|
126
|
+
.filter(Boolean);
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
return [];
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Get recent commit log entries.
|
|
134
|
+
*/
|
|
135
|
+
export async function getLog(cwd, maxCount = 5) {
|
|
136
|
+
try {
|
|
137
|
+
const git = getGit(cwd);
|
|
138
|
+
const log = await git.log({ maxCount });
|
|
139
|
+
return log.all.map((entry) => ({
|
|
140
|
+
hash: entry.hash,
|
|
141
|
+
date: entry.date,
|
|
142
|
+
message: entry.message,
|
|
143
|
+
author_name: entry.author_name,
|
|
144
|
+
}));
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
return [];
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* List local branches.
|
|
152
|
+
*/
|
|
153
|
+
export async function listBranches(cwd) {
|
|
154
|
+
try {
|
|
155
|
+
const git = getGit(cwd);
|
|
156
|
+
const summary = await git.branchLocal();
|
|
157
|
+
return summary.all;
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
return [];
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Write a git note under a custom ref namespace.
|
|
165
|
+
*/
|
|
166
|
+
export async function writeNote(cwd, ref, commitSha, content) {
|
|
167
|
+
const git = getGit(cwd);
|
|
168
|
+
await git.raw(["notes", "--ref", ref, "add", "-f", "-m", content, commitSha]);
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Read a git note from a custom ref namespace. Returns null if no note exists.
|
|
172
|
+
*/
|
|
173
|
+
export async function readNote(cwd, ref, commitSha) {
|
|
174
|
+
try {
|
|
175
|
+
const git = getGit(cwd);
|
|
176
|
+
return await git.raw(["notes", "--ref", ref, "show", commitSha]);
|
|
177
|
+
}
|
|
178
|
+
catch {
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
}
|