lcode-cli 0.20.0__tar.gz → 0.21.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 (149) hide show
  1. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/CHANGELOG.md +15 -1
  2. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/PKG-INFO +1 -1
  3. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/docs/installation.md +28 -3
  4. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/docs/quickstart.md +1 -1
  5. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/docs/usage.md +1 -0
  6. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/pyproject.toml +1 -0
  7. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/src/lcode/__init__.py +1 -1
  8. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/src/lcode/cli.py +17 -1
  9. lcode_cli-0.21.0/src/lcode/update.py +557 -0
  10. lcode_cli-0.21.0/tests/test_update.py +303 -0
  11. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/.editorconfig +0 -0
  12. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/.github/CODEOWNERS +0 -0
  13. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  14. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  15. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  16. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/.github/ISSUE_TEMPLATE/model_request.yml +0 -0
  17. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  18. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/.github/dependabot.yml +0 -0
  19. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/.github/workflows/ci.yml +0 -0
  20. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/.github/workflows/docs.yml +0 -0
  21. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/.github/workflows/release.yml +0 -0
  22. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/.gitignore +0 -0
  23. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/.pre-commit-config.yaml +0 -0
  24. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/AGENTS.md +0 -0
  25. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/CODE_OF_CONDUCT.md +0 -0
  26. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/CONTRIBUTING.md +0 -0
  27. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/LICENSE +0 -0
  28. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/README.md +0 -0
  29. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/SECURITY.md +0 -0
  30. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/action.yml +0 -0
  31. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/docs/agents.md +0 -0
  32. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/docs/assets/demo.svg +0 -0
  33. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/docs/assets/extra.css +0 -0
  34. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/docs/assets/logo.svg +0 -0
  35. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/docs/assets/social-preview.png +0 -0
  36. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/docs/automation.md +0 -0
  37. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/docs/bench.md +0 -0
  38. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/docs/changelog.md +0 -0
  39. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/docs/commands.md +0 -0
  40. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/docs/configuration.md +0 -0
  41. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/docs/contributing.md +0 -0
  42. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/docs/editors.md +0 -0
  43. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/docs/git.md +0 -0
  44. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/docs/hooks.md +0 -0
  45. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/docs/how-it-works.md +0 -0
  46. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/docs/index.md +0 -0
  47. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/docs/lsp.md +0 -0
  48. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/docs/mcp.md +0 -0
  49. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/docs/memory.md +0 -0
  50. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/docs/models.md +0 -0
  51. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/docs/sandbox.md +0 -0
  52. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/docs/search.md +0 -0
  53. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/docs/servers.md +0 -0
  54. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/docs/troubleshooting.md +0 -0
  55. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/examples/README.md +0 -0
  56. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/examples/api/fix_tests.py +0 -0
  57. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/examples/commands/review.md +0 -0
  58. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/examples/skills/commit-message/SKILL.md +0 -0
  59. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/examples/skills/commit-message/scripts/staged.sh +0 -0
  60. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/install.sh +0 -0
  61. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/mkdocs.yml +0 -0
  62. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/overrides/main.html +0 -0
  63. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/scripts/record_demo.py +0 -0
  64. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/scripts/social-preview.html +0 -0
  65. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/src/lcode/__main__.py +0 -0
  66. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/src/lcode/acp.py +0 -0
  67. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/src/lcode/action.py +0 -0
  68. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/src/lcode/agent.py +0 -0
  69. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/src/lcode/api.py +0 -0
  70. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/src/lcode/backends.py +0 -0
  71. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/src/lcode/bench.py +0 -0
  72. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/src/lcode/bench_backend.py +0 -0
  73. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/src/lcode/catalog.py +0 -0
  74. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/src/lcode/checkpoints.py +0 -0
  75. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/src/lcode/codesearch.py +0 -0
  76. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/src/lcode/config.py +0 -0
  77. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/src/lcode/context.py +0 -0
  78. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/src/lcode/extensions.py +0 -0
  79. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/src/lcode/frontmatter.py +0 -0
  80. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/src/lcode/gitflow.py +0 -0
  81. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/src/lcode/hardware.py +0 -0
  82. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/src/lcode/hooks.py +0 -0
  83. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/src/lcode/jobs.py +0 -0
  84. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/src/lcode/limits.py +0 -0
  85. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/src/lcode/lsp.py +0 -0
  86. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/src/lcode/mcp/__init__.py +0 -0
  87. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/src/lcode/mcp/auth.py +0 -0
  88. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/src/lcode/mcp/catalog.py +0 -0
  89. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/src/lcode/mcp/catalog.toml +0 -0
  90. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/src/lcode/mcp/client.py +0 -0
  91. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/src/lcode/mcp/commands.py +0 -0
  92. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/src/lcode/mcp/config.py +0 -0
  93. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/src/lcode/mcp/http.py +0 -0
  94. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/src/lcode/mcp/manager.py +0 -0
  95. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/src/lcode/mcp/protocol.py +0 -0
  96. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/src/lcode/mcp/server.py +0 -0
  97. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/src/lcode/mcp/stdio.py +0 -0
  98. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/src/lcode/memory.py +0 -0
  99. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/src/lcode/models.toml +0 -0
  100. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/src/lcode/notify.py +0 -0
  101. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/src/lcode/ollama.py +0 -0
  102. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/src/lcode/permissions.py +0 -0
  103. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/src/lcode/planning.py +0 -0
  104. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/src/lcode/render.py +0 -0
  105. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/src/lcode/repl.py +0 -0
  106. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/src/lcode/repomap.py +0 -0
  107. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/src/lcode/sandbox.py +0 -0
  108. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/src/lcode/servers/__init__.py +0 -0
  109. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/src/lcode/servers/encord.py +0 -0
  110. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/src/lcode/servers/valohai.py +0 -0
  111. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/src/lcode/sessions.py +0 -0
  112. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/src/lcode/subagents.py +0 -0
  113. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/src/lcode/tools.py +0 -0
  114. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/src/lcode/vision.py +0 -0
  115. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/src/lcode/web.py +0 -0
  116. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/tests/conftest.py +0 -0
  117. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/tests/fake_lsp_server.py +0 -0
  118. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/tests/fake_mcp_server.py +0 -0
  119. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/tests/test_acp.py +0 -0
  120. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/tests/test_action.py +0 -0
  121. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/tests/test_agent.py +0 -0
  122. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/tests/test_api.py +0 -0
  123. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/tests/test_backends.py +0 -0
  124. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/tests/test_bench.py +0 -0
  125. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/tests/test_catalog.py +0 -0
  126. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/tests/test_checkpoints.py +0 -0
  127. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/tests/test_cli.py +0 -0
  128. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/tests/test_codesearch.py +0 -0
  129. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/tests/test_config.py +0 -0
  130. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/tests/test_context.py +0 -0
  131. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/tests/test_context_picker.py +0 -0
  132. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/tests/test_extensions.py +0 -0
  133. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/tests/test_gitflow.py +0 -0
  134. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/tests/test_hooks.py +0 -0
  135. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/tests/test_jobs.py +0 -0
  136. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/tests/test_lsp.py +0 -0
  137. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/tests/test_mcp.py +0 -0
  138. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/tests/test_memory.py +0 -0
  139. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/tests/test_permissions.py +0 -0
  140. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/tests/test_plan_mode.py +0 -0
  141. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/tests/test_repomap.py +0 -0
  142. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/tests/test_sandbox.py +0 -0
  143. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/tests/test_servers.py +0 -0
  144. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/tests/test_sessions.py +0 -0
  145. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/tests/test_subagents.py +0 -0
  146. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/tests/test_tools.py +0 -0
  147. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/tests/test_vision.py +0 -0
  148. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/tests/test_web.py +0 -0
  149. {lcode_cli-0.20.0 → lcode_cli-0.21.0}/uv.lock +0 -0
@@ -6,6 +6,19 @@ All notable changes to lcode are documented here. The format follows
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.21.0] - 2026-10-06
10
+
11
+ ### Added
12
+
13
+ - `lcode update` updates lcode the way it was installed (uv tool, pipx, Homebrew, pip, or
14
+ `git pull` for a checkout), and Ollama when it runs in Docker. The newest Ollama release comes
15
+ from Docker Hub, not a local `latest` tag, and is pulled by its version tag (such as
16
+ `ollama/ollama:0.35.1`) so `docker ps` shows the version. A container from Docker Compose gets
17
+ the new tag in its compose file and is recreated with `docker compose up`; any other container is
18
+ recreated with the same settings, and the old one comes back if the new one doesn't start.
19
+ `lcode update --check` only shows which versions are out. See
20
+ [Updating](https://nasser1941.github.io/lcode/installation/#updating).
21
+
9
22
  ## [0.20.0] - 2026-10-06
10
23
 
11
24
  ### Added
@@ -467,7 +480,8 @@ First public release.
467
480
  - `AGENTS.md` project instructions and `/init` to generate them.
468
481
  - One-line installer for Linux and macOS.
469
482
 
470
- [Unreleased]: https://github.com/nasser1941/lcode/compare/v0.20.0...HEAD
483
+ [Unreleased]: https://github.com/nasser1941/lcode/compare/v0.21.0...HEAD
484
+ [0.21.0]: https://github.com/nasser1941/lcode/compare/v0.20.0...v0.21.0
471
485
  [0.20.0]: https://github.com/nasser1941/lcode/compare/v0.19.0...v0.20.0
472
486
  [0.19.0]: https://github.com/nasser1941/lcode/compare/v0.18.0...v0.19.0
473
487
  [0.18.0]: https://github.com/nasser1941/lcode/compare/v0.17.0...v0.18.0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: lcode-cli
3
- Version: 0.20.0
3
+ Version: 0.21.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/
@@ -161,11 +161,36 @@ lmstudio` (or `llama.cpp`, `vllm`, `mlx`). See [Other model servers](servers.md)
161
161
  Use [WSL2](https://learn.microsoft.com/windows/wsl/install) with Ubuntu and follow the Ubuntu
162
162
  steps. NVIDIA GPUs work inside WSL2 with the regular Windows driver.
163
163
 
164
- ## Upgrade and uninstall
164
+ ## Updating
165
165
 
166
166
  ```bash
167
- uv tool upgrade lcode-cli # upgrade (pipx: pipx upgrade lcode-cli; Homebrew: brew upgrade lcode)
168
- uv tool uninstall lcode-cli # remove lcode (Homebrew: brew uninstall lcode)
167
+ lcode update # update lcode, and Ollama if it runs in Docker
168
+ lcode update --check # only show which versions are out
169
+ ```
170
+
171
+ - **lcode** updates the way you installed it: `uv tool upgrade`, `pipx upgrade`, `brew upgrade`
172
+ or `pip`. If it runs from a git checkout, `git pull` (on `main`, without local changes).
173
+ - **Ollama in a Docker container** is updated to the newest release on Docker Hub. lcode looks
174
+ that up instead of trusting a local `latest` tag, which can be months old, and skips release
175
+ candidates. It pulls the version's own tag, such as `ollama/ollama:0.35.1`, so `docker ps` shows
176
+ which version runs. A ROCm image stays ROCm.
177
+ - **A container from Docker Compose:** lcode changes the `image:` line in its compose file and
178
+ runs `docker compose up -d` for that service, so Compose keeps managing it.
179
+ - **Any other container** is recreated with the same name, ports, volumes, environment, GPUs,
180
+ network and restart policy. The old one is kept until the new one answers with the new
181
+ version, and is put back if it doesn't.
182
+ - Your models stay: they're in the container's volume.
183
+ - **Ollama installed without Docker** gets the command that updates it: on Linux,
184
+ `curl -fsSL https://ollama.com/install.sh | sh`; on macOS, `brew upgrade ollama` or the app
185
+ itself.
186
+
187
+ lcode shows what it will do and asks first. `lcode update lcode` or `lcode update ollama` updates
188
+ only one; `-y` doesn't ask.
189
+
190
+ ## Uninstall
191
+
192
+ ```bash
193
+ uv tool uninstall lcode-cli # remove lcode (pipx: pipx uninstall lcode-cli; Homebrew: brew uninstall lcode)
169
194
  rm -rf ~/.config/lcode ~/.local/state/lcode # remove settings and saved sessions
170
195
  ollama rm lcode-qwen3.6-35b qwen3.6:35b-a3b-coding # remove downloaded models
171
196
  ```
@@ -12,7 +12,7 @@ lcode
12
12
 
13
13
  ```text
14
14
  ╭──────────────────────────────────────────────╮
15
- │ lcode v0.20.0 — local coding agent │
15
+ │ lcode v0.21.0 — local coding agent │
16
16
  │ │
17
17
  │ model lcode-qwen3.6-35b │
18
18
  │ context 256K tokens │
@@ -11,6 +11,7 @@ lcode config [set|unset] # show or change settings
11
11
  lcode bench [models] # score models on small coding tasks on this machine
12
12
  lcode mcp [catalog|add|list] # connect MCP servers: Jira, GitHub, AWS, databases… (see MCP servers)
13
13
  lcode acp # run inside an editor over the Agent Client Protocol (see Editors)
14
+ lcode update [--check] # update lcode, and Ollama when it runs in Docker (see Installation)
14
15
  ```
15
16
 
16
17
  | Option | Meaning |
@@ -87,6 +87,7 @@ ignore = [
87
87
  "src/lcode/gitflow.py" = ["E501"]
88
88
  "src/lcode/action.py" = ["E501"]
89
89
  "src/lcode/acp.py" = ["E501"]
90
+ "src/lcode/update.py" = ["E501"]
90
91
 
91
92
  [tool.pytest.ini_options]
92
93
  testpaths = ["tests"]
@@ -3,7 +3,7 @@
3
3
  From a program: `from lcode import Session` (see lcode.api).
4
4
  """
5
5
 
6
- __version__ = "0.20.0"
6
+ __version__ = "0.21.0"
7
7
 
8
8
  API = ("Session", "Result", "Options", "SetupError")
9
9
 
@@ -678,7 +678,7 @@ def build_parser() -> argparse.ArgumentParser:
678
678
  parser = argparse.ArgumentParser(
679
679
  prog="lcode",
680
680
  description="A local-first terminal coding agent powered by open-weight models via Ollama.",
681
- epilog="Subcommands: lcode setup | models | doctor | config | bench | mcp | index "
681
+ epilog="Subcommands: lcode setup | models | doctor | config | bench | mcp | index | update "
682
682
  "(lcode <subcommand> --help). "
683
683
  "Docs: https://nasser1941.github.io/lcode/",
684
684
  )
@@ -774,6 +774,15 @@ def build_subparsers() -> dict[str, argparse.ArgumentParser]:
774
774
  from lcode.mcp.commands import build_parser as mcp_parser
775
775
 
776
776
  subs["mcp"] = mcp_parser()
777
+ p = argparse.ArgumentParser(
778
+ prog="lcode update",
779
+ description="Update lcode, and Ollama when it runs in Docker (to the newest version on Docker Hub, pinned "
780
+ "to its version tag).",
781
+ )
782
+ p.add_argument("what", nargs="?", choices=["lcode", "ollama"], help="only this one (default: both)")
783
+ p.add_argument("--check", action="store_true", help="only show which versions are out")
784
+ p.add_argument("-y", "--yes", action="store_true", help="don't ask before updating")
785
+ subs["update"] = p
777
786
  subs["acp"] = argparse.ArgumentParser(
778
787
  prog="lcode acp",
779
788
  description="Run as the agent inside an editor, over the Agent Client Protocol on stdin and stdout "
@@ -787,6 +796,12 @@ def build_subparsers() -> dict[str, argparse.ArgumentParser]:
787
796
  return subs
788
797
 
789
798
 
799
+ def cmd_update(args) -> None:
800
+ from lcode import update
801
+
802
+ sys.exit(update.command(console, args.what or "", check=args.check, yes=args.yes))
803
+
804
+
790
805
  def cmd_acp(args) -> None:
791
806
  from lcode import acp
792
807
 
@@ -863,6 +878,7 @@ COMMANDS = {
863
878
  "index": cmd_index,
864
879
  "action": cmd_action,
865
880
  "acp": cmd_acp,
881
+ "update": cmd_update,
866
882
  }
867
883
 
868
884