lcode-cli 0.7.0__tar.gz → 0.9.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 (100) hide show
  1. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/CHANGELOG.md +42 -1
  2. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/PKG-INFO +7 -3
  3. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/README.md +6 -2
  4. lcode_cli-0.9.0/docs/agents.md +145 -0
  5. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/docs/configuration.md +4 -1
  6. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/docs/how-it-works.md +11 -0
  7. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/docs/index.md +7 -0
  8. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/docs/quickstart.md +1 -1
  9. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/docs/usage.md +51 -3
  10. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/mkdocs.yml +1 -0
  11. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/pyproject.toml +2 -0
  12. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/src/lcode/__init__.py +1 -1
  13. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/src/lcode/agent.py +119 -16
  14. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/src/lcode/cli.py +32 -1
  15. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/src/lcode/config.py +8 -3
  16. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/src/lcode/mcp/commands.py +2 -2
  17. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/src/lcode/memory.py +13 -4
  18. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/src/lcode/ollama.py +4 -1
  19. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/src/lcode/permissions.py +11 -3
  20. lcode_cli-0.9.0/src/lcode/planning.py +138 -0
  21. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/src/lcode/repl.py +79 -2
  22. lcode_cli-0.9.0/src/lcode/subagents.py +688 -0
  23. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/src/lcode/tools.py +49 -1
  24. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/tests/conftest.py +1 -1
  25. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/tests/test_mcp.py +15 -0
  26. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/tests/test_memory.py +1 -0
  27. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/tests/test_permissions.py +8 -0
  28. lcode_cli-0.9.0/tests/test_plan_mode.py +161 -0
  29. lcode_cli-0.9.0/tests/test_subagents.py +386 -0
  30. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/.editorconfig +0 -0
  31. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/.github/CODEOWNERS +0 -0
  32. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  33. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  34. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  35. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/.github/ISSUE_TEMPLATE/model_request.yml +0 -0
  36. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  37. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/.github/dependabot.yml +0 -0
  38. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/.github/workflows/ci.yml +0 -0
  39. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/.github/workflows/docs.yml +0 -0
  40. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/.github/workflows/release.yml +0 -0
  41. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/.gitignore +0 -0
  42. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/.pre-commit-config.yaml +0 -0
  43. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/AGENTS.md +0 -0
  44. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/CODE_OF_CONDUCT.md +0 -0
  45. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/CONTRIBUTING.md +0 -0
  46. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/LICENSE +0 -0
  47. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/SECURITY.md +0 -0
  48. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/docs/assets/demo.svg +0 -0
  49. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/docs/assets/extra.css +0 -0
  50. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/docs/assets/logo.svg +0 -0
  51. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/docs/assets/social-preview.png +0 -0
  52. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/docs/bench.md +0 -0
  53. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/docs/changelog.md +0 -0
  54. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/docs/contributing.md +0 -0
  55. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/docs/installation.md +0 -0
  56. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/docs/mcp.md +0 -0
  57. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/docs/memory.md +0 -0
  58. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/docs/models.md +0 -0
  59. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/docs/sandbox.md +0 -0
  60. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/docs/troubleshooting.md +0 -0
  61. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/install.sh +0 -0
  62. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/overrides/main.html +0 -0
  63. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/scripts/record_demo.py +0 -0
  64. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/scripts/social-preview.html +0 -0
  65. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/src/lcode/__main__.py +0 -0
  66. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/src/lcode/bench.py +0 -0
  67. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/src/lcode/catalog.py +0 -0
  68. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/src/lcode/checkpoints.py +0 -0
  69. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/src/lcode/hardware.py +0 -0
  70. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/src/lcode/limits.py +0 -0
  71. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/src/lcode/mcp/__init__.py +0 -0
  72. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/src/lcode/mcp/auth.py +0 -0
  73. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/src/lcode/mcp/catalog.py +0 -0
  74. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/src/lcode/mcp/catalog.toml +0 -0
  75. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/src/lcode/mcp/client.py +0 -0
  76. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/src/lcode/mcp/config.py +0 -0
  77. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/src/lcode/mcp/http.py +0 -0
  78. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/src/lcode/mcp/manager.py +0 -0
  79. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/src/lcode/mcp/protocol.py +0 -0
  80. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/src/lcode/mcp/stdio.py +0 -0
  81. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/src/lcode/models.toml +0 -0
  82. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/src/lcode/render.py +0 -0
  83. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/src/lcode/sandbox.py +0 -0
  84. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/src/lcode/sessions.py +0 -0
  85. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/src/lcode/vision.py +0 -0
  86. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/src/lcode/web.py +0 -0
  87. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/tests/fake_mcp_server.py +0 -0
  88. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/tests/test_agent.py +0 -0
  89. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/tests/test_bench.py +0 -0
  90. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/tests/test_catalog.py +0 -0
  91. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/tests/test_checkpoints.py +0 -0
  92. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/tests/test_cli.py +0 -0
  93. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/tests/test_config.py +0 -0
  94. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/tests/test_context_picker.py +0 -0
  95. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/tests/test_sandbox.py +0 -0
  96. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/tests/test_sessions.py +0 -0
  97. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/tests/test_tools.py +0 -0
  98. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/tests/test_vision.py +0 -0
  99. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/tests/test_web.py +0 -0
  100. {lcode_cli-0.7.0 → lcode_cli-0.9.0}/uv.lock +0 -0
@@ -6,6 +6,45 @@ All notable changes to lcode are documented here. The format follows
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.9.0] - 2026-10-05
10
+
11
+ ### Added
12
+
13
+ - Plan mode: a `plan` permission mode (Shift+Tab from `ask`, `/mode plan`, `lcode --plan`, or
14
+ `/plan <request>`) in which the model can read, search, run read-only commands, use the web and
15
+ read-only subagents, but can't change anything. It presents a plan with the new `present_plan`
16
+ tool, and you approve it (in `ask` or `auto-edit` mode), edit it, save it to `.lcode/plans/`, or
17
+ send it back with feedback. An approved plan fills the todo list and is kept through compaction;
18
+ `/plan` shows it. See [Plan mode](https://nasser1941.github.io/lcode/usage/#plan-mode).
19
+
20
+ ### Fixed
21
+
22
+ - `lcode mcp add` shows the default value in its questions again, such as `AWS region
23
+ [us-east-1]`; the terminal formatting swallowed it.
24
+ - The end-of-session "Worth remembering?" list shows each note's type (`[feedback]`, `[project]`, …),
25
+ which the same problem hid.
26
+
27
+ ## [0.8.0] - 2026-10-05
28
+
29
+ ### Added
30
+
31
+ - Subagents: the model can hand a task to a subagent with its own fresh context through the new
32
+ `agent` tool, and only the subagent's report comes back, so exploring a large codebase or reading
33
+ long output doesn't fill the main context. Built-in types: `explore` and `plan` (read-only) and
34
+ `worker` (all tools). Custom agents are markdown files in `.lcode/agents/` or
35
+ `~/.config/lcode/agents/`; `@name` asks for one. Subagents use the session's model and context
36
+ window (no reload), permissions (prompts are labelled with the agent), sandbox and checkpoints
37
+ (`/undo` covers their changes). With `max_parallel_agents` above 1 and Ollama's
38
+ `OLLAMA_NUM_PARALLEL`, several run at the same time; workers that do get their own git worktree
39
+ and their changes come back as a diff to approve. `/agents` shows the types and what each
40
+ subagent did; `lcode doctor` estimates how many could run at once. See
41
+ [Subagents](https://nasser1941.github.io/lcode/agents/).
42
+
43
+ ### Changed
44
+
45
+ - A shell command that starts with `cd <folder> &&` counts as read-only when the rest of it does,
46
+ so `cd src && grep -n foo *.py` runs without asking. A `cd` with `$(…)` or backticks still asks.
47
+
9
48
  ## [0.7.0] - 2026-10-05
10
49
 
11
50
  ### Added
@@ -225,7 +264,9 @@ First public release.
225
264
  - `AGENTS.md` project instructions and `/init` to generate them.
226
265
  - One-line installer for Linux and macOS.
227
266
 
228
- [Unreleased]: https://github.com/nasser1941/lcode/compare/v0.7.0...HEAD
267
+ [Unreleased]: https://github.com/nasser1941/lcode/compare/v0.9.0...HEAD
268
+ [0.9.0]: https://github.com/nasser1941/lcode/compare/v0.8.0...v0.9.0
269
+ [0.8.0]: https://github.com/nasser1941/lcode/compare/v0.7.0...v0.8.0
229
270
  [0.7.0]: https://github.com/nasser1941/lcode/compare/v0.6.1...v0.7.0
230
271
  [0.6.1]: https://github.com/nasser1941/lcode/compare/v0.6.0...v0.6.1
231
272
  [0.6.0]: https://github.com/nasser1941/lcode/compare/v0.5.0...v0.6.0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: lcode-cli
3
- Version: 0.7.0
3
+ Version: 0.9.0
4
4
  Summary: A local-first terminal coding agent powered by open-weight models on your own GPU or Mac, via Ollama.
5
5
  Project-URL: Homepage, https://nasser1941.github.io/lcode/
6
6
  Project-URL: Documentation, https://nasser1941.github.io/lcode/
@@ -80,8 +80,13 @@ through [Ollama](https://ollama.com), and when it needs current information it c
80
80
  your approval. `auto-edit` and `yolo` modes when you want speed.
81
81
  - **Sandbox (optional).** `lcode --sandbox` runs the model's shell commands in a container (Docker or
82
82
  Podman) that only sees your project, without network access unless you allow it.
83
+ - **Plan mode.** `/plan <request>` or Shift+Tab: the model explores read-only and presents a plan;
84
+ you approve, edit or send it back before anything changes.
83
85
  - **Undo.** lcode saves a checkpoint before the model changes files; `/undo` takes back the last
84
86
  request's edits, new files and shell-command changes, without touching your git history.
87
+ - **Subagents.** The model hands broad searches, planning and self-contained changes to subagents
88
+ with their own fresh context, so the main conversation keeps only their reports. Define your own
89
+ agent types in `.lcode/agents/`.
85
90
  - **Remembers what matters.** Corrections, decisions and where things live carry over to the next
86
91
  session as short notes, saved by the model, by you (`/remember`) or by a quick check at the end
87
92
  of a session. Not whole conversations, and never secrets.
@@ -192,8 +197,7 @@ fills up. Details: [How it works](https://nasser1941.github.io/lcode/how-it-work
192
197
 
193
198
  See the pinned [Roadmap issue](https://github.com/nasser1941/lcode/issues/10). Next up:
194
199
 
195
- - [Parallel subagents](https://github.com/nasser1941/lcode/issues/40) with their own context
196
- - [Plan mode](https://github.com/nasser1941/lcode/issues/41) and [custom commands and skills](https://github.com/nasser1941/lcode/issues/42)
200
+ - [Custom commands and skills](https://github.com/nasser1941/lcode/issues/42)
197
201
  - [Ready-made MCP for Metabase, Encord and Valohai](https://github.com/nasser1941/lcode/issues/53)
198
202
  - Then: [smarter context for small windows](https://github.com/nasser1941/lcode/issues/46), [language servers](https://github.com/nasser1941/lcode/issues/44), [a repository map with local embeddings](https://github.com/nasser1941/lcode/issues/45), [hooks](https://github.com/nasser1941/lcode/issues/43)
199
203
  - More models in the catalog, and test reports from your hardware ([report one](https://github.com/nasser1941/lcode/issues/new?template=model_request.yml))
@@ -46,8 +46,13 @@ through [Ollama](https://ollama.com), and when it needs current information it c
46
46
  your approval. `auto-edit` and `yolo` modes when you want speed.
47
47
  - **Sandbox (optional).** `lcode --sandbox` runs the model's shell commands in a container (Docker or
48
48
  Podman) that only sees your project, without network access unless you allow it.
49
+ - **Plan mode.** `/plan <request>` or Shift+Tab: the model explores read-only and presents a plan;
50
+ you approve, edit or send it back before anything changes.
49
51
  - **Undo.** lcode saves a checkpoint before the model changes files; `/undo` takes back the last
50
52
  request's edits, new files and shell-command changes, without touching your git history.
53
+ - **Subagents.** The model hands broad searches, planning and self-contained changes to subagents
54
+ with their own fresh context, so the main conversation keeps only their reports. Define your own
55
+ agent types in `.lcode/agents/`.
51
56
  - **Remembers what matters.** Corrections, decisions and where things live carry over to the next
52
57
  session as short notes, saved by the model, by you (`/remember`) or by a quick check at the end
53
58
  of a session. Not whole conversations, and never secrets.
@@ -158,8 +163,7 @@ fills up. Details: [How it works](https://nasser1941.github.io/lcode/how-it-work
158
163
 
159
164
  See the pinned [Roadmap issue](https://github.com/nasser1941/lcode/issues/10). Next up:
160
165
 
161
- - [Parallel subagents](https://github.com/nasser1941/lcode/issues/40) with their own context
162
- - [Plan mode](https://github.com/nasser1941/lcode/issues/41) and [custom commands and skills](https://github.com/nasser1941/lcode/issues/42)
166
+ - [Custom commands and skills](https://github.com/nasser1941/lcode/issues/42)
163
167
  - [Ready-made MCP for Metabase, Encord and Valohai](https://github.com/nasser1941/lcode/issues/53)
164
168
  - Then: [smarter context for small windows](https://github.com/nasser1941/lcode/issues/46), [language servers](https://github.com/nasser1941/lcode/issues/44), [a repository map with local embeddings](https://github.com/nasser1941/lcode/issues/45), [hooks](https://github.com/nasser1941/lcode/issues/43)
165
169
  - More models in the catalog, and test reports from your hardware ([report one](https://github.com/nasser1941/lcode/issues/new?template=model_request.yml))
@@ -0,0 +1,145 @@
1
+ # Subagents
2
+
3
+ A single conversation used to do everything. Exploring a large codebase, reading logs or comparing
4
+ approaches fills the context window with material that's only needed for a moment, and that hurts
5
+ most at 32K to 128K.
6
+
7
+ Now the model can hand a task to a **subagent**: a fresh agent with its own empty context that
8
+ works on the task alone and returns only its report. The main conversation keeps the answer, not
9
+ the 40 files the subagent read to find it.
10
+
11
+ ```text
12
+ ❯ how do the payment webhooks get verified, and where would I add retries?
13
+ ✓ ↳ explore: find webhook verification · 9 tools · 41s
14
+ ✓ ↳ plan: retries for webhook handlers · 6 tools · 38s
15
+ Webhooks are verified in `payments/webhooks.py:88` …
16
+ ```
17
+
18
+ ## Agent types
19
+
20
+ | Type | Does | Tools |
21
+ |---|---|---|
22
+ | `explore` | Finds code and answers questions about the codebase | Read-only: reading and searching files, read-only shell commands, the web |
23
+ | `plan` | Works out a step-by-step plan for a change, without making it | Read-only, like explore |
24
+ | `worker` | Makes a self-contained change and verifies it | All of lcode's tools |
25
+
26
+ The model picks the type and writes the task. A subagent can't see the conversation, so the model
27
+ is told to describe the task completely. Subagents can't start subagents of their own, and they
28
+ don't save [memory](memory.md) notes; they do see the notes and `AGENTS.md`.
29
+
30
+ To ask for a specific agent yourself, mention it: `@plan add a dark mode toggle` (or
31
+ `@agent-plan …`).
32
+
33
+ ## What you see
34
+
35
+ Each subagent gets one progress line with its current action, its tool count and its time. When it
36
+ finishes, the line stays as a summary. `/agents` lists the agent types and the subagents of this
37
+ session; `/agents 2` shows what the second one did, call by call.
38
+
39
+ Ctrl+C stops the subagents and the request.
40
+
41
+ ## Safety
42
+
43
+ Subagents work under the session's rules:
44
+
45
+ - **Permissions.** They use the session's permission mode. Every prompt names the agent
46
+ (`worker agent › Run command`) and is asked in the main terminal, one at a time, even when
47
+ several agents run at once.
48
+ - **Read-only agents** (`explore`, `plan`) can't edit files, and lcode refuses any shell command that
49
+ isn't on the read-only list.
50
+ - **Undo.** A worker's changes are part of your request's checkpoint, so `/undo` takes them back.
51
+ - **Sandbox.** With the [sandbox](sandbox.md) on, their commands run in it too.
52
+
53
+ ## Several at once
54
+
55
+ When the model calls several agents in one response, lcode can run them at the same time. Whether
56
+ that helps depends on Ollama:
57
+
58
+ - By default **Ollama runs one request at a time**. Two agents would take turns, and each turn would
59
+ push the other's conversation out of Ollama's prompt cache, which makes both slower. So lcode
60
+ runs subagents one after another by default (`max_parallel_agents = 1`).
61
+ - Ollama runs several requests at once when its server is started with `OLLAMA_NUM_PARALLEL`. Each
62
+ parallel request gets **its own context cache**, so memory use grows with every slot.
63
+
64
+ To run two at once:
65
+
66
+ ```bash
67
+ OLLAMA_NUM_PARALLEL=2 ollama serve
68
+ lcode config set max_parallel_agents 2
69
+ ```
70
+
71
+ `lcode doctor` estimates how many fit with your model and context window:
72
+
73
+ ```text
74
+ ✓ Agents subagents one at a time
75
+ ! 2 could run at once here (2 × 256K context fits): set OLLAMA_NUM_PARALLEL=2 on the
76
+ Ollama server and max_parallel_agents 2
77
+ ```
78
+
79
+ ### On a 12 GB GPU
80
+
81
+ Subagents use **the session's model and context window**. A different window, or a different
82
+ model, would make Ollama reload the model, and on one GPU that costs more than the subagent saves.
83
+ Some guidance:
84
+
85
+ - With one slot (the default), a subagent's requests push the main conversation out of Ollama's
86
+ cache, so the main model reads its whole context again afterwards. qwen3.6-35b reads about 850
87
+ tokens a second on a 12 GB laptop GPU: ~35 s for a 30K-token conversation. Delegating pays off when the subagent
88
+ would otherwise add much more than that to the main context.
89
+ - Two slots keep the main conversation cached while a subagent works. qwen3.6-35b's context cache
90
+ is small, so two slots of 128K fit in 12 GB of VRAM plus system RAM, but the extra cache sits in
91
+ system RAM and slows the model down.
92
+ - Smaller context windows leave room for more slots: `/context 64k` with
93
+ `OLLAMA_NUM_PARALLEL=3`.
94
+
95
+ ## Workers that run together
96
+
97
+ A worker edits your working tree directly. When **two or more workers** (or other agents that can
98
+ change files) run at the same time, each gets its own **git worktree** instead, created from your
99
+ working tree as it is now, uncommitted and untracked files included. When a worker finishes,
100
+ lcode shows its changes as a diff and asks before applying them to your working tree. The diff is
101
+ applied automatically in `auto-edit` and `yolo` mode. If the diff doesn't apply cleanly, lcode
102
+ saves it as a patch file and tells the model where.
103
+
104
+ Worktrees live in `.git/lcode-worktrees/` and are removed when the worker is done. Outside a git
105
+ repository, or before the first commit, workers run one after another in the working tree.
106
+
107
+ ## Custom agents
108
+
109
+ Define your own agent types as markdown files: the frontmatter describes the agent, and the body is
110
+ its instructions.
111
+
112
+ ```markdown
113
+ ---
114
+ description: reviews a change for bugs and missing tests (read-only)
115
+ tools: read-only
116
+ max_steps: 30
117
+ ---
118
+ Review the change described in the task. Read the changed code and its callers.
119
+ Report bugs first, with `path:line`, then missing tests, then style. Don't fix anything.
120
+ ```
121
+
122
+ | Key | Meaning |
123
+ |---|---|
124
+ | `description` | What it does; the main model reads this to decide when to use it (required) |
125
+ | `tools` | `all` (default), `read-only`, or a list such as `read_file, grep, bash` |
126
+ | `read_only` | `true` to allow only read-only shell commands (set by `tools: read-only`) |
127
+ | `max_steps` | Tool-calling steps before it must report (default 60, at most 200) |
128
+ | `model` | Another Ollama model for this agent. Only worth it if both fit in memory at once |
129
+ | `isolation` | `auto` (default: a worktree only when running with other editing agents), `worktree` (always) or `none` |
130
+
131
+ | Folder | Agents |
132
+ |---|---|
133
+ | `.lcode/agents/<name>.md` in the repository | For this repository; commit them to share them |
134
+ | `~/.config/lcode/agents/<name>.md` | For every repository |
135
+
136
+ The file name is the agent's name. A repository's agent overrides one of yours with the same name,
137
+ and both override the built-in types. `/agents` and `lcode doctor` point out files that couldn't be
138
+ read.
139
+
140
+ ## Settings
141
+
142
+ | Setting | Default | |
143
+ |---|---|---|
144
+ | `subagents` | `true` | Let the model use the `agent` tool |
145
+ | `max_parallel_agents` | `1` | How many subagents run at the same time (see [Several at once](#several-at-once)) |
@@ -20,7 +20,7 @@ lcode config path # print the file location
20
20
  | `num_batch` | 512 | Prompt batch size. Larger reads prompts faster but needs more GPU memory |
21
21
  | `keep_alive` | `30m` | How long Ollama keeps the model in memory after the last request |
22
22
  | `ollama_host` | `http://localhost:11434` | Ollama server URL |
23
- | `permission_mode` | `ask` | `ask`, `auto-edit` or `yolo` |
23
+ | `permission_mode` | `ask` | `ask`, `plan`, `auto-edit` or `yolo` |
24
24
  | `think` | `true` | Let the model reason before answering |
25
25
  | `web` | `on` | Web search and page fetching: `on`, `ask` (before each search/website) or `off` |
26
26
  | `search_backend` | `auto` | `auto`, `ollama`, `brave`, `tavily` or `searxng`; `auto` uses the first one configured |
@@ -31,6 +31,8 @@ lcode config path # print the file location
31
31
  | `vision_model` | `auto` | The model that [looks at images](usage.md#images): `auto`, `off` or an Ollama model that can see |
32
32
  | `mcp_tools` | `auto` | How [MCP](mcp.md#context) tool definitions reach the model: `auto`, `direct` or `search` (on demand) |
33
33
  | `memory` | `ask` | [Notes that carry over](memory.md) to later sessions: `ask` (confirm each), `auto` or `off` |
34
+ | `subagents` | `true` | Let the model hand tasks to [subagents](agents.md) with their own context |
35
+ | `max_parallel_agents` | `1` | Subagents that run at the same time; more needs `OLLAMA_NUM_PARALLEL` on the Ollama server ([details](agents.md#several-at-once)) |
34
36
  | `checkpoints` | `true` | Save a checkpoint before the model changes files, so [`/undo`](usage.md#undo-and-checkpoints) can restore them |
35
37
 
36
38
  Example file:
@@ -72,6 +74,7 @@ Environment variables override the file, which is useful for one-off runs and CI
72
74
  | `~/.local/state/lcode/mcp-logs/` | Error output of local MCP servers |
73
75
  | `~/.local/state/lcode/checkpoints/` | Checkpoints for `/undo` (copies of your project's files; deleted after 14 days) |
74
76
  | `~/.local/state/lcode/memory/` | [Memory](memory.md) notes: `user/` for every repository, `projects/<repository>/` for each one |
77
+ | `~/.config/lcode/agents/` | Your [custom agents](agents.md#custom-agents) (a repository's go in `.lcode/agents/`) |
75
78
  | `~/.local/state/lcode/limits.json` | Context sizes that ran out of GPU memory on this machine (safe to delete) |
76
79
 
77
80
  Sessions contain everything the model read, including file contents. Delete the folder to clear them.
@@ -29,6 +29,15 @@ All tools return text, and failures come back to the model as `Error: …` messa
29
29
  crashing the session, so the model can correct itself (for example re-read a file when an edit
30
30
  didn't match).
31
31
 
32
+ ## Subagents
33
+
34
+ The `agent` tool starts a [subagent](agents.md): another agent loop with its own conversation, the
35
+ same model and context window (so Ollama doesn't reload anything), the session's permissions,
36
+ sandbox and checkpoints, and a filtered set of tools. Only its final report goes back into the main
37
+ conversation. Several subagents run in threads when `max_parallel_agents` allows; their permission
38
+ prompts are queued and asked in the main thread. Workers that edit files at the same time each work
39
+ in a temporary git worktree, and their changes come back as a diff.
40
+
32
41
  ## Context management
33
42
 
34
43
  Ollama keeps the processed conversation in its KV cache, so each turn only processes the new tokens.
@@ -79,6 +88,8 @@ the Ollama server you configure, it only contacts the web when the model searche
79
88
  | `mcp/` | MCP client: stdio and HTTP transports, OAuth sign-in, server settings, the catalog, `lcode mcp` |
80
89
  | `bench.py` | `lcode bench`: the benchmark tasks, their checks and the reports |
81
90
  | `vision.py` | Looking at images with a model that can see |
91
+ | `subagents.py` | Subagents: agent types, running them (also in parallel), worktrees for workers |
92
+ | `planning.py` | Plan mode: what it allows, presenting a plan and approving it |
82
93
  | `memory.py` | Notes that carry over between sessions, and the end-of-session check |
83
94
  | `sandbox.py` | The optional container for shell commands |
84
95
  | `checkpoints.py` | Snapshots before the model changes files, for `/undo` and `/rewind` |
@@ -69,6 +69,13 @@ until the task is done, asking before it changes anything.
69
69
  Every edit is shown as a diff and every non-read-only command needs your approval, unless you
70
70
  choose otherwise. `/undo` takes back a request's file changes.
71
71
 
72
+ - :material-account-multiple-outline:{ .lg .middle } **Subagents**
73
+
74
+ ---
75
+
76
+ Broad searches, planning and self-contained changes go to [subagents](agents.md) with their own
77
+ context, so the main conversation stays small.
78
+
72
79
  - :material-brain:{ .lg .middle } **Remembers what matters**
73
80
 
74
81
  ---
@@ -12,7 +12,7 @@ lcode
12
12
 
13
13
  ```text
14
14
  ╭──────────────────────────────────────────────╮
15
- │ lcode v0.7.0 — local coding agent │
15
+ │ lcode v0.9.0 — local coding agent │
16
16
  │ │
17
17
  │ model lcode-qwen3.6-35b │
18
18
  │ context 256K tokens │
@@ -20,6 +20,7 @@ lcode mcp [catalog|add|list] # connect MCP servers: Jira, GitHub, AWS, databases
20
20
  | `-r, --repo DIR` | Work in another directory |
21
21
  | `-c, --continue` | Continue the most recently used session in this directory |
22
22
  | `--resume [SESSION]` | Resume a saved session: pick from a list, or give its number, name or id |
23
+ | `--plan` | Start in [plan mode](#plan-mode): agree on a plan before anything changes |
23
24
  | `--auto-edit` | Apply file edits without asking (commands still ask) |
24
25
  | `--yolo` | Never ask for permission |
25
26
  | `--no-think` | Turn off the model's reasoning: faster, less accurate |
@@ -38,9 +39,10 @@ lcode mcp [catalog|add|list] # connect MCP servers: Jira, GitHub, AWS, databases
38
39
  | ++esc++ ++enter++ or a trailing `\` | New line |
39
40
  | ++ctrl+c++ | Interrupt the model or a running command |
40
41
  | ++ctrl+d++ | Quit |
41
- | ++shift+tab++ | Cycle permission mode: ask → auto-edit → yolo |
42
+ | ++shift+tab++ | Cycle permission mode: ask → plan → auto-edit → yolo |
42
43
  | ++tab++ | Complete slash commands and `@` paths |
43
44
  | `@path` | Attach a file (or a directory listing) to your message |
45
+ | `@name` | Ask for a [subagent](agents.md) of that type, e.g. `@plan` |
44
46
 
45
47
  The status bar shows the model, how full the context window is, the permission mode and whether
46
48
  reasoning is on.
@@ -57,16 +59,18 @@ reasoning is on.
57
59
  | `/undo` | Undo the file changes of the last request ([details](#undo-and-checkpoints)) |
58
60
  | `/rewind [N]` | Go back to before request N: its files, and optionally the conversation |
59
61
  | `/checkpoints` | List the requests that changed files, and which files |
62
+ | `/agents [N]` | [Subagent](agents.md) types, and what this session's subagents did |
60
63
  | `/remember [-g] TEXT` | Save a [note](memory.md) for later sessions (`-g`: for every repository) |
61
64
  | `/memory [show\|edit\|delete N]` | The [notes](memory.md) lcode remembers |
62
65
  | `/sandbox [network on\|off]` | The [sandbox](sandbox.md) for shell commands |
63
66
  | `/mcp [tools\|login\|restart NAME]` | [MCP servers](mcp.md), their status and tools |
67
+ | `/plan [request]` | Work out a [plan](#plan-mode) before changing anything, or show the approved plan |
64
68
  | `/compact [focus]` | Summarize the conversation to free context |
65
69
  | `/context [size]` | Show how full the context window is and change its size: pick from a list with memory estimates, or give a size like `/context 128k` (`/ctx` is a shortcut) |
66
70
  | `/model [name]`, `/models` | Switch model, list models |
67
71
  | `/think [on\|off]` | Toggle reasoning |
68
72
  | `/verbose` | Toggle showing the reasoning text |
69
- | `/mode [ask\|auto-edit\|yolo]` | Set the permission mode |
73
+ | `/mode [ask\|plan\|auto-edit\|yolo]` | Set the permission mode |
70
74
  | `/cd DIR` | Change the working directory |
71
75
  | `/todos` | Show the model's task list |
72
76
  | `/exit` | Quit |
@@ -85,6 +89,10 @@ reasoning is on.
85
89
  | `todo_write` | Keep a visible task list for multi-step work |
86
90
  | `web_search` | Search the web for current information (needs a [search provider](#web-search)) |
87
91
  | `web_fetch` | Read a web page or text file by URL as clean text |
92
+ | `view_image` | Look at an image: a model that can see describes it ([Images](#images)) |
93
+ | `agent` | Hand a task to a [subagent](agents.md) with its own context; only its report comes back |
94
+ | `memory` | Save, update or delete [notes](memory.md) that later sessions load |
95
+ | `present_plan` | In [plan mode](#plan-mode): show the plan and ask for approval |
88
96
 
89
97
  lcode refuses to edit a file the model hasn't read in the session, or one that changed on disk since
90
98
  it was read, so the model always edits the current version.
@@ -122,12 +130,16 @@ image support off with `lcode config set vision_model off`.
122
130
  | Mode | File edits | Shell commands |
123
131
  |---|---|---|
124
132
  | `ask` (default) | ask | ask, except read-only commands |
133
+ | `plan` | refused | only read-only commands ([Plan mode](#plan-mode)) |
125
134
  | `auto-edit` | automatic | ask, except read-only commands |
126
135
  | `yolo` | automatic | automatic |
127
136
 
137
+ ++shift+tab++ cycles through them in this order, `/mode` sets one, and `--plan`, `--auto-edit` and
138
+ `--yolo` start in one.
139
+
128
140
  Read-only commands run without asking: `ls`, `cat`, `head`, `tail`, `grep`, `rg`, `find`, `tree`,
129
141
  `wc`, `diff`, `git status/log/diff/show/branch/blame` and similar, as long as they don't redirect
130
- output, chain commands or run subshells.
142
+ output, chain commands or run subshells. A `cd <folder> &&` in front is fine.
131
143
 
132
144
  When asked, answer ++y++ (once), ++a++ (always, for this command or for all edits, until you quit)
133
145
  or ++n++. Text after ++n++ goes to the model as instructions: `n run the tests with -x first`.
@@ -141,6 +153,42 @@ or ++n++. Text after ++n++ goes to the model as instructions: `n run the tests w
141
153
  With the [sandbox](sandbox.md) on, `auto-edit` mode runs shell commands without asking too: they can
142
154
  only reach the project, and `/undo` can take their changes back.
143
155
 
156
+ ## Plan mode
157
+
158
+ Local models are slower than cloud models and make more mistakes, so on a bigger change it pays to
159
+ agree on the approach before the model starts editing. In **plan mode** the model can read, search,
160
+ run read-only commands, use the web and [explore and plan subagents](agents.md), but it can't
161
+ change anything. It ends by presenting a plan: numbered steps, the files it will change, the risks
162
+ and how it will verify the work.
163
+
164
+ ```text
165
+ ❯ /plan add retries to the webhook handlers
166
+ …
167
+ ╭─ Plan: Retries for webhook handlers ───────────────────────────────────────────╮
168
+ │ 1. Wrap the HTTP call in payments/webhooks.py:88 in a retry loop (3 tries, …) │
169
+ │ 2. Add tests for a timeout and a 500 in tests/test_webhooks.py │
170
+ │ Risks: duplicate deliveries if the endpoint isn't idempotent … │
171
+ │ Verify: pytest tests/test_webhooks.py │
172
+ ╰────────────────────────────────────────────────────────────────────────────────╯
173
+ [y] run it, asking before changes · [a] run it, edits without asking (auto-edit)
174
+ [e] edit the plan · [s] save it to .lcode/plans/ · [n] keep planning (+ what to change)
175
+ >
176
+ ```
177
+
178
+ | Answer | |
179
+ |---|---|
180
+ | ++y++ or ++enter++ | Approve: lcode switches to `ask` mode and the model starts on the plan right away |
181
+ | ++a++ | Approve and switch to `auto-edit`, so file edits don't ask |
182
+ | ++e++ | Edit the plan in your editor first; the model follows your version |
183
+ | ++s++ | Save it as `.lcode/plans/<title>.md`, for example to share it or commit it |
184
+ | ++n++ + text | Send it back: `n keep the old API working` |
185
+
186
+ After approval, the todo list is filled from the plan's numbered steps, and the plan is kept word
187
+ for word when the conversation is compacted. `/plan` shows the approved plan.
188
+
189
+ Start planning with `/plan <request>` (switches to plan mode and sends the request), with
190
+ ++shift+tab++ (one step from `ask`), or with `lcode --plan`.
191
+
144
192
  ## Undo and checkpoints
145
193
 
146
194
  Before the model first changes anything in a request (an edit, a new file, or a shell command that
@@ -93,6 +93,7 @@ nav:
93
93
  - Guide:
94
94
  - Using lcode: usage.md
95
95
  - Memory: memory.md
96
+ - Subagents: agents.md
96
97
  - Models & context windows: models.md
97
98
  - Benchmarking models: bench.md
98
99
  - MCP servers: mcp.md
@@ -70,6 +70,8 @@ ignore = [
70
70
  [tool.ruff.lint.per-file-ignores]
71
71
  "src/lcode/agent.py" = ["E501"] # the prompts are prose; wrapping them would change what the model sees
72
72
  "src/lcode/memory.py" = ["E501"]
73
+ "src/lcode/subagents.py" = ["E501"]
74
+ "src/lcode/planning.py" = ["E501"]
73
75
 
74
76
  [tool.pytest.ini_options]
75
77
  testpaths = ["tests"]
@@ -1,3 +1,3 @@
1
1
  """lcode — a local-first terminal coding agent powered by open-weight models via Ollama."""
2
2
 
3
- __version__ = "0.7.0"
3
+ __version__ = "0.9.0"