lcode-cli 0.6.1__tar.gz → 0.8.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 (98) hide show
  1. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/CHANGELOG.md +38 -1
  2. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/PKG-INFO +10 -1
  3. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/README.md +9 -0
  4. lcode_cli-0.8.0/docs/agents.md +145 -0
  5. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/docs/configuration.md +6 -0
  6. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/docs/how-it-works.md +15 -3
  7. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/docs/index.md +14 -0
  8. lcode_cli-0.8.0/docs/memory.md +128 -0
  9. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/docs/quickstart.md +2 -1
  10. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/docs/usage.md +12 -0
  11. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/mkdocs.yml +2 -0
  12. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/pyproject.toml +2 -0
  13. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/src/lcode/__init__.py +1 -1
  14. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/src/lcode/agent.py +133 -18
  15. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/src/lcode/cli.py +38 -0
  16. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/src/lcode/config.py +14 -1
  17. lcode_cli-0.8.0/src/lcode/memory.py +526 -0
  18. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/src/lcode/ollama.py +4 -1
  19. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/src/lcode/permissions.py +16 -3
  20. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/src/lcode/repl.py +198 -0
  21. lcode_cli-0.8.0/src/lcode/subagents.py +688 -0
  22. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/src/lcode/tools.py +56 -1
  23. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/tests/conftest.py +4 -2
  24. lcode_cli-0.8.0/tests/test_memory.py +341 -0
  25. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/tests/test_permissions.py +8 -0
  26. lcode_cli-0.8.0/tests/test_subagents.py +386 -0
  27. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/uv.lock +23 -23
  28. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/.editorconfig +0 -0
  29. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/.github/CODEOWNERS +0 -0
  30. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  31. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  32. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  33. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/.github/ISSUE_TEMPLATE/model_request.yml +0 -0
  34. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  35. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/.github/dependabot.yml +0 -0
  36. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/.github/workflows/ci.yml +0 -0
  37. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/.github/workflows/docs.yml +0 -0
  38. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/.github/workflows/release.yml +0 -0
  39. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/.gitignore +0 -0
  40. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/.pre-commit-config.yaml +0 -0
  41. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/AGENTS.md +0 -0
  42. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/CODE_OF_CONDUCT.md +0 -0
  43. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/CONTRIBUTING.md +0 -0
  44. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/LICENSE +0 -0
  45. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/SECURITY.md +0 -0
  46. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/docs/assets/demo.svg +0 -0
  47. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/docs/assets/extra.css +0 -0
  48. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/docs/assets/logo.svg +0 -0
  49. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/docs/assets/social-preview.png +0 -0
  50. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/docs/bench.md +0 -0
  51. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/docs/changelog.md +0 -0
  52. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/docs/contributing.md +0 -0
  53. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/docs/installation.md +0 -0
  54. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/docs/mcp.md +0 -0
  55. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/docs/models.md +0 -0
  56. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/docs/sandbox.md +0 -0
  57. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/docs/troubleshooting.md +0 -0
  58. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/install.sh +0 -0
  59. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/overrides/main.html +0 -0
  60. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/scripts/record_demo.py +0 -0
  61. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/scripts/social-preview.html +0 -0
  62. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/src/lcode/__main__.py +0 -0
  63. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/src/lcode/bench.py +0 -0
  64. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/src/lcode/catalog.py +0 -0
  65. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/src/lcode/checkpoints.py +0 -0
  66. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/src/lcode/hardware.py +0 -0
  67. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/src/lcode/limits.py +0 -0
  68. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/src/lcode/mcp/__init__.py +0 -0
  69. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/src/lcode/mcp/auth.py +0 -0
  70. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/src/lcode/mcp/catalog.py +0 -0
  71. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/src/lcode/mcp/catalog.toml +0 -0
  72. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/src/lcode/mcp/client.py +0 -0
  73. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/src/lcode/mcp/commands.py +0 -0
  74. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/src/lcode/mcp/config.py +0 -0
  75. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/src/lcode/mcp/http.py +0 -0
  76. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/src/lcode/mcp/manager.py +0 -0
  77. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/src/lcode/mcp/protocol.py +0 -0
  78. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/src/lcode/mcp/stdio.py +0 -0
  79. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/src/lcode/models.toml +0 -0
  80. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/src/lcode/render.py +0 -0
  81. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/src/lcode/sandbox.py +0 -0
  82. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/src/lcode/sessions.py +0 -0
  83. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/src/lcode/vision.py +0 -0
  84. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/src/lcode/web.py +0 -0
  85. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/tests/fake_mcp_server.py +0 -0
  86. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/tests/test_agent.py +0 -0
  87. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/tests/test_bench.py +0 -0
  88. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/tests/test_catalog.py +0 -0
  89. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/tests/test_checkpoints.py +0 -0
  90. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/tests/test_cli.py +0 -0
  91. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/tests/test_config.py +0 -0
  92. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/tests/test_context_picker.py +0 -0
  93. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/tests/test_mcp.py +0 -0
  94. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/tests/test_sandbox.py +0 -0
  95. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/tests/test_sessions.py +0 -0
  96. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/tests/test_tools.py +0 -0
  97. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/tests/test_vision.py +0 -0
  98. {lcode_cli-0.6.1 → lcode_cli-0.8.0}/tests/test_web.py +0 -0
@@ -6,6 +6,41 @@ All notable changes to lcode are documented here. The format follows
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.8.0] - 2026-10-05
10
+
11
+ ### Added
12
+
13
+ - Subagents: the model can hand a task to a subagent with its own fresh context through the new
14
+ `agent` tool, and only the subagent's report comes back, so exploring a large codebase or reading
15
+ long output doesn't fill the main context. Built-in types: `explore` and `plan` (read-only) and
16
+ `worker` (all tools). Custom agents are markdown files in `.lcode/agents/` or
17
+ `~/.config/lcode/agents/`; `@name` asks for one. Subagents use the session's model and context
18
+ window (no reload), permissions (prompts are labelled with the agent), sandbox and checkpoints
19
+ (`/undo` covers their changes). With `max_parallel_agents` above 1 and Ollama's
20
+ `OLLAMA_NUM_PARALLEL`, several run at the same time; workers that do get their own git worktree
21
+ and their changes come back as a diff to approve. `/agents` shows the types and what each
22
+ subagent did; `lcode doctor` estimates how many could run at once. See
23
+ [Subagents](https://nasser1941.github.io/lcode/agents/).
24
+
25
+ ### Changed
26
+
27
+ - A shell command that starts with `cd <folder> &&` counts as read-only when the rest of it does,
28
+ so `cd src && grep -n foo *.py` runs without asking. A `cd` with `$(…)` or backticks still asks.
29
+
30
+ ## [0.7.0] - 2026-10-05
31
+
32
+ ### Added
33
+
34
+ - Memory across sessions: lcode keeps short notes that later sessions load, only key knowledge and
35
+ not whole conversations. The model saves them with its new `memory` tool (and updates or deletes
36
+ them), you add them with `/remember`, and when a session ends (on quit, `/clear` or before
37
+ compaction) one quick question asks the model what from it is worth remembering. Notes are
38
+ per repository, shared by its git worktrees, plus a few for every repository; they're plain
39
+ markdown files, managed with `/memory`. The index in the system prompt is capped at about 2,000
40
+ tokens. Notes that look like they contain secrets are never saved. The `memory` setting is `ask`
41
+ (confirm each note, the default), `auto` or `off`; `--no-memory` turns it off for a session.
42
+ See [Memory](https://nasser1941.github.io/lcode/memory/).
43
+
9
44
  ## [0.6.1] - 2026-10-01
10
45
 
11
46
  ### Fixed
@@ -211,7 +246,9 @@ First public release.
211
246
  - `AGENTS.md` project instructions and `/init` to generate them.
212
247
  - One-line installer for Linux and macOS.
213
248
 
214
- [Unreleased]: https://github.com/nasser1941/lcode/compare/v0.6.1...HEAD
249
+ [Unreleased]: https://github.com/nasser1941/lcode/compare/v0.8.0...HEAD
250
+ [0.8.0]: https://github.com/nasser1941/lcode/compare/v0.7.0...v0.8.0
251
+ [0.7.0]: https://github.com/nasser1941/lcode/compare/v0.6.1...v0.7.0
215
252
  [0.6.1]: https://github.com/nasser1941/lcode/compare/v0.6.0...v0.6.1
216
253
  [0.6.0]: https://github.com/nasser1941/lcode/compare/v0.5.0...v0.6.0
217
254
  [0.5.0]: https://github.com/nasser1941/lcode/compare/v0.4.1...v0.5.0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: lcode-cli
3
- Version: 0.6.1
3
+ Version: 0.8.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/
@@ -82,6 +82,12 @@ through [Ollama](https://ollama.com), and when it needs current information it c
82
82
  Podman) that only sees your project, without network access unless you allow it.
83
83
  - **Undo.** lcode saves a checkpoint before the model changes files; `/undo` takes back the last
84
84
  request's edits, new files and shell-command changes, without touching your git history.
85
+ - **Subagents.** The model hands broad searches, planning and self-contained changes to subagents
86
+ with their own fresh context, so the main conversation keeps only their reports. Define your own
87
+ agent types in `.lcode/agents/`.
88
+ - **Remembers what matters.** Corrections, decisions and where things live carry over to the next
89
+ session as short notes, saved by the model, by you (`/remember`) or by a quick check at the end
90
+ of a session. Not whole conversations, and never secrets.
85
91
  - **Bring your own model.** Eight curated open-weight models, all tested end to end, or any Ollama model
86
92
  with tool calling.
87
93
  - **MCP servers, ready to go.** Connect Jira and Confluence, GitHub, AWS, Google Drive, Grafana,
@@ -189,6 +195,9 @@ fills up. Details: [How it works](https://nasser1941.github.io/lcode/how-it-work
189
195
 
190
196
  See the pinned [Roadmap issue](https://github.com/nasser1941/lcode/issues/10). Next up:
191
197
 
198
+ - [Plan mode](https://github.com/nasser1941/lcode/issues/41) and [custom commands and skills](https://github.com/nasser1941/lcode/issues/42)
199
+ - [Ready-made MCP for Metabase, Encord and Valohai](https://github.com/nasser1941/lcode/issues/53)
200
+ - 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)
192
201
  - More models in the catalog, and test reports from your hardware ([report one](https://github.com/nasser1941/lcode/issues/new?template=model_request.yml))
193
202
 
194
203
  ## Contributing
@@ -48,6 +48,12 @@ through [Ollama](https://ollama.com), and when it needs current information it c
48
48
  Podman) that only sees your project, without network access unless you allow it.
49
49
  - **Undo.** lcode saves a checkpoint before the model changes files; `/undo` takes back the last
50
50
  request's edits, new files and shell-command changes, without touching your git history.
51
+ - **Subagents.** The model hands broad searches, planning and self-contained changes to subagents
52
+ with their own fresh context, so the main conversation keeps only their reports. Define your own
53
+ agent types in `.lcode/agents/`.
54
+ - **Remembers what matters.** Corrections, decisions and where things live carry over to the next
55
+ session as short notes, saved by the model, by you (`/remember`) or by a quick check at the end
56
+ of a session. Not whole conversations, and never secrets.
51
57
  - **Bring your own model.** Eight curated open-weight models, all tested end to end, or any Ollama model
52
58
  with tool calling.
53
59
  - **MCP servers, ready to go.** Connect Jira and Confluence, GitHub, AWS, Google Drive, Grafana,
@@ -155,6 +161,9 @@ fills up. Details: [How it works](https://nasser1941.github.io/lcode/how-it-work
155
161
 
156
162
  See the pinned [Roadmap issue](https://github.com/nasser1941/lcode/issues/10). Next up:
157
163
 
164
+ - [Plan mode](https://github.com/nasser1941/lcode/issues/41) and [custom commands and skills](https://github.com/nasser1941/lcode/issues/42)
165
+ - [Ready-made MCP for Metabase, Encord and Valohai](https://github.com/nasser1941/lcode/issues/53)
166
+ - 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)
158
167
  - More models in the catalog, and test reports from your hardware ([report one](https://github.com/nasser1941/lcode/issues/new?template=model_request.yml))
159
168
 
160
169
  ## Contributing
@@ -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)) |
@@ -30,6 +30,9 @@ lcode config path # print the file location
30
30
  | `sandbox_network` | `false` | Let commands in the sandbox use the network |
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
+ | `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)) |
33
36
  | `checkpoints` | `true` | Save a checkpoint before the model changes files, so [`/undo`](usage.md#undo-and-checkpoints) can restore them |
34
37
 
35
38
  Example file:
@@ -55,6 +58,7 @@ Environment variables override the file, which is useful for one-off runs and CI
55
58
  | `OLLAMA_HOST` | `ollama_host` (same variable the Ollama CLI uses) |
56
59
  | `LCODE_WEB` | `web` |
57
60
  | `LCODE_SANDBOX` | `sandbox` |
61
+ | `LCODE_MEMORY` | `memory` |
58
62
  | `OLLAMA_API_KEY`, `BRAVE_API_KEY`, `TAVILY_API_KEY` | API key for that [search provider](usage.md#web-search) (never stored in the config file) |
59
63
  | `LCODE_HOME` | where sessions and prompt history are stored |
60
64
 
@@ -69,6 +73,8 @@ Environment variables override the file, which is useful for one-off runs and CI
69
73
  | `~/.local/state/lcode/mcp-auth/` | Sign-in tokens for remote MCP servers (readable only by you) |
70
74
  | `~/.local/state/lcode/mcp-logs/` | Error output of local MCP servers |
71
75
  | `~/.local/state/lcode/checkpoints/` | Checkpoints for `/undo` (copies of your project's files; deleted after 14 days) |
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/`) |
72
78
  | `~/.local/state/lcode/limits.json` | Context sizes that ran out of GPU memory on this machine (safe to delete) |
73
79
 
74
80
  Sessions contain everything the model read, including file contents. Delete the folder to clear them.
@@ -18,7 +18,7 @@ flowchart LR
18
18
  ## The agent loop
19
19
 
20
20
  1. Your message goes to the model along with a system prompt (environment, repository layout,
21
- `AGENTS.md`) and the JSON schemas of the tools.
21
+ `AGENTS.md`, the index of [memory notes](memory.md)) and the JSON schemas of the tools.
22
22
  2. The response streams back. Reasoning shows as a spinner (or text with `--show-thinking`); the
23
23
  answer is rendered as markdown, block by block.
24
24
  3. If the model called tools, lcode runs them, asking for permission where needed, and appends the
@@ -29,13 +29,23 @@ 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.
35
44
  lcode tracks how full the window is from Ollama's token counts. At 85% it asks the model to write a
36
45
  summary of the conversation (goals, findings, files changed, next steps) and continues from that
37
- summary. Tool outputs are capped at 30,000 characters (head and tail kept) so one noisy command
38
- can't flood the window.
46
+ summary. Just before that, it asks whether anything from the conversation is worth
47
+ [remembering](memory.md), since the summary leaves details out. Tool outputs are capped at 30,000
48
+ characters (head and tail kept) so one noisy command can't flood the window.
39
49
 
40
50
  ## Memory sizing
41
51
 
@@ -78,6 +88,8 @@ the Ollama server you configure, it only contacts the web when the model searche
78
88
  | `mcp/` | MCP client: stdio and HTTP transports, OAuth sign-in, server settings, the catalog, `lcode mcp` |
79
89
  | `bench.py` | `lcode bench`: the benchmark tasks, their checks and the reports |
80
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
+ | `memory.py` | Notes that carry over between sessions, and the end-of-session check |
81
93
  | `sandbox.py` | The optional container for shell commands |
82
94
  | `checkpoints.py` | Snapshots before the model changes files, for `/undo` and `/rewind` |
83
95
  | `catalog.py`, `models.toml` | Model catalog and memory estimates |
@@ -69,6 +69,20 @@ 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
+
79
+ - :material-brain:{ .lg .middle } **Remembers what matters**
80
+
81
+ ---
82
+
83
+ Your corrections, decisions and where things live carry over to the next session as short
84
+ [notes](memory.md), never whole conversations or secrets.
85
+
72
86
  - :material-connection:{ .lg .middle } **MCP servers**
73
87
 
74
88
  ---
@@ -0,0 +1,128 @@
1
+ # Memory
2
+
3
+ Every session used to start from zero. Whatever you and the model worked out was lost unless
4
+ someone wrote it into `AGENTS.md`: the test command that actually works, "we use pnpm, not npm",
5
+ that the staging database needs the VPN, a correction you had to give twice.
6
+
7
+ lcode now keeps short **notes** that later sessions load: only key knowledge, not whole
8
+ conversations. A note is one fact, in one line, with optional details.
9
+
10
+ ```text
11
+ ❯ /memory
12
+ Memory
13
+ # For Type Note Updated
14
+ 1 every repo feedback Prefers short answers without a summary at the end 2026-10-03
15
+ 2 this repo project Run the tests with `uv run pytest -q`; plain pyte… 2026-10-05
16
+ 3 this repo reference Staging logs are in Grafana, dashboard "api-prod" 2026-10-04
17
+ ```
18
+
19
+ ## What gets saved
20
+
21
+ Only what a future session needs and can't find in the code, the git history or `AGENTS.md`. There
22
+ are four kinds:
23
+
24
+ | Type | For | Example |
25
+ |---|---|---|
26
+ | `feedback` | Your corrections and preferences | "Use pnpm, not npm" |
27
+ | `project` | Decisions, constraints, ongoing work | "The staging database needs the VPN" |
28
+ | `reference` | Where things live outside the repository | "Bugs are tracked in Linear, project API" |
29
+ | `user` | Who you are and how you like to work | "Prefers short answers" |
30
+
31
+ Never saved: code structure, file paths, what changed in a session (git has that), temporary
32
+ state, and **secrets**. lcode refuses any note that looks like it contains a password, API key,
33
+ token, private key or a URL with a password in it, whoever writes it. Write where the secret lives
34
+ instead ("staging credentials are in 1Password, vault Dev").
35
+
36
+ ## How notes get saved
37
+
38
+ - **The model** saves a note with its `memory` tool when it learns something worth keeping, for
39
+ example after you correct it. It can also update a note (same name) or delete one that turned out
40
+ wrong.
41
+ - **You** save one with `/remember`:
42
+
43
+ ```text
44
+ ❯ /remember the staging database needs the VPN
45
+ ❯ /remember feedback: don't add docstrings to private functions
46
+ ❯ /remember -g user: I'm a backend developer; explain frontend code in more detail
47
+ ```
48
+
49
+ `-g` saves it for every repository. Start with `feedback:`, `reference:` or `user:` to set the
50
+ type (the default is `project`).
51
+
52
+ - **At the end of a session**, because local models rarely save anything on their own, lcode
53
+ asks the model one short question: is anything from this session worth remembering? It happens
54
+ when you quit, on `/clear`, and before the conversation is compacted (the summary leaves details
55
+ out). The model proposes at most three notes:
56
+
57
+ ```text
58
+ ╭─ Worth remembering? ────────────────────────────────────────────────────────╮
59
+ │ 1 [feedback] Use pnpm, not npm (this repository) │
60
+ │ 2 [project] Integration tests need `docker compose up db` first (this │
61
+ │ repository) │
62
+ ╰───────────────────────────────────────────────────────────────────────────────╯
63
+ Save them? [y]es / numbers to keep, e.g. 1,3 / [n]o: 1
64
+ ```
65
+
66
+ The question is quick: it reuses the conversation Ollama already has in memory, so the model
67
+ only writes a few lines. Short sessions (one request and little work) are skipped, and Ctrl+C
68
+ skips it too.
69
+
70
+ ## Asking first: the `memory` setting
71
+
72
+ | `memory` | |
73
+ |---|---|
74
+ | `ask` (default) | Every note the model saves, and the end-of-session proposals, need your OK. Answer `a` once to allow the model's notes for the rest of the session. This holds in `yolo` mode too. |
75
+ | `auto` | Notes are saved without asking; lcode prints each one. |
76
+ | `off` | No notes are loaded or saved, and the model has no `memory` tool. |
77
+
78
+ ```bash
79
+ lcode config set memory auto
80
+ ```
81
+
82
+ `lcode --no-memory` turns memory off for one session. `lcode -p` runs never ask the end-of-session
83
+ question.
84
+
85
+ ## Managing notes
86
+
87
+ | Command | |
88
+ |---|---|
89
+ | `/memory` | List the notes for this repository and for every repository |
90
+ | `/memory show 2` | Show a note with its details (by number or name) |
91
+ | `/memory edit 2` | Open it in your editor (`$VISUAL`, `$EDITOR`, nano or vi) |
92
+ | `/memory delete 2` | Delete it |
93
+ | `/memory path` | Where the notes are stored |
94
+
95
+ Changes you make with `/memory` apply from the next session. Notes added with `/remember` are
96
+ also mentioned to the model right away.
97
+
98
+ ## How it works
99
+
100
+ Notes are plain markdown files with a small header, one fact per file:
101
+
102
+ ```markdown
103
+ ---
104
+ name: test-command
105
+ type: project
106
+ description: Run the tests with `uv run pytest -q`; plain pytest misses the dev dependencies
107
+ modified: 2026-10-05
108
+ ---
109
+ The dev dependencies are in a uv dependency group, which plain pytest doesn't see.
110
+ ```
111
+
112
+ | Folder | Notes |
113
+ |---|---|
114
+ | `~/.local/state/lcode/memory/projects/<repository>/` | For one repository, shared by all its git worktrees and subfolders |
115
+ | `~/.local/state/lcode/memory/user/` | For every repository |
116
+
117
+ Each folder also has a `MEMORY.md` listing its notes, for reading; lcode regenerates it, so edit
118
+ the notes rather than that file. A folder that isn't in a git repository gets its own notes.
119
+
120
+ At the start of a session, the model gets a one-line index of the notes (description, name, date)
121
+ in its instructions. The index is capped at about 2,000 tokens, or 5% of a small context window;
122
+ when there are more notes, the newest are shown and the model can list the rest with its `memory`
123
+ tool, which also reads a note's details. The dates let stale facts stand out, and the model is told
124
+ to trust what it finds in the code over an old note, and to fix the note.
125
+
126
+ Saving under an existing name replaces that note. A new note that says nearly the same as another
127
+ one is not saved twice: the model is told to update the existing note instead, and
128
+ end-of-session proposals that only restate a note are dropped.
@@ -12,12 +12,13 @@ lcode
12
12
 
13
13
  ```text
14
14
  ╭──────────────────────────────────────────────╮
15
- │ lcode v0.6.1 — local coding agent │
15
+ │ lcode v0.8.0 — local coding agent │
16
16
  │ │
17
17
  │ model lcode-qwen3.6-35b │
18
18
  │ context 256K tokens │
19
19
  │ cwd /home/you/code/my-project │
20
20
  │ mode ask (Shift+Tab to cycle) │
21
+ │ memory ask · no notes yet (/remember) │
21
22
  ╰──────────────────────────────────────────────╯
22
23
  ❯
23
24
  ```
@@ -25,6 +25,7 @@ lcode mcp [catalog|add|list] # connect MCP servers: Jira, GitHub, AWS, databases
25
25
  | `--no-think` | Turn off the model's reasoning: faster, less accurate |
26
26
  | `--no-web` | No web search or page fetching in this session |
27
27
  | `--no-mcp` | Don't start [MCP servers](mcp.md) in this session |
28
+ | `--no-memory` | Don't load or save [memory notes](memory.md) in this session |
28
29
  | `--sandbox` | Run shell commands in a container that only sees the project ([Sandbox](sandbox.md)) |
29
30
  | `--show-thinking` | Print the model's reasoning as it streams |
30
31
  | `-V, --version` | Print the version |
@@ -40,6 +41,7 @@ lcode mcp [catalog|add|list] # connect MCP servers: Jira, GitHub, AWS, databases
40
41
  | ++shift+tab++ | Cycle permission mode: ask → auto-edit → yolo |
41
42
  | ++tab++ | Complete slash commands and `@` paths |
42
43
  | `@path` | Attach a file (or a directory listing) to your message |
44
+ | `@name` | Ask for a [subagent](agents.md) of that type, e.g. `@plan` |
43
45
 
44
46
  The status bar shows the model, how full the context window is, the permission mode and whether
45
47
  reasoning is on.
@@ -56,6 +58,9 @@ reasoning is on.
56
58
  | `/undo` | Undo the file changes of the last request ([details](#undo-and-checkpoints)) |
57
59
  | `/rewind [N]` | Go back to before request N: its files, and optionally the conversation |
58
60
  | `/checkpoints` | List the requests that changed files, and which files |
61
+ | `/agents [N]` | [Subagent](agents.md) types, and what this session's subagents did |
62
+ | `/remember [-g] TEXT` | Save a [note](memory.md) for later sessions (`-g`: for every repository) |
63
+ | `/memory [show\|edit\|delete N]` | The [notes](memory.md) lcode remembers |
59
64
  | `/sandbox [network on\|off]` | The [sandbox](sandbox.md) for shell commands |
60
65
  | `/mcp [tools\|login\|restart NAME]` | [MCP servers](mcp.md), their status and tools |
61
66
  | `/compact [focus]` | Summarize the conversation to free context |
@@ -82,6 +87,9 @@ reasoning is on.
82
87
  | `todo_write` | Keep a visible task list for multi-step work |
83
88
  | `web_search` | Search the web for current information (needs a [search provider](#web-search)) |
84
89
  | `web_fetch` | Read a web page or text file by URL as clean text |
90
+ | `view_image` | Look at an image: a model that can see describes it ([Images](#images)) |
91
+ | `agent` | Hand a task to a [subagent](agents.md) with its own context; only its report comes back |
92
+ | `memory` | Save, update or delete [notes](memory.md) that later sessions load |
85
93
 
86
94
  lcode refuses to edit a file the model hasn't read in the session, or one that changed on disk since
87
95
  it was read, so the model always edits the current version.
@@ -225,6 +233,10 @@ At startup lcode reads `AGENTS.md` (or `LCODE.md`, or `CLAUDE.md`) from the work
225
233
  adds it to the model's instructions. Use it for build and test commands, architecture notes and
226
234
  conventions. `/init` writes a first version for you.
227
235
 
236
+ What doesn't belong in `AGENTS.md` but should carry over, such as your corrections and preferences,
237
+ goes into lcode's [memory](memory.md): short notes the model, you (`/remember`) or a short check at
238
+ the end of a session save, and that every later session in the repository loads.
239
+
228
240
  ## Sessions
229
241
 
230
242
  Every conversation is saved after each request to `~/.local/state/lcode/sessions/`, so you can
@@ -92,6 +92,8 @@ nav:
92
92
  - Quickstart: quickstart.md
93
93
  - Guide:
94
94
  - Using lcode: usage.md
95
+ - Memory: memory.md
96
+ - Subagents: agents.md
95
97
  - Models & context windows: models.md
96
98
  - Benchmarking models: bench.md
97
99
  - MCP servers: mcp.md
@@ -69,6 +69,8 @@ ignore = [
69
69
 
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
+ "src/lcode/memory.py" = ["E501"]
73
+ "src/lcode/subagents.py" = ["E501"]
72
74
 
73
75
  [tool.pytest.ini_options]
74
76
  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.6.1"
3
+ __version__ = "0.8.0"