-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathpyproject.toml
More file actions
186 lines (174 loc) · 7.59 KB
/
Copy pathpyproject.toml
File metadata and controls
186 lines (174 loc) · 7.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
name = "coderio"
version = "0.3.0"
description = "A skill-driven coding agent — structural harness, foldable thinking TUI, deepagents engine."
readme = "README.md"
license = "MIT"
requires-python = ">=3.11"
keywords = ["agent", "coding-agent", "llm", "langchain", "langgraph", "textual", "tui", "cli"]
classifiers = [
"Development Status :: 3 - Alpha",
"Environment :: Console",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Operating System :: Microsoft :: Windows",
"Operating System :: POSIX :: Linux",
"Operating System :: MacOS",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Topic :: Software Development :: Code Generators",
]
authors = [
{ name = "coderio contributors" },
]
project-urls = { Homepage = "https://github.com/Lion-1209/coderio", Issues = "https://github.com/Lion-1209/coderio/issues" }
dependencies = [
"ddgs>=4.0",
"deepagents>=0.6",
"httpx>=0.27",
"langchain-anthropic>=0.2",
"langchain-core>=0.3",
"langchain-openai>=0.2",
"langchain>=0.3",
"langgraph>=0.2",
"langgraph-checkpoint-sqlite>=2.0",
"pydantic>=2",
"rich>=13",
"textual>=0.40",
"tomli-w>=1.0",
"typer>=0.12",
]
[project.optional-dependencies]
dev = [
"pytest>=8",
"pytest-asyncio>=0.23",
"pytest-cov>=4",
"ruff>=0.16",
"build>=1.2",
"mypy>=1.10",
]
# MCP (Model Context Protocol) support — opt-in. Install with:
# pip install -e ".[mcp]"
# Without this extra, load_mcp_tools returns [] silently (no .mcp.json effect).
mcp = [
"mcp>=2.0",
"langchain-mcp-adapters>=0.3.2",
]
[project.scripts]
coderio = "coderio.cli.app:main_entry"
[tool.hatch.build.targets.wheel]
packages = ["src/coderio"]
[tool.ruff]
line-length = 120
[tool.ruff.lint]
# E/F = pycodestyle/pyflakes basics (errors + warnings). Keep src/ clean.
# S = bandit security rules (audited per-file below — the tool-execution code
# legitimately uses subprocess and swallows UI exceptions by design).
select = ["E", "F", "W", "I", "S"]
[tool.ruff.lint.per-file-ignores]
# Tests legitimately use:
# F841 — variables assigned for side effects (e.g. `final = run_agent(...)`
# where the assertion is on session state, not the return value).
# E731 — lambda assignments for quick inline mocks/patches.
# S101 — assert statements (test code uses assert, not exceptions).
# S108 — /tmp paths in test fixtures (mock data, not real file access).
# S607 — partial executable path ('git') in test setup scripts.
# S110 — try/except/pass in test cleanup (proc.kill() teardown); a failed
# kill in a test fixture must not mask the real assertion failure.
"tests/**" = ["F841", "E731", "S101", "S108", "S607", "S110"]
# TUI rendering: S110 (try-except-pass) is intentional — these are UI
# fault-tolerance guards. A failed widget mount/scroll/remove must never crash
# the agent's main loop. Logging would spam the terminal during streaming.
# Also S603 for the OnboardingScreen verification subprocess.
"src/coderio/cli/tui.py" = ["S110"]
"src/coderio/cli/tui_onboarding.py" = ["S110"]
"src/coderio/cli/tui_screens.py" = ["S110"]
"src/coderio/cli/tui_widgets.py" = ["S110"]
# Bash tool: S603 (subprocess with untrusted input) is the TOOL'S ENTIRE PURPOSE.
# The agent runs user/model-authored shell commands by design. The workspace
# policy + permission gate are the security boundary, not subprocess filtering.
"src/coderio/tools/bash.py" = ["S603", "S110"]
# Grep tool: S603 — spawns ripgrep, input is the model's pattern. Same rationale.
"src/coderio/tools/grep_tool.py" = ["S603"]
# Credentials: S603/S607 — runs icacls (Windows) / chmod (Linux) to set file
# permissions. Partial path is intentional (platform command, not user input).
"src/coderio/cli/credentials.py" = ["S603", "S607"]
# Skills installer: S603/S607 — runs git clone + git pull. The URL is from the
# user's config (trusted repo_url), not arbitrary model input.
"src/coderio/cli/skills_cmd.py" = ["S603", "S607"]
# Probe: S310 — urllib.request.urlopen for provider model-info discovery.
# The URL is constructed from the configured base_url (trusted), and we only
# connect to http/https endpoints. Not user-supplied arbitrary URLs.
"src/coderio/llm/probe.py" = ["S310"]
# Session IDs: S311 — random.choices for session ID suffixes. These are NOT
# cryptographic secrets; they're human-readable unique identifiers (timestamp +
# 4-char suffix). No security dependency on unpredictability.
"src/coderio/session/store.py" = ["S311"]
# Deep agent: S602 — shell=True is required by deepagents' LocalShellBackend.
# Experimental module, not wired into the default CLI path.
"src/coderio/agent/deep_loop.py" = ["S602"]
# Sandbox modules: S602/S603 — running arbitrary subprocess commands IS the
# sandbox's entire purpose. The sandbox itself (bubblewrap namespace isolation
# on Linux, Restricted Token + Job Object on Windows) is the security boundary,
# not subprocess filtering. S108 on linux_sandbox is the bwrap "--tmpfs /tmp"
# arg — that path is INSIDE the namespace (a private tmpfs), never the host /tmp.
"src/coderio/tools/win_sandbox.py" = ["S602", "S603"]
"src/coderio/tools/linux_sandbox.py" = ["S603", "S108"]
"src/coderio/tools/sandbox_runner.py" = ["S603"]
# REPL onboarding check: S110 — best-effort config parse, failure means skip.
"src/coderio/cli/repl.py" = ["S110"]
# App entry: S110 — stream.reconfigure may fail on some platforms; skip is safe.
"src/coderio/cli/app.py" = ["S110"]
[tool.pytest.ini_options]
asyncio_mode = "auto"
[tool.coverage.run]
source = ["coderio"]
[tool.coverage.report]
# Local-dev coverage floor. CI enforces a stricter 70% via --cov-fail-under
# (see .github/workflows/ci.yml). This 60% is the "running tests in your
# editor" safety net — lower than CI so local runs don't fail on partial
# test selection. Current baseline: ~75% total, deep_loop 75%, middleware 80%+.
fail_under = 60
[tool.mypy]
# Gradual typing: start lenient, tighten over time. The goal is to catch
# real type errors (wrong arg counts, None where a value is expected) without
# blocking on the many untyped third-party deps (langchain, deepagents, textual).
#
# CI runs mypy as a HARD GATE (no continue-on-error) for the modules NOT in
# the override list below. The modules listed in [[tool.mypy.overrides]] have
# `ignore_errors = true` until they're cleaned up — each ignore is a tracked
# TODO, not a permanent pass. Remove entries as the files are fixed.
python_version = "3.11"
ignore_missing_imports = true
warn_redundant_casts = true
warn_unused_ignores = true
# Don't require complete annotations yet — most modules have them, but
# flagging every untyped function would generate hundreds of warnings.
check_untyped_defs = false
# Exclude test files (they use dynamic fixtures, pytest monkeypatch, etc.)
exclude = ["tests/", "build/", "dist/", "\\.venv/"]
# Per-module overrides: lenient modules (tracked cleanup TODOs).
# Each entry here is a file with known type issues that would block CI if
# enforced strictly. Remove entries as the files are cleaned up.
[[tool.mypy.overrides]]
module = [
"coderio.cli.tui",
"coderio.cli.tui_onboarding",
"coderio.cli.tui_widgets",
"coderio.cli.commands",
"coderio.cli.onboarding",
"coderio.cli.stream",
"coderio.cli.repl",
"coderio.agent.deep_loop",
"coderio.tools.win_job",
"coderio.tools.win_sandbox",
"coderio.mcp_loader",
"coderio.session.store",
"coderio.session.message",
"coderio.llm.probe",
]
ignore_errors = true