@unerr-ai/unerr 0.2.1 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -0
- package/dist/cli.js +37236 -35793
- package/package.json +1 -1
- package/dist/behaviors/agent-llm-bridge.js +0 -166
- package/dist/behaviors/architecture-guard.js +0 -256
- package/dist/behaviors/auto-doc.js +0 -247
- package/dist/behaviors/cascade-guard.js +0 -289
- package/dist/behaviors/change-narrative.js +0 -270
- package/dist/behaviors/convention-drift.js +0 -290
- package/dist/behaviors/framework.js +0 -235
- package/dist/behaviors/guard-formatter.js +0 -44
- package/dist/behaviors/incomplete-work.js +0 -270
- package/dist/behaviors/loop-breaker.js +0 -300
- package/dist/behaviors/session-continuity.js +0 -208
- package/dist/commands/branches.js +0 -97
- package/dist/commands/check-commit.js +0 -225
- package/dist/commands/compress-output.js +0 -64
- package/dist/commands/config-verify.js +0 -243
- package/dist/commands/daemon.js +0 -905
- package/dist/commands/dashboard.js +0 -52
- package/dist/commands/debug.js +0 -200
- package/dist/commands/enrich.js +0 -184
- package/dist/commands/exec.js +0 -233
- package/dist/commands/gain.js +0 -156
- package/dist/commands/hook.js +0 -88
- package/dist/commands/index.js +0 -88
- package/dist/commands/init.js +0 -74
- package/dist/commands/install.js +0 -505
- package/dist/commands/learn.js +0 -116
- package/dist/commands/manifest.js +0 -193
- package/dist/commands/rewind.js +0 -103
- package/dist/commands/serve.js +0 -19
- package/dist/commands/setup-wizard.js +0 -414
- package/dist/commands/skills.js +0 -64
- package/dist/commands/stats.js +0 -20
- package/dist/commands/status.js +0 -654
- package/dist/commands/timeline.js +0 -139
- package/dist/commands/uninstall.js +0 -230
- package/dist/components/App.js +0 -109
- package/dist/components/Banner.js +0 -12
- package/dist/components/ConfirmPrompt.js +0 -25
- package/dist/components/DriftSummary.js +0 -23
- package/dist/components/GradeBadge.js +0 -15
- package/dist/components/HealthCard.js +0 -18
- package/dist/components/InkSpinner.js +0 -22
- package/dist/components/InputBox.js +0 -17
- package/dist/components/KeyValue.js +0 -13
- package/dist/components/MessageList.js +0 -14
- package/dist/components/ProgressBar.js +0 -26
- package/dist/components/Section.js +0 -16
- package/dist/components/SessionSummaryCard.js +0 -73
- package/dist/components/StartupDisplay.js +0 -24
- package/dist/components/StatusDashboard.js +0 -57
- package/dist/components/StatusLine.js +0 -8
- package/dist/components/StepLine.js +0 -22
- package/dist/components/Theme.js +0 -20
- package/dist/components/ToolProgress.js +0 -8
- package/dist/components/ViolationList.js +0 -21
- package/dist/components/render.js +0 -13
- package/dist/config/agent-registry.js +0 -237
- package/dist/config/claude-settings-hooks.js +0 -304
- package/dist/config/hook-installer.js +0 -65
- package/dist/config/instruction-writer.js +0 -388
- package/dist/config/mcp-config-writer.js +0 -266
- package/dist/config/settings.js +0 -174
- package/dist/config/tool-detector.js +0 -42
- package/dist/config/value-surfacing.js +0 -119
- package/dist/core/context-assembly.js +0 -108
- package/dist/core/conversation.js +0 -33
- package/dist/core/local-chat-provider.js +0 -475
- package/dist/core/provider-factory.js +0 -55
- package/dist/core/providers.js +0 -90
- package/dist/core/query-engine.js +0 -174
- package/dist/daemon/api.js +0 -312
- package/dist/daemon/autostart.js +0 -119
- package/dist/daemon/bootstrap.js +0 -39
- package/dist/daemon/client.js +0 -164
- package/dist/daemon/detect-ci.js +0 -81
- package/dist/daemon/platform-linux.js +0 -146
- package/dist/daemon/platform-macos.js +0 -134
- package/dist/daemon/platform-windows.js +0 -116
- package/dist/daemon/process-manager.js +0 -299
- package/dist/daemon/protocol.js +0 -23
- package/dist/daemon/registry.js +0 -270
- package/dist/daemon/settings-schema.js +0 -72
- package/dist/daemon/system-health.js +0 -134
- package/dist/daemon/version-checker.js +0 -262
- package/dist/daemon/warm-start.js +0 -223
- package/dist/entrypoints/cli.js +0 -1043
- package/dist/entrypoints/daemon.js +0 -380
- package/dist/entrypoints/repl.js +0 -147
- package/dist/hooks/adapters/claude-code.js +0 -90
- package/dist/hooks/adapters/cline.js +0 -100
- package/dist/hooks/adapters/cursor.js +0 -98
- package/dist/hooks/hook-dedup.js +0 -79
- package/dist/hooks/hook-runner.js +0 -113
- package/dist/hooks/navigation-hooks.js +0 -175
- package/dist/hooks/prompt-hooks.js +0 -63
- package/dist/hooks/shell-hooks.js +0 -47
- package/dist/ignore.js +0 -111
- package/dist/intelligence/approach-suggester.js +0 -61
- package/dist/intelligence/ast-extractor.js +0 -2615
- package/dist/intelligence/ast-worker.js +0 -34
- package/dist/intelligence/background-indexer.js +0 -121
- package/dist/intelligence/blast-radius.js +0 -200
- package/dist/intelligence/community-detection.js +0 -691
- package/dist/intelligence/community-detector.js +0 -184
- package/dist/intelligence/computation-scheduler.js +0 -75
- package/dist/intelligence/confidence-propagation.js +0 -47
- package/dist/intelligence/convention-detector.js +0 -242
- package/dist/intelligence/convention-learner.js +0 -205
- package/dist/intelligence/convention-matcher.js +0 -205
- package/dist/intelligence/cozo-schema.js +0 -376
- package/dist/intelligence/decision-point-detector.js +0 -90
- package/dist/intelligence/deep-dive-tools.js +0 -586
- package/dist/intelligence/durability-scorer.js +0 -84
- package/dist/intelligence/exploration-cost.js +0 -204
- package/dist/intelligence/exploration-pattern-tracker.js +0 -61
- package/dist/intelligence/fact-generator.js +0 -322
- package/dist/intelligence/facts-schema.js +0 -90
- package/dist/intelligence/file-intelligence.js +0 -59
- package/dist/intelligence/graph-holder.js +0 -220
- package/dist/intelligence/graph-temporal-joiner.js +0 -238
- package/dist/intelligence/health-grade.js +0 -423
- package/dist/intelligence/health-grader.js +0 -200
- package/dist/intelligence/health-map-data.js +0 -259
- package/dist/intelligence/import-symbols.js +0 -136
- package/dist/intelligence/incremental-indexer.js +0 -658
- package/dist/intelligence/indexer/centrality.js +0 -62
- package/dist/intelligence/indexer/cfg-context.js +0 -95
- package/dist/intelligence/indexer/confidence.js +0 -34
- package/dist/intelligence/indexer/cross-file-resolver.js +0 -104
- package/dist/intelligence/indexer/edge-repair.js +0 -89
- package/dist/intelligence/indexer/entity-key.js +0 -17
- package/dist/intelligence/indexer/export-map.js +0 -132
- package/dist/intelligence/indexer/git-cochange.js +0 -128
- package/dist/intelligence/indexer/graph-patch.js +0 -147
- package/dist/intelligence/indexer/incremental.js +0 -78
- package/dist/intelligence/indexer/ingest.js +0 -160
- package/dist/intelligence/indexer/language-detect.js +0 -226
- package/dist/intelligence/indexer/metadata.js +0 -63
- package/dist/intelligence/indexer/mutation-tracker.js +0 -79
- package/dist/intelligence/indexer/orchestrator.js +0 -155
- package/dist/intelligence/indexer/plugin-interface.js +0 -31
- package/dist/intelligence/indexer/plugins/csharp.js +0 -440
- package/dist/intelligence/indexer/plugins/go.js +0 -335
- package/dist/intelligence/indexer/plugins/java.js +0 -370
- package/dist/intelligence/indexer/plugins/python.js +0 -358
- package/dist/intelligence/indexer/plugins/regex-fallback.js +0 -82
- package/dist/intelligence/indexer/plugins/ruby.js +0 -290
- package/dist/intelligence/indexer/plugins/rust.js +0 -484
- package/dist/intelligence/indexer/plugins/tier2-generic.js +0 -310
- package/dist/intelligence/indexer/plugins/typescript.js +0 -456
- package/dist/intelligence/indexer/resource-monitor.js +0 -93
- package/dist/intelligence/indexer/scip/decoder.js +0 -253
- package/dist/intelligence/indexer/scip/detector.js +0 -232
- package/dist/intelligence/indexer/scip/downloader.js +0 -427
- package/dist/intelligence/indexer/scip/fallback.js +0 -34
- package/dist/intelligence/indexer/scip/merger.js +0 -109
- package/dist/intelligence/indexer/scip/orchestrator.js +0 -433
- package/dist/intelligence/indexer/scip/runner.js +0 -98
- package/dist/intelligence/indexer/snapshot.js +0 -66
- package/dist/intelligence/indexer/test-detector.js +0 -196
- package/dist/intelligence/indexer/watch-integration.js +0 -61
- package/dist/intelligence/indexer/worker.js +0 -85
- package/dist/intelligence/local-convention-detector.js +0 -437
- package/dist/intelligence/local-embeddings.js +0 -190
- package/dist/intelligence/local-graph.js +0 -1946
- package/dist/intelligence/local-indexer.js +0 -1575
- package/dist/intelligence/local-llm.js +0 -163
- package/dist/intelligence/local-rule-generator.js +0 -154
- package/dist/intelligence/local-snapshot.js +0 -213
- package/dist/intelligence/negative-knowledge.js +0 -103
- package/dist/intelligence/persistent-db.js +0 -85
- package/dist/intelligence/query-router.js +0 -2556
- package/dist/intelligence/risk-classifier.js +0 -116
- package/dist/intelligence/rule-evaluator.js +0 -380
- package/dist/intelligence/rule-generator.js +0 -49
- package/dist/intelligence/search-index.js +0 -173
- package/dist/intelligence/semantic/docstring-extractor.js +0 -67
- package/dist/intelligence/semantic/embedding-store.js +0 -52
- package/dist/intelligence/semantic/enrichment-orchestrator.js +0 -48
- package/dist/intelligence/semantic/git-message-miner.js +0 -114
- package/dist/intelligence/semantic/identifier-tokenizer.js +0 -51
- package/dist/intelligence/semantic/node2vec-embeddings.js +0 -71
- package/dist/intelligence/semantic/node2vec-walks.js +0 -103
- package/dist/intelligence/semantic/path-domain-inference.js +0 -112
- package/dist/intelligence/semantic/similarity-engine.js +0 -60
- package/dist/intelligence/semantic/tfidf-vectors.js +0 -88
- package/dist/intelligence/session-brief-builder.js +0 -159
- package/dist/intelligence/session-context.js +0 -221
- package/dist/intelligence/session-health-monitor.js +0 -211
- package/dist/intelligence/session-narrative.js +0 -197
- package/dist/intelligence/session-pattern-analyzer.js +0 -218
- package/dist/intelligence/signal-scorer.js +0 -390
- package/dist/intelligence/signal-show-store.js +0 -182
- package/dist/intelligence/smart-truncate.js +0 -158
- package/dist/intelligence/subgraph-cache.js +0 -88
- package/dist/intelligence/temporal-facts.js +0 -494
- package/dist/intelligence/token-estimator.js +0 -100
- package/dist/intelligence/tool-injector.js +0 -87
- package/dist/intelligence/tree-sitter-loader.js +0 -71
- package/dist/intelligence/worker-pool.js +0 -116
- package/dist/proxy/arg-validator.js +0 -79
- package/dist/proxy/auto-bootstrap.js +0 -167
- package/dist/proxy/bridge.js +0 -147
- package/dist/proxy/budget-enforcer.js +0 -70
- package/dist/proxy/compression-quality-monitor.js +0 -160
- package/dist/proxy/compression-stats.js +0 -51
- package/dist/proxy/context-rot-detector.js +0 -137
- package/dist/proxy/drift-detector.js +0 -139
- package/dist/proxy/efficiency-tracker.js +0 -79
- package/dist/proxy/fact-ranking.js +0 -154
- package/dist/proxy/format-encoder.js +0 -266
- package/dist/proxy/http-transport.js +0 -90
- package/dist/proxy/lifecycle-actor.js +0 -55
- package/dist/proxy/lifecycle-machine.js +0 -187
- package/dist/proxy/log-tailer.js +0 -265
- package/dist/proxy/model-pricing.js +0 -98
- package/dist/proxy/network-firewall.js +0 -141
- package/dist/proxy/nudge-state.js +0 -93
- package/dist/proxy/output-compressor.js +0 -185
- package/dist/proxy/pid-lock.js +0 -291
- package/dist/proxy/proxy-context.js +0 -11
- package/dist/proxy/proxy.js +0 -2633
- package/dist/proxy/response-enrichment.js +0 -32
- package/dist/proxy/response-envelope.js +0 -313
- package/dist/proxy/session-dedup.js +0 -82
- package/dist/proxy/session-legend.js +0 -30
- package/dist/proxy/session-persistence.js +0 -210
- package/dist/proxy/session-resume.js +0 -94
- package/dist/proxy/session-stats.js +0 -513
- package/dist/proxy/shell-classifier.js +0 -1346
- package/dist/proxy/shell-compression-log.js +0 -93
- package/dist/proxy/shell-compressor.js +0 -390
- package/dist/proxy/shell-graph-boost.js +0 -202
- package/dist/proxy/shell-monitor-map.js +0 -18
- package/dist/proxy/shell-stats.js +0 -54
- package/dist/proxy/shell-strategies/cloud.js +0 -215
- package/dist/proxy/shell-strategies/diff.js +0 -159
- package/dist/proxy/shell-strategies/error-diagnostic.js +0 -796
- package/dist/proxy/shell-strategies/filter-dsl.js +0 -358
- package/dist/proxy/shell-strategies/git-status.js +0 -177
- package/dist/proxy/shell-strategies/key-value.js +0 -193
- package/dist/proxy/shell-strategies/log-text.js +0 -154
- package/dist/proxy/shell-strategies/omni.js +0 -188
- package/dist/proxy/shell-strategies/progress.js +0 -55
- package/dist/proxy/shell-strategies/redact.js +0 -76
- package/dist/proxy/shell-strategies/structured.js +0 -241
- package/dist/proxy/shell-strategies/tabular.js +0 -243
- package/dist/proxy/shell-strategies/test-results-types.js +0 -13
- package/dist/proxy/shell-strategies/test-results.js +0 -784
- package/dist/proxy/shell-strategies/tree-paths.js +0 -144
- package/dist/proxy/shell-strategies/yaml.js +0 -182
- package/dist/proxy/shell-tee.js +0 -111
- package/dist/proxy/signal-dedup.js +0 -171
- package/dist/proxy/startup-renderer.js +0 -158
- package/dist/proxy/task-token-display.js +0 -38
- package/dist/proxy/token-counter.js +0 -61
- package/dist/proxy/tool-clusters.js +0 -273
- package/dist/proxy/tool-definitions.js +0 -525
- package/dist/proxy/transport-mux.js +0 -229
- package/dist/proxy/wire-cap.js +0 -268
- package/dist/rules/developer.mozilla.org.json +0 -9
- package/dist/rules/github.com.json +0 -21
- package/dist/schemas/api/skills.js +0 -19
- package/dist/schemas/common/errors.js +0 -7
- package/dist/schemas/common/headers.js +0 -5
- package/dist/schemas/entities/edge.js +0 -25
- package/dist/schemas/entities/entity.js +0 -22
- package/dist/schemas/entities/rule.js +0 -18
- package/dist/schemas/index.js +0 -14
- package/dist/server/event-bus.js +0 -59
- package/dist/server/http.js +0 -156
- package/dist/server/middleware.js +0 -70
- package/dist/server/routes/drift.js +0 -97
- package/dist/server/routes/intelligence.js +0 -1217
- package/dist/server/routes/reasoning-quality.js +0 -444
- package/dist/server/routes/session.js +0 -86
- package/dist/server/routes/stream.js +0 -120
- package/dist/server/routes/system.js +0 -73
- package/dist/server/routes/temporal.js +0 -170
- package/dist/server/routes/timeline.js +0 -232
- package/dist/server/routes/token-flow.js +0 -403
- package/dist/skills/effectiveness-tracker.js +0 -93
- package/dist/skills/local-pack.js +0 -380
- package/dist/skills/resolver.js +0 -495
- package/dist/state-detector.js +0 -83
- package/dist/timeline/intent-detector.js +0 -263
- package/dist/timeline/loop-miner.js +0 -140
- package/dist/timeline/open-threads.js +0 -49
- package/dist/timeline/signal-reinforcer.js +0 -62
- package/dist/timeline/timeline-bootstrap.js +0 -151
- package/dist/timeline/timeline-store.js +0 -618
- package/dist/tools/coding/bash.js +0 -49
- package/dist/tools/coding/file-edit.js +0 -72
- package/dist/tools/coding/file-outline.js +0 -227
- package/dist/tools/coding/file-read-protocol.js +0 -425
- package/dist/tools/coding/file-read.js +0 -35
- package/dist/tools/coding/file-write.js +0 -43
- package/dist/tools/coding/glob-tool.js +0 -109
- package/dist/tools/coding/grep.js +0 -162
- package/dist/tools/coding/index.js +0 -27
- package/dist/tools/intelligence/index.js +0 -269
- package/dist/tools/intelligence/record-fact.js +0 -48
- package/dist/tools/intelligence/timeline-markers.js +0 -130
- package/dist/tools/registry.js +0 -47
- package/dist/tools/types.js +0 -8
- package/dist/tracking/auto-snapshot-triggers.js +0 -246
- package/dist/tracking/branch-context.js +0 -115
- package/dist/tracking/branch-snapshot.js +0 -217
- package/dist/tracking/causal-bridge.js +0 -317
- package/dist/tracking/circuit-breaker.js +0 -147
- package/dist/tracking/commit-watcher.js +0 -114
- package/dist/tracking/context-ledger.js +0 -119
- package/dist/tracking/correction-detector.js +0 -324
- package/dist/tracking/drift-tracker.js +0 -874
- package/dist/tracking/durability-tracker.js +0 -94
- package/dist/tracking/entity-rewind.js +0 -200
- package/dist/tracking/file-hash-state.js +0 -114
- package/dist/tracking/git-attribution.js +0 -132
- package/dist/tracking/git-trailers.js +0 -171
- package/dist/tracking/intelligence-counter.js +0 -46
- package/dist/tracking/intent-correlator.js +0 -202
- package/dist/tracking/intent-encoder.js +0 -52
- package/dist/tracking/intent-token-tracker.js +0 -159
- package/dist/tracking/ledger-archiver.js +0 -94
- package/dist/tracking/ledger-chains.js +0 -245
- package/dist/tracking/metrics-store.js +0 -361
- package/dist/tracking/native-watcher.js +0 -131
- package/dist/tracking/offline-rewind.js +0 -295
- package/dist/tracking/pending-violations.js +0 -74
- package/dist/tracking/persistence-effectiveness.js +0 -167
- package/dist/tracking/prompt-durability.js +0 -202
- package/dist/tracking/quality-signals.js +0 -213
- package/dist/tracking/redactor.js +0 -73
- package/dist/tracking/rewind-engine.js +0 -161
- package/dist/tracking/session-history.js +0 -128
- package/dist/tracking/session-receipt.js +0 -88
- package/dist/tracking/session-summary-writer.js +0 -157
- package/dist/tracking/shadow-ledger.js +0 -321
- package/dist/tracking/stash-manager.js +0 -258
- package/dist/tracking/timeline-fork.js +0 -213
- package/dist/tracking/timeline.js +0 -69
- package/dist/tracking/token-flow.js +0 -276
- package/dist/tracking/turn-segmenter.js +0 -122
- package/dist/tracking/weekly-accumulator.js +0 -179
- package/dist/tracking/working-snapshots.js +0 -188
- package/dist/tracking/workspace-manifest.js +0 -176
- package/dist/transport/http.js +0 -102
- package/dist/utils/counterfactual.js +0 -65
- package/dist/utils/deep-link.js +0 -34
- package/dist/utils/detect.js +0 -193
- package/dist/utils/exec.js +0 -73
- package/dist/utils/file-logger.js +0 -87
- package/dist/utils/format-error.js +0 -29
- package/dist/utils/git.js +0 -181
- package/dist/utils/log.js +0 -57
- package/dist/utils/logger.js +0 -35
- package/dist/utils/mcp-content-json.js +0 -8
- package/dist/utils/session-logger.js +0 -154
- package/dist/utils/startup-log.js +0 -512
- package/dist/utils/ui.js +0 -56
|
@@ -1,193 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Strategy T6 — key=value (env, printenv) and Key: Value compression.
|
|
3
|
-
* Drops noisy keys, truncates long values, shortens PATH.
|
|
4
|
-
* Handles both KEY=VALUE format (env) and Key: Value format (kubectl describe, systemctl).
|
|
5
|
-
*/
|
|
6
|
-
/** Keys to drop from colon-format output (k8s/systemd noise). */
|
|
7
|
-
const DROP_COLON_KEYS = new Set([
|
|
8
|
-
"managedFields",
|
|
9
|
-
"resourceVersion",
|
|
10
|
-
"selfLink",
|
|
11
|
-
"uid",
|
|
12
|
-
"creationTimestamp",
|
|
13
|
-
"generation",
|
|
14
|
-
"ownerReferences",
|
|
15
|
-
"finalizers",
|
|
16
|
-
"kubectl.kubernetes.io/last-applied-configuration",
|
|
17
|
-
"deployment.kubernetes.io/revision",
|
|
18
|
-
"control-plane.alpha.kubernetes.io/leader",
|
|
19
|
-
]);
|
|
20
|
-
const DROP_KEYS = new Set([
|
|
21
|
-
// PWD/shell state
|
|
22
|
-
"OLDPWD",
|
|
23
|
-
"SHLVL",
|
|
24
|
-
"_",
|
|
25
|
-
"PWD",
|
|
26
|
-
// Terminal noise
|
|
27
|
-
"LS_COLORS",
|
|
28
|
-
"LESSOPEN",
|
|
29
|
-
"LESSCLOSE",
|
|
30
|
-
"LSCOLORS",
|
|
31
|
-
"TERM",
|
|
32
|
-
"TERM_PROGRAM",
|
|
33
|
-
"TERM_SESSION_ID",
|
|
34
|
-
"COLORTERM",
|
|
35
|
-
"CLICOLOR",
|
|
36
|
-
"CLICOLOR_FORCE",
|
|
37
|
-
"FORCE_COLOR",
|
|
38
|
-
// Locale
|
|
39
|
-
"LANG",
|
|
40
|
-
"LC_ALL",
|
|
41
|
-
"LC_CTYPE",
|
|
42
|
-
"LC_MESSAGES",
|
|
43
|
-
"LC_COLLATE",
|
|
44
|
-
"LC_MONETARY",
|
|
45
|
-
"LC_NUMERIC",
|
|
46
|
-
"LC_TIME",
|
|
47
|
-
// System noise
|
|
48
|
-
"HOSTNAME",
|
|
49
|
-
"LOGNAME",
|
|
50
|
-
"DISPLAY",
|
|
51
|
-
"XDG_SESSION_TYPE",
|
|
52
|
-
"XDG_RUNTIME_DIR",
|
|
53
|
-
"XDG_DATA_DIRS",
|
|
54
|
-
"XDG_CONFIG_DIRS",
|
|
55
|
-
"DBUS_SESSION_BUS_ADDRESS",
|
|
56
|
-
"DESKTOP_SESSION",
|
|
57
|
-
// SSH/GPG
|
|
58
|
-
"SSH_AUTH_SOCK",
|
|
59
|
-
"SSH_AGENT_PID",
|
|
60
|
-
"GPG_AGENT_INFO",
|
|
61
|
-
"GPG_TTY",
|
|
62
|
-
// Shell internals
|
|
63
|
-
"SHELL",
|
|
64
|
-
"BASH_VERSION",
|
|
65
|
-
"ZSH_VERSION",
|
|
66
|
-
"HISTSIZE",
|
|
67
|
-
"HISTFILESIZE",
|
|
68
|
-
"HIST_STAMPS",
|
|
69
|
-
"SAVEHIST",
|
|
70
|
-
"HISTCONTROL",
|
|
71
|
-
"HISTFILE",
|
|
72
|
-
// Misc
|
|
73
|
-
"MANPATH",
|
|
74
|
-
"INFOPATH",
|
|
75
|
-
"MAIL",
|
|
76
|
-
]);
|
|
77
|
-
const VALUE_MAX = 200;
|
|
78
|
-
/** Compress colon-format output (kubectl describe, systemctl status, etc.) */
|
|
79
|
-
function compressColonFormat(lines) {
|
|
80
|
-
const kept = [];
|
|
81
|
-
let i = 0;
|
|
82
|
-
while (i < lines.length) {
|
|
83
|
-
const line = lines[i];
|
|
84
|
-
const colonMatch = /^(\s{0,4})([\w][\w\s./-]*):\s*(.*)$/.exec(line);
|
|
85
|
-
if (!colonMatch) {
|
|
86
|
-
if (line.trim())
|
|
87
|
-
kept.push(line.trimEnd());
|
|
88
|
-
i++;
|
|
89
|
-
continue;
|
|
90
|
-
}
|
|
91
|
-
const [, indent, key, value] = colonMatch;
|
|
92
|
-
const keyTrimmed = key?.trim();
|
|
93
|
-
// Drop noisy k8s keys
|
|
94
|
-
if (keyTrimmed && DROP_COLON_KEYS.has(keyTrimmed)) {
|
|
95
|
-
i++;
|
|
96
|
-
// Skip indented child lines
|
|
97
|
-
const childIndent = (indent?.length ?? 0) + 2;
|
|
98
|
-
while (i < lines.length) {
|
|
99
|
-
const nextLine = lines[i];
|
|
100
|
-
if (nextLine.trim() === "") {
|
|
101
|
-
i++;
|
|
102
|
-
break;
|
|
103
|
-
}
|
|
104
|
-
const nextIndent = nextLine.match(/^(\s*)/)?.[1]?.length ?? 0;
|
|
105
|
-
if (nextIndent < childIndent && nextLine.trim())
|
|
106
|
-
break;
|
|
107
|
-
i++;
|
|
108
|
-
}
|
|
109
|
-
continue;
|
|
110
|
-
}
|
|
111
|
-
// Check for indented sub-block
|
|
112
|
-
const childIndent = (indent?.length ?? 0) + 2;
|
|
113
|
-
let childCount = 0;
|
|
114
|
-
let j = i + 1;
|
|
115
|
-
while (j < lines.length) {
|
|
116
|
-
const nextLine = lines[j];
|
|
117
|
-
if (nextLine.trim() === "")
|
|
118
|
-
break;
|
|
119
|
-
const nextInd = nextLine.match(/^(\s*)/)?.[1]?.length ?? 0;
|
|
120
|
-
if (nextInd < childIndent)
|
|
121
|
-
break;
|
|
122
|
-
childCount++;
|
|
123
|
-
j++;
|
|
124
|
-
}
|
|
125
|
-
if (childCount > 10 && !value?.trim()) {
|
|
126
|
-
// Collapse large sub-blocks
|
|
127
|
-
kept.push(`${indent}${keyTrimmed}: [${childCount} entries]`);
|
|
128
|
-
i = j;
|
|
129
|
-
}
|
|
130
|
-
else {
|
|
131
|
-
// Truncate long values
|
|
132
|
-
let val = value ?? "";
|
|
133
|
-
if (val.length > VALUE_MAX) {
|
|
134
|
-
val = `${val.slice(0, 100)}…(${val.length} chars)`;
|
|
135
|
-
}
|
|
136
|
-
kept.push(val ? `${indent}${keyTrimmed}: ${val}` : line.trimEnd());
|
|
137
|
-
i++;
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
return kept.join("\n");
|
|
141
|
-
}
|
|
142
|
-
export function compressKeyValue(raw, command) {
|
|
143
|
-
const lines = raw.split("\n");
|
|
144
|
-
// Detect format: KEY=VALUE vs Key: Value
|
|
145
|
-
const equalsCount = lines.filter((l) => /^[A-Za-z_]\w*=/.test(l)).length;
|
|
146
|
-
const colonCount = lines.filter((l) => /^\s{0,4}[A-Za-z][\w\s-]*:\s/.test(l)).length;
|
|
147
|
-
// Nothing to compress: input has no key=value or key:value rows. The
|
|
148
|
-
// classifier sometimes maps a `git`/`kubectl` subcommand to key_value
|
|
149
|
-
// (correct hint) even when the actual output is a single bare word
|
|
150
|
-
// (e.g. `git branch --show-current` → "main\n"). Emitting the
|
|
151
|
-
// `_shell_fmt:key_value\n` header on a sub-header-length payload is
|
|
152
|
-
// strictly net-negative — passthrough verbatim instead. Matches the
|
|
153
|
-
// "header is fixed overhead with nothing to decode" convention from
|
|
154
|
-
// log_text / omni / progress / yaml / tabular.
|
|
155
|
-
if (colonCount === 0 && equalsCount === 0)
|
|
156
|
-
return raw;
|
|
157
|
-
if (colonCount > equalsCount) {
|
|
158
|
-
const body = compressColonFormat(lines);
|
|
159
|
-
const clipped = body.length > 8000
|
|
160
|
-
? `${body.slice(0, 5000)}\n…kv_omitted…\n${body.slice(-2000)}`
|
|
161
|
-
: body;
|
|
162
|
-
return `_shell_fmt:key_value\n${clipped}`;
|
|
163
|
-
}
|
|
164
|
-
// Original KEY=VALUE format handling
|
|
165
|
-
void command;
|
|
166
|
-
const kept = [];
|
|
167
|
-
for (const line of lines) {
|
|
168
|
-
const m = /^([A-Za-z_][A-Za-z0-9_]*)=(.*)$/.exec(line);
|
|
169
|
-
if (!m) {
|
|
170
|
-
if (line.trim())
|
|
171
|
-
kept.push(line.trimEnd());
|
|
172
|
-
continue;
|
|
173
|
-
}
|
|
174
|
-
const key = m[1];
|
|
175
|
-
let val = m[2] ?? "";
|
|
176
|
-
if (!key || DROP_KEYS.has(key))
|
|
177
|
-
continue;
|
|
178
|
-
// Shorten PATH
|
|
179
|
-
if (key === "PATH" && val.length > VALUE_MAX) {
|
|
180
|
-
const parts = val.split(":");
|
|
181
|
-
val = `${parts.slice(0, 3).join(":")}:…:${parts.length} segments`;
|
|
182
|
-
}
|
|
183
|
-
else if (val.length > VALUE_MAX) {
|
|
184
|
-
val = `${val.slice(0, 100)}…(${val.length} chars)`;
|
|
185
|
-
}
|
|
186
|
-
kept.push(`${key}=${val}`);
|
|
187
|
-
}
|
|
188
|
-
const body = kept.join("\n");
|
|
189
|
-
const clipped = body.length > 8000
|
|
190
|
-
? `${body.slice(0, 5000)}\n…kv_omitted…\n${body.slice(-2000)}`
|
|
191
|
-
: body;
|
|
192
|
-
return `_shell_fmt:key_value\n${clipped}`;
|
|
193
|
-
}
|
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Strategy T3 — log/build output compression.
|
|
3
|
-
* Deduplicates by normalized pattern, preserves errors, emits compact summary.
|
|
4
|
-
*/
|
|
5
|
-
const SMALL_THRESHOLD = 80;
|
|
6
|
-
const MAX_PATTERNS = 20;
|
|
7
|
-
const MAX_ERROR_LINES = 30;
|
|
8
|
-
const MAX_KEPT_LINES = 20;
|
|
9
|
-
const ERROR_RE = /\b(ERROR|FATAL|CRIT|PANIC|Exception|Traceback|FAIL(?:ED)?|WARN(?:ING)?)\b/i;
|
|
10
|
-
const FRAME_RE = /^\s+at\s/;
|
|
11
|
-
const BUILD_RESULT_RE = /\b(error|warning|built|compiled|bundled|output|dist\/|size:|gzip:|emitted|generated|BUILD (SUCCESS|FAIL)|Finished|Total time|succeeded|SUCCEED|actionable tasks|up-to-date)\b/i;
|
|
12
|
-
const BUILD_CMD_RE = /\b(build|compile|bundle|webpack|vite build|rollup|esbuild|swc|parcel|make|cmake|ninja|gradle|gradlew|mvn|sbt|xcodebuild|dotnet build|cargo build|go build|nx build|turbo|bazel)\b/i;
|
|
13
|
-
/**
|
|
14
|
-
* Normalize a log line by replacing timestamps, UUIDs, IPs, and timings
|
|
15
|
-
* with placeholders so identical-in-spirit lines merge.
|
|
16
|
-
*/
|
|
17
|
-
function normalizeLogLine(line) {
|
|
18
|
-
return (line
|
|
19
|
-
.replace(/\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2}[.\d]*Z?/g, "<TS>")
|
|
20
|
-
.replace(/\b[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\b/gi, "<UUID>")
|
|
21
|
-
.replace(/\b[0-9a-f]{7,40}\b/gi, "<HASH>")
|
|
22
|
-
.replace(/\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b/g, "<IP>")
|
|
23
|
-
// File paths: src/foo/bar.ts → <PATH>
|
|
24
|
-
.replace(/\b(?:src|lib|app|test|pkg|cmd|internal)\/\S+/g, "<PATH>")
|
|
25
|
-
// Bare filenames with extensions
|
|
26
|
-
.replace(/\b[\w.-]+\.(ts|js|tsx|jsx|py|go|rs|c|cpp|java|rb|swift|kt|cs|o|so|dll|wasm)\b/g, "<FILE>")
|
|
27
|
-
// Relative/absolute paths
|
|
28
|
-
.replace(/(?:\.\.?\/|\/)[\w./-]+/g, "<PATH>")
|
|
29
|
-
// Package names with versions: foo@1.2.3, foo-1.2.3, foo v1.2.3
|
|
30
|
-
.replace(/\b[\w@/-]+[@-]\d+\.\d+[\w.-]*/g, "<PKG>")
|
|
31
|
-
// Port numbers
|
|
32
|
-
.replace(/:\d{2,5}\b/g, ":<PORT>")
|
|
33
|
-
// Timings with units
|
|
34
|
-
.replace(/\b\d+(\.\d+)?\s*(ms|s|sec|min|MB|KB|GB|B|bytes)\b/gi, "<N>$2")
|
|
35
|
-
.replace(/\b\d+ms\b/g, "<N>ms")
|
|
36
|
-
.replace(/\b\d+\.\d+s\b/g, "<N>s")
|
|
37
|
-
.replace(/\blatency=\d+/g, "latency=<N>")
|
|
38
|
-
.replace(/\bstatus=\d{3}/g, "status=<N>")
|
|
39
|
-
// Generic numbers (last, after specific patterns)
|
|
40
|
-
.replace(/\b\d+\b/g, "<N>"));
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* R1 — success short-circuit. When the entire output is a clean build/run
|
|
44
|
-
* (no errors, no warnings, classic "all green" markers), collapse to a
|
|
45
|
-
* one-line summary regardless of total length. Tee still preserves the raw
|
|
46
|
-
* payload on disk for recovery.
|
|
47
|
-
*/
|
|
48
|
-
const SUCCESS_PATTERNS = [
|
|
49
|
-
/\bBUILD SUCCESS(?:FUL)?\b/i,
|
|
50
|
-
/\bbuild succeeded\b/i,
|
|
51
|
-
/\bbuilt successfully\b/i,
|
|
52
|
-
/\bcompil(?:ed|ation) successful\b/i,
|
|
53
|
-
/^Finished\b.*\bin\s/m,
|
|
54
|
-
/\b0 errors?,?\s*0 warnings?\b/i,
|
|
55
|
-
/\bno (?:errors|problems|issues|violations) (?:found|reported)\b/i,
|
|
56
|
-
/\ball checks pass(?:ed)?\b/i,
|
|
57
|
-
];
|
|
58
|
-
function isCleanSuccess(text) {
|
|
59
|
-
if (ERROR_RE.test(text))
|
|
60
|
-
return { ok: false };
|
|
61
|
-
for (const pat of SUCCESS_PATTERNS) {
|
|
62
|
-
const m = text.match(pat);
|
|
63
|
-
if (m)
|
|
64
|
-
return { ok: true, line: m[0] };
|
|
65
|
-
}
|
|
66
|
-
return { ok: false };
|
|
67
|
-
}
|
|
68
|
-
export function compressLogText(text, command) {
|
|
69
|
-
const lines = text.replace(/\r\n/g, "\n").split("\n");
|
|
70
|
-
const total = lines.length;
|
|
71
|
-
if (total <= SMALL_THRESHOLD) {
|
|
72
|
-
return text;
|
|
73
|
-
}
|
|
74
|
-
const isBuild = command ? BUILD_CMD_RE.test(command) : false;
|
|
75
|
-
// R1 success short-circuit — content-driven (not command-gated).
|
|
76
|
-
// SUCCESS_PATTERNS are specific enough ("0 errors, 0 warnings",
|
|
77
|
-
// "Finished release...", "compilation successful") that wrapper scripts
|
|
78
|
-
// benefit too. The ERROR_RE veto inside isCleanSuccess prevents false
|
|
79
|
-
// positives when error/warning markers are also present.
|
|
80
|
-
{
|
|
81
|
-
const probe = isCleanSuccess(text);
|
|
82
|
-
if (probe.ok) {
|
|
83
|
-
const label = isBuild ? "build ok" : "ok";
|
|
84
|
-
return `_shell_fmt:log_text\n${label} — ${probe.line ?? "succeeded"} (${total} lines suppressed)`;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
const patterns = new Map();
|
|
88
|
-
const errorLines = [];
|
|
89
|
-
const keptLines = [];
|
|
90
|
-
for (const line of lines) {
|
|
91
|
-
if (!line.trim())
|
|
92
|
-
continue;
|
|
93
|
-
// Always keep error/warning and stack frame lines verbatim
|
|
94
|
-
if (ERROR_RE.test(line) || FRAME_RE.test(line)) {
|
|
95
|
-
errorLines.push(line);
|
|
96
|
-
continue;
|
|
97
|
-
}
|
|
98
|
-
// For build output, keep result/summary lines
|
|
99
|
-
if (isBuild && BUILD_RESULT_RE.test(line)) {
|
|
100
|
-
keptLines.push(line);
|
|
101
|
-
continue;
|
|
102
|
-
}
|
|
103
|
-
const normalized = normalizeLogLine(line);
|
|
104
|
-
const existing = patterns.get(normalized);
|
|
105
|
-
if (existing) {
|
|
106
|
-
existing.count++;
|
|
107
|
-
}
|
|
108
|
-
else {
|
|
109
|
-
patterns.set(normalized, { firstLine: line, count: 1 });
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
const parts = ["_shell_fmt:log_text"];
|
|
113
|
-
parts.push(`(${total} lines, ${patterns.size} unique patterns)`);
|
|
114
|
-
// Errors first — dedup identical error/warning lines with [×N]
|
|
115
|
-
if (errorLines.length > 0) {
|
|
116
|
-
const errDedup = new Map();
|
|
117
|
-
for (const e of errorLines) {
|
|
118
|
-
const existing = errDedup.get(e);
|
|
119
|
-
if (existing)
|
|
120
|
-
existing.count++;
|
|
121
|
-
else
|
|
122
|
-
errDedup.set(e, { line: e, count: 1 });
|
|
123
|
-
}
|
|
124
|
-
let shown = 0;
|
|
125
|
-
for (const { line, count } of errDedup.values()) {
|
|
126
|
-
if (shown >= MAX_ERROR_LINES)
|
|
127
|
-
break;
|
|
128
|
-
parts.push(count > 1 ? `${line} [×${count}]` : line);
|
|
129
|
-
shown++;
|
|
130
|
-
}
|
|
131
|
-
if (errDedup.size > MAX_ERROR_LINES) {
|
|
132
|
-
parts.push(`… ${errDedup.size - MAX_ERROR_LINES} more error lines`);
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
// Build-specific kept lines
|
|
136
|
-
if (keptLines.length > 0) {
|
|
137
|
-
for (const k of keptLines.slice(0, MAX_KEPT_LINES))
|
|
138
|
-
parts.push(k);
|
|
139
|
-
}
|
|
140
|
-
// Deduped patterns sorted by count desc
|
|
141
|
-
const sorted = [...patterns.values()].sort((a, b) => b.count - a.count);
|
|
142
|
-
for (const p of sorted.slice(0, MAX_PATTERNS)) {
|
|
143
|
-
if (p.count > 1) {
|
|
144
|
-
parts.push(`${p.firstLine} [×${p.count}]`);
|
|
145
|
-
}
|
|
146
|
-
else {
|
|
147
|
-
parts.push(p.firstLine);
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
if (sorted.length > MAX_PATTERNS) {
|
|
151
|
-
parts.push(`… ${sorted.length - MAX_PATTERNS} more unique patterns`);
|
|
152
|
-
}
|
|
153
|
-
return parts.join("\n");
|
|
154
|
-
}
|
|
@@ -1,188 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Omni catch-all compression for unclassified shell output.
|
|
3
|
-
* Five tiers: normalize → pattern-dedup → consecutive-dedup → smart truncate → char cap.
|
|
4
|
-
* Fires only when classifier confidence < 0.7.
|
|
5
|
-
*/
|
|
6
|
-
const SMALL_THRESHOLD = 40;
|
|
7
|
-
const DEDUP_THRESHOLD = 30;
|
|
8
|
-
const DEDUP_MIN_RUN = 3;
|
|
9
|
-
const TRUNCATE_THRESHOLD = 200;
|
|
10
|
-
const HEAD_KEEP = 20;
|
|
11
|
-
const TAIL_KEEP = 40;
|
|
12
|
-
const CHAR_CAP = 50_000;
|
|
13
|
-
const CHAR_HEAD = 30_000;
|
|
14
|
-
const CHAR_TAIL = 15_000;
|
|
15
|
-
const MAX_PATTERNS = 30;
|
|
16
|
-
const DIAGNOSTIC_RE = /\b(ERROR|FATAL|WARN(?:ING)?|FAIL(?:ED)?|Exception|Traceback|panic|SIGKILL|SIGSEGV|OOM|error\[E\d+\]|cannot find|undefined reference|segmentation fault)\b/i;
|
|
17
|
-
/** Normalize a line by replacing variable parts (numbers, hashes, UUIDs, paths) for pattern matching. */
|
|
18
|
-
function normalizeForPattern(line) {
|
|
19
|
-
return line
|
|
20
|
-
.replace(/\b[0-9a-f]{7,40}\b/gi, "<HASH>")
|
|
21
|
-
.replace(/\b[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\b/gi, "<UUID>")
|
|
22
|
-
.replace(/\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b/g, "<IP>")
|
|
23
|
-
.replace(/\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2}[.\d]*Z?/g, "<TS>")
|
|
24
|
-
.replace(/\b\d+(\.\d+)?\s*(ms|s|sec|min|MB|KB|GB|B|bytes)\b/gi, "<N>$2")
|
|
25
|
-
.replace(/\d+/g, "<N>")
|
|
26
|
-
.trim();
|
|
27
|
-
}
|
|
28
|
-
/** Tier 1: Collapse blank runs (3+ → 1) and trim trailing whitespace. */
|
|
29
|
-
function normalize(lines) {
|
|
30
|
-
const out = [];
|
|
31
|
-
let blankRun = 0;
|
|
32
|
-
for (const line of lines) {
|
|
33
|
-
const trimmed = line.trimEnd();
|
|
34
|
-
if (trimmed.length === 0) {
|
|
35
|
-
blankRun++;
|
|
36
|
-
if (blankRun <= 1)
|
|
37
|
-
out.push("");
|
|
38
|
-
continue;
|
|
39
|
-
}
|
|
40
|
-
blankRun = 0;
|
|
41
|
-
out.push(trimmed);
|
|
42
|
-
}
|
|
43
|
-
return out;
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Tier 2: Pattern-based dedup — merge lines that are identical after normalizing
|
|
47
|
-
* variable parts (numbers, hashes, timestamps). Non-consecutive duplicates merge.
|
|
48
|
-
*/
|
|
49
|
-
function patternDedup(lines) {
|
|
50
|
-
if (lines.length < DEDUP_THRESHOLD)
|
|
51
|
-
return lines;
|
|
52
|
-
// Separate diagnostic lines (always keep verbatim)
|
|
53
|
-
const diagnosticLines = [];
|
|
54
|
-
const normalLines = [];
|
|
55
|
-
for (const line of lines) {
|
|
56
|
-
if (DIAGNOSTIC_RE.test(line)) {
|
|
57
|
-
diagnosticLines.push(line);
|
|
58
|
-
}
|
|
59
|
-
else {
|
|
60
|
-
normalLines.push(line);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
// Group normal lines by normalized pattern
|
|
64
|
-
const patterns = new Map();
|
|
65
|
-
const ordered = []; // track insertion order of pattern keys
|
|
66
|
-
for (const line of normalLines) {
|
|
67
|
-
if (!line.trim())
|
|
68
|
-
continue;
|
|
69
|
-
const norm = normalizeForPattern(line);
|
|
70
|
-
const existing = patterns.get(norm);
|
|
71
|
-
if (existing) {
|
|
72
|
-
existing.count++;
|
|
73
|
-
}
|
|
74
|
-
else {
|
|
75
|
-
patterns.set(norm, { firstLine: line, count: 1 });
|
|
76
|
-
ordered.push(norm);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
// If dedup saved less than 20% of lines, not worth it — return as-is
|
|
80
|
-
const dedupedCount = ordered.length + diagnosticLines.length;
|
|
81
|
-
if (dedupedCount > lines.length * 0.8)
|
|
82
|
-
return lines;
|
|
83
|
-
// Rebuild: diagnostics first, then patterns sorted by original order
|
|
84
|
-
const out = [];
|
|
85
|
-
// Dedup diagnostic lines too (identical ones)
|
|
86
|
-
const diagDedup = new Map();
|
|
87
|
-
for (const d of diagnosticLines) {
|
|
88
|
-
const existing = diagDedup.get(d);
|
|
89
|
-
if (existing)
|
|
90
|
-
existing.count++;
|
|
91
|
-
else
|
|
92
|
-
diagDedup.set(d, { line: d, count: 1 });
|
|
93
|
-
}
|
|
94
|
-
for (const { line, count } of diagDedup.values()) {
|
|
95
|
-
out.push(count > 1 ? `${line} [×${count}]` : line);
|
|
96
|
-
}
|
|
97
|
-
let shown = 0;
|
|
98
|
-
for (const key of ordered) {
|
|
99
|
-
if (shown >= MAX_PATTERNS)
|
|
100
|
-
break;
|
|
101
|
-
const p = patterns.get(key);
|
|
102
|
-
if (p.count > 1) {
|
|
103
|
-
out.push(`${p.firstLine} [×${p.count}]`);
|
|
104
|
-
}
|
|
105
|
-
else {
|
|
106
|
-
out.push(p.firstLine);
|
|
107
|
-
}
|
|
108
|
-
shown++;
|
|
109
|
-
}
|
|
110
|
-
if (ordered.length > MAX_PATTERNS) {
|
|
111
|
-
out.push(`… ${ordered.length - MAX_PATTERNS} more unique patterns`);
|
|
112
|
-
}
|
|
113
|
-
return out;
|
|
114
|
-
}
|
|
115
|
-
/** Tier 3: Collapse runs of 3+ identical consecutive lines into `line [×N]`. */
|
|
116
|
-
function consecutiveDedup(lines) {
|
|
117
|
-
if (lines.length < DEDUP_THRESHOLD)
|
|
118
|
-
return lines;
|
|
119
|
-
const out = [];
|
|
120
|
-
let i = 0;
|
|
121
|
-
while (i < lines.length) {
|
|
122
|
-
const line = lines[i];
|
|
123
|
-
let runLen = 1;
|
|
124
|
-
while (i + runLen < lines.length &&
|
|
125
|
-
lines[i + runLen] === line &&
|
|
126
|
-
line.length > 0) {
|
|
127
|
-
runLen++;
|
|
128
|
-
}
|
|
129
|
-
if (runLen >= DEDUP_MIN_RUN) {
|
|
130
|
-
out.push(`${line} [×${runLen}]`);
|
|
131
|
-
}
|
|
132
|
-
else {
|
|
133
|
-
for (let j = 0; j < runLen; j++)
|
|
134
|
-
out.push(line);
|
|
135
|
-
}
|
|
136
|
-
i += runLen;
|
|
137
|
-
}
|
|
138
|
-
return out;
|
|
139
|
-
}
|
|
140
|
-
/** Tier 4: Head + diagnostic-preserving middle + tail truncation. */
|
|
141
|
-
function truncate(lines) {
|
|
142
|
-
if (lines.length <= TRUNCATE_THRESHOLD)
|
|
143
|
-
return lines;
|
|
144
|
-
const head = lines.slice(0, HEAD_KEEP);
|
|
145
|
-
const tail = lines.slice(-TAIL_KEEP);
|
|
146
|
-
const middleStart = HEAD_KEEP;
|
|
147
|
-
const middleEnd = lines.length - TAIL_KEEP;
|
|
148
|
-
const diagnostics = [];
|
|
149
|
-
for (let i = middleStart; i < middleEnd; i++) {
|
|
150
|
-
if (DIAGNOSTIC_RE.test(lines[i]))
|
|
151
|
-
diagnostics.push(lines[i]);
|
|
152
|
-
}
|
|
153
|
-
const omitted = middleEnd - middleStart - diagnostics.length;
|
|
154
|
-
const marker = diagnostics.length > 0
|
|
155
|
-
? `… ${omitted} lines omitted (${diagnostics.length} diagnostic lines preserved) …`
|
|
156
|
-
: `… ${omitted} lines omitted …`;
|
|
157
|
-
return [...head, marker, ...diagnostics, ...tail];
|
|
158
|
-
}
|
|
159
|
-
/** Tier 5: Character-level safety cap for extremely wide output (e.g., minified JS). */
|
|
160
|
-
function capChars(text) {
|
|
161
|
-
if (text.length <= CHAR_CAP)
|
|
162
|
-
return text;
|
|
163
|
-
const omitted = text.length - CHAR_HEAD - CHAR_TAIL;
|
|
164
|
-
return `${text.slice(0, CHAR_HEAD)}\n… ${omitted} chars omitted …\n${text.slice(-CHAR_TAIL)}`;
|
|
165
|
-
}
|
|
166
|
-
/** Universal catch-all compression. Format-agnostic, safe on any text. */
|
|
167
|
-
export function compressOmni(raw) {
|
|
168
|
-
const lines = raw.replace(/\r\n/g, "\n").split("\n");
|
|
169
|
-
const originalCount = lines.length;
|
|
170
|
-
// Small output — pass through. Skip header (no compression happened);
|
|
171
|
-
// capChars's `… N chars omitted …` marker still signals any wide-line cap.
|
|
172
|
-
if (originalCount <= SMALL_THRESHOLD) {
|
|
173
|
-
return capChars(raw);
|
|
174
|
-
}
|
|
175
|
-
const normalized = normalize(lines);
|
|
176
|
-
// Try pattern dedup first (more aggressive, non-consecutive)
|
|
177
|
-
const patternDeduped = patternDedup(normalized);
|
|
178
|
-
// Then consecutive dedup on whatever remains
|
|
179
|
-
const deduped = consecutiveDedup(patternDeduped);
|
|
180
|
-
const truncated = truncate(deduped);
|
|
181
|
-
const joined = truncated.join("\n");
|
|
182
|
-
const capped = capChars(joined);
|
|
183
|
-
const savedLines = originalCount - truncated.length;
|
|
184
|
-
const header = savedLines > 5
|
|
185
|
-
? `_shell_fmt:omni (${originalCount}→${truncated.length} lines)`
|
|
186
|
-
: "_shell_fmt:omni";
|
|
187
|
-
return `${header}\n${capped}`;
|
|
188
|
-
}
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Strategy T9 — npm/pip-style progress: extract summary, drop transient lines.
|
|
3
|
-
*/
|
|
4
|
-
const KEEP_LAST = 18;
|
|
5
|
-
const SUMMARY_PATTERNS = [
|
|
6
|
-
// npm/pnpm/yarn
|
|
7
|
-
/^added \d+ packages?/i,
|
|
8
|
-
/^Packages: \+\d+/,
|
|
9
|
-
/^success Saved lockfile/,
|
|
10
|
-
/^\d+ packages? installed/,
|
|
11
|
-
/^up to date/i,
|
|
12
|
-
/^Done in \d/,
|
|
13
|
-
/^✨\s+Done in/,
|
|
14
|
-
/^Lockfile is up to date/,
|
|
15
|
-
// pip/uv
|
|
16
|
-
/^Successfully installed/i,
|
|
17
|
-
/^Requirement already satisfied/i,
|
|
18
|
-
/^Resolved \d+ packages?/i,
|
|
19
|
-
/^Installed \d+ packages?/i,
|
|
20
|
-
// cargo
|
|
21
|
-
/^\s*Compiling .+ v\d/,
|
|
22
|
-
/^\s*Finished .+ target/,
|
|
23
|
-
/^\s*Downloaded \d+ crates?/,
|
|
24
|
-
// go
|
|
25
|
-
/^go: downloading /,
|
|
26
|
-
/^go: added /,
|
|
27
|
-
// bundle (ruby)
|
|
28
|
-
/^Bundle complete!/,
|
|
29
|
-
/^Using /,
|
|
30
|
-
/^\d+ gems? installed/,
|
|
31
|
-
// composer (php)
|
|
32
|
-
/^Package operations:/,
|
|
33
|
-
/^Generating autoload files/,
|
|
34
|
-
// apt/brew/dnf
|
|
35
|
-
/^\d+ upgraded, \d+ newly installed/,
|
|
36
|
-
/^==> (Downloading|Installing|Pouring)/,
|
|
37
|
-
/^Complete!/,
|
|
38
|
-
/^Transaction Summary/,
|
|
39
|
-
];
|
|
40
|
-
export function compressProgress(text, command) {
|
|
41
|
-
void command;
|
|
42
|
-
const lines = text.replace(/\r\n/g, "\n").split("\n");
|
|
43
|
-
// Look for summary line near the end
|
|
44
|
-
const summary = [...lines]
|
|
45
|
-
.reverse()
|
|
46
|
-
.find((l) => SUMMARY_PATTERNS.some((p) => p.test(l.trim())));
|
|
47
|
-
if (summary) {
|
|
48
|
-
return `_shell_fmt:progress\n${summary.trim()}`;
|
|
49
|
-
}
|
|
50
|
-
if (lines.length <= KEEP_LAST) {
|
|
51
|
-
return text;
|
|
52
|
-
}
|
|
53
|
-
const tail = lines.slice(-KEEP_LAST).join("\n");
|
|
54
|
-
return `_shell_fmt:progress\n… ${lines.length - KEEP_LAST} progress line(s) omitted …\n${tail}`;
|
|
55
|
-
}
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pre-strategy redaction — runs BEFORE classification so every strategy
|
|
3
|
-
* sees normalized input. Strips boilerplate that survives ANSI strip and
|
|
4
|
-
* has no semantic value to a coding agent.
|
|
5
|
-
*
|
|
6
|
-
* Token wins are small per-rule but stack across every shell call:
|
|
7
|
-
* absolute home paths → ~, long hashes → <sha>, ISO timestamps → <ts>,
|
|
8
|
-
* surviving CSI/OSC cursor codes that the basic ANSI strip missed.
|
|
9
|
-
*/
|
|
10
|
-
import { homedir } from "node:os";
|
|
11
|
-
const HOME = (() => {
|
|
12
|
-
try {
|
|
13
|
-
return homedir();
|
|
14
|
-
}
|
|
15
|
-
catch {
|
|
16
|
-
return "";
|
|
17
|
-
}
|
|
18
|
-
})();
|
|
19
|
-
function escapeRegex(s) {
|
|
20
|
-
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Built-in redactors. Order matters — longer/more-specific patterns first.
|
|
24
|
-
*/
|
|
25
|
-
const BUILTIN_RULES = [
|
|
26
|
-
// Home directory → ~ (only the literal home, not arbitrary user paths)
|
|
27
|
-
...(HOME
|
|
28
|
-
? [{ pattern: new RegExp(escapeRegex(HOME), "g"), replacement: "~" }]
|
|
29
|
-
: []),
|
|
30
|
-
// ISO timestamps — keep the date but compress time portion
|
|
31
|
-
// 2026-05-13T14:32:01.123Z → <ts>
|
|
32
|
-
{
|
|
33
|
-
pattern: /\b\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:?\d{2})?\b/g,
|
|
34
|
-
replacement: "<ts>",
|
|
35
|
-
},
|
|
36
|
-
// Long full-line UUIDs
|
|
37
|
-
{
|
|
38
|
-
pattern: /\b[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\b/gi,
|
|
39
|
-
replacement: "<uuid>",
|
|
40
|
-
},
|
|
41
|
-
// 40-char or 64-char hex digests (sha1/sha256) — keep first 7
|
|
42
|
-
{
|
|
43
|
-
pattern: /\b([0-9a-f]{7})[0-9a-f]{33,57}\b/gi,
|
|
44
|
-
replacement: "$1…",
|
|
45
|
-
},
|
|
46
|
-
// Surviving CSI cursor movement / scroll region codes that the basic
|
|
47
|
-
// ANSI stripper missed (rare but real on Windows-style output)
|
|
48
|
-
// biome-ignore lint/suspicious/noControlCharactersInRegex: stripping control codes by design
|
|
49
|
-
{ pattern: /\x1b\][^\x07\x1b]*\x1b?\\?/g, replacement: "" },
|
|
50
|
-
// npm/pip progress carriage returns that don't survive ANSI strip cleanly
|
|
51
|
-
{ pattern: /\r(?!\n)/g, replacement: "\n" },
|
|
52
|
-
];
|
|
53
|
-
/**
|
|
54
|
-
* Apply default + user redactors to raw output. Idempotent. Cheap.
|
|
55
|
-
*/
|
|
56
|
-
export function redactOutput(raw, extra) {
|
|
57
|
-
if (!raw)
|
|
58
|
-
return raw;
|
|
59
|
-
let s = raw;
|
|
60
|
-
for (const r of BUILTIN_RULES) {
|
|
61
|
-
s = s.replace(r.pattern, r.replacement);
|
|
62
|
-
}
|
|
63
|
-
if (extra && extra.length > 0) {
|
|
64
|
-
for (const r of extra) {
|
|
65
|
-
s = s.replace(r.pattern, r.replacement);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
return s;
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Expose builtin rules so the filter-DSL loader (R3) can merge user
|
|
72
|
-
* rules with the same shape.
|
|
73
|
-
*/
|
|
74
|
-
export function getBuiltinRedactRules() {
|
|
75
|
-
return BUILTIN_RULES;
|
|
76
|
-
}
|