turnloop 0.1.8__tar.gz → 0.1.10__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.
- {turnloop-0.1.8 → turnloop-0.1.10}/PKG-INFO +15 -7
- {turnloop-0.1.8 → turnloop-0.1.10}/README.md +14 -6
- {turnloop-0.1.8 → turnloop-0.1.10}/pyproject.toml +9 -1
- turnloop-0.1.10/tests/fixtures/github_chrome.html +12 -0
- turnloop-0.1.10/tests/fixtures/github_page.html +1548 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/tests/test_bash.py +194 -150
- {turnloop-0.1.8 → turnloop-0.1.10}/tests/test_skills_install.py +863 -523
- {turnloop-0.1.8 → turnloop-0.1.10}/tests/test_system_prompt_layout.py +119 -85
- turnloop-0.1.10/tests/test_webfetch.py +70 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/__init__.py +1 -1
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/agent/system_prompt.py +308 -294
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/cli.py +69 -7
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/config.py +5 -1
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/skills_install.py +492 -328
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/tools/bash.py +434 -423
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/tools/webfetch.py +273 -235
- turnloop-0.1.8/.github/workflows/ci.yml +0 -36
- turnloop-0.1.8/.turnloop/.gitignore +0 -2
- turnloop-0.1.8/.turnloop/settings.local.json +0 -3
- {turnloop-0.1.8 → turnloop-0.1.10}/.gitignore +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/tests/conftest.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/tests/fixtures/anthropic_tool_call.sse +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/tests/fixtures/glm_tool_call.sse +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/tests/fixtures/mcp_echo_server.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/tests/test_compaction.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/tests/test_config.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/tests/test_config_screen.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/tests/test_configio.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/tests/test_experiments.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/tests/test_hooks_mcp_commands.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/tests/test_loop.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/tests/test_permissions.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/tests/test_providers.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/tests/test_tools_files.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/tests/test_tui.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/tests/test_websearch.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/__main__.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/agent/__init__.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/agent/factory.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/agent/headless.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/agent/loop.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/agent/subagent.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/commands/__init__.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/commands/dispatch.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/commands/loader.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/configio.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/context/__init__.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/context/budget.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/context/compaction.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/context/memory.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/core/__init__.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/core/events.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/core/ids.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/core/messages.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/core/tokens.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/diagnostics.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/errors.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/__init__.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/configs/bakeoff.yaml +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/configs/ceiling-check.yaml +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/configs/context-glm.yaml +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/configs/context.yaml +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/configs/glm-selfhosted.yaml +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/configs/groq-free.yaml +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/configs/hard-calibration.yaml +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/configs/hard-glm.yaml +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/configs/loop.yaml +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/configs/nvidia-smoke.yaml +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/configs/reliability.yaml +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/configs/rewrite-calibration.yaml +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/configs/smoke.yaml +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/graders.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/report.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/runner.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/suite/default.yaml +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/suite/fixtures/bulky/module_1.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/suite/fixtures/bulky/module_2.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/suite/fixtures/bulky/module_3.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/suite/fixtures/bulky/module_4.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/suite/fixtures/bulky/module_5.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/suite/fixtures/bulky/module_6.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/suite/fixtures/bulky/module_7.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/suite/fixtures/bulky/module_8.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/suite/fixtures/circular_import/models.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/suite/fixtures/circular_import/services.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/suite/fixtures/circular_import/test_cancel.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/suite/fixtures/cli_flag/app.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/suite/fixtures/cross_file_contract/decode.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/suite/fixtures/cross_file_contract/encode.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/suite/fixtures/cross_file_contract/test_roundtrip.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/suite/fixtures/cross_file_contract/test_wire_format.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/suite/fixtures/empty/.keep +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/suite/fixtures/failing_test/calc.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/suite/fixtures/failing_test/test_calc.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/suite/fixtures/generate_bulky.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/suite/fixtures/grep_edit/ingest.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/suite/fixtures/grep_edit/load.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/suite/fixtures/grep_edit/transform.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/suite/fixtures/misleading_traceback/checkout.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/suite/fixtures/misleading_traceback/invoice.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/suite/fixtures/misleading_traceback/pricing.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/suite/fixtures/misleading_traceback/test_checkout.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/suite/fixtures/misleading_traceback/test_invoice.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/suite/fixtures/needle/inventory.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/suite/fixtures/needle/pricing.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/suite/fixtures/needle/shipping.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/suite/fixtures/regression_trap/test_validators.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/suite/fixtures/regression_trap/validators.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/suite/fixtures/rename/billing.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/suite/fixtures/rename/report.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/suite/fixtures/rename/test_billing.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/suite/fixtures/spec/parser.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/suite/fixtures/spec/test_parser.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/suite/fixtures/subtle_spec_edge/leaderboard.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/suite/fixtures/subtle_spec_edge/test_leaderboard.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/experiments/suite/fixtures/util/util.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/hooks/__init__.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/hooks/runner.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/mcp/__init__.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/mcp/adapter.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/mcp/client.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/permissions/__init__.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/permissions/engine.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/permissions/rules.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/providers/__init__.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/providers/anthropic.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/providers/base.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/providers/gemini.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/providers/mock.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/providers/openai_compat.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/providers/pricing.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/providers/registry.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/providers/sse.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/sessions/__init__.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/sessions/models.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/sessions/store.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/tools/__init__.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/tools/ask.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/tools/base.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/tools/builtin.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/tools/edit.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/tools/glob.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/tools/grep.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/tools/read.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/tools/runner.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/tools/shell.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/tools/skill.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/tools/task.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/tools/textio.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/tools/todo.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/tools/websearch.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/tools/write.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/tui/__init__.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/tui/app.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/tui/app.tcss +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/tui/bridge.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/tui/config_screen.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/tui/mcp_screen.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/tui/session_screen.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/tui/widgets/__init__.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/tui/widgets/permission.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/tui/widgets/status.py +0 -0
- {turnloop-0.1.8 → turnloop-0.1.10}/turnloop/tui/widgets/transcript.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: turnloop
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.10
|
|
4
4
|
Summary: A local-first agentic coding harness: streaming tool loop, permission gating, context compaction, subagents, and any LLM provider.
|
|
5
5
|
Project-URL: Homepage, https://github.com/Pranesh-2005/turnloop
|
|
6
6
|
Author: Pranesh
|
|
@@ -49,7 +49,7 @@ tl experiment run smoke # a measurement run, offline and free
|
|
|
49
49
|
|
|
50
50
|
Four runtime dependencies: `textual`, `pydantic`, `httpx`, `pyyaml`. No vendor
|
|
51
51
|
SDKs, no agent framework — the loop is the point, so the loop is written here.
|
|
52
|
-
~
|
|
52
|
+
~21,500 lines of Python, 364 tests, no network in the default test run.
|
|
53
53
|
|
|
54
54
|
---
|
|
55
55
|
|
|
@@ -117,7 +117,7 @@ point.
|
|
|
117
117
|
Verify:
|
|
118
118
|
|
|
119
119
|
```bash
|
|
120
|
-
tl --version # turnloop 0.1.
|
|
120
|
+
tl --version # turnloop 0.1.10
|
|
121
121
|
tl doctor # every provider, key presence, shell, context budget
|
|
122
122
|
```
|
|
123
123
|
|
|
@@ -1023,7 +1023,7 @@ one-line edit in a CRLF checkout does not produce a whole-file diff.
|
|
|
1023
1023
|
## Testing
|
|
1024
1024
|
|
|
1025
1025
|
```bash
|
|
1026
|
-
pytest #
|
|
1026
|
+
pytest # 364 tests, no network
|
|
1027
1027
|
ruff check turnloop
|
|
1028
1028
|
mypy turnloop
|
|
1029
1029
|
```
|
|
@@ -1037,7 +1037,7 @@ mypy turnloop
|
|
|
1037
1037
|
| `test_hooks_mcp_commands.py` | 28 | lifecycle hooks, MCP client, slash commands |
|
|
1038
1038
|
| `test_tui.py` | 25 | Textual snapshots, `/config` and `/mcp add` driven through a real app |
|
|
1039
1039
|
| `test_config.py` | 23 | layering, env overrides, presets, narrow-console guard |
|
|
1040
|
-
| `test_skills_install.py` |
|
|
1040
|
+
| `test_skills_install.py` | 39 | frontmatter validation, GitHub resolution, agent-mirror tiebreak, concurrent fetch ordering, console caps, EOF on every prompt, drive-root refusal |
|
|
1041
1041
|
| `test_loop.py` | 23 | streaming, truncation, iteration cap |
|
|
1042
1042
|
| `test_compaction.py` | 16 | three tiers, tool_use/tool_result invariant |
|
|
1043
1043
|
| `test_configio.py` | 15 | minimal-diff writes, atomic save, secret-bearing MCP targets, the settings deny rules |
|
|
@@ -1092,11 +1092,19 @@ in the system prompt and load their body on demand, which on a 65k window is the
|
|
|
1092
1092
|
difference between having skills and not.
|
|
1093
1093
|
|
|
1094
1094
|
The system prompt also documents this layout to the model itself, as `CONFIG_LAYOUT`
|
|
1095
|
-
—
|
|
1095
|
+
— 432 tokens, in the cacheable region, omitted from the `minimal` variant. Without it
|
|
1096
1096
|
the model cannot configure the tool it is running inside: asked to add an MCP server
|
|
1097
1097
|
it invented `.turnloop/turnloop.config.json`, and asked to install a skill it wrote to
|
|
1098
1098
|
`examples/` — both real outputs from live runs. With it, both go to the right place
|
|
1099
|
-
first try.
|
|
1099
|
+
first try.
|
|
1100
|
+
|
|
1101
|
+
It also names `tl skills add` explicitly and tells the model *not* to run the install
|
|
1102
|
+
scripts skill repos publish for other agents. That paragraph was added after watching
|
|
1103
|
+
three separate sessions try `/plugin marketplace add` as a shell command, then
|
|
1104
|
+
`clawhub install`, then `git clone` plus `npm install` plus `npm test` — twenty-six
|
|
1105
|
+
messages ending in "the ponytail skill has been installed", when nothing had been put
|
|
1106
|
+
anywhere turnloop looks. The same request now costs 11,090 tokens and answers
|
|
1107
|
+
`tl skills add DietrichGebert/ponytail`. It includes the literal YAML frontmatter a skill needs, since a skill with
|
|
1100
1108
|
markdown-bold frontmatter instead of YAML used to vanish with no diagnostic; `/skills`
|
|
1101
1109
|
now also reports anything found on disk but rejected, with the reason and path — see
|
|
1102
1110
|
[Bugs worth reading about](#bugs-worth-reading-about).
|
|
@@ -20,7 +20,7 @@ tl experiment run smoke # a measurement run, offline and free
|
|
|
20
20
|
|
|
21
21
|
Four runtime dependencies: `textual`, `pydantic`, `httpx`, `pyyaml`. No vendor
|
|
22
22
|
SDKs, no agent framework — the loop is the point, so the loop is written here.
|
|
23
|
-
~
|
|
23
|
+
~21,500 lines of Python, 364 tests, no network in the default test run.
|
|
24
24
|
|
|
25
25
|
---
|
|
26
26
|
|
|
@@ -88,7 +88,7 @@ point.
|
|
|
88
88
|
Verify:
|
|
89
89
|
|
|
90
90
|
```bash
|
|
91
|
-
tl --version # turnloop 0.1.
|
|
91
|
+
tl --version # turnloop 0.1.10
|
|
92
92
|
tl doctor # every provider, key presence, shell, context budget
|
|
93
93
|
```
|
|
94
94
|
|
|
@@ -994,7 +994,7 @@ one-line edit in a CRLF checkout does not produce a whole-file diff.
|
|
|
994
994
|
## Testing
|
|
995
995
|
|
|
996
996
|
```bash
|
|
997
|
-
pytest #
|
|
997
|
+
pytest # 364 tests, no network
|
|
998
998
|
ruff check turnloop
|
|
999
999
|
mypy turnloop
|
|
1000
1000
|
```
|
|
@@ -1008,7 +1008,7 @@ mypy turnloop
|
|
|
1008
1008
|
| `test_hooks_mcp_commands.py` | 28 | lifecycle hooks, MCP client, slash commands |
|
|
1009
1009
|
| `test_tui.py` | 25 | Textual snapshots, `/config` and `/mcp add` driven through a real app |
|
|
1010
1010
|
| `test_config.py` | 23 | layering, env overrides, presets, narrow-console guard |
|
|
1011
|
-
| `test_skills_install.py` |
|
|
1011
|
+
| `test_skills_install.py` | 39 | frontmatter validation, GitHub resolution, agent-mirror tiebreak, concurrent fetch ordering, console caps, EOF on every prompt, drive-root refusal |
|
|
1012
1012
|
| `test_loop.py` | 23 | streaming, truncation, iteration cap |
|
|
1013
1013
|
| `test_compaction.py` | 16 | three tiers, tool_use/tool_result invariant |
|
|
1014
1014
|
| `test_configio.py` | 15 | minimal-diff writes, atomic save, secret-bearing MCP targets, the settings deny rules |
|
|
@@ -1063,11 +1063,19 @@ in the system prompt and load their body on demand, which on a 65k window is the
|
|
|
1063
1063
|
difference between having skills and not.
|
|
1064
1064
|
|
|
1065
1065
|
The system prompt also documents this layout to the model itself, as `CONFIG_LAYOUT`
|
|
1066
|
-
—
|
|
1066
|
+
— 432 tokens, in the cacheable region, omitted from the `minimal` variant. Without it
|
|
1067
1067
|
the model cannot configure the tool it is running inside: asked to add an MCP server
|
|
1068
1068
|
it invented `.turnloop/turnloop.config.json`, and asked to install a skill it wrote to
|
|
1069
1069
|
`examples/` — both real outputs from live runs. With it, both go to the right place
|
|
1070
|
-
first try.
|
|
1070
|
+
first try.
|
|
1071
|
+
|
|
1072
|
+
It also names `tl skills add` explicitly and tells the model *not* to run the install
|
|
1073
|
+
scripts skill repos publish for other agents. That paragraph was added after watching
|
|
1074
|
+
three separate sessions try `/plugin marketplace add` as a shell command, then
|
|
1075
|
+
`clawhub install`, then `git clone` plus `npm install` plus `npm test` — twenty-six
|
|
1076
|
+
messages ending in "the ponytail skill has been installed", when nothing had been put
|
|
1077
|
+
anywhere turnloop looks. The same request now costs 11,090 tokens and answers
|
|
1078
|
+
`tl skills add DietrichGebert/ponytail`. It includes the literal YAML frontmatter a skill needs, since a skill with
|
|
1071
1079
|
markdown-bold frontmatter instead of YAML used to vanish with no diagnostic; `/skills`
|
|
1072
1080
|
now also reports anything found on disk but rejected, with the reason and path — see
|
|
1073
1081
|
[Bugs worth reading about](#bugs-worth-reading-about).
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "turnloop"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.10"
|
|
8
8
|
description = "A local-first agentic coding harness: streaming tool loop, permission gating, context compaction, subagents, and any LLM provider."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11"
|
|
@@ -54,6 +54,14 @@ Homepage = "https://github.com/Pranesh-2005/turnloop"
|
|
|
54
54
|
[tool.hatch.build.targets.wheel]
|
|
55
55
|
packages = ["turnloop"]
|
|
56
56
|
|
|
57
|
+
# Without an explicit include, the sdist sweeps up whatever happens to be sitting
|
|
58
|
+
# in the working tree. A stray `git clone` left behind by a failed skill install
|
|
59
|
+
# put 157 of 317 entries — 4.2 MB of an unrelated repository — into the 0.1.8
|
|
60
|
+
# sdist before this was pinned down. An allowlist fails closed: new junk is not
|
|
61
|
+
# published, and a genuinely new top-level path has to be added here on purpose.
|
|
62
|
+
[tool.hatch.build.targets.sdist]
|
|
63
|
+
include = ["turnloop", "tests", "README.md", "pyproject.toml", "LICENSE"]
|
|
64
|
+
|
|
57
65
|
[tool.ruff]
|
|
58
66
|
line-length = 100
|
|
59
67
|
target-version = "py311"
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html><head><title>anthropics/anthropic-sdk-python</title></head>
|
|
3
|
+
<body>
|
|
4
|
+
<nav aria-label="Global"><a href="#start-of-content" data-skip-target-assigned="false" class="px-2 tmp-py-4 color-bg-accent-emphasis color-fg-on-emphasis show-on-focus js-skip-to-content">Skip to content</a></nav>
|
|
5
|
+
<header>
|
|
6
|
+
<nav class="prc-components-UnderlineWrapper-eT-Yj" aria-label="Repository files"><ul class="prc-UnderlineNav-ItemsList-oj8gN prc-components-UnderlineItemList-xKlKC" role="list"><li role="presentation" aria-hidden="true" class="prc-UnderlineNav-WrapSpacer--aLgz"></li><li role="presentation" aria-hidden="true" class="prc-UnderlineNav-WrapSpacer--aLgz"></li><li role="presentation" aria-hidden="true" class="prc-UnderlineNav-WrapSpacer--aLgz"></li><li role="presentation" aria-hidden="true" class="prc-UnderlineNav-WrapSpacer--aLgz"></li><li role="presentation" aria-hidden="true" class="prc-UnderlineNav-WrapSpacer--aLgz"></li><li role="presentation" aria-hidden="true" class="prc-UnderlineNav-WrapSpacer--aLgz"></li><li role="presentation" aria-hidden="true" class="prc-UnderlineNav-WrapSpacer--aLgz"></li><li role="presentation" aria-hidden="true" class="prc-UnderlineNav-WrapSpacer--aLgz"></li><li role="presentation" aria-hidden="true" class="prc-UnderlineNav-WrapSpacer--aLgz"></li><li role="presentation" aria-hidden="true" class="prc-UnderlineNav-WrapSpacer--aLgz"></li><li role="presentation" aria-hidden="true" class="prc-UnderlineNav-WrapSpacer--aLgz"></li><li role="presentation" aria-hidden="true" class="prc-UnderlineNav-WrapSpacer--aLgz"></li><li role="presentation" aria-hidden="true" class="prc-UnderlineNav-WrapSpacer--aLgz"></li><li role="presentation" aria-hidden="true" class="prc-UnderlineNav-WrapSpacer--aLgz"></li><li role="presentation" aria-hidden="true" class="prc-UnderlineNav-WrapSpacer--aLgz"></li><li role="presentation" aria-hidden="true" class="prc-UnderlineNav-WrapSpacer--aLgz"></li><li role="presentation" aria-hidden="true" class="prc-UnderlineNav-WrapSpacer--aLgz"></li><li role="presentation" aria-hidden="true" class="prc-UnderlineNav-WrapSpacer--aLgz"></li><li role="presentation" aria-hidden="true" class="prc-UnderlineNav-WrapSpacer--aLgz"></li><li role="presentation" aria-hidden="true" class="prc-UnderlineNav-WrapSpacer--aLgz"></li><li role="presentation" aria-hidden="true" class="prc-UnderlineNav-WrapSpacer--aLgz"></li><li role="presentation" aria-hidden="true" class="prc-UnderlineNav-WrapSpacer--aLgz"></li><li role="presentation" aria-hidden="true" class="prc-UnderlineNav-WrapSpacer--aLgz"></li><li role="presentation" aria-hidden="true" class="prc-UnderlineNav-WrapSpacer--aLgz"></li><li role="presentation" aria-hidden="true" class="prc-UnderlineNav-WrapSpacer--aLgz"></li><li role="presentation" aria-hidden="true" class="prc-UnderlineNav-WrapSpacer--aLgz"></li><li role="presentation" aria-hidden="true" class="prc-UnderlineNav-WrapSpacer--aLgz"></li><li role="presentation" aria-hidden="true" class="prc-UnderlineNav-WrapSpacer--aLgz"></li><li role="presentation" aria-hidden="true" class="prc-UnderlineNav-WrapSpacer--aLgz"></li><li role="presentation" aria-hidden="true" class="prc-UnderlineNav-WrapSpacer--aLgz"></li><li role="presentation" aria-hidden="true" class="prc-UnderlineNav-WrapSpacer--aLgz"></li><li role="presentation" aria-hidden="true" class="prc-UnderlineNav-WrapSpacer--aLgz"></li><li role="presentation" aria-hidden="true" class="prc-UnderlineNav-WrapSpacer--aLgz"></li><li role="presentation" aria-hidden="true" class="prc-UnderlineNav-WrapSpacer--aLgz"></li><li role="presentation" aria-hidden="true" class="prc-UnderlineNav-WrapSpacer--aLgz"></li><li role="presentation" aria-hidden="true" class="prc-UnderlineNav-WrapSpacer--aLgz"></li><li role="presentation" aria-hidden="true" class="prc-UnderlineNav-WrapSpacer--aLgz"></li><li role="presentation" aria-hidden="true" class="prc-UnderlineNav-WrapSpacer--aLgz"></li><li role="presentation" aria-hidden="true" class="prc-UnderlineNav-WrapSpacer--aLgz"></li><li role="presentation" aria-hidden="true" class="prc-UnderlineNav-WrapSpacer--aLgz"></li><li class="prc-UnderlineNav-UnderlineNavItem-syRjR"><a href="#" aria-current="page" class="prc-components-UnderlineItem-7fP-n"><span data-component="icon"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-book" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M0 1.75A.75.75 0 0 1 .75 1h4.253c1.227 0 2.317.59 3 1.501A3.743 3.743 0 0 1 11.006 1h4.245a.75.75 0 0 1 .75.75v10.5a.75.75 0 0 1-.75.75h-4.507a2.25 2.25 0 0 0-1.591.659l-.622.621a.75.75 0 0 1-1.06 0l-.622-.621A2.25 2.25 0 0 0 5.258 13H.75a.75.75 0 0 1-.75-.75Zm7.251 10.324.004-5.073-.002-2.253A2.25 2.25 0 0 0 5.003 2.5H1.5v9h3.757a3.75 3.75 0 0 1 1.994.574ZM8.755 4.75l-.004 7.322a3.752 3.752 0 0 1 1.992-.572H14.5v-9h-3.495a2.25 2.25 0 0 0-2.25 2.25Z"></path></svg></span><span data-component="text" data-content="README">README</span></a></li></ul></nav>
|
|
7
|
+
</header>
|
|
8
|
+
<main>
|
|
9
|
+
<h1>Claude SDK for Python</h1>
|
|
10
|
+
<p>The Claude SDK for Python provides access to the Claude API from Python applications.</p>
|
|
11
|
+
</main>
|
|
12
|
+
</body></html>
|