@unerr-ai/unerr 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/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 +996 -710
- 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 +312 -0
- package/dist/ui/assets/index-B-0HTtUR.js +0 -10
package/dist/cli.js
CHANGED
|
@@ -2187,7 +2187,7 @@ var init_local_graph = __esm({
|
|
|
2187
2187
|
{ key: entityKey2 }
|
|
2188
2188
|
);
|
|
2189
2189
|
if (fileResult.rows.length === 0) return [];
|
|
2190
|
-
const filePath = fileResult.rows[0][0];
|
|
2190
|
+
const filePath = fileResult.rows[0]?.[0];
|
|
2191
2191
|
const siblingsResult = await this.query(
|
|
2192
2192
|
`?[key, name, fp] := *edges{from_key: $fileKey, to_key: key, type: "contains"}, *entities{key, name, file_path: fp}, key != $entityKey`,
|
|
2193
2193
|
{ fileKey: `file:${filePath}`, entityKey: entityKey2 }
|
|
@@ -2222,11 +2222,11 @@ var init_local_graph = __esm({
|
|
|
2222
2222
|
async getFileNeighbors(filePath) {
|
|
2223
2223
|
const fileKey = `file:${filePath}`;
|
|
2224
2224
|
const outResult = await this.query(
|
|
2225
|
-
|
|
2225
|
+
"?[to_key, type] := *edges{from_key: $fk, to_key, type}, to_key != $fk",
|
|
2226
2226
|
{ fk: fileKey }
|
|
2227
2227
|
);
|
|
2228
2228
|
const inResult = await this.query(
|
|
2229
|
-
|
|
2229
|
+
"?[from_key, type] := *edges{from_key, to_key: $fk, type}, from_key != $fk",
|
|
2230
2230
|
{ fk: fileKey }
|
|
2231
2231
|
);
|
|
2232
2232
|
const outbound = [];
|
|
@@ -2422,6 +2422,82 @@ var init_local_graph = __esm({
|
|
|
2422
2422
|
scored.sort((a, b) => b.surprise_score - a.surprise_score);
|
|
2423
2423
|
return scored.slice(0, topN);
|
|
2424
2424
|
}
|
|
2425
|
+
/**
|
|
2426
|
+
* Get cross-boundary links for a specific pair of directory prefixes.
|
|
2427
|
+
*
|
|
2428
|
+
* Unlike getCrossBoundaryLinks (which fetches ALL cross-community edges and
|
|
2429
|
+
* post-filters), this runs a targeted Datalog query with starts_with so it
|
|
2430
|
+
* always finds relevant edges regardless of how many total cross-community
|
|
2431
|
+
* edges exist in the project. Used when both from_path and to_path are
|
|
2432
|
+
* provided to get_cross_boundary_links.
|
|
2433
|
+
*
|
|
2434
|
+
* NOTE: Entity community IDs are hierarchical (macroCid * 1000 + subId).
|
|
2435
|
+
* The `communities` table only stores macro IDs. This method avoids the
|
|
2436
|
+
* table join and resolves labels by looking up macroId = floor(id / 1000).
|
|
2437
|
+
*/
|
|
2438
|
+
async getCrossPathLinks(fromPrefix, toPrefix, topN) {
|
|
2439
|
+
const fp = fromPrefix.endsWith("/") ? fromPrefix : `${fromPrefix}/`;
|
|
2440
|
+
const tp = toPrefix.endsWith("/") ? toPrefix : `${toPrefix}/`;
|
|
2441
|
+
const mkQuery = (a, b) => `?[fn, ff, fc, tn, tf, tc, et] :=
|
|
2442
|
+
*edges{from_key: fk, to_key: tk, type: et},
|
|
2443
|
+
*entities{key: fk, name: fn, file_path: ff, community: fc},
|
|
2444
|
+
*entities{key: tk, name: tn, file_path: tf, community: tc},
|
|
2445
|
+
starts_with(ff, $a), starts_with(tf, $b),
|
|
2446
|
+
fc >= 0, tc >= 0
|
|
2447
|
+
:limit $n`;
|
|
2448
|
+
const [fwdRes, revRes] = await Promise.all([
|
|
2449
|
+
this.query(mkQuery(fp, tp), { a: fp, b: tp, n: topN }).catch(() => ({
|
|
2450
|
+
rows: []
|
|
2451
|
+
})),
|
|
2452
|
+
this.query(mkQuery(tp, fp), { a: tp, b: fp, n: topN }).catch(() => ({
|
|
2453
|
+
rows: []
|
|
2454
|
+
}))
|
|
2455
|
+
]);
|
|
2456
|
+
const macroIds = /* @__PURE__ */ new Set();
|
|
2457
|
+
for (const rows of [fwdRes.rows, revRes.rows]) {
|
|
2458
|
+
for (const row of rows) {
|
|
2459
|
+
macroIds.add(Math.floor(row[2] / 1e3));
|
|
2460
|
+
macroIds.add(Math.floor(row[5] / 1e3));
|
|
2461
|
+
}
|
|
2462
|
+
}
|
|
2463
|
+
const labelMap = /* @__PURE__ */ new Map();
|
|
2464
|
+
if (macroIds.size > 0) {
|
|
2465
|
+
const ids = [...macroIds];
|
|
2466
|
+
try {
|
|
2467
|
+
const labelRes = await this.query(
|
|
2468
|
+
`?[id, label] := *communities{id, label}, id in $ids`,
|
|
2469
|
+
{ ids }
|
|
2470
|
+
);
|
|
2471
|
+
for (const row of labelRes.rows) {
|
|
2472
|
+
labelMap.set(row[0], row[1]);
|
|
2473
|
+
}
|
|
2474
|
+
} catch {
|
|
2475
|
+
}
|
|
2476
|
+
}
|
|
2477
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2478
|
+
const results = [];
|
|
2479
|
+
for (const row of [...fwdRes.rows, ...revRes.rows]) {
|
|
2480
|
+
const fc = row[2];
|
|
2481
|
+
const tc = row[5];
|
|
2482
|
+
const key = `${row[0]}:${row[3]}:${row[6]}`;
|
|
2483
|
+
if (seen.has(key)) continue;
|
|
2484
|
+
seen.add(key);
|
|
2485
|
+
results.push({
|
|
2486
|
+
from_name: row[0],
|
|
2487
|
+
from_file: row[1],
|
|
2488
|
+
from_community: fc,
|
|
2489
|
+
from_community_label: labelMap.get(Math.floor(fc / 1e3)) ?? String(Math.floor(fc / 1e3)),
|
|
2490
|
+
to_name: row[3],
|
|
2491
|
+
to_file: row[4],
|
|
2492
|
+
to_community: tc,
|
|
2493
|
+
to_community_label: labelMap.get(Math.floor(tc / 1e3)) ?? String(Math.floor(tc / 1e3)),
|
|
2494
|
+
edge_type: row[6],
|
|
2495
|
+
surprise_score: 1
|
|
2496
|
+
// all edges here cross an explicit path boundary
|
|
2497
|
+
});
|
|
2498
|
+
}
|
|
2499
|
+
return results.slice(0, topN);
|
|
2500
|
+
}
|
|
2425
2501
|
/**
|
|
2426
2502
|
* Get critical nodes — highest degree entities excluding file-level hubs.
|
|
2427
2503
|
* Degree ranking excluding kind=="file" and kind=="module".
|
|
@@ -5252,11 +5328,13 @@ import { execSync } from "child_process";
|
|
|
5252
5328
|
import {
|
|
5253
5329
|
existsSync as existsSync10,
|
|
5254
5330
|
mkdirSync as mkdirSync5,
|
|
5331
|
+
readFileSync as readFileSync9,
|
|
5332
|
+
realpathSync,
|
|
5255
5333
|
unlinkSync,
|
|
5256
5334
|
writeFileSync as writeFileSync4
|
|
5257
5335
|
} from "fs";
|
|
5258
5336
|
import { homedir as homedir4 } from "os";
|
|
5259
|
-
import { join as join10 } from "path";
|
|
5337
|
+
import { dirname as dirname5, join as join10, resolve as resolve2 } from "path";
|
|
5260
5338
|
function plistDir() {
|
|
5261
5339
|
return join10(homedir4(), "Library", "LaunchAgents");
|
|
5262
5340
|
}
|
|
@@ -5266,15 +5344,41 @@ function plistPath() {
|
|
|
5266
5344
|
function logPath() {
|
|
5267
5345
|
return join10(homedir4(), ".unerr", "logs", "unerrd.boot.log");
|
|
5268
5346
|
}
|
|
5269
|
-
function
|
|
5347
|
+
function resolveNodeBin() {
|
|
5348
|
+
try {
|
|
5349
|
+
return realpathSync(process.execPath);
|
|
5350
|
+
} catch {
|
|
5351
|
+
return process.execPath;
|
|
5352
|
+
}
|
|
5353
|
+
}
|
|
5354
|
+
function resolveCliEntry() {
|
|
5355
|
+
if (process.argv[1]) {
|
|
5356
|
+
const resolved = resolve2(process.argv[1]);
|
|
5357
|
+
if (existsSync10(resolved)) return resolved;
|
|
5358
|
+
}
|
|
5270
5359
|
try {
|
|
5271
|
-
|
|
5360
|
+
const shimPath = execSync("which unerr", { encoding: "utf-8" }).trim();
|
|
5361
|
+
if (shimPath && existsSync10(shimPath)) {
|
|
5362
|
+
const shimContent = readFileSync9(shimPath, "utf-8");
|
|
5363
|
+
const jsMatch = /"\$basedir\/((?:\.\.\/)*[^"]+\.js)"/m.exec(shimContent);
|
|
5364
|
+
if (jsMatch?.[1]) {
|
|
5365
|
+
const basedir = dirname5(shimPath);
|
|
5366
|
+
const abs = resolve2(basedir, jsMatch[1]);
|
|
5367
|
+
if (existsSync10(abs)) return abs;
|
|
5368
|
+
}
|
|
5369
|
+
}
|
|
5272
5370
|
} catch {
|
|
5273
|
-
return join10(process.argv[1] || "unerr");
|
|
5274
5371
|
}
|
|
5372
|
+
const fallbackBase = process.argv[1] ? dirname5(resolve2(process.argv[1])) : process.cwd();
|
|
5373
|
+
return join10(fallbackBase, "cli.js");
|
|
5374
|
+
}
|
|
5375
|
+
function xmlEscape(s) {
|
|
5376
|
+
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
5275
5377
|
}
|
|
5276
|
-
function generatePlist(
|
|
5378
|
+
function generatePlist(nodeBin, cliEntry) {
|
|
5277
5379
|
const log24 = logPath();
|
|
5380
|
+
const nodeBinDir = dirname5(nodeBin);
|
|
5381
|
+
const e = xmlEscape;
|
|
5278
5382
|
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
5279
5383
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
5280
5384
|
<plist version="1.0">
|
|
@@ -5283,11 +5387,17 @@ function generatePlist(bin) {
|
|
|
5283
5387
|
<string>com.unerr.daemon</string>
|
|
5284
5388
|
<key>ProgramArguments</key>
|
|
5285
5389
|
<array>
|
|
5286
|
-
<string>${
|
|
5390
|
+
<string>${e(nodeBin)}</string>
|
|
5391
|
+
<string>${e(cliEntry)}</string>
|
|
5287
5392
|
<string>daemon</string>
|
|
5288
5393
|
<string>start</string>
|
|
5289
5394
|
<string>--foreground</string>
|
|
5290
5395
|
</array>
|
|
5396
|
+
<key>EnvironmentVariables</key>
|
|
5397
|
+
<dict>
|
|
5398
|
+
<key>PATH</key>
|
|
5399
|
+
<string>${e(nodeBinDir)}:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
|
|
5400
|
+
</dict>
|
|
5291
5401
|
<key>RunAtLoad</key>
|
|
5292
5402
|
<true/>
|
|
5293
5403
|
<key>KeepAlive</key>
|
|
@@ -5295,10 +5405,12 @@ function generatePlist(bin) {
|
|
|
5295
5405
|
<key>SuccessfulExit</key>
|
|
5296
5406
|
<false/>
|
|
5297
5407
|
</dict>
|
|
5408
|
+
<key>ThrottleInterval</key>
|
|
5409
|
+
<integer>30</integer>
|
|
5298
5410
|
<key>StandardOutPath</key>
|
|
5299
|
-
<string>${log24}</string>
|
|
5411
|
+
<string>${e(log24)}</string>
|
|
5300
5412
|
<key>StandardErrorPath</key>
|
|
5301
|
-
<string>${log24}</string>
|
|
5413
|
+
<string>${e(log24)}</string>
|
|
5302
5414
|
<key>ProcessType</key>
|
|
5303
5415
|
<string>Background</string>
|
|
5304
5416
|
<key>LowPriorityBackgroundIO</key>
|
|
@@ -5309,12 +5421,13 @@ function generatePlist(bin) {
|
|
|
5309
5421
|
function installLaunchd() {
|
|
5310
5422
|
const dir = plistDir();
|
|
5311
5423
|
const path7 = plistPath();
|
|
5312
|
-
const
|
|
5424
|
+
const nodeBin = resolveNodeBin();
|
|
5425
|
+
const cliEntry = resolveCliEntry();
|
|
5313
5426
|
try {
|
|
5314
5427
|
mkdirSync5(dir, { recursive: true });
|
|
5315
5428
|
const logDir = join10(homedir4(), ".unerr", "logs");
|
|
5316
5429
|
mkdirSync5(logDir, { recursive: true });
|
|
5317
|
-
const plist = generatePlist(
|
|
5430
|
+
const plist = generatePlist(nodeBin, cliEntry);
|
|
5318
5431
|
writeFileSync4(path7, plist, "utf-8");
|
|
5319
5432
|
const uid = process.getuid?.() ?? execSync("id -u", { encoding: "utf-8" }).trim();
|
|
5320
5433
|
try {
|
|
@@ -5395,24 +5508,46 @@ import {
|
|
|
5395
5508
|
existsSync as existsSync11,
|
|
5396
5509
|
mkdirSync as mkdirSync6,
|
|
5397
5510
|
readFileSync as readFileSync10,
|
|
5511
|
+
realpathSync as realpathSync2,
|
|
5398
5512
|
unlinkSync as unlinkSync2,
|
|
5399
5513
|
writeFileSync as writeFileSync5
|
|
5400
5514
|
} from "fs";
|
|
5401
5515
|
import { homedir as homedir5 } from "os";
|
|
5402
|
-
import { join as join11 } from "path";
|
|
5516
|
+
import { dirname as dirname6, join as join11, resolve as resolve3 } from "path";
|
|
5403
5517
|
function unitDir() {
|
|
5404
5518
|
return join11(homedir5(), ".config", "systemd", "user");
|
|
5405
5519
|
}
|
|
5406
5520
|
function unitPath() {
|
|
5407
5521
|
return join11(unitDir(), UNIT_NAME);
|
|
5408
5522
|
}
|
|
5409
|
-
function
|
|
5523
|
+
function resolveNodeBin2() {
|
|
5410
5524
|
try {
|
|
5411
|
-
return
|
|
5525
|
+
return realpathSync2(process.execPath);
|
|
5412
5526
|
} catch {
|
|
5413
|
-
return
|
|
5527
|
+
return process.execPath;
|
|
5414
5528
|
}
|
|
5415
5529
|
}
|
|
5530
|
+
function resolveCliEntry2() {
|
|
5531
|
+
if (process.argv[1]) {
|
|
5532
|
+
const resolved = resolve3(process.argv[1]);
|
|
5533
|
+
if (existsSync11(resolved)) return resolved;
|
|
5534
|
+
}
|
|
5535
|
+
try {
|
|
5536
|
+
const shimPath = execSync2("which unerr", { encoding: "utf-8" }).trim();
|
|
5537
|
+
if (shimPath && existsSync11(shimPath)) {
|
|
5538
|
+
const shimContent = readFileSync10(shimPath, "utf-8");
|
|
5539
|
+
const jsMatch = /"\$basedir\/((?:\.\.\/)*[^"]+\.js)"/m.exec(shimContent);
|
|
5540
|
+
if (jsMatch?.[1]) {
|
|
5541
|
+
const basedir = dirname6(shimPath);
|
|
5542
|
+
const abs = resolve3(basedir, jsMatch[1]);
|
|
5543
|
+
if (existsSync11(abs)) return abs;
|
|
5544
|
+
}
|
|
5545
|
+
}
|
|
5546
|
+
} catch {
|
|
5547
|
+
}
|
|
5548
|
+
const fallbackBase = process.argv[1] ? dirname6(resolve3(process.argv[1])) : process.cwd();
|
|
5549
|
+
return join11(fallbackBase, "cli.js");
|
|
5550
|
+
}
|
|
5416
5551
|
function isWSL() {
|
|
5417
5552
|
try {
|
|
5418
5553
|
const version = readFileSync10("/proc/version", "utf-8");
|
|
@@ -5421,18 +5556,25 @@ function isWSL() {
|
|
|
5421
5556
|
return false;
|
|
5422
5557
|
}
|
|
5423
5558
|
}
|
|
5424
|
-
function
|
|
5559
|
+
function systemdQuote(s) {
|
|
5560
|
+
if (/[\s"\\]/.test(s))
|
|
5561
|
+
return `"${s.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
|
|
5562
|
+
return s;
|
|
5563
|
+
}
|
|
5564
|
+
function generateUnit(nodeBin, cliEntry) {
|
|
5565
|
+
const nodeBinDir = dirname6(nodeBin);
|
|
5566
|
+
const home = homedir5();
|
|
5425
5567
|
return `[Unit]
|
|
5426
5568
|
Description=unerr daemon supervisor
|
|
5427
5569
|
After=network.target
|
|
5428
5570
|
|
|
5429
5571
|
[Service]
|
|
5430
5572
|
Type=simple
|
|
5431
|
-
ExecStart=${
|
|
5573
|
+
ExecStart=${systemdQuote(nodeBin)} ${systemdQuote(cliEntry)} daemon start --foreground
|
|
5432
5574
|
Restart=on-failure
|
|
5433
|
-
RestartSec=
|
|
5434
|
-
Environment=HOME=${
|
|
5435
|
-
Environment=PATH=${
|
|
5575
|
+
RestartSec=30
|
|
5576
|
+
Environment=HOME=${home}
|
|
5577
|
+
Environment=PATH=${nodeBinDir}:/usr/local/bin:/usr/bin:/bin
|
|
5436
5578
|
|
|
5437
5579
|
[Install]
|
|
5438
5580
|
WantedBy=default.target
|
|
@@ -5448,16 +5590,18 @@ function installSystemd() {
|
|
|
5448
5590
|
};
|
|
5449
5591
|
}
|
|
5450
5592
|
try {
|
|
5451
|
-
const
|
|
5593
|
+
const nodeBin = resolveNodeBin2();
|
|
5594
|
+
const cliEntry = resolveCliEntry2();
|
|
5452
5595
|
const dir = unitDir();
|
|
5453
5596
|
mkdirSync6(dir, { recursive: true });
|
|
5454
|
-
writeFileSync5(path7, generateUnit(
|
|
5597
|
+
writeFileSync5(path7, generateUnit(nodeBin, cliEntry), "utf-8");
|
|
5455
5598
|
execSync2("systemctl --user daemon-reload", { stdio: "ignore" });
|
|
5456
5599
|
execSync2("systemctl --user enable --now unerrd.service", {
|
|
5457
5600
|
stdio: "ignore"
|
|
5458
5601
|
});
|
|
5459
5602
|
try {
|
|
5460
|
-
|
|
5603
|
+
const username = process.env.USER || execSync2("whoami", { encoding: "utf-8" }).trim();
|
|
5604
|
+
execSync2(`loginctl enable-linger ${username}`, { stdio: "ignore" });
|
|
5461
5605
|
} catch {
|
|
5462
5606
|
}
|
|
5463
5607
|
return { installed: true, path: path7 };
|
|
@@ -5533,9 +5677,16 @@ __export(platform_windows_exports, {
|
|
|
5533
5677
|
uninstallWindows: () => uninstallWindows
|
|
5534
5678
|
});
|
|
5535
5679
|
import { execSync as execSync3 } from "child_process";
|
|
5536
|
-
import {
|
|
5680
|
+
import {
|
|
5681
|
+
existsSync as existsSync12,
|
|
5682
|
+
mkdirSync as mkdirSync7,
|
|
5683
|
+
readFileSync as readFileSync11,
|
|
5684
|
+
realpathSync as realpathSync3,
|
|
5685
|
+
unlinkSync as unlinkSync3,
|
|
5686
|
+
writeFileSync as writeFileSync6
|
|
5687
|
+
} from "fs";
|
|
5537
5688
|
import { homedir as homedir6 } from "os";
|
|
5538
|
-
import { join as join12 } from "path";
|
|
5689
|
+
import { dirname as dirname7, join as join12, resolve as resolve4 } from "path";
|
|
5539
5690
|
function startupDir() {
|
|
5540
5691
|
return join12(
|
|
5541
5692
|
process.env.APPDATA || join12(homedir6(), "AppData", "Roaming"),
|
|
@@ -5549,28 +5700,50 @@ function startupDir() {
|
|
|
5549
5700
|
function startupCmdPath() {
|
|
5550
5701
|
return join12(startupDir(), STARTUP_CMD_NAME);
|
|
5551
5702
|
}
|
|
5552
|
-
function
|
|
5703
|
+
function resolveNodeBin3() {
|
|
5704
|
+
try {
|
|
5705
|
+
return realpathSync3(process.execPath);
|
|
5706
|
+
} catch {
|
|
5707
|
+
return process.execPath;
|
|
5708
|
+
}
|
|
5709
|
+
}
|
|
5710
|
+
function resolveCliEntry3() {
|
|
5711
|
+
if (process.argv[1]) {
|
|
5712
|
+
const resolved = resolve4(process.argv[1]);
|
|
5713
|
+
if (existsSync12(resolved)) return resolved;
|
|
5714
|
+
}
|
|
5553
5715
|
try {
|
|
5554
|
-
|
|
5716
|
+
const whereLine = execSync3("where unerr", { encoding: "utf-8" }).trim().split("\n")[0]?.trim();
|
|
5717
|
+
if (whereLine && existsSync12(whereLine)) {
|
|
5718
|
+
const shimContent = readFileSync11(whereLine, "utf-8");
|
|
5719
|
+
const jsMatch = /"%~dp0\\([^"]+\.js)"/m.exec(shimContent);
|
|
5720
|
+
if (jsMatch?.[1]) {
|
|
5721
|
+
const abs = resolve4(dirname7(whereLine), jsMatch[1]);
|
|
5722
|
+
if (existsSync12(abs)) return abs;
|
|
5723
|
+
}
|
|
5724
|
+
}
|
|
5555
5725
|
} catch {
|
|
5556
|
-
return process.argv[1] || "unerr";
|
|
5557
5726
|
}
|
|
5727
|
+
const fallbackBase = process.argv[1] ? dirname7(resolve4(process.argv[1])) : process.cwd();
|
|
5728
|
+
return join12(fallbackBase, "cli.js");
|
|
5558
5729
|
}
|
|
5559
5730
|
function installWindows() {
|
|
5560
|
-
const
|
|
5561
|
-
const
|
|
5731
|
+
const nodeBin = resolveNodeBin3();
|
|
5732
|
+
const cliEntry = resolveCliEntry3();
|
|
5733
|
+
const taskResult = installScheduledTask(nodeBin, cliEntry);
|
|
5562
5734
|
if (taskResult.installed) return taskResult;
|
|
5563
|
-
return installStartupCmd(
|
|
5735
|
+
return installStartupCmd(nodeBin, cliEntry);
|
|
5564
5736
|
}
|
|
5565
|
-
function installScheduledTask(
|
|
5566
|
-
const
|
|
5737
|
+
function installScheduledTask(nodeBin, cliEntry) {
|
|
5738
|
+
const innerCmd = `\\"${nodeBin}\\" \\"${cliEntry}\\" daemon start --foreground`;
|
|
5739
|
+
const trArg = `"${innerCmd}"`;
|
|
5567
5740
|
try {
|
|
5568
5741
|
try {
|
|
5569
5742
|
execSync3(`schtasks /Delete /TN "${TASK_NAME}" /F`, { stdio: "ignore" });
|
|
5570
5743
|
} catch {
|
|
5571
5744
|
}
|
|
5572
5745
|
execSync3(
|
|
5573
|
-
`schtasks /Create /SC ONLOGON /TN "${TASK_NAME}" /TR ${
|
|
5746
|
+
`schtasks /Create /SC ONLOGON /TN "${TASK_NAME}" /TR ${trArg} /RL LIMITED /F`,
|
|
5574
5747
|
{ stdio: "ignore" }
|
|
5575
5748
|
);
|
|
5576
5749
|
return { installed: true, path: `Scheduled Task: ${TASK_NAME}` };
|
|
@@ -5582,13 +5755,13 @@ function installScheduledTask(bin) {
|
|
|
5582
5755
|
};
|
|
5583
5756
|
}
|
|
5584
5757
|
}
|
|
5585
|
-
function installStartupCmd(
|
|
5758
|
+
function installStartupCmd(nodeBin, cliEntry) {
|
|
5586
5759
|
const path7 = startupCmdPath();
|
|
5587
5760
|
try {
|
|
5588
5761
|
const dir = startupDir();
|
|
5589
5762
|
mkdirSync7(dir, { recursive: true });
|
|
5590
5763
|
const script = `@echo off\r
|
|
5591
|
-
"${
|
|
5764
|
+
"${nodeBin}" "${cliEntry}" daemon start --foreground\r
|
|
5592
5765
|
`;
|
|
5593
5766
|
writeFileSync6(path7, script, "utf-8");
|
|
5594
5767
|
return { installed: true, path: path7 };
|
|
@@ -5770,7 +5943,7 @@ function daemonSockPath() {
|
|
|
5770
5943
|
return join14(globalDir(), "unerrd.sock");
|
|
5771
5944
|
}
|
|
5772
5945
|
function sendRequest(sockPath2, request, timeoutMs = 3e4) {
|
|
5773
|
-
return new Promise((
|
|
5946
|
+
return new Promise((resolve9, reject) => {
|
|
5774
5947
|
let buffer = "";
|
|
5775
5948
|
let settled = false;
|
|
5776
5949
|
const timer = setTimeout(() => {
|
|
@@ -5796,7 +5969,7 @@ function sendRequest(sockPath2, request, timeoutMs = 3e4) {
|
|
|
5796
5969
|
clearTimeout(timer);
|
|
5797
5970
|
socket.destroy();
|
|
5798
5971
|
try {
|
|
5799
|
-
|
|
5972
|
+
resolve9(JSON.parse(line));
|
|
5800
5973
|
} catch {
|
|
5801
5974
|
reject(new Error(`Invalid JSON from unerrd: ${line.slice(0, 200)}`));
|
|
5802
5975
|
}
|
|
@@ -5863,21 +6036,21 @@ async function getStatus(sockPath2) {
|
|
|
5863
6036
|
return resp;
|
|
5864
6037
|
}
|
|
5865
6038
|
function probeDaemon(sockPath2) {
|
|
5866
|
-
return new Promise((
|
|
6039
|
+
return new Promise((resolve9) => {
|
|
5867
6040
|
const socket = createConnection(sockPath2);
|
|
5868
6041
|
const timer = setTimeout(() => {
|
|
5869
6042
|
socket.destroy();
|
|
5870
|
-
|
|
6043
|
+
resolve9(false);
|
|
5871
6044
|
}, 1e3);
|
|
5872
6045
|
timer.unref();
|
|
5873
6046
|
socket.on("connect", () => {
|
|
5874
6047
|
clearTimeout(timer);
|
|
5875
6048
|
socket.destroy();
|
|
5876
|
-
|
|
6049
|
+
resolve9(true);
|
|
5877
6050
|
});
|
|
5878
6051
|
socket.on("error", () => {
|
|
5879
6052
|
clearTimeout(timer);
|
|
5880
|
-
|
|
6053
|
+
resolve9(false);
|
|
5881
6054
|
});
|
|
5882
6055
|
});
|
|
5883
6056
|
}
|
|
@@ -6062,8 +6235,8 @@ var init_process_manager = __esm({
|
|
|
6062
6235
|
if (repo.sock && repo.status === "running") {
|
|
6063
6236
|
return Promise.resolve(repo.sock);
|
|
6064
6237
|
}
|
|
6065
|
-
return new Promise((
|
|
6066
|
-
repo.readyResolve =
|
|
6238
|
+
return new Promise((resolve9, reject) => {
|
|
6239
|
+
repo.readyResolve = resolve9;
|
|
6067
6240
|
repo.readyReject = reject;
|
|
6068
6241
|
const timer = setTimeout(() => {
|
|
6069
6242
|
repo.readyReject?.(
|
|
@@ -6130,9 +6303,9 @@ var init_process_manager = __esm({
|
|
|
6130
6303
|
}
|
|
6131
6304
|
// ── Internal: graceful shutdown ─────────────────────────────
|
|
6132
6305
|
shutdownChild(repo) {
|
|
6133
|
-
return new Promise((
|
|
6306
|
+
return new Promise((resolve9) => {
|
|
6134
6307
|
if (!repo.child) {
|
|
6135
|
-
|
|
6308
|
+
resolve9();
|
|
6136
6309
|
return;
|
|
6137
6310
|
}
|
|
6138
6311
|
const child = repo.child;
|
|
@@ -6140,12 +6313,12 @@ var init_process_manager = __esm({
|
|
|
6140
6313
|
if (!child.killed) {
|
|
6141
6314
|
child.kill("SIGKILL");
|
|
6142
6315
|
}
|
|
6143
|
-
|
|
6316
|
+
resolve9();
|
|
6144
6317
|
}, 1e4);
|
|
6145
6318
|
timer.unref();
|
|
6146
6319
|
child.once("exit", () => {
|
|
6147
6320
|
clearTimeout(timer);
|
|
6148
|
-
|
|
6321
|
+
resolve9();
|
|
6149
6322
|
});
|
|
6150
6323
|
try {
|
|
6151
6324
|
child.send({ type: "shutdown" });
|
|
@@ -6183,7 +6356,7 @@ import {
|
|
|
6183
6356
|
statSync as statSync2,
|
|
6184
6357
|
unlinkSync as unlinkSync5
|
|
6185
6358
|
} from "fs";
|
|
6186
|
-
import { dirname as
|
|
6359
|
+
import { dirname as dirname8 } from "path";
|
|
6187
6360
|
function stripAnsi(s) {
|
|
6188
6361
|
return s.replace(ANSI_RE, "");
|
|
6189
6362
|
}
|
|
@@ -6206,7 +6379,7 @@ function rotate(filePath, keep) {
|
|
|
6206
6379
|
}
|
|
6207
6380
|
function installFileLogger(opts) {
|
|
6208
6381
|
const { filePath, maxBytes = 5e6, keep = 5 } = opts;
|
|
6209
|
-
mkdirSync9(
|
|
6382
|
+
mkdirSync9(dirname8(filePath), { recursive: true });
|
|
6210
6383
|
let bytesWritten = 0;
|
|
6211
6384
|
try {
|
|
6212
6385
|
bytesWritten = statSync2(filePath).size;
|
|
@@ -6244,7 +6417,7 @@ var init_file_logger = __esm({
|
|
|
6244
6417
|
|
|
6245
6418
|
// src/daemon/system-health.ts
|
|
6246
6419
|
import { execSync as execSync4 } from "child_process";
|
|
6247
|
-
import { existsSync as existsSync15, readFileSync as
|
|
6420
|
+
import { existsSync as existsSync15, readFileSync as readFileSync12, readdirSync as readdirSync3 } from "fs";
|
|
6248
6421
|
import { cpus, loadavg, platform } from "os";
|
|
6249
6422
|
function onBattery() {
|
|
6250
6423
|
const now = Date.now();
|
|
@@ -6283,7 +6456,7 @@ function detectBatteryLinux() {
|
|
|
6283
6456
|
if (name.startsWith("AC") || name.startsWith("ADP")) {
|
|
6284
6457
|
const onlinePath = `${psDir}/${name}/online`;
|
|
6285
6458
|
if (existsSync15(onlinePath)) {
|
|
6286
|
-
const online =
|
|
6459
|
+
const online = readFileSync12(onlinePath, "utf-8").trim();
|
|
6287
6460
|
if (online === "0") return true;
|
|
6288
6461
|
if (online === "1") return false;
|
|
6289
6462
|
}
|
|
@@ -6353,14 +6526,14 @@ __export(warm_start_exports, {
|
|
|
6353
6526
|
scheduleWarmStart: () => scheduleWarmStart,
|
|
6354
6527
|
selectCandidates: () => selectCandidates
|
|
6355
6528
|
});
|
|
6356
|
-
import { existsSync as existsSync16, mkdirSync as mkdirSync10, readFileSync as
|
|
6529
|
+
import { existsSync as existsSync16, mkdirSync as mkdirSync10, readFileSync as readFileSync13, writeFileSync as writeFileSync8 } from "fs";
|
|
6357
6530
|
import { homedir as homedir8 } from "os";
|
|
6358
6531
|
import { join as join15 } from "path";
|
|
6359
6532
|
function loadWarmStartConfig() {
|
|
6360
6533
|
const configPath = join15(homedir8(), ".unerr", "config.json");
|
|
6361
6534
|
try {
|
|
6362
6535
|
if (!existsSync16(configPath)) return { ...DEFAULT_CONFIG };
|
|
6363
|
-
const raw = JSON.parse(
|
|
6536
|
+
const raw = JSON.parse(readFileSync13(configPath, "utf-8"));
|
|
6364
6537
|
return {
|
|
6365
6538
|
warmStartBudget: typeof raw.warmStartBudget === "number" ? raw.warmStartBudget : DEFAULT_CONFIG.warmStartBudget,
|
|
6366
6539
|
warmStartIdleDays: typeof raw.warmStartIdleDays === "number" ? raw.warmStartIdleDays : DEFAULT_CONFIG.warmStartIdleDays,
|
|
@@ -6377,7 +6550,7 @@ function saveWarmStartConfig(partial) {
|
|
|
6377
6550
|
let existing = {};
|
|
6378
6551
|
try {
|
|
6379
6552
|
if (existsSync16(configPath)) {
|
|
6380
|
-
existing = JSON.parse(
|
|
6553
|
+
existing = JSON.parse(readFileSync13(configPath, "utf-8"));
|
|
6381
6554
|
}
|
|
6382
6555
|
} catch {
|
|
6383
6556
|
}
|
|
@@ -6553,7 +6726,7 @@ __export(version_checker_exports, {
|
|
|
6553
6726
|
startPeriodicCheck: () => startPeriodicCheck,
|
|
6554
6727
|
writeVersionCache: () => writeVersionCache
|
|
6555
6728
|
});
|
|
6556
|
-
import { existsSync as existsSync17, mkdirSync as mkdirSync11, readFileSync as
|
|
6729
|
+
import { existsSync as existsSync17, mkdirSync as mkdirSync11, readFileSync as readFileSync14, writeFileSync as writeFileSync9 } from "fs";
|
|
6557
6730
|
import { get as httpsGet } from "https";
|
|
6558
6731
|
import { homedir as homedir9 } from "os";
|
|
6559
6732
|
import { join as join16 } from "path";
|
|
@@ -6565,7 +6738,7 @@ function getInstalledVersion() {
|
|
|
6565
6738
|
try {
|
|
6566
6739
|
const pkgPath = join16(__dirname, "../../package.json");
|
|
6567
6740
|
if (existsSync17(pkgPath)) {
|
|
6568
|
-
const pkg = JSON.parse(
|
|
6741
|
+
const pkg = JSON.parse(readFileSync14(pkgPath, "utf-8"));
|
|
6569
6742
|
cachedInstalledVersion = pkg.version;
|
|
6570
6743
|
return pkg.version;
|
|
6571
6744
|
}
|
|
@@ -6575,7 +6748,7 @@ function getInstalledVersion() {
|
|
|
6575
6748
|
const binDir = join16(process.argv[1] || "", "..");
|
|
6576
6749
|
const pkgPath = join16(binDir, "../package.json");
|
|
6577
6750
|
if (existsSync17(pkgPath)) {
|
|
6578
|
-
const pkg = JSON.parse(
|
|
6751
|
+
const pkg = JSON.parse(readFileSync14(pkgPath, "utf-8"));
|
|
6579
6752
|
cachedInstalledVersion = pkg.version;
|
|
6580
6753
|
return pkg.version;
|
|
6581
6754
|
}
|
|
@@ -6596,7 +6769,7 @@ function readVersionCache() {
|
|
|
6596
6769
|
const path7 = versionCachePath();
|
|
6597
6770
|
if (!existsSync17(path7)) return defaults;
|
|
6598
6771
|
const raw = JSON.parse(
|
|
6599
|
-
|
|
6772
|
+
readFileSync14(path7, "utf-8")
|
|
6600
6773
|
);
|
|
6601
6774
|
return {
|
|
6602
6775
|
lastChecked: raw.lastChecked ?? defaults.lastChecked,
|
|
@@ -6620,7 +6793,7 @@ function parseSemVer(version) {
|
|
|
6620
6793
|
if (parts.length < 3) return null;
|
|
6621
6794
|
const major = Number.parseInt(parts[0], 10);
|
|
6622
6795
|
const minor = Number.parseInt(parts[1], 10);
|
|
6623
|
-
const patch = Number.parseInt(parts[2]
|
|
6796
|
+
const patch = Number.parseInt(parts[2]?.split("-")[0], 10);
|
|
6624
6797
|
if (!Number.isFinite(major) || !Number.isFinite(minor) || !Number.isFinite(patch))
|
|
6625
6798
|
return null;
|
|
6626
6799
|
return { major, minor, patch };
|
|
@@ -6642,14 +6815,14 @@ function minorsBehind(latest, current) {
|
|
|
6642
6815
|
return Math.max(0, l.minor - c.minor);
|
|
6643
6816
|
}
|
|
6644
6817
|
function fetchLatestVersion() {
|
|
6645
|
-
return new Promise((
|
|
6818
|
+
return new Promise((resolve9) => {
|
|
6646
6819
|
const req = httpsGet(
|
|
6647
6820
|
REGISTRY_URL,
|
|
6648
6821
|
{ headers: { Accept: "application/json" }, timeout: REQUEST_TIMEOUT_MS },
|
|
6649
6822
|
(res) => {
|
|
6650
6823
|
if (res.statusCode !== 200) {
|
|
6651
6824
|
res.resume();
|
|
6652
|
-
|
|
6825
|
+
resolve9(null);
|
|
6653
6826
|
return;
|
|
6654
6827
|
}
|
|
6655
6828
|
let body = "";
|
|
@@ -6659,17 +6832,17 @@ function fetchLatestVersion() {
|
|
|
6659
6832
|
res.on("end", () => {
|
|
6660
6833
|
try {
|
|
6661
6834
|
const data = JSON.parse(body);
|
|
6662
|
-
|
|
6835
|
+
resolve9(data.version ?? null);
|
|
6663
6836
|
} catch {
|
|
6664
|
-
|
|
6837
|
+
resolve9(null);
|
|
6665
6838
|
}
|
|
6666
6839
|
});
|
|
6667
6840
|
}
|
|
6668
6841
|
);
|
|
6669
|
-
req.on("error", () =>
|
|
6842
|
+
req.on("error", () => resolve9(null));
|
|
6670
6843
|
req.on("timeout", () => {
|
|
6671
6844
|
req.destroy();
|
|
6672
|
-
|
|
6845
|
+
resolve9(null);
|
|
6673
6846
|
});
|
|
6674
6847
|
});
|
|
6675
6848
|
}
|
|
@@ -6773,9 +6946,9 @@ var api_exports = {};
|
|
|
6773
6946
|
__export(api_exports, {
|
|
6774
6947
|
startDaemonApi: () => startDaemonApi
|
|
6775
6948
|
});
|
|
6776
|
-
import { existsSync as existsSync18, readFileSync as
|
|
6949
|
+
import { existsSync as existsSync18, readFileSync as readFileSync15 } from "fs";
|
|
6777
6950
|
import { request as httpRequest } from "http";
|
|
6778
|
-
import { dirname as
|
|
6951
|
+
import { dirname as dirname9, join as join17 } from "path";
|
|
6779
6952
|
import { fileURLToPath } from "url";
|
|
6780
6953
|
import { serve } from "@hono/node-server";
|
|
6781
6954
|
import { serveStatic } from "@hono/node-server/serve-static";
|
|
@@ -6829,7 +7002,7 @@ function startDaemonApi(pm) {
|
|
|
6829
7002
|
if (!existsSync18(serverJsonPath)) return null;
|
|
6830
7003
|
try {
|
|
6831
7004
|
const serverInfo = JSON.parse(
|
|
6832
|
-
|
|
7005
|
+
readFileSync15(serverJsonPath, "utf-8")
|
|
6833
7006
|
);
|
|
6834
7007
|
const [sessionStats, tokenFlow] = await Promise.allSettled([
|
|
6835
7008
|
fetchRepoApi(serverInfo.port, "/api/session/stats"),
|
|
@@ -6943,7 +7116,7 @@ function startDaemonApi(pm) {
|
|
|
6943
7116
|
}
|
|
6944
7117
|
let repoPort;
|
|
6945
7118
|
try {
|
|
6946
|
-
const info2 = JSON.parse(
|
|
7119
|
+
const info2 = JSON.parse(readFileSync15(serverJsonPath, "utf-8"));
|
|
6947
7120
|
repoPort = info2.port;
|
|
6948
7121
|
} catch {
|
|
6949
7122
|
return c.json({ error: `Cannot read server.json for ${label}` }, 500);
|
|
@@ -6961,10 +7134,10 @@ function startDaemonApi(pm) {
|
|
|
6961
7134
|
return c.json({ error: `Proxy error: ${err.message}` }, 502);
|
|
6962
7135
|
}
|
|
6963
7136
|
});
|
|
6964
|
-
const distDir = join17(
|
|
7137
|
+
const distDir = join17(dirname9(fileURLToPath(import.meta.url)), "ui");
|
|
6965
7138
|
const spaIndex = join17(distDir, "index.html");
|
|
6966
7139
|
if (existsSync18(spaIndex)) {
|
|
6967
|
-
const spaHtml =
|
|
7140
|
+
const spaHtml = readFileSync15(spaIndex, "utf-8");
|
|
6968
7141
|
app.use("*", serveStatic({ root: distDir }));
|
|
6969
7142
|
app.get("*", (c) => {
|
|
6970
7143
|
if (c.req.path.startsWith("/api/")) return c.notFound();
|
|
@@ -7010,7 +7183,7 @@ function startDaemonApi(pm) {
|
|
|
7010
7183
|
};
|
|
7011
7184
|
}
|
|
7012
7185
|
function fetchRepoApi(port, path7) {
|
|
7013
|
-
return new Promise((
|
|
7186
|
+
return new Promise((resolve9, reject) => {
|
|
7014
7187
|
const req = httpRequest(
|
|
7015
7188
|
{ hostname: "127.0.0.1", port, path: path7, method: "GET", timeout: 3e3 },
|
|
7016
7189
|
(res) => {
|
|
@@ -7020,9 +7193,9 @@ function fetchRepoApi(port, path7) {
|
|
|
7020
7193
|
});
|
|
7021
7194
|
res.on("end", () => {
|
|
7022
7195
|
try {
|
|
7023
|
-
|
|
7196
|
+
resolve9(JSON.parse(body));
|
|
7024
7197
|
} catch {
|
|
7025
|
-
|
|
7198
|
+
resolve9(body);
|
|
7026
7199
|
}
|
|
7027
7200
|
});
|
|
7028
7201
|
}
|
|
@@ -7036,7 +7209,7 @@ function fetchRepoApi(port, path7) {
|
|
|
7036
7209
|
});
|
|
7037
7210
|
}
|
|
7038
7211
|
function proxyToRepoHttp(port, path7, method) {
|
|
7039
|
-
return new Promise((
|
|
7212
|
+
return new Promise((resolve9, reject) => {
|
|
7040
7213
|
const req = httpRequest(
|
|
7041
7214
|
{ hostname: "127.0.0.1", port, path: path7, method, timeout: 1e4 },
|
|
7042
7215
|
(res) => {
|
|
@@ -7046,9 +7219,9 @@ function proxyToRepoHttp(port, path7, method) {
|
|
|
7046
7219
|
});
|
|
7047
7220
|
res.on("end", () => {
|
|
7048
7221
|
try {
|
|
7049
|
-
|
|
7222
|
+
resolve9(JSON.parse(body));
|
|
7050
7223
|
} catch {
|
|
7051
|
-
|
|
7224
|
+
resolve9(body);
|
|
7052
7225
|
}
|
|
7053
7226
|
});
|
|
7054
7227
|
}
|
|
@@ -7078,7 +7251,7 @@ __export(daemon_exports, {
|
|
|
7078
7251
|
import {
|
|
7079
7252
|
existsSync as existsSync19,
|
|
7080
7253
|
mkdirSync as mkdirSync12,
|
|
7081
|
-
readFileSync as
|
|
7254
|
+
readFileSync as readFileSync16,
|
|
7082
7255
|
unlinkSync as unlinkSync6,
|
|
7083
7256
|
writeFileSync as writeFileSync10
|
|
7084
7257
|
} from "fs";
|
|
@@ -7101,7 +7274,7 @@ function isProcessAlive(pid) {
|
|
|
7101
7274
|
function acquirePidLock() {
|
|
7102
7275
|
const p = pidPath();
|
|
7103
7276
|
try {
|
|
7104
|
-
const raw =
|
|
7277
|
+
const raw = readFileSync16(p, "utf-8").trim();
|
|
7105
7278
|
const existingPid = Number.parseInt(raw, 10);
|
|
7106
7279
|
if (Number.isFinite(existingPid) && isProcessAlive(existingPid)) {
|
|
7107
7280
|
return false;
|
|
@@ -7149,8 +7322,9 @@ function createUdsServer(pm) {
|
|
|
7149
7322
|
let buffer = "";
|
|
7150
7323
|
socket.on("data", (chunk) => {
|
|
7151
7324
|
buffer += chunk.toString();
|
|
7152
|
-
|
|
7153
|
-
|
|
7325
|
+
while (true) {
|
|
7326
|
+
const newlineIdx = buffer.indexOf("\n");
|
|
7327
|
+
if (newlineIdx === -1) break;
|
|
7154
7328
|
const line = buffer.slice(0, newlineIdx).trim();
|
|
7155
7329
|
buffer = buffer.slice(newlineIdx + 1);
|
|
7156
7330
|
if (!line) continue;
|
|
@@ -7309,14 +7483,14 @@ async function startDaemon(opts) {
|
|
|
7309
7483
|
}
|
|
7310
7484
|
});
|
|
7311
7485
|
});
|
|
7312
|
-
await new Promise((
|
|
7486
|
+
await new Promise((resolve9, reject) => {
|
|
7313
7487
|
server.on("error", (err) => {
|
|
7314
7488
|
log.error(`UDS server error: ${err.message}`);
|
|
7315
7489
|
releasePidLock();
|
|
7316
7490
|
reject(err);
|
|
7317
7491
|
});
|
|
7318
7492
|
server.listen(sock, () => {
|
|
7319
|
-
|
|
7493
|
+
resolve9();
|
|
7320
7494
|
});
|
|
7321
7495
|
});
|
|
7322
7496
|
const reg = readRegistry();
|
|
@@ -7399,19 +7573,23 @@ __export(startup_log_exports, {
|
|
|
7399
7573
|
import {
|
|
7400
7574
|
appendFileSync as appendFileSync4,
|
|
7401
7575
|
mkdirSync as mkdirSync13,
|
|
7402
|
-
readFileSync as
|
|
7576
|
+
readFileSync as readFileSync17,
|
|
7403
7577
|
writeFileSync as writeFileSync11
|
|
7404
7578
|
} from "fs";
|
|
7405
7579
|
import { join as join19 } from "path";
|
|
7406
7580
|
function stripAnsi2(s) {
|
|
7407
|
-
|
|
7581
|
+
const ESC2 = "\x1B";
|
|
7582
|
+
const CSI = new RegExp(`${ESC2}\\[[0-9;?]*[A-Za-z~]`, "g");
|
|
7583
|
+
const OSC = new RegExp(`${ESC2}\\][^\\x07]*\\x07`, "g");
|
|
7584
|
+
return s.replace(CSI, "").replace(OSC, "");
|
|
7408
7585
|
}
|
|
7409
7586
|
function rotateIfNeeded(filePath, maxLines, keepLines) {
|
|
7410
7587
|
try {
|
|
7411
|
-
const content =
|
|
7588
|
+
const content = readFileSync17(filePath, "utf-8");
|
|
7412
7589
|
const lines = content.split("\n").filter(Boolean);
|
|
7413
7590
|
if (lines.length > maxLines) {
|
|
7414
|
-
writeFileSync11(filePath, lines.slice(-keepLines).join("\n")
|
|
7591
|
+
writeFileSync11(filePath, `${lines.slice(-keepLines).join("\n")}
|
|
7592
|
+
`);
|
|
7415
7593
|
}
|
|
7416
7594
|
} catch {
|
|
7417
7595
|
}
|
|
@@ -7432,7 +7610,8 @@ function writeToFile(level, message, meta) {
|
|
|
7432
7610
|
...meta
|
|
7433
7611
|
};
|
|
7434
7612
|
try {
|
|
7435
|
-
appendFileSync4(_fileLogPath, JSON.stringify(entry)
|
|
7613
|
+
appendFileSync4(_fileLogPath, `${JSON.stringify(entry)}
|
|
7614
|
+
`);
|
|
7436
7615
|
if (++_fileLogCount % 200 === 0) rotateIfNeeded(_fileLogPath, 2e3, 1e3);
|
|
7437
7616
|
} catch {
|
|
7438
7617
|
}
|
|
@@ -7960,7 +8139,7 @@ __export(settings_exports, {
|
|
|
7960
8139
|
resolveEmbeddingEndpoint: () => resolveEmbeddingEndpoint,
|
|
7961
8140
|
resolveInferenceEndpoint: () => resolveInferenceEndpoint
|
|
7962
8141
|
});
|
|
7963
|
-
import { existsSync as existsSync22, readFileSync as
|
|
8142
|
+
import { existsSync as existsSync22, readFileSync as readFileSync20 } from "fs";
|
|
7964
8143
|
import { homedir as homedir11 } from "os";
|
|
7965
8144
|
import { join as join22 } from "path";
|
|
7966
8145
|
import { z } from "zod";
|
|
@@ -7985,7 +8164,7 @@ function resolveInferenceEndpoint(config) {
|
|
|
7985
8164
|
function loadJsonFile(filePath) {
|
|
7986
8165
|
if (!existsSync22(filePath)) return {};
|
|
7987
8166
|
try {
|
|
7988
|
-
return JSON.parse(
|
|
8167
|
+
return JSON.parse(readFileSync20(filePath, "utf-8"));
|
|
7989
8168
|
} catch {
|
|
7990
8169
|
return {};
|
|
7991
8170
|
}
|
|
@@ -8611,9 +8790,9 @@ __export(metrics_store_exports, {
|
|
|
8611
8790
|
closeMetricsStore: () => closeMetricsStore,
|
|
8612
8791
|
openMetricsStore: () => openMetricsStore
|
|
8613
8792
|
});
|
|
8614
|
-
import Database from "better-sqlite3";
|
|
8615
8793
|
import { mkdirSync as mkdirSync16 } from "fs";
|
|
8616
8794
|
import { join as join25 } from "path";
|
|
8795
|
+
import Database from "better-sqlite3";
|
|
8617
8796
|
function openMetricsStore(unerrDir) {
|
|
8618
8797
|
let store = instances.get(unerrDir);
|
|
8619
8798
|
if (!store) {
|
|
@@ -9278,7 +9457,7 @@ __export(shell_stats_exports, {
|
|
|
9278
9457
|
readShellCompressionAggregate: () => readShellCompressionAggregate,
|
|
9279
9458
|
recordShellCompressionEvent: () => recordShellCompressionEvent
|
|
9280
9459
|
});
|
|
9281
|
-
import { existsSync as existsSync25, mkdirSync as mkdirSync17, readFileSync as
|
|
9460
|
+
import { existsSync as existsSync25, mkdirSync as mkdirSync17, readFileSync as readFileSync22, writeFileSync as writeFileSync13 } from "fs";
|
|
9282
9461
|
import { join as join27 } from "path";
|
|
9283
9462
|
function estimateRoughTokens(s) {
|
|
9284
9463
|
return Math.max(1, Math.ceil(s.length / 4));
|
|
@@ -9301,7 +9480,7 @@ function recordShellCompressionEvent(cwd, category, original, compressed) {
|
|
|
9301
9480
|
agg = {
|
|
9302
9481
|
...agg,
|
|
9303
9482
|
...JSON.parse(
|
|
9304
|
-
|
|
9483
|
+
readFileSync22(path7, "utf-8")
|
|
9305
9484
|
)
|
|
9306
9485
|
};
|
|
9307
9486
|
}
|
|
@@ -9321,7 +9500,7 @@ function readShellCompressionAggregate(cwd) {
|
|
|
9321
9500
|
try {
|
|
9322
9501
|
const path7 = join27(cwd, ".unerr", "state", "shell_compression_stats.json");
|
|
9323
9502
|
if (!existsSync25(path7)) return null;
|
|
9324
|
-
return JSON.parse(
|
|
9503
|
+
return JSON.parse(readFileSync22(path7, "utf-8"));
|
|
9325
9504
|
} catch {
|
|
9326
9505
|
return null;
|
|
9327
9506
|
}
|
|
@@ -9344,7 +9523,7 @@ __export(local_snapshot_exports, {
|
|
|
9344
9523
|
import {
|
|
9345
9524
|
existsSync as existsSync29,
|
|
9346
9525
|
mkdirSync as mkdirSync20,
|
|
9347
|
-
readFileSync as
|
|
9526
|
+
readFileSync as readFileSync28,
|
|
9348
9527
|
readdirSync as readdirSync6,
|
|
9349
9528
|
statSync as statSync6,
|
|
9350
9529
|
writeFileSync as writeFileSync16
|
|
@@ -9401,7 +9580,7 @@ async function loadLocalSnapshot(projectRoot, graphStore) {
|
|
|
9401
9580
|
try {
|
|
9402
9581
|
const { unpack } = await import("msgpackr");
|
|
9403
9582
|
const { gunzipSync: gunzipSync3 } = await import("zlib");
|
|
9404
|
-
const raw =
|
|
9583
|
+
const raw = readFileSync28(path7);
|
|
9405
9584
|
const buffer = gunzipSync3(raw);
|
|
9406
9585
|
const envelope = unpack(buffer);
|
|
9407
9586
|
await graphStore.loadSnapshot(envelope);
|
|
@@ -9489,6 +9668,28 @@ var init_local_snapshot = __esm({
|
|
|
9489
9668
|
}
|
|
9490
9669
|
});
|
|
9491
9670
|
|
|
9671
|
+
// src/utils/format-error.ts
|
|
9672
|
+
function formatUnknownError(err) {
|
|
9673
|
+
if (err instanceof Error) return err.stack ?? err.message;
|
|
9674
|
+
if (typeof err === "object" && err !== null) {
|
|
9675
|
+
const obj = err;
|
|
9676
|
+
if (typeof obj.display === "string") return obj.display;
|
|
9677
|
+
if (typeof obj.message === "string") return obj.message;
|
|
9678
|
+
try {
|
|
9679
|
+
const serialized = JSON.stringify(err, Object.getOwnPropertyNames(err));
|
|
9680
|
+
if (serialized && serialized !== "{}") return serialized;
|
|
9681
|
+
} catch {
|
|
9682
|
+
}
|
|
9683
|
+
return Object.prototype.toString.call(err);
|
|
9684
|
+
}
|
|
9685
|
+
return String(err);
|
|
9686
|
+
}
|
|
9687
|
+
var init_format_error = __esm({
|
|
9688
|
+
"src/utils/format-error.ts"() {
|
|
9689
|
+
"use strict";
|
|
9690
|
+
}
|
|
9691
|
+
});
|
|
9692
|
+
|
|
9492
9693
|
// src/intelligence/ast-extractor.ts
|
|
9493
9694
|
var ast_extractor_exports = {};
|
|
9494
9695
|
__export(ast_extractor_exports, {
|
|
@@ -11047,6 +11248,28 @@ function extractTSEdges(root, edges, entities) {
|
|
|
11047
11248
|
}
|
|
11048
11249
|
}
|
|
11049
11250
|
}
|
|
11251
|
+
if (n.type === "call_expression") {
|
|
11252
|
+
const func = n.childForFieldName("function");
|
|
11253
|
+
if (func?.type === "import") {
|
|
11254
|
+
const awaitExpr = n.parent;
|
|
11255
|
+
const varDecl = awaitExpr?.type === "await_expression" ? awaitExpr.parent : null;
|
|
11256
|
+
if (varDecl?.type === "variable_declarator") {
|
|
11257
|
+
const pattern = varDecl.childForFieldName("name");
|
|
11258
|
+
if (pattern?.type === "object_pattern") {
|
|
11259
|
+
for (const prop of pattern.namedChildren) {
|
|
11260
|
+
if (prop.type === "shorthand_property_identifier_pattern") {
|
|
11261
|
+
importedNames.add(prop.text);
|
|
11262
|
+
} else if (prop.type === "pair_pattern") {
|
|
11263
|
+
const val = prop.childForFieldName("value");
|
|
11264
|
+
if (val?.type === "identifier") importedNames.add(val.text);
|
|
11265
|
+
}
|
|
11266
|
+
}
|
|
11267
|
+
} else if (pattern?.type === "identifier") {
|
|
11268
|
+
importedNames.add(pattern.text);
|
|
11269
|
+
}
|
|
11270
|
+
}
|
|
11271
|
+
}
|
|
11272
|
+
}
|
|
11050
11273
|
});
|
|
11051
11274
|
walkNodes(root, (n) => {
|
|
11052
11275
|
if (n.type === "import_statement") {
|
|
@@ -11116,6 +11339,26 @@ function extractTSEdges(root, edges, entities) {
|
|
|
11116
11339
|
if (n.type === "call_expression") {
|
|
11117
11340
|
const func = n.childForFieldName("function");
|
|
11118
11341
|
if (!func) return;
|
|
11342
|
+
if (func.type === "import") {
|
|
11343
|
+
const argsNode = n.childForFieldName("arguments");
|
|
11344
|
+
if (argsNode) {
|
|
11345
|
+
const strArg = argsNode.namedChildren.find(
|
|
11346
|
+
(c) => c.type === "string"
|
|
11347
|
+
);
|
|
11348
|
+
if (strArg) {
|
|
11349
|
+
const src = strArg.text.replace(/['"]/g, "");
|
|
11350
|
+
if (src) {
|
|
11351
|
+
edges.push({
|
|
11352
|
+
from_name: "__file__",
|
|
11353
|
+
to_name: "__dynamic_import__",
|
|
11354
|
+
type: "imports",
|
|
11355
|
+
import_source: src
|
|
11356
|
+
});
|
|
11357
|
+
}
|
|
11358
|
+
}
|
|
11359
|
+
}
|
|
11360
|
+
return;
|
|
11361
|
+
}
|
|
11119
11362
|
let calledName = null;
|
|
11120
11363
|
if (func.type === "identifier") {
|
|
11121
11364
|
calledName = func.text;
|
|
@@ -11948,12 +12191,12 @@ var init_logger = __esm({
|
|
|
11948
12191
|
});
|
|
11949
12192
|
|
|
11950
12193
|
// src/intelligence/indexer/scip/decoder.ts
|
|
11951
|
-
import { readFileSync as
|
|
12194
|
+
import { readFileSync as readFileSync29 } from "fs";
|
|
11952
12195
|
async function decodeScipOutput(filePath) {
|
|
11953
12196
|
const start = performance.now();
|
|
11954
12197
|
let buffer;
|
|
11955
12198
|
try {
|
|
11956
|
-
buffer =
|
|
12199
|
+
buffer = readFileSync29(filePath);
|
|
11957
12200
|
} catch {
|
|
11958
12201
|
return emptyResult(start);
|
|
11959
12202
|
}
|
|
@@ -11970,7 +12213,7 @@ async function decodeScipOutput(filePath) {
|
|
|
11970
12213
|
offset = field.nextOffset;
|
|
11971
12214
|
if (field.fieldNumber === 2 && field.wireType === 2) {
|
|
11972
12215
|
const doc = parseDocument(field.data);
|
|
11973
|
-
if (doc
|
|
12216
|
+
if (doc?.relativePath) {
|
|
11974
12217
|
documents.push(doc);
|
|
11975
12218
|
symbolCount += doc.symbols.length;
|
|
11976
12219
|
definitionCount += doc.symbols.filter((s) => s.isDefinition).length;
|
|
@@ -12545,7 +12788,6 @@ async function detectScipBinary(language) {
|
|
|
12545
12788
|
};
|
|
12546
12789
|
}
|
|
12547
12790
|
} catch {
|
|
12548
|
-
continue;
|
|
12549
12791
|
}
|
|
12550
12792
|
}
|
|
12551
12793
|
return {
|
|
@@ -12823,7 +13065,7 @@ var init_runner = __esm({
|
|
|
12823
13065
|
import {
|
|
12824
13066
|
existsSync as existsSync34,
|
|
12825
13067
|
mkdirSync as mkdirSync23,
|
|
12826
|
-
readFileSync as
|
|
13068
|
+
readFileSync as readFileSync30,
|
|
12827
13069
|
statSync as statSync7,
|
|
12828
13070
|
writeFileSync as writeFileSync17
|
|
12829
13071
|
} from "fs";
|
|
@@ -12876,7 +13118,7 @@ async function enrichWithScip(files, projectRoot, existingEdges, entities, optio
|
|
|
12876
13118
|
if (language === "typescript") {
|
|
12877
13119
|
if (!existsSync34(join37(projectRoot, "tsconfig.json")) && !existsSync34(join37(projectRoot, "jsconfig.json"))) {
|
|
12878
13120
|
log6.info(
|
|
12879
|
-
|
|
13121
|
+
"SCIP skipping TypeScript: no tsconfig.json or jsconfig.json found in project root. Create one to enable SCIP indexing."
|
|
12880
13122
|
);
|
|
12881
13123
|
continue;
|
|
12882
13124
|
}
|
|
@@ -12891,7 +13133,7 @@ async function enrichWithScip(files, projectRoot, existingEdges, entities, optio
|
|
|
12891
13133
|
const compdbPath = resolveCompileCommandsJson(projectRoot);
|
|
12892
13134
|
if (!compdbPath) {
|
|
12893
13135
|
log6.info(
|
|
12894
|
-
|
|
13136
|
+
"SCIP skipping C/C++: no compile_commands.json found. Generate one with CMake (-DCMAKE_EXPORT_COMPILE_COMMANDS=ON), Bear, or your build system."
|
|
12895
13137
|
);
|
|
12896
13138
|
continue;
|
|
12897
13139
|
}
|
|
@@ -12966,7 +13208,7 @@ function detectJavaBuildTools(projectRoot) {
|
|
|
12966
13208
|
function getStoredBuildTool(projectRoot) {
|
|
12967
13209
|
try {
|
|
12968
13210
|
const configPath = join37(projectRoot, ".unerr", "config.json");
|
|
12969
|
-
const config = JSON.parse(
|
|
13211
|
+
const config = JSON.parse(readFileSync30(configPath, "utf-8"));
|
|
12970
13212
|
return config.javaBuildTool ?? null;
|
|
12971
13213
|
} catch {
|
|
12972
13214
|
return null;
|
|
@@ -12976,7 +13218,7 @@ function storeBuildTool(projectRoot, tool) {
|
|
|
12976
13218
|
const configPath = join37(projectRoot, ".unerr", "config.json");
|
|
12977
13219
|
let config = {};
|
|
12978
13220
|
try {
|
|
12979
|
-
config = JSON.parse(
|
|
13221
|
+
config = JSON.parse(readFileSync30(configPath, "utf-8"));
|
|
12980
13222
|
} catch {
|
|
12981
13223
|
}
|
|
12982
13224
|
config.javaBuildTool = tool;
|
|
@@ -13102,13 +13344,13 @@ async function installScipDotnet() {
|
|
|
13102
13344
|
const dotnetCheck = await exec("which", ["dotnet"]);
|
|
13103
13345
|
if (dotnetCheck.exitCode !== 0) {
|
|
13104
13346
|
log6.warn(
|
|
13105
|
-
|
|
13347
|
+
"SCIP skipping C#: dotnet CLI not found on PATH. Install the .NET SDK to enable SCIP indexing for C#."
|
|
13106
13348
|
);
|
|
13107
13349
|
return false;
|
|
13108
13350
|
}
|
|
13109
13351
|
} catch {
|
|
13110
13352
|
log6.warn(
|
|
13111
|
-
|
|
13353
|
+
"SCIP skipping C#: dotnet CLI not found on PATH. Install the .NET SDK to enable SCIP indexing for C#."
|
|
13112
13354
|
);
|
|
13113
13355
|
return false;
|
|
13114
13356
|
}
|
|
@@ -13192,34 +13434,12 @@ var init_orchestrator = __esm({
|
|
|
13192
13434
|
}
|
|
13193
13435
|
});
|
|
13194
13436
|
|
|
13195
|
-
// src/utils/format-error.ts
|
|
13196
|
-
function formatUnknownError(err) {
|
|
13197
|
-
if (err instanceof Error) return err.stack ?? err.message;
|
|
13198
|
-
if (typeof err === "object" && err !== null) {
|
|
13199
|
-
const obj = err;
|
|
13200
|
-
if (typeof obj.display === "string") return obj.display;
|
|
13201
|
-
if (typeof obj.message === "string") return obj.message;
|
|
13202
|
-
try {
|
|
13203
|
-
const serialized = JSON.stringify(err, Object.getOwnPropertyNames(err));
|
|
13204
|
-
if (serialized && serialized !== "{}") return serialized;
|
|
13205
|
-
} catch {
|
|
13206
|
-
}
|
|
13207
|
-
return Object.prototype.toString.call(err);
|
|
13208
|
-
}
|
|
13209
|
-
return String(err);
|
|
13210
|
-
}
|
|
13211
|
-
var init_format_error = __esm({
|
|
13212
|
-
"src/utils/format-error.ts"() {
|
|
13213
|
-
"use strict";
|
|
13214
|
-
}
|
|
13215
|
-
});
|
|
13216
|
-
|
|
13217
13437
|
// src/intelligence/local-convention-detector.ts
|
|
13218
13438
|
var local_convention_detector_exports = {};
|
|
13219
13439
|
__export(local_convention_detector_exports, {
|
|
13220
13440
|
detectLocalConventions: () => detectLocalConventions
|
|
13221
13441
|
});
|
|
13222
|
-
import { dirname as
|
|
13442
|
+
import { dirname as dirname11 } from "path";
|
|
13223
13443
|
async function detectLocalConventions(db) {
|
|
13224
13444
|
const start = Date.now();
|
|
13225
13445
|
const entities = await queryAllEntities(db);
|
|
@@ -13364,7 +13584,7 @@ function detectFileStructurePatterns(entities) {
|
|
|
13364
13584
|
const conventions = [];
|
|
13365
13585
|
const byDir = /* @__PURE__ */ new Map();
|
|
13366
13586
|
for (const e of entities) {
|
|
13367
|
-
const dir =
|
|
13587
|
+
const dir = dirname11(e.file_path);
|
|
13368
13588
|
const existing = byDir.get(dir);
|
|
13369
13589
|
if (existing) {
|
|
13370
13590
|
existing.push(e);
|
|
@@ -13394,8 +13614,8 @@ function detectFileStructurePatterns(entities) {
|
|
|
13394
13614
|
(e) => e.file_path.endsWith("/index.ts") || e.file_path.endsWith("/index.js") || e.file_path === "index.ts" || e.file_path === "index.js"
|
|
13395
13615
|
);
|
|
13396
13616
|
if (indexFiles.length >= MIN_SAMPLE_SIZE) {
|
|
13397
|
-
const dirsWithIndex = new Set(indexFiles.map((e) =>
|
|
13398
|
-
const totalDirs = new Set(entities.map((e) =>
|
|
13617
|
+
const dirsWithIndex = new Set(indexFiles.map((e) => dirname11(e.file_path)));
|
|
13618
|
+
const totalDirs = new Set(entities.map((e) => dirname11(e.file_path))).size;
|
|
13399
13619
|
if (totalDirs > 0) {
|
|
13400
13620
|
const adherence = dirsWithIndex.size / totalDirs;
|
|
13401
13621
|
if (adherence >= 0.3) {
|
|
@@ -13484,8 +13704,8 @@ function detectImportDirectionPatterns(entities, edges, communities) {
|
|
|
13484
13704
|
const fromEntity = entities.find((e) => e.key === edge.from_key);
|
|
13485
13705
|
const toEntity = entities.find((e) => e.key === edge.to_key);
|
|
13486
13706
|
if (!fromEntity || !toEntity) continue;
|
|
13487
|
-
const fromDir =
|
|
13488
|
-
const toDir =
|
|
13707
|
+
const fromDir = dirname11(fromEntity.file_path);
|
|
13708
|
+
const toDir = dirname11(toEntity.file_path);
|
|
13489
13709
|
if (fromDir === toDir) continue;
|
|
13490
13710
|
const fromStats = dirImports.get(fromDir) ?? { inbound: 0, outbound: 0 };
|
|
13491
13711
|
fromStats.outbound++;
|
|
@@ -13512,8 +13732,8 @@ function detectImportDirectionPatterns(entities, edges, communities) {
|
|
|
13512
13732
|
const fromEntity = entities.find((e) => e.key === edge.from_key);
|
|
13513
13733
|
const toEntity = entities.find((e) => e.key === edge.to_key);
|
|
13514
13734
|
if (!fromEntity || !toEntity) continue;
|
|
13515
|
-
const fromDir =
|
|
13516
|
-
const toDir =
|
|
13735
|
+
const fromDir = dirname11(fromEntity.file_path);
|
|
13736
|
+
const toDir = dirname11(toEntity.file_path);
|
|
13517
13737
|
if (fromDir === toDir) continue;
|
|
13518
13738
|
const pairKey2 = `${fromDir}->${toDir}`;
|
|
13519
13739
|
layerPairs.set(pairKey2, (layerPairs.get(pairKey2) ?? 0) + 1);
|
|
@@ -13738,7 +13958,7 @@ __export(local_indexer_exports, {
|
|
|
13738
13958
|
runCommunityDetection: () => runCommunityDetection,
|
|
13739
13959
|
runConventionDetection: () => runConventionDetection
|
|
13740
13960
|
});
|
|
13741
|
-
import { readFileSync as
|
|
13961
|
+
import { readFileSync as readFileSync31, readdirSync as readdirSync8, statSync as statSync8 } from "fs";
|
|
13742
13962
|
import { basename as basename3, extname as extname2, join as join38, relative as relative2 } from "path";
|
|
13743
13963
|
function isExcludedPath(relPath) {
|
|
13744
13964
|
for (const prefix of EXCLUDED_PATH_PREFIXES) {
|
|
@@ -13772,7 +13992,7 @@ async function indexLocalProject(projectRoot, graphStore, repoId, opts) {
|
|
|
13772
13992
|
});
|
|
13773
13993
|
let content;
|
|
13774
13994
|
try {
|
|
13775
|
-
content =
|
|
13995
|
+
content = readFileSync31(absPath, "utf-8");
|
|
13776
13996
|
} catch {
|
|
13777
13997
|
filesProcessed++;
|
|
13778
13998
|
continue;
|
|
@@ -13959,7 +14179,7 @@ async function reindexFile(projectRoot, filePath, graphStore, repoId) {
|
|
|
13959
14179
|
await removeFileEntities(graphStore, relPath);
|
|
13960
14180
|
let content;
|
|
13961
14181
|
try {
|
|
13962
|
-
content =
|
|
14182
|
+
content = readFileSync31(absPath, "utf-8");
|
|
13963
14183
|
} catch {
|
|
13964
14184
|
return { entities: 0, edges: 0 };
|
|
13965
14185
|
}
|
|
@@ -14153,7 +14373,7 @@ function resolveImportSourceToFile(importSource, sourceFile, projectFiles) {
|
|
|
14153
14373
|
for (let i = Math.max(0, segments.length - 3); i < segments.length; i++) {
|
|
14154
14374
|
const suffix = segments.slice(i).join("/");
|
|
14155
14375
|
for (const fp of projectFiles) {
|
|
14156
|
-
if (fp.endsWith(".go") && fp.includes(suffix
|
|
14376
|
+
if (fp.endsWith(".go") && fp.includes(`${suffix}/`)) {
|
|
14157
14377
|
return fp;
|
|
14158
14378
|
}
|
|
14159
14379
|
const dir = fp.substring(0, fp.lastIndexOf("/"));
|
|
@@ -14184,9 +14404,7 @@ function resolveImportSourceToFile(importSource, sourceFile, projectFiles) {
|
|
|
14184
14404
|
function resolveRelativeImport(importSource, sourceFile, projectFiles) {
|
|
14185
14405
|
const sourceDir = sourceFile.substring(0, sourceFile.lastIndexOf("/"));
|
|
14186
14406
|
const candidates = [];
|
|
14187
|
-
const parts =
|
|
14188
|
-
"/"
|
|
14189
|
-
);
|
|
14407
|
+
const parts = `${sourceDir}/${importSource.replace(/^\.\//, "")}`.split("/");
|
|
14190
14408
|
const resolved = [];
|
|
14191
14409
|
for (const p of parts) {
|
|
14192
14410
|
if (p === "..") resolved.pop();
|
|
@@ -14843,21 +15061,25 @@ function extractDocTokens(absPath, relPath) {
|
|
|
14843
15061
|
}
|
|
14844
15062
|
const ext = extname2(absPath).toLowerCase();
|
|
14845
15063
|
try {
|
|
14846
|
-
const content =
|
|
15064
|
+
const content = readFileSync31(absPath, "utf-8").slice(0, DOC_READ_LIMIT);
|
|
14847
15065
|
const pattern = DOC_TOKEN_PATTERNS[ext];
|
|
14848
15066
|
if (pattern) {
|
|
14849
15067
|
pattern.lastIndex = 0;
|
|
14850
15068
|
let match;
|
|
14851
|
-
|
|
15069
|
+
match = pattern.exec(content);
|
|
15070
|
+
while (match !== null) {
|
|
14852
15071
|
if (match[1]) for (const t of tokenize(match[1])) tokens.add(t);
|
|
14853
15072
|
if (match[2]) for (const t of tokenize(match[2])) tokens.add(t);
|
|
15073
|
+
match = pattern.exec(content);
|
|
14854
15074
|
}
|
|
14855
15075
|
}
|
|
14856
15076
|
if (ext === ".yaml" || ext === ".yml") {
|
|
14857
15077
|
const yamlKeyRegex = /^([a-zA-Z_][\w-]*)\s*:/gm;
|
|
14858
15078
|
let match;
|
|
14859
|
-
|
|
15079
|
+
match = yamlKeyRegex.exec(content);
|
|
15080
|
+
while (match !== null) {
|
|
14860
15081
|
if (match[1]) for (const t of tokenize(match[1])) tokens.add(t);
|
|
15082
|
+
match = yamlKeyRegex.exec(content);
|
|
14861
15083
|
}
|
|
14862
15084
|
}
|
|
14863
15085
|
} catch {
|
|
@@ -14910,12 +15132,12 @@ var INDEXABLE_EXTENSIONS, EXCLUDED_DIRS2, EXCLUDED_PATH_PREFIXES, MAX_FILE_SIZE,
|
|
|
14910
15132
|
var init_local_indexer = __esm({
|
|
14911
15133
|
"src/intelligence/local-indexer.ts"() {
|
|
14912
15134
|
"use strict";
|
|
15135
|
+
init_format_error();
|
|
14913
15136
|
init_ast_extractor();
|
|
14914
15137
|
init_community_detection();
|
|
14915
15138
|
init_git_cochange();
|
|
14916
15139
|
init_orchestrator();
|
|
14917
15140
|
init_test_detector();
|
|
14918
|
-
init_format_error();
|
|
14919
15141
|
init_local_convention_detector();
|
|
14920
15142
|
init_local_rule_generator();
|
|
14921
15143
|
init_local_snapshot();
|
|
@@ -15586,14 +15808,14 @@ __export(resolver_exports, {
|
|
|
15586
15808
|
import {
|
|
15587
15809
|
existsSync as existsSync39,
|
|
15588
15810
|
mkdirSync as mkdirSync27,
|
|
15589
|
-
readFileSync as
|
|
15811
|
+
readFileSync as readFileSync34,
|
|
15590
15812
|
readdirSync as readdirSync9,
|
|
15591
15813
|
rmSync,
|
|
15592
15814
|
unlinkSync as unlinkSync10,
|
|
15593
15815
|
writeFileSync as writeFileSync21
|
|
15594
15816
|
} from "fs";
|
|
15595
15817
|
import { homedir as homedir15 } from "os";
|
|
15596
|
-
import { dirname as
|
|
15818
|
+
import { dirname as dirname13, join as join43 } from "path";
|
|
15597
15819
|
function getSkillDir(ide, cwd) {
|
|
15598
15820
|
switch (ide) {
|
|
15599
15821
|
case "claude-code":
|
|
@@ -15826,11 +16048,9 @@ globs:
|
|
|
15826
16048
|
${globs.map((g) => ` - ${g}`).join("\n")}`;
|
|
15827
16049
|
}
|
|
15828
16050
|
if (triggerType === "manual") {
|
|
15829
|
-
frontmatter +=
|
|
15830
|
-
user_invocable: true`;
|
|
16051
|
+
frontmatter += "\nuser_invocable: true";
|
|
15831
16052
|
}
|
|
15832
|
-
frontmatter +=
|
|
15833
|
-
---`;
|
|
16053
|
+
frontmatter += "\n---";
|
|
15834
16054
|
return `${frontmatter}
|
|
15835
16055
|
|
|
15836
16056
|
${skill.content}
|
|
@@ -15873,7 +16093,7 @@ function scanSkillDirectory(dir) {
|
|
|
15873
16093
|
const files = readdirSync9(dir).filter((f) => f.endsWith(".md"));
|
|
15874
16094
|
for (const file of files) {
|
|
15875
16095
|
try {
|
|
15876
|
-
const raw =
|
|
16096
|
+
const raw = readFileSync34(join43(dir, file), "utf-8");
|
|
15877
16097
|
const { meta, content } = parseFrontmatter(raw);
|
|
15878
16098
|
const name = meta.name ?? file.replace(/\.md$/, "");
|
|
15879
16099
|
skills.push({
|
|
@@ -15967,7 +16187,7 @@ function removeInstalledSkills(ide, cwd) {
|
|
|
15967
16187
|
for (const skill of skills) {
|
|
15968
16188
|
try {
|
|
15969
16189
|
if (dirPerSkill) {
|
|
15970
|
-
rmSync(
|
|
16190
|
+
rmSync(dirname13(skill.path), { recursive: true, force: true });
|
|
15971
16191
|
} else {
|
|
15972
16192
|
unlinkSync10(skill.path);
|
|
15973
16193
|
}
|
|
@@ -15989,7 +16209,7 @@ var correction_detector_exports = {};
|
|
|
15989
16209
|
__export(correction_detector_exports, {
|
|
15990
16210
|
detectCorrections: () => detectCorrections
|
|
15991
16211
|
});
|
|
15992
|
-
import { existsSync as existsSync41, readFileSync as
|
|
16212
|
+
import { existsSync as existsSync41, readFileSync as readFileSync36 } from "fs";
|
|
15993
16213
|
function detectCorrections(ledgerPath, options) {
|
|
15994
16214
|
const MIN_CONFIDENCE = options?.min_confidence ?? 0.6;
|
|
15995
16215
|
const CORRECTION_WINDOW = options?.correction_window_ms ?? 6e4;
|
|
@@ -16016,7 +16236,7 @@ function readLedgerEntries(ledgerPath, sinceDays) {
|
|
|
16016
16236
|
const cutoff = Date.now() - sinceDays * 24 * 60 * 60 * 1e3;
|
|
16017
16237
|
const entries = [];
|
|
16018
16238
|
try {
|
|
16019
|
-
const content =
|
|
16239
|
+
const content = readFileSync36(ledgerPath, "utf-8");
|
|
16020
16240
|
const lines = content.split("\n");
|
|
16021
16241
|
for (const line of lines) {
|
|
16022
16242
|
if (line.trim().length === 0) continue;
|
|
@@ -16223,7 +16443,7 @@ import {
|
|
|
16223
16443
|
appendFileSync as appendFileSync5,
|
|
16224
16444
|
existsSync as existsSync44,
|
|
16225
16445
|
mkdirSync as mkdirSync29,
|
|
16226
|
-
readFileSync as
|
|
16446
|
+
readFileSync as readFileSync38,
|
|
16227
16447
|
writeFileSync as writeFileSync23
|
|
16228
16448
|
} from "fs";
|
|
16229
16449
|
import { join as join47 } from "path";
|
|
@@ -16364,7 +16584,7 @@ function readBranchCounter(unerrDir) {
|
|
|
16364
16584
|
const contextPath = join47(unerrDir, "ledger", "branch_context.json");
|
|
16365
16585
|
if (!existsSync44(contextPath)) return 1;
|
|
16366
16586
|
try {
|
|
16367
|
-
const data = JSON.parse(
|
|
16587
|
+
const data = JSON.parse(readFileSync38(contextPath, "utf-8"));
|
|
16368
16588
|
return data.timeline_branch ?? 1;
|
|
16369
16589
|
} catch {
|
|
16370
16590
|
return 1;
|
|
@@ -16379,7 +16599,7 @@ function incrementBranchCounter(unerrDir) {
|
|
|
16379
16599
|
let data = {};
|
|
16380
16600
|
if (existsSync44(contextPath)) {
|
|
16381
16601
|
try {
|
|
16382
|
-
data = JSON.parse(
|
|
16602
|
+
data = JSON.parse(readFileSync38(contextPath, "utf-8"));
|
|
16383
16603
|
} catch {
|
|
16384
16604
|
}
|
|
16385
16605
|
}
|
|
@@ -16400,7 +16620,7 @@ function markEntriesReverted(unerrDir, entryIds) {
|
|
|
16400
16620
|
let existing = [];
|
|
16401
16621
|
if (existsSync44(revertedPath)) {
|
|
16402
16622
|
try {
|
|
16403
|
-
existing = JSON.parse(
|
|
16623
|
+
existing = JSON.parse(readFileSync38(revertedPath, "utf-8"));
|
|
16404
16624
|
} catch {
|
|
16405
16625
|
}
|
|
16406
16626
|
}
|
|
@@ -16631,7 +16851,7 @@ import {
|
|
|
16631
16851
|
appendFileSync as appendFileSync6,
|
|
16632
16852
|
existsSync as existsSync45,
|
|
16633
16853
|
mkdirSync as mkdirSync30,
|
|
16634
|
-
readFileSync as
|
|
16854
|
+
readFileSync as readFileSync39,
|
|
16635
16855
|
writeFileSync as writeFileSync24
|
|
16636
16856
|
} from "fs";
|
|
16637
16857
|
import { join as join48 } from "path";
|
|
@@ -16798,7 +17018,7 @@ var init_shadow_ledger = __esm({
|
|
|
16798
17018
|
readAllEntries() {
|
|
16799
17019
|
if (!existsSync45(this.filePath)) return [];
|
|
16800
17020
|
try {
|
|
16801
|
-
const content =
|
|
17021
|
+
const content = readFileSync39(this.filePath, "utf-8");
|
|
16802
17022
|
const lines = content.split("\n").filter((l) => l.trim().length > 0);
|
|
16803
17023
|
return lines.map((line) => JSON.parse(line));
|
|
16804
17024
|
} catch {
|
|
@@ -16837,7 +17057,7 @@ var init_shadow_ledger = __esm({
|
|
|
16837
17057
|
recoverFile() {
|
|
16838
17058
|
if (!existsSync45(this.filePath)) return;
|
|
16839
17059
|
try {
|
|
16840
|
-
const content =
|
|
17060
|
+
const content = readFileSync39(this.filePath, "utf-8");
|
|
16841
17061
|
const lines = content.split("\n");
|
|
16842
17062
|
const validLines = [];
|
|
16843
17063
|
for (const line of lines) {
|
|
@@ -16870,7 +17090,7 @@ var init_shadow_ledger = __esm({
|
|
|
16870
17090
|
loadRecentEntries() {
|
|
16871
17091
|
if (!existsSync45(this.filePath)) return;
|
|
16872
17092
|
try {
|
|
16873
|
-
const content =
|
|
17093
|
+
const content = readFileSync39(this.filePath, "utf-8");
|
|
16874
17094
|
const lines = content.split("\n").filter((l) => l.trim().length > 0);
|
|
16875
17095
|
const start = Math.max(0, lines.length - MAX_BUFFER_SIZE);
|
|
16876
17096
|
for (let i = start; i < lines.length; i++) {
|
|
@@ -16900,7 +17120,7 @@ var init_shadow_ledger = __esm({
|
|
|
16900
17120
|
countEntries() {
|
|
16901
17121
|
if (!existsSync45(this.filePath)) return 0;
|
|
16902
17122
|
try {
|
|
16903
|
-
const content =
|
|
17123
|
+
const content = readFileSync39(this.filePath, "utf-8");
|
|
16904
17124
|
return content.split("\n").filter((l) => l.trim().length > 0).length;
|
|
16905
17125
|
} catch {
|
|
16906
17126
|
return 0;
|
|
@@ -16925,7 +17145,7 @@ __export(timeline_fork_exports, {
|
|
|
16925
17145
|
resetTimelineForks: () => resetTimelineForks,
|
|
16926
17146
|
wasForkPoint: () => wasForkPoint
|
|
16927
17147
|
});
|
|
16928
|
-
import { existsSync as existsSync46, mkdirSync as mkdirSync31, readFileSync as
|
|
17148
|
+
import { existsSync as existsSync46, mkdirSync as mkdirSync31, readFileSync as readFileSync40, writeFileSync as writeFileSync25 } from "fs";
|
|
16929
17149
|
import { join as join49 } from "path";
|
|
16930
17150
|
function createTimelineFork(snapshotId, abandonedEntities, prompts, reason, unerrDir) {
|
|
16931
17151
|
const state = unerrDir ? loadState(unerrDir) : { activeTimeline: inMemoryTimeline, forks: [] };
|
|
@@ -17066,7 +17286,7 @@ function loadState(unerrDir) {
|
|
|
17066
17286
|
return { activeTimeline: 0, forks: [] };
|
|
17067
17287
|
}
|
|
17068
17288
|
try {
|
|
17069
|
-
const raw =
|
|
17289
|
+
const raw = readFileSync40(path7, "utf-8");
|
|
17070
17290
|
const parsed = JSON.parse(raw);
|
|
17071
17291
|
return {
|
|
17072
17292
|
activeTimeline: typeof parsed.activeTimeline === "number" ? parsed.activeTimeline : 0,
|
|
@@ -17142,9 +17362,9 @@ function createEmptyAllTime() {
|
|
|
17142
17362
|
function loadStats() {
|
|
17143
17363
|
const currentWeek = getWeekStart();
|
|
17144
17364
|
try {
|
|
17145
|
-
const { readFileSync:
|
|
17365
|
+
const { readFileSync: readFileSync68 } = __require("fs");
|
|
17146
17366
|
const raw = JSON.parse(
|
|
17147
|
-
|
|
17367
|
+
readFileSync68(getStatsPath(), "utf-8")
|
|
17148
17368
|
);
|
|
17149
17369
|
if (raw.version !== 1) {
|
|
17150
17370
|
return {
|
|
@@ -17271,7 +17491,7 @@ __export(branch_context_exports, {
|
|
|
17271
17491
|
getHeadSha: () => getHeadSha2,
|
|
17272
17492
|
startBranchPoller: () => startBranchPoller
|
|
17273
17493
|
});
|
|
17274
|
-
import { existsSync as existsSync47, readFileSync as
|
|
17494
|
+
import { existsSync as existsSync47, readFileSync as readFileSync41 } from "fs";
|
|
17275
17495
|
import { join as join51 } from "path";
|
|
17276
17496
|
async function computeBranchContext(cwd) {
|
|
17277
17497
|
const dir = cwd ?? process.cwd();
|
|
@@ -17338,7 +17558,7 @@ function getCurrentBranch2(cwd) {
|
|
|
17338
17558
|
const headPath = join51(gitDir, "HEAD");
|
|
17339
17559
|
if (!existsSync47(headPath)) return null;
|
|
17340
17560
|
try {
|
|
17341
|
-
const content =
|
|
17561
|
+
const content = readFileSync41(headPath, "utf-8").trim();
|
|
17342
17562
|
if (content.startsWith("ref: refs/heads/")) {
|
|
17343
17563
|
return content.slice("ref: refs/heads/".length);
|
|
17344
17564
|
}
|
|
@@ -17861,9 +18081,9 @@ function getCumulativePath() {
|
|
|
17861
18081
|
function loadCumulativeStats() {
|
|
17862
18082
|
const currentWeek = getWeekStart2();
|
|
17863
18083
|
try {
|
|
17864
|
-
const { readFileSync:
|
|
18084
|
+
const { readFileSync: readFileSync68 } = __require("fs");
|
|
17865
18085
|
const raw = JSON.parse(
|
|
17866
|
-
|
|
18086
|
+
readFileSync68(getCumulativePath(), "utf-8")
|
|
17867
18087
|
);
|
|
17868
18088
|
if (raw.weekStart !== currentWeek) {
|
|
17869
18089
|
return {
|
|
@@ -17924,9 +18144,9 @@ function createEmptyCumulativeLocal(weekStart) {
|
|
|
17924
18144
|
function loadCumulativeLocalStats() {
|
|
17925
18145
|
const currentWeek = getWeekStart2();
|
|
17926
18146
|
try {
|
|
17927
|
-
const { readFileSync:
|
|
18147
|
+
const { readFileSync: readFileSync68 } = __require("fs");
|
|
17928
18148
|
const raw = JSON.parse(
|
|
17929
|
-
|
|
18149
|
+
readFileSync68(getCumulativeLocalPath(), "utf-8")
|
|
17930
18150
|
);
|
|
17931
18151
|
if (raw.weekStartDate !== currentWeek) {
|
|
17932
18152
|
return createEmptyCumulativeLocal(currentWeek);
|
|
@@ -18524,6 +18744,63 @@ var init_render = __esm({
|
|
|
18524
18744
|
}
|
|
18525
18745
|
});
|
|
18526
18746
|
|
|
18747
|
+
// src/proxy/arg-validator.ts
|
|
18748
|
+
function normalizeArgAliases(toolDef, args) {
|
|
18749
|
+
const props = toolDef.inputSchema.properties;
|
|
18750
|
+
for (const [canonical, aliases] of Object.entries(ALIAS_MAP)) {
|
|
18751
|
+
if (!(canonical in props)) continue;
|
|
18752
|
+
if (args[canonical] !== void 0 && args[canonical] !== null && args[canonical] !== "") {
|
|
18753
|
+
continue;
|
|
18754
|
+
}
|
|
18755
|
+
for (const alias of aliases) {
|
|
18756
|
+
const v = args[alias];
|
|
18757
|
+
if (typeof v === "string" && v.trim() !== "") {
|
|
18758
|
+
args[canonical] = v;
|
|
18759
|
+
break;
|
|
18760
|
+
}
|
|
18761
|
+
if (typeof v === "number" || typeof v === "boolean") {
|
|
18762
|
+
args[canonical] = v;
|
|
18763
|
+
break;
|
|
18764
|
+
}
|
|
18765
|
+
}
|
|
18766
|
+
}
|
|
18767
|
+
}
|
|
18768
|
+
function validateRequiredArgs(toolDef, args) {
|
|
18769
|
+
const required = toolDef.inputSchema.required ?? [];
|
|
18770
|
+
if (required.length === 0) return null;
|
|
18771
|
+
const missing = required.filter((field) => {
|
|
18772
|
+
const v = args[field];
|
|
18773
|
+
if (v === void 0 || v === null) return true;
|
|
18774
|
+
if (typeof v === "string" && v.trim() === "") return true;
|
|
18775
|
+
return false;
|
|
18776
|
+
});
|
|
18777
|
+
if (missing.length === 0) return null;
|
|
18778
|
+
const props = toolDef.inputSchema.properties;
|
|
18779
|
+
const details = missing.map((m) => {
|
|
18780
|
+
const desc = props[m]?.description?.trim();
|
|
18781
|
+
return desc ? `${m}: ${desc}` : `${m}: required`;
|
|
18782
|
+
}).join("; ");
|
|
18783
|
+
return {
|
|
18784
|
+
error: `${toolDef.name}: missing required parameter(s): ${missing.join(", ")}`,
|
|
18785
|
+
required: missing,
|
|
18786
|
+
details
|
|
18787
|
+
};
|
|
18788
|
+
}
|
|
18789
|
+
function aliasAndValidate(toolDef, args) {
|
|
18790
|
+
normalizeArgAliases(toolDef, args);
|
|
18791
|
+
return validateRequiredArgs(toolDef, args);
|
|
18792
|
+
}
|
|
18793
|
+
var ALIAS_MAP;
|
|
18794
|
+
var init_arg_validator = __esm({
|
|
18795
|
+
"src/proxy/arg-validator.ts"() {
|
|
18796
|
+
"use strict";
|
|
18797
|
+
ALIAS_MAP = {
|
|
18798
|
+
key: ["entity_name", "entity"],
|
|
18799
|
+
file_path: ["file", "path"]
|
|
18800
|
+
};
|
|
18801
|
+
}
|
|
18802
|
+
});
|
|
18803
|
+
|
|
18527
18804
|
// src/proxy/pid-lock.ts
|
|
18528
18805
|
var pid_lock_exports = {};
|
|
18529
18806
|
__export(pid_lock_exports, {
|
|
@@ -18532,7 +18809,7 @@ __export(pid_lock_exports, {
|
|
|
18532
18809
|
import {
|
|
18533
18810
|
existsSync as existsSync51,
|
|
18534
18811
|
mkdirSync as mkdirSync32,
|
|
18535
|
-
readFileSync as
|
|
18812
|
+
readFileSync as readFileSync45,
|
|
18536
18813
|
unlinkSync as unlinkSync12,
|
|
18537
18814
|
writeFileSync as writeFileSync27
|
|
18538
18815
|
} from "fs";
|
|
@@ -18619,7 +18896,7 @@ var init_pid_lock = __esm({
|
|
|
18619
18896
|
}
|
|
18620
18897
|
if (existsSync51(this.pidPath)) {
|
|
18621
18898
|
try {
|
|
18622
|
-
const raw =
|
|
18899
|
+
const raw = readFileSync45(this.pidPath, "utf-8").trim();
|
|
18623
18900
|
const pidData = parsePidFile(raw);
|
|
18624
18901
|
if (pidData && isProcessAlive2(pidData.pid)) {
|
|
18625
18902
|
if (pidData.healthPort) {
|
|
@@ -18682,7 +18959,7 @@ var init_pid_lock = __esm({
|
|
|
18682
18959
|
writeFileSync27(this.pidPath, JSON.stringify(data), "utf-8");
|
|
18683
18960
|
}
|
|
18684
18961
|
async startHealthServer() {
|
|
18685
|
-
return new Promise((
|
|
18962
|
+
return new Promise((resolve9) => {
|
|
18686
18963
|
this.healthServer = createServer2((req, res) => {
|
|
18687
18964
|
if (req.url === "/health" && req.method === "GET") {
|
|
18688
18965
|
const uptimeS = Math.round(
|
|
@@ -18706,7 +18983,7 @@ var init_pid_lock = __esm({
|
|
|
18706
18983
|
this.healthServer.listen(0, "127.0.0.1", () => {
|
|
18707
18984
|
const addr = this.healthServer?.address();
|
|
18708
18985
|
this.healthPort = typeof addr === "object" && addr ? addr.port : 0;
|
|
18709
|
-
|
|
18986
|
+
resolve9();
|
|
18710
18987
|
});
|
|
18711
18988
|
this.healthServer.unref();
|
|
18712
18989
|
});
|
|
@@ -18725,7 +19002,7 @@ var init_pid_lock = __esm({
|
|
|
18725
19002
|
}
|
|
18726
19003
|
try {
|
|
18727
19004
|
if (existsSync51(this.pidPath)) {
|
|
18728
|
-
const raw =
|
|
19005
|
+
const raw = readFileSync45(this.pidPath, "utf-8").trim();
|
|
18729
19006
|
const data = parsePidFile(raw);
|
|
18730
19007
|
if (data && data.pid === process.pid) {
|
|
18731
19008
|
unlinkSync12(this.pidPath);
|
|
@@ -18740,7 +19017,7 @@ var init_pid_lock = __esm({
|
|
|
18740
19017
|
isLocked() {
|
|
18741
19018
|
if (!existsSync51(this.pidPath)) return { locked: false };
|
|
18742
19019
|
try {
|
|
18743
|
-
const raw =
|
|
19020
|
+
const raw = readFileSync45(this.pidPath, "utf-8").trim();
|
|
18744
19021
|
const data = parsePidFile(raw);
|
|
18745
19022
|
if (data && isProcessAlive2(data.pid)) {
|
|
18746
19023
|
return { locked: true, pid: data.pid, healthPort: data.healthPort };
|
|
@@ -18757,7 +19034,7 @@ var init_pid_lock = __esm({
|
|
|
18757
19034
|
async probe() {
|
|
18758
19035
|
if (!existsSync51(this.pidPath)) return { alive: false };
|
|
18759
19036
|
try {
|
|
18760
|
-
const raw =
|
|
19037
|
+
const raw = readFileSync45(this.pidPath, "utf-8").trim();
|
|
18761
19038
|
const pidData = parsePidFile(raw);
|
|
18762
19039
|
if (!pidData || !isProcessAlive2(pidData.pid)) return { alive: false };
|
|
18763
19040
|
if (pidData.healthPort) {
|
|
@@ -18776,7 +19053,7 @@ var init_pid_lock = __esm({
|
|
|
18776
19053
|
const pidPath2 = join55(stateDir, PID_FILENAME);
|
|
18777
19054
|
if (!existsSync51(pidPath2)) return null;
|
|
18778
19055
|
try {
|
|
18779
|
-
const raw =
|
|
19056
|
+
const raw = readFileSync45(pidPath2, "utf-8").trim();
|
|
18780
19057
|
const data = parsePidFile(raw);
|
|
18781
19058
|
if (data && isProcessAlive2(data.pid)) return data;
|
|
18782
19059
|
return null;
|
|
@@ -19005,7 +19282,7 @@ var init_deep_link = __esm({
|
|
|
19005
19282
|
});
|
|
19006
19283
|
|
|
19007
19284
|
// src/proxy/startup-renderer.ts
|
|
19008
|
-
import { existsSync as existsSync52, readFileSync as
|
|
19285
|
+
import { existsSync as existsSync52, readFileSync as readFileSync46, writeFileSync as writeFileSync28 } from "fs";
|
|
19009
19286
|
import { join as join56 } from "path";
|
|
19010
19287
|
import React2 from "react";
|
|
19011
19288
|
var StartupRenderer;
|
|
@@ -19120,7 +19397,7 @@ var init_startup_renderer = __esm({
|
|
|
19120
19397
|
);
|
|
19121
19398
|
if (!existsSync52(versionPath)) return true;
|
|
19122
19399
|
try {
|
|
19123
|
-
const data = JSON.parse(
|
|
19400
|
+
const data = JSON.parse(readFileSync46(versionPath, "utf-8"));
|
|
19124
19401
|
return !data.first_boot_shown;
|
|
19125
19402
|
} catch {
|
|
19126
19403
|
return true;
|
|
@@ -19132,7 +19409,7 @@ var init_startup_renderer = __esm({
|
|
|
19132
19409
|
try {
|
|
19133
19410
|
let data = {};
|
|
19134
19411
|
if (existsSync52(versionPath)) {
|
|
19135
|
-
data = JSON.parse(
|
|
19412
|
+
data = JSON.parse(readFileSync46(versionPath, "utf-8"));
|
|
19136
19413
|
}
|
|
19137
19414
|
data.first_boot_shown = true;
|
|
19138
19415
|
writeFileSync28(versionPath, JSON.stringify(data, null, 2));
|
|
@@ -19904,63 +20181,6 @@ var init_tool_definitions = __esm({
|
|
|
19904
20181
|
}
|
|
19905
20182
|
});
|
|
19906
20183
|
|
|
19907
|
-
// src/proxy/arg-validator.ts
|
|
19908
|
-
function normalizeArgAliases(toolDef, args) {
|
|
19909
|
-
const props = toolDef.inputSchema.properties;
|
|
19910
|
-
for (const [canonical, aliases] of Object.entries(ALIAS_MAP)) {
|
|
19911
|
-
if (!(canonical in props)) continue;
|
|
19912
|
-
if (args[canonical] !== void 0 && args[canonical] !== null && args[canonical] !== "") {
|
|
19913
|
-
continue;
|
|
19914
|
-
}
|
|
19915
|
-
for (const alias of aliases) {
|
|
19916
|
-
const v = args[alias];
|
|
19917
|
-
if (typeof v === "string" && v.trim() !== "") {
|
|
19918
|
-
args[canonical] = v;
|
|
19919
|
-
break;
|
|
19920
|
-
}
|
|
19921
|
-
if (typeof v === "number" || typeof v === "boolean") {
|
|
19922
|
-
args[canonical] = v;
|
|
19923
|
-
break;
|
|
19924
|
-
}
|
|
19925
|
-
}
|
|
19926
|
-
}
|
|
19927
|
-
}
|
|
19928
|
-
function validateRequiredArgs(toolDef, args) {
|
|
19929
|
-
const required = toolDef.inputSchema.required ?? [];
|
|
19930
|
-
if (required.length === 0) return null;
|
|
19931
|
-
const missing = required.filter((field) => {
|
|
19932
|
-
const v = args[field];
|
|
19933
|
-
if (v === void 0 || v === null) return true;
|
|
19934
|
-
if (typeof v === "string" && v.trim() === "") return true;
|
|
19935
|
-
return false;
|
|
19936
|
-
});
|
|
19937
|
-
if (missing.length === 0) return null;
|
|
19938
|
-
const props = toolDef.inputSchema.properties;
|
|
19939
|
-
const details = missing.map((m) => {
|
|
19940
|
-
const desc = props[m]?.description?.trim();
|
|
19941
|
-
return desc ? `${m}: ${desc}` : `${m}: required`;
|
|
19942
|
-
}).join("; ");
|
|
19943
|
-
return {
|
|
19944
|
-
error: `${toolDef.name}: missing required parameter(s): ${missing.join(", ")}`,
|
|
19945
|
-
required: missing,
|
|
19946
|
-
details
|
|
19947
|
-
};
|
|
19948
|
-
}
|
|
19949
|
-
function aliasAndValidate(toolDef, args) {
|
|
19950
|
-
normalizeArgAliases(toolDef, args);
|
|
19951
|
-
return validateRequiredArgs(toolDef, args);
|
|
19952
|
-
}
|
|
19953
|
-
var ALIAS_MAP;
|
|
19954
|
-
var init_arg_validator = __esm({
|
|
19955
|
-
"src/proxy/arg-validator.ts"() {
|
|
19956
|
-
"use strict";
|
|
19957
|
-
ALIAS_MAP = {
|
|
19958
|
-
key: ["entity_name", "entity"],
|
|
19959
|
-
file_path: ["file", "path"]
|
|
19960
|
-
};
|
|
19961
|
-
}
|
|
19962
|
-
});
|
|
19963
|
-
|
|
19964
20184
|
// src/utils/mcp-content-json.ts
|
|
19965
20185
|
function stringifyMcpToolJson(value) {
|
|
19966
20186
|
return JSON.stringify(value);
|
|
@@ -20554,7 +20774,7 @@ var init_temporal_facts = __esm({
|
|
|
20554
20774
|
const scopes = [filePath];
|
|
20555
20775
|
const parts = filePath.split("/");
|
|
20556
20776
|
for (let i = parts.length - 1; i > 0; i--) {
|
|
20557
|
-
scopes.push(parts.slice(0, i).join("/")
|
|
20777
|
+
scopes.push(`${parts.slice(0, i).join("/")}/`);
|
|
20558
20778
|
}
|
|
20559
20779
|
scopes.push("project");
|
|
20560
20780
|
return scopes;
|
|
@@ -20735,7 +20955,7 @@ var init_temporal_facts = __esm({
|
|
|
20735
20955
|
filter_subject: subject
|
|
20736
20956
|
}
|
|
20737
20957
|
);
|
|
20738
|
-
return result.rows.length > 0 ? result.rows[0][0] : null;
|
|
20958
|
+
return result.rows.length > 0 ? result.rows[0]?.[0] : null;
|
|
20739
20959
|
}
|
|
20740
20960
|
async getRawFact(factId) {
|
|
20741
20961
|
const result = await this.db.run(
|
|
@@ -20999,7 +21219,7 @@ __export(fact_generator_exports, {
|
|
|
20999
21219
|
generateFromSessionAnalysis: () => generateFromSessionAnalysis,
|
|
21000
21220
|
runFactGenerationPipeline: () => runFactGenerationPipeline
|
|
21001
21221
|
});
|
|
21002
|
-
import { existsSync as existsSync54, readFileSync as
|
|
21222
|
+
import { existsSync as existsSync54, readFileSync as readFileSync47, readdirSync as readdirSync11 } from "fs";
|
|
21003
21223
|
import { join as join58 } from "path";
|
|
21004
21224
|
async function runFactGenerationPipeline(factStore, unerrDir) {
|
|
21005
21225
|
const results = [];
|
|
@@ -21168,7 +21388,7 @@ function loadRecentSessions(unerrDir, limit) {
|
|
|
21168
21388
|
const summaries = [];
|
|
21169
21389
|
for (const file of files) {
|
|
21170
21390
|
try {
|
|
21171
|
-
const content =
|
|
21391
|
+
const content = readFileSync47(join58(sessionsDir, file), "utf-8");
|
|
21172
21392
|
const lines = content.trim().split("\n").filter(Boolean);
|
|
21173
21393
|
const lastLine = lines[lines.length - 1];
|
|
21174
21394
|
if (lastLine) {
|
|
@@ -22279,7 +22499,7 @@ function signalId(s) {
|
|
|
22279
22499
|
return h.toString(16).padStart(8, "0");
|
|
22280
22500
|
}
|
|
22281
22501
|
function computeComposite(actionability, relevance, confidence) {
|
|
22282
|
-
return
|
|
22502
|
+
return actionability ** 1.5 * relevance * confidence;
|
|
22283
22503
|
}
|
|
22284
22504
|
function createSignal(params) {
|
|
22285
22505
|
return {
|
|
@@ -22965,7 +23185,7 @@ var init_response_envelope = __esm({
|
|
|
22965
23185
|
"use strict";
|
|
22966
23186
|
init_token_estimator();
|
|
22967
23187
|
init_signal_dedup();
|
|
22968
|
-
VERSION = "0.1.
|
|
23188
|
+
VERSION = "0.1.2";
|
|
22969
23189
|
updateNotification = null;
|
|
22970
23190
|
WIRE_STRIP_ALWAYS = /* @__PURE__ */ new Set([
|
|
22971
23191
|
"source",
|
|
@@ -23655,7 +23875,7 @@ __export(import_symbols_exports, {
|
|
|
23655
23875
|
parseImportSymbols: () => parseImportSymbols
|
|
23656
23876
|
});
|
|
23657
23877
|
import { promises as fs4 } from "fs";
|
|
23658
|
-
import { isAbsolute, resolve as
|
|
23878
|
+
import { isAbsolute, resolve as resolve6 } from "path";
|
|
23659
23879
|
function parseClause(clause) {
|
|
23660
23880
|
const symbols = [];
|
|
23661
23881
|
const trimmed = clause.trim();
|
|
@@ -23728,7 +23948,7 @@ function parseImportSymbols(source) {
|
|
|
23728
23948
|
return out;
|
|
23729
23949
|
}
|
|
23730
23950
|
async function loadImportSymbols(projectRoot, filePath) {
|
|
23731
|
-
const abs = isAbsolute(filePath) ? filePath :
|
|
23951
|
+
const abs = isAbsolute(filePath) ? filePath : resolve6(projectRoot, filePath);
|
|
23732
23952
|
try {
|
|
23733
23953
|
const text2 = await fs4.readFile(abs, "utf8");
|
|
23734
23954
|
return parseImportSymbols(text2);
|
|
@@ -23751,8 +23971,8 @@ __export(file_outline_exports, {
|
|
|
23751
23971
|
buildFileOutline: () => buildFileOutline,
|
|
23752
23972
|
fileOutlineTool: () => fileOutlineTool
|
|
23753
23973
|
});
|
|
23754
|
-
import { existsSync as existsSync55, readFileSync as
|
|
23755
|
-
import { relative as relative3, resolve as
|
|
23974
|
+
import { existsSync as existsSync55, readFileSync as readFileSync48 } from "fs";
|
|
23975
|
+
import { relative as relative3, resolve as resolve7 } from "path";
|
|
23756
23976
|
function normRisk(rl) {
|
|
23757
23977
|
const x2 = (rl ?? "low").toLowerCase();
|
|
23758
23978
|
if (x2 === "critical") return "critical";
|
|
@@ -23790,12 +24010,12 @@ function detectExportedNames(lines, scanLimit) {
|
|
|
23790
24010
|
const m = /^export\s+(?:default\s+)?(?:async\s+)?(?:function\*?\s+|const\s+|let\s+|var\s+|class\s+|interface\s+|type\s+|enum\s+)(\w+)/.exec(
|
|
23791
24011
|
t
|
|
23792
24012
|
);
|
|
23793
|
-
if (m
|
|
24013
|
+
if (m?.[1]) {
|
|
23794
24014
|
exported.add(m[1]);
|
|
23795
24015
|
continue;
|
|
23796
24016
|
}
|
|
23797
24017
|
const braceMatch = /^export\s*\{([^}]+)\}/.exec(t);
|
|
23798
|
-
if (braceMatch
|
|
24018
|
+
if (braceMatch?.[1]) {
|
|
23799
24019
|
const names = braceMatch[1].split(",").map((n) => {
|
|
23800
24020
|
const asMatch = /(\w+)\s+as\s+\w+/.exec(n.trim());
|
|
23801
24021
|
return asMatch ? asMatch[1] : n.trim();
|
|
@@ -23808,12 +24028,12 @@ function detectExportedNames(lines, scanLimit) {
|
|
|
23808
24028
|
return exported;
|
|
23809
24029
|
}
|
|
23810
24030
|
async function buildFileOutline(params) {
|
|
23811
|
-
const abs =
|
|
24031
|
+
const abs = resolve7(params.cwd, params.filePathArg);
|
|
23812
24032
|
const rel = relative3(params.cwd, abs).replace(/\\/g, "/") || params.filePathArg;
|
|
23813
24033
|
if (!existsSync55(abs)) {
|
|
23814
24034
|
throw new Error(`File not found: ${abs}`);
|
|
23815
24035
|
}
|
|
23816
|
-
const raw =
|
|
24036
|
+
const raw = readFileSync48(abs);
|
|
23817
24037
|
const sampleEnd = Math.min(raw.length, 8192);
|
|
23818
24038
|
for (let i = 0; i < sampleEnd; i++) {
|
|
23819
24039
|
if (raw[i] === 0) {
|
|
@@ -23970,8 +24190,8 @@ __export(file_read_protocol_exports, {
|
|
|
23970
24190
|
runFileReadForRouter: () => runFileReadForRouter,
|
|
23971
24191
|
runFileReadTool: () => runFileReadTool
|
|
23972
24192
|
});
|
|
23973
|
-
import { existsSync as existsSync56, readFileSync as
|
|
23974
|
-
import { relative as relative4, resolve as
|
|
24193
|
+
import { existsSync as existsSync56, readFileSync as readFileSync49 } from "fs";
|
|
24194
|
+
import { relative as relative4, resolve as resolve8 } from "path";
|
|
23975
24195
|
function isGeneratedPath(rel) {
|
|
23976
24196
|
return /(?:^|\/)node_modules\/|(?:^|\/)dist\/|\/\.next\/|\.generated\./.test(
|
|
23977
24197
|
rel
|
|
@@ -24010,7 +24230,6 @@ function rankEntityMatches(entities, query) {
|
|
|
24010
24230
|
score: 40 + specificity * 20,
|
|
24011
24231
|
matchType: "substring"
|
|
24012
24232
|
});
|
|
24013
|
-
continue;
|
|
24014
24233
|
}
|
|
24015
24234
|
}
|
|
24016
24235
|
return results.sort((a, b) => b.score - a.score);
|
|
@@ -24043,13 +24262,13 @@ async function runFileReadForRouter(args, ctx) {
|
|
|
24043
24262
|
const budgetLines = Math.floor(
|
|
24044
24263
|
tokenBudget * CHARS_PER_TOKEN4 / AVG_CHARS_PER_LINE
|
|
24045
24264
|
);
|
|
24046
|
-
const abs =
|
|
24265
|
+
const abs = resolve8(ctx.cwd, filePathArg);
|
|
24047
24266
|
const rel = relative4(ctx.cwd, abs).replace(/\\/g, "/") || filePathArg;
|
|
24048
24267
|
const isOutOfProject = rel.startsWith("..");
|
|
24049
24268
|
if (!existsSync56(abs)) {
|
|
24050
24269
|
return { content: { error: `File not found: ${abs}` } };
|
|
24051
24270
|
}
|
|
24052
|
-
const raw =
|
|
24271
|
+
const raw = readFileSync49(abs);
|
|
24053
24272
|
const sampleEnd = Math.min(raw.length, 8192);
|
|
24054
24273
|
for (let i = 0; i < sampleEnd; i++) {
|
|
24055
24274
|
if (raw[i] === 0) {
|
|
@@ -24118,8 +24337,9 @@ async function runFileReadForRouter(args, ctx) {
|
|
|
24118
24337
|
]).catch(() => []);
|
|
24119
24338
|
if (entities.length > 0) {
|
|
24120
24339
|
const ranked = rankEntityMatches(entities, entityName);
|
|
24121
|
-
|
|
24122
|
-
|
|
24340
|
+
const topRanked = ranked[0];
|
|
24341
|
+
if (ranked.length > 0 && topRanked && topRanked.score >= 70) {
|
|
24342
|
+
const match = topRanked.entity;
|
|
24123
24343
|
if (match.start_line >= 1 && match.start_line <= totalLines) {
|
|
24124
24344
|
const start = Math.max(1, match.start_line - ENTITY_CONTEXT);
|
|
24125
24345
|
const endLine = (match.end_line ?? 0) > match.start_line ? match.end_line : match.start_line + match.body.split("\n").length - 1;
|
|
@@ -24131,8 +24351,8 @@ async function runFileReadForRouter(args, ctx) {
|
|
|
24131
24351
|
entityMatchInfo = {
|
|
24132
24352
|
matched: true,
|
|
24133
24353
|
name: match.name,
|
|
24134
|
-
score:
|
|
24135
|
-
matchType:
|
|
24354
|
+
score: topRanked.score,
|
|
24355
|
+
matchType: topRanked.matchType
|
|
24136
24356
|
};
|
|
24137
24357
|
}
|
|
24138
24358
|
} else if (ranked.length > 0) {
|
|
@@ -24158,8 +24378,9 @@ async function runFileReadForRouter(args, ctx) {
|
|
|
24158
24378
|
body: lines.slice(e.line_start - 1, e.line_end).join("\n")
|
|
24159
24379
|
}));
|
|
24160
24380
|
const ranked = rankEntityMatches(astEntities, entityName);
|
|
24161
|
-
|
|
24162
|
-
|
|
24381
|
+
const topAstRank = ranked[0];
|
|
24382
|
+
if (topAstRank && topAstRank.score >= 70 && topAstRank.entity) {
|
|
24383
|
+
const match = topAstRank.entity;
|
|
24163
24384
|
if (match.start_line >= 1 && match.start_line <= totalLines) {
|
|
24164
24385
|
const start = Math.max(1, match.start_line - ENTITY_CONTEXT);
|
|
24165
24386
|
const endLine = match.start_line + match.body.split("\n").length - 1;
|
|
@@ -24170,8 +24391,8 @@ async function runFileReadForRouter(args, ctx) {
|
|
|
24170
24391
|
entityMatchInfo = {
|
|
24171
24392
|
matched: true,
|
|
24172
24393
|
name: match.name,
|
|
24173
|
-
score:
|
|
24174
|
-
matchType:
|
|
24394
|
+
score: topAstRank.score,
|
|
24395
|
+
matchType: topAstRank.matchType
|
|
24175
24396
|
};
|
|
24176
24397
|
}
|
|
24177
24398
|
} else if (ranked.length > 0 && !entityMatchInfo) {
|
|
@@ -25827,7 +26048,7 @@ var init_query_router = __esm({
|
|
|
25827
26048
|
const hiddenFile = topHidden[0];
|
|
25828
26049
|
if (hiddenFile) {
|
|
25829
26050
|
const otherFile = hiddenFile.file_a === filePath ? hiddenFile.file_b : hiddenFile.file_a;
|
|
25830
|
-
context.co_changes =
|
|
26051
|
+
context.co_changes = `${context.co_changes ? `${context.co_changes}. ` : ""}Hidden dependency: ${otherFile} (${hiddenFile.evidence})`;
|
|
25831
26052
|
hasContext = true;
|
|
25832
26053
|
}
|
|
25833
26054
|
}
|
|
@@ -26193,9 +26414,13 @@ var init_query_router = __esm({
|
|
|
26193
26414
|
const filePathPattern = /(?:^|\s)([\w/.]+\.[a-z]{1,4})(?:\s|:|$)/gm;
|
|
26194
26415
|
const seen = /* @__PURE__ */ new Set();
|
|
26195
26416
|
let match;
|
|
26196
|
-
|
|
26417
|
+
match = filePathPattern.exec(text2);
|
|
26418
|
+
while (match !== null) {
|
|
26197
26419
|
const filePath = match[1];
|
|
26198
|
-
if (seen.has(filePath))
|
|
26420
|
+
if (seen.has(filePath)) {
|
|
26421
|
+
match = filePathPattern.exec(text2);
|
|
26422
|
+
continue;
|
|
26423
|
+
}
|
|
26199
26424
|
seen.add(filePath);
|
|
26200
26425
|
if (seen.size > 20) break;
|
|
26201
26426
|
const entities = await this.localGraph.getEntitiesByFile(filePath);
|
|
@@ -26208,6 +26433,7 @@ var init_query_router = __esm({
|
|
|
26208
26433
|
isChokepoint: br.is_chokepoint
|
|
26209
26434
|
});
|
|
26210
26435
|
}
|
|
26436
|
+
match = filePathPattern.exec(text2);
|
|
26211
26437
|
}
|
|
26212
26438
|
} catch (err) {
|
|
26213
26439
|
process.stderr.write(
|
|
@@ -26241,13 +26467,13 @@ var init_query_router = __esm({
|
|
|
26241
26467
|
const kindHint = args.kind ?? aliasKind;
|
|
26242
26468
|
const key = await this.resolveKeyArg(rawArg, kindHint);
|
|
26243
26469
|
const entity = await this.resolveEntityWithOverlay(key);
|
|
26244
|
-
if (entity
|
|
26470
|
+
if (entity?.file_path && entity.start_line > 0) {
|
|
26245
26471
|
try {
|
|
26246
|
-
const { readFileSync:
|
|
26247
|
-
const { resolve:
|
|
26472
|
+
const { readFileSync: readFileSync68 } = await import("fs");
|
|
26473
|
+
const { resolve: resolve9 } = await import("path");
|
|
26248
26474
|
const cwd = this.projectRoot ?? process.cwd();
|
|
26249
|
-
const abs =
|
|
26250
|
-
const lines =
|
|
26475
|
+
const abs = resolve9(cwd, entity.file_path);
|
|
26476
|
+
const lines = readFileSync68(abs, "utf-8").split("\n");
|
|
26251
26477
|
const start = entity.start_line - 1;
|
|
26252
26478
|
const end = entity.end_line ?? lines.length;
|
|
26253
26479
|
const bodyLines = lines.slice(start, end);
|
|
@@ -26380,20 +26606,41 @@ var init_query_router = __esm({
|
|
|
26380
26606
|
const topN = args.top_n ?? 20;
|
|
26381
26607
|
const fromPath = args.from_path;
|
|
26382
26608
|
const toPath = args.to_path;
|
|
26383
|
-
|
|
26609
|
+
if (fromPath && toPath) {
|
|
26610
|
+
const norm2 = (p) => p.replace(/\/+$/, "");
|
|
26611
|
+
const result2 = await this.localGraph.getCrossPathLinks(
|
|
26612
|
+
norm2(fromPath),
|
|
26613
|
+
norm2(toPath),
|
|
26614
|
+
topN
|
|
26615
|
+
);
|
|
26616
|
+
if (result2.length === 0) {
|
|
26617
|
+
return {
|
|
26618
|
+
links: [],
|
|
26619
|
+
_hint: "No edges found between these directory prefixes. call file_connections({file_path:'<file>'}) for import-level neighbors, or get_references({entity:'<name>', direction:'callees'}) for call-level dependencies."
|
|
26620
|
+
};
|
|
26621
|
+
}
|
|
26622
|
+
return result2;
|
|
26623
|
+
}
|
|
26624
|
+
const fetchN = fromPath ? Math.max(topN * 10, 200) : topN;
|
|
26384
26625
|
const rows = await this.localGraph.getCrossBoundaryLinks(
|
|
26385
26626
|
communityId,
|
|
26386
26627
|
fetchN
|
|
26387
26628
|
);
|
|
26388
|
-
if (!fromPath
|
|
26629
|
+
if (!fromPath) return rows;
|
|
26389
26630
|
const norm = (p) => p ? p.replace(/\/+$/, "") : "";
|
|
26390
26631
|
const f = norm(fromPath);
|
|
26391
|
-
const t = norm(toPath);
|
|
26392
26632
|
const matches = (file, prefix) => !prefix || file === prefix || file.startsWith(prefix.endsWith("/") ? prefix : `${prefix}/`);
|
|
26393
26633
|
const filtered = rows.filter(
|
|
26394
|
-
(r) => matches(r.from_file, f)
|
|
26634
|
+
(r) => matches(r.from_file, f) || matches(r.to_file, f)
|
|
26395
26635
|
);
|
|
26396
|
-
|
|
26636
|
+
const result = filtered.slice(0, topN);
|
|
26637
|
+
if (result.length === 0) {
|
|
26638
|
+
return {
|
|
26639
|
+
links: [],
|
|
26640
|
+
_hint: "No cross-community edges found for this path filter. call file_connections({file_path:'<file>'}) for import-level neighbors, or get_references({entity:'<name>', direction:'callees'}) for call-level dependencies."
|
|
26641
|
+
};
|
|
26642
|
+
}
|
|
26643
|
+
return result;
|
|
26397
26644
|
}
|
|
26398
26645
|
case "get_critical_nodes": {
|
|
26399
26646
|
const topN = args.top_n ?? 10;
|
|
@@ -27823,7 +28070,7 @@ __export(causal_bridge_exports, {
|
|
|
27823
28070
|
assembleCausalChain: () => assembleCausalChain,
|
|
27824
28071
|
computeDurability: () => computeDurability
|
|
27825
28072
|
});
|
|
27826
|
-
import { existsSync as existsSync57, readFileSync as
|
|
28073
|
+
import { existsSync as existsSync57, readFileSync as readFileSync50 } from "fs";
|
|
27827
28074
|
import { join as join59 } from "path";
|
|
27828
28075
|
function computeAggregateDurability(interactions) {
|
|
27829
28076
|
if (interactions.length === 0) return 1;
|
|
@@ -27983,7 +28230,7 @@ var init_causal_bridge = __esm({
|
|
|
27983
28230
|
loadEntityLedgerEntries(entityKey2) {
|
|
27984
28231
|
const ledgerPath = join59(this.unerrDir, "ledger", "shadow.jsonl");
|
|
27985
28232
|
if (!existsSync57(ledgerPath)) return [];
|
|
27986
|
-
const content =
|
|
28233
|
+
const content = readFileSync50(ledgerPath, "utf-8");
|
|
27987
28234
|
const lines = content.split("\n").filter((l) => l.trim().length > 0);
|
|
27988
28235
|
const entries = [];
|
|
27989
28236
|
for (const line of lines) {
|
|
@@ -28469,7 +28716,7 @@ var context_ledger_exports = {};
|
|
|
28469
28716
|
__export(context_ledger_exports, {
|
|
28470
28717
|
createContextLedger: () => createContextLedger
|
|
28471
28718
|
});
|
|
28472
|
-
import { existsSync as existsSync58, mkdirSync as mkdirSync34, readFileSync as
|
|
28719
|
+
import { existsSync as existsSync58, mkdirSync as mkdirSync34, readFileSync as readFileSync51, writeFileSync as writeFileSync29 } from "fs";
|
|
28473
28720
|
import { join as join60 } from "path";
|
|
28474
28721
|
function createContextLedger(unerrDir) {
|
|
28475
28722
|
const stateDir = join60(unerrDir, "state");
|
|
@@ -28492,7 +28739,7 @@ function createContextLedger(unerrDir) {
|
|
|
28492
28739
|
return /* @__PURE__ */ new Map();
|
|
28493
28740
|
}
|
|
28494
28741
|
try {
|
|
28495
|
-
const raw =
|
|
28742
|
+
const raw = readFileSync51(filePath, "utf-8");
|
|
28496
28743
|
const parsed = JSON.parse(raw);
|
|
28497
28744
|
records = Array.isArray(parsed) ? parsed : [];
|
|
28498
28745
|
} catch {
|
|
@@ -29401,7 +29648,7 @@ __export(intent_correlator_exports, {
|
|
|
29401
29648
|
import {
|
|
29402
29649
|
existsSync as existsSync59,
|
|
29403
29650
|
mkdirSync as mkdirSync35,
|
|
29404
|
-
readFileSync as
|
|
29651
|
+
readFileSync as readFileSync52,
|
|
29405
29652
|
renameSync as renameSync2,
|
|
29406
29653
|
writeFileSync as writeFileSync30
|
|
29407
29654
|
} from "fs";
|
|
@@ -29549,7 +29796,7 @@ var init_intent_correlator = __esm({
|
|
|
29549
29796
|
load() {
|
|
29550
29797
|
if (!existsSync59(this.pendingPath)) return;
|
|
29551
29798
|
try {
|
|
29552
|
-
const raw =
|
|
29799
|
+
const raw = readFileSync52(this.pendingPath, "utf-8");
|
|
29553
29800
|
const parsed = JSON.parse(raw);
|
|
29554
29801
|
if (Array.isArray(parsed)) {
|
|
29555
29802
|
this.pending = parsed;
|
|
@@ -29891,10 +30138,10 @@ var init_timeline_store = __esm({
|
|
|
29891
30138
|
async setSessionAgent(sessionId, agentName, nowMs = Date.now()) {
|
|
29892
30139
|
if (!agentName || agentName.length === 0) return;
|
|
29893
30140
|
const existing = await this.db.run(
|
|
29894
|
-
|
|
30141
|
+
"?[first_seen] := *session_agents{session_id, first_seen}, session_id = $sid",
|
|
29895
30142
|
{ sid: sessionId }
|
|
29896
30143
|
);
|
|
29897
|
-
const firstSeen = existing.rows.length > 0 ? existing.rows[0][0] : nowMs;
|
|
30144
|
+
const firstSeen = existing.rows.length > 0 ? existing.rows[0]?.[0] : nowMs;
|
|
29898
30145
|
await this.db.run(
|
|
29899
30146
|
`?[session_id, agent_name, first_seen, last_seen] <-
|
|
29900
30147
|
[[$sid, $name, $first, $last]]
|
|
@@ -29912,7 +30159,7 @@ var init_timeline_store = __esm({
|
|
|
29912
30159
|
/** Lookup the agent name for one session id. Returns null when unknown. */
|
|
29913
30160
|
async getSessionAgent(sessionId) {
|
|
29914
30161
|
const result = await this.db.run(
|
|
29915
|
-
|
|
30162
|
+
"?[agent_name] := *session_agents{session_id, agent_name}, session_id = $sid",
|
|
29916
30163
|
{ sid: sessionId }
|
|
29917
30164
|
);
|
|
29918
30165
|
const row = result.rows[0];
|
|
@@ -30029,7 +30276,7 @@ var init_timeline_store = __esm({
|
|
|
30029
30276
|
}
|
|
30030
30277
|
async getSessionFiles(sessionId) {
|
|
30031
30278
|
const result = await this.db.run(
|
|
30032
|
-
|
|
30279
|
+
"?[file_path] := *session_files{session_id: $session_id, file_path}",
|
|
30033
30280
|
{ session_id: sessionId }
|
|
30034
30281
|
);
|
|
30035
30282
|
return result.rows.map((r) => r[0]);
|
|
@@ -30047,7 +30294,7 @@ var init_timeline_store = __esm({
|
|
|
30047
30294
|
}
|
|
30048
30295
|
async listIntents(opts = {}) {
|
|
30049
30296
|
const limit = Math.max(1, Math.min(opts.limit ?? 100, 500));
|
|
30050
|
-
const filter = opts.status ?
|
|
30297
|
+
const filter = opts.status ? ", status = $status" : "";
|
|
30051
30298
|
const query = `?[intent_id, title, started_at, last_active_at, file_set, file_set_hash, status, confidence, source] :=
|
|
30052
30299
|
*intents{intent_id, title, started_at, last_active_at, file_set, file_set_hash, status, confidence, source}${filter}
|
|
30053
30300
|
:order -last_active_at
|
|
@@ -30076,7 +30323,7 @@ var init_timeline_store = __esm({
|
|
|
30076
30323
|
}
|
|
30077
30324
|
async listIntentSessions(intentId) {
|
|
30078
30325
|
const result = await this.db.run(
|
|
30079
|
-
|
|
30326
|
+
"?[session_id] := *intent_sessions{intent_id: $intent_id, session_id}",
|
|
30080
30327
|
{ intent_id: intentId }
|
|
30081
30328
|
);
|
|
30082
30329
|
return result.rows.map((r) => r[0]);
|
|
@@ -30086,7 +30333,7 @@ var init_timeline_store = __esm({
|
|
|
30086
30333
|
*/
|
|
30087
30334
|
async findIntentForSession(sessionId) {
|
|
30088
30335
|
const result = await this.db.run(
|
|
30089
|
-
|
|
30336
|
+
"?[intent_id] := *intent_sessions{intent_id, session_id: $session_id}",
|
|
30090
30337
|
{ session_id: sessionId }
|
|
30091
30338
|
);
|
|
30092
30339
|
const row = result.rows[0];
|
|
@@ -30439,7 +30686,10 @@ function stitchIntents(sessions, existingIntents, existingAttachments, opts = {}
|
|
|
30439
30686
|
}
|
|
30440
30687
|
function attachSession(intent, session) {
|
|
30441
30688
|
for (const f of session.files) intent._filesSet.add(f);
|
|
30442
|
-
intent.last_active_at = Math.max(
|
|
30689
|
+
intent.last_active_at = Math.max(
|
|
30690
|
+
intent.last_active_at,
|
|
30691
|
+
session.last_active_at
|
|
30692
|
+
);
|
|
30443
30693
|
intent.confidence = Math.min(1, intent.confidence + 0.05);
|
|
30444
30694
|
intent.file_set = JSON.stringify([...intent._filesSet].sort());
|
|
30445
30695
|
intent.file_set_hash = hashFileSet(intent._filesSet);
|
|
@@ -30525,7 +30775,12 @@ async function runIntentStitch(store, opts = {}) {
|
|
|
30525
30775
|
existingAttachments.push({ intent_id: i.intent_id, session_id: sid });
|
|
30526
30776
|
}
|
|
30527
30777
|
}
|
|
30528
|
-
const result = stitchIntents(
|
|
30778
|
+
const result = stitchIntents(
|
|
30779
|
+
summaries,
|
|
30780
|
+
existingIntents,
|
|
30781
|
+
existingAttachments,
|
|
30782
|
+
opts
|
|
30783
|
+
);
|
|
30529
30784
|
let created = 0;
|
|
30530
30785
|
const existingIds = new Set(existingIntents.map((i) => i.intent_id));
|
|
30531
30786
|
for (const i of result.intents) {
|
|
@@ -30560,7 +30815,7 @@ __export(signal_reinforcer_exports, {
|
|
|
30560
30815
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
30561
30816
|
async function reinforceSignal(store, identity, delta, source, opts = {}) {
|
|
30562
30817
|
const now = opts.nowMs ?? Date.now();
|
|
30563
|
-
|
|
30818
|
+
const signal = await resolveSignal(store, identity);
|
|
30564
30819
|
if (!signal) {
|
|
30565
30820
|
const created = {
|
|
30566
30821
|
signal_id: "signal_id" in identity ? identity.signal_id : randomUUID3(),
|
|
@@ -30612,16 +30867,16 @@ var ledger_archiver_exports = {};
|
|
|
30612
30867
|
__export(ledger_archiver_exports, {
|
|
30613
30868
|
archiveShadowLedger: () => archiveShadowLedger
|
|
30614
30869
|
});
|
|
30615
|
-
import { gzipSync } from "zlib";
|
|
30616
30870
|
import {
|
|
30617
30871
|
appendFileSync as appendFileSync7,
|
|
30618
30872
|
existsSync as existsSync61,
|
|
30619
30873
|
mkdirSync as mkdirSync37,
|
|
30620
|
-
readFileSync as
|
|
30874
|
+
readFileSync as readFileSync53,
|
|
30621
30875
|
renameSync as renameSync3,
|
|
30622
30876
|
writeFileSync as writeFileSync31
|
|
30623
30877
|
} from "fs";
|
|
30624
30878
|
import { join as join63 } from "path";
|
|
30879
|
+
import { gzipSync } from "zlib";
|
|
30625
30880
|
function archiveShadowLedger(unerrDir, opts = {}) {
|
|
30626
30881
|
const ledgerDir = join63(unerrDir, "ledger");
|
|
30627
30882
|
const filePath = join63(ledgerDir, "shadow.jsonl");
|
|
@@ -30632,13 +30887,13 @@ function archiveShadowLedger(unerrDir, opts = {}) {
|
|
|
30632
30887
|
const retainMs = opts.retainMs ?? DEFAULT_RETAIN_MS;
|
|
30633
30888
|
const now = opts.nowMs ?? Date.now();
|
|
30634
30889
|
const cutoff = now - retainMs;
|
|
30635
|
-
const raw =
|
|
30890
|
+
const raw = readFileSync53(filePath, "utf-8");
|
|
30636
30891
|
const initialBytes = Buffer.byteLength(raw);
|
|
30637
30892
|
const lines = raw.split("\n").filter((l) => l.trim().length > 0);
|
|
30638
30893
|
const keep = [];
|
|
30639
30894
|
const archive = [];
|
|
30640
30895
|
for (const line of lines) {
|
|
30641
|
-
let entryTs = NaN;
|
|
30896
|
+
let entryTs = Number.NaN;
|
|
30642
30897
|
try {
|
|
30643
30898
|
const obj = JSON.parse(line);
|
|
30644
30899
|
if (typeof obj.ts === "string") entryTs = Date.parse(obj.ts);
|
|
@@ -30669,7 +30924,7 @@ function archiveShadowLedger(unerrDir, opts = {}) {
|
|
|
30669
30924
|
const tmpPath = `${filePath}.tmp-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
30670
30925
|
const kept = `${keep.join("\n")}${keep.length > 0 ? "\n" : ""}`;
|
|
30671
30926
|
writeFileSync31(tmpPath, kept, "utf-8");
|
|
30672
|
-
const afterRaw =
|
|
30927
|
+
const afterRaw = readFileSync53(filePath, "utf-8");
|
|
30673
30928
|
const afterBytes = Buffer.byteLength(afterRaw);
|
|
30674
30929
|
if (afterBytes > initialBytes) {
|
|
30675
30930
|
const tail = afterRaw.slice(raw.length);
|
|
@@ -30815,7 +31070,12 @@ var init_session_narrative = __esm({
|
|
|
30815
31070
|
const byArea = /* @__PURE__ */ new Map();
|
|
30816
31071
|
for (const n of this.narratives) {
|
|
30817
31072
|
const area = extractFeatureArea(n.file_path);
|
|
30818
|
-
|
|
31073
|
+
let list = byArea.get(area);
|
|
31074
|
+
if (!list) {
|
|
31075
|
+
list = [];
|
|
31076
|
+
byArea.set(area, list);
|
|
31077
|
+
}
|
|
31078
|
+
list.push(n);
|
|
30819
31079
|
}
|
|
30820
31080
|
const areaSummaries = [...byArea.entries()].map(([area, entries]) => {
|
|
30821
31081
|
const whats = entries.map((e) => e.what).slice(0, 3);
|
|
@@ -31173,7 +31433,7 @@ import { randomBytes as randomBytes4 } from "crypto";
|
|
|
31173
31433
|
import {
|
|
31174
31434
|
existsSync as existsSync62,
|
|
31175
31435
|
mkdirSync as mkdirSync38,
|
|
31176
|
-
readFileSync as
|
|
31436
|
+
readFileSync as readFileSync54,
|
|
31177
31437
|
readdirSync as readdirSync12,
|
|
31178
31438
|
rmSync as rmSync2,
|
|
31179
31439
|
writeFileSync as writeFileSync32
|
|
@@ -31234,7 +31494,7 @@ var init_working_snapshots = __esm({
|
|
|
31234
31494
|
const filePath = join64(this.snapshotDir, `${snapshotId}.json`);
|
|
31235
31495
|
if (!existsSync62(filePath)) return null;
|
|
31236
31496
|
try {
|
|
31237
|
-
return JSON.parse(
|
|
31497
|
+
return JSON.parse(readFileSync54(filePath, "utf-8"));
|
|
31238
31498
|
} catch {
|
|
31239
31499
|
return null;
|
|
31240
31500
|
}
|
|
@@ -31250,7 +31510,7 @@ var init_working_snapshots = __esm({
|
|
|
31250
31510
|
const snapshots = [];
|
|
31251
31511
|
for (const file of files) {
|
|
31252
31512
|
try {
|
|
31253
|
-
const raw =
|
|
31513
|
+
const raw = readFileSync54(join64(this.snapshotDir, file), "utf-8");
|
|
31254
31514
|
snapshots.push(JSON.parse(raw));
|
|
31255
31515
|
} catch {
|
|
31256
31516
|
}
|
|
@@ -31318,7 +31578,7 @@ var init_working_snapshots = __esm({
|
|
|
31318
31578
|
const contextPath = join64(this.unerrDir, "branch_context.json");
|
|
31319
31579
|
if (!existsSync62(contextPath)) return 0;
|
|
31320
31580
|
try {
|
|
31321
|
-
const ctx = JSON.parse(
|
|
31581
|
+
const ctx = JSON.parse(readFileSync54(contextPath, "utf-8"));
|
|
31322
31582
|
return ctx.timelineBranch ?? 0;
|
|
31323
31583
|
} catch {
|
|
31324
31584
|
return 0;
|
|
@@ -31332,7 +31592,7 @@ var init_working_snapshots = __esm({
|
|
|
31332
31592
|
let ctx = {};
|
|
31333
31593
|
if (existsSync62(contextPath)) {
|
|
31334
31594
|
try {
|
|
31335
|
-
ctx = JSON.parse(
|
|
31595
|
+
ctx = JSON.parse(readFileSync54(contextPath, "utf-8"));
|
|
31336
31596
|
} catch {
|
|
31337
31597
|
ctx = {};
|
|
31338
31598
|
}
|
|
@@ -31505,7 +31765,7 @@ var quality_signals_exports = {};
|
|
|
31505
31765
|
__export(quality_signals_exports, {
|
|
31506
31766
|
QualitySignalTracker: () => QualitySignalTracker
|
|
31507
31767
|
});
|
|
31508
|
-
import { existsSync as existsSync63, readFileSync as
|
|
31768
|
+
import { existsSync as existsSync63, readFileSync as readFileSync55, writeFileSync as writeFileSync33 } from "fs";
|
|
31509
31769
|
import { join as join65 } from "path";
|
|
31510
31770
|
function computeDurabilityFromAge(survivalMs) {
|
|
31511
31771
|
if (survivalMs < FRAGILE_THRESHOLD_MS) {
|
|
@@ -31681,7 +31941,7 @@ var init_quality_signals = __esm({
|
|
|
31681
31941
|
}
|
|
31682
31942
|
try {
|
|
31683
31943
|
return JSON.parse(
|
|
31684
|
-
|
|
31944
|
+
readFileSync55(this.signalsPath, "utf-8")
|
|
31685
31945
|
);
|
|
31686
31946
|
} catch {
|
|
31687
31947
|
return {
|
|
@@ -32265,8 +32525,8 @@ function extractPreviousSession(allEntries, currentSessionId) {
|
|
|
32265
32525
|
return allEntries.filter((e) => e.session_id === lastSessionId);
|
|
32266
32526
|
}
|
|
32267
32527
|
function buildResumePayload(entries, maxItems) {
|
|
32268
|
-
const firstTs = new Date(entries[0]
|
|
32269
|
-
const lastTs = new Date(entries[entries.length - 1]
|
|
32528
|
+
const firstTs = new Date(entries[0]?.ts ?? 0).getTime();
|
|
32529
|
+
const lastTs = new Date(entries[entries.length - 1]?.ts ?? 0).getTime();
|
|
32270
32530
|
const durationMs = lastTs - firstTs;
|
|
32271
32531
|
const elapsedSinceMs = Date.now() - lastTs;
|
|
32272
32532
|
const filesModified = /* @__PURE__ */ new Set();
|
|
@@ -32316,7 +32576,7 @@ function buildResumePayload(entries, maxItems) {
|
|
|
32316
32576
|
summaryParts.push(`${filesModified.size} file(s) touched`);
|
|
32317
32577
|
if (incompleteWork.length > 0)
|
|
32318
32578
|
summaryParts.push(`${incompleteWork.length} incomplete item(s)`);
|
|
32319
|
-
const suggestedNext = incompleteWork.length > 0 ? `Complete outstanding work on ${incompleteWork[0]
|
|
32579
|
+
const suggestedNext = incompleteWork.length > 0 ? `Complete outstanding work on ${incompleteWork[0]?.entity} (${incompleteWork[0]?.status})` : "No outstanding items from last session \u2014 ready for new work.";
|
|
32320
32580
|
return {
|
|
32321
32581
|
last_session: {
|
|
32322
32582
|
when: formatElapsed(elapsedSinceMs),
|
|
@@ -32507,8 +32767,10 @@ function extractSignatures(content, entityName) {
|
|
|
32507
32767
|
const results = [];
|
|
32508
32768
|
for (const pattern of patterns) {
|
|
32509
32769
|
let match;
|
|
32510
|
-
|
|
32770
|
+
match = pattern.exec(content);
|
|
32771
|
+
while (match !== null) {
|
|
32511
32772
|
results.push(match[0]);
|
|
32773
|
+
match = pattern.exec(content);
|
|
32512
32774
|
}
|
|
32513
32775
|
if (results.length > 0) break;
|
|
32514
32776
|
}
|
|
@@ -32698,7 +32960,7 @@ var incomplete_work_exports = {};
|
|
|
32698
32960
|
__export(incomplete_work_exports, {
|
|
32699
32961
|
IncompleteWorkDetector: () => IncompleteWorkDetector
|
|
32700
32962
|
});
|
|
32701
|
-
import { existsSync as existsSync64, mkdirSync as mkdirSync39, readFileSync as
|
|
32963
|
+
import { existsSync as existsSync64, mkdirSync as mkdirSync39, readFileSync as readFileSync56, writeFileSync as writeFileSync34 } from "fs";
|
|
32702
32964
|
import { join as join66 } from "path";
|
|
32703
32965
|
function severityRank(severity) {
|
|
32704
32966
|
switch (severity) {
|
|
@@ -32916,7 +33178,7 @@ var init_incomplete_work = __esm({
|
|
|
32916
33178
|
try {
|
|
32917
33179
|
const filePath = join66(unerrDir, "state", PERSISTENCE_FILE);
|
|
32918
33180
|
if (!existsSync64(filePath)) return [];
|
|
32919
|
-
const data = JSON.parse(
|
|
33181
|
+
const data = JSON.parse(readFileSync56(filePath, "utf-8"));
|
|
32920
33182
|
return data.items ?? [];
|
|
32921
33183
|
} catch {
|
|
32922
33184
|
return [];
|
|
@@ -32969,8 +33231,10 @@ function extractDefinedNames(content) {
|
|
|
32969
33231
|
];
|
|
32970
33232
|
for (const pattern of patterns) {
|
|
32971
33233
|
let match;
|
|
32972
|
-
|
|
33234
|
+
match = pattern.exec(content);
|
|
33235
|
+
while (match !== null) {
|
|
32973
33236
|
if (match[1]) names.push(match[1]);
|
|
33237
|
+
match = pattern.exec(content);
|
|
32974
33238
|
}
|
|
32975
33239
|
}
|
|
32976
33240
|
return [...new Set(names)];
|
|
@@ -32979,8 +33243,10 @@ function extractImportLines(content) {
|
|
|
32979
33243
|
const imports = [];
|
|
32980
33244
|
const pattern = /import\s+.*?from\s+['"]([^'"]+)['"]/g;
|
|
32981
33245
|
let match;
|
|
32982
|
-
|
|
33246
|
+
match = pattern.exec(content);
|
|
33247
|
+
while (match !== null) {
|
|
32983
33248
|
if (match[1]) imports.push(match[1]);
|
|
33249
|
+
match = pattern.exec(content);
|
|
32984
33250
|
}
|
|
32985
33251
|
return imports;
|
|
32986
33252
|
}
|
|
@@ -33220,7 +33486,8 @@ function extractExportedSignatures(content) {
|
|
|
33220
33486
|
const results = [];
|
|
33221
33487
|
const pattern = /(?:export\s+)?(?:async\s+)?function\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\s*(\([^)]*\))(?:\s*:\s*([^{]+?))?(?:\s*\{)/g;
|
|
33222
33488
|
let match;
|
|
33223
|
-
|
|
33489
|
+
match = pattern.exec(content);
|
|
33490
|
+
while (match !== null) {
|
|
33224
33491
|
const name = match[1];
|
|
33225
33492
|
const params = match[2];
|
|
33226
33493
|
const returnType = match[3]?.trim() ?? null;
|
|
@@ -33230,6 +33497,7 @@ function extractExportedSignatures(content) {
|
|
|
33230
33497
|
startIndex: match.index,
|
|
33231
33498
|
returnType
|
|
33232
33499
|
});
|
|
33500
|
+
match = pattern.exec(content);
|
|
33233
33501
|
}
|
|
33234
33502
|
return results;
|
|
33235
33503
|
}
|
|
@@ -33455,7 +33723,7 @@ function parseImports(content) {
|
|
|
33455
33723
|
const isTypeOnly = !!importMatch[1];
|
|
33456
33724
|
const specifier = importMatch[2];
|
|
33457
33725
|
if (!specifier.startsWith(".")) continue;
|
|
33458
|
-
const prevLine = i > 0 ? lines[i - 1]
|
|
33726
|
+
const prevLine = i > 0 ? lines[i - 1]?.trim() ?? "" : "";
|
|
33459
33727
|
const hasOverride = OVERRIDE_PATTERN.test(prevLine) || OVERRIDE_PATTERN.test(line);
|
|
33460
33728
|
results.push({
|
|
33461
33729
|
raw: line,
|
|
@@ -33598,7 +33866,7 @@ var init_architecture_guard = __esm({
|
|
|
33598
33866
|
},
|
|
33599
33867
|
{
|
|
33600
33868
|
pattern: "interface_bridge",
|
|
33601
|
-
example:
|
|
33869
|
+
example: "Define shared types in a schemas/ module accessible to both communities"
|
|
33602
33870
|
}
|
|
33603
33871
|
);
|
|
33604
33872
|
}
|
|
@@ -34690,7 +34958,7 @@ __export(git_trailers_exports, {
|
|
|
34690
34958
|
parseTrailersFromMessage: () => parseTrailersFromMessage,
|
|
34691
34959
|
uninstallPrepareCommitMsgHook: () => uninstallPrepareCommitMsgHook
|
|
34692
34960
|
});
|
|
34693
|
-
import { existsSync as existsSync66, readFileSync as
|
|
34961
|
+
import { existsSync as existsSync66, readFileSync as readFileSync57, writeFileSync as writeFileSync35 } from "fs";
|
|
34694
34962
|
import { join as join67 } from "path";
|
|
34695
34963
|
function getCommitTrailers(ledger, timelineBranch, branch) {
|
|
34696
34964
|
const recent = ledger.getRecentEntries(1);
|
|
@@ -34719,7 +34987,7 @@ function installPrepareCommitMsgHook(projectRoot) {
|
|
|
34719
34987
|
const marker = "# unerr-trailer-injection";
|
|
34720
34988
|
if (existsSync66(hookPath)) {
|
|
34721
34989
|
try {
|
|
34722
|
-
const existing =
|
|
34990
|
+
const existing = readFileSync57(hookPath, "utf-8");
|
|
34723
34991
|
if (existing.includes(marker)) {
|
|
34724
34992
|
return true;
|
|
34725
34993
|
}
|
|
@@ -34751,7 +35019,7 @@ function uninstallPrepareCommitMsgHook(projectRoot) {
|
|
|
34751
35019
|
const hookPath = join67(projectRoot, ".git", "hooks", "prepare-commit-msg");
|
|
34752
35020
|
if (!existsSync66(hookPath)) return true;
|
|
34753
35021
|
try {
|
|
34754
|
-
const content =
|
|
35022
|
+
const content = readFileSync57(hookPath, "utf-8");
|
|
34755
35023
|
const marker = "# unerr-trailer-injection";
|
|
34756
35024
|
if (!content.includes(marker)) return true;
|
|
34757
35025
|
const lines = content.split("\n");
|
|
@@ -34890,12 +35158,12 @@ async function startHttpTransport(opts) {
|
|
|
34890
35158
|
})
|
|
34891
35159
|
);
|
|
34892
35160
|
});
|
|
34893
|
-
return new Promise((
|
|
35161
|
+
return new Promise((resolve9) => {
|
|
34894
35162
|
httpServer.listen(port, "127.0.0.1", () => {
|
|
34895
35163
|
const addr = httpServer.address();
|
|
34896
35164
|
const resolvedPort = typeof addr === "object" && addr ? addr.port : port;
|
|
34897
35165
|
log24(`HTTP transport listening on http://127.0.0.1:${resolvedPort}/mcp`);
|
|
34898
|
-
|
|
35166
|
+
resolve9({
|
|
34899
35167
|
server: httpServer,
|
|
34900
35168
|
port: resolvedPort,
|
|
34901
35169
|
close: () => {
|
|
@@ -34918,7 +35186,7 @@ var init_http_transport = __esm({
|
|
|
34918
35186
|
import {
|
|
34919
35187
|
existsSync as existsSync67,
|
|
34920
35188
|
mkdirSync as mkdirSync41,
|
|
34921
|
-
readFileSync as
|
|
35189
|
+
readFileSync as readFileSync58,
|
|
34922
35190
|
readdirSync as readdirSync13,
|
|
34923
35191
|
rmSync as rmSync3,
|
|
34924
35192
|
statSync as statSync9,
|
|
@@ -34996,7 +35264,7 @@ var init_branch_snapshot = __esm({
|
|
|
34996
35264
|
return null;
|
|
34997
35265
|
}
|
|
34998
35266
|
try {
|
|
34999
|
-
const raw =
|
|
35267
|
+
const raw = readFileSync58(overlayPath, "utf-8");
|
|
35000
35268
|
const snapshot = JSON.parse(raw);
|
|
35001
35269
|
for (const entity of snapshot.entities) {
|
|
35002
35270
|
await localGraph.upsertDriftEntity(entity);
|
|
@@ -35038,7 +35306,7 @@ var init_branch_snapshot = __esm({
|
|
|
35038
35306
|
const hashesPath = join68(this.branchDir, dirName, HASHES_FILE);
|
|
35039
35307
|
if (!existsSync67(hashesPath)) return null;
|
|
35040
35308
|
try {
|
|
35041
|
-
const raw =
|
|
35309
|
+
const raw = readFileSync58(hashesPath, "utf-8");
|
|
35042
35310
|
return JSON.parse(raw);
|
|
35043
35311
|
} catch {
|
|
35044
35312
|
return null;
|
|
@@ -35087,7 +35355,7 @@ var init_branch_snapshot = __esm({
|
|
|
35087
35355
|
const overlayPath = join68(this.branchDir, entry.name, OVERLAY_FILE);
|
|
35088
35356
|
if (!existsSync67(overlayPath)) continue;
|
|
35089
35357
|
try {
|
|
35090
|
-
const raw =
|
|
35358
|
+
const raw = readFileSync58(overlayPath, "utf-8");
|
|
35091
35359
|
const snapshot = JSON.parse(raw);
|
|
35092
35360
|
const accessPath = join68(this.branchDir, entry.name, ".last_access");
|
|
35093
35361
|
let accessedAt;
|
|
@@ -35137,7 +35405,7 @@ import { createHash as createHash3 } from "crypto";
|
|
|
35137
35405
|
import {
|
|
35138
35406
|
existsSync as existsSync68,
|
|
35139
35407
|
mkdirSync as mkdirSync42,
|
|
35140
|
-
readFileSync as
|
|
35408
|
+
readFileSync as readFileSync59,
|
|
35141
35409
|
renameSync as renameSync4,
|
|
35142
35410
|
writeFileSync as writeFileSync37
|
|
35143
35411
|
} from "fs";
|
|
@@ -35232,7 +35500,7 @@ var init_file_hash_state = __esm({
|
|
|
35232
35500
|
return { files: {} };
|
|
35233
35501
|
}
|
|
35234
35502
|
try {
|
|
35235
|
-
const raw =
|
|
35503
|
+
const raw = readFileSync59(this.statePath, "utf-8");
|
|
35236
35504
|
return JSON.parse(raw);
|
|
35237
35505
|
} catch {
|
|
35238
35506
|
return { files: {} };
|
|
@@ -35246,7 +35514,7 @@ var init_file_hash_state = __esm({
|
|
|
35246
35514
|
import {
|
|
35247
35515
|
existsSync as existsSync69,
|
|
35248
35516
|
mkdirSync as mkdirSync43,
|
|
35249
|
-
readFileSync as
|
|
35517
|
+
readFileSync as readFileSync60,
|
|
35250
35518
|
readdirSync as readdirSync14,
|
|
35251
35519
|
rmSync as rmSync4,
|
|
35252
35520
|
statSync as statSync10,
|
|
@@ -35361,7 +35629,7 @@ var init_stash_manager = __esm({
|
|
|
35361
35629
|
return 0;
|
|
35362
35630
|
}
|
|
35363
35631
|
try {
|
|
35364
|
-
const raw =
|
|
35632
|
+
const raw = readFileSync60(overlayPath, "utf-8");
|
|
35365
35633
|
const snapshot = JSON.parse(raw);
|
|
35366
35634
|
for (const entity of snapshot.entities) {
|
|
35367
35635
|
await localGraph.upsertDriftEntity(entity);
|
|
@@ -35394,7 +35662,7 @@ var init_stash_manager = __esm({
|
|
|
35394
35662
|
const hashesPath = join70(this.stashDir, latest.id, HASHES_FILE2);
|
|
35395
35663
|
if (!existsSync69(hashesPath)) return null;
|
|
35396
35664
|
try {
|
|
35397
|
-
const raw =
|
|
35665
|
+
const raw = readFileSync60(hashesPath, "utf-8");
|
|
35398
35666
|
return JSON.parse(raw);
|
|
35399
35667
|
} catch {
|
|
35400
35668
|
return null;
|
|
@@ -35442,7 +35710,7 @@ var init_stash_manager = __esm({
|
|
|
35442
35710
|
const stashPath = join70(this.gitDir, "refs", "stash");
|
|
35443
35711
|
if (!existsSync69(stashPath)) return null;
|
|
35444
35712
|
try {
|
|
35445
|
-
return
|
|
35713
|
+
return readFileSync60(stashPath, "utf-8").trim() || null;
|
|
35446
35714
|
} catch {
|
|
35447
35715
|
return null;
|
|
35448
35716
|
}
|
|
@@ -35454,7 +35722,7 @@ var init_stash_manager = __esm({
|
|
|
35454
35722
|
const logPath2 = join70(this.gitDir, "logs", "refs", "stash");
|
|
35455
35723
|
if (!existsSync69(logPath2)) return 0;
|
|
35456
35724
|
try {
|
|
35457
|
-
const content =
|
|
35725
|
+
const content = readFileSync60(logPath2, "utf-8");
|
|
35458
35726
|
return content.split("\n").filter((line) => line.trim().length > 0).length;
|
|
35459
35727
|
} catch {
|
|
35460
35728
|
return 0;
|
|
@@ -35488,7 +35756,7 @@ __export(drift_tracker_exports, {
|
|
|
35488
35756
|
import {
|
|
35489
35757
|
existsSync as existsSync70,
|
|
35490
35758
|
mkdirSync as mkdirSync44,
|
|
35491
|
-
readFileSync as
|
|
35759
|
+
readFileSync as readFileSync61,
|
|
35492
35760
|
statSync as statSync11,
|
|
35493
35761
|
writeFileSync as writeFileSync39
|
|
35494
35762
|
} from "fs";
|
|
@@ -35749,7 +36017,7 @@ var init_drift_tracker = __esm({
|
|
|
35749
36017
|
this.maybeEmitDrift(relPath, result);
|
|
35750
36018
|
return result;
|
|
35751
36019
|
}
|
|
35752
|
-
const content =
|
|
36020
|
+
const content = readFileSync61(absPath, "utf-8");
|
|
35753
36021
|
const sha = contentSha256(content);
|
|
35754
36022
|
const decision = this.fileHashManager.shouldProcess(relPath, sha, headSha);
|
|
35755
36023
|
if (decision === "skip") {
|
|
@@ -36397,7 +36665,7 @@ var init_graph_holder = __esm({
|
|
|
36397
36665
|
}
|
|
36398
36666
|
runIncremental(changedFiles, changesAtStart, startMs) {
|
|
36399
36667
|
_log8.info(`Incremental indexing ${changedFiles.length} files...`);
|
|
36400
|
-
this.incrementalFactory(changedFiles).then((result) => {
|
|
36668
|
+
this.incrementalFactory?.(changedFiles).then((result) => {
|
|
36401
36669
|
for (const fp of changedFiles) {
|
|
36402
36670
|
this.changedFilePaths.delete(fp);
|
|
36403
36671
|
}
|
|
@@ -36437,7 +36705,7 @@ var init_graph_holder = __esm({
|
|
|
36437
36705
|
_log8.info(
|
|
36438
36706
|
`Full reindex (${changesAtStart} file changes since last rebuild)...`
|
|
36439
36707
|
);
|
|
36440
|
-
this.rebuildFactory().then(({ graph: newGraph, result }) => {
|
|
36708
|
+
this.rebuildFactory?.().then(({ graph: newGraph, result }) => {
|
|
36441
36709
|
const oldGraph = this.current;
|
|
36442
36710
|
this.current = newGraph;
|
|
36443
36711
|
for (const cb of this.swapCallbacks) {
|
|
@@ -36485,7 +36753,7 @@ var incremental_indexer_exports = {};
|
|
|
36485
36753
|
__export(incremental_indexer_exports, {
|
|
36486
36754
|
indexFilesIncremental: () => indexFilesIncremental
|
|
36487
36755
|
});
|
|
36488
|
-
import { existsSync as existsSync71, readFileSync as
|
|
36756
|
+
import { existsSync as existsSync71, readFileSync as readFileSync62 } from "fs";
|
|
36489
36757
|
import { join as join72, relative as relative5 } from "path";
|
|
36490
36758
|
async function indexFilesIncremental(projectRoot, changedFiles, graphStore, repoId) {
|
|
36491
36759
|
const startMs = Date.now();
|
|
@@ -36519,7 +36787,7 @@ async function indexFilesIncremental(projectRoot, changedFiles, graphStore, repo
|
|
|
36519
36787
|
}
|
|
36520
36788
|
let content;
|
|
36521
36789
|
try {
|
|
36522
|
-
content =
|
|
36790
|
+
content = readFileSync62(absPath, "utf-8");
|
|
36523
36791
|
} catch {
|
|
36524
36792
|
continue;
|
|
36525
36793
|
}
|
|
@@ -36713,7 +36981,7 @@ async function getFileEdgeKeysBatched(db, relPath, entities) {
|
|
|
36713
36981
|
}
|
|
36714
36982
|
try {
|
|
36715
36983
|
const result = await db.run(
|
|
36716
|
-
|
|
36984
|
+
"?[from_key, to_key, type] := *edges{from_key: $key, to_key, type}",
|
|
36717
36985
|
{ key: `file:${relPath}` }
|
|
36718
36986
|
);
|
|
36719
36987
|
for (const row of result.rows) {
|
|
@@ -36742,7 +37010,7 @@ async function deleteFileFromGraph(db, relPath) {
|
|
|
36742
37010
|
}
|
|
36743
37011
|
try {
|
|
36744
37012
|
await db.write(
|
|
36745
|
-
|
|
37013
|
+
"?[file_path, entity_key] := *file_index{file_path: $fp, entity_key} :rm file_index { file_path, entity_key }",
|
|
36746
37014
|
{ fp: relPath }
|
|
36747
37015
|
);
|
|
36748
37016
|
} catch {
|
|
@@ -36760,7 +37028,7 @@ async function removeEntitiesAndEdgesBatched(db, entityKeys) {
|
|
|
36760
37028
|
for (const key of entityKeys) {
|
|
36761
37029
|
try {
|
|
36762
37030
|
const result = await db.write(
|
|
36763
|
-
|
|
37031
|
+
"?[from_key, to_key, type] := *edges{from_key: $key, to_key, type} :rm edges { from_key, to_key, type }",
|
|
36764
37032
|
{ key }
|
|
36765
37033
|
);
|
|
36766
37034
|
edgesRemoved += result.rows?.length ?? 0;
|
|
@@ -36768,7 +37036,7 @@ async function removeEntitiesAndEdgesBatched(db, entityKeys) {
|
|
|
36768
37036
|
}
|
|
36769
37037
|
try {
|
|
36770
37038
|
const result = await db.write(
|
|
36771
|
-
|
|
37039
|
+
"?[from_key, to_key, type] := *edges{from_key, to_key: $key, type} :rm edges { from_key, to_key, type }",
|
|
36772
37040
|
{ key }
|
|
36773
37041
|
);
|
|
36774
37042
|
edgesRemoved += result.rows?.length ?? 0;
|
|
@@ -36784,7 +37052,7 @@ async function removeEntitiesAndEdgesBatched(db, entityKeys) {
|
|
|
36784
37052
|
for (const key of entityKeys) {
|
|
36785
37053
|
try {
|
|
36786
37054
|
await db.write(
|
|
36787
|
-
|
|
37055
|
+
"?[file_path, entity_key] := *file_index{file_path, entity_key}, entity_key = $key :rm file_index { file_path, entity_key }",
|
|
36788
37056
|
{ key }
|
|
36789
37057
|
);
|
|
36790
37058
|
} catch {
|
|
@@ -36797,14 +37065,14 @@ async function removeEdgesForKeysBatched(db, entityKeys) {
|
|
|
36797
37065
|
for (const key of entityKeys) {
|
|
36798
37066
|
try {
|
|
36799
37067
|
await db.write(
|
|
36800
|
-
|
|
37068
|
+
"?[from_key, to_key, type] := *edges{from_key: $key, to_key, type} :rm edges { from_key, to_key, type }",
|
|
36801
37069
|
{ key }
|
|
36802
37070
|
);
|
|
36803
37071
|
} catch {
|
|
36804
37072
|
}
|
|
36805
37073
|
try {
|
|
36806
37074
|
await db.write(
|
|
36807
|
-
|
|
37075
|
+
"?[from_key, to_key, type] := *edges{from_key, to_key: $key, type} :rm edges { from_key, to_key, type }",
|
|
36808
37076
|
{ key }
|
|
36809
37077
|
);
|
|
36810
37078
|
} catch {
|
|
@@ -36880,7 +37148,7 @@ async function removeEdgesBatched(db, edges) {
|
|
|
36880
37148
|
for (const [fk, tk, type] of edges) {
|
|
36881
37149
|
try {
|
|
36882
37150
|
await db.write(
|
|
36883
|
-
|
|
37151
|
+
"?[from_key, to_key, type] <- [[$fk, $tk, $type]] :rm edges { from_key, to_key, type }",
|
|
36884
37152
|
{ fk, tk, type }
|
|
36885
37153
|
);
|
|
36886
37154
|
} catch {
|
|
@@ -37015,7 +37283,7 @@ async function updateFanCountsBatched(db, affectedKeys) {
|
|
|
37015
37283
|
const fo = fanOutMap.get(key) ?? 0;
|
|
37016
37284
|
try {
|
|
37017
37285
|
await db.write(
|
|
37018
|
-
|
|
37286
|
+
"?[key, fan_in, fan_out] <- [[$key, $fi, $fo]] :update entities { key => fan_in, fan_out }",
|
|
37019
37287
|
{ key, fi, fo }
|
|
37020
37288
|
);
|
|
37021
37289
|
} catch {
|
|
@@ -37255,13 +37523,7 @@ var init_background_indexer = __esm({
|
|
|
37255
37523
|
this._result = null;
|
|
37256
37524
|
this._error = null;
|
|
37257
37525
|
this._completedAt = null;
|
|
37258
|
-
this.runIndexing(
|
|
37259
|
-
projectRoot,
|
|
37260
|
-
graphStore,
|
|
37261
|
-
repoId,
|
|
37262
|
-
onComplete,
|
|
37263
|
-
onError
|
|
37264
|
-
);
|
|
37526
|
+
this.runIndexing(projectRoot, graphStore, repoId, onComplete, onError);
|
|
37265
37527
|
}
|
|
37266
37528
|
/** Whether indexing is currently in progress. */
|
|
37267
37529
|
isIndexing() {
|
|
@@ -37531,7 +37793,7 @@ async function computeDriftImpact(db) {
|
|
|
37531
37793
|
async function detectOrphanTestFiles(db) {
|
|
37532
37794
|
try {
|
|
37533
37795
|
const testFilesResult = await db.run(
|
|
37534
|
-
|
|
37796
|
+
"?[fp] := *entities{file_path: fp, is_test: t}, t = true"
|
|
37535
37797
|
);
|
|
37536
37798
|
const allTestFiles = new Set(
|
|
37537
37799
|
testFilesResult.rows.map((row) => row[0])
|
|
@@ -37703,7 +37965,7 @@ var workspace_manifest_exports = {};
|
|
|
37703
37965
|
__export(workspace_manifest_exports, {
|
|
37704
37966
|
WorkspaceManifest: () => WorkspaceManifest
|
|
37705
37967
|
});
|
|
37706
|
-
import { existsSync as existsSync72, mkdirSync as mkdirSync45, readFileSync as
|
|
37968
|
+
import { existsSync as existsSync72, mkdirSync as mkdirSync45, readFileSync as readFileSync63, writeFileSync as writeFileSync40 } from "fs";
|
|
37707
37969
|
import { join as join73 } from "path";
|
|
37708
37970
|
var WorkspaceManifest;
|
|
37709
37971
|
var init_workspace_manifest = __esm({
|
|
@@ -37819,7 +38081,7 @@ var init_workspace_manifest = __esm({
|
|
|
37819
38081
|
};
|
|
37820
38082
|
}
|
|
37821
38083
|
try {
|
|
37822
|
-
const raw =
|
|
38084
|
+
const raw = readFileSync63(this.manifestPath, "utf-8");
|
|
37823
38085
|
const parsed = JSON.parse(raw);
|
|
37824
38086
|
if (parsed.repoId !== this.repoId) {
|
|
37825
38087
|
return {
|
|
@@ -38338,6 +38600,83 @@ var init_middleware = __esm({
|
|
|
38338
38600
|
}
|
|
38339
38601
|
});
|
|
38340
38602
|
|
|
38603
|
+
// src/server/routes/drift.ts
|
|
38604
|
+
import { existsSync as existsSync74, readFileSync as readFileSync64, readdirSync as readdirSync15 } from "fs";
|
|
38605
|
+
import { join as join75 } from "path";
|
|
38606
|
+
import { Hono as Hono2 } from "hono";
|
|
38607
|
+
function readFlags(path7) {
|
|
38608
|
+
try {
|
|
38609
|
+
if (!existsSync74(path7)) return null;
|
|
38610
|
+
return JSON.parse(readFileSync64(path7, "utf8"));
|
|
38611
|
+
} catch {
|
|
38612
|
+
return null;
|
|
38613
|
+
}
|
|
38614
|
+
}
|
|
38615
|
+
function listSessionFiles(stateDir) {
|
|
38616
|
+
try {
|
|
38617
|
+
if (!existsSync74(stateDir)) return [];
|
|
38618
|
+
return readdirSync15(stateDir).filter((f) => f.startsWith("nudge-") && f.endsWith(".flags")).map((f) => join75(stateDir, f));
|
|
38619
|
+
} catch {
|
|
38620
|
+
return [];
|
|
38621
|
+
}
|
|
38622
|
+
}
|
|
38623
|
+
function rowFor(file) {
|
|
38624
|
+
const flags = readFlags(file);
|
|
38625
|
+
if (!flags) return null;
|
|
38626
|
+
const id = file.split("/").pop()?.replace(/^nudge-/, "").replace(/\.flags$/, "");
|
|
38627
|
+
return {
|
|
38628
|
+
session_id: id ?? "",
|
|
38629
|
+
tier0_emitted: Boolean(flags.tier0_emitted),
|
|
38630
|
+
tier1_kinds: Array.isArray(flags.tier1_emitted_kinds) ? flags.tier1_emitted_kinds : [],
|
|
38631
|
+
drift_count: typeof flags.drift_count === "number" ? flags.drift_count : 0,
|
|
38632
|
+
tier2_emitted: Boolean(flags.tier2_emitted),
|
|
38633
|
+
last_unerr_tool_at: flags.last_unerr_tool_at ?? null
|
|
38634
|
+
};
|
|
38635
|
+
}
|
|
38636
|
+
function createDriftRoutes(deps) {
|
|
38637
|
+
const app = new Hono2();
|
|
38638
|
+
const stateDir = join75(deps.cwd, ".unerr", "state");
|
|
38639
|
+
app.get("/sessions", (c) => {
|
|
38640
|
+
const rows = [];
|
|
38641
|
+
for (const file of listSessionFiles(stateDir)) {
|
|
38642
|
+
const r = rowFor(file);
|
|
38643
|
+
if (r) rows.push(r);
|
|
38644
|
+
}
|
|
38645
|
+
const totalDrift = rows.reduce((s, r) => s + r.drift_count, 0);
|
|
38646
|
+
const corrected = rows.filter((r) => r.last_unerr_tool_at).length;
|
|
38647
|
+
return c.json({
|
|
38648
|
+
data: {
|
|
38649
|
+
sessions: rows,
|
|
38650
|
+
total_sessions: rows.length,
|
|
38651
|
+
total_drift_events: totalDrift,
|
|
38652
|
+
sessions_with_correction: corrected,
|
|
38653
|
+
correction_rate: rows.length > 0 ? corrected / rows.length : 0
|
|
38654
|
+
}
|
|
38655
|
+
});
|
|
38656
|
+
});
|
|
38657
|
+
app.get("/current", (c) => {
|
|
38658
|
+
const id = process.env.UNERR_SESSION_ID ?? `pid-${process.pid}`;
|
|
38659
|
+
const file = join75(stateDir, `nudge-${id}.flags`);
|
|
38660
|
+
const row = rowFor(file);
|
|
38661
|
+
return c.json({
|
|
38662
|
+
data: row ?? {
|
|
38663
|
+
session_id: id,
|
|
38664
|
+
tier0_emitted: false,
|
|
38665
|
+
tier1_kinds: [],
|
|
38666
|
+
drift_count: 0,
|
|
38667
|
+
tier2_emitted: false,
|
|
38668
|
+
last_unerr_tool_at: null
|
|
38669
|
+
}
|
|
38670
|
+
});
|
|
38671
|
+
});
|
|
38672
|
+
return app;
|
|
38673
|
+
}
|
|
38674
|
+
var init_drift = __esm({
|
|
38675
|
+
"src/server/routes/drift.ts"() {
|
|
38676
|
+
"use strict";
|
|
38677
|
+
}
|
|
38678
|
+
});
|
|
38679
|
+
|
|
38341
38680
|
// src/intelligence/health-map-data.ts
|
|
38342
38681
|
var health_map_data_exports = {};
|
|
38343
38682
|
__export(health_map_data_exports, {
|
|
@@ -38569,7 +38908,7 @@ var init_health_map_data = __esm({
|
|
|
38569
38908
|
});
|
|
38570
38909
|
|
|
38571
38910
|
// src/server/routes/intelligence.ts
|
|
38572
|
-
import { Hono as
|
|
38911
|
+
import { Hono as Hono3 } from "hono";
|
|
38573
38912
|
function slimCallerCallee(e) {
|
|
38574
38913
|
return {
|
|
38575
38914
|
key: e.key,
|
|
@@ -38597,7 +38936,7 @@ function parseLimit(raw, fallback, max) {
|
|
|
38597
38936
|
return Math.min(n, max);
|
|
38598
38937
|
}
|
|
38599
38938
|
function createIntelligenceRoutes(deps) {
|
|
38600
|
-
const app = new
|
|
38939
|
+
const app = new Hono3();
|
|
38601
38940
|
app.get("/search", async (c) => {
|
|
38602
38941
|
const start = performance.now();
|
|
38603
38942
|
const q = (c.req.query("q") ?? "").trim();
|
|
@@ -38899,7 +39238,7 @@ function createIntelligenceRoutes(deps) {
|
|
|
38899
39238
|
const type = row[2];
|
|
38900
39239
|
if (type === "contains") {
|
|
38901
39240
|
if (!containsChildren.has(from)) containsChildren.set(from, /* @__PURE__ */ new Set());
|
|
38902
|
-
containsChildren.get(from)
|
|
39241
|
+
containsChildren.get(from)?.add(to);
|
|
38903
39242
|
childToParent.set(to, from);
|
|
38904
39243
|
} else {
|
|
38905
39244
|
relationshipEdges.push({ from, to, type });
|
|
@@ -39218,7 +39557,8 @@ function createIntelligenceRoutes(deps) {
|
|
|
39218
39557
|
for (const [, ents] of fileEntityMap) {
|
|
39219
39558
|
if (ents.length <= 1) {
|
|
39220
39559
|
if (ents.length === 1) {
|
|
39221
|
-
|
|
39560
|
+
const ent0 = ents[0];
|
|
39561
|
+
if (ent0) positions.entities[ent0.id] = { x: 0, y: 0 };
|
|
39222
39562
|
}
|
|
39223
39563
|
continue;
|
|
39224
39564
|
}
|
|
@@ -39852,7 +40192,7 @@ var init_session_history = __esm({
|
|
|
39852
40192
|
});
|
|
39853
40193
|
|
|
39854
40194
|
// src/server/routes/reasoning-quality.ts
|
|
39855
|
-
import { Hono as
|
|
40195
|
+
import { Hono as Hono4 } from "hono";
|
|
39856
40196
|
function computeQualityMetrics(events) {
|
|
39857
40197
|
if (events.length === 0) {
|
|
39858
40198
|
return {
|
|
@@ -40048,7 +40388,7 @@ function computeQualityMetrics(events) {
|
|
|
40048
40388
|
};
|
|
40049
40389
|
}
|
|
40050
40390
|
function createReasoningQualityRoutes(deps) {
|
|
40051
|
-
const app = new
|
|
40391
|
+
const app = new Hono4();
|
|
40052
40392
|
app.get("/global", (c) => {
|
|
40053
40393
|
const start = performance.now();
|
|
40054
40394
|
const fromTs = c.req.query("from_ts");
|
|
@@ -40173,7 +40513,7 @@ function createReasoningQualityRoutes(deps) {
|
|
|
40173
40513
|
memory_signals_fired: m.memory_signals_fired,
|
|
40174
40514
|
memory_verdicts_total: m.memory_verdicts_total
|
|
40175
40515
|
};
|
|
40176
|
-
}).sort((a, b) => b.last_ts.localeCompare(a.last_ts));
|
|
40516
|
+
}).sort((a, b) => (b.last_ts ?? "").localeCompare(a.last_ts ?? ""));
|
|
40177
40517
|
const paginated = allSessions.slice(offset, offset + limit);
|
|
40178
40518
|
return c.json({
|
|
40179
40519
|
data: paginated,
|
|
@@ -40249,14 +40589,14 @@ var init_reasoning_quality = __esm({
|
|
|
40249
40589
|
});
|
|
40250
40590
|
|
|
40251
40591
|
// src/server/routes/session.ts
|
|
40252
|
-
import { Hono as
|
|
40592
|
+
import { Hono as Hono5 } from "hono";
|
|
40253
40593
|
function parseLimit2(raw, fallback, max) {
|
|
40254
40594
|
const n = Number.parseInt(raw ?? "", 10);
|
|
40255
40595
|
if (Number.isNaN(n) || n < 1) return fallback;
|
|
40256
40596
|
return Math.min(n, max);
|
|
40257
40597
|
}
|
|
40258
40598
|
function createSessionRoutes(deps) {
|
|
40259
|
-
const app = new
|
|
40599
|
+
const app = new Hono5();
|
|
40260
40600
|
app.get("/stats", async (c) => {
|
|
40261
40601
|
const start = performance.now();
|
|
40262
40602
|
const s = deps.stats;
|
|
@@ -40339,10 +40679,10 @@ var init_session = __esm({
|
|
|
40339
40679
|
});
|
|
40340
40680
|
|
|
40341
40681
|
// src/server/routes/stream.ts
|
|
40342
|
-
import { Hono as
|
|
40682
|
+
import { Hono as Hono6 } from "hono";
|
|
40343
40683
|
import { streamSSE } from "hono/streaming";
|
|
40344
40684
|
function createStreamRoutes(deps) {
|
|
40345
|
-
const app = new
|
|
40685
|
+
const app = new Hono6();
|
|
40346
40686
|
app.get("/", (c) => {
|
|
40347
40687
|
return streamSSE(c, async (stream) => {
|
|
40348
40688
|
let id = 0;
|
|
@@ -40429,7 +40769,7 @@ function createStreamRoutes(deps) {
|
|
|
40429
40769
|
}
|
|
40430
40770
|
}, 3e4);
|
|
40431
40771
|
while (!aborted) {
|
|
40432
|
-
await new Promise((
|
|
40772
|
+
await new Promise((resolve9) => setTimeout(resolve9, 1e3));
|
|
40433
40773
|
}
|
|
40434
40774
|
clearInterval(pingInterval);
|
|
40435
40775
|
clearInterval(statsInterval);
|
|
@@ -40447,9 +40787,9 @@ var init_stream = __esm({
|
|
|
40447
40787
|
});
|
|
40448
40788
|
|
|
40449
40789
|
// src/server/routes/system.ts
|
|
40450
|
-
import { Hono as
|
|
40790
|
+
import { Hono as Hono7 } from "hono";
|
|
40451
40791
|
function createSystemRoutes(deps) {
|
|
40452
|
-
const app = new
|
|
40792
|
+
const app = new Hono7();
|
|
40453
40793
|
app.get("/status", async (c) => {
|
|
40454
40794
|
const start = performance.now();
|
|
40455
40795
|
const uptime = Math.round((Date.now() - deps.startedAt) / 1e3);
|
|
@@ -40479,13 +40819,13 @@ function createSystemRoutes(deps) {
|
|
|
40479
40819
|
});
|
|
40480
40820
|
app.get("/config", async (c) => {
|
|
40481
40821
|
const start = performance.now();
|
|
40482
|
-
const { existsSync: existsSync80, readFileSync:
|
|
40822
|
+
const { existsSync: existsSync80, readFileSync: readFileSync68 } = await import("fs");
|
|
40483
40823
|
const { join: join81 } = await import("path");
|
|
40484
40824
|
let config = {};
|
|
40485
40825
|
const configPath = join81(deps.cwd, ".unerr", "config.json");
|
|
40486
40826
|
if (existsSync80(configPath)) {
|
|
40487
40827
|
try {
|
|
40488
|
-
config = JSON.parse(
|
|
40828
|
+
config = JSON.parse(readFileSync68(configPath, "utf-8"));
|
|
40489
40829
|
} catch {
|
|
40490
40830
|
config = { error: "unreadable" };
|
|
40491
40831
|
}
|
|
@@ -40519,83 +40859,6 @@ var init_system = __esm({
|
|
|
40519
40859
|
}
|
|
40520
40860
|
});
|
|
40521
40861
|
|
|
40522
|
-
// src/server/routes/drift.ts
|
|
40523
|
-
import { existsSync as existsSync74, readFileSync as readFileSync63, readdirSync as readdirSync15 } from "fs";
|
|
40524
|
-
import { join as join75 } from "path";
|
|
40525
|
-
import { Hono as Hono7 } from "hono";
|
|
40526
|
-
function readFlags(path7) {
|
|
40527
|
-
try {
|
|
40528
|
-
if (!existsSync74(path7)) return null;
|
|
40529
|
-
return JSON.parse(readFileSync63(path7, "utf8"));
|
|
40530
|
-
} catch {
|
|
40531
|
-
return null;
|
|
40532
|
-
}
|
|
40533
|
-
}
|
|
40534
|
-
function listSessionFiles(stateDir) {
|
|
40535
|
-
try {
|
|
40536
|
-
if (!existsSync74(stateDir)) return [];
|
|
40537
|
-
return readdirSync15(stateDir).filter((f) => f.startsWith("nudge-") && f.endsWith(".flags")).map((f) => join75(stateDir, f));
|
|
40538
|
-
} catch {
|
|
40539
|
-
return [];
|
|
40540
|
-
}
|
|
40541
|
-
}
|
|
40542
|
-
function rowFor(file) {
|
|
40543
|
-
const flags = readFlags(file);
|
|
40544
|
-
if (!flags) return null;
|
|
40545
|
-
const id = file.split("/").pop().replace(/^nudge-/, "").replace(/\.flags$/, "");
|
|
40546
|
-
return {
|
|
40547
|
-
session_id: id,
|
|
40548
|
-
tier0_emitted: Boolean(flags.tier0_emitted),
|
|
40549
|
-
tier1_kinds: Array.isArray(flags.tier1_emitted_kinds) ? flags.tier1_emitted_kinds : [],
|
|
40550
|
-
drift_count: typeof flags.drift_count === "number" ? flags.drift_count : 0,
|
|
40551
|
-
tier2_emitted: Boolean(flags.tier2_emitted),
|
|
40552
|
-
last_unerr_tool_at: flags.last_unerr_tool_at ?? null
|
|
40553
|
-
};
|
|
40554
|
-
}
|
|
40555
|
-
function createDriftRoutes(deps) {
|
|
40556
|
-
const app = new Hono7();
|
|
40557
|
-
const stateDir = join75(deps.cwd, ".unerr", "state");
|
|
40558
|
-
app.get("/sessions", (c) => {
|
|
40559
|
-
const rows = [];
|
|
40560
|
-
for (const file of listSessionFiles(stateDir)) {
|
|
40561
|
-
const r = rowFor(file);
|
|
40562
|
-
if (r) rows.push(r);
|
|
40563
|
-
}
|
|
40564
|
-
const totalDrift = rows.reduce((s, r) => s + r.drift_count, 0);
|
|
40565
|
-
const corrected = rows.filter((r) => r.last_unerr_tool_at).length;
|
|
40566
|
-
return c.json({
|
|
40567
|
-
data: {
|
|
40568
|
-
sessions: rows,
|
|
40569
|
-
total_sessions: rows.length,
|
|
40570
|
-
total_drift_events: totalDrift,
|
|
40571
|
-
sessions_with_correction: corrected,
|
|
40572
|
-
correction_rate: rows.length > 0 ? corrected / rows.length : 0
|
|
40573
|
-
}
|
|
40574
|
-
});
|
|
40575
|
-
});
|
|
40576
|
-
app.get("/current", (c) => {
|
|
40577
|
-
const id = process.env.UNERR_SESSION_ID ?? `pid-${process.pid}`;
|
|
40578
|
-
const file = join75(stateDir, `nudge-${id}.flags`);
|
|
40579
|
-
const row = rowFor(file);
|
|
40580
|
-
return c.json({
|
|
40581
|
-
data: row ?? {
|
|
40582
|
-
session_id: id,
|
|
40583
|
-
tier0_emitted: false,
|
|
40584
|
-
tier1_kinds: [],
|
|
40585
|
-
drift_count: 0,
|
|
40586
|
-
tier2_emitted: false,
|
|
40587
|
-
last_unerr_tool_at: null
|
|
40588
|
-
}
|
|
40589
|
-
});
|
|
40590
|
-
});
|
|
40591
|
-
return app;
|
|
40592
|
-
}
|
|
40593
|
-
var init_drift = __esm({
|
|
40594
|
-
"src/server/routes/drift.ts"() {
|
|
40595
|
-
"use strict";
|
|
40596
|
-
}
|
|
40597
|
-
});
|
|
40598
|
-
|
|
40599
40862
|
// src/server/routes/temporal.ts
|
|
40600
40863
|
import { Hono as Hono8 } from "hono";
|
|
40601
40864
|
function createTemporalRoutes(deps) {
|
|
@@ -40861,7 +41124,7 @@ function detectLoops(entries, opts = {}) {
|
|
|
40861
41124
|
return all.sort((a, b) => Date.parse(b.last_ts) - Date.parse(a.last_ts));
|
|
40862
41125
|
}
|
|
40863
41126
|
function maxTs(entries) {
|
|
40864
|
-
let max =
|
|
41127
|
+
let max = Number.NEGATIVE_INFINITY;
|
|
40865
41128
|
for (const e of entries) {
|
|
40866
41129
|
const t = entryTsMs(e);
|
|
40867
41130
|
if (Number.isFinite(t) && t > max) max = t;
|
|
@@ -40872,12 +41135,7 @@ var READ_TOOLS, EDIT_TOOLS8, DEFAULT_READ_WINDOW_MS, DEFAULT_QUERY_WINDOW_MS, DE
|
|
|
40872
41135
|
var init_loop_miner = __esm({
|
|
40873
41136
|
"src/timeline/loop-miner.ts"() {
|
|
40874
41137
|
"use strict";
|
|
40875
|
-
READ_TOOLS = /* @__PURE__ */ new Set([
|
|
40876
|
-
"file_read",
|
|
40877
|
-
"file_outline",
|
|
40878
|
-
"get_file",
|
|
40879
|
-
"Read"
|
|
40880
|
-
]);
|
|
41138
|
+
READ_TOOLS = /* @__PURE__ */ new Set(["file_read", "file_outline", "get_file", "Read"]);
|
|
40881
41139
|
EDIT_TOOLS8 = /* @__PURE__ */ new Set([
|
|
40882
41140
|
"Edit",
|
|
40883
41141
|
"Write",
|
|
@@ -41135,9 +41393,9 @@ function createTimelineRoutes(deps) {
|
|
|
41135
41393
|
var init_timeline = __esm({
|
|
41136
41394
|
"src/server/routes/timeline.ts"() {
|
|
41137
41395
|
"use strict";
|
|
41396
|
+
init_intent_detector();
|
|
41138
41397
|
init_loop_miner();
|
|
41139
41398
|
init_open_threads();
|
|
41140
|
-
init_intent_detector();
|
|
41141
41399
|
}
|
|
41142
41400
|
});
|
|
41143
41401
|
|
|
@@ -41507,20 +41765,20 @@ var http_exports = {};
|
|
|
41507
41765
|
__export(http_exports, {
|
|
41508
41766
|
startDashboardServer: () => startDashboardServer
|
|
41509
41767
|
});
|
|
41510
|
-
import { existsSync as existsSync75, readFileSync as
|
|
41768
|
+
import { existsSync as existsSync75, readFileSync as readFileSync65, unlinkSync as unlinkSync14, writeFileSync as writeFileSync41 } from "fs";
|
|
41511
41769
|
import { createServer as createServer4 } from "net";
|
|
41512
|
-
import { dirname as
|
|
41770
|
+
import { dirname as dirname14, join as join76 } from "path";
|
|
41513
41771
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
41514
41772
|
import { serve as serve2 } from "@hono/node-server";
|
|
41515
41773
|
import { serveStatic as serveStatic2 } from "@hono/node-server/serve-static";
|
|
41516
41774
|
import { Hono as Hono11 } from "hono";
|
|
41517
41775
|
async function findAvailablePort() {
|
|
41518
41776
|
for (let port = PORT_START; port <= PORT_END; port++) {
|
|
41519
|
-
const available = await new Promise((
|
|
41777
|
+
const available = await new Promise((resolve9) => {
|
|
41520
41778
|
const server = createServer4();
|
|
41521
|
-
server.once("error", () =>
|
|
41779
|
+
server.once("error", () => resolve9(false));
|
|
41522
41780
|
server.once("listening", () => {
|
|
41523
|
-
server.close(() =>
|
|
41781
|
+
server.close(() => resolve9(true));
|
|
41524
41782
|
});
|
|
41525
41783
|
server.listen(port, "127.0.0.1");
|
|
41526
41784
|
});
|
|
@@ -41563,10 +41821,10 @@ async function startDashboardServer(opts) {
|
|
|
41563
41821
|
);
|
|
41564
41822
|
}
|
|
41565
41823
|
if (!opts.apiOnly) {
|
|
41566
|
-
const distDir = join76(
|
|
41824
|
+
const distDir = join76(dirname14(fileURLToPath3(import.meta.url)), "ui");
|
|
41567
41825
|
const spaIndex = join76(distDir, "index.html");
|
|
41568
41826
|
if (existsSync75(spaIndex)) {
|
|
41569
|
-
const spaHtml =
|
|
41827
|
+
const spaHtml = readFileSync65(spaIndex, "utf-8");
|
|
41570
41828
|
app.use("*", serveStatic2({ root: distDir }));
|
|
41571
41829
|
app.get("*", (c) => {
|
|
41572
41830
|
const path7 = c.req.path;
|
|
@@ -41626,12 +41884,12 @@ var init_http = __esm({
|
|
|
41626
41884
|
"src/server/http.ts"() {
|
|
41627
41885
|
"use strict";
|
|
41628
41886
|
init_middleware();
|
|
41887
|
+
init_drift();
|
|
41629
41888
|
init_intelligence();
|
|
41630
41889
|
init_reasoning_quality();
|
|
41631
41890
|
init_session();
|
|
41632
41891
|
init_stream();
|
|
41633
41892
|
init_system();
|
|
41634
|
-
init_drift();
|
|
41635
41893
|
init_temporal();
|
|
41636
41894
|
init_timeline();
|
|
41637
41895
|
init_token_flow2();
|
|
@@ -41718,7 +41976,9 @@ function printSessionReceipt(input) {
|
|
|
41718
41976
|
}
|
|
41719
41977
|
}
|
|
41720
41978
|
function stripAnsi3(s) {
|
|
41721
|
-
|
|
41979
|
+
const ESC2 = "\x1B";
|
|
41980
|
+
const CSI = new RegExp(`${ESC2}\\[[0-9;?]*[A-Za-z~]`, "g");
|
|
41981
|
+
return s.replace(CSI, "");
|
|
41722
41982
|
}
|
|
41723
41983
|
var DIM2, BOLD2, RESET2, EMERALD2, CYAN2, VIOLET2, MUTED2;
|
|
41724
41984
|
var init_session_receipt = __esm({
|
|
@@ -42024,7 +42284,7 @@ import {
|
|
|
42024
42284
|
existsSync as existsSync76,
|
|
42025
42285
|
writeFileSync as fsWriteFileSync,
|
|
42026
42286
|
mkdirSync as mkdirSync46,
|
|
42027
|
-
readFileSync as
|
|
42287
|
+
readFileSync as readFileSync66,
|
|
42028
42288
|
readdirSync as readdirSync16
|
|
42029
42289
|
} from "fs";
|
|
42030
42290
|
import { join as join77 } from "path";
|
|
@@ -42122,8 +42382,8 @@ async function handleRecallFactsProxy(args, unerrDir, effectiveness) {
|
|
|
42122
42382
|
}
|
|
42123
42383
|
const useRotation = rotationMode !== "none" && proxyShowStore !== null;
|
|
42124
42384
|
const ranked = rankFactsWithRotation2(facts, {
|
|
42125
|
-
getShowCount: useRotation ? (id) => proxyShowStore
|
|
42126
|
-
getLastShownMs: useRotation ? (id) => proxyShowStore
|
|
42385
|
+
getShowCount: useRotation ? (id) => proxyShowStore?.getEffectiveShowCount(id) ?? 0 : void 0,
|
|
42386
|
+
getLastShownMs: useRotation ? (id) => proxyShowStore?.getLastShownMs(id) ?? 0 : void 0
|
|
42127
42387
|
});
|
|
42128
42388
|
const total = ranked.length;
|
|
42129
42389
|
const sliced = applyDiversityQuota2(ranked, requestedLimit);
|
|
@@ -42178,14 +42438,15 @@ function migrateAgentPermissions(cwd) {
|
|
|
42178
42438
|
try {
|
|
42179
42439
|
const settingsPath = join77(cwd, ".claude", "settings.json");
|
|
42180
42440
|
if (!existsSync76(settingsPath)) return;
|
|
42181
|
-
const raw =
|
|
42441
|
+
const raw = readFileSync66(settingsPath, "utf-8");
|
|
42182
42442
|
const settings = JSON.parse(raw);
|
|
42183
42443
|
const deny = settings?.permissions?.deny;
|
|
42184
42444
|
if (!Array.isArray(deny)) return;
|
|
42185
42445
|
const readIdx = deny.indexOf("Read");
|
|
42186
42446
|
if (readIdx < 0) return;
|
|
42187
42447
|
deny.splice(readIdx, 1);
|
|
42188
|
-
fsWriteFileSync(settingsPath, JSON.stringify(settings, null, 2)
|
|
42448
|
+
fsWriteFileSync(settingsPath, `${JSON.stringify(settings, null, 2)}
|
|
42449
|
+
`);
|
|
42189
42450
|
process.stderr.write(
|
|
42190
42451
|
"[unerr] Migrated permissions: removed Read from deny list (required for Edit workflow)\n"
|
|
42191
42452
|
);
|
|
@@ -42244,7 +42505,7 @@ async function startProxy(opts = {}) {
|
|
|
42244
42505
|
const configPath = join77(process.cwd(), ".unerr", "config.json");
|
|
42245
42506
|
if (existsSync76(configPath)) {
|
|
42246
42507
|
try {
|
|
42247
|
-
const config = JSON.parse(
|
|
42508
|
+
const config = JSON.parse(readFileSync66(configPath, "utf-8"));
|
|
42248
42509
|
if (config.repoId) repoIds = [config.repoId];
|
|
42249
42510
|
} catch {
|
|
42250
42511
|
}
|
|
@@ -42633,7 +42894,7 @@ async function startProxy(opts = {}) {
|
|
|
42633
42894
|
const { StdioServerTransport } = await import("@modelcontextprotocol/sdk/server/stdio.js");
|
|
42634
42895
|
const { ListToolsRequestSchema, CallToolRequestSchema } = await import("@modelcontextprotocol/sdk/types.js");
|
|
42635
42896
|
const server = new Server(
|
|
42636
|
-
{ name: "unerr-local", version: "0.1.
|
|
42897
|
+
{ name: "unerr-local", version: "0.1.2" },
|
|
42637
42898
|
{ capabilities: { tools: {} } }
|
|
42638
42899
|
);
|
|
42639
42900
|
const toolDefinitions = [...TOOL_DEFINITIONS];
|
|
@@ -42812,9 +43073,7 @@ async function startProxy(opts = {}) {
|
|
|
42812
43073
|
);
|
|
42813
43074
|
router.setEffectivenessTracker(effectivenessTracker);
|
|
42814
43075
|
shadowLedger.getTurnSegmenter().onTurnClose(() => {
|
|
42815
|
-
effectivenessTracker.closeWindow(
|
|
42816
|
-
router.sessionContext.getToolCallCount()
|
|
42817
|
-
);
|
|
43076
|
+
effectivenessTracker.closeWindow(router.sessionContext.getToolCallCount());
|
|
42818
43077
|
});
|
|
42819
43078
|
const { WorkingSnapshotStore: WorkingSnapshotStore2 } = await Promise.resolve().then(() => (init_working_snapshots(), working_snapshots_exports));
|
|
42820
43079
|
const workingSnapshotStore = new WorkingSnapshotStore2(unerrDirForLedger);
|
|
@@ -42884,9 +43143,7 @@ async function startProxy(opts = {}) {
|
|
|
42884
43143
|
`
|
|
42885
43144
|
);
|
|
42886
43145
|
return {
|
|
42887
|
-
content: [
|
|
42888
|
-
{ type: "text", text: JSON.stringify(validationFailure) }
|
|
42889
|
-
],
|
|
43146
|
+
content: [{ type: "text", text: JSON.stringify(validationFailure) }],
|
|
42890
43147
|
isError: true
|
|
42891
43148
|
};
|
|
42892
43149
|
}
|
|
@@ -42954,23 +43211,24 @@ async function startProxy(opts = {}) {
|
|
|
42954
43211
|
headShaVal = await getHeadSha3(process.cwd()) ?? "";
|
|
42955
43212
|
} catch {
|
|
42956
43213
|
}
|
|
42957
|
-
return handleMarkerCall2(
|
|
42958
|
-
|
|
42959
|
-
|
|
42960
|
-
|
|
42961
|
-
|
|
42962
|
-
|
|
42963
|
-
branch: branchVal,
|
|
42964
|
-
headSha: headShaVal
|
|
42965
|
-
}
|
|
42966
|
-
);
|
|
43214
|
+
return handleMarkerCall2(name, args, {
|
|
43215
|
+
ledger: shadowLedger,
|
|
43216
|
+
store: timelineHandle.store,
|
|
43217
|
+
branch: branchVal,
|
|
43218
|
+
headSha: headShaVal
|
|
43219
|
+
});
|
|
42967
43220
|
}
|
|
42968
43221
|
}
|
|
42969
43222
|
if (name === "record_fact" || name === "recall_facts") {
|
|
42970
|
-
const factResult = name === "record_fact" ? await handleRecordFactProxy(
|
|
42971
|
-
|
|
42972
|
-
|
|
42973
|
-
|
|
43223
|
+
const factResult = name === "record_fact" ? await handleRecordFactProxy(
|
|
43224
|
+
args,
|
|
43225
|
+
unerrDirForLedger,
|
|
43226
|
+
shadowLedger,
|
|
43227
|
+
{
|
|
43228
|
+
tracker: effectivenessTracker,
|
|
43229
|
+
turn: router.sessionContext.getToolCallCount()
|
|
43230
|
+
}
|
|
43231
|
+
) : await handleRecallFactsProxy(args, unerrDirForLedger, {
|
|
42974
43232
|
tracker: effectivenessTracker,
|
|
42975
43233
|
turn: router.sessionContext.getToolCallCount()
|
|
42976
43234
|
});
|
|
@@ -43127,7 +43385,7 @@ async function startProxy(opts = {}) {
|
|
|
43127
43385
|
const lastEntry = recentEntries[recentEntries.length - 1];
|
|
43128
43386
|
if (lastEntry) {
|
|
43129
43387
|
setImmediate(
|
|
43130
|
-
() => narrativeCapture
|
|
43388
|
+
() => narrativeCapture?.captureEditNarrative(lastEntry).catch(() => {
|
|
43131
43389
|
})
|
|
43132
43390
|
);
|
|
43133
43391
|
}
|
|
@@ -43137,11 +43395,11 @@ async function startProxy(opts = {}) {
|
|
|
43137
43395
|
setImmediate(async () => {
|
|
43138
43396
|
try {
|
|
43139
43397
|
const { analyzeSessionPatterns: analyzeSessionPatterns2 } = await Promise.resolve().then(() => (init_session_pattern_analyzer(), session_pattern_analyzer_exports));
|
|
43140
|
-
const entries = shadowLedger
|
|
43398
|
+
const entries = shadowLedger?.getRecentEntries(20);
|
|
43141
43399
|
await analyzeSessionPatterns2({
|
|
43142
43400
|
ledgerEntries: entries,
|
|
43143
43401
|
factStore: proxyFactStore2,
|
|
43144
|
-
sessionId: shadowLedger
|
|
43402
|
+
sessionId: shadowLedger?.getSessionId()
|
|
43145
43403
|
});
|
|
43146
43404
|
} catch {
|
|
43147
43405
|
}
|
|
@@ -43248,7 +43506,7 @@ ${signalFooter.trimEnd()}` : "";
|
|
|
43248
43506
|
result: {
|
|
43249
43507
|
protocolVersion: "2024-11-05",
|
|
43250
43508
|
capabilities: { tools: {} },
|
|
43251
|
-
serverInfo: { name: "unerr-local", version: "0.1.
|
|
43509
|
+
serverInfo: { name: "unerr-local", version: "0.1.2" }
|
|
43252
43510
|
}
|
|
43253
43511
|
};
|
|
43254
43512
|
}
|
|
@@ -43808,7 +44066,7 @@ ${signalFooter2.trimEnd()}` : "";
|
|
|
43808
44066
|
});
|
|
43809
44067
|
for (const file of sourceFiles.slice(0, 500)) {
|
|
43810
44068
|
try {
|
|
43811
|
-
const content =
|
|
44069
|
+
const content = readFileSync66(join77(process.cwd(), file), "utf-8");
|
|
43812
44070
|
const entities = extractEntitiesFromSource2(file, content);
|
|
43813
44071
|
parseIndex.addEntities(entities);
|
|
43814
44072
|
} catch {
|
|
@@ -43978,7 +44236,7 @@ ${signalFooter2.trimEnd()}` : "";
|
|
|
43978
44236
|
temporal: await (async () => {
|
|
43979
44237
|
try {
|
|
43980
44238
|
const { TemporalFactStore: TemporalFactStore2 } = await Promise.resolve().then(() => (init_temporal_facts(), temporal_facts_exports));
|
|
43981
|
-
const { readdirSync: readdirSync18, readFileSync:
|
|
44239
|
+
const { readdirSync: readdirSync18, readFileSync: readFileSync68 } = await import("fs");
|
|
43982
44240
|
const factStore = await TemporalFactStore2.create(process.cwd());
|
|
43983
44241
|
return {
|
|
43984
44242
|
factStore,
|
|
@@ -43987,7 +44245,7 @@ ${signalFooter2.trimEnd()}` : "";
|
|
|
43987
44245
|
const sessDir = join77(unerrDirForApi, "sessions");
|
|
43988
44246
|
const files = readdirSync18(sessDir).filter((f) => f.endsWith(".jsonl")).sort().slice(-limit);
|
|
43989
44247
|
return files.map((f) => {
|
|
43990
|
-
const content =
|
|
44248
|
+
const content = readFileSync68(join77(sessDir, f), "utf-8").trim().split("\n").pop();
|
|
43991
44249
|
return JSON.parse(content);
|
|
43992
44250
|
});
|
|
43993
44251
|
} catch {
|
|
@@ -44152,10 +44410,7 @@ ${signalFooter2.trimEnd()}` : "";
|
|
|
44152
44410
|
const counterfactualStr = tokensWithout > 0 ? formatCounterfactual2(tokensWithout, tokensWithout - tokensSaved) : void 0;
|
|
44153
44411
|
try {
|
|
44154
44412
|
const React3 = __require("react");
|
|
44155
|
-
const { SessionSummaryCard: SessionSummaryCard2 } = (
|
|
44156
|
-
// biome-ignore lint/suspicious/noExplicitAny: dynamic require in non-critical shutdown path
|
|
44157
|
-
(init_SessionSummaryCard(), __toCommonJS(SessionSummaryCard_exports))
|
|
44158
|
-
);
|
|
44413
|
+
const { SessionSummaryCard: SessionSummaryCard2 } = (init_SessionSummaryCard(), __toCommonJS(SessionSummaryCard_exports));
|
|
44159
44414
|
const { ThemeProvider: ThemeProvider2 } = (init_Theme(), __toCommonJS(Theme_exports));
|
|
44160
44415
|
const { renderToStderr: renderToStderr2 } = (init_render(), __toCommonJS(render_exports));
|
|
44161
44416
|
const el = React3.createElement(
|
|
@@ -44448,12 +44703,12 @@ var log21, proxyFactStore, proxyShowStore;
|
|
|
44448
44703
|
var init_proxy = __esm({
|
|
44449
44704
|
"src/proxy/proxy.ts"() {
|
|
44450
44705
|
"use strict";
|
|
44706
|
+
init_arg_validator();
|
|
44451
44707
|
init_pid_lock();
|
|
44452
44708
|
init_session_stats();
|
|
44453
44709
|
init_startup_renderer();
|
|
44454
44710
|
init_tool_clusters();
|
|
44455
44711
|
init_tool_definitions();
|
|
44456
|
-
init_arg_validator();
|
|
44457
44712
|
init_file_logger();
|
|
44458
44713
|
init_format_error();
|
|
44459
44714
|
init_mcp_content_json();
|
|
@@ -45014,7 +45269,7 @@ __export(bridge_exports, {
|
|
|
45014
45269
|
});
|
|
45015
45270
|
import { connect } from "net";
|
|
45016
45271
|
function startUdsBridge(sockPath2) {
|
|
45017
|
-
return new Promise((
|
|
45272
|
+
return new Promise((resolve9, reject) => {
|
|
45018
45273
|
const socket = connect(sockPath2);
|
|
45019
45274
|
let heartbeatTimer;
|
|
45020
45275
|
let heartbeatTimeoutTimer;
|
|
@@ -45027,7 +45282,7 @@ function startUdsBridge(sockPath2) {
|
|
|
45027
45282
|
if (heartbeatTimer) clearInterval(heartbeatTimer);
|
|
45028
45283
|
if (heartbeatTimeoutTimer) clearTimeout(heartbeatTimeoutTimer);
|
|
45029
45284
|
if (!socket.destroyed) socket.destroy();
|
|
45030
|
-
|
|
45285
|
+
resolve9({ reason });
|
|
45031
45286
|
}
|
|
45032
45287
|
socket.on("connect", () => {
|
|
45033
45288
|
log23.info(`Connected to proxy at ${sockPath2}`);
|
|
@@ -45077,7 +45332,8 @@ function startUdsBridge(sockPath2) {
|
|
|
45077
45332
|
params: { ts: Date.now() }
|
|
45078
45333
|
});
|
|
45079
45334
|
try {
|
|
45080
|
-
socket.write(ping
|
|
45335
|
+
socket.write(`${ping}
|
|
45336
|
+
`);
|
|
45081
45337
|
} catch {
|
|
45082
45338
|
cleanup("daemon_dead");
|
|
45083
45339
|
return;
|
|
@@ -45127,7 +45383,7 @@ var init_bridge = __esm({
|
|
|
45127
45383
|
});
|
|
45128
45384
|
|
|
45129
45385
|
// src/entrypoints/cli.ts
|
|
45130
|
-
import { existsSync as existsSync79, readFileSync as
|
|
45386
|
+
import { existsSync as existsSync79, readFileSync as readFileSync67 } from "fs";
|
|
45131
45387
|
import { join as join80 } from "path";
|
|
45132
45388
|
import { Command } from "commander";
|
|
45133
45389
|
|
|
@@ -45521,7 +45777,7 @@ init_config_verify();
|
|
|
45521
45777
|
|
|
45522
45778
|
// src/commands/daemon.ts
|
|
45523
45779
|
init_registry();
|
|
45524
|
-
import { resolve as
|
|
45780
|
+
import { resolve as resolve5 } from "path";
|
|
45525
45781
|
|
|
45526
45782
|
// src/daemon/settings-schema.ts
|
|
45527
45783
|
init_protocol();
|
|
@@ -45604,9 +45860,7 @@ function registerDaemonCommand(program2) {
|
|
|
45604
45860
|
const { existsSync: existsSync80, mkdirSync: mkdirSync49, writeFileSync: writeFileSync43 } = await import("fs");
|
|
45605
45861
|
const { homedir: homedir16 } = await import("os");
|
|
45606
45862
|
const { join: join81 } = await import("path");
|
|
45607
|
-
write2(
|
|
45608
|
-
"\x1B[38;2;139;92;246m\u25B8\x1B[0m Initializing unerr daemon...\n"
|
|
45609
|
-
);
|
|
45863
|
+
write2("\x1B[38;2;139;92;246m\u25B8\x1B[0m Initializing unerr daemon...\n");
|
|
45610
45864
|
const result = await installForCurrentPlatform2();
|
|
45611
45865
|
if (result.installed) {
|
|
45612
45866
|
const sentinel = join81(homedir16(), ".unerr", ".autostart-installed");
|
|
@@ -45718,8 +45972,8 @@ function registerDaemonCommand(program2) {
|
|
|
45718
45972
|
const pidPath2 = join81(homedir16(), ".unerr", "unerrd.pid");
|
|
45719
45973
|
let daemonPid = String(child.pid);
|
|
45720
45974
|
try {
|
|
45721
|
-
const { readFileSync:
|
|
45722
|
-
daemonPid =
|
|
45975
|
+
const { readFileSync: readFileSync68 } = await import("fs");
|
|
45976
|
+
daemonPid = readFileSync68(pidPath2, "utf-8").trim();
|
|
45723
45977
|
} catch {
|
|
45724
45978
|
}
|
|
45725
45979
|
write2(
|
|
@@ -45744,19 +45998,19 @@ function registerDaemonCommand(program2) {
|
|
|
45744
45998
|
return;
|
|
45745
45999
|
}
|
|
45746
46000
|
try {
|
|
45747
|
-
await new Promise((
|
|
46001
|
+
await new Promise((resolve9, reject) => {
|
|
45748
46002
|
const conn = createConnection3(sock, () => {
|
|
45749
46003
|
conn.write(`${JSON.stringify({ cmd: "shutdown" })}
|
|
45750
46004
|
`);
|
|
45751
46005
|
});
|
|
45752
46006
|
conn.on("data", () => {
|
|
45753
46007
|
conn.destroy();
|
|
45754
|
-
|
|
46008
|
+
resolve9();
|
|
45755
46009
|
});
|
|
45756
46010
|
conn.on("error", (err) => reject(err));
|
|
45757
46011
|
setTimeout(() => {
|
|
45758
46012
|
conn.destroy();
|
|
45759
|
-
|
|
46013
|
+
resolve9();
|
|
45760
46014
|
}, 3e3);
|
|
45761
46015
|
});
|
|
45762
46016
|
write2("\x1B[38;2;52;211;153m\u2713\x1B[0m unerrd stopped.\n");
|
|
@@ -45780,19 +46034,19 @@ function registerDaemonCommand(program2) {
|
|
|
45780
46034
|
if (existsSync80(sock)) {
|
|
45781
46035
|
write2("\x1B[38;2;139;92;246m\u25B8\x1B[0m Stopping unerrd...\n");
|
|
45782
46036
|
try {
|
|
45783
|
-
await new Promise((
|
|
46037
|
+
await new Promise((resolve9, reject) => {
|
|
45784
46038
|
const conn = createConnection3(sock, () => {
|
|
45785
46039
|
conn.write(`${JSON.stringify({ cmd: "shutdown" })}
|
|
45786
46040
|
`);
|
|
45787
46041
|
});
|
|
45788
46042
|
conn.on("data", () => {
|
|
45789
46043
|
conn.destroy();
|
|
45790
|
-
|
|
46044
|
+
resolve9();
|
|
45791
46045
|
});
|
|
45792
46046
|
conn.on("error", (err) => reject(err));
|
|
45793
46047
|
setTimeout(() => {
|
|
45794
46048
|
conn.destroy();
|
|
45795
|
-
|
|
46049
|
+
resolve9();
|
|
45796
46050
|
}, 3e3);
|
|
45797
46051
|
});
|
|
45798
46052
|
stopped = true;
|
|
@@ -45818,14 +46072,10 @@ function registerDaemonCommand(program2) {
|
|
|
45818
46072
|
`
|
|
45819
46073
|
);
|
|
45820
46074
|
} else {
|
|
45821
|
-
write2(
|
|
45822
|
-
"\x1B[38;2;52;211;153m\u2713\x1B[0m Boot registration removed.\n"
|
|
45823
|
-
);
|
|
46075
|
+
write2("\x1B[38;2;52;211;153m\u2713\x1B[0m Boot registration removed.\n");
|
|
45824
46076
|
}
|
|
45825
46077
|
} catch {
|
|
45826
|
-
write2(
|
|
45827
|
-
"\x1B[38;2;251;191;36m\u26A0\x1B[0m No boot registration found.\n"
|
|
45828
|
-
);
|
|
46078
|
+
write2("\x1B[38;2;251;191;36m\u26A0\x1B[0m No boot registration found.\n");
|
|
45829
46079
|
}
|
|
45830
46080
|
const pidFile = join81(home, "unerrd.pid");
|
|
45831
46081
|
for (const f of [sock, pidFile]) {
|
|
@@ -45840,18 +46090,16 @@ function registerDaemonCommand(program2) {
|
|
|
45840
46090
|
write2("\x1B[38;2;139;92;246m\u25B8\x1B[0m Purging ~/.unerr...\n");
|
|
45841
46091
|
if (existsSync80(home)) {
|
|
45842
46092
|
rmSync5(home, { recursive: true, force: true });
|
|
45843
|
-
write2(
|
|
45844
|
-
"\x1B[38;2;52;211;153m\u2713\x1B[0m ~/.unerr removed.\n"
|
|
45845
|
-
);
|
|
46093
|
+
write2("\x1B[38;2;52;211;153m\u2713\x1B[0m ~/.unerr removed.\n");
|
|
45846
46094
|
}
|
|
45847
46095
|
}
|
|
45848
46096
|
write2(
|
|
45849
|
-
|
|
46097
|
+
`
|
|
46098
|
+
\x1B[38;2;52;211;153m\u2713\x1B[0m Daemon teardown complete.${opts.purge ? "" : " Registry and logs preserved in ~/.unerr (use --purge to remove)."}
|
|
46099
|
+
`
|
|
45850
46100
|
);
|
|
45851
46101
|
if (!opts.purge) {
|
|
45852
|
-
write2(
|
|
45853
|
-
"\n To re-initialize: \x1B[1munerr daemon initialize\x1B[0m\n"
|
|
45854
|
-
);
|
|
46102
|
+
write2("\n To re-initialize: \x1B[1munerr daemon initialize\x1B[0m\n");
|
|
45855
46103
|
}
|
|
45856
46104
|
});
|
|
45857
46105
|
const addCmd = daemon.command("add [path]").description("Register a repo with unerrd").option(
|
|
@@ -45866,7 +46114,7 @@ function registerDaemonCommand(program2) {
|
|
|
45866
46114
|
}
|
|
45867
46115
|
addCmd.action(
|
|
45868
46116
|
async (pathArg, opts) => {
|
|
45869
|
-
const targetPath =
|
|
46117
|
+
const targetPath = resolve5(pathArg ?? ".");
|
|
45870
46118
|
const settingsRaw = {};
|
|
45871
46119
|
for (const s of SETTINGS_SCHEMA) {
|
|
45872
46120
|
const camelFlag = s.flag.replace(
|
|
@@ -45933,7 +46181,7 @@ function registerDaemonCommand(program2) {
|
|
|
45933
46181
|
}
|
|
45934
46182
|
);
|
|
45935
46183
|
daemon.command("remove [path]").description("Unregister a repo from unerrd").action((pathArg) => {
|
|
45936
|
-
const targetPath =
|
|
46184
|
+
const targetPath = resolve5(pathArg ?? ".");
|
|
45937
46185
|
const removed = removeRepo(targetPath);
|
|
45938
46186
|
if (removed) {
|
|
45939
46187
|
write2(`\x1B[38;2;52;211;153m\u2713\x1B[0m Removed ${targetPath}
|
|
@@ -45972,7 +46220,13 @@ function registerDaemonCommand(program2) {
|
|
|
45972
46220
|
const { request } = await import("http");
|
|
45973
46221
|
const body = await new Promise((resolveReq, rejectReq) => {
|
|
45974
46222
|
const req = request(
|
|
45975
|
-
{
|
|
46223
|
+
{
|
|
46224
|
+
hostname: "127.0.0.1",
|
|
46225
|
+
port: 9847,
|
|
46226
|
+
path: "/api/repos",
|
|
46227
|
+
method: "GET",
|
|
46228
|
+
timeout: 2e3
|
|
46229
|
+
},
|
|
45976
46230
|
(res) => {
|
|
45977
46231
|
let data = "";
|
|
45978
46232
|
res.on("data", (chunk) => {
|
|
@@ -45991,7 +46245,13 @@ function registerDaemonCommand(program2) {
|
|
|
45991
46245
|
const parsed = JSON.parse(body);
|
|
45992
46246
|
liveStatus = /* @__PURE__ */ new Map();
|
|
45993
46247
|
for (const r of parsed.repos) {
|
|
45994
|
-
liveStatus.set(r.path, {
|
|
46248
|
+
liveStatus.set(r.path, {
|
|
46249
|
+
status: r.status,
|
|
46250
|
+
pid: r.pid,
|
|
46251
|
+
connections: r.connections,
|
|
46252
|
+
idle: r.idle,
|
|
46253
|
+
memory: r.memory
|
|
46254
|
+
});
|
|
45995
46255
|
}
|
|
45996
46256
|
}
|
|
45997
46257
|
} catch {
|
|
@@ -46026,8 +46286,7 @@ function registerDaemonCommand(program2) {
|
|
|
46026
46286
|
);
|
|
46027
46287
|
}
|
|
46028
46288
|
if (needsInput.length > 0) {
|
|
46029
|
-
write2(
|
|
46030
|
-
`);
|
|
46289
|
+
write2(" \x1B[38;2;251;191;36m\u26A0\x1B[0m Needs input:\n");
|
|
46031
46290
|
for (const ni of needsInput) {
|
|
46032
46291
|
write2(
|
|
46033
46292
|
` ${ni.key}: auto-selected \x1B[1m${ni.auto}\x1B[0m (${ni.reason})
|
|
@@ -46046,7 +46305,7 @@ function registerDaemonCommand(program2) {
|
|
|
46046
46305
|
}
|
|
46047
46306
|
configCmd.action(
|
|
46048
46307
|
(pathArg, opts) => {
|
|
46049
|
-
const targetPath =
|
|
46308
|
+
const targetPath = resolve5(pathArg ?? ".");
|
|
46050
46309
|
const settingsRaw = {};
|
|
46051
46310
|
for (const s of SETTINGS_SCHEMA) {
|
|
46052
46311
|
const camelFlag = s.flag.replace(
|
|
@@ -46090,9 +46349,7 @@ function registerDaemonCommand(program2) {
|
|
|
46090
46349
|
const needsInput = readNeedsInput(entry.path);
|
|
46091
46350
|
if (needsInput.length > 0) {
|
|
46092
46351
|
write2(
|
|
46093
|
-
|
|
46094
|
-
\x1B[38;2;251;191;36m\u26A0 Auto-detected picks (override with flags):\x1B[0m
|
|
46095
|
-
`
|
|
46352
|
+
"\n \x1B[38;2;251;191;36m\u26A0 Auto-detected picks (override with flags):\x1B[0m\n"
|
|
46096
46353
|
);
|
|
46097
46354
|
for (const ni of needsInput) {
|
|
46098
46355
|
write2(
|
|
@@ -46153,10 +46410,7 @@ function registerDaemonCommand(program2) {
|
|
|
46153
46410
|
const autostartRepos = repos.filter(
|
|
46154
46411
|
(r) => (r.settings?.autostart ?? "auto") !== "never"
|
|
46155
46412
|
);
|
|
46156
|
-
write2(
|
|
46157
|
-
\x1B[1munerr daemon autostart\x1B[0m
|
|
46158
|
-
|
|
46159
|
-
`);
|
|
46413
|
+
write2("\n \x1B[1munerr daemon autostart\x1B[0m\n\n");
|
|
46160
46414
|
write2(` Platform: ${status.platform}
|
|
46161
46415
|
`);
|
|
46162
46416
|
write2(
|
|
@@ -46269,11 +46523,11 @@ function registerDaemonCommand(program2) {
|
|
|
46269
46523
|
stdio: ["ignore", "inherit", "inherit"]
|
|
46270
46524
|
}
|
|
46271
46525
|
);
|
|
46272
|
-
await new Promise((
|
|
46273
|
-
child.on("close", () =>
|
|
46526
|
+
await new Promise((resolve9) => {
|
|
46527
|
+
child.on("close", () => resolve9());
|
|
46274
46528
|
process.on("SIGINT", () => {
|
|
46275
46529
|
child.kill("SIGTERM");
|
|
46276
|
-
|
|
46530
|
+
resolve9();
|
|
46277
46531
|
});
|
|
46278
46532
|
});
|
|
46279
46533
|
return;
|
|
@@ -46377,10 +46631,7 @@ ${tail}
|
|
|
46377
46631
|
if (!anySet) {
|
|
46378
46632
|
const { loadWarmStartConfig: loadWarmStartConfig2 } = await Promise.resolve().then(() => (init_warm_start(), warm_start_exports));
|
|
46379
46633
|
const config = loadWarmStartConfig2();
|
|
46380
|
-
write2(
|
|
46381
|
-
\x1B[1mGlobal daemon config\x1B[0m
|
|
46382
|
-
|
|
46383
|
-
`);
|
|
46634
|
+
write2("\n \x1B[1mGlobal daemon config\x1B[0m\n\n");
|
|
46384
46635
|
write2(` warmStartBudget: ${config.warmStartBudget}
|
|
46385
46636
|
`);
|
|
46386
46637
|
write2(` warmStartIdleDays: ${config.warmStartIdleDays}
|
|
@@ -46425,12 +46676,12 @@ ${tail}
|
|
|
46425
46676
|
input: process.stdin,
|
|
46426
46677
|
output: process.stderr
|
|
46427
46678
|
});
|
|
46428
|
-
const answer = await new Promise((
|
|
46679
|
+
const answer = await new Promise((resolve9) => {
|
|
46429
46680
|
rl.question(
|
|
46430
46681
|
` Update unerr ${info2.current} \u2192 ${info2.latest}? [y/N] `,
|
|
46431
46682
|
(ans) => {
|
|
46432
46683
|
rl.close();
|
|
46433
|
-
|
|
46684
|
+
resolve9(ans.trim().toLowerCase());
|
|
46434
46685
|
}
|
|
46435
46686
|
);
|
|
46436
46687
|
});
|
|
@@ -46448,19 +46699,19 @@ ${tail}
|
|
|
46448
46699
|
const sock = join81(globalDir2(), "unerrd.sock");
|
|
46449
46700
|
const { existsSync: existsSync80 } = await import("fs");
|
|
46450
46701
|
if (existsSync80(sock)) {
|
|
46451
|
-
await new Promise((
|
|
46702
|
+
await new Promise((resolve9) => {
|
|
46452
46703
|
const conn = createConnection3(sock, () => {
|
|
46453
46704
|
conn.write(`${JSON.stringify({ cmd: "shutdown" })}
|
|
46454
46705
|
`);
|
|
46455
46706
|
});
|
|
46456
46707
|
conn.on("data", () => {
|
|
46457
46708
|
conn.destroy();
|
|
46458
|
-
|
|
46709
|
+
resolve9();
|
|
46459
46710
|
});
|
|
46460
|
-
conn.on("error", () =>
|
|
46711
|
+
conn.on("error", () => resolve9());
|
|
46461
46712
|
setTimeout(() => {
|
|
46462
46713
|
conn.destroy();
|
|
46463
|
-
|
|
46714
|
+
resolve9();
|
|
46464
46715
|
}, 5e3);
|
|
46465
46716
|
});
|
|
46466
46717
|
await new Promise((r) => setTimeout(r, 2e3));
|
|
@@ -46572,13 +46823,13 @@ function toKebab(s) {
|
|
|
46572
46823
|
init_exec();
|
|
46573
46824
|
init_git();
|
|
46574
46825
|
init_startup_log();
|
|
46575
|
-
import { existsSync as existsSync20, readFileSync as
|
|
46826
|
+
import { existsSync as existsSync20, readFileSync as readFileSync18 } from "fs";
|
|
46576
46827
|
import { join as join20 } from "path";
|
|
46577
46828
|
function readServerJson(cwd) {
|
|
46578
46829
|
const p = join20(cwd, ".unerr", "state", "server.json");
|
|
46579
46830
|
if (!existsSync20(p)) return null;
|
|
46580
46831
|
try {
|
|
46581
|
-
const raw =
|
|
46832
|
+
const raw = readFileSync18(p, "utf-8");
|
|
46582
46833
|
return JSON.parse(raw);
|
|
46583
46834
|
} catch {
|
|
46584
46835
|
return null;
|
|
@@ -46617,7 +46868,7 @@ function registerDashboardCommand(program2) {
|
|
|
46617
46868
|
|
|
46618
46869
|
// src/commands/debug.ts
|
|
46619
46870
|
init_git();
|
|
46620
|
-
import { existsSync as existsSync21, readFileSync as
|
|
46871
|
+
import { existsSync as existsSync21, readFileSync as readFileSync19, readdirSync as readdirSync4, statSync as statSync3 } from "fs";
|
|
46621
46872
|
import { arch, homedir as homedir10, platform as platform3, release } from "os";
|
|
46622
46873
|
import { join as join21 } from "path";
|
|
46623
46874
|
var UNERR_DIR = join21(homedir10(), ".unerr");
|
|
@@ -46635,7 +46886,7 @@ function registerDebugCommand(program2) {
|
|
|
46635
46886
|
if (existsSync21(settingsPath)) {
|
|
46636
46887
|
try {
|
|
46637
46888
|
const settings = JSON.parse(
|
|
46638
|
-
|
|
46889
|
+
readFileSync19(settingsPath, "utf-8")
|
|
46639
46890
|
);
|
|
46640
46891
|
for (const [key, value] of Object.entries(settings)) {
|
|
46641
46892
|
if (key === "anthropicApiKey" && typeof value === "string") {
|
|
@@ -46663,7 +46914,7 @@ function registerDebugCommand(program2) {
|
|
|
46663
46914
|
if (existsSync21(configPath)) {
|
|
46664
46915
|
try {
|
|
46665
46916
|
const config = JSON.parse(
|
|
46666
|
-
|
|
46917
|
+
readFileSync19(configPath, "utf-8")
|
|
46667
46918
|
);
|
|
46668
46919
|
for (const [key, value] of Object.entries(config)) {
|
|
46669
46920
|
sections.push(` ${key}: ${String(value)}`);
|
|
@@ -46680,7 +46931,7 @@ function registerDebugCommand(program2) {
|
|
|
46680
46931
|
if (existsSync21(pidPath2)) {
|
|
46681
46932
|
try {
|
|
46682
46933
|
const pid = Number.parseInt(
|
|
46683
|
-
|
|
46934
|
+
readFileSync19(pidPath2, "utf-8").trim(),
|
|
46684
46935
|
10
|
|
46685
46936
|
);
|
|
46686
46937
|
let alive = false;
|
|
@@ -46751,7 +47002,7 @@ function registerDebugCommand(program2) {
|
|
|
46751
47002
|
if (logFiles.length > 0 && logFiles[0]) {
|
|
46752
47003
|
const logPath2 = join21(logsDir, logFiles[0]);
|
|
46753
47004
|
try {
|
|
46754
|
-
const content =
|
|
47005
|
+
const content = readFileSync19(logPath2, "utf-8");
|
|
46755
47006
|
const lines = content.split("\n").filter(Boolean);
|
|
46756
47007
|
const last20 = lines.slice(-20);
|
|
46757
47008
|
for (const line of last20) {
|
|
@@ -47075,7 +47326,7 @@ function formatDriftNudge(hint) {
|
|
|
47075
47326
|
}
|
|
47076
47327
|
|
|
47077
47328
|
// src/proxy/nudge-state.ts
|
|
47078
|
-
import { existsSync as existsSync24, mkdirSync as mkdirSync15, readFileSync as
|
|
47329
|
+
import { existsSync as existsSync24, mkdirSync as mkdirSync15, readFileSync as readFileSync21, writeFileSync as writeFileSync12 } from "fs";
|
|
47079
47330
|
import { join as join24 } from "path";
|
|
47080
47331
|
function defaultState() {
|
|
47081
47332
|
return {
|
|
@@ -47093,7 +47344,7 @@ function readNudgeState(cwd) {
|
|
|
47093
47344
|
try {
|
|
47094
47345
|
const path7 = statePath(cwd);
|
|
47095
47346
|
if (!existsSync24(path7)) return defaultState();
|
|
47096
|
-
const raw =
|
|
47347
|
+
const raw = readFileSync21(path7, "utf8");
|
|
47097
47348
|
const parsed = JSON.parse(raw);
|
|
47098
47349
|
return {
|
|
47099
47350
|
tier0_emitted: Boolean(parsed.tier0_emitted),
|
|
@@ -47124,7 +47375,7 @@ function updateNudgeState(cwd, mutator) {
|
|
|
47124
47375
|
|
|
47125
47376
|
// src/proxy/shell-compressor.ts
|
|
47126
47377
|
init_token_flow();
|
|
47127
|
-
import { readFileSync as
|
|
47378
|
+
import { readFileSync as readFileSync24 } from "fs";
|
|
47128
47379
|
|
|
47129
47380
|
// src/proxy/shell-classifier.ts
|
|
47130
47381
|
var COMMAND_HINTS = {
|
|
@@ -48469,7 +48720,7 @@ async function tryLoadGraphForShellBoost(cwd) {
|
|
|
48469
48720
|
if (cached && Date.now() - cached.loadedAt < BOOST_TTL_MS) {
|
|
48470
48721
|
return cached.kind === "ok" ? cached.graph : null;
|
|
48471
48722
|
}
|
|
48472
|
-
const { existsSync: existsSync80, readFileSync:
|
|
48723
|
+
const { existsSync: existsSync80, readFileSync: readFileSync68 } = await import("fs");
|
|
48473
48724
|
const { join: join81 } = await import("path");
|
|
48474
48725
|
const snapshotsDir = join81(cwd, ".unerr", "snapshots");
|
|
48475
48726
|
let snapshotPath2 = join81(snapshotsDir, "graph.msgpack.gz");
|
|
@@ -48501,7 +48752,7 @@ async function tryLoadGraphForShellBoost(cwd) {
|
|
|
48501
48752
|
let buffer;
|
|
48502
48753
|
try {
|
|
48503
48754
|
const { gunzipSync: gunzipSync3 } = await import("zlib");
|
|
48504
|
-
const raw =
|
|
48755
|
+
const raw = readFileSync68(snapshotPath2);
|
|
48505
48756
|
try {
|
|
48506
48757
|
buffer = gunzipSync3(raw);
|
|
48507
48758
|
} catch {
|
|
@@ -48584,8 +48835,7 @@ function parseAwsEc2(raw) {
|
|
|
48584
48835
|
);
|
|
48585
48836
|
}
|
|
48586
48837
|
}
|
|
48587
|
-
if (count === 0) return
|
|
48588
|
-
0 instances`;
|
|
48838
|
+
if (count === 0) return "_shell_fmt:cloud[aws-ec2]\n0 instances";
|
|
48589
48839
|
return `_shell_fmt:cloud[aws-ec2]
|
|
48590
48840
|
${fmtCount(count, "instance")}
|
|
48591
48841
|
id state type ip az name
|
|
@@ -48970,7 +49220,7 @@ function compressEslintErrors(lines) {
|
|
|
48970
49220
|
existing.count++;
|
|
48971
49221
|
} else {
|
|
48972
49222
|
ruleGroups.set(rule, {
|
|
48973
|
-
message: message
|
|
49223
|
+
message: message?.trim() ?? "",
|
|
48974
49224
|
count: 1,
|
|
48975
49225
|
firstFile: currentFile,
|
|
48976
49226
|
firstLine: lineNum
|
|
@@ -49208,7 +49458,9 @@ function compressPythonErrors(lines) {
|
|
|
49208
49458
|
const diagGroups = /* @__PURE__ */ new Map();
|
|
49209
49459
|
let diagCount = 0;
|
|
49210
49460
|
for (const line of lines) {
|
|
49211
|
-
let code = ""
|
|
49461
|
+
let code = "";
|
|
49462
|
+
let message = "";
|
|
49463
|
+
let filePath = "";
|
|
49212
49464
|
const mp = MYPY_RE.exec(line);
|
|
49213
49465
|
if (mp) {
|
|
49214
49466
|
filePath = mp[1] ?? "";
|
|
@@ -49297,7 +49549,8 @@ function compressPythonErrors(lines) {
|
|
|
49297
49549
|
}
|
|
49298
49550
|
const seen = /* @__PURE__ */ new Map();
|
|
49299
49551
|
for (const tb of tracebacks) {
|
|
49300
|
-
const fingerprint2 = tb.frames.join("\n")
|
|
49552
|
+
const fingerprint2 = `${tb.frames.join("\n")}
|
|
49553
|
+
${tb.error}`;
|
|
49301
49554
|
const prev = seen.get(fingerprint2) ?? 0;
|
|
49302
49555
|
seen.set(fingerprint2, prev + 1);
|
|
49303
49556
|
if (prev === 0) {
|
|
@@ -49431,7 +49684,7 @@ function compressLineDiagnostics(lines) {
|
|
|
49431
49684
|
continue;
|
|
49432
49685
|
}
|
|
49433
49686
|
const [, filePath, , , severity, message] = m;
|
|
49434
|
-
const normMsg = message
|
|
49687
|
+
const normMsg = message?.trim().replace(/`[^`]+`/g, "`<id>`").replace(/'\S+'/, "'<id>'");
|
|
49435
49688
|
const key = `${severity ?? "warning"}:${normMsg}`;
|
|
49436
49689
|
const existing = groups.get(key);
|
|
49437
49690
|
if (existing) {
|
|
@@ -49439,7 +49692,7 @@ function compressLineDiagnostics(lines) {
|
|
|
49439
49692
|
existing.files.add(filePath);
|
|
49440
49693
|
} else {
|
|
49441
49694
|
groups.set(key, {
|
|
49442
|
-
message: message
|
|
49695
|
+
message: message?.trim() ?? "",
|
|
49443
49696
|
severity: severity ?? "warning",
|
|
49444
49697
|
count: 1,
|
|
49445
49698
|
files: /* @__PURE__ */ new Set([filePath]),
|
|
@@ -49564,7 +49817,7 @@ function compressErrorDiagnostic(raw, command) {
|
|
|
49564
49817
|
}
|
|
49565
49818
|
|
|
49566
49819
|
// src/proxy/shell-strategies/filter-dsl.ts
|
|
49567
|
-
import { existsSync as existsSync26, readFileSync as
|
|
49820
|
+
import { existsSync as existsSync26, readFileSync as readFileSync23 } from "fs";
|
|
49568
49821
|
import { homedir as homedir12 } from "os";
|
|
49569
49822
|
import { join as join28 } from "path";
|
|
49570
49823
|
var cachedFilters = null;
|
|
@@ -49572,7 +49825,7 @@ var cacheKey = "";
|
|
|
49572
49825
|
function readFile(path7) {
|
|
49573
49826
|
try {
|
|
49574
49827
|
if (!existsSync26(path7)) return null;
|
|
49575
|
-
return
|
|
49828
|
+
return readFileSync23(path7, "utf8");
|
|
49576
49829
|
} catch {
|
|
49577
49830
|
return null;
|
|
49578
49831
|
}
|
|
@@ -49635,7 +49888,7 @@ function parseToml(src) {
|
|
|
49635
49888
|
for (const rawLine of src.split("\n")) {
|
|
49636
49889
|
const line = rawLine.replace(/#.*$/, "");
|
|
49637
49890
|
if (depth > 0) {
|
|
49638
|
-
buf +=
|
|
49891
|
+
buf += ` ${line.trim()}`;
|
|
49639
49892
|
} else if (line.includes("[") && !line.match(/^\s*\[[^=]*\]\s*$/)) {
|
|
49640
49893
|
buf = line;
|
|
49641
49894
|
} else {
|
|
@@ -49797,10 +50050,10 @@ ${sc.message}`,
|
|
|
49797
50050
|
}
|
|
49798
50051
|
let lines = text2.split("\n");
|
|
49799
50052
|
if (filter.strip) {
|
|
49800
|
-
lines = lines.filter((l) => !filter.strip
|
|
50053
|
+
lines = lines.filter((l) => !filter.strip?.some((r) => r.test(l)));
|
|
49801
50054
|
}
|
|
49802
50055
|
if (filter.keep) {
|
|
49803
|
-
lines = lines.filter((l) => filter.keep
|
|
50056
|
+
lines = lines.filter((l) => filter.keep?.some((r) => r.test(l)));
|
|
49804
50057
|
}
|
|
49805
50058
|
if (filter.raw.truncate_lines_at) {
|
|
49806
50059
|
const limit = filter.raw.truncate_lines_at;
|
|
@@ -49846,7 +50099,7 @@ function extOf(path7) {
|
|
|
49846
50099
|
}
|
|
49847
50100
|
function dirOf(path7) {
|
|
49848
50101
|
const i = path7.lastIndexOf("/");
|
|
49849
|
-
return i >= 0 ? path7.slice(0, i)
|
|
50102
|
+
return i >= 0 ? `${path7.slice(0, i)}/` : "./";
|
|
49850
50103
|
}
|
|
49851
50104
|
function topExt(byExt, k = 3) {
|
|
49852
50105
|
const sorted = [...byExt.entries()].sort((a, b) => b[1] - a[1]);
|
|
@@ -49912,15 +50165,19 @@ function compressGitStatus(raw) {
|
|
|
49912
50165
|
} else {
|
|
49913
50166
|
buckets[currentBucket].files.push(stripped);
|
|
49914
50167
|
}
|
|
49915
|
-
continue;
|
|
49916
50168
|
}
|
|
49917
50169
|
}
|
|
49918
50170
|
const totalFiles = buckets.staged.files.length + buckets.modified.files.length + buckets.untracked.files.length + buckets.unmerged.files.length;
|
|
49919
50171
|
if (totalFiles === 0 && !branch) return null;
|
|
49920
|
-
const out = [
|
|
50172
|
+
const out = ["_shell_fmt:git_status"];
|
|
49921
50173
|
const branchLine = branch ? tracking ? `branch=${branch}; ${tracking}` : `branch=${branch}` : "";
|
|
49922
50174
|
if (branchLine) out.push(branchLine);
|
|
49923
|
-
const sectionOrder = [
|
|
50175
|
+
const sectionOrder = [
|
|
50176
|
+
"staged",
|
|
50177
|
+
"modified",
|
|
50178
|
+
"untracked",
|
|
50179
|
+
"unmerged"
|
|
50180
|
+
];
|
|
49924
50181
|
for (const bucket of sectionOrder) {
|
|
49925
50182
|
const b = buckets[bucket];
|
|
49926
50183
|
if (b.files.length === 0) continue;
|
|
@@ -49941,7 +50198,9 @@ function compressGitStatus(raw) {
|
|
|
49941
50198
|
const ext = extOf(f);
|
|
49942
50199
|
agg.byExt.set(ext, (agg.byExt.get(ext) ?? 0) + 1);
|
|
49943
50200
|
}
|
|
49944
|
-
const sortedDirs = [...byDir.entries()].sort(
|
|
50201
|
+
const sortedDirs = [...byDir.entries()].sort(
|
|
50202
|
+
(a, b2) => b2[1].total - a[1].total
|
|
50203
|
+
);
|
|
49945
50204
|
for (const [dir, agg] of sortedDirs.slice(0, 8)) {
|
|
49946
50205
|
out.push(` ${dir} (${agg.total}: ${topExt(agg.byExt)})`);
|
|
49947
50206
|
}
|
|
@@ -50038,8 +50297,8 @@ function compressColonFormat(lines) {
|
|
|
50038
50297
|
continue;
|
|
50039
50298
|
}
|
|
50040
50299
|
const [, indent, key, value] = colonMatch;
|
|
50041
|
-
const keyTrimmed = key
|
|
50042
|
-
if (DROP_COLON_KEYS.has(keyTrimmed)) {
|
|
50300
|
+
const keyTrimmed = key?.trim();
|
|
50301
|
+
if (keyTrimmed && DROP_COLON_KEYS.has(keyTrimmed)) {
|
|
50043
50302
|
i++;
|
|
50044
50303
|
const childIndent2 = (indent?.length ?? 0) + 2;
|
|
50045
50304
|
while (i < lines.length) {
|
|
@@ -50193,7 +50452,7 @@ ${label} \u2014 ${probe.line ?? "succeeded"} (${total} lines suppressed)`;
|
|
|
50193
50452
|
patterns.set(normalized, { firstLine: line, count: 1 });
|
|
50194
50453
|
}
|
|
50195
50454
|
}
|
|
50196
|
-
const parts = [
|
|
50455
|
+
const parts = ["_shell_fmt:log_text"];
|
|
50197
50456
|
parts.push(`(${total} lines, ${patterns.size} unique patterns)`);
|
|
50198
50457
|
if (errorLines.length > 0) {
|
|
50199
50458
|
const errDedup = /* @__PURE__ */ new Map();
|
|
@@ -50367,7 +50626,7 @@ function compressOmni(raw) {
|
|
|
50367
50626
|
const joined = truncated.join("\n");
|
|
50368
50627
|
const capped = capChars(joined);
|
|
50369
50628
|
const savedLines = originalCount - truncated.length;
|
|
50370
|
-
const header = savedLines > 5 ? `_shell_fmt:omni (${originalCount}\u2192${truncated.length} lines)` :
|
|
50629
|
+
const header = savedLines > 5 ? `_shell_fmt:omni (${originalCount}\u2192${truncated.length} lines)` : "_shell_fmt:omni";
|
|
50371
50630
|
return `${header}
|
|
50372
50631
|
${capped}`;
|
|
50373
50632
|
}
|
|
@@ -50548,9 +50807,9 @@ function compressRepeatedValueLines(lines, marker) {
|
|
|
50548
50807
|
const out = [];
|
|
50549
50808
|
let i = 0;
|
|
50550
50809
|
while (i < lines.length) {
|
|
50551
|
-
if (lines[i]
|
|
50810
|
+
if (lines[i]?.includes(marker)) {
|
|
50552
50811
|
const runStart = i;
|
|
50553
|
-
while (i < lines.length && lines[i]
|
|
50812
|
+
while (i < lines.length && lines[i]?.includes(marker)) i++;
|
|
50554
50813
|
const runLen = i - runStart;
|
|
50555
50814
|
if (runLen >= 3) {
|
|
50556
50815
|
out.push(lines[runStart]);
|
|
@@ -50779,8 +51038,8 @@ function compressTabularInner(text2, command) {
|
|
|
50779
51038
|
const profile = command ? matchColumnProfile(command) : null;
|
|
50780
51039
|
const useLastColRest = command ? isLastColRestCommand(command) : false;
|
|
50781
51040
|
if (useLastColRest && lines.length >= 2) {
|
|
50782
|
-
const headerTokens = lines[0]
|
|
50783
|
-
if (headerTokens.length >= 2) {
|
|
51041
|
+
const headerTokens = lines[0]?.trim().split(/\s+/).filter(Boolean);
|
|
51042
|
+
if (headerTokens && headerTokens.length >= 2) {
|
|
50784
51043
|
const numCols = headerTokens.length;
|
|
50785
51044
|
const dataRows = lines.slice(1);
|
|
50786
51045
|
let keepIndices;
|
|
@@ -50790,9 +51049,10 @@ function compressTabularInner(text2, command) {
|
|
|
50790
51049
|
keepIndices = [];
|
|
50791
51050
|
keepNames = [];
|
|
50792
51051
|
for (let i = 0; i < headerTokens.length; i++) {
|
|
50793
|
-
|
|
51052
|
+
const tok = headerTokens[i];
|
|
51053
|
+
if (tok && keepSet.has(tok.toUpperCase())) {
|
|
50794
51054
|
keepIndices.push(i);
|
|
50795
|
-
keepNames.push(
|
|
51055
|
+
keepNames.push(tok);
|
|
50796
51056
|
}
|
|
50797
51057
|
}
|
|
50798
51058
|
if (keepIndices.length < 2) {
|
|
@@ -51075,7 +51335,6 @@ function parsePytest(lines) {
|
|
|
51075
51335
|
}
|
|
51076
51336
|
if (/^FAILED\s/.test(line)) {
|
|
51077
51337
|
summaryLines.push(line.trim());
|
|
51078
|
-
continue;
|
|
51079
51338
|
}
|
|
51080
51339
|
}
|
|
51081
51340
|
if (currentFail) failures.push(currentFail);
|
|
@@ -51231,7 +51490,6 @@ function parseRspec(lines) {
|
|
|
51231
51490
|
} else {
|
|
51232
51491
|
currentFail.lines.push(line);
|
|
51233
51492
|
}
|
|
51234
|
-
continue;
|
|
51235
51493
|
}
|
|
51236
51494
|
}
|
|
51237
51495
|
if (currentFail) failures.push(currentFail);
|
|
@@ -51668,7 +51926,7 @@ function compressTreePaths(raw, _maxDepth, command) {
|
|
|
51668
51926
|
if (parentBucket) parentBucket.subdirs.add(dir);
|
|
51669
51927
|
}
|
|
51670
51928
|
const sortedDirs = [...buckets.keys()].sort();
|
|
51671
|
-
const out = [
|
|
51929
|
+
const out = ["_shell_fmt:tree_paths"];
|
|
51672
51930
|
out.push(
|
|
51673
51931
|
`(${paths.length} paths across ${sortedDirs.length} dirs; rolled up)`
|
|
51674
51932
|
);
|
|
@@ -51708,13 +51966,13 @@ var VALUE_MAX2 = 200;
|
|
|
51708
51966
|
function detectIndentUnit(lines) {
|
|
51709
51967
|
for (const line of lines) {
|
|
51710
51968
|
const m = /^( +)\S/.exec(line);
|
|
51711
|
-
if (m) return m[1]
|
|
51969
|
+
if (m) return m[1]?.length ?? 0;
|
|
51712
51970
|
}
|
|
51713
51971
|
return 2;
|
|
51714
51972
|
}
|
|
51715
51973
|
function indentOf(line) {
|
|
51716
51974
|
const m = /^( *)/.exec(line);
|
|
51717
|
-
return m ? m[1]
|
|
51975
|
+
return m ? m[1]?.length ?? 0 : 0;
|
|
51718
51976
|
}
|
|
51719
51977
|
function compressYaml(raw, command) {
|
|
51720
51978
|
void command;
|
|
@@ -51769,7 +52027,7 @@ function compressYaml(raw, command) {
|
|
|
51769
52027
|
let preview = 0;
|
|
51770
52028
|
let k = i + 1;
|
|
51771
52029
|
while (k < j && preview < 3) {
|
|
51772
|
-
if (lines[k]
|
|
52030
|
+
if (lines[k]?.trim()) {
|
|
51773
52031
|
kept.push(lines[k]);
|
|
51774
52032
|
preview++;
|
|
51775
52033
|
}
|
|
@@ -51870,12 +52128,12 @@ function teeShellOutput(cwd, command, raw, compressed) {
|
|
|
51870
52128
|
const filename = `${ts}-${slug}.txt`;
|
|
51871
52129
|
const filePath = join29(teeDir, filename);
|
|
51872
52130
|
const header = [
|
|
51873
|
-
|
|
52131
|
+
"# unerr tee \u2014 full shell output",
|
|
51874
52132
|
`# command: ${command}`,
|
|
51875
52133
|
`# captured: ${new Date(ts).toISOString()}`,
|
|
51876
52134
|
`# raw_bytes: ${raw.length} compressed_bytes: ${compressed.length} ratio: ${(ratio * 100).toFixed(1)}%`,
|
|
51877
|
-
|
|
51878
|
-
|
|
52135
|
+
"# ---",
|
|
52136
|
+
""
|
|
51879
52137
|
].join("\n");
|
|
51880
52138
|
const content = header + raw;
|
|
51881
52139
|
try {
|
|
@@ -52286,7 +52544,7 @@ function recordShellTokenFlow(cwd, command, category, raw, compressed, strategy)
|
|
|
52286
52544
|
const unerrDir = `${cwd}/.unerr`;
|
|
52287
52545
|
if (!sessionId) {
|
|
52288
52546
|
try {
|
|
52289
|
-
sessionId =
|
|
52547
|
+
sessionId = readFileSync24(
|
|
52290
52548
|
`${unerrDir}/state/session.id`,
|
|
52291
52549
|
"utf-8"
|
|
52292
52550
|
).trim();
|
|
@@ -52417,8 +52675,7 @@ async function runExecMain(argv) {
|
|
|
52417
52675
|
`
|
|
52418
52676
|
);
|
|
52419
52677
|
process.stderr.write(
|
|
52420
|
-
|
|
52421
|
-
`
|
|
52678
|
+
"[unerr:exec] \u2191 this error is from the command itself, not unerr\n"
|
|
52422
52679
|
);
|
|
52423
52680
|
process.stdout.write(combined);
|
|
52424
52681
|
if (combined.length > 0 && !combined.endsWith("\n"))
|
|
@@ -52485,7 +52742,7 @@ function registerExecCommand(program2) {
|
|
|
52485
52742
|
}
|
|
52486
52743
|
|
|
52487
52744
|
// src/commands/gain.ts
|
|
52488
|
-
import { existsSync as existsSync27, readFileSync as
|
|
52745
|
+
import { existsSync as existsSync27, readFileSync as readFileSync25 } from "fs";
|
|
52489
52746
|
import { join as join30 } from "path";
|
|
52490
52747
|
var PALETTE = {
|
|
52491
52748
|
reset: "\x1B[0m",
|
|
@@ -52500,7 +52757,7 @@ var PALETTE = {
|
|
|
52500
52757
|
function loadFlow(cwd) {
|
|
52501
52758
|
const path7 = join30(cwd, ".unerr", "token-flow.jsonl");
|
|
52502
52759
|
if (!existsSync27(path7)) return [];
|
|
52503
|
-
const raw =
|
|
52760
|
+
const raw = readFileSync25(path7, "utf8");
|
|
52504
52761
|
const events = [];
|
|
52505
52762
|
for (const line of raw.split("\n")) {
|
|
52506
52763
|
if (!line.trim()) continue;
|
|
@@ -52624,18 +52881,18 @@ function registerDiscoverCommand(program2) {
|
|
|
52624
52881
|
}
|
|
52625
52882
|
|
|
52626
52883
|
// src/commands/hook.ts
|
|
52627
|
-
import { readFileSync as
|
|
52884
|
+
import { readFileSync as readFileSync27 } from "fs";
|
|
52628
52885
|
|
|
52629
52886
|
// src/hooks/hook-dedup.ts
|
|
52630
|
-
import { existsSync as existsSync28, mkdirSync as mkdirSync19, readFileSync as
|
|
52631
|
-
import { dirname as
|
|
52887
|
+
import { existsSync as existsSync28, mkdirSync as mkdirSync19, readFileSync as readFileSync26, writeFileSync as writeFileSync15 } from "fs";
|
|
52888
|
+
import { dirname as dirname10, join as join31 } from "path";
|
|
52632
52889
|
var STATE_FILE = join31(".unerr", "state", "hook-recent.json");
|
|
52633
52890
|
var DEFAULT_TTL_MS = 3e4;
|
|
52634
52891
|
var PRUNE_FACTOR = 10;
|
|
52635
52892
|
function readMap(file) {
|
|
52636
52893
|
try {
|
|
52637
52894
|
if (!existsSync28(file)) return {};
|
|
52638
|
-
const raw =
|
|
52895
|
+
const raw = readFileSync26(file, "utf8");
|
|
52639
52896
|
const obj = JSON.parse(raw);
|
|
52640
52897
|
if (obj && typeof obj === "object") return obj;
|
|
52641
52898
|
} catch {
|
|
@@ -52644,7 +52901,7 @@ function readMap(file) {
|
|
|
52644
52901
|
}
|
|
52645
52902
|
function writeMap(file, map) {
|
|
52646
52903
|
try {
|
|
52647
|
-
const dir =
|
|
52904
|
+
const dir = dirname10(file);
|
|
52648
52905
|
if (!existsSync28(dir)) mkdirSync19(dir, { recursive: true });
|
|
52649
52906
|
writeFileSync15(file, JSON.stringify(map));
|
|
52650
52907
|
} catch {
|
|
@@ -52779,7 +53036,7 @@ var clineAdapter = {
|
|
|
52779
53036
|
if (result.type === "rewrite" && result.updatedInput) {
|
|
52780
53037
|
return JSON.stringify({
|
|
52781
53038
|
allow: true,
|
|
52782
|
-
context:
|
|
53039
|
+
context: "Suggested rewrite: use unerr exec for this command."
|
|
52783
53040
|
});
|
|
52784
53041
|
}
|
|
52785
53042
|
return JSON.stringify({ allow: true });
|
|
@@ -52977,11 +53234,11 @@ Text grep matches comments, strings, and unrelated code. Graph tools are precise
|
|
|
52977
53234
|
}
|
|
52978
53235
|
if (looksLikeImportSearch) {
|
|
52979
53236
|
return nudge(
|
|
52980
|
-
|
|
53237
|
+
"STOP: Use `get_imports` instead of Grep for import/dependency tracing. It returns structured import maps in <5ms \u2014 more reliable than grepping for import statements."
|
|
52981
53238
|
);
|
|
52982
53239
|
}
|
|
52983
53240
|
return nudge(
|
|
52984
|
-
|
|
53241
|
+
"REQUIRED: This project has unerr graph tools indexed. Use `search_code` for code entity searches (faster, more accurate than Grep). Use `get_references` for finding callers."
|
|
52985
53242
|
);
|
|
52986
53243
|
};
|
|
52987
53244
|
var preGlobHandler = (normalized) => {
|
|
@@ -53020,13 +53277,13 @@ var preEditHandler = (normalized) => {
|
|
|
53020
53277
|
);
|
|
53021
53278
|
if (hasSignatureChange) {
|
|
53022
53279
|
return nudge(
|
|
53023
|
-
readPrereq
|
|
53280
|
+
`${readPrereq}You're editing a function/class signature in "${filePath}". This may break callers.
|
|
53024
53281
|
- \`get_references\` on the entity you're modifying \u2014 all callers must be updated to match
|
|
53025
53282
|
- \`get_test_coverage\` on the entity \u2014 verify which tests cover it`
|
|
53026
53283
|
);
|
|
53027
53284
|
}
|
|
53028
53285
|
return nudge(
|
|
53029
|
-
readPrereq
|
|
53286
|
+
`${readPrereq}Before editing "${filePath}":
|
|
53030
53287
|
- \`get_references\` on any entity you're changing \u2014 ensure callers won't break`
|
|
53031
53288
|
);
|
|
53032
53289
|
};
|
|
@@ -53038,11 +53295,11 @@ var postReadHandler = (normalized) => {
|
|
|
53038
53295
|
const isClaudeCode = normalized.agentName === "claude-code";
|
|
53039
53296
|
if (isClaudeCode) {
|
|
53040
53297
|
return enrich(
|
|
53041
|
-
|
|
53298
|
+
"ur|hnt Edit needs built-in Read first; for understanding use `file_read` (auto-injects facts/drift)."
|
|
53042
53299
|
);
|
|
53043
53300
|
}
|
|
53044
53301
|
return enrich(
|
|
53045
|
-
|
|
53302
|
+
"ur|hnt Prefer `file_read` over built-in Read \u2014 it auto-injects conventions, facts, drift."
|
|
53046
53303
|
);
|
|
53047
53304
|
};
|
|
53048
53305
|
var postGrepHandler = (normalized) => {
|
|
@@ -53059,9 +53316,7 @@ var postGrepHandler = (normalized) => {
|
|
|
53059
53316
|
);
|
|
53060
53317
|
}
|
|
53061
53318
|
return enrich(
|
|
53062
|
-
|
|
53063
|
-
- \`search_code\` for entity-level search (functions, classes, types)
|
|
53064
|
-
- \`get_references\` for reference tracing (no false positives)`
|
|
53319
|
+
"You just grepped for a pattern. For structured code navigation, unerr graph tools are faster and more accurate:\n- `search_code` for entity-level search (functions, classes, types)\n- `get_references` for reference tracing (no false positives)"
|
|
53065
53320
|
);
|
|
53066
53321
|
};
|
|
53067
53322
|
var postGlobHandler = () => {
|
|
@@ -53174,7 +53429,7 @@ function runPreBashHook(stdinJson) {
|
|
|
53174
53429
|
function safeHookAction(handler) {
|
|
53175
53430
|
return () => {
|
|
53176
53431
|
try {
|
|
53177
|
-
const stdin =
|
|
53432
|
+
const stdin = readFileSync27(0, "utf-8");
|
|
53178
53433
|
process.stdout.write(handler(stdin));
|
|
53179
53434
|
} catch (e) {
|
|
53180
53435
|
process.stderr.write(`[unerr] hook error: ${e}
|
|
@@ -53370,14 +53625,14 @@ import {
|
|
|
53370
53625
|
chmodSync as chmodSync4,
|
|
53371
53626
|
existsSync as existsSync40,
|
|
53372
53627
|
mkdirSync as mkdirSync28,
|
|
53373
|
-
readFileSync as
|
|
53628
|
+
readFileSync as readFileSync35,
|
|
53374
53629
|
writeFileSync as writeFileSync22
|
|
53375
53630
|
} from "fs";
|
|
53376
53631
|
import { join as join44 } from "path";
|
|
53377
53632
|
|
|
53378
53633
|
// src/config/claude-settings-hooks.ts
|
|
53379
53634
|
import { execSync as execSync6 } from "child_process";
|
|
53380
|
-
import { existsSync as existsSync37, mkdirSync as mkdirSync25, readFileSync as
|
|
53635
|
+
import { existsSync as existsSync37, mkdirSync as mkdirSync25, readFileSync as readFileSync32, writeFileSync as writeFileSync19 } from "fs";
|
|
53381
53636
|
import { join as join41 } from "path";
|
|
53382
53637
|
function resolveUnerrBinary() {
|
|
53383
53638
|
const entryScript = process.argv[1];
|
|
@@ -53451,7 +53706,7 @@ function mergePreToolUseBashHook(cwd) {
|
|
|
53451
53706
|
let settings = {};
|
|
53452
53707
|
if (existsSync37(settingsPath)) {
|
|
53453
53708
|
try {
|
|
53454
|
-
settings = JSON.parse(
|
|
53709
|
+
settings = JSON.parse(readFileSync32(settingsPath, "utf-8"));
|
|
53455
53710
|
} catch {
|
|
53456
53711
|
settings = {};
|
|
53457
53712
|
}
|
|
@@ -53516,7 +53771,7 @@ function addDisallowedTools(cwd) {
|
|
|
53516
53771
|
let settings = {};
|
|
53517
53772
|
if (existsSync37(settingsPath)) {
|
|
53518
53773
|
try {
|
|
53519
|
-
settings = JSON.parse(
|
|
53774
|
+
settings = JSON.parse(readFileSync32(settingsPath, "utf-8"));
|
|
53520
53775
|
} catch {
|
|
53521
53776
|
settings = {};
|
|
53522
53777
|
}
|
|
@@ -53554,7 +53809,7 @@ function removeDisallowedTools(cwd) {
|
|
|
53554
53809
|
const settingsPath = join41(cwd, ".claude", "settings.json");
|
|
53555
53810
|
if (!existsSync37(settingsPath)) return false;
|
|
53556
53811
|
try {
|
|
53557
|
-
const settings = JSON.parse(
|
|
53812
|
+
const settings = JSON.parse(readFileSync32(settingsPath, "utf-8"));
|
|
53558
53813
|
const permissions = settings.permissions;
|
|
53559
53814
|
if (!permissions || !Array.isArray(permissions.deny)) return false;
|
|
53560
53815
|
const before = permissions.deny.length;
|
|
@@ -53563,8 +53818,9 @@ function removeDisallowedTools(cwd) {
|
|
|
53563
53818
|
);
|
|
53564
53819
|
const removed = before - permissions.deny.length;
|
|
53565
53820
|
if (removed === 0) return false;
|
|
53566
|
-
if (permissions.deny.length === 0)
|
|
53567
|
-
|
|
53821
|
+
if (permissions.deny.length === 0)
|
|
53822
|
+
permissions.deny = void 0;
|
|
53823
|
+
if (Object.keys(permissions).length === 0) settings.permissions = void 0;
|
|
53568
53824
|
writeFileSync19(
|
|
53569
53825
|
settingsPath,
|
|
53570
53826
|
`${JSON.stringify(settings, null, 2)}
|
|
@@ -53580,7 +53836,7 @@ function removePreToolUseBashHook(cwd) {
|
|
|
53580
53836
|
const settingsPath = join41(cwd, ".claude", "settings.json");
|
|
53581
53837
|
if (!existsSync37(settingsPath)) return false;
|
|
53582
53838
|
try {
|
|
53583
|
-
const settings = JSON.parse(
|
|
53839
|
+
const settings = JSON.parse(readFileSync32(settingsPath, "utf-8"));
|
|
53584
53840
|
const hooks = settings.hooks;
|
|
53585
53841
|
if (!hooks) return false;
|
|
53586
53842
|
let totalRemoved = 0;
|
|
@@ -53600,7 +53856,7 @@ function removePreToolUseBashHook(cwd) {
|
|
|
53600
53856
|
if (hooks[eventType].length === 0) delete hooks[eventType];
|
|
53601
53857
|
}
|
|
53602
53858
|
if (totalRemoved === 0) return false;
|
|
53603
|
-
if (Object.keys(hooks).length === 0)
|
|
53859
|
+
if (Object.keys(hooks).length === 0) settings.hooks = void 0;
|
|
53604
53860
|
writeFileSync19(
|
|
53605
53861
|
settingsPath,
|
|
53606
53862
|
`${JSON.stringify(settings, null, 2)}
|
|
@@ -53621,16 +53877,16 @@ init_agent_registry();
|
|
|
53621
53877
|
import {
|
|
53622
53878
|
existsSync as existsSync38,
|
|
53623
53879
|
mkdirSync as mkdirSync26,
|
|
53624
|
-
readFileSync as
|
|
53880
|
+
readFileSync as readFileSync33,
|
|
53625
53881
|
unlinkSync as unlinkSync9,
|
|
53626
53882
|
writeFileSync as writeFileSync20
|
|
53627
53883
|
} from "fs";
|
|
53628
|
-
import { dirname as
|
|
53884
|
+
import { dirname as dirname12, join as join42 } from "path";
|
|
53629
53885
|
var SENTINEL_START = "<!-- unerr:start -->";
|
|
53630
53886
|
var SENTINEL_END = "<!-- unerr:end -->";
|
|
53631
53887
|
function getInstructionContent(ide) {
|
|
53632
53888
|
const isClaudeCode = ide === "claude-code";
|
|
53633
|
-
const readForEditRow = isClaudeCode ? `| Understand a file before editing | \`file_read\` with \`purpose:'explore'\` to understand, then built-in \`Read\` (offset/limit) on target lines before Edit | Reading entire file |` :
|
|
53889
|
+
const readForEditRow = isClaudeCode ? `| Understand a file before editing | \`file_read\` with \`purpose:'explore'\` to understand, then built-in \`Read\` (offset/limit) on target lines before Edit | Reading entire file |` : "| Read a file before editing | `file_read` with `entity` param or offset/limit for targeted access | Reading entire file |";
|
|
53634
53890
|
const twoStepSection = isClaudeCode ? `
|
|
53635
53891
|
### IMPORTANT: Two-step Read Routing (Claude Code specific)
|
|
53636
53892
|
|
|
@@ -53646,9 +53902,7 @@ function getInstructionContent(ide) {
|
|
|
53646
53902
|
When your next action is Edit, use built-in Read with offset/limit on the target lines. For everything else, use \`file_read\`.
|
|
53647
53903
|
|
|
53648
53904
|
**Common failure mode:** Using \`file_read\` to understand a file, then attempting Edit without calling built-in Read first. The Edit tool WILL reject with "File has not been read yet". Always call built-in Read (with offset/limit) immediately before Edit.` : "";
|
|
53649
|
-
const summaryEditNote = isClaudeCode ?
|
|
53650
|
-
NEVER use built-in Read/Grep/Glob for code navigation. EXCEPTION: built-in Read (with offset/limit) is REQUIRED immediately before Edit (file_read cannot substitute \u2014 Edit will fail without it).` : `
|
|
53651
|
-
NEVER use built-in Read/Grep/Glob for code navigation \u2014 use unerr MCP tools instead.`;
|
|
53905
|
+
const summaryEditNote = isClaudeCode ? "\nNEVER use built-in Read/Grep/Glob for code navigation. EXCEPTION: built-in Read (with offset/limit) is REQUIRED immediately before Edit (file_read cannot substitute \u2014 Edit will fail without it)." : "\nNEVER use built-in Read/Grep/Glob for code navigation \u2014 use unerr MCP tools instead.";
|
|
53652
53906
|
return `## REQUIRED: Use unerr Graph Intelligence Tools (22 MCP tools)
|
|
53653
53907
|
|
|
53654
53908
|
This project has unerr MCP tools installed. You MUST use these instead of built-in Read/Grep/Glob for code navigation. unerr tools are graph-backed, return results in <5ms, and include project context that built-in tools miss.
|
|
@@ -53817,7 +54071,7 @@ function writeInstructionFile(cwd, ide) {
|
|
|
53817
54071
|
return writeMdcInstructionFile(filePath);
|
|
53818
54072
|
}
|
|
53819
54073
|
if (agentDef.instructionFormat === "windsurf-rule") {
|
|
53820
|
-
mkdirSync26(
|
|
54074
|
+
mkdirSync26(dirname12(filePath), { recursive: true });
|
|
53821
54075
|
const content = getInstructionContent(ide);
|
|
53822
54076
|
const truncatedContent = content.length > 5800 ? `${content.slice(0, 5800)}
|
|
53823
54077
|
|
|
@@ -53831,7 +54085,7 @@ ${truncatedContent}
|
|
|
53831
54085
|
`;
|
|
53832
54086
|
const existed = existsSync38(filePath);
|
|
53833
54087
|
if (existed) {
|
|
53834
|
-
const existing =
|
|
54088
|
+
const existing = readFileSync33(filePath, "utf-8");
|
|
53835
54089
|
if (existing === windsurfContent) {
|
|
53836
54090
|
return { path: filePath, action: "skipped" };
|
|
53837
54091
|
}
|
|
@@ -53840,7 +54094,7 @@ ${truncatedContent}
|
|
|
53840
54094
|
return { path: filePath, action: existed ? "updated" : "created" };
|
|
53841
54095
|
}
|
|
53842
54096
|
if (agentDef.instructionFormat === "antigravity-rule") {
|
|
53843
|
-
mkdirSync26(
|
|
54097
|
+
mkdirSync26(dirname12(filePath), { recursive: true });
|
|
53844
54098
|
const content = getInstructionContent(ide);
|
|
53845
54099
|
const antigravityContent = `---
|
|
53846
54100
|
name: unerr-instructions
|
|
@@ -53852,7 +54106,7 @@ ${content}
|
|
|
53852
54106
|
`;
|
|
53853
54107
|
const existed = existsSync38(filePath);
|
|
53854
54108
|
if (existed) {
|
|
53855
|
-
const existing =
|
|
54109
|
+
const existing = readFileSync33(filePath, "utf-8");
|
|
53856
54110
|
if (existing === antigravityContent) {
|
|
53857
54111
|
return { path: filePath, action: "skipped" };
|
|
53858
54112
|
}
|
|
@@ -53867,13 +54121,13 @@ function mergeMarkdownSection(filePath, content) {
|
|
|
53867
54121
|
${content}
|
|
53868
54122
|
${SENTINEL_END}`;
|
|
53869
54123
|
if (!existsSync38(filePath)) {
|
|
53870
|
-
const dir =
|
|
54124
|
+
const dir = dirname12(filePath);
|
|
53871
54125
|
if (!existsSync38(dir)) mkdirSync26(dir, { recursive: true });
|
|
53872
54126
|
writeFileSync20(filePath, `${wrappedContent}
|
|
53873
54127
|
`);
|
|
53874
54128
|
return { path: filePath, action: "created" };
|
|
53875
54129
|
}
|
|
53876
|
-
const existing =
|
|
54130
|
+
const existing = readFileSync33(filePath, "utf-8");
|
|
53877
54131
|
const startIdx = existing.indexOf(SENTINEL_START);
|
|
53878
54132
|
const endIdx = existing.indexOf(SENTINEL_END);
|
|
53879
54133
|
if (startIdx === -1 || endIdx === -1) {
|
|
@@ -53895,12 +54149,12 @@ function writeMdcInstructionFile(filePath) {
|
|
|
53895
54149
|
const content = getMdcContent();
|
|
53896
54150
|
const alreadyExists = existsSync38(filePath);
|
|
53897
54151
|
if (alreadyExists) {
|
|
53898
|
-
const existing =
|
|
54152
|
+
const existing = readFileSync33(filePath, "utf-8");
|
|
53899
54153
|
if (existing === content) {
|
|
53900
54154
|
return { path: filePath, action: "skipped" };
|
|
53901
54155
|
}
|
|
53902
54156
|
}
|
|
53903
|
-
const dir =
|
|
54157
|
+
const dir = dirname12(filePath);
|
|
53904
54158
|
if (!existsSync38(dir)) mkdirSync26(dir, { recursive: true });
|
|
53905
54159
|
writeFileSync20(filePath, content);
|
|
53906
54160
|
return {
|
|
@@ -53931,13 +54185,14 @@ function removeInstructionSection(cwd, ide) {
|
|
|
53931
54185
|
}
|
|
53932
54186
|
return false;
|
|
53933
54187
|
}
|
|
53934
|
-
const content =
|
|
54188
|
+
const content = readFileSync33(filePath, "utf-8");
|
|
53935
54189
|
const startIdx = content.indexOf(SENTINEL_START);
|
|
53936
54190
|
const endIdx = content.indexOf(SENTINEL_END);
|
|
53937
54191
|
if (startIdx === -1 || endIdx === -1) return false;
|
|
53938
54192
|
const before = content.slice(0, startIdx);
|
|
53939
54193
|
const after = content.slice(endIdx + SENTINEL_END.length);
|
|
53940
|
-
const cleaned = (before + after).replace(/\n{3,}/g, "\n\n").trimEnd()
|
|
54194
|
+
const cleaned = `${(before + after).replace(/\n{3,}/g, "\n\n").trimEnd()}
|
|
54195
|
+
`;
|
|
53941
54196
|
const trimmed = cleaned.replace(/\s/g, "");
|
|
53942
54197
|
if (trimmed.length === 0) {
|
|
53943
54198
|
unlinkSync9(filePath);
|
|
@@ -54037,14 +54292,12 @@ function registerInstallCommand(program2) {
|
|
|
54037
54292
|
}
|
|
54038
54293
|
if (result.hookInstalled) {
|
|
54039
54294
|
process.stderr.write(
|
|
54040
|
-
|
|
54041
|
-
`
|
|
54295
|
+
" \x1B[38;2;52;211;153m\u2713\x1B[0m PreToolUse hook installed (graph-first navigation)\n"
|
|
54042
54296
|
);
|
|
54043
54297
|
}
|
|
54044
54298
|
if (result.gitignoreUpdated) {
|
|
54045
54299
|
process.stderr.write(
|
|
54046
|
-
|
|
54047
|
-
`
|
|
54300
|
+
" \x1B[38;2;52;211;153m\u2713\x1B[0m .unerr added to .gitignore\n"
|
|
54048
54301
|
);
|
|
54049
54302
|
}
|
|
54050
54303
|
if (result.instructionsInjected) {
|
|
@@ -54055,14 +54308,12 @@ function registerInstallCommand(program2) {
|
|
|
54055
54308
|
}
|
|
54056
54309
|
if (result.toolsDenied > 0) {
|
|
54057
54310
|
process.stderr.write(
|
|
54058
|
-
|
|
54059
|
-
`
|
|
54311
|
+
" \x1B[38;2;52;211;153m\u2713\x1B[0m Built-in Read/Grep/Glob denied (use --no-force-tools to keep)\n"
|
|
54060
54312
|
);
|
|
54061
54313
|
}
|
|
54062
54314
|
process.stderr.write("\n");
|
|
54063
54315
|
process.stderr.write(
|
|
54064
|
-
|
|
54065
|
-
`
|
|
54316
|
+
" \x1B[38;2;161;161;170mRun \x1B[0munerr\x1B[38;2;161;161;170m to start the intelligence engine.\x1B[0m\n"
|
|
54066
54317
|
);
|
|
54067
54318
|
process.stderr.write("\n");
|
|
54068
54319
|
}
|
|
@@ -54111,6 +54362,17 @@ async function runInstall(cwd, ide, opts) {
|
|
|
54111
54362
|
} catch {
|
|
54112
54363
|
}
|
|
54113
54364
|
}
|
|
54365
|
+
try {
|
|
54366
|
+
const { autoInstallIfNeeded: autoInstallIfNeeded2 } = await Promise.resolve().then(() => (init_autostart(), autostart_exports));
|
|
54367
|
+
const autostartResult = await autoInstallIfNeeded2();
|
|
54368
|
+
if (autostartResult?.installed) {
|
|
54369
|
+
process.stderr.write(
|
|
54370
|
+
`\x1B[38;2;52;211;153m\u2713\x1B[0m Daemon auto-start registered: ${autostartResult.path}
|
|
54371
|
+
`
|
|
54372
|
+
);
|
|
54373
|
+
}
|
|
54374
|
+
} catch {
|
|
54375
|
+
}
|
|
54114
54376
|
let repoRegistered = false;
|
|
54115
54377
|
try {
|
|
54116
54378
|
const { daemonSockPath: daemonSockPath2, probeDaemon: probeDaemon2, ensureRepo: ensureRepo2 } = await Promise.resolve().then(() => (init_client(), client_exports));
|
|
@@ -54407,7 +54669,7 @@ function installCursorHooks(cwd) {
|
|
|
54407
54669
|
if (existsSync40(hooksJsonPath)) {
|
|
54408
54670
|
try {
|
|
54409
54671
|
const existing = JSON.parse(
|
|
54410
|
-
|
|
54672
|
+
readFileSync35(hooksJsonPath, "utf-8")
|
|
54411
54673
|
);
|
|
54412
54674
|
if (existing.version && existing.hooks) {
|
|
54413
54675
|
config = existing;
|
|
@@ -54481,7 +54743,7 @@ function ensureGitignore(cwd) {
|
|
|
54481
54743
|
const gitignorePath = join44(cwd, ".gitignore");
|
|
54482
54744
|
if (!existsSync40(gitignorePath)) return false;
|
|
54483
54745
|
try {
|
|
54484
|
-
const content =
|
|
54746
|
+
const content = readFileSync35(gitignorePath, "utf-8");
|
|
54485
54747
|
const lines = content.split("\n");
|
|
54486
54748
|
if (lines.some((l) => l.trim() === ".unerr" || l.trim() === ".unerr/")) {
|
|
54487
54749
|
return false;
|
|
@@ -54582,8 +54844,8 @@ async function persistPatterns(patterns, _unerrDir) {
|
|
|
54582
54844
|
);
|
|
54583
54845
|
return;
|
|
54584
54846
|
}
|
|
54585
|
-
const { readFileSync:
|
|
54586
|
-
const config = JSON.parse(
|
|
54847
|
+
const { readFileSync: readFileSync68 } = await import("fs");
|
|
54848
|
+
const config = JSON.parse(readFileSync68(configPath, "utf-8"));
|
|
54587
54849
|
if (!config.repoId || !config.orgId) {
|
|
54588
54850
|
warn("Repo not configured \u2014 cannot persist to CozoDB.");
|
|
54589
54851
|
return;
|
|
@@ -54601,7 +54863,7 @@ async function persistPatterns(patterns, _unerrDir) {
|
|
|
54601
54863
|
const { CozoGraphStore: CozoGraphStore2 } = await Promise.resolve().then(() => (init_local_graph(), local_graph_exports));
|
|
54602
54864
|
const store = await CozoGraphStore2.create(db);
|
|
54603
54865
|
const { unpack } = await import("msgpackr");
|
|
54604
|
-
const raw =
|
|
54866
|
+
const raw = readFileSync68(snapshotPath2);
|
|
54605
54867
|
const buffer = gunzipSync2(raw);
|
|
54606
54868
|
const envelope = unpack(buffer);
|
|
54607
54869
|
await store.loadSnapshot(envelope);
|
|
@@ -54618,7 +54880,7 @@ async function persistPatterns(patterns, _unerrDir) {
|
|
|
54618
54880
|
|
|
54619
54881
|
// src/commands/manifest.ts
|
|
54620
54882
|
init_exec();
|
|
54621
|
-
import { existsSync as existsSync43, readFileSync as
|
|
54883
|
+
import { existsSync as existsSync43, readFileSync as readFileSync37 } from "fs";
|
|
54622
54884
|
import { join as join46 } from "path";
|
|
54623
54885
|
async function findRepoRoot() {
|
|
54624
54886
|
return gitQuery(["rev-parse", "--show-toplevel"]);
|
|
@@ -54627,7 +54889,7 @@ function loadManifest(repoRoot) {
|
|
|
54627
54889
|
const manifestPath = join46(repoRoot, ".unerr", "manifest.json");
|
|
54628
54890
|
if (!existsSync43(manifestPath)) return null;
|
|
54629
54891
|
try {
|
|
54630
|
-
const raw =
|
|
54892
|
+
const raw = readFileSync37(manifestPath, "utf-8");
|
|
54631
54893
|
return JSON.parse(raw);
|
|
54632
54894
|
} catch {
|
|
54633
54895
|
return null;
|
|
@@ -54950,7 +55212,7 @@ function registerStatsCommand(program2) {
|
|
|
54950
55212
|
|
|
54951
55213
|
// src/commands/status.ts
|
|
54952
55214
|
init_git();
|
|
54953
|
-
import { existsSync as existsSync48, readFileSync as
|
|
55215
|
+
import { existsSync as existsSync48, readFileSync as readFileSync42 } from "fs";
|
|
54954
55216
|
import { join as join52 } from "path";
|
|
54955
55217
|
import React from "react";
|
|
54956
55218
|
function buildSuggestions(data) {
|
|
@@ -55001,7 +55263,7 @@ function registerStatusCommand(program2) {
|
|
|
55001
55263
|
const configPath = join52(unerrDir, "config.json");
|
|
55002
55264
|
if (existsSync48(configPath)) {
|
|
55003
55265
|
try {
|
|
55004
|
-
const config = JSON.parse(
|
|
55266
|
+
const config = JSON.parse(readFileSync42(configPath, "utf-8"));
|
|
55005
55267
|
repoId = config.repoId ?? "";
|
|
55006
55268
|
} catch {
|
|
55007
55269
|
}
|
|
@@ -55032,7 +55294,7 @@ function registerStatusCommand(program2) {
|
|
|
55032
55294
|
const pidPath2 = join52(unerrDir, "state", "proxy.pid");
|
|
55033
55295
|
if (existsSync48(pidPath2)) {
|
|
55034
55296
|
try {
|
|
55035
|
-
const pidStr =
|
|
55297
|
+
const pidStr = readFileSync42(pidPath2, "utf-8").trim();
|
|
55036
55298
|
const pid = Number.parseInt(pidStr, 10);
|
|
55037
55299
|
process.kill(pid, 0);
|
|
55038
55300
|
proxyStatus = `Running (PID ${pid})`;
|
|
@@ -55046,7 +55308,7 @@ function registerStatusCommand(program2) {
|
|
|
55046
55308
|
if (repoId && existsSync48(join52(manifestsDir, `${repoId}.json`))) {
|
|
55047
55309
|
try {
|
|
55048
55310
|
const manifest = JSON.parse(
|
|
55049
|
-
|
|
55311
|
+
readFileSync42(join52(manifestsDir, `${repoId}.json`), "utf-8")
|
|
55050
55312
|
);
|
|
55051
55313
|
const entityCount = manifest.entityCount ?? 0;
|
|
55052
55314
|
const edgeCount = manifest.edgeCount ?? 0;
|
|
@@ -55068,7 +55330,7 @@ function registerStatusCommand(program2) {
|
|
|
55068
55330
|
if (existsSync48(driftSummaryPath)) {
|
|
55069
55331
|
try {
|
|
55070
55332
|
const summary = JSON.parse(
|
|
55071
|
-
|
|
55333
|
+
readFileSync42(driftSummaryPath, "utf-8")
|
|
55072
55334
|
);
|
|
55073
55335
|
drift = {
|
|
55074
55336
|
modified: summary.modified ?? 0,
|
|
@@ -55083,7 +55345,7 @@ function registerStatusCommand(program2) {
|
|
|
55083
55345
|
const graphVersionPath = join52(unerrDir, "state", "graph_version.json");
|
|
55084
55346
|
if (existsSync48(graphVersionPath)) {
|
|
55085
55347
|
try {
|
|
55086
|
-
const gv = JSON.parse(
|
|
55348
|
+
const gv = JSON.parse(readFileSync42(graphVersionPath, "utf-8"));
|
|
55087
55349
|
healthGrade = gv.health_grade;
|
|
55088
55350
|
healthScore = gv.health_score;
|
|
55089
55351
|
} catch {
|
|
@@ -55102,7 +55364,7 @@ function registerStatusCommand(program2) {
|
|
|
55102
55364
|
const { unpack } = await import("msgpackr");
|
|
55103
55365
|
const { default: CozoDbConstructor } = await import("cozo-node");
|
|
55104
55366
|
const { CozoGraphStore: CozoGraphStore2 } = await Promise.resolve().then(() => (init_local_graph(), local_graph_exports));
|
|
55105
|
-
const raw =
|
|
55367
|
+
const raw = readFileSync42(snapshotPath2);
|
|
55106
55368
|
let buffer;
|
|
55107
55369
|
try {
|
|
55108
55370
|
buffer = gunzipSync3(raw);
|
|
@@ -55123,7 +55385,7 @@ function registerStatusCommand(program2) {
|
|
|
55123
55385
|
const statsPath = join52(unerrDir, "state", "session_stats.json");
|
|
55124
55386
|
if (existsSync48(statsPath) && proxyRunning) {
|
|
55125
55387
|
try {
|
|
55126
|
-
const liveStats = JSON.parse(
|
|
55388
|
+
const liveStats = JSON.parse(readFileSync42(statsPath, "utf-8"));
|
|
55127
55389
|
const localCalls = liveStats.toolCallsLocal ?? 0;
|
|
55128
55390
|
if (localCalls > 0) {
|
|
55129
55391
|
liveToolCalls = { local: localCalls };
|
|
@@ -55151,7 +55413,7 @@ function registerStatusCommand(program2) {
|
|
|
55151
55413
|
"firewall_stats.json"
|
|
55152
55414
|
);
|
|
55153
55415
|
if (existsSync48(firewallStatsPath)) {
|
|
55154
|
-
const fs6 = JSON.parse(
|
|
55416
|
+
const fs6 = JSON.parse(readFileSync42(firewallStatsPath, "utf-8"));
|
|
55155
55417
|
firewallBlocked = fs6.blocked ?? 0;
|
|
55156
55418
|
}
|
|
55157
55419
|
} catch {
|
|
@@ -55190,7 +55452,7 @@ function registerStatusCommand(program2) {
|
|
|
55190
55452
|
const snapshotMetaPath = join52(unerrDir, "state", "snapshot_meta.json");
|
|
55191
55453
|
if (existsSync48(snapshotMetaPath)) {
|
|
55192
55454
|
try {
|
|
55193
|
-
const meta = JSON.parse(
|
|
55455
|
+
const meta = JSON.parse(readFileSync42(snapshotMetaPath, "utf-8"));
|
|
55194
55456
|
if (meta.indexedAt) {
|
|
55195
55457
|
const ageMs = Date.now() - new Date(meta.indexedAt).getTime();
|
|
55196
55458
|
const ageHours = Math.floor(ageMs / 36e5);
|
|
@@ -55208,7 +55470,7 @@ function registerStatusCommand(program2) {
|
|
|
55208
55470
|
try {
|
|
55209
55471
|
const corrPath = join52(unerrDir, "state", "corrections_count.json");
|
|
55210
55472
|
if (existsSync48(corrPath)) {
|
|
55211
|
-
const cc = JSON.parse(
|
|
55473
|
+
const cc = JSON.parse(readFileSync42(corrPath, "utf-8"));
|
|
55212
55474
|
corrections = cc.count;
|
|
55213
55475
|
}
|
|
55214
55476
|
} catch {
|
|
@@ -55218,7 +55480,7 @@ function registerStatusCommand(program2) {
|
|
|
55218
55480
|
let ruleCount;
|
|
55219
55481
|
try {
|
|
55220
55482
|
if (existsSync48(graphVersionPath)) {
|
|
55221
|
-
const gv = JSON.parse(
|
|
55483
|
+
const gv = JSON.parse(readFileSync42(graphVersionPath, "utf-8"));
|
|
55222
55484
|
communityCount = gv.community_count;
|
|
55223
55485
|
conventionCount = gv.convention_count;
|
|
55224
55486
|
ruleCount = gv.rule_count;
|
|
@@ -55261,7 +55523,7 @@ function registerStatusCommand(program2) {
|
|
|
55261
55523
|
try {
|
|
55262
55524
|
const ledgerPath = join52(unerrDir, "ledger", "shadow.jsonl");
|
|
55263
55525
|
if (existsSync48(ledgerPath)) {
|
|
55264
|
-
const content =
|
|
55526
|
+
const content = readFileSync42(ledgerPath, "utf-8");
|
|
55265
55527
|
ledgerEntryCount = content.split("\n").filter((l) => l.trim().length > 0).length;
|
|
55266
55528
|
}
|
|
55267
55529
|
} catch {
|
|
@@ -55301,7 +55563,7 @@ function registerStatusCommand(program2) {
|
|
|
55301
55563
|
try {
|
|
55302
55564
|
const statsPath2 = join52(unerrDir, "state", "session_stats.json");
|
|
55303
55565
|
if (existsSync48(statsPath2)) {
|
|
55304
|
-
const raw = JSON.parse(
|
|
55566
|
+
const raw = JSON.parse(readFileSync42(statsPath2, "utf-8"));
|
|
55305
55567
|
const totalCalls = raw.toolCallsLocal ?? 0;
|
|
55306
55568
|
if (totalCalls > 0) {
|
|
55307
55569
|
const endTime = raw.updatedAt ? new Date(raw.updatedAt) : /* @__PURE__ */ new Date();
|
|
@@ -55337,7 +55599,7 @@ function registerStatusCommand(program2) {
|
|
|
55337
55599
|
try {
|
|
55338
55600
|
const sp = join52(cwd, ".claude", "settings.json");
|
|
55339
55601
|
if (existsSync48(sp)) {
|
|
55340
|
-
const raw =
|
|
55602
|
+
const raw = readFileSync42(sp, "utf8");
|
|
55341
55603
|
preBashHookConfigured = raw.includes("unerr hook pre-bash") || raw.includes('"unerr hook pre-bash"');
|
|
55342
55604
|
}
|
|
55343
55605
|
} catch {
|
|
@@ -55384,7 +55646,7 @@ function registerStatusCommand(program2) {
|
|
|
55384
55646
|
const { readTokenFlowEvents: readTokenFlowEvents2, aggregateSession: aggSession } = await Promise.resolve().then(() => (init_token_flow(), token_flow_exports));
|
|
55385
55647
|
const events = readTokenFlowEvents2(unerrDir);
|
|
55386
55648
|
if (events.length > 0) {
|
|
55387
|
-
const latestSessionId = events[events.length - 1]
|
|
55649
|
+
const latestSessionId = events[events.length - 1]?.session_id ?? "";
|
|
55388
55650
|
const summary = aggSession(events, latestSessionId);
|
|
55389
55651
|
if (summary.total_tokens_saved > 0) {
|
|
55390
55652
|
tokenFlowData = {
|
|
@@ -55628,7 +55890,7 @@ function registerTimelineCommand(program2) {
|
|
|
55628
55890
|
|
|
55629
55891
|
// src/commands/uninstall.ts
|
|
55630
55892
|
init_agent_registry();
|
|
55631
|
-
import { existsSync as existsSync50, readFileSync as
|
|
55893
|
+
import { existsSync as existsSync50, readFileSync as readFileSync44, unlinkSync as unlinkSync11, writeFileSync as writeFileSync26 } from "fs";
|
|
55632
55894
|
import { join as join54 } from "path";
|
|
55633
55895
|
init_hook_installer();
|
|
55634
55896
|
init_mcp_config_writer();
|
|
@@ -55803,7 +56065,7 @@ function removeCursorHooks(cwd) {
|
|
|
55803
56065
|
const hooksPath = join54(cwd, ".cursor", "hooks.json");
|
|
55804
56066
|
if (!existsSync50(hooksPath)) return false;
|
|
55805
56067
|
try {
|
|
55806
|
-
const config = JSON.parse(
|
|
56068
|
+
const config = JSON.parse(readFileSync44(hooksPath, "utf-8"));
|
|
55807
56069
|
if (!Array.isArray(config.hooks)) return false;
|
|
55808
56070
|
const before = config.hooks.length;
|
|
55809
56071
|
config.hooks = config.hooks.filter(
|
|
@@ -56227,7 +56489,7 @@ async function detectProjectRoot(cwd) {
|
|
|
56227
56489
|
let hasGit = false;
|
|
56228
56490
|
const normalizedCwd = cwd.replace(/\\/g, "/");
|
|
56229
56491
|
for (const ap of ANTI_SIGNAL_PATHS) {
|
|
56230
|
-
if (normalizedCwd === ap || normalizedCwd === ap
|
|
56492
|
+
if (normalizedCwd === ap || normalizedCwd === `${ap}/`) {
|
|
56231
56493
|
return {
|
|
56232
56494
|
isProject: false,
|
|
56233
56495
|
hasGit: false,
|
|
@@ -56392,7 +56654,7 @@ function readLocalConfig(cwd) {
|
|
|
56392
56654
|
const configPath = join80(cwd, ".unerr", "config.json");
|
|
56393
56655
|
if (!existsSync79(configPath)) return null;
|
|
56394
56656
|
try {
|
|
56395
|
-
return JSON.parse(
|
|
56657
|
+
return JSON.parse(readFileSync67(configPath, "utf-8"));
|
|
56396
56658
|
} catch {
|
|
56397
56659
|
return null;
|
|
56398
56660
|
}
|
|
@@ -56406,8 +56668,14 @@ async function resumeBoot(config) {
|
|
|
56406
56668
|
`\x1B[38;2;248;113;113m\u2717\x1B[0m No code project detected in this directory.
|
|
56407
56669
|
Found .unerr/config.json but the directory doesn't look like a project root.
|
|
56408
56670
|
Detection score: ${detection.score} (need ${DETECTION_THRESHOLD})
|
|
56409
|
-
|
|
56410
|
-
` : ""
|
|
56671
|
+
${antiSignals.length > 0 ? ` Negative signals: ${antiSignals.map((s) => s.replace("anti-", "")).join(", ")}
|
|
56672
|
+
` : ""}
|
|
56673
|
+
unerr checks for: project files (package.json, Cargo.toml, go.mod, ...),
|
|
56674
|
+
VCS directories (.git, .hg), IDE configs, CI/CD files, lock files,
|
|
56675
|
+
and source code across 50+ languages.
|
|
56676
|
+
|
|
56677
|
+
\u25B8 Run \x1B[1munerr\x1B[0m from a project root directory.
|
|
56678
|
+
`
|
|
56411
56679
|
);
|
|
56412
56680
|
process.exit(1);
|
|
56413
56681
|
}
|
|
@@ -56442,14 +56710,25 @@ async function firstRunBoot() {
|
|
|
56442
56710
|
`\x1B[38;2;248;113;113m\u2717\x1B[0m No code project detected in this directory.
|
|
56443
56711
|
unerr needs a folder containing source code to index.
|
|
56444
56712
|
Detection score: ${detection.score} (need ${DETECTION_THRESHOLD})
|
|
56445
|
-
|
|
56446
|
-
` : ""
|
|
56713
|
+
${antiSignals.length > 0 ? ` Negative signals: ${antiSignals.map((s) => s.replace("anti-", "")).join(", ")}
|
|
56714
|
+
` : ""}
|
|
56715
|
+
Checked for: project files (package.json, Cargo.toml, go.mod, pyproject.toml, ...),
|
|
56716
|
+
VCS directories (.git, .hg, .svn), IDE configs (.vscode, .idea),
|
|
56717
|
+
CI/CD files (.github, Jenkinsfile), lock files, and source code
|
|
56718
|
+
across 50+ languages in root + standard source directories.
|
|
56719
|
+
|
|
56720
|
+
\u25B8 Run \x1B[1munerr\x1B[0m from a project root directory.
|
|
56721
|
+
`
|
|
56447
56722
|
);
|
|
56448
56723
|
process.exit(1);
|
|
56449
56724
|
}
|
|
56450
56725
|
if (!detection.hasGit) {
|
|
56451
56726
|
process.stderr.write(
|
|
56452
|
-
|
|
56727
|
+
`\x1B[38;2;251;191;36m\u26A0\x1B[0m Project detected (${detection.reason}) but no git repository found.
|
|
56728
|
+
unerr works best with git. Consider running \x1B[1mgit init\x1B[0m first.
|
|
56729
|
+
Continuing anyway...
|
|
56730
|
+
|
|
56731
|
+
`
|
|
56453
56732
|
);
|
|
56454
56733
|
}
|
|
56455
56734
|
log24.info({
|
|
@@ -56588,7 +56867,14 @@ ${antiSignals.length > 0 ? ` Negative signals: ${antiSignals.map((s) => s.repla
|
|
|
56588
56867
|
return bridgeAndExit(startUdsBridge2, repoSock);
|
|
56589
56868
|
}
|
|
56590
56869
|
}
|
|
56591
|
-
const {
|
|
56870
|
+
const {
|
|
56871
|
+
daemonSockPath: daemonSockPath2,
|
|
56872
|
+
probeDaemon: probeDaemon2,
|
|
56873
|
+
ensureRepo: ensureRepo2,
|
|
56874
|
+
connectRepo: connectRepo2,
|
|
56875
|
+
disconnectRepo: disconnectRepo2,
|
|
56876
|
+
sendActivity: sendActivity2
|
|
56877
|
+
} = await Promise.resolve().then(() => (init_client(), client_exports));
|
|
56592
56878
|
const { findRepo: findRepo2 } = await Promise.resolve().then(() => (init_registry(), registry_exports));
|
|
56593
56879
|
const daemonSock = daemonSockPath2();
|
|
56594
56880
|
const daemonRunning = await probeDaemon2(daemonSock);
|
|
@@ -56656,7 +56942,7 @@ async function bridgeAndExit(startBridge, sockPath2) {
|
|
|
56656
56942
|
}
|
|
56657
56943
|
}
|
|
56658
56944
|
var program = new Command();
|
|
56659
|
-
program.name("unerr").description("Code intelligence for AI agents").version("0.1.
|
|
56945
|
+
program.name("unerr").description("Code intelligence for AI agents").version("0.1.2").option("--ide <type>", "IDE type: cursor, vscode, claude-code, windsurf").option("--mcp", "Start in MCP server mode (stdio, no interactive prompts)").option(
|
|
56660
56946
|
"--daemon-child",
|
|
56661
56947
|
"Run as a daemon-managed child process (internal, set by unerrd)"
|
|
56662
56948
|
).showHelpAfterError("(use --help for available commands)").action(
|