coderio 0.4.4__tar.gz → 0.5.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.
- {coderio-0.4.4 → coderio-0.5.0}/.github/workflows/ci.yml +18 -2
- {coderio-0.4.4 → coderio-0.5.0}/.github/workflows/release.yml +39 -9
- coderio-0.5.0/.gitignore +64 -0
- {coderio-0.4.4 → coderio-0.5.0}/CHANGELOG.md +217 -1
- {coderio-0.4.4 → coderio-0.5.0}/CONTRIBUTING.md +11 -5
- {coderio-0.4.4 → coderio-0.5.0}/PKG-INFO +62 -21
- {coderio-0.4.4 → coderio-0.5.0}/README.md +54 -10
- coderio-0.5.0/README_en.md +149 -0
- coderio-0.5.0/ROADMAP.md +64 -0
- coderio-0.5.0/ROADMAP_en.md +83 -0
- coderio-0.5.0/demo.gif +0 -0
- coderio-0.5.0/docs/CONFIG.md +223 -0
- {coderio-0.4.4 → coderio-0.5.0}/docs/coderio-architecture.md +68 -84
- coderio-0.5.0/docs/images/confirm-menu.svg +190 -0
- coderio-0.5.0/docs/images/harness-warn.svg +190 -0
- coderio-0.5.0/docs/images/todo-panel.svg +192 -0
- {coderio-0.4.4 → coderio-0.5.0}/pyproject.toml +20 -6
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/agent/_deepagents_compat.py +6 -20
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/agent/command_review.py +9 -4
- coderio-0.5.0/src/coderio/agent/deep_loop.py +1242 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/agent/harness.py +159 -24
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/agent/harness_middleware.py +67 -39
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/agent/hooks.py +65 -8
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/agent/permission_middleware.py +3 -2
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/agent/plan_artifact.py +70 -2
- coderio-0.5.0/src/coderio/agent/project_instructions.py +164 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/agent/prompts.py +4 -10
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/agent/skill_tool.py +20 -9
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/agent/stream.py +4 -4
- coderio-0.5.0/src/coderio/agent/sync_only.py +28 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/cli/app.py +6 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/cli/commands.py +24 -5
- coderio-0.5.0/src/coderio/cli/credentials.py +147 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/cli/multimodal.py +8 -2
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/cli/onboarding.py +46 -40
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/cli/providers.py +10 -4
- coderio-0.5.0/src/coderio/cli/render.py +17 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/cli/repl.py +117 -7
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/cli/run_cmd.py +37 -24
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/cli/stream.py +0 -12
- coderio-0.5.0/src/coderio/cli/stream_controller.py +550 -0
- coderio-0.5.0/src/coderio/cli/tui.py +1043 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/cli/tui_onboarding.py +71 -38
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/cli/tui_runtime.py +16 -20
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/cli/tui_widgets.py +53 -8
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/config/__init__.py +0 -2
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/config/loader.py +12 -11
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/config/models.py +11 -32
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/config/trust.py +28 -5
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/llm/factory.py +10 -9
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/mcp_loader.py +17 -1
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/session/message.py +16 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/session/store.py +40 -13
- coderio-0.5.0/src/coderio/tools/__init__.py +55 -0
- coderio-0.5.0/src/coderio/tools/base.py +40 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/tools/bash.py +3 -1
- coderio-0.5.0/src/coderio/tools/checkpoint.py +178 -0
- coderio-0.5.0/src/coderio/tools/command_policy.py +864 -0
- coderio-0.5.0/src/coderio/tools/confirm_diff.py +162 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/tools/multi_edit.py +30 -4
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/tools/permission.py +4 -2
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/tools/sandbox_runner.py +9 -0
- coderio-0.5.0/src/coderio/tools/taxonomy.py +122 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/tools/web_fetch.py +29 -3
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/tools/win_job.py +32 -12
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/tools/win_sandbox.py +116 -4
- {coderio-0.4.4 → coderio-0.5.0}/tests/agent/test_deep_integration.py +28 -41
- {coderio-0.4.4 → coderio-0.5.0}/tests/agent/test_deep_loop_unit.py +246 -11
- {coderio-0.4.4 → coderio-0.5.0}/tests/agent/test_deepagents_compat.py +0 -42
- {coderio-0.4.4 → coderio-0.5.0}/tests/agent/test_harness.py +115 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/agent/test_harness_middleware.py +74 -1
- {coderio-0.4.4 → coderio-0.5.0}/tests/agent/test_hooks.py +86 -10
- {coderio-0.4.4 → coderio-0.5.0}/tests/agent/test_perf_baseline.py +9 -6
- {coderio-0.4.4 → coderio-0.5.0}/tests/agent/test_plan_artifact.py +6 -2
- coderio-0.5.0/tests/agent/test_production_seam.py +479 -0
- coderio-0.5.0/tests/agent/test_project_instructions.py +201 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/agent/test_skill_tool.py +19 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/agent/test_stream.py +0 -9
- coderio-0.5.0/tests/agent/test_sync_only_middleware.py +64 -0
- coderio-0.5.0/tests/cli/test_app_commands.py +246 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/cli/test_commands.py +43 -0
- coderio-0.5.0/tests/cli/test_credentials.py +181 -0
- coderio-0.5.0/tests/cli/test_gate_builder.py +75 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/cli/test_live_thinking.py +3 -2
- {coderio-0.4.4 → coderio-0.5.0}/tests/cli/test_multimodal.py +24 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/cli/test_onboarding.py +50 -0
- coderio-0.5.0/tests/cli/test_render.py +7 -0
- coderio-0.5.0/tests/cli/test_stream_controller.py +75 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/cli/test_truncation.py +1 -1
- {coderio-0.4.4 → coderio-0.5.0}/tests/cli/test_tui_onboarding.py +61 -3
- coderio-0.5.0/tests/cli/test_tui_runtime_screens.py +330 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/cli/test_tui_startup.py +157 -5
- {coderio-0.4.4 → coderio-0.5.0}/tests/cli/test_tui_widgets.py +118 -1
- coderio-0.5.0/tests/cli/test_ux_features.py +264 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/config/test_loader.py +0 -33
- {coderio-0.4.4 → coderio-0.5.0}/tests/config/test_trust.py +41 -1
- coderio-0.5.0/tests/e2e/test_cli_e2e.py +150 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/llm/test_factory.py +32 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/session/test_message.py +23 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/session/test_store.py +83 -2
- {coderio-0.4.4 → coderio-0.5.0}/tests/test_seams.py +11 -9
- {coderio-0.4.4 → coderio-0.5.0}/tests/tools/test_checkpoint.py +139 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/tools/test_command_policy.py +383 -0
- coderio-0.5.0/tests/tools/test_confirm_diff.py +212 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/tools/test_multi_edit.py +50 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/tools/test_sandbox.py +120 -4
- {coderio-0.4.4 → coderio-0.5.0}/tests/tools/test_web_fetch.py +28 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/tools/test_win_job.py +56 -0
- {coderio-0.4.4 → coderio-0.5.0}/uv.lock +4 -4
- coderio-0.4.4/.gitignore +0 -41
- coderio-0.4.4/README_en.md +0 -107
- coderio-0.4.4/src/coderio/agent/deep_loop.py +0 -960
- coderio-0.4.4/src/coderio/cli/credentials.py +0 -70
- coderio-0.4.4/src/coderio/cli/render.py +0 -28
- coderio-0.4.4/src/coderio/cli/tui.py +0 -1332
- coderio-0.4.4/src/coderio/tools/__init__.py +0 -94
- coderio-0.4.4/src/coderio/tools/base.py +0 -55
- coderio-0.4.4/src/coderio/tools/checkpoint.py +0 -105
- coderio-0.4.4/src/coderio/tools/command_policy.py +0 -434
- coderio-0.4.4/tests/cli/test_credentials.py +0 -39
- coderio-0.4.4/tests/cli/test_render.py +0 -30
- coderio-0.4.4/tests/cli/test_ux_features.py +0 -125
- {coderio-0.4.4 → coderio-0.5.0}/.github/dependabot.yml +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/LICENSE +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/THIRD_PARTY_LICENSES.md +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/scripts/verify_deepagent_live.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/scripts/verify_harness_live.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/__init__.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/agent/__init__.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/agent/custom_agents.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/agent/state.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/cli/__init__.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/cli/custom_commands.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/cli/mcp_cmd.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/cli/skills_cmd.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/cli/tui_screens.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/config/bootstrap.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/llm/__init__.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/llm/probe.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/session/__init__.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/skills/__init__.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/skills/bundled/executing-plans/SKILL.md +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/skills/lion-skills/LICENSE +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/skills/lion-skills/README.md +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/skills/lion-skills/skills/clarifying-questions/SKILL.md +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/skills/lion-skills/skills/clarifying-questions/evals/evals.json +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/skills/lion-skills/skills/code-review/SKILL.md +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/skills/lion-skills/skills/code-review/evals/evals.json +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/skills/lion-skills/skills/commit-message/SKILL.md +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/skills/lion-skills/skills/commit-message/evals/evals.json +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/skills/lion-skills/skills/debugging/SKILL.md +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/skills/lion-skills/skills/debugging/evals/evals.json +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/skills/lion-skills/skills/error-handling/SKILL.md +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/skills/lion-skills/skills/error-handling/evals/evals.json +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/skills/lion-skills/skills/lion-writing-skills/SKILL.md +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/skills/lion-skills/skills/lion-writing-skills/evals/evals.json +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/skills/lion-skills/skills/naming/SKILL.md +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/skills/lion-skills/skills/naming/evals/evals.json +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/skills/lion-skills/skills/onboarding-unknown-codebase/SKILL.md +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/skills/lion-skills/skills/onboarding-unknown-codebase/evals/evals.json +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/skills/lion-skills/skills/spec-writing/SKILL.md +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/skills/lion-skills/skills/spec-writing/evals/evals.json +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/skills/lion-skills/skills/task-breakdown/SKILL.md +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/skills/lion-skills/skills/task-breakdown/evals/evals.json +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/skills/lion-skills/skills/testing/SKILL.md +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/skills/lion-skills/skills/testing/evals/evals.json +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/skills/lion-skills/skills/verify-and-fix/SKILL.md +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/skills/lion-skills/skills/verify-and-fix/evals/evals.json +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/skills/models.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/skills/parser.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/skills/store.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/tools/edit_file.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/tools/glob_tool.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/tools/grep_tool.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/tools/linux_sandbox.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/tools/list_dir.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/tools/note.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/tools/read_file.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/tools/todo.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/tools/web_search.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/src/coderio/tools/write_file.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/__init__.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/agent/__init__.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/agent/conftest.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/agent/test_command_review.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/agent/test_custom_agents.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/agent/test_deep_loop.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/agent/test_prompts.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/agent/test_state.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/cli/__init__.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/cli/test_app.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/cli/test_command_menu.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/cli/test_custom_commands.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/cli/test_input_isolation.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/cli/test_mcp_cmd.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/cli/test_onboarding_logic.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/cli/test_providers.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/cli/test_repl_loop.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/cli/test_repl_reset.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/cli/test_run_cmd.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/cli/test_skills_cmd.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/cli/test_status_bar.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/cli/test_stream.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/cli/test_tui_picker.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/cli/test_tui_runtime.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/cli/test_tui_screens.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/config/__init__.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/config/test_bootstrap.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/config/test_models.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/conftest.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/e2e/__init__.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/llm/__init__.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/llm/test_probe.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/session/__init__.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/skills/__init__.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/skills/test_bundled.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/skills/test_parser.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/skills/test_skill_tools.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/skills/test_store.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/test_mcp_loader.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/test_p0_stability.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/test_repl.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/test_version.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/tools/__init__.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/tools/test_bash.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/tools/test_concrete_gates.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/tools/test_edit_prefix.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/tools/test_file_tools.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/tools/test_glob_tool.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/tools/test_grep_tool.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/tools/test_list_dir.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/tools/test_note.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/tools/test_permission.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/tools/test_registry.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/tools/test_search_tools.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/tools/test_todo.py +0 -0
- {coderio-0.4.4 → coderio-0.5.0}/tests/tools/test_web.py +0 -0
|
@@ -67,9 +67,11 @@ jobs:
|
|
|
67
67
|
|
|
68
68
|
- name: Audit dependencies for known vulnerabilities
|
|
69
69
|
# Scans installed packages against the PyPI advisory database.
|
|
70
|
-
#
|
|
70
|
+
# BLOCKING since 2026-08-28 (audit finding: continue-on-error made the
|
|
71
|
+
# scan decorative — known CVEs could never turn CI red). If a flagged
|
|
72
|
+
# vuln is a false positive / unfixable, add an explicit --ignore-vuln
|
|
73
|
+
# with a comment rather than re-adding continue-on-error.
|
|
71
74
|
shell: bash
|
|
72
|
-
continue-on-error: true
|
|
73
75
|
run: |
|
|
74
76
|
uv pip install pip-audit
|
|
75
77
|
uv run pip-audit
|
|
@@ -86,6 +88,20 @@ jobs:
|
|
|
86
88
|
run: |
|
|
87
89
|
uv run python -m pytest -q --cov=coderio --cov-report=term-missing --cov-fail-under=75
|
|
88
90
|
|
|
91
|
+
- name: MCP extra smoke (install + loader import)
|
|
92
|
+
# The mcp extra was never installed in CI (audit 2026-09-04 P1-17):
|
|
93
|
+
# `load_mcp_tools_sync` — the code path behind README's "MCP support"
|
|
94
|
+
# — was never executed anywhere, in tests or CI. Install the extra
|
|
95
|
+
# from the frozen lock and at least run the loader test module
|
|
96
|
+
# against the real adapters package. One matrix leg is enough (the
|
|
97
|
+
# loader is pure Python; this step exists so the import path can't
|
|
98
|
+
# rot silently).
|
|
99
|
+
if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.12'
|
|
100
|
+
run: |
|
|
101
|
+
uv sync --frozen --extra dev --extra mcp
|
|
102
|
+
uv run python -c "from coderio.mcp_loader import load_mcp_tools_sync; print('mcp loader import OK')"
|
|
103
|
+
uv run python -m pytest tests/test_mcp_loader.py -q
|
|
104
|
+
|
|
89
105
|
- name: Type check (mypy)
|
|
90
106
|
# HARD GATE for clean modules. pyproject.toml's [[tool.mypy.overrides]]
|
|
91
107
|
# lists modules with known type issues (ignore_errors=true) — each is a
|
|
@@ -28,7 +28,18 @@ jobs:
|
|
|
28
28
|
# workflow covers pushes/PRs, but a tag could be cut from a commit that
|
|
29
29
|
# predates a fix; this gate makes the release itself fail loudly instead.
|
|
30
30
|
test:
|
|
31
|
-
|
|
31
|
+
# Runs on ubuntu AND windows: windows-latest is the priority platform and
|
|
32
|
+
# a tag could otherwise ship a Windows-only regression (2026-08-28 audit).
|
|
33
|
+
strategy:
|
|
34
|
+
fail-fast: false
|
|
35
|
+
matrix:
|
|
36
|
+
os: [ubuntu-latest, windows-latest]
|
|
37
|
+
runs-on: ${{ matrix.os }}
|
|
38
|
+
env:
|
|
39
|
+
# Mirror ci.yml: Windows runners default to cp1252 and CJK output
|
|
40
|
+
# crashes with UnicodeEncodeError (audit finding #11).
|
|
41
|
+
PYTHONIOENCODING: utf-8
|
|
42
|
+
PYTHONUTF8: "1"
|
|
32
43
|
steps:
|
|
33
44
|
- uses: actions/checkout@v7
|
|
34
45
|
- uses: astral-sh/setup-uv@v7
|
|
@@ -94,10 +105,30 @@ jobs:
|
|
|
94
105
|
/tmp/sdist-test-venv/bin/coderio --help
|
|
95
106
|
|
|
96
107
|
- name: Create GitHub Release + attach artifacts
|
|
108
|
+
# Restored (2026-08-28 audit #3): the artifact refactor
|
|
109
|
+
# accidentally dropped Release creation while the header still
|
|
110
|
+
# promised it. dist/ is still in this job's workspace; the publish
|
|
111
|
+
# job downloads the same artifacts separately.
|
|
97
112
|
uses: softprops/action-gh-release@v3
|
|
98
113
|
with:
|
|
99
114
|
generate_release_notes: true
|
|
100
|
-
files:
|
|
115
|
+
files: |
|
|
116
|
+
dist/*.whl
|
|
117
|
+
dist/*.tar.gz
|
|
118
|
+
|
|
119
|
+
- name: Upload verified artifacts for publishing
|
|
120
|
+
# Pass the EXACT artifacts that were verified in the clean venvs to
|
|
121
|
+
# the publish job — the old flow REBUILT in publish-pypi, so PyPI
|
|
122
|
+
# could receive a different byte stream than the one verified above
|
|
123
|
+
# (2026-08-28 audit: non-deterministic build gap).
|
|
124
|
+
uses: actions/upload-artifact@v4
|
|
125
|
+
with:
|
|
126
|
+
name: dist
|
|
127
|
+
path: |
|
|
128
|
+
dist/*.whl
|
|
129
|
+
dist/*.tar.gz
|
|
130
|
+
if-no-files-found: error
|
|
131
|
+
retention-days: 3
|
|
101
132
|
|
|
102
133
|
publish-pypi:
|
|
103
134
|
# PyPI via Trusted Publishing (OIDC) — no API token to manage or leak.
|
|
@@ -108,14 +139,13 @@ jobs:
|
|
|
108
139
|
permissions:
|
|
109
140
|
id-token: write # OIDC token for Trusted Publishing
|
|
110
141
|
steps:
|
|
111
|
-
-
|
|
112
|
-
|
|
142
|
+
- name: Download verified artifacts
|
|
143
|
+
# No rebuild: publish EXACTLY the wheel/sdist verified in the release
|
|
144
|
+
# job (2026-08-28 audit fix). No checkout needed either.
|
|
145
|
+
uses: actions/download-artifact@v4
|
|
113
146
|
with:
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
run: |
|
|
117
|
-
pip install build
|
|
118
|
-
python -m build
|
|
147
|
+
name: dist
|
|
148
|
+
path: dist
|
|
119
149
|
- name: Publish to PyPI
|
|
120
150
|
uses: pypa/gh-action-pypi-publish@release/v1
|
|
121
151
|
with:
|
coderio-0.5.0/.gitignore
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# OS
|
|
2
|
+
.DS_Store
|
|
3
|
+
Thumbs.db
|
|
4
|
+
desktop.ini
|
|
5
|
+
|
|
6
|
+
# IDE / Editor
|
|
7
|
+
.vscode/
|
|
8
|
+
.idea/
|
|
9
|
+
*.swp
|
|
10
|
+
*.swo
|
|
11
|
+
|
|
12
|
+
# Node
|
|
13
|
+
node_modules/
|
|
14
|
+
npm-debug.log*
|
|
15
|
+
yarn-debug.log*
|
|
16
|
+
yarn-error.log*
|
|
17
|
+
|
|
18
|
+
# Python
|
|
19
|
+
__pycache__/
|
|
20
|
+
*.py[cod]
|
|
21
|
+
.venv/
|
|
22
|
+
venv/
|
|
23
|
+
*.egg-info/
|
|
24
|
+
build/
|
|
25
|
+
dist/
|
|
26
|
+
|
|
27
|
+
# Testing / linting
|
|
28
|
+
.pytest_cache/
|
|
29
|
+
.mypy_cache/
|
|
30
|
+
.coverage
|
|
31
|
+
coverage.xml
|
|
32
|
+
htmlcov/
|
|
33
|
+
|
|
34
|
+
# coderio user data (project-local layer)
|
|
35
|
+
.coderio/
|
|
36
|
+
|
|
37
|
+
# Misc
|
|
38
|
+
*.log
|
|
39
|
+
.tmp/
|
|
40
|
+
tmp/
|
|
41
|
+
.zcode/
|
|
42
|
+
|
|
43
|
+
# zcode workspace instructions — local only, not part of the project
|
|
44
|
+
/AGENTS.md
|
|
45
|
+
/AGENTS_EXAMPLE.md
|
|
46
|
+
|
|
47
|
+
# Local audit/analysis artifacts — single-maintainer working notes (2026-09-02
|
|
48
|
+
# review: 34 untracked items at repo root). Files stay on disk; git just
|
|
49
|
+
# stops listing them. Delete manually when no longer wanted.
|
|
50
|
+
/coderio-*analysis*.md
|
|
51
|
+
/coderio-optimization-checklist-*.md
|
|
52
|
+
/coderio-latest-test-report-*.md
|
|
53
|
+
/coderio-detailed-analysis-*.md
|
|
54
|
+
/coderio-project-analysis.md
|
|
55
|
+
/coderio-vs-mainstream-agents-*.md
|
|
56
|
+
/juejin-post-*.md
|
|
57
|
+
/_test_subagent/
|
|
58
|
+
/docs/blog/
|
|
59
|
+
/hello.py
|
|
60
|
+
/test.py
|
|
61
|
+
|
|
62
|
+
# Local screenshots / assets at the repo root (not shipped docs images)
|
|
63
|
+
/*.png
|
|
64
|
+
!/docs/images/*.png
|
|
@@ -6,6 +6,216 @@ All notable changes to coderio are documented here. The format follows
|
|
|
6
6
|
`pyproject.toml`'s `[project].version` — `coderio.__version__` reads it via
|
|
7
7
|
`importlib.metadata`.
|
|
8
8
|
|
|
9
|
+
## [0.5.0] — 2026-09-04
|
|
10
|
+
|
|
11
|
+
### Security — 2026-09-04 third-party audit batch (P0; each fix re-verified by an independent adversarial round, mutation-tested, and runtime-audited)
|
|
12
|
+
|
|
13
|
+
An external third-party audit (report committed as `PROJECT_REVIEW_2026-09-04.md`)
|
|
14
|
+
found five confirmed issues and three seam breaks where the implementation was
|
|
15
|
+
weaker than the documentation's promise. All fixed and double-checked:
|
|
16
|
+
|
|
17
|
+
- **P0-1 · command blacklist leaked plain (non-obfuscated) footguns.**
|
|
18
|
+
`${HOME}` brace expansion, any drive letter (`Remove-Item -Recurse D:\`,
|
|
19
|
+
`rd /s /q D:\data`) and UNC targets, PowerShell home spellings
|
|
20
|
+
(`$USERPROFILE` / `$env:USERPROFILE` / `%USERPROFILE%`), the documented
|
|
21
|
+
symbolic chmod modes (`a+rwx`, `ugo+rwx`) plus `7777`/`1777` supersets,
|
|
22
|
+
PowerShell `Stop-Computer`/`Restart-Computer`, `diskutil partitionDisk` /
|
|
23
|
+
`apfs delete*`, the `cp`/`shred`/`wipefs` raw-device family, named-function
|
|
24
|
+
fork bombs (`bomb(){ bomb|bomb & }; bomb`, newline-call variant), and the
|
|
25
|
+
`Remove-Item` pipeline form (`ls D:\ | ri -r`) — all blocked now. One false
|
|
26
|
+
positive fixed in the same pass: `git rm -r D:\proj` was caught by an alias
|
|
27
|
+
match at any token position; the PowerShell branch now matches only at the
|
|
28
|
+
segment head.
|
|
29
|
+
- **P0-2 · web_fetch SSRF: shared-address ranges leaked.** `is_global`
|
|
30
|
+
depends on the CPython version (CVE-2024-4032 reclassified several ranges in
|
|
31
|
+
3.11.9/3.12.3), so on older 3.11 patch releases the Aliyun internal metadata
|
|
32
|
+
service (`100.100.200.200`, the classic SSRF payout) was fetchable. Explicit
|
|
33
|
+
CIDR blocks for 100.64/10, 192.0.0.0/24, 192.88.99.0/24, 198.18.0.0/15 —
|
|
34
|
+
version-independent — plus the `is_global` catch-all for everything else.
|
|
35
|
+
- **P0-3 · VerifyGate counted `echo foo.py` as verification.** The
|
|
36
|
+
file-reference branch required only that the command MENTION a written file.
|
|
37
|
+
Now the segment must actually run it: an interpreter/runner head
|
|
38
|
+
(`python src/foo.py`, `uv run …`), the file itself as the command
|
|
39
|
+
(`./foo.py`), or a known verifier — with shell wrappers unwrapped first
|
|
40
|
+
(`bash -c 'echo foo.py'` is an echo), inline-code flags closing the segment
|
|
41
|
+
(`python -c "print('foo.py')"`, incl. `python -u -c`), and Windows
|
|
42
|
+
`.exe` spellings normalized. `cat`/`git diff`/`ls` mentions never verify.
|
|
43
|
+
- **P0-4 · credentials: non-atomic write + corrupt file silently wiped keys.**
|
|
44
|
+
A crash mid-write truncated the TOML, `read_credentials` treated corrupt
|
|
45
|
+
files as empty, and the next save persisted that emptiness — every stored
|
|
46
|
+
key gone. Writes are now atomic (PID-unique temp file, permission-
|
|
47
|
+
restricted before key bytes land, `os.replace`); a corrupt file is backed up
|
|
48
|
+
to `.corrupt` before being rebuilt; `UnicodeDecodeError` (non-UTF-8
|
|
49
|
+
corruption) is caught explicitly — it previously crashed /setup outright.
|
|
50
|
+
- **P0-5 · the Windows session lock was not mutually exclusive.**
|
|
51
|
+
`msvcrt.locking` locks at the current position and an append-mode handle
|
|
52
|
+
starts at open-time EOF — a holder appending under the lock grew the file,
|
|
53
|
+
so a later opener locked a different byte and both processes "held" the
|
|
54
|
+
lock (reproduced before the fix). The mutex is now byte [0,1) via
|
|
55
|
+
`seek(0)`; appends still land at the never-locked EOF; unlock targets the
|
|
56
|
+
range actually held.
|
|
57
|
+
- **P0-6 · default-config execute could hang forever (Windows).** The plain
|
|
58
|
+
path used `subprocess.run(timeout=...)`, whose Windows timeout kills only
|
|
59
|
+
the direct child — grandchildren kept the pipes open and `communicate()`
|
|
60
|
+
waited for EOF indefinitely (the exact bug `tools/bash.py` had fixed; the
|
|
61
|
+
production path regressed it). Now Popen + `taskkill /T /F` tree kill (Job
|
|
62
|
+
fallback) + bounded reap, returning exit 124 at ~timeout; the old Job-at-
|
|
63
|
+
kill-time approach in `win_job` never contained pre-existing grandchildren.
|
|
64
|
+
- **P0-7 · the documented `Z_API_KEY` path guaranteed an auth failure.**
|
|
65
|
+
Onboarding skip and the headless error both say "set Z_API_KEY", but
|
|
66
|
+
`_pick_api_key("anthropic")` read only `ANTHROPIC_API_KEY` — and every
|
|
67
|
+
coding-plan provider is anthropic-kind. `Z_API_KEY` now falls through
|
|
68
|
+
(Anthropic's own variable keeps precedence).
|
|
69
|
+
|
|
70
|
+
### Fixed — P1 behavior defects + P2 hygiene (2026-09-04, same audit)
|
|
71
|
+
|
|
72
|
+
- **P1-8** the bash probe cache was one class-level value: the first
|
|
73
|
+
instance's result shadowed every other instance's `[tools].bash_shell`
|
|
74
|
+
config for the whole process. Now keyed by the configured shell.
|
|
75
|
+
- **P1-9** `activate_skill` returned only "Activated skill: X" — the playbook
|
|
76
|
+
body reached the system prompt one turn LATER (the docstring's
|
|
77
|
+
`on_activate_skill` callback never existed). The body now rides the tool
|
|
78
|
+
result (same-turn context), and re-activation re-supplies it (recovery
|
|
79
|
+
after context compaction).
|
|
80
|
+
- **P1-10** PLAN mode wrote files: every successful `write_todos` mirrored
|
|
81
|
+
arbitrary todo content to `<project>/.coderio/plan.md` — bypassing the
|
|
82
|
+
read-only contract and `/undo`. Suppressed under a PLAN gate (todos still
|
|
83
|
+
work in memory); the PlanGate nudge no longer advertises the mirror there.
|
|
84
|
+
- **P1-11** sandbox degradation is visible and honest: a degraded run
|
|
85
|
+
(Linux without bubblewrap) prefixes `[sandbox unavailable: …]` to the tool
|
|
86
|
+
output, and `auto_allow_if_sandboxed` now works only where the sandbox
|
|
87
|
+
actually provides a boundary — on macOS / Linux-without-bwrap / Linux job
|
|
88
|
+
mode it is disabled with a printed reason instead of yielding "zero
|
|
89
|
+
isolation + zero confirmation".
|
|
90
|
+
- **P1-12** checkpoint `/undo` could silently restore an OLDER state: budget
|
|
91
|
+
eviction had no floor, so a newest snapshot over budget evicted itself.
|
|
92
|
+
The newest entry is now eviction-proof; files over the whole budget are
|
|
93
|
+
skipped with a warning; the multi-instance lost-update boundary is
|
|
94
|
+
documented.
|
|
95
|
+
- **P1-13** TUI wedge: `worker.cancel()` landing between submit and thread
|
|
96
|
+
start finished the worker without running its `finally`, leaving
|
|
97
|
+
`_is_running` stuck True (every submit refused until restart). The stale
|
|
98
|
+
state is now detected and cleared (one resubmit); the in-flight guard is
|
|
99
|
+
not weakened, and `action_interrupt` no longer claims cancel() can unblock
|
|
100
|
+
a running thread.
|
|
101
|
+
- **P1-14** the repo trust gate now covers `.coderio/commands/` and
|
|
102
|
+
`.coderio/agents/` — prompt templates injected into the model verbatim
|
|
103
|
+
deserve the same first-use confirmation as skills. NOTE for existing users:
|
|
104
|
+
repos that ship these directories will re-prompt once (trust is
|
|
105
|
+
content-keyed).
|
|
106
|
+
- **P1-15** explicit sync-only middleware contract: all four production
|
|
107
|
+
middlewares inherit `SyncOnlyMiddleware`, and a contract test pins that no
|
|
108
|
+
async surface is defined (an overriding `aafter_model` was tested and
|
|
109
|
+
breaks even the sync path — langgraph wires the node differently).
|
|
110
|
+
- **P1-18** multimodal prompts were `str(list)`'d in three places — hook
|
|
111
|
+
rejection persisted base64 garbage into the session (prompt text lost),
|
|
112
|
+
`/export` leaked image blobs into markdown, and the TUI encoded every
|
|
113
|
+
image twice per message. New `session.message.text_of_content` is the
|
|
114
|
+
single text view; `build_user_content` accepts pre-extracted images.
|
|
115
|
+
- **P1-19** `win_sandbox` now checks `assign_to_job`'s return value (a
|
|
116
|
+
failure previously meant no resource caps and a dead timeout tree-kill,
|
|
117
|
+
silently); the `cmd /c` quoting/`$VAR` divergence between sandboxed and
|
|
118
|
+
plain runs is documented in the module docstring and README. Found during
|
|
119
|
+
the release gate itself: when the restricted-token launch dies during
|
|
120
|
+
initialization (NTSTATUS 0xC0000142 family with zero output — observed on
|
|
121
|
+
a windows-latest runner image roll), `run_sandboxed` now degrades to a
|
|
122
|
+
visibly-marked plain run instead of returning a mysterious crash code.
|
|
123
|
+
- **P2 hygiene**: `neutralize_base_prompt` removed (deepagents 0.7.6
|
|
124
|
+
deprecated `BASE_AGENT_PROMPT` with zero internal consumption — the call
|
|
125
|
+
was a no-op that raised a LangChainDeprecationWarning every startup);
|
|
126
|
+
dead `render_markdown`/`render_error`/`render_tool_call` and the ghost
|
|
127
|
+
`on_truncated` protocol method removed; factory's duplicate custom-provider
|
|
128
|
+
branch collapsed; `HookSpec` caches its compiled matcher (was a fresh
|
|
129
|
+
re.compile per tool call per hook); hook `communicate` failures kill and
|
|
130
|
+
reap the child; model-facing `timeout` args bounded (web_fetch ≤ 600s,
|
|
131
|
+
bash ≤ 3600s).
|
|
132
|
+
- **docs**: the architecture doc no longer describes the removed hand-written
|
|
133
|
+
loop (`run_step`/`_execute_turn` pseudocode), the deleted `[context]`
|
|
134
|
+
config section, or the `_invoke_tool` error-grading table; the data-flow
|
|
135
|
+
chapter follows the real deepagents middleware path; README/README_en
|
|
136
|
+
dropped the "auto-compaction (60% window trigger)" claim (no such knob);
|
|
137
|
+
the third-party report itself is committed as
|
|
138
|
+
`PROJECT_REVIEW_2026-09-04.md`.
|
|
139
|
+
- **CI**: new `MCP extra smoke` leg (ubuntu/py3.12) installs the mcp extra
|
|
140
|
+
from the frozen lock and runs the loader tests against real adapters —
|
|
141
|
+
`load_mcp_tools_sync` had never been executed by any test or CI job.
|
|
142
|
+
Surfaced (and fixed) a pre-existing mypy error that only appears with the
|
|
143
|
+
py.typed adapters installed.
|
|
144
|
+
|
|
145
|
+
### Added — 2026-09-03 review batch
|
|
146
|
+
- **Confirm diff preview**: CONFIRM-mode prompts for write_file / edit_file /
|
|
147
|
+
multi_edit render a unified diff of the change (matching the real tool
|
|
148
|
+
semantics: replace_all, multi-match failure, multi_edit all-or-nothing).
|
|
149
|
+
- **hooks environment whitelist**: hook subprocesses get CODERIO_* +
|
|
150
|
+
exec-resolution + temp/locale vars instead of the full os.environ.
|
|
151
|
+
- **credentials hardening**: ACL-restricted before key bytes hit the disk;
|
|
152
|
+
icacls failures logged; corrupt credentials file no longer crashes /setup.
|
|
153
|
+
- **AGENTS.md walk boundary**: falls back to the enclosing GIT root for
|
|
154
|
+
repos without coderio config (subdirectory launches keep nearest-wins).
|
|
155
|
+
- **concurrent-submission guard** + interruptible permission wait + escaped
|
|
156
|
+
model-name retry in onboarding (`m` = change model) + `--version` flag.
|
|
157
|
+
- ROADMAP.md / ROADMAP_en.md added (maintenance status, Now/Next/Later,
|
|
158
|
+
non-goals).
|
|
159
|
+
|
|
160
|
+
### Fixed — audit-driven hardening (2026-08-28 + 2026-09-02 review batches)
|
|
161
|
+
- **Command blacklist**: rebuilt segment/token parsing (multi-line, wrapper
|
|
162
|
+
shells incl. path-qualified and sudo-prefixed, PowerShell/cmd variants);
|
|
163
|
+
xargs-into-recursive-rm with flags in any position; `find -delete`/
|
|
164
|
+
`-exec rm` dangerous-root set widened to any absolute path, ~, $HOME, globs
|
|
165
|
+
(the `rm -rf /etc` blocked / `find /etc -delete` leaked double standard).
|
|
166
|
+
- **Instruction injection**: the AGENTS.md walk is bounded at the launch dir
|
|
167
|
+
even when no workspace_root is configured (a parent directory's AGENTS.md
|
|
168
|
+
could previously leak into every project launched from below it).
|
|
169
|
+
- **Hooks**: subprocess environment is now a whitelist (CODERIO_* + exec
|
|
170
|
+
resolution + temp/locale) instead of a full os.environ copy — repo hooks
|
|
171
|
+
can no longer read environment secrets; hooks stdout contract documented
|
|
172
|
+
(raw stdout injects for SessionStart/UserPromptSubmit, no JSON parsing).
|
|
173
|
+
- **Credentials**: the file is created and ACL-restricted BEFORE any key
|
|
174
|
+
bytes hit the disk (write-then-restrict window closed); icacls failures
|
|
175
|
+
are logged; a missing Windows username skips inheritance-stripping
|
|
176
|
+
instead of producing a file nobody can read.
|
|
177
|
+
- **TUI/engine**: a turn in flight no longer accepts a second submission
|
|
178
|
+
(concurrent engine threads interleaved session writes); Esc now breaks a
|
|
179
|
+
pending permission-prompt wait (previously blocked up to 120s); interrupt
|
|
180
|
+
drops the thread checkpoint (dangling tool_calls state) — now regression
|
|
181
|
+
tested.
|
|
182
|
+
- **run**: timeout path logs why the daemon thread survives and how
|
|
183
|
+
`[tools].sandbox_mode = "job"` reaps the process tree; headless stdout
|
|
184
|
+
writes survive interpreter teardown.
|
|
185
|
+
|
|
186
|
+
### Changed — structure (P2 decomposition, behavior-preserving)
|
|
187
|
+
- `run_deep_agent` decomposed: `TurnSpec` dataclass (15 kwargs → 1 spec),
|
|
188
|
+
`build_middleware/build_backend/build_subagents` builders, module-level
|
|
189
|
+
`make_shell_backend` factory; body ≤80 lines, behavior pinned by the
|
|
190
|
+
existing suite + adversarial equivalence review.
|
|
191
|
+
- `CoderioTUI` (1380 → 983 lines): StreamHandler protocol, agent-thread
|
|
192
|
+
state, render queue and confirmation wait extracted to
|
|
193
|
+
`cli/stream_controller.py`; every bare `except: pass` in tui.py now logs.
|
|
194
|
+
- `build_turn_spec` in cli/repl.py is the single CommandPolicy/TurnSpec
|
|
195
|
+
construction path for headless and TUI runs (was two field-identical
|
|
196
|
+
copies).
|
|
197
|
+
- Tool-name registry (`tools/taxonomy.py`) is now the literal single source:
|
|
198
|
+
web_search registered, permission/harness literals re-pointed, the two
|
|
199
|
+
bash→execute prose regexes merged, the shim removed.
|
|
200
|
+
- tests/e2e filled (5 black-box CLI tests); app.py coverage 36%→95%,
|
|
201
|
+
tui_runtime.py 35%→96%.
|
|
202
|
+
|
|
203
|
+
### Added
|
|
204
|
+
- AGENTS.md / CLAUDE.md project instructions injected into the system
|
|
205
|
+
prompt (nearest-wins, bounded at the project root / git root).
|
|
206
|
+
- Tool-name registry `tools/taxonomy.py` — one definition of engine/harness
|
|
207
|
+
names and categories (was 6+ drifting ad-hoc copies, the root cause of
|
|
208
|
+
several recorded P0s).
|
|
209
|
+
- `--version` flag.
|
|
210
|
+
- docs/CONFIG.md — full config.toml field reference, hooks syntax,
|
|
211
|
+
.mcp.json fields, custom agents/commands, trust mechanism.
|
|
212
|
+
|
|
213
|
+
### Deprecated / Removed
|
|
214
|
+
- Removed half-demolished relics: [context] config section, RichStream,
|
|
215
|
+
phase-timeline dead branches, to_langchain_tools passthrough (P2-8 batch).
|
|
216
|
+
- README: removed the Claude Code / aider comparison table; honest
|
|
217
|
+
macOS-sandbox disclosure added to Known limitations.
|
|
218
|
+
|
|
9
219
|
## [0.4.4] — 2026-08-24
|
|
10
220
|
|
|
11
221
|
### Added — extensibility & safety-of-agency features (each adversarially reviewed, mutation-verified)
|
|
@@ -606,7 +816,13 @@ All notable changes to coderio are documented here. The format follows
|
|
|
606
816
|
- Rich stream UI + Textual TUI with foldable thinking.
|
|
607
817
|
- jsonl session persistence with compression truncation.
|
|
608
818
|
|
|
609
|
-
[Unreleased]: https://github.com/Lion-1209/coderio/compare/v0.
|
|
819
|
+
[Unreleased]: https://github.com/Lion-1209/coderio/compare/v0.5.0...HEAD
|
|
820
|
+
[0.5.0]: https://github.com/Lion-1209/coderio/compare/v0.4.4...v0.5.0
|
|
821
|
+
[0.4.4]: https://github.com/Lion-1209/coderio/releases/tag/v0.4.4
|
|
822
|
+
[0.4.3]: https://github.com/Lion-1209/coderio/releases/tag/v0.4.3
|
|
823
|
+
[0.4.2]: https://github.com/Lion-1209/coderio/releases/tag/v0.4.2
|
|
824
|
+
[0.4.1]: https://github.com/Lion-1209/coderio/releases/tag/v0.4.1
|
|
825
|
+
[0.4.0]: https://github.com/Lion-1209/coderio/releases/tag/v0.4.0
|
|
610
826
|
[0.3.0]: https://github.com/Lion-1209/coderio/releases/tag/v0.3.0
|
|
611
827
|
[0.2.0]: https://github.com/Lion-1209/coderio/releases/tag/v0.2.0
|
|
612
828
|
[0.1.0]: https://github.com/Lion-1209/coderio/releases/tag/v0.1.0
|
|
@@ -6,16 +6,22 @@ Thanks for your interest in contributing! This guide covers the basics.
|
|
|
6
6
|
|
|
7
7
|
## Development setup
|
|
8
8
|
|
|
9
|
+
The project uses [uv](https://docs.astral.sh/uv/) for dependency management
|
|
10
|
+
(locked via `uv.lock`, same as CI). Python 3.11+ required.
|
|
11
|
+
|
|
9
12
|
```bash
|
|
10
13
|
git clone <repo-url> coderio
|
|
11
14
|
cd coderio
|
|
12
|
-
|
|
15
|
+
uv sync --frozen # creates .venv from the lockfile
|
|
16
|
+
uv run pytest -q # run anything inside the managed venv
|
|
17
|
+
```
|
|
13
18
|
|
|
14
|
-
|
|
15
|
-
|
|
19
|
+
With the venv activated (`.venv/Scripts/activate` on Windows,
|
|
20
|
+
`.venv/bin/activate` elsewhere) the plain commands work too:
|
|
16
21
|
|
|
17
|
-
|
|
18
|
-
|
|
22
|
+
```bash
|
|
23
|
+
python -m pytest -q
|
|
24
|
+
python -m ruff check src tests
|
|
19
25
|
```
|
|
20
26
|
|
|
21
27
|
Set your API key:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: coderio
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.0
|
|
4
4
|
Summary: A skill-driven coding agent — structural harness, foldable thinking TUI, deepagents engine.
|
|
5
5
|
Author: coderio contributors
|
|
6
6
|
License-Expression: MIT
|
|
@@ -15,18 +15,17 @@ Classifier: Operating System :: POSIX :: Linux
|
|
|
15
15
|
Classifier: Programming Language :: Python :: 3
|
|
16
16
|
Classifier: Programming Language :: Python :: 3.11
|
|
17
17
|
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
-
Classifier: Programming Language :: Python :: 3.13
|
|
19
18
|
Classifier: Topic :: Software Development :: Code Generators
|
|
20
19
|
Requires-Python: >=3.11
|
|
21
20
|
Requires-Dist: ddgs>=4.0
|
|
22
|
-
Requires-Dist: deepagents
|
|
21
|
+
Requires-Dist: deepagents<0.8,>=0.7.6
|
|
23
22
|
Requires-Dist: httpx>=0.27
|
|
24
23
|
Requires-Dist: langchain-anthropic>=0.2
|
|
25
24
|
Requires-Dist: langchain-core>=0.3
|
|
26
25
|
Requires-Dist: langchain-openai>=0.2
|
|
27
|
-
Requires-Dist: langchain>=0
|
|
26
|
+
Requires-Dist: langchain>=1.0
|
|
28
27
|
Requires-Dist: langgraph-checkpoint-sqlite>=2.0
|
|
29
|
-
Requires-Dist: langgraph>=0
|
|
28
|
+
Requires-Dist: langgraph>=1.0
|
|
30
29
|
Requires-Dist: pydantic>=2
|
|
31
30
|
Requires-Dist: rich>=13
|
|
32
31
|
Requires-Dist: textual>=0.40
|
|
@@ -47,8 +46,8 @@ Description-Content-Type: text/markdown
|
|
|
47
46
|
|
|
48
47
|
[中文](README.md) | **English**
|
|
49
48
|
|
|
50
|
-
> The agent claims "done" without running the tests? coderio's harness stops it.
|
|
51
|
-
> A local coding agent
|
|
49
|
+
> The agent claims "done" without running the tests? coderio's harness stops it — system-level enforcement, not prompt politeness.
|
|
50
|
+
> A fully open-source local coding agent that runs on **your** endpoint: native Zhipu GLM & StepFun coding-plan support, any Anthropic-protocol or OpenAI-compatible API, four-tier permissions, a layered sandbox, MCP, lifecycle hooks, and an interactive TUI.
|
|
52
51
|
|
|
53
52
|

|
|
54
53
|
|
|
@@ -61,46 +60,87 @@ coderio # onboarding wizard on first launch (pick provider, paste API key, au
|
|
|
61
60
|
|
|
62
61
|
Requires Python 3.11+; Git Bash on Windows. Linux / macOS supported.
|
|
63
62
|
|
|
63
|
+
Optional: MCP external tools (`.mcp.json`) need an extra — `pip install "coderio[mcp]"`; without it MCP tools stay disabled (a notice appears at startup).
|
|
64
|
+
|
|
64
65
|
## Why coderio
|
|
65
66
|
|
|
66
|
-
The shared weakness of coding agents: **the model says "I'm done" and you just have to trust it**.
|
|
67
|
+
The shared weakness of coding agents: **the model says "I'm done" and you just have to trust it**. Most agents treat that as a prompting problem — coderio treats it as an enforcement problem. The harness holds the termination decision and checks tool-call ground truth (what actually ran, what actually got read) before a turn is allowed to end.
|
|
67
68
|
|
|
68
|
-
### The Four Gates: the agent can't
|
|
69
|
+
### The Four Gates: the agent can't talk its way past the harness
|
|
69
70
|
|
|
70
71
|
| Gate | Behavior |
|
|
71
72
|
|---|---|
|
|
72
|
-
| **VerifyGate** | Wrote code, never ran it, wants to finish → intercepted, forced to continue. Parses real exit codes — **a failing test run does NOT count as verified
|
|
73
|
+
| **VerifyGate** | Wrote code, never ran it, wants to finish → intercepted, forced to continue. Parses real exit codes — **a failing test run does NOT count as verified**, and `echo app.py` doesn't count as "running it" |
|
|
73
74
|
| **CompletionGate** | Declares done with pending todos → intercepted |
|
|
74
|
-
| **GroundingGate** | Cites files it never read → intercepted |
|
|
75
|
+
| **GroundingGate** | Cites files it never actually read → intercepted |
|
|
75
76
|
| **PlanGate** | Writes code without a todo list → soft nudge |
|
|
76
77
|
|
|
77
|
-
Not
|
|
78
|
+
Not prompt-level soft rules — a system-level control based on tool-call ground truth, with escalating enforcement: the agent is force-continued twice, then released with a loud warning. Never infinite, never silent.
|
|
79
|
+
|
|
80
|
+

|
|
78
81
|
|
|
79
|
-
###
|
|
82
|
+
### Where coderio fits
|
|
80
83
|
|
|
81
|
-
Zhipu **GLM Coding Plan** and StepFun **Step Plan**
|
|
84
|
+
- **Your endpoint, no middleman.** Bring the API you already pay for: Zhipu **GLM Coding Plan** and StepFun **Step Plan** connect directly over the Anthropic protocol (subscription quota runs a local agent — no proxy layer), and OpenAI / Anthropic / Ollama / any OpenAI-compatible endpoint work the same way, with multi-profile switching.
|
|
85
|
+
- **Enforcement, not vibes.** Verified completion, trust-gated repo config, four-tier permissions, a command blacklist for accident prevention, SSRF-protected web_fetch — each layer isolated in its own module.
|
|
86
|
+
- **A reference you can actually read.** A layered monolith (~16k lines of Python) where harness, permissions, sandbox and trust are separate, individually tested modules — built as a working reference for people building their own agents.
|
|
82
87
|
|
|
83
88
|
### Layered security, honestly stated
|
|
84
89
|
|
|
85
90
|
- Four permission tiers (plan read-only / confirm per-action / auto_edit / full)
|
|
86
91
|
- Command blacklist + whitelist (accident prevention); Linux bubblewrap OS sandbox (boundary enforcement)
|
|
87
|
-
- First-use repo-config trust confirmation (hostile-repo protection); web_fetch SSRF protection
|
|
92
|
+
- First-use repo-config trust confirmation — `config.toml`, `.mcp.json`, skills, **custom commands and custom agents** are all gated (hostile-repo protection); web_fetch SSRF protection
|
|
88
93
|
- The blacklist/whitelist are **accident prevention, not adversarial defense** — adversarial protection comes from the sandbox + permissions; use a VM for hostile code
|
|
89
94
|
|
|
95
|
+
In confirm mode, every write is one keystroke away from allow / deny / custom reply:
|
|
96
|
+
|
|
97
|
+

|
|
98
|
+
|
|
99
|
+
## First task in 3 minutes
|
|
100
|
+
|
|
101
|
+
After install + onboarding, launch the TUI and just talk:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
coderio
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Try this:
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
Find the failing test under tests/, fix it, and run the suite to confirm
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
What you'll see:
|
|
114
|
+
|
|
115
|
+
1. **Thinking streaming live** (Ctrl+O folds/unfolds each round)
|
|
116
|
+
2. **Every tool call on its own line** — files read, commands run, output capped to one summary line
|
|
117
|
+
3. A live **TODO panel** whenever the agent plans with write_todos:
|
|
118
|
+
|
|
119
|
+

|
|
120
|
+
|
|
121
|
+
4. The final answer in a blue **coderio** panel, plus a one-line "files changed this turn" summary; in confirm mode, every disk write goes through the vertical menu above
|
|
122
|
+
5. Skeptical? `/undo` rolls the agent's writes back step by step; `/think` unfolds what it was thinking
|
|
123
|
+
|
|
124
|
+
No TUI? Headless works the same:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
coderio run "count the Python lines under src/ and summarize" --quiet
|
|
128
|
+
```
|
|
129
|
+
|
|
90
130
|
## Feature highlights
|
|
91
131
|
|
|
92
132
|
- **Interactive TUI**: streaming output, foldable thinking (Ctrl+O), collapsible TODO panel, vertical permission menu, task interruption (Esc), slash-command autocomplete, session management
|
|
93
133
|
- **Custom slash commands**: `.coderio/commands/*.md` (project/user layers) turn prompt templates into `/commands` with `$ARGUMENTS` substitution; built-ins can never be shadowed
|
|
94
134
|
- **Custom subagents**: `.coderio/agents/*.md` define personas invokable via `task(subagent_type=...)` — you customize WHO the agent is, its capabilities stay on the read-only stack
|
|
95
135
|
- **File rollback**: every structured agent write is auto-checkpointed; `/undo` reverts step by step (a bad edit is one command from gone)
|
|
96
|
-
- **Plan artifact**: the task list auto-mirrors to `.coderio/plan.md`; edit it by hand and the agent adopts your version at the next turn
|
|
136
|
+
- **Plan artifact**: the task list auto-mirrors to `.coderio/plan.md`; edit it by hand and the agent adopts your version at the next turn (read-only PLAN mode doesn't write it)
|
|
97
137
|
- **Headless mode**: `coderio run "task"` one-shot execution (CI / scripts / benchmarks) with graded exit codes
|
|
98
138
|
- **MCP support**: connect external tools via `.mcp.json` (Claude Code-compatible format), managed with `coderio mcp`
|
|
99
139
|
- **Lifecycle hooks**: `[[hooks]]` run your commands at PreToolUse / PostToolUse / UserPromptSubmit (exit 2 = block) — IO contract compatible with Claude Code
|
|
100
140
|
- **Three-layer skills**: bundled + user + project, progressive disclosure saves context
|
|
101
|
-
- **Context governance**: auto-
|
|
141
|
+
- **Context governance**: deepagents auto-summarization + large-block offload, sqlite checkpoints across turns
|
|
102
142
|
- **Subagents**: research (read-only, double-enforced) + general-purpose (inherits the main agent's full security stack)
|
|
103
|
-
- **Engineering discipline**:
|
|
143
|
+
- **Engineering discipline**: 1280+ tests, coverage gated at 75% in CI, mypy hard gate, uv.lock, 3 OS × 2 Python CI matrix
|
|
104
144
|
|
|
105
145
|
<details>
|
|
106
146
|
<summary><b>Config example</b> (click to expand)</summary>
|
|
@@ -122,7 +162,7 @@ matcher = "write_file|edit_file"
|
|
|
122
162
|
command = "python .hooks/protect.py" # JSON on stdin; exit 2 = block
|
|
123
163
|
```
|
|
124
164
|
|
|
125
|
-
MCP, the sandbox 4-tuple
|
|
165
|
+
Every config field — MCP, hooks, the sandbox 4-tuple — is documented in [docs/CONFIG.md](docs/CONFIG.md); architecture design in [docs/coderio-architecture.md](docs/coderio-architecture.md).
|
|
126
166
|
|
|
127
167
|
</details>
|
|
128
168
|
|
|
@@ -140,12 +180,13 @@ Type `/` inside the TUI for all commands (/resume sessions, /mode permissions, /
|
|
|
140
180
|
|
|
141
181
|
## Known limitations
|
|
142
182
|
|
|
143
|
-
- The Windows write-sandbox currently equals job mode (true isolation awaits the ACL work — documented honestly)
|
|
183
|
+
- The Windows write-sandbox currently equals job mode (true isolation awaits the ACL work — documented honestly); sandboxed commands run through `cmd /c`, so quoting/`$VAR` semantics differ from the Git Bash plain path; **macOS has no OS-level sandbox** (bubblewrap is Linux-only) — use a VM for adversarial scenarios
|
|
184
|
+
- Where a sandbox can't deliver (Linux without bubblewrap), degradation is explicit: tool output is marked `[sandbox unavailable: …]`, and `auto_allow_if_sandboxed` is disabled — execute prompts per command instead of running with "zero isolation + zero confirmation"
|
|
144
185
|
- Blacklist/whitelist are accident-prevention by design (regex can be bypassed by obfuscation); use the sandbox / a VM for adversarial scenarios
|
|
145
186
|
|
|
146
187
|
## Origin
|
|
147
188
|
|
|
148
|
-
A spare-time project, open-sourced as a working reference for developers building their own coding agents. The name is **code + rio** (the author's English name is Lion; "codelion" sounded odd).
|
|
189
|
+
A spare-time project, open-sourced as a working reference for developers building their own coding agents. The name is **code + rio** (the author's English name is Lion; "codelion" sounded odd). Project direction and maintenance status: [ROADMAP_en.md](ROADMAP_en.md).
|
|
149
190
|
|
|
150
191
|
## Contributing & License
|
|
151
192
|
|