cli-agent-yzf 0.6.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 (29) hide show
  1. cli_agent_yzf-0.6.0/PKG-INFO +161 -0
  2. cli_agent_yzf-0.6.0/README.md +143 -0
  3. cli_agent_yzf-0.6.0/pyproject.toml +81 -0
  4. cli_agent_yzf-0.6.0/pyproject.toml.orig +66 -0
  5. cli_agent_yzf-0.6.0/src/cli_agent/__init__.py +3 -0
  6. cli_agent_yzf-0.6.0/src/cli_agent/__main__.py +8 -0
  7. cli_agent_yzf-0.6.0/src/cli_agent/agent.py +388 -0
  8. cli_agent_yzf-0.6.0/src/cli_agent/checkpoint.py +345 -0
  9. cli_agent_yzf-0.6.0/src/cli_agent/cli.py +755 -0
  10. cli_agent_yzf-0.6.0/src/cli_agent/config.py +173 -0
  11. cli_agent_yzf-0.6.0/src/cli_agent/log.py +39 -0
  12. cli_agent_yzf-0.6.0/src/cli_agent/mcp.py +306 -0
  13. cli_agent_yzf-0.6.0/src/cli_agent/messages.py +127 -0
  14. cli_agent_yzf-0.6.0/src/cli_agent/permissions.py +294 -0
  15. cli_agent_yzf-0.6.0/src/cli_agent/prompt.py +79 -0
  16. cli_agent_yzf-0.6.0/src/cli_agent/providers/__init__.py +0 -0
  17. cli_agent_yzf-0.6.0/src/cli_agent/providers/anthropic.py +283 -0
  18. cli_agent_yzf-0.6.0/src/cli_agent/providers/base.py +116 -0
  19. cli_agent_yzf-0.6.0/src/cli_agent/providers/fake.py +81 -0
  20. cli_agent_yzf-0.6.0/src/cli_agent/providers/openai.py +301 -0
  21. cli_agent_yzf-0.6.0/src/cli_agent/py.typed +0 -0
  22. cli_agent_yzf-0.6.0/src/cli_agent/sandbox.py +117 -0
  23. cli_agent_yzf-0.6.0/src/cli_agent/session.py +274 -0
  24. cli_agent_yzf-0.6.0/src/cli_agent/tools/__init__.py +13 -0
  25. cli_agent_yzf-0.6.0/src/cli_agent/tools/base.py +118 -0
  26. cli_agent_yzf-0.6.0/src/cli_agent/tools/files.py +522 -0
  27. cli_agent_yzf-0.6.0/src/cli_agent/tools/shell.py +224 -0
  28. cli_agent_yzf-0.6.0/src/cli_agent/ui.py +283 -0
  29. cli_agent_yzf-0.6.0/src/cli_agent/workspace.py +59 -0
@@ -0,0 +1,161 @@
1
+ Metadata-Version: 2.4
2
+ Name: cli-agent-yzf
3
+ Version: 0.6.0
4
+ Summary: An autonomous coding agent for the terminal
5
+ Author: yezhoufan2005
6
+ Author-email: yezhoufan2005 <176495279+yezhoufan2005@users.noreply.github.com>
7
+ License-Expression: MIT
8
+ Classifier: Programming Language :: Python :: 3.11
9
+ Classifier: Programming Language :: Python :: 3.12
10
+ Classifier: Programming Language :: Python :: 3.13
11
+ Classifier: Programming Language :: Python :: 3.14
12
+ Classifier: Environment :: Console
13
+ Classifier: Operating System :: POSIX :: Linux
14
+ Classifier: Operating System :: MacOS
15
+ Requires-Dist: httpx==0.28.1
16
+ Requires-Python: >=3.11
17
+ Description-Content-Type: text/markdown
18
+
19
+ # cli-agent
20
+
21
+ An autonomous coding agent for your terminal. Give it a task in plain language; it reads your code, edits files, runs commands, and checks its own work — inside one workspace directory, under a permission policy you control.
22
+
23
+ Status: early (0.x). See [docs/progress.md](docs/progress.md) for what is verified and what is not.
24
+
25
+ ## Install
26
+
27
+ Requires Python 3.11+ and [uv](https://docs.astral.sh/uv/) (or pip).
28
+
29
+ ```bash
30
+ uv tool install cli-agent-yzf # from PyPI; installs the `cli-agent` command
31
+ # or a GitHub release wheel:
32
+ uv tool install https://github.com/yezhoufan2005/CLI-Agent/releases/download/v0.6.0/cli_agent_yzf-0.6.0-py3-none-any.whl
33
+ # or the latest main:
34
+ uv tool install git+https://github.com/yezhoufan2005/CLI-Agent
35
+ # or, from a checkout:
36
+ uv tool install .
37
+ ```
38
+
39
+ Set credentials in the environment (never in a config file):
40
+
41
+ ```bash
42
+ export ANTHROPIC_API_KEY=sk-ant-...
43
+ # or, for an Anthropic-compatible proxy:
44
+ export ANTHROPIC_BASE_URL=https://proxy.example
45
+ export ANTHROPIC_AUTH_TOKEN=...
46
+ cli-agent doctor # checks config and makes one tiny model call
47
+ ```
48
+
49
+ Any OpenAI-compatible Chat Completions endpoint (OpenAI, OpenRouter, Ollama, vLLM, LiteLLM, …) also works:
50
+
51
+ ```bash
52
+ export OPENAI_API_KEY=... # optional for local servers
53
+ export OPENAI_BASE_URL=http://localhost:11434/v1 # default: https://api.openai.com/v1
54
+ cli-agent --provider openai --model qwen2.5-coder "explain src/main.py"
55
+ ```
56
+
57
+ ## Use
58
+
59
+ ```bash
60
+ cli-agent "the tests in tests/test_parser.py fail; fix them" # one task, then exit
61
+ echo "add a --verbose flag" | cli-agent --mode auto-edit # task from stdin
62
+ cli-agent # interactive session
63
+ cli-agent --continue "now update the docs" # continue last session here
64
+ cli-agent --json "summarize this repo" | jq . # JSON-lines events for scripts
65
+ cli-agent sessions # list saved sessions
66
+ cli-agent undo # revert file changes of the last prompt
67
+ ```
68
+
69
+ `cli-agent undo` (or `/undo` in a session) puts back the files the agent's file tools changed during the most recent prompt, and deletes files it created. Each further undo goes back one more prompt, up to 20. If you edited a file yourself after the agent wrote it, undo leaves that file alone. Changes made through shell commands are not tracked; undo tells you how many shell commands ran in that prompt, so check `git status` for those. The agent is instructed to change file contents only through its file tools, so most edits are covered.
70
+
71
+ Exit codes: `0` done, `1` error (model/API failure, refusal), `2` usage/config error, `3` stopped incomplete (turn limit, output-token limit, or `--max-session-tokens` budget), `130` interrupted (Ctrl-C), `129`/`143` terminated by SIGHUP/SIGTERM (the running command is killed and the session saved first). An interrupted or failed session is saved and can be resumed with `--resume ID`.
72
+
73
+ ## Permissions
74
+
75
+ | Mode | Read tools | File writes | Shell commands |
76
+ |---|---|---|---|
77
+ | `read-only` | allow | deny | deny |
78
+ | `ask` (default) | allow | ask | ask |
79
+ | `auto-edit` | allow | allow | ask |
80
+ | `auto` | allow | allow | allow |
81
+
82
+ When there is no terminal to ask on (stdin piped, `--json`), "ask" means "deny".
83
+
84
+ Rules refine the mode: `--allow 'run_shell:pytest*'`, `--deny 'run_shell:git push*'`, or `allow = [...]` / `deny = [...]` in `~/.config/cli-agent/config.toml`. Deny rules win over allow rules.
85
+
86
+ - Path rules match the path normalized relative to the workspace, so `src/../.env` is matched as `.env`.
87
+ - A shell allow glob never matches a command line that contains shell metacharacters (`; & | $ ` < > ( )`, newlines). `run_shell:pytest*` allows `pytest -q tests/`, but `pytest; curl … | sh` still asks. The same applies to harmless pipes such as `pytest -q | tail`; in a headless run the agent is told which rule nearly matched, so it can retry the plain command.
88
+ - Shell deny rules are also checked against each simple command in a line (`cd x && git push` matches `git push*`). They are best-effort, not a security boundary.
89
+ - "Always" for a shell command approves exactly that command line for the session.
90
+ - Writes under `.git/` (hooks, config) always ask, even in `auto` and `auto-edit`, unless an explicit path rule such as `write_file:.git/info/*` allows them.
91
+ - A small built-in guard blocks catastrophic shell commands (`rm -rf ~`, `mkfs`, force-push, …) in every mode.
92
+
93
+ Each shell command runs with empty stdin, a timeout (default 120 s, max 600 s), and a 50 MB output cap. When it finishes, anything it left running (`&` jobs and, on Linux, `setsid`/`nohup` escapees) is killed, so an agent cannot leave daemons behind.
94
+
95
+ ### Shell sandbox (Linux)
96
+
97
+ `--sandbox auto` (or `sandbox = "auto"` in the config file, or `CLI_AGENT_SANDBOX=auto`) runs every shell command inside [bubblewrap](https://github.com/containers/bubblewrap):
98
+ - The filesystem is read-only except for the workspace and a private `/tmp`.
99
+ - Your home directory is replaced by an empty directory, so `~/.ssh` and `~/.aws` are not visible.
100
+ - There is no network unless you set `sandbox_network = true`.
101
+ - The command runs in its own PID namespace.
102
+
103
+ `auto` falls back to unsandboxed execution with a warning when bubblewrap cannot run. `required` refuses to start in that case. Bubblewrap needs unprivileged user namespaces, so it does not work inside most Docker containers. On Ubuntu 24.04 it may need `kernel.apparmor_restrict_unprivileged_userns=0` or an AppArmor profile. The default is `off`.
104
+
105
+ File tools cannot touch paths outside the workspace (symlinks are resolved first; list/search skip symlinks). Shell commands run with your user's privileges and are **not sandboxed**: the workspace boundary applies only to file tools, and an approved command can read or change anything your user can. Credential-like environment variables (`*TOKEN*`, `*KEY*`, `*SECRET*`, `*_PASS`, `DATABASE_URL`, `SSH_AUTH_SOCK`, …) are removed from the environment of shell commands, and on Linux the agent marks itself non-dumpable so commands cannot read its environment through `/proc`. Credential *files* your user can read (e.g. `~/.aws/credentials`) remain readable to shell commands.
106
+
107
+ `AGENTS.md` / `CLAUDE.md` in the workspace root are given to the model as project conventions; they cannot change permissions.
108
+
109
+ ## Configuration
110
+
111
+ `~/.config/cli-agent/config.toml` (override with `CLI_AGENT_CONFIG` or `--config`):
112
+
113
+ ```toml
114
+ model = "claude-sonnet-4-6"
115
+ mode = "auto-edit"
116
+ allow = ["run_shell:pytest*", "run_shell:git status*", "run_shell:git diff*"]
117
+ deny = ["run_shell:git push*"]
118
+ max_turns = 50
119
+ max_session_tokens = 2000000 # optional cost cap per session (input + output tokens)
120
+ shell_timeout = 120
121
+ ```
122
+
123
+ ### MCP servers
124
+
125
+ Tools from [MCP](https://modelcontextprotocol.io) stdio servers can be added in the user config file only; a repository cannot add servers:
126
+
127
+ ```toml
128
+ [mcp_servers.fs]
129
+ command = ["npx", "-y", "@modelcontextprotocol/server-filesystem", "/path/to/dir"]
130
+ env = { SOME_SETTING = "value" } # optional; passed to the server as-is
131
+ ```
132
+
133
+ They appear to the model as `mcp__<server>__<tool>`. Every MCP tool counts as a command: it asks in `ask` and `auto-edit` mode and is denied in `read-only` mode. You can allow one with a rule such as `--allow mcp__fs__read_file`. Servers get the same scrubbed environment as shell commands, plus their configured `env`. They are not sandboxed. Only the tools part of MCP is supported; resources, prompts and sampling are not.
134
+
135
+ Precedence: defaults < config file < environment (`CLI_AGENT_PROVIDER`, `CLI_AGENT_MODEL`, `CLI_AGENT_MODE`, `ANTHROPIC_*` / `OPENAI_*`) < flags. `provider = "openai"` in the config file selects the OpenAI-compatible provider.
136
+
137
+ ## How well does it work?
138
+
139
+ Measured with real models; full method and caveats in [docs/progress.md](docs/progress.md):
140
+
141
+ | Benchmark | claude-sonnet-4-6 | claude-haiku-4-5 |
142
+ |---|---|---|
143
+ | Built-in E2E tasks (`scripts/e2e.sh`, 11 tasks) | 11/11 | 11/11 |
144
+ | Exercism Python, 30 exercises, hidden tests (`scripts/bench.py`) | 27/30 | 27/30 |
145
+ | SWE-bench Lite sympy, 2 samples of 20, Docker-free (`scripts/swebench_sympy.py`) | 29/40 | 30/40 |
146
+
147
+ These are single runs on small samples, not official leaderboard numbers.
148
+
149
+ ## Development
150
+
151
+ ```bash
152
+ ./scripts/setup-dev.sh # once: sync deps, enable the pre-commit hook
153
+ ./scripts/check.sh # format, lint, type-check, tests — the same gate CI runs
154
+ ./scripts/e2e.sh # real-model tasks (needs credentials; not run in CI)
155
+ ```
156
+
157
+ Release procedure: [docs/release.md](docs/release.md).
158
+
159
+ Docs: [product spec](docs/product.md) · [architecture](docs/architecture.md) · [operating model](docs/operating-model.md) · [backlog](docs/backlog.md) · [progress](docs/progress.md).
160
+
161
+ License: MIT.
@@ -0,0 +1,143 @@
1
+ # cli-agent
2
+
3
+ An autonomous coding agent for your terminal. Give it a task in plain language; it reads your code, edits files, runs commands, and checks its own work — inside one workspace directory, under a permission policy you control.
4
+
5
+ Status: early (0.x). See [docs/progress.md](docs/progress.md) for what is verified and what is not.
6
+
7
+ ## Install
8
+
9
+ Requires Python 3.11+ and [uv](https://docs.astral.sh/uv/) (or pip).
10
+
11
+ ```bash
12
+ uv tool install cli-agent-yzf # from PyPI; installs the `cli-agent` command
13
+ # or a GitHub release wheel:
14
+ uv tool install https://github.com/yezhoufan2005/CLI-Agent/releases/download/v0.6.0/cli_agent_yzf-0.6.0-py3-none-any.whl
15
+ # or the latest main:
16
+ uv tool install git+https://github.com/yezhoufan2005/CLI-Agent
17
+ # or, from a checkout:
18
+ uv tool install .
19
+ ```
20
+
21
+ Set credentials in the environment (never in a config file):
22
+
23
+ ```bash
24
+ export ANTHROPIC_API_KEY=sk-ant-...
25
+ # or, for an Anthropic-compatible proxy:
26
+ export ANTHROPIC_BASE_URL=https://proxy.example
27
+ export ANTHROPIC_AUTH_TOKEN=...
28
+ cli-agent doctor # checks config and makes one tiny model call
29
+ ```
30
+
31
+ Any OpenAI-compatible Chat Completions endpoint (OpenAI, OpenRouter, Ollama, vLLM, LiteLLM, …) also works:
32
+
33
+ ```bash
34
+ export OPENAI_API_KEY=... # optional for local servers
35
+ export OPENAI_BASE_URL=http://localhost:11434/v1 # default: https://api.openai.com/v1
36
+ cli-agent --provider openai --model qwen2.5-coder "explain src/main.py"
37
+ ```
38
+
39
+ ## Use
40
+
41
+ ```bash
42
+ cli-agent "the tests in tests/test_parser.py fail; fix them" # one task, then exit
43
+ echo "add a --verbose flag" | cli-agent --mode auto-edit # task from stdin
44
+ cli-agent # interactive session
45
+ cli-agent --continue "now update the docs" # continue last session here
46
+ cli-agent --json "summarize this repo" | jq . # JSON-lines events for scripts
47
+ cli-agent sessions # list saved sessions
48
+ cli-agent undo # revert file changes of the last prompt
49
+ ```
50
+
51
+ `cli-agent undo` (or `/undo` in a session) puts back the files the agent's file tools changed during the most recent prompt, and deletes files it created. Each further undo goes back one more prompt, up to 20. If you edited a file yourself after the agent wrote it, undo leaves that file alone. Changes made through shell commands are not tracked; undo tells you how many shell commands ran in that prompt, so check `git status` for those. The agent is instructed to change file contents only through its file tools, so most edits are covered.
52
+
53
+ Exit codes: `0` done, `1` error (model/API failure, refusal), `2` usage/config error, `3` stopped incomplete (turn limit, output-token limit, or `--max-session-tokens` budget), `130` interrupted (Ctrl-C), `129`/`143` terminated by SIGHUP/SIGTERM (the running command is killed and the session saved first). An interrupted or failed session is saved and can be resumed with `--resume ID`.
54
+
55
+ ## Permissions
56
+
57
+ | Mode | Read tools | File writes | Shell commands |
58
+ |---|---|---|---|
59
+ | `read-only` | allow | deny | deny |
60
+ | `ask` (default) | allow | ask | ask |
61
+ | `auto-edit` | allow | allow | ask |
62
+ | `auto` | allow | allow | allow |
63
+
64
+ When there is no terminal to ask on (stdin piped, `--json`), "ask" means "deny".
65
+
66
+ Rules refine the mode: `--allow 'run_shell:pytest*'`, `--deny 'run_shell:git push*'`, or `allow = [...]` / `deny = [...]` in `~/.config/cli-agent/config.toml`. Deny rules win over allow rules.
67
+
68
+ - Path rules match the path normalized relative to the workspace, so `src/../.env` is matched as `.env`.
69
+ - A shell allow glob never matches a command line that contains shell metacharacters (`; & | $ ` < > ( )`, newlines). `run_shell:pytest*` allows `pytest -q tests/`, but `pytest; curl … | sh` still asks. The same applies to harmless pipes such as `pytest -q | tail`; in a headless run the agent is told which rule nearly matched, so it can retry the plain command.
70
+ - Shell deny rules are also checked against each simple command in a line (`cd x && git push` matches `git push*`). They are best-effort, not a security boundary.
71
+ - "Always" for a shell command approves exactly that command line for the session.
72
+ - Writes under `.git/` (hooks, config) always ask, even in `auto` and `auto-edit`, unless an explicit path rule such as `write_file:.git/info/*` allows them.
73
+ - A small built-in guard blocks catastrophic shell commands (`rm -rf ~`, `mkfs`, force-push, …) in every mode.
74
+
75
+ Each shell command runs with empty stdin, a timeout (default 120 s, max 600 s), and a 50 MB output cap. When it finishes, anything it left running (`&` jobs and, on Linux, `setsid`/`nohup` escapees) is killed, so an agent cannot leave daemons behind.
76
+
77
+ ### Shell sandbox (Linux)
78
+
79
+ `--sandbox auto` (or `sandbox = "auto"` in the config file, or `CLI_AGENT_SANDBOX=auto`) runs every shell command inside [bubblewrap](https://github.com/containers/bubblewrap):
80
+ - The filesystem is read-only except for the workspace and a private `/tmp`.
81
+ - Your home directory is replaced by an empty directory, so `~/.ssh` and `~/.aws` are not visible.
82
+ - There is no network unless you set `sandbox_network = true`.
83
+ - The command runs in its own PID namespace.
84
+
85
+ `auto` falls back to unsandboxed execution with a warning when bubblewrap cannot run. `required` refuses to start in that case. Bubblewrap needs unprivileged user namespaces, so it does not work inside most Docker containers. On Ubuntu 24.04 it may need `kernel.apparmor_restrict_unprivileged_userns=0` or an AppArmor profile. The default is `off`.
86
+
87
+ File tools cannot touch paths outside the workspace (symlinks are resolved first; list/search skip symlinks). Shell commands run with your user's privileges and are **not sandboxed**: the workspace boundary applies only to file tools, and an approved command can read or change anything your user can. Credential-like environment variables (`*TOKEN*`, `*KEY*`, `*SECRET*`, `*_PASS`, `DATABASE_URL`, `SSH_AUTH_SOCK`, …) are removed from the environment of shell commands, and on Linux the agent marks itself non-dumpable so commands cannot read its environment through `/proc`. Credential *files* your user can read (e.g. `~/.aws/credentials`) remain readable to shell commands.
88
+
89
+ `AGENTS.md` / `CLAUDE.md` in the workspace root are given to the model as project conventions; they cannot change permissions.
90
+
91
+ ## Configuration
92
+
93
+ `~/.config/cli-agent/config.toml` (override with `CLI_AGENT_CONFIG` or `--config`):
94
+
95
+ ```toml
96
+ model = "claude-sonnet-4-6"
97
+ mode = "auto-edit"
98
+ allow = ["run_shell:pytest*", "run_shell:git status*", "run_shell:git diff*"]
99
+ deny = ["run_shell:git push*"]
100
+ max_turns = 50
101
+ max_session_tokens = 2000000 # optional cost cap per session (input + output tokens)
102
+ shell_timeout = 120
103
+ ```
104
+
105
+ ### MCP servers
106
+
107
+ Tools from [MCP](https://modelcontextprotocol.io) stdio servers can be added in the user config file only; a repository cannot add servers:
108
+
109
+ ```toml
110
+ [mcp_servers.fs]
111
+ command = ["npx", "-y", "@modelcontextprotocol/server-filesystem", "/path/to/dir"]
112
+ env = { SOME_SETTING = "value" } # optional; passed to the server as-is
113
+ ```
114
+
115
+ They appear to the model as `mcp__<server>__<tool>`. Every MCP tool counts as a command: it asks in `ask` and `auto-edit` mode and is denied in `read-only` mode. You can allow one with a rule such as `--allow mcp__fs__read_file`. Servers get the same scrubbed environment as shell commands, plus their configured `env`. They are not sandboxed. Only the tools part of MCP is supported; resources, prompts and sampling are not.
116
+
117
+ Precedence: defaults < config file < environment (`CLI_AGENT_PROVIDER`, `CLI_AGENT_MODEL`, `CLI_AGENT_MODE`, `ANTHROPIC_*` / `OPENAI_*`) < flags. `provider = "openai"` in the config file selects the OpenAI-compatible provider.
118
+
119
+ ## How well does it work?
120
+
121
+ Measured with real models; full method and caveats in [docs/progress.md](docs/progress.md):
122
+
123
+ | Benchmark | claude-sonnet-4-6 | claude-haiku-4-5 |
124
+ |---|---|---|
125
+ | Built-in E2E tasks (`scripts/e2e.sh`, 11 tasks) | 11/11 | 11/11 |
126
+ | Exercism Python, 30 exercises, hidden tests (`scripts/bench.py`) | 27/30 | 27/30 |
127
+ | SWE-bench Lite sympy, 2 samples of 20, Docker-free (`scripts/swebench_sympy.py`) | 29/40 | 30/40 |
128
+
129
+ These are single runs on small samples, not official leaderboard numbers.
130
+
131
+ ## Development
132
+
133
+ ```bash
134
+ ./scripts/setup-dev.sh # once: sync deps, enable the pre-commit hook
135
+ ./scripts/check.sh # format, lint, type-check, tests — the same gate CI runs
136
+ ./scripts/e2e.sh # real-model tasks (needs credentials; not run in CI)
137
+ ```
138
+
139
+ Release procedure: [docs/release.md](docs/release.md).
140
+
141
+ Docs: [product spec](docs/product.md) · [architecture](docs/architecture.md) · [operating model](docs/operating-model.md) · [backlog](docs/backlog.md) · [progress](docs/progress.md).
142
+
143
+ License: MIT.
@@ -0,0 +1,81 @@
1
+ [project]
2
+ name = "cli-agent-yzf"
3
+ version = "0.6.0"
4
+ description = "An autonomous coding agent for the terminal"
5
+ readme = "README.md"
6
+ requires-python = ">=3.11"
7
+ dependencies = ["httpx==0.28.1"]
8
+ license = "MIT"
9
+ classifiers = [
10
+ "Programming Language :: Python :: 3.11",
11
+ "Programming Language :: Python :: 3.12",
12
+ "Programming Language :: Python :: 3.13",
13
+ "Programming Language :: Python :: 3.14",
14
+ "Environment :: Console",
15
+ "Operating System :: POSIX :: Linux",
16
+ "Operating System :: MacOS",
17
+ ]
18
+
19
+ [[project.authors]]
20
+ name = "yezhoufan2005"
21
+ email = "176495279+yezhoufan2005@users.noreply.github.com"
22
+
23
+ [project.scripts]
24
+ cli-agent = "cli_agent.cli:main"
25
+
26
+ [build-system]
27
+ requires = ["uv_build>=0.11.31,<0.12.0"]
28
+ build-backend = "uv_build"
29
+
30
+ [tool.uv.build-backend]
31
+ module-name = "cli_agent"
32
+
33
+ [tool.ruff]
34
+ line-length = 100
35
+ target-version = "py311"
36
+ extend-exclude = ["tests/e2e"]
37
+
38
+ [tool.ruff.lint]
39
+ select = [
40
+ "E",
41
+ "F",
42
+ "W",
43
+ "I",
44
+ "B",
45
+ "UP",
46
+ "S",
47
+ "BLE",
48
+ "RUF",
49
+ ]
50
+ ignore = [
51
+ "S603",
52
+ "S607",
53
+ "S101",
54
+ "RUF001",
55
+ "RUF012",
56
+ ]
57
+
58
+ [tool.ruff.lint.per-file-ignores]
59
+ "tests/**" = [
60
+ "S",
61
+ "BLE",
62
+ ]
63
+
64
+ [tool.mypy]
65
+ python_version = "3.11"
66
+ strict = true
67
+ files = ["src"]
68
+
69
+ [tool.pytest.ini_options]
70
+ testpaths = ["tests"]
71
+ timeout = 60
72
+ addopts = "-q"
73
+ norecursedirs = ["tests/e2e"]
74
+
75
+ [dependency-groups]
76
+ dev = [
77
+ "mypy==1.18.2",
78
+ "pytest==8.4.2",
79
+ "pytest-timeout==2.4.0",
80
+ "ruff==0.14.3",
81
+ ]
@@ -0,0 +1,66 @@
1
+ [project]
2
+ name = "cli-agent-yzf"
3
+ version = "0.6.0"
4
+ description = "An autonomous coding agent for the terminal"
5
+ readme = "README.md"
6
+ authors = [
7
+ { name = "yezhoufan2005", email = "176495279+yezhoufan2005@users.noreply.github.com" }
8
+ ]
9
+ requires-python = ">=3.11"
10
+ dependencies = [
11
+ "httpx==0.28.1",
12
+ ]
13
+
14
+ license = "MIT"
15
+ classifiers = [
16
+ "Programming Language :: Python :: 3.11",
17
+ "Programming Language :: Python :: 3.12",
18
+ "Programming Language :: Python :: 3.13",
19
+ "Programming Language :: Python :: 3.14",
20
+ "Environment :: Console",
21
+ "Operating System :: POSIX :: Linux",
22
+ "Operating System :: MacOS",
23
+ ]
24
+
25
+ [project.scripts]
26
+ cli-agent = "cli_agent.cli:main"
27
+
28
+ [build-system]
29
+ requires = ["uv_build>=0.11.31,<0.12.0"]
30
+ build-backend = "uv_build"
31
+
32
+ # "cli-agent" is taken on PyPI; the distribution is "cli-agent-yzf", the module and command stay cli_agent / cli-agent
33
+ [tool.uv.build-backend]
34
+ module-name = "cli_agent"
35
+
36
+ [dependency-groups]
37
+ dev = [
38
+ "mypy==1.18.2",
39
+ "pytest==8.4.2",
40
+ "pytest-timeout==2.4.0",
41
+ "ruff==0.14.3",
42
+ ]
43
+
44
+ [tool.ruff]
45
+ line-length = 100
46
+ target-version = "py311"
47
+ # E2E fixture repos are test inputs for the agent, not project code.
48
+ extend-exclude = ["tests/e2e"]
49
+
50
+ [tool.ruff.lint]
51
+ select = ["E", "F", "W", "I", "B", "UP", "S", "BLE", "RUF"]
52
+ ignore = ["S603", "S607", "S101", "RUF001", "RUF012"]
53
+
54
+ [tool.ruff.lint.per-file-ignores]
55
+ "tests/**" = ["S", "BLE"]
56
+
57
+ [tool.mypy]
58
+ python_version = "3.11"
59
+ strict = true
60
+ files = ["src"]
61
+
62
+ [tool.pytest.ini_options]
63
+ testpaths = ["tests"]
64
+ timeout = 60
65
+ addopts = "-q"
66
+ norecursedirs = ["tests/e2e"]
@@ -0,0 +1,3 @@
1
+ """cli-agent: an autonomous coding agent for the terminal."""
2
+
3
+ __version__ = "0.6.0"
@@ -0,0 +1,8 @@
1
+ import sys
2
+
3
+ from cli_agent.cli import main
4
+
5
+ # The guard matters: search_files spawns a child process, which re-imports the
6
+ # main module and must not run the CLI again.
7
+ if __name__ == "__main__":
8
+ sys.exit(main())