hyperspell-brain 0.4.0__tar.gz

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.
Files changed (37) hide show
  1. hyperspell_brain-0.4.0/.gitignore +6 -0
  2. hyperspell_brain-0.4.0/LICENSE +21 -0
  3. hyperspell_brain-0.4.0/PKG-INFO +217 -0
  4. hyperspell_brain-0.4.0/README.md +202 -0
  5. hyperspell_brain-0.4.0/pyproject.toml +43 -0
  6. hyperspell_brain-0.4.0/src/hyperbrain/__init__.py +3 -0
  7. hyperspell_brain-0.4.0/src/hyperbrain/cli.py +141 -0
  8. hyperspell_brain-0.4.0/src/hyperbrain/client.py +93 -0
  9. hyperspell_brain-0.4.0/src/hyperbrain/commands/__init__.py +0 -0
  10. hyperspell_brain-0.4.0/src/hyperbrain/commands/_query.py +55 -0
  11. hyperspell_brain-0.4.0/src/hyperbrain/commands/api.py +89 -0
  12. hyperspell_brain-0.4.0/src/hyperbrain/commands/ask.py +79 -0
  13. hyperspell_brain-0.4.0/src/hyperbrain/commands/auth.py +43 -0
  14. hyperspell_brain-0.4.0/src/hyperbrain/commands/brain.py +147 -0
  15. hyperspell_brain-0.4.0/src/hyperbrain/commands/completion.py +70 -0
  16. hyperspell_brain-0.4.0/src/hyperbrain/commands/config.py +116 -0
  17. hyperspell_brain-0.4.0/src/hyperbrain/commands/connections.py +39 -0
  18. hyperspell_brain-0.4.0/src/hyperbrain/commands/doctor.py +67 -0
  19. hyperspell_brain-0.4.0/src/hyperbrain/commands/guide.py +132 -0
  20. hyperspell_brain-0.4.0/src/hyperbrain/commands/integrations.py +25 -0
  21. hyperspell_brain-0.4.0/src/hyperbrain/commands/login.py +145 -0
  22. hyperspell_brain-0.4.0/src/hyperbrain/commands/memories.py +233 -0
  23. hyperspell_brain-0.4.0/src/hyperbrain/commands/remember.py +91 -0
  24. hyperspell_brain-0.4.0/src/hyperbrain/commands/search.py +48 -0
  25. hyperspell_brain-0.4.0/src/hyperbrain/commands/structure.py +141 -0
  26. hyperspell_brain-0.4.0/src/hyperbrain/commands/update.py +184 -0
  27. hyperspell_brain-0.4.0/src/hyperbrain/config.py +139 -0
  28. hyperspell_brain-0.4.0/src/hyperbrain/context.py +23 -0
  29. hyperspell_brain-0.4.0/src/hyperbrain/mcp.py +361 -0
  30. hyperspell_brain-0.4.0/src/hyperbrain/output.py +174 -0
  31. hyperspell_brain-0.4.0/tests/test_completion.py +55 -0
  32. hyperspell_brain-0.4.0/tests/test_doctor.py +51 -0
  33. hyperspell_brain-0.4.0/tests/test_guide.py +70 -0
  34. hyperspell_brain-0.4.0/tests/test_mcp.py +329 -0
  35. hyperspell_brain-0.4.0/tests/test_output.py +125 -0
  36. hyperspell_brain-0.4.0/tests/test_update.py +169 -0
  37. hyperspell_brain-0.4.0/uv.lock +1137 -0
@@ -0,0 +1,6 @@
1
+ .venv/
2
+ dist/
3
+ build/
4
+ *.egg-info/
5
+ __pycache__/
6
+ *.pyc
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Hyperspell
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,217 @@
1
+ Metadata-Version: 2.4
2
+ Name: hyperspell-brain
3
+ Version: 0.4.0
4
+ Summary: hyperbrain — an agent-first CLI for the Hyperspell company brain
5
+ Author-email: Hyperspell <hello@hyperspell.com>
6
+ License-Expression: MIT
7
+ License-File: LICENSE
8
+ Requires-Python: >=3.10
9
+ Requires-Dist: httpx<1,>=0.27
10
+ Requires-Dist: hyperspell<1,>=0.36
11
+ Requires-Dist: typer<1,>=0.12
12
+ Provides-Extra: mcp
13
+ Requires-Dist: mcp<2,>=1.28; extra == 'mcp'
14
+ Description-Content-Type: text/markdown
15
+
16
+ # hyperbrain — agent-first CLI for the Hyperspell company brain
17
+
18
+ Hyperspell is the brain for your business — the memory layer that unifies
19
+ everything your company knows. `hyperbrain` is the command line into it: one verb
20
+ that humans *and* agents use to query, write, and synthesize that memory.
21
+ Structured JSON by default, pipe-friendly, no interactive prompts required.
22
+
23
+ ```bash
24
+ hyperbrain ask "what's our deployment strategy?" # synthesized answer + sources
25
+ hyperbrain search "rds proxy" --source slack -n 5 # ranked documents, no synthesis
26
+ echo "remember this" | hyperbrain remember # write knowledge in
27
+ hyperbrain brain generate # (re)build the company-brain tree
28
+ hyperbrain memories status # indexing progress per source
29
+ hyperbrain schema # dump the command tree as JSON
30
+ ```
31
+
32
+ ## Why this exists
33
+
34
+ If agents are the primary consumer, why a CLI and not just the API? Because the
35
+ CLI is the **universal adapter**. Any agent that can spawn a shell — Claude Code,
36
+ Cursor, a cron job, an autonomous worker you haven't built yet — can use `hyperbrain`
37
+ with zero bespoke integration. No protocol to implement, no server to run, no SDK
38
+ to vendor. Where MCP says "speak this protocol," `hyperbrain` says "here's a verb."
39
+
40
+ It's best understood as one half of a pair:
41
+
42
+ - **Passive context** — the sync daemon writes the synthesized company brain into
43
+ `~/.hyperspell/` and injects it into every agent's `CLAUDE.md` / `AGENTS.md` /
44
+ `.cursorrules`. Agents *start* with company context without asking.
45
+ - **Active query** — when the synced summary isn't enough, the agent calls `hyperbrain`
46
+ to go deeper on demand.
47
+
48
+ Neither alone is the point: the summary is cheap but shallow, `hyperbrain ask` is deep
49
+ but costs a round-trip. Together, an agent has a free baseline and an escape hatch.
50
+
51
+ And note the framing: this is a **brain / memory layer**, not retrieval-as-a-service.
52
+ Anyone can do vector search. The value — and the hard part — is keeping a *living,
53
+ curated, coherent* company memory that's current. `hyperbrain brain generate` (synthesis) and
54
+ `hyperbrain remember` (write-back) point at that; raw `search` is just the primitive
55
+ underneath.
56
+
57
+ ## How it's used best
58
+
59
+ **The highest-leverage move is to register `hyperbrain` as a tool your agents can call**,
60
+ and let them decide when to consult company memory. `hyperbrain schema` exists precisely
61
+ so an agent can introspect every capability as JSON.
62
+
63
+ Pick the right verb and effort for the job:
64
+
65
+ | Want | Command | Why |
66
+ |---|---|---|
67
+ | A grounded answer | `hyperbrain ask "…"` | synthesizes + cites; defaults to **all connected sources** |
68
+ | Raw material for another tool | `hyperbrain search "…"` | ranked docs, no LLM — the composable primitive |
69
+ | Speed | `-e minimal` / `low` | verbatim retrieval, or a single LLM query-rewrite |
70
+ | Genuinely multi-hop questions | `-e medium` / `high` | agentic refinement loop (up to 3 / 6 rounds) |
71
+
72
+ Lean into composability — this is where it beats a UI:
73
+
74
+ ```bash
75
+ hyperbrain ask "what's our deploy process?" -o json | jq -r .answer # clean text for a prompt
76
+ hyperbrain search "rds proxy" --source slack -n 20 | jq '.documents[].title'
77
+ hyperbrain schema | jq # discover every capability
78
+ ```
79
+
80
+ **Close the loop.** A brain only gets smarter if knowledge flows back in. Treat
81
+ `remember` as a habit — decisions, postmortems, the "why" behind a choice — so future
82
+ queries (by humans *or* agents) surface it:
83
+
84
+ ```bash
85
+ echo "Decision: standardizing on X because Y" | hyperbrain remember --title "arch decision"
86
+ ```
87
+
88
+ Rule of thumb: scope tight (`--source`, low effort) for speed and precision; go broad
89
+ and high-effort only for hard, cross-source questions. The UI *shows* you the brain —
90
+ the CLI lets your agents **think with it**.
91
+
92
+ ## Auth
93
+
94
+ Reuses the sync daemon's `~/.hyperspell/config.toml` — if you've run
95
+ `hyperspell login` or `hyperspell install`, `hyperbrain` just works. Otherwise pass
96
+ `--api-key` or set `HYPERSPELL_API_KEY` (a long-lived API key or a device JWT).
97
+
98
+ Precedence: flags > environment > `~/.hyperspell/config.toml` > defaults.
99
+
100
+ ## Agent-first contract
101
+
102
+ - **JSON by default** to stdout when not a TTY (piped/captured); a human table
103
+ on a terminal. Force either with `-o json` / `-o table`.
104
+ - **Diagnostics to stderr**, so stdout is a clean data channel.
105
+ - **Stable exit codes**: `0` ok, `2` usage, `3` auth, `4` not found, `5` API error.
106
+ - **No prompts** — every input is a flag, argument, or stdin.
107
+
108
+ ## Install
109
+
110
+ ```bash
111
+ uv tool install . # from a clone; or: uvx --from . hyperbrain ...
112
+ # once published: uv tool install hyperspell-brain / pipx install hyperspell-brain
113
+ ```
114
+
115
+ The published distribution is `hyperspell-brain` (the bare `hyperbrain` name is
116
+ taken on PyPI by an unrelated project); the installed command is still
117
+ `hyperbrain`.
118
+
119
+ Once installed, upgrade in place with `hyperbrain update` (a thin wrapper over
120
+ `uv tool upgrade`; `--check` reports whether a newer version exists without
121
+ installing, `--reinstall` forces fresh code from a path install). `update`
122
+ requires a `uv tool` install — if you installed via pipx, upgrade with
123
+ `pipx upgrade hyperspell-brain` instead (the command says so rather than
124
+ silently no-op'ing).
125
+
126
+ Shell completion is a generator, not an installer — print the script and put it
127
+ where you want:
128
+
129
+ ```bash
130
+ eval "$(hyperbrain completion zsh)" # this session
131
+ hyperbrain completion zsh >> ~/.zshrc # persist (bash/zsh/fish supported)
132
+ ```
133
+
134
+ `hyperbrain doctor` prints resolved endpoint, auth state, version, and config
135
+ path with no network call — the first thing to run when something's off.
136
+
137
+ ## For agents
138
+
139
+ - **`hyperbrain help --agent`** — the whole CLI surface as one compact, low-token
140
+ markdown doc (commands + auth tiers + contract + recipes), generated from the
141
+ live command tree. Read it once to self-orient. Scope it with
142
+ `hyperbrain help --agent <command>`.
143
+ - **`--fields a,b,c`** (global) projects every result to those top-level keys;
144
+ **`-q/--quiet`** (global) suppresses stdout so you can branch on the exit code
145
+ alone. Both cut token usage.
146
+ - **`hyperbrain schema`** dumps the full command tree as JSON for programmatic
147
+ introspection.
148
+
149
+ ## MCP server (Claude Desktop)
150
+
151
+ Hosts that can't run a CLI or read `CLAUDE.md` — Claude Desktop chief among them —
152
+ reach the brain over MCP instead. The server is an opt-in extra (it pulls
153
+ starlette/uvicorn) and runs over stdio. Its tools come in two tiers, mirroring how
154
+ the product works:
155
+
156
+ - **Local (fast, no API):** `list_context`, `read_context`, `grep_context` read the
157
+ synced `~/.hyperspell` summary off disk (also exposed as `hyperbrain://context/...`
158
+ resources). Read these first.
159
+ - **Source (the full index):** `ask`, `search`, `remember`, `list_memories`,
160
+ `list_connections` go to the Hyperspell index for source-level detail.
161
+
162
+ `brain_status` reports what local context exists and the read-local-first workflow.
163
+
164
+ Crucially, it teaches the host **how** to use the brain. Coding agents learn the
165
+ workflow from the daemon-written `CLAUDE.md` ("read the synced summary first, then
166
+ query"); Claude Desktop never sees that file. So the server detects whether the
167
+ sync daemon's local summary is present and bakes the same ordered methodology into
168
+ its MCP `instructions`, pointing at the actual synced index/sections. A
169
+ `brain_status` tool reports the live state (and the how-to) so a long session can
170
+ re-check after the daemon syncs.
171
+
172
+ `~/Library/Application Support/Claude/claude_desktop_config.json`:
173
+
174
+ ```json
175
+ {
176
+ "mcpServers": {
177
+ "hyperbrain": {
178
+ "command": "uvx",
179
+ "args": ["--from", "hyperspell-brain[mcp]", "hyperbrain-mcp"],
180
+ "env": { "HYPERSPELL_API_KEY": "hs2-..." }
181
+ }
182
+ }
183
+ }
184
+ ```
185
+
186
+ The API key is read from the config `env` (Desktop users never run
187
+ `hyperspell login`). For local dev, point `--from` at the repo path instead of
188
+ the published dist.
189
+
190
+ ## Capability tiers
191
+
192
+ - **Works with a user API key:** `ask`, `search`, `remember`, `memories`,
193
+ `connections`, `integrations`, `brain generate`/`latest`/`get`/`progress`.
194
+ - **Needs an admin JWT (not yet wired):** people, skills, config, canonical docs,
195
+ conflicts, api-keys.
196
+ - **Web-only, no public API (out of scope):** app creation, billing, app settings.
197
+
198
+ ## Design notes & honest limitations
199
+
200
+ A few things to know — and a few things worth fixing:
201
+
202
+ - **`ask` needs at least one matching document.** With zero results, the answer
203
+ path currently returns a server-side 500 instead of a clean empty answer. In an
204
+ agent loop this reads as a hard error when it really means "no memories matched."
205
+ - **Deep effort is gated.** `medium` / `high` run an agentic loop behind a per-app
206
+ feature flag. If the flag is off, they *silently* downgrade to a single
207
+ query-rewrite — so `-e high` isn't always doing what it says. Silent downgrade is
208
+ a trust wart for an agent reasoning about cost vs. quality; it should be loud.
209
+ - **Curation is the real product.** Once agents `remember` autonomously, brain
210
+ quality becomes a governance problem — indiscriminate ingestion makes a junk
211
+ drawer, not a brain. The interesting question isn't "can agents write to it" but
212
+ "what's *true* when sources disagree." That's the canonical-docs / conflicts
213
+ machinery, and it's where the moat actually is.
214
+ - **`hyperbrain` and the daemon will likely converge.** They share `~/.hyperspell` and
215
+ half a worldview (both even have `search`). Today they're two tools — passive sync
216
+ (`hyperspell`) and active query (`hyperbrain`) — but one binary doing both is the
217
+ probable end state.
@@ -0,0 +1,202 @@
1
+ # hyperbrain — agent-first CLI for the Hyperspell company brain
2
+
3
+ Hyperspell is the brain for your business — the memory layer that unifies
4
+ everything your company knows. `hyperbrain` is the command line into it: one verb
5
+ that humans *and* agents use to query, write, and synthesize that memory.
6
+ Structured JSON by default, pipe-friendly, no interactive prompts required.
7
+
8
+ ```bash
9
+ hyperbrain ask "what's our deployment strategy?" # synthesized answer + sources
10
+ hyperbrain search "rds proxy" --source slack -n 5 # ranked documents, no synthesis
11
+ echo "remember this" | hyperbrain remember # write knowledge in
12
+ hyperbrain brain generate # (re)build the company-brain tree
13
+ hyperbrain memories status # indexing progress per source
14
+ hyperbrain schema # dump the command tree as JSON
15
+ ```
16
+
17
+ ## Why this exists
18
+
19
+ If agents are the primary consumer, why a CLI and not just the API? Because the
20
+ CLI is the **universal adapter**. Any agent that can spawn a shell — Claude Code,
21
+ Cursor, a cron job, an autonomous worker you haven't built yet — can use `hyperbrain`
22
+ with zero bespoke integration. No protocol to implement, no server to run, no SDK
23
+ to vendor. Where MCP says "speak this protocol," `hyperbrain` says "here's a verb."
24
+
25
+ It's best understood as one half of a pair:
26
+
27
+ - **Passive context** — the sync daemon writes the synthesized company brain into
28
+ `~/.hyperspell/` and injects it into every agent's `CLAUDE.md` / `AGENTS.md` /
29
+ `.cursorrules`. Agents *start* with company context without asking.
30
+ - **Active query** — when the synced summary isn't enough, the agent calls `hyperbrain`
31
+ to go deeper on demand.
32
+
33
+ Neither alone is the point: the summary is cheap but shallow, `hyperbrain ask` is deep
34
+ but costs a round-trip. Together, an agent has a free baseline and an escape hatch.
35
+
36
+ And note the framing: this is a **brain / memory layer**, not retrieval-as-a-service.
37
+ Anyone can do vector search. The value — and the hard part — is keeping a *living,
38
+ curated, coherent* company memory that's current. `hyperbrain brain generate` (synthesis) and
39
+ `hyperbrain remember` (write-back) point at that; raw `search` is just the primitive
40
+ underneath.
41
+
42
+ ## How it's used best
43
+
44
+ **The highest-leverage move is to register `hyperbrain` as a tool your agents can call**,
45
+ and let them decide when to consult company memory. `hyperbrain schema` exists precisely
46
+ so an agent can introspect every capability as JSON.
47
+
48
+ Pick the right verb and effort for the job:
49
+
50
+ | Want | Command | Why |
51
+ |---|---|---|
52
+ | A grounded answer | `hyperbrain ask "…"` | synthesizes + cites; defaults to **all connected sources** |
53
+ | Raw material for another tool | `hyperbrain search "…"` | ranked docs, no LLM — the composable primitive |
54
+ | Speed | `-e minimal` / `low` | verbatim retrieval, or a single LLM query-rewrite |
55
+ | Genuinely multi-hop questions | `-e medium` / `high` | agentic refinement loop (up to 3 / 6 rounds) |
56
+
57
+ Lean into composability — this is where it beats a UI:
58
+
59
+ ```bash
60
+ hyperbrain ask "what's our deploy process?" -o json | jq -r .answer # clean text for a prompt
61
+ hyperbrain search "rds proxy" --source slack -n 20 | jq '.documents[].title'
62
+ hyperbrain schema | jq # discover every capability
63
+ ```
64
+
65
+ **Close the loop.** A brain only gets smarter if knowledge flows back in. Treat
66
+ `remember` as a habit — decisions, postmortems, the "why" behind a choice — so future
67
+ queries (by humans *or* agents) surface it:
68
+
69
+ ```bash
70
+ echo "Decision: standardizing on X because Y" | hyperbrain remember --title "arch decision"
71
+ ```
72
+
73
+ Rule of thumb: scope tight (`--source`, low effort) for speed and precision; go broad
74
+ and high-effort only for hard, cross-source questions. The UI *shows* you the brain —
75
+ the CLI lets your agents **think with it**.
76
+
77
+ ## Auth
78
+
79
+ Reuses the sync daemon's `~/.hyperspell/config.toml` — if you've run
80
+ `hyperspell login` or `hyperspell install`, `hyperbrain` just works. Otherwise pass
81
+ `--api-key` or set `HYPERSPELL_API_KEY` (a long-lived API key or a device JWT).
82
+
83
+ Precedence: flags > environment > `~/.hyperspell/config.toml` > defaults.
84
+
85
+ ## Agent-first contract
86
+
87
+ - **JSON by default** to stdout when not a TTY (piped/captured); a human table
88
+ on a terminal. Force either with `-o json` / `-o table`.
89
+ - **Diagnostics to stderr**, so stdout is a clean data channel.
90
+ - **Stable exit codes**: `0` ok, `2` usage, `3` auth, `4` not found, `5` API error.
91
+ - **No prompts** — every input is a flag, argument, or stdin.
92
+
93
+ ## Install
94
+
95
+ ```bash
96
+ uv tool install . # from a clone; or: uvx --from . hyperbrain ...
97
+ # once published: uv tool install hyperspell-brain / pipx install hyperspell-brain
98
+ ```
99
+
100
+ The published distribution is `hyperspell-brain` (the bare `hyperbrain` name is
101
+ taken on PyPI by an unrelated project); the installed command is still
102
+ `hyperbrain`.
103
+
104
+ Once installed, upgrade in place with `hyperbrain update` (a thin wrapper over
105
+ `uv tool upgrade`; `--check` reports whether a newer version exists without
106
+ installing, `--reinstall` forces fresh code from a path install). `update`
107
+ requires a `uv tool` install — if you installed via pipx, upgrade with
108
+ `pipx upgrade hyperspell-brain` instead (the command says so rather than
109
+ silently no-op'ing).
110
+
111
+ Shell completion is a generator, not an installer — print the script and put it
112
+ where you want:
113
+
114
+ ```bash
115
+ eval "$(hyperbrain completion zsh)" # this session
116
+ hyperbrain completion zsh >> ~/.zshrc # persist (bash/zsh/fish supported)
117
+ ```
118
+
119
+ `hyperbrain doctor` prints resolved endpoint, auth state, version, and config
120
+ path with no network call — the first thing to run when something's off.
121
+
122
+ ## For agents
123
+
124
+ - **`hyperbrain help --agent`** — the whole CLI surface as one compact, low-token
125
+ markdown doc (commands + auth tiers + contract + recipes), generated from the
126
+ live command tree. Read it once to self-orient. Scope it with
127
+ `hyperbrain help --agent <command>`.
128
+ - **`--fields a,b,c`** (global) projects every result to those top-level keys;
129
+ **`-q/--quiet`** (global) suppresses stdout so you can branch on the exit code
130
+ alone. Both cut token usage.
131
+ - **`hyperbrain schema`** dumps the full command tree as JSON for programmatic
132
+ introspection.
133
+
134
+ ## MCP server (Claude Desktop)
135
+
136
+ Hosts that can't run a CLI or read `CLAUDE.md` — Claude Desktop chief among them —
137
+ reach the brain over MCP instead. The server is an opt-in extra (it pulls
138
+ starlette/uvicorn) and runs over stdio. Its tools come in two tiers, mirroring how
139
+ the product works:
140
+
141
+ - **Local (fast, no API):** `list_context`, `read_context`, `grep_context` read the
142
+ synced `~/.hyperspell` summary off disk (also exposed as `hyperbrain://context/...`
143
+ resources). Read these first.
144
+ - **Source (the full index):** `ask`, `search`, `remember`, `list_memories`,
145
+ `list_connections` go to the Hyperspell index for source-level detail.
146
+
147
+ `brain_status` reports what local context exists and the read-local-first workflow.
148
+
149
+ Crucially, it teaches the host **how** to use the brain. Coding agents learn the
150
+ workflow from the daemon-written `CLAUDE.md` ("read the synced summary first, then
151
+ query"); Claude Desktop never sees that file. So the server detects whether the
152
+ sync daemon's local summary is present and bakes the same ordered methodology into
153
+ its MCP `instructions`, pointing at the actual synced index/sections. A
154
+ `brain_status` tool reports the live state (and the how-to) so a long session can
155
+ re-check after the daemon syncs.
156
+
157
+ `~/Library/Application Support/Claude/claude_desktop_config.json`:
158
+
159
+ ```json
160
+ {
161
+ "mcpServers": {
162
+ "hyperbrain": {
163
+ "command": "uvx",
164
+ "args": ["--from", "hyperspell-brain[mcp]", "hyperbrain-mcp"],
165
+ "env": { "HYPERSPELL_API_KEY": "hs2-..." }
166
+ }
167
+ }
168
+ }
169
+ ```
170
+
171
+ The API key is read from the config `env` (Desktop users never run
172
+ `hyperspell login`). For local dev, point `--from` at the repo path instead of
173
+ the published dist.
174
+
175
+ ## Capability tiers
176
+
177
+ - **Works with a user API key:** `ask`, `search`, `remember`, `memories`,
178
+ `connections`, `integrations`, `brain generate`/`latest`/`get`/`progress`.
179
+ - **Needs an admin JWT (not yet wired):** people, skills, config, canonical docs,
180
+ conflicts, api-keys.
181
+ - **Web-only, no public API (out of scope):** app creation, billing, app settings.
182
+
183
+ ## Design notes & honest limitations
184
+
185
+ A few things to know — and a few things worth fixing:
186
+
187
+ - **`ask` needs at least one matching document.** With zero results, the answer
188
+ path currently returns a server-side 500 instead of a clean empty answer. In an
189
+ agent loop this reads as a hard error when it really means "no memories matched."
190
+ - **Deep effort is gated.** `medium` / `high` run an agentic loop behind a per-app
191
+ feature flag. If the flag is off, they *silently* downgrade to a single
192
+ query-rewrite — so `-e high` isn't always doing what it says. Silent downgrade is
193
+ a trust wart for an agent reasoning about cost vs. quality; it should be loud.
194
+ - **Curation is the real product.** Once agents `remember` autonomously, brain
195
+ quality becomes a governance problem — indiscriminate ingestion makes a junk
196
+ drawer, not a brain. The interesting question isn't "can agents write to it" but
197
+ "what's *true* when sources disagree." That's the canonical-docs / conflicts
198
+ machinery, and it's where the moat actually is.
199
+ - **`hyperbrain` and the daemon will likely converge.** They share `~/.hyperspell` and
200
+ half a worldview (both even have `search`). Today they're two tools — passive sync
201
+ (`hyperspell`) and active query (`hyperbrain`) — but one binary doing both is the
202
+ probable end state.
@@ -0,0 +1,43 @@
1
+ [project]
2
+ # Distribution name is `hyperspell-brain`, not `hyperbrain`: the bare
3
+ # `hyperbrain` name is taken on PyPI by an unrelated 2020 project. The console
4
+ # script stays `hyperbrain` (see [project.scripts]) and the import package stays
5
+ # `hyperbrain` (see tool.hatch.build) — only the published dist name changes.
6
+ name = "hyperspell-brain"
7
+ version = "0.4.0"
8
+ description = "hyperbrain — an agent-first CLI for the Hyperspell company brain"
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = "MIT"
12
+ authors = [{ name = "Hyperspell", email = "hello@hyperspell.com" }]
13
+ dependencies = [
14
+ "hyperspell>=0.36,<1",
15
+ "typer>=0.12,<1",
16
+ "httpx>=0.27,<1",
17
+ ]
18
+
19
+ # The MCP server (for Claude Desktop and other MCP hosts) is opt-in: it pulls
20
+ # starlette/uvicorn/etc., which the common CLI install doesn't need. Install
21
+ # `hyperspell-brain[mcp]` to get the `hyperbrain-mcp` entry point.
22
+ [project.optional-dependencies]
23
+ mcp = ["mcp>=1.28,<2"]
24
+
25
+ [dependency-groups]
26
+ dev = [
27
+ "pytest>=8,<9",
28
+ "mcp>=1.28,<2", # the MCP tests import hyperbrain.mcp, which needs the extra
29
+ ]
30
+
31
+ [project.scripts]
32
+ hyperbrain = "hyperbrain.cli:app"
33
+ hyperbrain-mcp = "hyperbrain.mcp:main"
34
+
35
+ [build-system]
36
+ requires = ["hatchling"]
37
+ build-backend = "hatchling.build"
38
+
39
+ [tool.hatch.build.targets.wheel]
40
+ packages = ["src/hyperbrain"]
41
+
42
+ [tool.ruff]
43
+ line-length = 100
@@ -0,0 +1,3 @@
1
+ """hyperbrain — an agent-first CLI for the Hyperspell company brain."""
2
+
3
+ __version__ = "0.4.0"
@@ -0,0 +1,141 @@
1
+ """hyperbrain — agent-first CLI for the Hyperspell company brain.
2
+
3
+ Root command: wires global options into a per-invocation AppCtx, then dispatches
4
+ to the command modules. Designed so an agent can call any subcommand
5
+ non-interactively and parse JSON from stdout.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from typing import Any, Optional
11
+
12
+ import typer
13
+
14
+ from . import __version__, config
15
+ from .context import AppCtx
16
+ from .output import FORMAT_OPTION, Format, emit, pick, set_output_options
17
+ from .commands import api as api_cmd
18
+ from .commands import ask as ask_cmd
19
+ from .commands import auth as auth_cmd
20
+ from .commands import brain as brain_cmd
21
+ from .commands import completion as completion_cmd
22
+ from .commands import config as config_cmd
23
+ from .commands import connections as connections_cmd
24
+ from .commands import doctor as doctor_cmd
25
+ from .commands import guide as guide_cmd
26
+ from .commands import integrations as integrations_cmd
27
+ from .commands import login as login_cmd
28
+ from .commands import memories as memories_cmd
29
+ from .commands import remember as remember_cmd
30
+ from .commands import search as search_cmd
31
+ from .commands import structure as structure_cmd
32
+ from .commands import update as update_cmd
33
+
34
+ app = typer.Typer(
35
+ name="hyperbrain",
36
+ help="Agent-first CLI for the Hyperspell company brain. JSON by default; pipe-friendly.",
37
+ no_args_is_help=True,
38
+ add_completion=False,
39
+ context_settings={"help_option_names": ["-h", "--help"]},
40
+ )
41
+
42
+
43
+ def _version(value: bool) -> None:
44
+ if value:
45
+ typer.echo(__version__)
46
+ raise typer.Exit()
47
+
48
+
49
+ @app.callback()
50
+ def main(
51
+ ctx: typer.Context,
52
+ api_key: Optional[str] = typer.Option(
53
+ None, "--api-key", envvar="HYPERSPELL_API_KEY", help="API key (or device JWT)."
54
+ ),
55
+ api_url: Optional[str] = typer.Option(
56
+ None, "--api-url", envvar="HYPERSPELL_BASE_URL", help="API base URL."
57
+ ),
58
+ as_user: Optional[str] = typer.Option(
59
+ None, "--as-user", help="Act as this user (X-As-User; API-key auth only)."
60
+ ),
61
+ output_format: Format = typer.Option(
62
+ Format.AUTO,
63
+ "--format",
64
+ "-o",
65
+ help="Output format: auto (table on TTY, else json), json, table.",
66
+ ),
67
+ fields: Optional[str] = typer.Option(
68
+ None,
69
+ "--fields",
70
+ help="Comma-separated top-level keys to keep in the output (token economy).",
71
+ ),
72
+ quiet: bool = typer.Option(
73
+ False,
74
+ "--quiet",
75
+ "-q",
76
+ help="Suppress the stdout data channel; branch on the exit code instead.",
77
+ ),
78
+ _v: bool = typer.Option(
79
+ False, "--version", callback=_version, is_eager=True, help="Show version and exit."
80
+ ),
81
+ ) -> None:
82
+ """Resolve credentials/endpoint once and stash them for subcommands."""
83
+ set_output_options(fields=fields, quiet=quiet)
84
+ ctx.obj = AppCtx(
85
+ resolved=config.resolve(api_key=api_key, api_url=api_url, as_user=as_user),
86
+ fmt=output_format,
87
+ )
88
+
89
+
90
+ # Top-level verbs.
91
+ app.command()(login_cmd.login)
92
+ app.command()(ask_cmd.ask)
93
+ app.command()(search_cmd.search)
94
+ app.command()(remember_cmd.remember)
95
+ app.command(name="api")(api_cmd.api)
96
+ app.command()(update_cmd.update)
97
+ app.command()(doctor_cmd.doctor)
98
+ app.command()(completion_cmd.completion)
99
+ app.command(name="help")(guide_cmd.help)
100
+
101
+ # Grouped nouns.
102
+ app.add_typer(memories_cmd.app, name="memories")
103
+ app.add_typer(connections_cmd.app, name="connections")
104
+ app.add_typer(integrations_cmd.app, name="integrations")
105
+ app.add_typer(brain_cmd.app, name="brain")
106
+ app.add_typer(structure_cmd.app, name="structure")
107
+ app.add_typer(config_cmd.app, name="config")
108
+ app.add_typer(auth_cmd.app, name="auth")
109
+
110
+
111
+ def _describe(cmd: Any, name: str) -> dict[str, Any]:
112
+ """Recursively describe a click command tree using duck-typing (no click import)."""
113
+ node: dict[str, Any] = {"name": name, "help": (getattr(cmd, "help", "") or "").strip()}
114
+ params = []
115
+ for p in getattr(cmd, "params", []):
116
+ kind = getattr(p, "param_type_name", "parameter") # 'option' | 'argument'
117
+ entry: dict[str, Any] = {"name": p.name, "kind": kind, "required": bool(p.required)}
118
+ if kind == "option":
119
+ entry["flags"] = list(getattr(p, "opts", []))
120
+ entry["help"] = getattr(p, "help", "") or ""
121
+ params.append(entry)
122
+ if params:
123
+ node["params"] = params
124
+ subcommands = getattr(cmd, "commands", None) # dict on click Groups
125
+ if isinstance(subcommands, dict):
126
+ node["commands"] = [_describe(sub, sub_name) for sub_name, sub in subcommands.items()]
127
+ return node
128
+
129
+
130
+ @app.command()
131
+ def schema(
132
+ ctx: typer.Context,
133
+ fmt: Optional[Format] = FORMAT_OPTION,
134
+ ) -> None:
135
+ """Dump the full command tree as JSON, so an agent can introspect capabilities."""
136
+ root = typer.main.get_command(app)
137
+ emit(_describe(root, "hyperbrain"), pick(ctx, fmt))
138
+
139
+
140
+ if __name__ == "__main__":
141
+ app()