@spatz/cli 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +217 -147
  2. package/package.json +6 -5
package/README.md CHANGED
@@ -1,227 +1,297 @@
1
1
  # spatz
2
2
 
3
- spatz recommends a model and effort pair for a coding-agent task, and learns which pairs succeed.
3
+ **Choose a model and effort for your coding task. Learn from the result.**
4
4
 
5
- The motto is: do not use a cannon to shoot sparrows. Do not use the strongest model when a cheaper model is good enough.
5
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
6
+ [![Version](https://img.shields.io/github/v/release/lorenzh/spatz)](https://github.com/lorenzh/spatz/releases/latest)
7
+ [![Bun 1.4](https://img.shields.io/badge/Bun-1.4-black?logo=bun)](https://bun.sh)
6
8
 
7
- ## Status
9
+ Do not use a cannon to shoot sparrows.
8
10
 
9
- spatz is a proof of concept. Expect changes to commands, output and the database schema.
11
+ spatz ranks the model and effort pairs that you can use for a coding task.
12
+ It learns from task results to help choose cheaper pairs that succeed.
13
+ You or your coding agent run the task with the recommended pair.
10
14
 
11
- What works:
15
+ [Quickstart](#quickstart) · [Documentation](#documentation) · [Contributing](#contributing) · [Releases](https://github.com/lorenzh/spatz/releases)
12
16
 
13
- - Recommendations from the candidates that you give with `--models`.
14
- - Task classification with Jev, or with local keyword rules when Jev is off.
15
- - Learning from Claude Code and Codex CLI hooks, and from `spatz report`.
16
- - Statistics per task type with `spatz stats`.
17
+ ## Why spatz?
17
18
 
18
- What does not work yet:
19
+ Different tasks need different models and effort levels.
20
+ spatz combines task classification with results from your previous tasks.
19
21
 
20
- - Signal collection works only with Claude Code and Codex CLI hooks. Other coding agents can only use `spatz report`.
21
- - There is no MCP server.
22
+ - **Use your available models.** Pass the candidates with `--models`.
23
+ - **Learn from results.** Record outcomes through hooks or `spatz report`.
24
+ - **Compare performance.** Use `spatz stats` to see results per task type or routing scope.
25
+ - **Connect to coding agents.** Hooks support Claude Code and Codex CLI. Other agents can use the CLI directly.
26
+ - **Keep learning data local.** spatz stores results in `~/.spatz/spatz.db`. It does not store task text.
22
27
 
23
- ## How it works
24
-
25
- You give spatz a task text and a list of candidate pairs. A local filter first checks the task text for secrets. If the filter finds no secret, Jev classifies the task. The classification gives a task type, a difficulty and a criticality. Jev is a TypeSafe AI model that returns typed answers with calibrated probabilities. spatz then reads the learned success estimates for each candidate in that task class and ranks the candidates. spatz never runs the task and never switches the model. You or your agent pick the model. Claude Code hooks and `spatz report` send the outcome back, and spatz updates its estimates.
26
-
27
- ```mermaid
28
- flowchart LR
29
- T[Task text] --> F[Privacy filter]
30
- F -->|no secret, Jev on| J[Jev classification]
31
- F -->|secret found, Jev off or no key| K[Keyword rules]
32
- J -->|Jev error| K
33
- J --> E[Learned estimates]
34
- K --> E
35
- E --> R[Ranking of --models candidates]
36
- R --> U[You or your agent pick a pair]
37
- U --> H[Claude Code or Codex hooks]
38
- U --> S[spatz report]
39
- H --> O[(Outcomes in ~/.spatz/spatz.db)]
40
- S --> O
41
- O --> E
42
- ```
28
+ ## Quickstart
43
29
 
44
- [docs/how-it-works.md](docs/how-it-works.md) and [docs/recommendation.md](docs/recommendation.md) explain the details.
30
+ ### 1. Install
45
31
 
46
- ## Requirements
32
+ Install the stable CLI with Node.js 18 or newer:
47
33
 
48
- - Node.js 18 or newer for npm installation. The platform package includes the Bun runtime.
49
- - Bun 1.4 for development or installation from source. Release archives include the runtime.
50
- - Optional: a TypeSafe AI API key for Jev classification. Jev is in early access.
34
+ ```bash
35
+ npm install -g @spatz/cli
36
+ spatz --version
37
+ ```
51
38
 
52
- spatz works without a key. Without a key, spatz uses the keyword rules. These rules set only the criticality. The task type is always `other`.
39
+ The npm package includes the Bun runtime. Keep optional dependencies enabled.
40
+ Linux needs glibc. spatz does not support Alpine Linux.
41
+ Windows x64 support is experimental. Some releases omit it.
53
42
 
54
- ## Releases
43
+ For installation without Node.js, use a [release archive](#releases).
44
+ For the unstable nightly version, use `npm install -g @spatz/cli@nightly`.
55
45
 
56
- Download an archive and its matching `.sha256` file from [GitHub Releases](https://github.com/lorenzh/spatz/releases).
57
- Choose `linux` or `darwin` (macOS), then `x64` (Intel/AMD) or `arm64` (including Apple Silicon). Windows x64 archives are experimental.
58
- Linux builds need glibc. They do not support Alpine Linux.
46
+ ### 2. Ask for a recommendation
59
47
 
60
- Check the checksum before you extract the archive. This Linux x64 example uses version `0.1.0`. Use your downloaded version:
48
+ Pass the task and the model pairs that your agent can run:
61
49
 
62
50
  ```bash
63
- version=0.1.0
64
- archive="spatz-cli-$version-linux-x64.tar.gz"
65
- sha256sum --check "$archive.sha256"
51
+ spatz "Fix the off-by-one error in src/list.ts" \
52
+ --models claude-opus-5-5:high+medium,claude-sonnet-5-5:medium+low
66
53
  ```
67
54
 
68
- On macOS, use `shasum -a 256 --check "$archive.sha256"` and a `darwin` archive.
69
- The release also contains `SHA256SUMS` with checksums for all archives.
70
- On Windows, download the `win32-x64.zip` archive and its `.sha256` file. Windows support is experimental; hooks are untested on Windows.
55
+ Each candidate uses `<model-id>:<effort>+<effort>...`.
56
+ Use model IDs and efforts that your environment supports.
57
+ The output includes a `suggestion_id` and a ranked list of pairs.
58
+ Add `--json` for machine-readable output.
71
59
 
72
- Keep the archive contents together. Put a symlink to the executable on your `PATH`:
60
+ spatz works without an API key.
61
+ Without Jev or learned results, it recommends the most expensive candidate.
62
+ Jev is the TypeSafe AI model that classifies the task and estimates candidate suitability.
63
+ To enable Jev, set your TypeSafe AI key:
73
64
 
74
65
  ```bash
75
- mkdir -p ~/.local/lib/spatz ~/.local/bin
76
- tar -xzf "$archive" -C ~/.local/lib/spatz
77
- ln -sfn "$HOME/.local/lib/spatz/${archive%.tar.gz}/spatz" ~/.local/bin/spatz
78
- export PATH="$HOME/.local/bin:$PATH"
79
- spatz --version
66
+ export TYPESAFE_AI_API_KEY="<your-key>"
80
67
  ```
81
68
 
82
- If needed, add the `PATH` line to your shell profile.
83
- Each archive includes `spatz`, `LICENSE`, `README.md`, the DuckDB binding, and the DuckDB shared library.
84
- `spatz stats` needs the binding and shared library beside the executable.
85
- The Windows archive contains `spatz.exe` and the DuckDB Windows binding and DLL beside it.
86
- On first use, it downloads DuckDB's SQLite extension into `~/.spatz/duckdb-extensions`.
87
- Later runs can use that extension offline.
88
-
89
- The fixed [`nightly` release](https://github.com/lorenzh/spatz/releases/tag/nightly) is unstable.
90
- When code or release inputs change on `main`, it updates at the next daily run at 03:00 UTC.
91
- You can also start a manual workflow run with `force` enabled.
92
- See [RELEASING.md](RELEASING.md) for the release procedure.
69
+ When you enable Jev, spatz sends task text and candidate details to TypeSafe AI.
70
+ Read [Privacy](#privacy) before using sensitive task text.
93
71
 
94
- ## Install and quickstart
72
+ ### 3. Run the task and report the result
95
73
 
96
- Install the stable version with npm:
74
+ Run the task with the chosen model and effort in your coding agent.
75
+ Then report the pair you actually used:
97
76
 
98
77
  ```bash
99
- npm i -g @spatz/cli
100
- spatz --version
78
+ spatz report <suggestion_id> \
79
+ --model claude-sonnet-5-5 --effort medium --result pass
80
+
81
+ spatz stats
101
82
  ```
102
83
 
103
- For the unstable nightly version:
84
+ Replace `<suggestion_id>` with the ID from the recommendation.
85
+ Results can be `pass`, `partial`, or `fail`.
86
+ An explicit report overrides hook signals for that recommendation.
104
87
 
105
- ```bash
106
- npm i -g @spatz/cli@nightly
107
- ```
88
+ For experiments, add `--dry-run` to the recommendation command.
89
+ These suggestions never count toward learning or statistics.
108
90
 
109
- Keep optional dependencies enabled. npm selects the package for your OS and architecture.
110
- Linux needs glibc and does not support Alpine Linux.
111
- Windows x64 is experimental. Some releases omit it.
112
- You can also [download a GitHub release archive](#releases). Archives need neither Node.js nor Bun installed.
91
+ ## How it works
113
92
 
114
- To install from source instead:
93
+ 1. A local filter checks the task text for known secret patterns.
94
+ 2. Jev classifies the task. Without Jev, spatz uses local keyword rules.
95
+ 3. spatz ranks your candidates using classification and learned success estimates.
96
+ 4. You or your agent choose a pair and run the task.
97
+ 5. Hooks or `spatz report` record the outcome for future recommendations.
115
98
 
116
- 1. Clone the repository and install the dependencies.
99
+ The CLI recommends pairs. The optional Claude Code mod can apply them automatically.
100
+ See [How it works](docs/how-it-works.md) and [Recommendation rules](docs/recommendation.md) for the decision process.
117
101
 
118
- ```bash
119
- git clone https://github.com/lorenzh/spatz.git
120
- cd spatz
121
- bun install
122
- ```
102
+ ## Agent integrations
123
103
 
124
- 2. Put `spatz` on your `PATH` with a small wrapper. Hooks run in a non-interactive shell, so a shell alias does not work.
104
+ | Integration | What it does | Setup |
105
+ | --- | --- | --- |
106
+ | Claude Code `spatz` plugin | Record task signals and model usage. | [Hooks guide](docs/hooks.md) |
107
+ | Codex `spatz` plugin | Record shell results and model usage. | [Hooks guide](docs/hooks.md) |
108
+ | Claude Code `spatz-mod` plugin (mod) | Show recommendations or apply model and effort choices. | [Mod guide](docs/claude-mod.md) |
109
+ | Other agents | Request recommendations and report outcomes through the CLI. | [Installation](docs/installation.md) | CLI and plugin setup, runtime requirements, and release-specific installs. |
110
+ | [CLI reference](docs/cli.md) |
125
111
 
126
- ```bash
127
- mkdir -p ~/.local/bin
128
- printf '#!/bin/sh\nexec bun "%s/packages/cli/src/cli.ts" "$@"\n' "$PWD" > ~/.local/bin/spatz
129
- chmod +x ~/.local/bin/spatz
130
- ```
112
+ The Claude Code mod supports `step`, `turn`, `subagent`, `session`, and `escalate` routing scopes.
113
+ Hooks and the mod can run together. The mod's `record: auto` avoids duplicate usage recording with the `spatz` hooks plugin.
131
114
 
132
- 3. Optional: set your TypeSafe AI key to turn on Jev.
115
+ ### Install for Claude Code
133
116
 
134
- ```bash
135
- export TYPESAFE_AI_API_KEY=<your-key>
117
+ Use macOS or Linux with a POSIX shell. The plugins do not support native Windows.
118
+ Install the [spatz CLI](#quickstart) first so the hooks and mod can find it on `PATH`.
119
+ The mod needs Claude Code 2.1.287 or newer.
120
+
121
+ 1. Start Claude Code. Add the marketplace and install the hooks:
122
+
123
+ ```text
124
+ /plugin marketplace add lorenzh/spatz
125
+ /plugin install spatz@spatz
136
126
  ```
137
127
 
138
- 4. Ask for a recommendation. `--models` lists the pairs that you can use, in the form `<id>[:<effort>+<effort>...]`.
128
+ The hooks record test/build results and model usage. They do not switch models.
139
129
 
140
- ```bash
141
- spatz "Fix the off-by-one error in src/list.ts" \
142
- --models claude-opus-5-5:high+medium,claude-sonnet-5-5:medium+low --dry-run
130
+ 2. Optional: install the mod for automatic recommendations:
131
+
132
+ ```text
133
+ /plugin install spatz-mod@spatz
143
134
  ```
144
135
 
145
- Example output without a key (`SPATZ_NO_JEV=1`, empty database):
136
+ The mod defaults to `show` mode. To apply recommendations to subagents, run:
146
137
 
147
138
  ```text
148
- suggestion_id: fd8b7c1f-1f93-44f6-ac7b-b77ee287d1bb
149
- 1. anthropic/claude-opus-5.5:high estimate=0.50 n=0
150
- reason: Without Jev and learned data the most expensive pair anthropic/claude-opus-5.5 (high) is recommended.
151
- task_type: other difficulty: medium criticality: none
152
- explored: false control: false fallback_used: true (dry-run)
139
+ /spatz mode apply
140
+ /spatz status
153
141
  ```
154
142
 
155
- `--dry-run` marks the recommendation as a test. A test never counts for learning or statistics. Remove the flag for real use.
143
+ When you install both plugins, keep `record: auto`. The hooks then handle recording.
144
+ To apply recommendations to the main session too, enable `/spatz main on`.
156
145
 
157
- spatz gets model prices from the OpenRouter model list and keeps them for 24 hours in `~/.spatz/openrouter-models.json`. To fill this cache, spatz needs network access. Without network access, you still get a recommendation. spatz uses the cached prices, even from a stale cache. If no cache exists, all prices are unknown and the models rank as most expensive.
146
+ 3. Remove any manual `spatz hook` entries from `~/.claude/settings.json` and project settings.
147
+ Keep unrelated hooks. This avoids duplicate records.
158
148
 
159
- 5. After the task, report the pair that you used and the result.
149
+ See the [Claude Code mod guide](docs/claude-mod.md) for routing scopes and persistent configuration.
150
+
151
+ ### Install for Codex CLI
152
+
153
+ Use macOS or Linux with a POSIX shell and a Codex CLI version with plugin support.
154
+ Install the [spatz CLI](#quickstart) first and check `spatz --version` in your terminal.
155
+
156
+ 1. Add the marketplace and install the hooks from your terminal:
160
157
 
161
158
  ```bash
162
- spatz report <suggestion_id> --model claude-sonnet-5-5 --effort medium --result pass
159
+ codex plugin marketplace add lorenzh/spatz
160
+ codex plugin add spatz@spatz
161
+ codex plugin list
163
162
  ```
164
163
 
165
- A report overrides all hook signals for that recommendation.
164
+ 2. Start Codex. Run `/hooks` to review and trust the spatz hooks.
165
+ Codex skips plugin hooks until you trust them. See [OpenAI's hook documentation](https://learn.chatgpt.com/docs/hooks#review-and-trust-hooks).
166
166
 
167
- ## Use with Claude Code
167
+ 3. Remove any manual `spatz hook … --agent codex` entries from `~/.codex/hooks.json`.
168
+ Keep unrelated hooks. This avoids duplicate records.
168
169
 
169
- You can connect spatz to Claude Code in three ways. They can run alone or together.
170
+ The plugin records shell results and model usage. Its routing skill guides the agent through recommendations and outcome reports.
171
+ It does not automatically switch the Codex model.
172
+ See the [Codex hooks guide](docs/hooks.md#codex-cli) for recorded events and limits.
170
173
 
171
- - **Hooks only.** The hooks in your Claude Code settings watch Bash calls and record test and build results, models and tokens. See [docs/hooks.md](docs/hooks.md).
172
- - **Mod only.** The `spatz` mod in `packages/claude-mod` asks spatz for each decision. In `apply` mode it sets model and effort for subagents or for the main session. It records usage itself. See [docs/claude-mod.md](docs/claude-mod.md).
173
- - **Both.** The mod routes and the hooks record. With `record: auto` the mod stops recording when the `spatz-hooks` plugin is enabled, so nothing is counted twice.
174
+ ### Check your setup
174
175
 
175
- The mod has five routing scopes: `step`, `turn`, `subagent` (default), `session` and `escalate`. `spatz stats --by scope` compares them.
176
+ If you use Jev, set `TYPESAFE_AI_API_KEY` in the terminal before starting your coding agent.
177
+ Ask your agent to request a recommendation for a real task using its available model and effort pairs.
178
+ Keep the suggestion output unfiltered so the hooks can read its ID.
179
+ After the task, ask the agent to report the actual pair and result with `spatz report`.
180
+ Run `spatz stats` to see recorded outcomes.
176
181
 
177
- ## Commands
182
+ Every plugin ships the `spatz` routing skill. You do not need to edit your agent instructions.
183
+ The hooks plugins can also run without a global CLI through their bundled launcher using Bun or npx.
184
+ The first run downloads about 60 MB. Codex hooks time out after 10 seconds.
185
+ For this setup, warm the launcher before the first session with `"<plugin root>/bin/spatz" --version`.
186
+ See [Installation](docs/installation.md) for launcher paths and setup without a global CLI.
178
187
 
179
- The suggestion, report, usage, link and stats commands accept `--json` for machine-readable output.
188
+ ## Privacy
180
189
 
181
- | Command | Purpose |
182
- | --- | --- |
183
- | `spatz --version` | Print the CLI version. |
184
- | `spatz "<task>" --models <list> [--scope <scope>] [--session <id>] [--turn <id>] [--agent-id <id>] [--source <agent>] [--dry-run]` | Rank candidate pairs and optionally store routing attribution. |
185
- | `spatz report <suggestion_id> --model <m> --effort <e> --result pass\|partial\|fail [--rounds <n>] [--note <t>] [--turn <id> --source claude-code-mod]` | Record the pair that you used and the result. |
186
- | `spatz usage <suggestion_id> ... --turn <id> --source claude-code-mod` | Record direct model usage and token counts. |
187
- | `spatz link <suggestion_id> --agent-id <id> --session <id>` | Link a subagent suggestion after its id is known. |
188
- | `spatz hook <event> [--agent codex]` | Read a Claude Code or Codex hook event from stdin. Prints nothing and always exits 0. |
189
- | `spatz stats [--type <t>] [--by scope]` | Show results per task type or routing scope. |
190
+ spatz stores learning data under `~/.spatz`. It does not store task text or tool output.
191
+ Hooks process task signals locally and make no network requests.
190
192
 
191
- Exit codes: 0 for success, 1 for a runtime error (for example an unknown `suggestion_id`), 2 for a usage error. [docs/cli.md](docs/cli.md) is the full reference.
193
+ When you enable Jev, spatz sends task text and candidate details to TypeSafe AI.
194
+ The secret filter catches known patterns. It cannot detect every secret.
195
+ Do not put secrets in task text.
192
196
 
193
- ## Configuration and privacy
197
+ To disable Jev:
194
198
 
195
- spatz reads four environment variables. `HOME` sets the location of `~/.spatz`. `TYPESAFE_AI_API_KEY` turns on Jev. `SPATZ_NO_JEV=1` turns off Jev. If you set `OPENROUTER_API_KEY`, spatz sends it with the OpenRouter model-list request. A project can also turn off Jev with `{"jev": false}` in `.spatz.json` in the working directory. All data stays in `~/.spatz`. [docs/configuration.md](docs/configuration.md) lists all settings and files.
199
+ ```bash
200
+ export SPATZ_NO_JEV=1
201
+ ```
202
+
203
+ For a project, put `{"jev": false}` in `.spatz.json` in the working directory.
204
+ Without `TYPESAFE_AI_API_KEY`, Jev is also disabled.
205
+
206
+ Disabling Jev still allows OpenRouter requests for model prices. These requests contain no task data.
207
+ spatz caches prices for 24 hours. When the network is unavailable, spatz can still use cached prices.
208
+ The first `spatz stats` run downloads DuckDB's SQLite extension.
209
+
210
+ See the [Privacy guide](docs/privacy.md) for data flows and deletion instructions.
211
+ See [Configuration](docs/configuration.md) for environment variables and local files.
212
+
213
+ ## Releases
214
+
215
+ Download an archive and its matching `.sha256` file from [GitHub Releases](https://github.com/lorenzh/spatz/releases).
216
+ Archives include the runtime. You do not need Node.js or Bun installed.
217
+
218
+ Choose `linux` or `darwin` (macOS), then `x64` or `arm64`.
219
+ Apple Silicon uses `darwin-arm64`. Linux builds need glibc.
220
+ Windows x64 ZIP archives are experimental. The agent plugins do not support native Windows.
196
221
 
197
- When Jev is on, spatz sends the task text and the candidate list to TypeSafe AI. The candidate list holds the `model:effort` labels and a short description per model. If Jev is off, the key is missing or the secret filter finds a secret, spatz sends nothing to TypeSafe AI. spatz does not store the task text. The OpenRouter model-list request holds no task data. Turning off Jev does not stop this request. The hooks store only derived signals, model names, efforts and token counts. [docs/privacy.md](docs/privacy.md) describes each data flow.
222
+ Check the checksum before extraction. This Linux x64 example uses version `0.1.0`:
223
+
224
+ ```bash
225
+ version=0.1.0
226
+ archive="spatz-cli-$version-linux-x64.tar.gz"
227
+ sha256sum --check "$archive.sha256"
228
+
229
+ mkdir -p ~/.local/lib/spatz ~/.local/bin
230
+ tar -xzf "$archive" -C ~/.local/lib/spatz
231
+ ln -sfn "$HOME/.local/lib/spatz/${archive%.tar.gz}/spatz" ~/.local/bin/spatz
232
+ export PATH="$HOME/.local/bin:$PATH"
233
+ spatz --version
234
+ ```
235
+
236
+ Use your downloaded version. On macOS, use `shasum -a 256 --check "$archive.sha256"`.
237
+ If your shell does not include `~/.local/bin`, add the `PATH` line to your shell profile.
238
+ Keep the executable and DuckDB libraries together. `spatz stats` needs these libraries beside the executable.
239
+
240
+ The [nightly release](https://github.com/lorenzh/spatz/releases/tag/nightly) is unstable.
241
+ See [Releasing spatz](RELEASING.md) for the release process.
242
+
243
+ ## Install from source
244
+
245
+ Install Bun 1.4, then clone the repository:
246
+
247
+ ```bash
248
+ git clone https://github.com/lorenzh/spatz.git
249
+ cd spatz
250
+ bun install
251
+ ```
252
+
253
+ Put a wrapper on your `PATH` so hooks can find `spatz` in non-interactive shells:
254
+
255
+ ```bash
256
+ mkdir -p ~/.local/bin
257
+ printf '#!/bin/sh\nexec bun "%s/packages/cli/src/cli.ts" "$@"\n' "$PWD" > ~/.local/bin/spatz
258
+ chmod +x ~/.local/bin/spatz
259
+ export PATH="$HOME/.local/bin:$PATH"
260
+ spatz --version
261
+ ```
262
+
263
+ A shell alias does not work for hooks.
264
+ See [Contributing](CONTRIBUTING.md) for the full development setup.
198
265
 
199
266
  ## Documentation
200
267
 
201
- - [docs/how-it-works.md](docs/how-it-works.md): the architecture and the flow from task to outcome.
202
- - [docs/recommendation.md](docs/recommendation.md): how spatz ranks candidates, explores and uses control groups.
203
- - [docs/privacy.md](docs/privacy.md): what data leaves your machine and what spatz stores.
204
- - [docs/cli.md](docs/cli.md): all commands, flags, output fields and exit codes.
205
- - [docs/hooks.md](docs/hooks.md): the Claude Code hooks setup and the signals they record.
206
- - [docs/claude-mod.md](docs/claude-mod.md): the Claude Code mod, its modes, routing scopes and `/spatz` commands.
207
- - [docs/configuration.md](docs/configuration.md): environment variables, project file and files in `~/.spatz`.
208
- - [CONTRIBUTING.md](CONTRIBUTING.md): development setup, tests and the change process.
209
- - [SECURITY.md](SECURITY.md): how to report a vulnerability.
268
+ | Guide | What you will find |
269
+ | --- | --- |
270
+ | [CLI reference](docs/cli.md) | Commands, flags, model IDs, output fields, and exit codes. |
271
+ | [How it works](docs/how-it-works.md) | Architecture and the flow from task to outcome. |
272
+ | [Recommendation rules](docs/recommendation.md) | Ranking, exploration, and control groups. |
273
+ | [Hooks](docs/hooks.md) | Claude Code and Codex CLI setup and recorded signals. |
274
+ | [Claude Code mod](docs/claude-mod.md) | Modes, routing scopes, and `/spatz` commands. |
275
+ | [Configuration](docs/configuration.md) | Environment variables and local files. |
276
+ | [Privacy](docs/privacy.md) | Network requests, stored data, and deletion. |
210
277
 
211
- ## Development
278
+ ## Contributing
212
279
 
213
- The repository is a Bun workspace with two packages. `packages/core` (`@spatz/core`) holds all logic. `packages/cli` (`@spatz/cli`) is a thin CLI on top of it.
280
+ Bug reports and pull requests are welcome.
281
+ For larger changes, [open an issue](https://github.com/lorenzh/spatz/issues) first to agree on the scope.
282
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for setup and the test-first workflow.
283
+ Changes to `main` must go through a pull request.
214
284
 
215
- Run these gates before you push:
285
+ Run the checks before submitting a change:
216
286
 
217
287
  ```bash
218
- bun test # all tests, including end-to-end tests of the CLI
219
- bun run typecheck # tsc --noEmit
220
- bun run lint # biome check
288
+ bun test
289
+ bun run typecheck
290
+ bun run lint
221
291
  ```
222
292
 
223
- Work test first. Write a failing test and make it pass with the minimum code. Then clean up. [CONTRIBUTING.md](CONTRIBUTING.md) has the details.
293
+ For vulnerabilities, follow [SECURITY.md](SECURITY.md). Do not open a public issue.
224
294
 
225
295
  ## License
226
296
 
227
- MIT. See [LICENSE](LICENSE).
297
+ [MIT](LICENSE) © 2026 Lorenz Hilpert.
package/package.json CHANGED
@@ -1,15 +1,16 @@
1
1
  {
2
2
  "name": "@spatz/cli",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Model and effort recommendations for coding agents",
5
5
  "bin": {
6
6
  "spatz": "bin/spatz.js"
7
7
  },
8
8
  "optionalDependencies": {
9
- "@spatz/cli-linux-x64": "0.1.0",
10
- "@spatz/cli-linux-arm64": "0.1.0",
11
- "@spatz/cli-darwin-arm64": "0.1.0",
12
- "@spatz/cli-darwin-x64": "0.1.0"
9
+ "@spatz/cli-linux-x64": "0.1.2",
10
+ "@spatz/cli-linux-arm64": "0.1.2",
11
+ "@spatz/cli-darwin-arm64": "0.1.2",
12
+ "@spatz/cli-darwin-x64": "0.1.2",
13
+ "@spatz/cli-win32-x64": "0.1.2"
13
14
  },
14
15
  "engines": {
15
16
  "node": ">=18"