axor-cli 0.2.0__tar.gz → 0.5.3__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 (38) hide show
  1. axor_cli-0.5.3/CHANGELOG.md +40 -0
  2. axor_cli-0.5.3/PKG-INFO +385 -0
  3. axor_cli-0.5.3/README.md +346 -0
  4. axor_cli-0.5.3/axor_cli/_version.py +1 -0
  5. {axor_cli-0.2.0 → axor_cli-0.5.3}/axor_cli/adapters.py +78 -9
  6. {axor_cli-0.2.0 → axor_cli-0.5.3}/axor_cli/auth.py +71 -10
  7. axor_cli-0.5.3/axor_cli/display.py +379 -0
  8. axor_cli-0.5.3/axor_cli/hooks.py +182 -0
  9. axor_cli-0.5.3/axor_cli/images.py +55 -0
  10. axor_cli-0.5.3/axor_cli/main.py +658 -0
  11. axor_cli-0.5.3/axor_cli/mcp_config.py +67 -0
  12. axor_cli-0.5.3/axor_cli/memory_provider.py +283 -0
  13. axor_cli-0.5.3/axor_cli/permissions.py +142 -0
  14. axor_cli-0.5.3/axor_cli/routing_config.py +193 -0
  15. axor_cli-0.5.3/axor_cli/session_store.py +106 -0
  16. axor_cli-0.5.3/axor_cli/skill_commands.py +109 -0
  17. axor_cli-0.5.3/axor_cli/streaming.py +247 -0
  18. {axor_cli-0.2.0 → axor_cli-0.5.3}/pyproject.toml +15 -9
  19. {axor_cli-0.2.0 → axor_cli-0.5.3}/tests/unit/test_auth.py +37 -0
  20. axor_cli-0.2.0/CHANGELOG.md +0 -17
  21. axor_cli-0.2.0/PKG-INFO +0 -279
  22. axor_cli-0.2.0/README.md +0 -243
  23. axor_cli-0.2.0/axor_cli/_version.py +0 -1
  24. axor_cli-0.2.0/axor_cli/display.py +0 -188
  25. axor_cli-0.2.0/axor_cli/main.py +0 -329
  26. axor_cli-0.2.0/axor_cli/streaming.py +0 -109
  27. {axor_cli-0.2.0 → axor_cli-0.5.3}/.github/workflows/ci.yml +0 -0
  28. {axor_cli-0.2.0 → axor_cli-0.5.3}/.gitignore +0 -0
  29. {axor_cli-0.2.0 → axor_cli-0.5.3}/CONTRIBUTING.md +0 -0
  30. {axor_cli-0.2.0 → axor_cli-0.5.3}/LICENSE +0 -0
  31. {axor_cli-0.2.0 → axor_cli-0.5.3}/axor_cli/__init__.py +0 -0
  32. {axor_cli-0.2.0 → axor_cli-0.5.3}/axor_cli/telemetry.py +0 -0
  33. {axor_cli-0.2.0 → axor_cli-0.5.3}/tests/__init__.py +0 -0
  34. {axor_cli-0.2.0 → axor_cli-0.5.3}/tests/conftest.py +0 -0
  35. {axor_cli-0.2.0 → axor_cli-0.5.3}/tests/unit/test_adapters.py +0 -0
  36. {axor_cli-0.2.0 → axor_cli-0.5.3}/tests/unit/test_display.py +0 -0
  37. {axor_cli-0.2.0 → axor_cli-0.5.3}/tests/unit/test_smoke.py +0 -0
  38. {axor_cli-0.2.0 → axor_cli-0.5.3}/tests/unit/test_telemetry_bridge.py +0 -0
@@ -0,0 +1,40 @@
1
+ # Changelog
2
+
3
+ ## 0.3.0 — 2026-04-29
4
+
5
+ ### Added
6
+ - `ConfigCorruptError` raised when `~/.axor/config.toml` exists but cannot
7
+ be parsed. The previous behaviour silently returned `{}` and let the
8
+ next save **overwrite the broken file**, dropping any other adapter's
9
+ saved key. Refusing to write preserves user data; the user is told to
10
+ fix or delete the file.
11
+
12
+ ### Fixed
13
+ - TOML escaping made spec-compliant. The old version only escaped `\` and
14
+ `"`; pasting an API key that contained a newline (or any control byte)
15
+ produced a file that crashed the next `tomllib.load()`. Now handles
16
+ `\n`, `\r`, `\t`, `\b`, `\f`, plus a `\uXXXX` fallback for any other
17
+ control char.
18
+
19
+ ### Changed
20
+ - Model registry refreshed: `claude-sonnet-4-6`, `claude-opus-4-7`,
21
+ `claude-haiku-4-5`. Default is `claude-sonnet-4-6`.
22
+
23
+ ### Constraints
24
+ - Pin bump: `axor-core>=0.4.0,<0.5` (was `>=0.3.0`).
25
+
26
+ ## 0.2.0 — 2026-04-24
27
+
28
+ ### Added
29
+ - `axor-telemetry` integration. New `/telemetry` slash command:
30
+ `status` / `on [--remote]` / `off` / `preview` / `consent`.
31
+ - One-time stderr opt-in banner. Marker file
32
+ `~/.axor/.telemetry_notice_shown` suppresses subsequent prints;
33
+ `AXOR_NO_BANNER=1` suppresses on-demand.
34
+ - `build_session` wires a `TelemetryPipeline` into `GovernedSession`.
35
+ - Optional `[telemetry]` extra: `pip install axor-cli[telemetry]`.
36
+ - 11 new bridge tests + smoke-test fix (44 total).
37
+
38
+ ## 0.1.0 — 2026-04-14
39
+
40
+ Initial release of the `axor` CLI shell.
@@ -0,0 +1,385 @@
1
+ Metadata-Version: 2.4
2
+ Name: axor-cli
3
+ Version: 0.5.3
4
+ Summary: CLI for axor-core governance kernel — governed agent sessions in your terminal
5
+ Project-URL: Bug Tracker, https://github.com/Bucha11/axor-cli/issues
6
+ Project-URL: Changelog, https://github.com/Bucha11/axor-cli/releases
7
+ Project-URL: Repository, https://github.com/Bucha11/axor-cli
8
+ License: MIT
9
+ License-File: LICENSE
10
+ Keywords: agents,axor,claude,cli,governance,llm
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Topic :: Software Development :: Libraries
18
+ Classifier: Topic :: Terminals
19
+ Requires-Python: >=3.11
20
+ Requires-Dist: axor-core<0.6,>=0.5.0
21
+ Provides-Extra: all
22
+ Requires-Dist: axor-claude>=0.1.0; extra == 'all'
23
+ Requires-Dist: axor-openai>=0.1.0; extra == 'all'
24
+ Requires-Dist: axor-openrouter>=0.1.0; extra == 'all'
25
+ Requires-Dist: axor-telemetry>=0.1.0; extra == 'all'
26
+ Provides-Extra: claude
27
+ Requires-Dist: axor-claude>=0.1.0; extra == 'claude'
28
+ Provides-Extra: dev
29
+ Requires-Dist: axor-telemetry>=0.1.0; extra == 'dev'
30
+ Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
31
+ Requires-Dist: pytest>=8.0; extra == 'dev'
32
+ Provides-Extra: openai
33
+ Requires-Dist: axor-openai>=0.1.0; extra == 'openai'
34
+ Provides-Extra: openrouter
35
+ Requires-Dist: axor-openrouter>=0.1.0; extra == 'openrouter'
36
+ Provides-Extra: telemetry
37
+ Requires-Dist: axor-telemetry>=0.1.0; extra == 'telemetry'
38
+ Description-Content-Type: text/markdown
39
+
40
+ # axor-cli
41
+
42
+ [![PyPI](https://img.shields.io/pypi/v/axor-cli?cacheSeconds=300)](https://pypi.org/project/axor-cli/)
43
+ [![Python](https://img.shields.io/pypi/pyversions/axor-cli?cacheSeconds=300)](https://pypi.org/project/axor-cli/)
44
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
45
+
46
+ **Governed agent sessions in your terminal.**
47
+
48
+ Run Claude or any OpenRouter model under axor-core governance — controlled tool permissions, token budgets, context compression, hooks, skills, memory, and full audit trail. Feature-compatible with [Claude Code](https://claude.ai/code) configuration files.
49
+
50
+ ---
51
+
52
+ ## Installation
53
+
54
+ ```bash
55
+ # With OpenRouter (200+ models, recommended)
56
+ pip install axor-cli axor-openrouter
57
+
58
+ # With Claude directly
59
+ pip install axor-cli axor-claude
60
+
61
+ # With OpenAI
62
+ pip install axor-cli axor-openai
63
+ ```
64
+
65
+ ---
66
+
67
+ ## Quick start
68
+
69
+ ```bash
70
+ # Set API key (saved to ~/.axor/config.toml)
71
+ axor openrouter /auth
72
+
73
+ # Interactive REPL
74
+ axor openrouter
75
+
76
+ # Single task and exit
77
+ axor openrouter "refactor the auth module"
78
+
79
+ # With options
80
+ axor openrouter --policy readonly "review this PR"
81
+ axor openrouter --limit 100000 --model anthropic/claude-opus-4-7 "large migration"
82
+ axor openrouter -y "scaffold a FastAPI project" # auto-approve all tools
83
+ ```
84
+
85
+ ---
86
+
87
+ ## Authentication
88
+
89
+ On first run, axor prompts for an API key and saves it to `~/.axor/config.toml` (permissions: 600).
90
+
91
+ Key priority (highest wins):
92
+
93
+ | Source | When used |
94
+ |--------|-----------|
95
+ | `--api-key` flag | One-off, never saved |
96
+ | Env var (`ANTHROPIC_API_KEY`, `OPENROUTER_API_KEY`, `OPENAI_API_KEY`) | CI/CD, containers |
97
+ | `~/.axor/config.toml` | Persistent, set via `/auth` |
98
+
99
+ ```
100
+ > /auth # prompt and save
101
+ > /auth --show # show source (never shows the key)
102
+ > /auth --clear # remove saved key
103
+ ```
104
+
105
+ ---
106
+
107
+ ## CLI options
108
+
109
+ ```
110
+ axor <adapter> [task] [options]
111
+
112
+ Adapters: openrouter, claude, openai
113
+
114
+ Options:
115
+ -p, --policy PRESET readonly | sandboxed | standard | federated
116
+ -l, --limit TOKENS Soft token limit (triggers auto-compact and budget signals)
117
+ -m, --model NAME Model override (e.g. anthropic/claude-opus-4-7)
118
+ --api-key KEY API key for this session only (never saved)
119
+ --tools TOOL ... Tools to enable (default: read write edit bash search glob fetch)
120
+ --yes, -y Auto-approve all tool calls without prompting
121
+ --resume Inject last session's context as starting history
122
+ --image PATH Attach image file (can be repeated, vision models only)
123
+ --thinking TOKENS Extended thinking budget in tokens (e.g. 8000)
124
+ --no-skills Skip CLAUDE.md and .claude/skills/
125
+ --no-plugins Skip .claude/plugins/
126
+ --list-adapters Show installed adapters and exit
127
+ --version Show version
128
+ ```
129
+
130
+ ---
131
+
132
+ ## REPL commands
133
+
134
+ ### Built-in
135
+
136
+ | Command | Description |
137
+ |---------|-------------|
138
+ | `/auth [--show\|--clear]` | Manage API key |
139
+ | `/model [name]` | Show available models; restart hint for switching |
140
+ | `/init` | Generate `CLAUDE.md` from the current codebase |
141
+ | `/memory` | List memories saved for this project |
142
+ | `/memory add <text>` | Save text to persistent memory |
143
+ | `/memory forget <key>` | Delete a memory by key |
144
+ | `/memory search <query>` | Full-text search memories |
145
+ | `/todos` | Show the model's current task list |
146
+ | `/telemetry [on\|off\|preview]` | Manage local telemetry |
147
+ | `/help` | All commands including loaded skills |
148
+ | `!<text>` | Shorthand for `/memory add <text>` |
149
+ | `exit` / `quit` / `^D` | Exit |
150
+
151
+ ### Governed (handled by axor-core)
152
+
153
+ | Command | Description |
154
+ |---------|-------------|
155
+ | `/cost` | Token usage for this session |
156
+ | `/policy` | Last execution policy |
157
+ | `/compact` | Compress context (reduces token usage) |
158
+ | `/clear` | Clear all context fragments and cache |
159
+ | `/status` | Session overview |
160
+ | `/tools` | Tools available under the current policy |
161
+
162
+ ### Skills
163
+
164
+ Skills in `.claude/skills/` or `~/.claude/skills/` are available as `/skillname`. See [Skills](#skills) below.
165
+
166
+ ---
167
+
168
+ ## Tool approval
169
+
170
+ When a tool needs approval, axor shows:
171
+
172
+ ```
173
+ write(path='auth.py', content='...') [y/n/a/?]
174
+ ```
175
+
176
+ | Key | Action |
177
+ |-----|--------|
178
+ | `y` / Enter | Allow once |
179
+ | `n` | Deny |
180
+ | `a` | Always allow this tool for the rest of the session |
181
+ | `?` | Show help |
182
+
183
+ Tools that are always auto-approved (non-destructive): `read`, `search`, `glob`, `fetch`.
184
+
185
+ ---
186
+
187
+ ## @file and @url references
188
+
189
+ Prefix any file path or URL with `@` to inject its content into the task:
190
+
191
+ ```
192
+ > review @./src/auth.py for security issues
193
+ > summarize @https://docs.example.com/api
194
+ > compare @./old.py and @./new.py
195
+ ```
196
+
197
+ The content is prepended as a `<context src="...">` block; the `@ref` is stripped from the task text.
198
+
199
+ ---
200
+
201
+ ## Configuration files
202
+
203
+ axor-cli reads the same config files as [Claude Code](https://claude.ai/code).
204
+
205
+ ### CLAUDE.md
206
+
207
+ Place a `CLAUDE.md` in your project root. It's loaded as the system prompt context at session start, giving the model standing instructions about your project.
208
+
209
+ Generate one automatically:
210
+
211
+ ```
212
+ > /init
213
+ ```
214
+
215
+ ### `.claudeignore`
216
+
217
+ Works like `.gitignore`. Files and directories matching these patterns are excluded from `read`, `glob`, `search`, and `/init` tree walks.
218
+
219
+ ```
220
+ # .claudeignore
221
+ *.pyc
222
+ __pycache__
223
+ node_modules
224
+ .venv
225
+ dist/
226
+ secrets.env
227
+ ```
228
+
229
+ ### `~/.claude/settings.json` and `.claude/settings.json`
230
+
231
+ Tool permission rules and hooks. Project settings override user settings.
232
+
233
+ ```json
234
+ {
235
+ "permissions": {
236
+ "allow": ["Read", "Bash(npm *)"],
237
+ "deny": ["Bash(rm -rf *)", "Write(/etc/*)"]
238
+ },
239
+ "hooks": {
240
+ "PreToolUse": [{"matcher": "bash", "command": "echo 'Running: $TOOL_INPUT'"}],
241
+ "PostToolUse": [{"command": "notify-send 'Tool done'"}],
242
+ "Stop": [{"command": "say Done"}],
243
+ "SessionStart":[{"command": "npm run build 2>&1 || true"}]
244
+ }
245
+ }
246
+ ```
247
+
248
+ Permission rule format: `ToolName` (blanket) or `ToolName(glob_pattern)` (pattern match on primary arg).
249
+
250
+ Hook env vars: `TOOL_NAME`, `TOOL_INPUT` (JSON), `TOOL_RESULT`. PreToolUse hooks block the call on non-zero exit.
251
+
252
+ ---
253
+
254
+ ## Skills
255
+
256
+ Skills are markdown files in `.claude/skills/` (project) or `~/.claude/skills/` (user).
257
+
258
+ ```markdown
259
+ ---
260
+ description: Run the full test suite and show coverage
261
+ run: pytest --cov=src --cov-report=term-missing
262
+ ---
263
+ ```
264
+
265
+ Or as an agent task:
266
+
267
+ ```markdown
268
+ ---
269
+ description: Write and run a benchmark for the current module
270
+ ---
271
+ Write a benchmark for the current module using timeit, run it, and show results.
272
+ ```
273
+
274
+ Skills appear in `/help` and are invoked as `/skillname`.
275
+
276
+ ---
277
+
278
+ ## Memory
279
+
280
+ axor stores persistent memories in `~/.axor/memory.db` (SQLite), scoped to the project directory.
281
+
282
+ ```
283
+ > !Always use type hints in this project.
284
+ ✓ Saved to memory: Always use type hints in this project.
285
+
286
+ > /memory search type hints
287
+ > /memory forget <key>
288
+ > /memory
289
+ ```
290
+
291
+ Memories are injected into the system prompt at session start.
292
+
293
+ ---
294
+
295
+ ## Auto-compact
296
+
297
+ When accumulated tokens exceed 75% of `--limit` (or 80,000 tokens with no limit), axor automatically compresses context and reports:
298
+
299
+ ```
300
+ → auto-compact: 45,231 → 12,108 ctx tokens (73% freed)
301
+ ```
302
+
303
+ Use `/compact` to trigger manually.
304
+
305
+ ---
306
+
307
+ ## Config file
308
+
309
+ `~/.axor/config.toml` — auto-created with permissions 600:
310
+
311
+ ```toml
312
+ [openrouter]
313
+ api_key = "sk-or-..."
314
+
315
+ [claude]
316
+ api_key = "sk-ant-..."
317
+
318
+ # OpenRouter routing (optional)
319
+ [openrouter.routing]
320
+ mode = "smart" # smart | cascade | flat
321
+ prefer_free_at_depth = 3
322
+ root_model = "anthropic/claude-sonnet-4-6"
323
+
324
+ # MCP servers (optional)
325
+ [[mcp.servers]]
326
+ name = "filesystem"
327
+ command = "npx"
328
+ args = ["-y", "@modelcontextprotocol/server-filesystem", "."]
329
+ ```
330
+
331
+ See [axor-openrouter](https://github.com/Bucha11/axor-openrouter) for full routing and MCP documentation.
332
+
333
+ ---
334
+
335
+ ## Available adapters
336
+
337
+ ```
338
+ $ axor --list-adapters
339
+
340
+ Available adapters:
341
+ openrouter installed
342
+ claude installed
343
+ openai not installed → pip install axor-openai
344
+ ```
345
+
346
+ Each adapter must expose `make_session(**kwargs) -> GovernedSession`.
347
+
348
+ ---
349
+
350
+ ## Repository structure
351
+
352
+ ```
353
+ axor-cli/
354
+ ├── axor_cli/
355
+ │ ├── main.py CLI entrypoint, REPL loop, argument parsing
356
+ │ ├── adapters.py Adapter registry, lazy imports, build_session()
357
+ │ ├── auth.py Key management — ~/.axor/config.toml, priority chain
358
+ │ ├── display.py Terminal output — color, spinner, markdown renderer
359
+ │ ├── streaming.py Connects GovernedSession to terminal (callbacks, approval)
360
+ │ ├── hooks.py Hook runner — PreToolUse, PostToolUse, Stop, SessionStart
361
+ │ ├── permissions.py Settings.json allow/deny rules
362
+ │ ├── skill_commands.py Skill discovery from .claude/skills/*.md
363
+ │ ├── memory_provider.py SQLite memory store with FTS5 full-text search
364
+ │ ├── session_store.py Session history persistence for --resume
365
+ │ ├── mcp_config.py MCP server config loader
366
+ │ ├── routing_config.py OpenRouter cascade/smart routing config
367
+ │ ├── images.py Multimodal image encoding (data URIs)
368
+ │ ├── telemetry.py Optional telemetry bridge
369
+ │ └── _version.py
370
+ └── tests/
371
+ ```
372
+
373
+ ---
374
+
375
+ ## Requirements
376
+
377
+ - Python 3.11+
378
+ - `axor-core >= 0.5.0`
379
+ - At least one adapter: `axor-openrouter`, `axor-claude`, or `axor-openai`
380
+
381
+ ---
382
+
383
+ ## License
384
+
385
+ MIT