@merittdev/horus 0.24.4 → 0.24.6
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 +172 -59
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -1,92 +1,205 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="https://meritt-dev-assets.s3.eu-central-1.amazonaws.com/public/horus-logo-dark-20260614171147.svg" width="72" alt="Horus" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
1
5
|
# Horus
|
|
2
6
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
- logs
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
**Understand what happened.**
|
|
8
|
+
|
|
9
|
+
Open-source incident investigation. Horus connects Elasticsearch, Sentry, Grafana, MongoDB, Postgres, Redis (incl. BullMQ queues), Axiom logs, Shopify Admin, Azure Monitor, CloudWatch Logs, Google Cloud Logging, Prometheus, Azure Service Bus, Kafka, Firestore, SQL Server, and source intelligence into deterministic reports.
|
|
10
|
+
|
|
11
|
+
Horus is a single native CLI binary, and it only reads from production.
|
|
12
|
+
|
|
13
|
+
[horus.sh](https://horus.sh) · [github.com/meritt-dev/horus](https://github.com/meritt-dev/horus)
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
curl -fsSL https://horus.sh/install.sh | bash
|
|
17
|
+
npm install -g @merittdev/horus
|
|
18
|
+
brew install meritt-dev/tap/horus
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## What Horus does
|
|
24
|
+
|
|
25
|
+
Horus reads from the systems you already run and rebuilds the incident from what they recorded.
|
|
26
|
+
|
|
27
|
+
Instead of a page of raw logs, you get a **deterministic report** that links runtime signals to the code behind them. It lists suspected causes (ranked), hypotheses, evidence, gaps, and next actions. Optional `--ai` adds an Anthropic narrative on top, written from that evidence.
|
|
28
|
+
|
|
29
|
+
Horus sits on top of the monitoring and observability tools you already run. They detect problems and show signals. Horus reads from them and works out what happened.
|
|
30
|
+
|
|
31
|
+
## Getting started
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
cd your-service
|
|
35
|
+
horus init # index the repo, start the source host, write .horus/config.json
|
|
36
|
+
horus connect elasticsearch # optional runtime connectors (see `horus connect --help`)
|
|
37
|
+
horus doctor
|
|
38
|
+
horus investigate "checkout latency spike"
|
|
39
|
+
horus investigations # list saved IDs
|
|
40
|
+
horus replay <id>
|
|
41
|
+
horus postmortem <id>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
`horus --help` lists every command.
|
|
45
|
+
|
|
46
|
+
## How it works
|
|
47
|
+
|
|
48
|
+
| Runtime and source | Investigation engine | Report |
|
|
49
|
+
|---|---|---|
|
|
50
|
+
| Elasticsearch · Axiom · cloud logs · Sentry errors | Correlation | Suspected causes (ranked) |
|
|
51
|
+
| Grafana · Prometheus metrics | Timeline | Hypotheses + confidence |
|
|
52
|
+
| MongoDB · Postgres · SQL Server · Firestore · Redis state | Cause ranking | Evidence + gaps |
|
|
53
|
+
| BullMQ · Kafka · Azure Service Bus queues | | Next actions |
|
|
54
|
+
| Source graph + git | | |
|
|
55
|
+
|
|
56
|
+
Pipeline: **Evidence → Correlation → Hypotheses → Timeline → Report**
|
|
57
|
+
|
|
58
|
+
## Example output (illustrative)
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
cd ~/code/atlas-payments
|
|
62
|
+
horus investigate --env production "checkout latency spike"
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
```text
|
|
66
|
+
# Investigation inv-347
|
|
67
|
+
Hint: checkout latency spike
|
|
68
|
+
|
|
69
|
+
## Suspected causes (ranked)
|
|
70
|
+
1. [0.82 / high] Redis connection pool exhaustion [↑ queue]
|
|
71
|
+
|
|
72
|
+
## Hypotheses
|
|
73
|
+
[supported] [0.78] queue: backlog growth preceded latency spike
|
|
74
|
+
|
|
75
|
+
## Evidence gaps
|
|
76
|
+
- queue runtime state: worker heartbeat unavailable
|
|
77
|
+
|
|
78
|
+
## Evidence
|
|
79
|
+
- ev-01 [elasticsearch/error] Request timeout increase
|
|
80
|
+
- ev-04 [bullmq/queue] checkout-jobs backlog growth
|
|
81
|
+
|
|
82
|
+
## Next actions
|
|
83
|
+
- Inspect worker concurrency changes in deploy #784
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Principles
|
|
87
|
+
|
|
88
|
+
Horus only reads. It never writes to your production systems.
|
|
89
|
+
|
|
90
|
+
The engine is deterministic. The same evidence gives the same report, and `--ai` only adds a narrative on top.
|
|
91
|
+
|
|
92
|
+
Connectors read straight from your own clusters. Investigations and incident memory stay in a local SQLite store (`~/.horus/horus-rust.db`) and sync with Horus Cloud when the repo is linked.
|
|
93
|
+
|
|
94
|
+
The repo you run in is the project. Its `.horus/config.json` holds the config, and `--config <path>` points Horus at another repo.
|
|
95
|
+
|
|
96
|
+
Every investigation and analysis command takes `--json` (compact by default, `--full` for the raw structure). Each result carries a `nextSteps` array that an agent can follow.
|
|
97
|
+
|
|
98
|
+
## Core commands
|
|
99
|
+
|
|
100
|
+
| Command | What it does |
|
|
101
|
+
| --- | --- |
|
|
102
|
+
| `horus init [--env <e>]` | Set up the current repo: config, source-intelligence host, index, queue map |
|
|
103
|
+
| `horus connect <type>` | Add or update a runtime connector (`horus connect --help` lists the types), or `ai` for an AI provider |
|
|
104
|
+
| `horus status [--env]` | Per-project/env connector-health matrix |
|
|
105
|
+
| `horus doctor` | Check local readiness: CLI version, git root, `.horus` config, source-intelligence setup |
|
|
106
|
+
| `horus investigate --env <e> "<hint>"` | Full deterministic investigation report |
|
|
107
|
+
| `horus packet <hint\|savedId> [--for claude] [--json]` | Short briefing sized for a coding agent's context window, with confidence stated plainly |
|
|
108
|
+
| `horus logs` · `state` · `metrics` · `queues [--live]` | Single-source evidence: error signatures, application state, metrics, queue topology and live depths |
|
|
109
|
+
| `horus search` · `explain` · `blast-radius` · `architecture` · `what-changed` · `changes` | Source-aware code intelligence |
|
|
110
|
+
| `horus memory <show\|add\|list\|link\|...>` | Inspect and author incident memory |
|
|
111
|
+
| `horus feedback <id> [--resolved] [--note] [--cause]` | Record the outcome of an investigation |
|
|
112
|
+
| `horus hosts [--reap]` · `horus stop [--all]` | List or stop source-intelligence hosts |
|
|
113
|
+
| `horus report` | File a Horus bug or capability gap as a pre-filled GitHub issue (nothing is sent automatically) |
|
|
114
|
+
| `horus update` | Update Horus (through npm or Homebrew when installed that way) |
|
|
115
|
+
|
|
116
|
+
## For coding agents
|
|
117
|
+
|
|
118
|
+
Coding agents can call Horus for evidence before they guess at a cause. Install a skill that tells your agent when to use it, or expose the knowledge index over MCP:
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
horus skill install claude # also: codex · gemini · cursor · generic
|
|
122
|
+
horus mcp # expose the local knowledge index to agents over MCP (stdio)
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Configuration
|
|
126
|
+
|
|
127
|
+
Config keeps code and runtime apart. Code belongs to the project: `repositories[]`, each served by its own source-intelligence host. Runtime belongs to the environment: `environments[].connectors`, scoped per project and environment, with no global connector defaults.
|
|
11
128
|
|
|
12
|
-
|
|
129
|
+
A repo carries `.horus/config.json`, discovered by walking up from the working directory like `.git`. `horus.config.{js,ts}` files are also supported and are loaded through an installed `node`.
|
|
13
130
|
|
|
14
|
-
|
|
131
|
+
Secrets stay out of git. `horus connect` encrypts connector credentials into `.horus/secrets.local.json` (never `config.json`) and adds `.horus/` to `.gitignore`. Environment variables also work at runtime. See [horus.sh/docs/security](https://horus.sh/docs/security).
|
|
15
132
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
133
|
+
## Source intelligence
|
|
134
|
+
|
|
135
|
+
Horus expects source intelligence to be present. The bundled backend (code graph, semantic search, impact analysis, ownership, tree-sitter across TypeScript/JavaScript, Python, Go, Java and Rust) lives in [`packages/source-py`](packages/source-py) and ships as `horus_source.whl` beside the binary. `horus init` installs it with [uv](https://docs.astral.sh/uv/). Horus talks to it over HTTP/MCP only.
|
|
136
|
+
|
|
137
|
+
Horus adds one thing the backend lacks. It stitches queue boundaries, linking a producer's `queue.add(...)` to the consumer's `@Processor` handler.
|
|
138
|
+
|
|
139
|
+
> If the backend is unavailable, Horus still collects runtime evidence, but source context, impact analysis, change analysis and queue stitching are degraded.
|
|
21
140
|
|
|
22
141
|
## Install
|
|
23
142
|
|
|
143
|
+
See [horus.sh/docs/installation](https://horus.sh/docs/installation) for full install, update and uninstall instructions.
|
|
144
|
+
|
|
24
145
|
```sh
|
|
146
|
+
curl -fsSL https://horus.sh/install.sh | bash # binary + backend
|
|
25
147
|
npm i -g @merittdev/horus # npm (macOS / Linux, arm64 / x64)
|
|
26
148
|
brew install meritt-dev/tap/horus # Homebrew
|
|
27
|
-
curl --proto '=https' --tlsv1.2 -LsSf \
|
|
28
|
-
https://github.com/Meritt-dev/horus-rust/releases/latest/download/horus-cli-installer.sh | sh
|
|
29
|
-
horus update --force # after the curl installer: installs the bundled backend
|
|
30
149
|
```
|
|
31
150
|
|
|
32
|
-
The npm and Homebrew packages bundle the matching
|
|
151
|
+
The npm and Homebrew packages bundle the matching backend wheel. If you install the bare binary from [GitHub Releases](https://github.com/meritt-dev/horus/releases), run `horus update --force` once to fetch the wheel.
|
|
152
|
+
|
|
153
|
+
Requirements: macOS or Linux (arm64 / x64), `git`, and Python 3.11+ with uv for the source backend. The binary itself needs no Node.js.
|
|
154
|
+
|
|
155
|
+
If something goes wrong, run `horus doctor`.
|
|
33
156
|
|
|
34
157
|
## Upgrading from the TypeScript horus (≤ 0.23.0)
|
|
35
158
|
|
|
36
|
-
|
|
37
|
-
- **Homebrew:** `brew upgrade horus`. The formula no longer depends on `node`.
|
|
38
|
-
- **Config and secrets** in `~/.horus` and `.horus/config.json` are read as-is.
|
|
39
|
-
- **Local history.** The TS CLI kept investigations and memory in a PGlite store at `~/.horus/horus.db`. This build uses SQLite at `~/.horus/horus-rust.db`. Copy the history over once (needs `node`/`npx`; the TS store is only read):
|
|
159
|
+
From 0.24.0 Horus is this Rust implementation, on every channel. It is a command-for-command port of the TypeScript CLI (now archived at [Meritt-dev/horus-ts](https://github.com/Meritt-dev/horus-ts)): same commands, flags, help text, output and exit codes.
|
|
40
160
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
161
|
+
| Installed with | Upgrade |
|
|
162
|
+
| --- | --- |
|
|
163
|
+
| npm | `npm i -g @merittdev/horus@latest` |
|
|
164
|
+
| Homebrew | `brew upgrade horus` (the formula no longer depends on `node`) |
|
|
165
|
+
| curl | `curl -fsSL https://horus.sh/install.sh \| bash` |
|
|
44
166
|
|
|
45
|
-
|
|
167
|
+
Config and secrets in `~/.horus` and `.horus/config.json` are read as they are.
|
|
46
168
|
|
|
47
|
-
|
|
169
|
+
The TS CLI kept investigations and memory in PGlite at `~/.horus/horus.db`. Copy them into the new SQLite store once (needs `node`/`npx`; the TS store is only read):
|
|
48
170
|
|
|
49
171
|
```sh
|
|
50
|
-
|
|
51
|
-
horus init # index the repo, start the source host, write .horus/config.json
|
|
52
|
-
horus connect elasticsearch … # add runtime connectors (see `horus connect --help`)
|
|
53
|
-
horus doctor
|
|
54
|
-
horus investigate "checkout requests timing out since the last deploy"
|
|
172
|
+
horus db migrate-from-ts
|
|
55
173
|
```
|
|
56
174
|
|
|
57
|
-
`horus
|
|
58
|
-
|
|
59
|
-
## How it compares to the TypeScript CLI
|
|
175
|
+
Until you do, `horus` prints a one-line reminder while the new store is empty. Re-running the migration is safe.
|
|
60
176
|
|
|
61
|
-
We
|
|
62
|
-
- **Startup:** 5 ms vs 158 ms cold start.
|
|
63
|
-
- **Memory:** 10 MB vs 153 MB idle; 140–175 MB vs about 1 GB for a full investigation.
|
|
64
|
-
- **Speed:** 2.5–11.8× faster per project.
|
|
65
|
-
- **Output parity:** 98–100% mean match on the 11 other repos; 66/76 identical cases on the main project (the rest differ only by local history, live data or clock).
|
|
66
|
-
|
|
67
|
-
The intended differences are listed in [DIVERGENCES.md](DIVERGENCES.md). The main ones:
|
|
68
|
-
- **Local database.** History lives in `~/.horus/horus-rust.db` (SQLite), not the TS CLI's PGlite `~/.horus/horus.db`; `horus db migrate-from-ts` copies it over. Horus Cloud memory syncs into both.
|
|
69
|
-
- **JS/TS config files.** `horus.config.{js,ts}` is loaded through an installed `node`. `.horus/config.json` needs nothing extra.
|
|
70
|
-
- **Cloud writes switch.** `HORUS_RUST_CLOUD_WRITE=0` keeps a run local: no Cloud writes and no telemetry.
|
|
177
|
+
We benchmarked both CLIs on 12 real repositories ([docs/BENCHMARK.md](docs/BENCHMARK.md)). The Rust build starts in 5 ms instead of 158 ms, idles at 10 MB instead of 153 MB, and runs 2.5 to 11.8× faster per project. Output matched 98 to 100% on 11 of the repos, and 66 of 76 cases were identical on the main one. The rest differ only by local history, live data or the clock. Intended differences are listed in [DIVERGENCES.md](DIVERGENCES.md).
|
|
71
178
|
|
|
72
179
|
## Build from source
|
|
73
180
|
|
|
74
181
|
```sh
|
|
75
|
-
HORUS_VERSION=0.24.
|
|
182
|
+
HORUS_VERSION=0.24.6 cargo build --release -p horus-cli # → target/release/horus
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Cross-platform builds are covered in [PORTING.md](PORTING.md), and cutting a release in [docs/RELEASE.md](docs/RELEASE.md). To build the backend wheel, run `scripts/release/build-source-wheel.sh` (needs uv, Python 3.11+ and Node.js).
|
|
186
|
+
|
|
187
|
+
```
|
|
188
|
+
crates/
|
|
189
|
+
core/ evidence model, config schema, project/env resolution, version pins
|
|
190
|
+
connectors/ provider contracts, source intelligence client, runtime connectors
|
|
191
|
+
stitcher/ queue-boundary stitcher
|
|
192
|
+
db/ local SQLite store
|
|
193
|
+
engine/ deterministic investigation pipeline (timeline, correlation, hypotheses, gaps)
|
|
194
|
+
ai/ optional narrative layer
|
|
195
|
+
knowledge/ local project-knowledge index
|
|
196
|
+
eval/ read-only accuracy harness
|
|
197
|
+
cli/ the horus binary
|
|
198
|
+
packages/
|
|
199
|
+
source-py/ source-intelligence backend (Python), built into horus_source.whl
|
|
76
200
|
```
|
|
77
201
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
The workspace mirrors the TS monorepo crate-for-package:
|
|
81
|
-
- `core`
|
|
82
|
-
- `connectors`
|
|
83
|
-
- `db`
|
|
84
|
-
- `stitcher`
|
|
85
|
-
- `engine`
|
|
86
|
-
- `ai`
|
|
87
|
-
- `knowledge`
|
|
88
|
-
- `eval`
|
|
89
|
-
- `cli`
|
|
202
|
+
IncidentBench, the open benchmark for startup recall, is described in [docs/incident-bench.md](docs/incident-bench.md).
|
|
90
203
|
|
|
91
204
|
## License
|
|
92
205
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@merittdev/horus",
|
|
3
|
-
"version": "0.24.
|
|
3
|
+
"version": "0.24.6",
|
|
4
4
|
"description": "Local-first, source-aware production-incident investigation engine",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
@@ -13,10 +13,10 @@
|
|
|
13
13
|
"homepage": "https://horus.sh",
|
|
14
14
|
"repository": {
|
|
15
15
|
"type": "git",
|
|
16
|
-
"url": "https://github.com/Meritt-dev/horus
|
|
16
|
+
"url": "https://github.com/Meritt-dev/horus"
|
|
17
17
|
},
|
|
18
18
|
"bugs": {
|
|
19
|
-
"url": "https://github.com/Meritt-dev/horus
|
|
19
|
+
"url": "https://github.com/Meritt-dev/horus/issues"
|
|
20
20
|
},
|
|
21
21
|
"bin": {
|
|
22
22
|
"horus": "bin/horus.js"
|
|
@@ -28,10 +28,10 @@
|
|
|
28
28
|
"node": ">=18"
|
|
29
29
|
},
|
|
30
30
|
"optionalDependencies": {
|
|
31
|
-
"@merittdev/horus-darwin-arm64": "0.24.
|
|
32
|
-
"@merittdev/horus-darwin-x64": "0.24.
|
|
33
|
-
"@merittdev/horus-linux-arm64": "0.24.
|
|
34
|
-
"@merittdev/horus-linux-x64": "0.24.
|
|
31
|
+
"@merittdev/horus-darwin-arm64": "0.24.6",
|
|
32
|
+
"@merittdev/horus-darwin-x64": "0.24.6",
|
|
33
|
+
"@merittdev/horus-linux-arm64": "0.24.6",
|
|
34
|
+
"@merittdev/horus-linux-x64": "0.24.6"
|
|
35
35
|
},
|
|
36
36
|
"publishConfig": {
|
|
37
37
|
"access": "public"
|