oy-cli 0.3.4__tar.gz → 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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: oy-cli
3
- Version: 0.3.4
3
+ Version: 0.4.0
4
4
  Summary: Tiny local coding CLI with a small tool surface
5
5
  Author: oy-cli contributors
6
6
  License-Expression: Apache-2.0
@@ -13,32 +13,30 @@ License-File: LICENSE
13
13
  Requires-Dist: boto3>=1.35.0
14
14
  Requires-Dist: defopt>=7.0.0
15
15
  Requires-Dist: httpx>=0.28.1
16
- Requires-Dist: markdownify>=1.2.0
17
16
  Requires-Dist: openai>=1.68.0
18
17
  Requires-Dist: rich>=14.3.0
19
18
  Requires-Dist: tiktoken>=0.7.0
20
19
  Requires-Dist: tenacity>=9.0.0
21
20
  Requires-Dist: msgspec>=0.20.0
21
+ Requires-Dist: headroom-ai>=0.4.6
22
22
  Dynamic: license-file
23
23
 
24
24
  # oy-cli
25
25
 
26
26
  [![PyPI](https://img.shields.io/pypi/v/oy-cli)](https://pypi.org/project/oy-cli/)
27
27
 
28
- **Tiny AI coding assistant for your shell.** Reads files, runs commands, makes precise edits, and stays intentionally small.
28
+ **AI coding assistant for your shell.** Reads files, searches content, and runs commands.
29
29
 
30
30
  ```bash
31
31
  uv tool install oy-cli
32
32
  oy "add docstrings to public functions"
33
33
  ```
34
34
 
35
- Note: `oy` also supports a Copilot-compatible shim via `OY_SHIM=copilot` or `copilot:model` selection where available.
36
-
37
35
  ## Examples
38
36
 
39
37
  ```bash
40
38
  # Basic usage
41
- oy "read the main module and suggest improvements"
39
+ oy "inspect the main module and suggest improvements"
42
40
 
43
41
  # Work in a specific directory
44
42
  OY_ROOT=./my-project oy "fix the failing tests"
@@ -63,29 +61,29 @@ oy --help # Show all commands
63
61
 
64
62
  ## Why This Exists
65
63
 
66
- Most AI coding tools are large, complex, or lock you into a single provider. `oy` is deliberately small, easy to audit, and built around a narrow tool surface.
64
+ `oy` is small, auditable, and built around a narrow tool surface.
67
65
 
68
66
  **Design goals:** small auditable codebase, minimal tool surface,
69
67
  OpenAI-completions-focused CLI loop, multiple backends behind shims,
70
- fresh session each run, and explicit checkpoints when needed.
68
+ new session each run, and explicit checkpoints when needed.
71
69
 
72
70
  ## System Prompts
73
71
 
74
- The system prompt is intentionally short. Tool semantics live with the tool definitions; the system prompt focuses on operating rules and judgment:
72
+ The system prompt is short. Tool semantics live with the tool definitions; the system prompt focuses on operating rules and judgment:
75
73
 
76
74
  ### Base Prompt
77
75
 
78
76
  ```markdown
79
- You are oy, a tiny coding cli with tools.
80
- Work by inspecting first, then making explicit changes. Prefer simple auditable solutions.
81
- Keep going until done or genuinely blocked; if blocked, say what you tried and next steps.
82
- Use grugbrain-style simplicity for complexity, OWASP-minded judgment for security, and performance-aware judgment to avoid obvious waste.
77
+ You are oy, a coding cli with tools.
78
+ Inspect before editing with `read` for file content, `search` for regex matches, and `list` for path discovery. For existing code changes, prefer syntax-aware edits via `ast-grep` run through `bash`. Keep edits small, auditable, and verified with `read`, `git diff`, and batch independent tool calls.
79
+ Keep going until done or blocked; if blocked, say what you tried and next steps.
80
+ Use grugbrain.dev approach for maintainability/simplicity, OWASP-minded judgment for security, and performance-aware programming (Computer, Enhance!).
83
81
  ```
84
82
 
85
83
  ### Interactive Appendix
86
84
 
87
85
  ```markdown
88
- Use ask only when significant clarification or direction is needed.
86
+ Use ask only when clarification or direction is needed.
89
87
  ```
90
88
 
91
89
  ### Non-Interactive Appendix
@@ -96,20 +94,21 @@ Non-interactive mode: do not pause for approval.
96
94
 
97
95
  ## Tools
98
96
 
99
- Each tool description is passed directly to the model. These are the exact descriptions:
97
+ Each tool description is passed directly to the model:
100
98
 
101
99
  | Tool | Description |
102
100
  |------|-------------|
103
- | `list` | List a directory. Use this first on unfamiliar trees. Returns sorted entries, one per line, with / for directories. |
104
- | `read` | Read a file or directory. Use before editing. Files return line-numbered text; directories fall back to list. Use offset/limit for large files. |
105
- | `apply` | Edit files inside the workspace. Operations: replace, write, move, delete. Read first and keep edits precise. |
106
- | `bash` | Run shell commands for tests, builds, git, and scripts. Do not use for routine file inspection. Returns stdout and stderr together. |
107
- | `grep` | Search file contents by text or regex. Use file_glob to narrow by filename pattern. Returns matching lines with file and line numbers. |
108
- | `glob` | Find files by name pattern like '*.py' or 'src/**/*.js'. Use when you know the path shape. Supports *, ?, and **. |
109
- | `httpx` | Fetch web pages or APIs over HTTP(S). Presets: page, json, post_json. Use json_path to extract nested fields. Sensitive headers are redacted. |
110
- | `ask` | Ask the user a question in interactive runs. Use for significant ambiguity or decisions. Provide choices when useful. |
101
+ | `list` | List paths by calling `Path.glob(path)`. Defaults to `path: "*"`. Use `src/*` or `src/**/*.py` exactly like pathlib glob patterns. Returns sorted entries, one per line, with / for directories. |
102
+ | `read` | Read a file or directory. Files return line-numbered text. Directories return sorted entries, one per line, with / for directories. Use `offset` and `limit` for large files. |
103
+ | `bash` | Shell commands are easy to run. For edits, prefer `ast-grep` for precise search/replace, `scc` for code-count analysis, and `xh` for web/API interaction; pipe to `rg` or `yq` for filtering when useful. These tools are effective for their niches, guaranteed to be available during an `oy` run, and their current usage docs can be checked with `--help`. For inspection, prefer the `search` tool. Returns structured results with `command`, `exit_code`, `ok`, `output_format`, `output`, and `truncated`. JSON output is parsed when possible. |
104
+ | `search` | Search with ripgrep JSON output. Takes `pattern` and `path`, then passes any extra ripgrep flags from `args`, for example `pattern: 'needle', path: 'src', args: ['--glob', '*.py', '-i']`. `limit` only limits displayed results after ripgrep runs. |
105
+ | `ask` | Ask the user a question in interactive runs. Use for ambiguity or decisions. Provide choices. |
106
+
107
+ **Output truncation:** tool output is clipped to preserve context window; `bash` summarizes output into a single `output` field and marks truncation with one `truncated` flag. When clipped, narrow the next query or use `search` with a tighter `path` instead of re-running broad inspection.
108
+
109
+ **Conversation compaction:** interactive chat compresses prepared context with [Headroom](https://github.com/chopratejas/headroom) before each model request, then falls back to omitting the oldest messages if the transcript still does not fit.
111
110
 
112
- **Output truncation:** tool output is clipped to preserve context window; `bash` keeps both head and tail. When clipped, narrow the next query.
111
+ **Parallel tool calls:** `oy` can execute multiple tool calls returned in a single assistant turn. Explicit provider flags for parallel tool calls are only sent where the upstream API supports them directly today; other providers rely on their native tool-calling behavior.
113
112
 
114
113
  ## Audit Command
115
114
 
@@ -119,13 +118,14 @@ Each tool description is passed directly to the model. These are the exact descr
119
118
 
120
119
  ```markdown
121
120
  Audit the repo for security, unnecessary complexity, and major
122
- obvious performance issues, preserving project and human context.
121
+ performance issues, preserving project and human context.
123
122
  First read key markdown docs, then refresh or generate an audit
124
123
  header at the top of ISSUES.md that includes the current date,
125
- the latest Git commit reference, and a concise codebase summary
126
- using tools like `scc` or `tokei`. Next, fetch the current OWASP
124
+ the latest Git commit reference, and a codebase summary
125
+ using tools like `scc`. Next, fetch the current OWASP
127
126
  ASVS (or MASVS if more relevant) and grugbrain.dev guidelines
128
- using httpx, inspect the codebase against these, and write or
127
+ using `bash` with `xh` (pipe to `rg` or `yq` if useful),
128
+ inspect the codebase against these, and write or
129
129
  merge prioritised findings (max 10-15) into the ISSUES.md file.
130
130
  Ensure each finding is formatted to include its location, category
131
131
  (security, complexity, or performance), standard reference, a clear
@@ -146,7 +146,7 @@ OY_ROOT=./src oy audit # Audit specific directory
146
146
  | Variable | Purpose |
147
147
  |----------|---------|
148
148
  | `OY_MODEL` | Override model for this session (bare name or `shim:model`) |
149
- | `OY_SHIM` | Force a specific shim: `openai`, `codex`, `gemini`, `claude`, `bedrock`, or `bedrock-mantle` |
149
+ | `OY_SHIM` | Force a specific shim: `openai`, `codex`, `gemini`, `claude`, `copilot`, `bedrock`, or `bedrock-mantle` |
150
150
  | `OY_NON_INTERACTIVE` | Set to `1` to disable checkpoints |
151
151
  | `OY_ROOT` | Run against different workspace |
152
152
  | `OY_SYSTEM_FILE` | Append extra system instructions |
@@ -165,16 +165,17 @@ On first run, if no model is configured, `oy` prompts you to pick one from
165
165
  the available backends. Set `OY_MODEL`, `OY_SHIM`, or save a config with
166
166
  `oy model` to pin behavior.
167
167
 
168
- **Recommended model:** From testing, `glm-5` offers the best balance of
169
- intelligence, cost, and tool-use ability. `kimi-k2.5` is another strong option.
168
+ **Model notes:** From testing, `glm-5` balances intelligence,
169
+ cost, and tool-use ability. `kimi-k2.5` is another option.
170
170
  The [Artificial Analysis Comparison of Open Source Models](https://artificialanalysis.ai/models/open-source)
171
- is a good reference.
171
+ is a reference.
172
172
 
173
173
  ## Requirements
174
174
 
175
175
  - Python 3.14+
176
176
  - `bash`
177
- - (Optional) `rg` (ripgrep) for faster search
177
+ - `mise` installed and activated in the shell before launching `oy`
178
+ - (Optional helper CLIs; `oy` auto-installs them on demand via `mise`): `rg` (ripgrep), `ast-grep`, `scc`, `xh`, `yq`
178
179
  - OpenAI API key or Codex local auth **OR** Gemini CLI OAuth credentials
179
180
  (`~/.gemini/oauth_creds.json`) **OR** Claude Code local auth **OR**
180
181
  AWS CLI configured for Bedrock
@@ -199,10 +200,10 @@ export OPENAI_BASE_URL=https://your-endpoint.example/v1
199
200
  export OPENAI_API_KEY=...
200
201
  ```
201
202
 
202
- Gemini, Claude, Codex (OpenAI) creds should be automatically introspected
203
+ Gemini, Claude, Copilot, and Codex (OpenAI) creds are introspected
203
204
  and used, if creds are available `oy model` will show them in the model list.
204
205
 
205
- **AWS Bedrock (automatic):** Uses your default AWS profile/region. Supports auto-refresh of stale SSO sessions.
206
+ **AWS Bedrock:** Uses your default AWS profile/region. Supports auto-refresh of stale SSO sessions.
206
207
  ```bash
207
208
  export AWS_PROFILE=my-profile
208
209
  export AWS_REGION=us-west-2
@@ -218,6 +219,10 @@ ensure your profile has `bedrock:InvokeModel` permission.
218
219
 
219
220
  **"AWS SSO session is stale"** -> Run `aws sso login --use-device-code --no-browser`.
220
221
 
222
+ **"Missing helper tool"** -> Install or activate `mise`, then rerun `oy`; `oy` assumes a working `mise` shell activation and auto-installs missing helper CLIs together through `mise`.
223
+
224
+ **"`mise` is required; install and activate `mise` before running `oy`."** -> Install `mise`, activate it in your shell, then relaunch `oy`.
225
+
221
226
  ## Security
222
227
 
223
228
  `oy` can run shell commands and modify files with your permissions. Treat it like any other local automation tool.
@@ -228,9 +233,7 @@ Recommended:
228
233
  - avoid exposing long-lived secrets in the environment
229
234
  - review generated changes before shipping
230
235
 
231
- **Automatic protections:** workspace-bound file access, structured edits
232
- through `apply`, sensitive header redaction in `httpx`, and native boto3
233
- credential resolution for Bedrock.
236
+ **Protections:** workspace-bound file access for built-in file tools and native boto3 credential resolution for Bedrock.
234
237
 
235
238
  ## Links
236
239
 
@@ -2,20 +2,18 @@
2
2
 
3
3
  [![PyPI](https://img.shields.io/pypi/v/oy-cli)](https://pypi.org/project/oy-cli/)
4
4
 
5
- **Tiny AI coding assistant for your shell.** Reads files, runs commands, makes precise edits, and stays intentionally small.
5
+ **AI coding assistant for your shell.** Reads files, searches content, and runs commands.
6
6
 
7
7
  ```bash
8
8
  uv tool install oy-cli
9
9
  oy "add docstrings to public functions"
10
10
  ```
11
11
 
12
- Note: `oy` also supports a Copilot-compatible shim via `OY_SHIM=copilot` or `copilot:model` selection where available.
13
-
14
12
  ## Examples
15
13
 
16
14
  ```bash
17
15
  # Basic usage
18
- oy "read the main module and suggest improvements"
16
+ oy "inspect the main module and suggest improvements"
19
17
 
20
18
  # Work in a specific directory
21
19
  OY_ROOT=./my-project oy "fix the failing tests"
@@ -40,29 +38,29 @@ oy --help # Show all commands
40
38
 
41
39
  ## Why This Exists
42
40
 
43
- Most AI coding tools are large, complex, or lock you into a single provider. `oy` is deliberately small, easy to audit, and built around a narrow tool surface.
41
+ `oy` is small, auditable, and built around a narrow tool surface.
44
42
 
45
43
  **Design goals:** small auditable codebase, minimal tool surface,
46
44
  OpenAI-completions-focused CLI loop, multiple backends behind shims,
47
- fresh session each run, and explicit checkpoints when needed.
45
+ new session each run, and explicit checkpoints when needed.
48
46
 
49
47
  ## System Prompts
50
48
 
51
- The system prompt is intentionally short. Tool semantics live with the tool definitions; the system prompt focuses on operating rules and judgment:
49
+ The system prompt is short. Tool semantics live with the tool definitions; the system prompt focuses on operating rules and judgment:
52
50
 
53
51
  ### Base Prompt
54
52
 
55
53
  ```markdown
56
- You are oy, a tiny coding cli with tools.
57
- Work by inspecting first, then making explicit changes. Prefer simple auditable solutions.
58
- Keep going until done or genuinely blocked; if blocked, say what you tried and next steps.
59
- Use grugbrain-style simplicity for complexity, OWASP-minded judgment for security, and performance-aware judgment to avoid obvious waste.
54
+ You are oy, a coding cli with tools.
55
+ Inspect before editing with `read` for file content, `search` for regex matches, and `list` for path discovery. For existing code changes, prefer syntax-aware edits via `ast-grep` run through `bash`. Keep edits small, auditable, and verified with `read`, `git diff`, and batch independent tool calls.
56
+ Keep going until done or blocked; if blocked, say what you tried and next steps.
57
+ Use grugbrain.dev approach for maintainability/simplicity, OWASP-minded judgment for security, and performance-aware programming (Computer, Enhance!).
60
58
  ```
61
59
 
62
60
  ### Interactive Appendix
63
61
 
64
62
  ```markdown
65
- Use ask only when significant clarification or direction is needed.
63
+ Use ask only when clarification or direction is needed.
66
64
  ```
67
65
 
68
66
  ### Non-Interactive Appendix
@@ -73,20 +71,21 @@ Non-interactive mode: do not pause for approval.
73
71
 
74
72
  ## Tools
75
73
 
76
- Each tool description is passed directly to the model. These are the exact descriptions:
74
+ Each tool description is passed directly to the model:
77
75
 
78
76
  | Tool | Description |
79
77
  |------|-------------|
80
- | `list` | List a directory. Use this first on unfamiliar trees. Returns sorted entries, one per line, with / for directories. |
81
- | `read` | Read a file or directory. Use before editing. Files return line-numbered text; directories fall back to list. Use offset/limit for large files. |
82
- | `apply` | Edit files inside the workspace. Operations: replace, write, move, delete. Read first and keep edits precise. |
83
- | `bash` | Run shell commands for tests, builds, git, and scripts. Do not use for routine file inspection. Returns stdout and stderr together. |
84
- | `grep` | Search file contents by text or regex. Use file_glob to narrow by filename pattern. Returns matching lines with file and line numbers. |
85
- | `glob` | Find files by name pattern like '*.py' or 'src/**/*.js'. Use when you know the path shape. Supports *, ?, and **. |
86
- | `httpx` | Fetch web pages or APIs over HTTP(S). Presets: page, json, post_json. Use json_path to extract nested fields. Sensitive headers are redacted. |
87
- | `ask` | Ask the user a question in interactive runs. Use for significant ambiguity or decisions. Provide choices when useful. |
78
+ | `list` | List paths by calling `Path.glob(path)`. Defaults to `path: "*"`. Use `src/*` or `src/**/*.py` exactly like pathlib glob patterns. Returns sorted entries, one per line, with / for directories. |
79
+ | `read` | Read a file or directory. Files return line-numbered text. Directories return sorted entries, one per line, with / for directories. Use `offset` and `limit` for large files. |
80
+ | `bash` | Shell commands are easy to run. For edits, prefer `ast-grep` for precise search/replace, `scc` for code-count analysis, and `xh` for web/API interaction; pipe to `rg` or `yq` for filtering when useful. These tools are effective for their niches, guaranteed to be available during an `oy` run, and their current usage docs can be checked with `--help`. For inspection, prefer the `search` tool. Returns structured results with `command`, `exit_code`, `ok`, `output_format`, `output`, and `truncated`. JSON output is parsed when possible. |
81
+ | `search` | Search with ripgrep JSON output. Takes `pattern` and `path`, then passes any extra ripgrep flags from `args`, for example `pattern: 'needle', path: 'src', args: ['--glob', '*.py', '-i']`. `limit` only limits displayed results after ripgrep runs. |
82
+ | `ask` | Ask the user a question in interactive runs. Use for ambiguity or decisions. Provide choices. |
83
+
84
+ **Output truncation:** tool output is clipped to preserve context window; `bash` summarizes output into a single `output` field and marks truncation with one `truncated` flag. When clipped, narrow the next query or use `search` with a tighter `path` instead of re-running broad inspection.
85
+
86
+ **Conversation compaction:** interactive chat compresses prepared context with [Headroom](https://github.com/chopratejas/headroom) before each model request, then falls back to omitting the oldest messages if the transcript still does not fit.
88
87
 
89
- **Output truncation:** tool output is clipped to preserve context window; `bash` keeps both head and tail. When clipped, narrow the next query.
88
+ **Parallel tool calls:** `oy` can execute multiple tool calls returned in a single assistant turn. Explicit provider flags for parallel tool calls are only sent where the upstream API supports them directly today; other providers rely on their native tool-calling behavior.
90
89
 
91
90
  ## Audit Command
92
91
 
@@ -96,13 +95,14 @@ Each tool description is passed directly to the model. These are the exact descr
96
95
 
97
96
  ```markdown
98
97
  Audit the repo for security, unnecessary complexity, and major
99
- obvious performance issues, preserving project and human context.
98
+ performance issues, preserving project and human context.
100
99
  First read key markdown docs, then refresh or generate an audit
101
100
  header at the top of ISSUES.md that includes the current date,
102
- the latest Git commit reference, and a concise codebase summary
103
- using tools like `scc` or `tokei`. Next, fetch the current OWASP
101
+ the latest Git commit reference, and a codebase summary
102
+ using tools like `scc`. Next, fetch the current OWASP
104
103
  ASVS (or MASVS if more relevant) and grugbrain.dev guidelines
105
- using httpx, inspect the codebase against these, and write or
104
+ using `bash` with `xh` (pipe to `rg` or `yq` if useful),
105
+ inspect the codebase against these, and write or
106
106
  merge prioritised findings (max 10-15) into the ISSUES.md file.
107
107
  Ensure each finding is formatted to include its location, category
108
108
  (security, complexity, or performance), standard reference, a clear
@@ -123,7 +123,7 @@ OY_ROOT=./src oy audit # Audit specific directory
123
123
  | Variable | Purpose |
124
124
  |----------|---------|
125
125
  | `OY_MODEL` | Override model for this session (bare name or `shim:model`) |
126
- | `OY_SHIM` | Force a specific shim: `openai`, `codex`, `gemini`, `claude`, `bedrock`, or `bedrock-mantle` |
126
+ | `OY_SHIM` | Force a specific shim: `openai`, `codex`, `gemini`, `claude`, `copilot`, `bedrock`, or `bedrock-mantle` |
127
127
  | `OY_NON_INTERACTIVE` | Set to `1` to disable checkpoints |
128
128
  | `OY_ROOT` | Run against different workspace |
129
129
  | `OY_SYSTEM_FILE` | Append extra system instructions |
@@ -142,16 +142,17 @@ On first run, if no model is configured, `oy` prompts you to pick one from
142
142
  the available backends. Set `OY_MODEL`, `OY_SHIM`, or save a config with
143
143
  `oy model` to pin behavior.
144
144
 
145
- **Recommended model:** From testing, `glm-5` offers the best balance of
146
- intelligence, cost, and tool-use ability. `kimi-k2.5` is another strong option.
145
+ **Model notes:** From testing, `glm-5` balances intelligence,
146
+ cost, and tool-use ability. `kimi-k2.5` is another option.
147
147
  The [Artificial Analysis Comparison of Open Source Models](https://artificialanalysis.ai/models/open-source)
148
- is a good reference.
148
+ is a reference.
149
149
 
150
150
  ## Requirements
151
151
 
152
152
  - Python 3.14+
153
153
  - `bash`
154
- - (Optional) `rg` (ripgrep) for faster search
154
+ - `mise` installed and activated in the shell before launching `oy`
155
+ - (Optional helper CLIs; `oy` auto-installs them on demand via `mise`): `rg` (ripgrep), `ast-grep`, `scc`, `xh`, `yq`
155
156
  - OpenAI API key or Codex local auth **OR** Gemini CLI OAuth credentials
156
157
  (`~/.gemini/oauth_creds.json`) **OR** Claude Code local auth **OR**
157
158
  AWS CLI configured for Bedrock
@@ -176,10 +177,10 @@ export OPENAI_BASE_URL=https://your-endpoint.example/v1
176
177
  export OPENAI_API_KEY=...
177
178
  ```
178
179
 
179
- Gemini, Claude, Codex (OpenAI) creds should be automatically introspected
180
+ Gemini, Claude, Copilot, and Codex (OpenAI) creds are introspected
180
181
  and used, if creds are available `oy model` will show them in the model list.
181
182
 
182
- **AWS Bedrock (automatic):** Uses your default AWS profile/region. Supports auto-refresh of stale SSO sessions.
183
+ **AWS Bedrock:** Uses your default AWS profile/region. Supports auto-refresh of stale SSO sessions.
183
184
  ```bash
184
185
  export AWS_PROFILE=my-profile
185
186
  export AWS_REGION=us-west-2
@@ -195,6 +196,10 @@ ensure your profile has `bedrock:InvokeModel` permission.
195
196
 
196
197
  **"AWS SSO session is stale"** -> Run `aws sso login --use-device-code --no-browser`.
197
198
 
199
+ **"Missing helper tool"** -> Install or activate `mise`, then rerun `oy`; `oy` assumes a working `mise` shell activation and auto-installs missing helper CLIs together through `mise`.
200
+
201
+ **"`mise` is required; install and activate `mise` before running `oy`."** -> Install `mise`, activate it in your shell, then relaunch `oy`.
202
+
198
203
  ## Security
199
204
 
200
205
  `oy` can run shell commands and modify files with your permissions. Treat it like any other local automation tool.
@@ -205,9 +210,7 @@ Recommended:
205
210
  - avoid exposing long-lived secrets in the environment
206
211
  - review generated changes before shipping
207
212
 
208
- **Automatic protections:** workspace-bound file access, structured edits
209
- through `apply`, sensitive header redaction in `httpx`, and native boto3
210
- credential resolution for Bedrock.
213
+ **Protections:** workspace-bound file access for built-in file tools and native boto3 credential resolution for Bedrock.
211
214
 
212
215
  ## Links
213
216
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: oy-cli
3
- Version: 0.3.4
3
+ Version: 0.4.0
4
4
  Summary: Tiny local coding CLI with a small tool surface
5
5
  Author: oy-cli contributors
6
6
  License-Expression: Apache-2.0
@@ -13,32 +13,30 @@ License-File: LICENSE
13
13
  Requires-Dist: boto3>=1.35.0
14
14
  Requires-Dist: defopt>=7.0.0
15
15
  Requires-Dist: httpx>=0.28.1
16
- Requires-Dist: markdownify>=1.2.0
17
16
  Requires-Dist: openai>=1.68.0
18
17
  Requires-Dist: rich>=14.3.0
19
18
  Requires-Dist: tiktoken>=0.7.0
20
19
  Requires-Dist: tenacity>=9.0.0
21
20
  Requires-Dist: msgspec>=0.20.0
21
+ Requires-Dist: headroom-ai>=0.4.6
22
22
  Dynamic: license-file
23
23
 
24
24
  # oy-cli
25
25
 
26
26
  [![PyPI](https://img.shields.io/pypi/v/oy-cli)](https://pypi.org/project/oy-cli/)
27
27
 
28
- **Tiny AI coding assistant for your shell.** Reads files, runs commands, makes precise edits, and stays intentionally small.
28
+ **AI coding assistant for your shell.** Reads files, searches content, and runs commands.
29
29
 
30
30
  ```bash
31
31
  uv tool install oy-cli
32
32
  oy "add docstrings to public functions"
33
33
  ```
34
34
 
35
- Note: `oy` also supports a Copilot-compatible shim via `OY_SHIM=copilot` or `copilot:model` selection where available.
36
-
37
35
  ## Examples
38
36
 
39
37
  ```bash
40
38
  # Basic usage
41
- oy "read the main module and suggest improvements"
39
+ oy "inspect the main module and suggest improvements"
42
40
 
43
41
  # Work in a specific directory
44
42
  OY_ROOT=./my-project oy "fix the failing tests"
@@ -63,29 +61,29 @@ oy --help # Show all commands
63
61
 
64
62
  ## Why This Exists
65
63
 
66
- Most AI coding tools are large, complex, or lock you into a single provider. `oy` is deliberately small, easy to audit, and built around a narrow tool surface.
64
+ `oy` is small, auditable, and built around a narrow tool surface.
67
65
 
68
66
  **Design goals:** small auditable codebase, minimal tool surface,
69
67
  OpenAI-completions-focused CLI loop, multiple backends behind shims,
70
- fresh session each run, and explicit checkpoints when needed.
68
+ new session each run, and explicit checkpoints when needed.
71
69
 
72
70
  ## System Prompts
73
71
 
74
- The system prompt is intentionally short. Tool semantics live with the tool definitions; the system prompt focuses on operating rules and judgment:
72
+ The system prompt is short. Tool semantics live with the tool definitions; the system prompt focuses on operating rules and judgment:
75
73
 
76
74
  ### Base Prompt
77
75
 
78
76
  ```markdown
79
- You are oy, a tiny coding cli with tools.
80
- Work by inspecting first, then making explicit changes. Prefer simple auditable solutions.
81
- Keep going until done or genuinely blocked; if blocked, say what you tried and next steps.
82
- Use grugbrain-style simplicity for complexity, OWASP-minded judgment for security, and performance-aware judgment to avoid obvious waste.
77
+ You are oy, a coding cli with tools.
78
+ Inspect before editing with `read` for file content, `search` for regex matches, and `list` for path discovery. For existing code changes, prefer syntax-aware edits via `ast-grep` run through `bash`. Keep edits small, auditable, and verified with `read`, `git diff`, and batch independent tool calls.
79
+ Keep going until done or blocked; if blocked, say what you tried and next steps.
80
+ Use grugbrain.dev approach for maintainability/simplicity, OWASP-minded judgment for security, and performance-aware programming (Computer, Enhance!).
83
81
  ```
84
82
 
85
83
  ### Interactive Appendix
86
84
 
87
85
  ```markdown
88
- Use ask only when significant clarification or direction is needed.
86
+ Use ask only when clarification or direction is needed.
89
87
  ```
90
88
 
91
89
  ### Non-Interactive Appendix
@@ -96,20 +94,21 @@ Non-interactive mode: do not pause for approval.
96
94
 
97
95
  ## Tools
98
96
 
99
- Each tool description is passed directly to the model. These are the exact descriptions:
97
+ Each tool description is passed directly to the model:
100
98
 
101
99
  | Tool | Description |
102
100
  |------|-------------|
103
- | `list` | List a directory. Use this first on unfamiliar trees. Returns sorted entries, one per line, with / for directories. |
104
- | `read` | Read a file or directory. Use before editing. Files return line-numbered text; directories fall back to list. Use offset/limit for large files. |
105
- | `apply` | Edit files inside the workspace. Operations: replace, write, move, delete. Read first and keep edits precise. |
106
- | `bash` | Run shell commands for tests, builds, git, and scripts. Do not use for routine file inspection. Returns stdout and stderr together. |
107
- | `grep` | Search file contents by text or regex. Use file_glob to narrow by filename pattern. Returns matching lines with file and line numbers. |
108
- | `glob` | Find files by name pattern like '*.py' or 'src/**/*.js'. Use when you know the path shape. Supports *, ?, and **. |
109
- | `httpx` | Fetch web pages or APIs over HTTP(S). Presets: page, json, post_json. Use json_path to extract nested fields. Sensitive headers are redacted. |
110
- | `ask` | Ask the user a question in interactive runs. Use for significant ambiguity or decisions. Provide choices when useful. |
101
+ | `list` | List paths by calling `Path.glob(path)`. Defaults to `path: "*"`. Use `src/*` or `src/**/*.py` exactly like pathlib glob patterns. Returns sorted entries, one per line, with / for directories. |
102
+ | `read` | Read a file or directory. Files return line-numbered text. Directories return sorted entries, one per line, with / for directories. Use `offset` and `limit` for large files. |
103
+ | `bash` | Shell commands are easy to run. For edits, prefer `ast-grep` for precise search/replace, `scc` for code-count analysis, and `xh` for web/API interaction; pipe to `rg` or `yq` for filtering when useful. These tools are effective for their niches, guaranteed to be available during an `oy` run, and their current usage docs can be checked with `--help`. For inspection, prefer the `search` tool. Returns structured results with `command`, `exit_code`, `ok`, `output_format`, `output`, and `truncated`. JSON output is parsed when possible. |
104
+ | `search` | Search with ripgrep JSON output. Takes `pattern` and `path`, then passes any extra ripgrep flags from `args`, for example `pattern: 'needle', path: 'src', args: ['--glob', '*.py', '-i']`. `limit` only limits displayed results after ripgrep runs. |
105
+ | `ask` | Ask the user a question in interactive runs. Use for ambiguity or decisions. Provide choices. |
106
+
107
+ **Output truncation:** tool output is clipped to preserve context window; `bash` summarizes output into a single `output` field and marks truncation with one `truncated` flag. When clipped, narrow the next query or use `search` with a tighter `path` instead of re-running broad inspection.
108
+
109
+ **Conversation compaction:** interactive chat compresses prepared context with [Headroom](https://github.com/chopratejas/headroom) before each model request, then falls back to omitting the oldest messages if the transcript still does not fit.
111
110
 
112
- **Output truncation:** tool output is clipped to preserve context window; `bash` keeps both head and tail. When clipped, narrow the next query.
111
+ **Parallel tool calls:** `oy` can execute multiple tool calls returned in a single assistant turn. Explicit provider flags for parallel tool calls are only sent where the upstream API supports them directly today; other providers rely on their native tool-calling behavior.
113
112
 
114
113
  ## Audit Command
115
114
 
@@ -119,13 +118,14 @@ Each tool description is passed directly to the model. These are the exact descr
119
118
 
120
119
  ```markdown
121
120
  Audit the repo for security, unnecessary complexity, and major
122
- obvious performance issues, preserving project and human context.
121
+ performance issues, preserving project and human context.
123
122
  First read key markdown docs, then refresh or generate an audit
124
123
  header at the top of ISSUES.md that includes the current date,
125
- the latest Git commit reference, and a concise codebase summary
126
- using tools like `scc` or `tokei`. Next, fetch the current OWASP
124
+ the latest Git commit reference, and a codebase summary
125
+ using tools like `scc`. Next, fetch the current OWASP
127
126
  ASVS (or MASVS if more relevant) and grugbrain.dev guidelines
128
- using httpx, inspect the codebase against these, and write or
127
+ using `bash` with `xh` (pipe to `rg` or `yq` if useful),
128
+ inspect the codebase against these, and write or
129
129
  merge prioritised findings (max 10-15) into the ISSUES.md file.
130
130
  Ensure each finding is formatted to include its location, category
131
131
  (security, complexity, or performance), standard reference, a clear
@@ -146,7 +146,7 @@ OY_ROOT=./src oy audit # Audit specific directory
146
146
  | Variable | Purpose |
147
147
  |----------|---------|
148
148
  | `OY_MODEL` | Override model for this session (bare name or `shim:model`) |
149
- | `OY_SHIM` | Force a specific shim: `openai`, `codex`, `gemini`, `claude`, `bedrock`, or `bedrock-mantle` |
149
+ | `OY_SHIM` | Force a specific shim: `openai`, `codex`, `gemini`, `claude`, `copilot`, `bedrock`, or `bedrock-mantle` |
150
150
  | `OY_NON_INTERACTIVE` | Set to `1` to disable checkpoints |
151
151
  | `OY_ROOT` | Run against different workspace |
152
152
  | `OY_SYSTEM_FILE` | Append extra system instructions |
@@ -165,16 +165,17 @@ On first run, if no model is configured, `oy` prompts you to pick one from
165
165
  the available backends. Set `OY_MODEL`, `OY_SHIM`, or save a config with
166
166
  `oy model` to pin behavior.
167
167
 
168
- **Recommended model:** From testing, `glm-5` offers the best balance of
169
- intelligence, cost, and tool-use ability. `kimi-k2.5` is another strong option.
168
+ **Model notes:** From testing, `glm-5` balances intelligence,
169
+ cost, and tool-use ability. `kimi-k2.5` is another option.
170
170
  The [Artificial Analysis Comparison of Open Source Models](https://artificialanalysis.ai/models/open-source)
171
- is a good reference.
171
+ is a reference.
172
172
 
173
173
  ## Requirements
174
174
 
175
175
  - Python 3.14+
176
176
  - `bash`
177
- - (Optional) `rg` (ripgrep) for faster search
177
+ - `mise` installed and activated in the shell before launching `oy`
178
+ - (Optional helper CLIs; `oy` auto-installs them on demand via `mise`): `rg` (ripgrep), `ast-grep`, `scc`, `xh`, `yq`
178
179
  - OpenAI API key or Codex local auth **OR** Gemini CLI OAuth credentials
179
180
  (`~/.gemini/oauth_creds.json`) **OR** Claude Code local auth **OR**
180
181
  AWS CLI configured for Bedrock
@@ -199,10 +200,10 @@ export OPENAI_BASE_URL=https://your-endpoint.example/v1
199
200
  export OPENAI_API_KEY=...
200
201
  ```
201
202
 
202
- Gemini, Claude, Codex (OpenAI) creds should be automatically introspected
203
+ Gemini, Claude, Copilot, and Codex (OpenAI) creds are introspected
203
204
  and used, if creds are available `oy model` will show them in the model list.
204
205
 
205
- **AWS Bedrock (automatic):** Uses your default AWS profile/region. Supports auto-refresh of stale SSO sessions.
206
+ **AWS Bedrock:** Uses your default AWS profile/region. Supports auto-refresh of stale SSO sessions.
206
207
  ```bash
207
208
  export AWS_PROFILE=my-profile
208
209
  export AWS_REGION=us-west-2
@@ -218,6 +219,10 @@ ensure your profile has `bedrock:InvokeModel` permission.
218
219
 
219
220
  **"AWS SSO session is stale"** -> Run `aws sso login --use-device-code --no-browser`.
220
221
 
222
+ **"Missing helper tool"** -> Install or activate `mise`, then rerun `oy`; `oy` assumes a working `mise` shell activation and auto-installs missing helper CLIs together through `mise`.
223
+
224
+ **"`mise` is required; install and activate `mise` before running `oy`."** -> Install `mise`, activate it in your shell, then relaunch `oy`.
225
+
221
226
  ## Security
222
227
 
223
228
  `oy` can run shell commands and modify files with your permissions. Treat it like any other local automation tool.
@@ -228,9 +233,7 @@ Recommended:
228
233
  - avoid exposing long-lived secrets in the environment
229
234
  - review generated changes before shipping
230
235
 
231
- **Automatic protections:** workspace-bound file access, structured edits
232
- through `apply`, sensitive header redaction in `httpx`, and native boto3
233
- credential resolution for Bedrock.
236
+ **Protections:** workspace-bound file access for built-in file tools and native boto3 credential resolution for Bedrock.
234
237
 
235
238
  ## Links
236
239
 
@@ -1,6 +1,7 @@
1
1
  LICENSE
2
2
  README.md
3
3
  oy_cli.py
4
+ providers.py
4
5
  pyproject.toml
5
6
  shim.py
6
7
  oy_cli.egg-info/PKG-INFO
@@ -9,5 +10,6 @@ oy_cli.egg-info/dependency_links.txt
9
10
  oy_cli.egg-info/entry_points.txt
10
11
  oy_cli.egg-info/requires.txt
11
12
  oy_cli.egg-info/top_level.txt
13
+ tests/test_async_cleanup.py
12
14
  tests/test_oy_cli.py
13
15
  tests/test_shim.py
@@ -1,9 +1,9 @@
1
1
  boto3>=1.35.0
2
2
  defopt>=7.0.0
3
3
  httpx>=0.28.1
4
- markdownify>=1.2.0
5
4
  openai>=1.68.0
6
5
  rich>=14.3.0
7
6
  tiktoken>=0.7.0
8
7
  tenacity>=9.0.0
9
8
  msgspec>=0.20.0
9
+ headroom-ai>=0.4.6
@@ -1,2 +1,3 @@
1
1
  oy_cli
2
+ providers
2
3
  shim