comodor 0.2.0__tar.gz → 0.2.2__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 (115) hide show
  1. {comodor-0.2.0 → comodor-0.2.2}/.gitignore +9 -0
  2. comodor-0.2.2/PKG-INFO +435 -0
  3. comodor-0.2.2/README.md +409 -0
  4. {comodor-0.2.0 → comodor-0.2.2}/pyproject.toml +9 -2
  5. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/__init__.py +9 -1
  6. comodor-0.2.2/src/comodor/_version.py +24 -0
  7. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/cli.py +112 -0
  8. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/setup.py +100 -24
  9. comodor-0.2.2/src/comodor/ui/chooser.py +271 -0
  10. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/ui/input/reader.py +24 -1
  11. comodor-0.2.2/src/comodor/ui/markdown.py +155 -0
  12. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/ui/theme.py +7 -0
  13. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/ui/widgets/buttons.py +27 -15
  14. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/ui/widgets/statusbar.py +77 -31
  15. comodor-0.2.2/src/comodor/uninstall.py +615 -0
  16. comodor-0.2.2/tests/test_chooser.py +208 -0
  17. {comodor-0.2.0 → comodor-0.2.2}/tests/test_input.py +48 -0
  18. comodor-0.2.2/tests/test_markdown.py +103 -0
  19. comodor-0.2.2/tests/test_uninstall.py +347 -0
  20. comodor-0.2.0/PKG-INFO +0 -585
  21. comodor-0.2.0/README.md +0 -559
  22. comodor-0.2.0/src/comodor/ui/markdown.py +0 -76
  23. {comodor-0.2.0 → comodor-0.2.2}/LICENSE +0 -0
  24. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/__main__.py +0 -0
  25. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/agent/__init__.py +0 -0
  26. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/agent/context.py +0 -0
  27. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/agent/loop.py +0 -0
  28. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/agent/prompts.py +0 -0
  29. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/agent/tokens.py +0 -0
  30. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/catalogue.py +0 -0
  31. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/config.py +0 -0
  32. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/doctor.py +0 -0
  33. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/events.py +0 -0
  34. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/learning/__init__.py +0 -0
  35. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/learning/bm25.py +0 -0
  36. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/learning/hotindex.py +0 -0
  37. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/learning/memory.py +0 -0
  38. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/learning/progress.py +0 -0
  39. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/learning/reflect.py +0 -0
  40. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/learning/rules.py +0 -0
  41. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/learning/signals.py +0 -0
  42. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/learning/store.py +0 -0
  43. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/learning/writer.py +0 -0
  44. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/mcp/__init__.py +0 -0
  45. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/mcp/catalogue.py +0 -0
  46. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/mcp/commands.py +0 -0
  47. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/mcp/manager.py +0 -0
  48. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/mcp/protocol.py +0 -0
  49. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/net/__init__.py +0 -0
  50. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/net/http.py +0 -0
  51. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/net/sse.py +0 -0
  52. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/paths.py +0 -0
  53. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/providers/__init__.py +0 -0
  54. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/providers/anthropic.py +0 -0
  55. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/providers/base.py +0 -0
  56. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/providers/fake.py +0 -0
  57. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/providers/gateway.py +0 -0
  58. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/providers/openai_compat.py +0 -0
  59. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/providers/registry.py +0 -0
  60. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/safety/__init__.py +0 -0
  61. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/safety/checkpoints.py +0 -0
  62. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/safety/permissions.py +0 -0
  63. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/safety/redact.py +0 -0
  64. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/session/__init__.py +0 -0
  65. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/session/search.py +0 -0
  66. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/session/store.py +0 -0
  67. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/skills/__init__.py +0 -0
  68. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/skills/examples.py +0 -0
  69. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/skills/loader.py +0 -0
  70. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/skills/propose.py +0 -0
  71. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/skills/registry.py +0 -0
  72. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/tools/__init__.py +0 -0
  73. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/tools/base.py +0 -0
  74. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/tools/fs.py +0 -0
  75. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/tools/history.py +0 -0
  76. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/tools/mcp.py +0 -0
  77. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/tools/registry.py +0 -0
  78. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/tools/search.py +0 -0
  79. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/tools/shell.py +0 -0
  80. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/tools/skills.py +0 -0
  81. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/tools/todo.py +0 -0
  82. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/tools/web.py +0 -0
  83. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/ui/__init__.py +0 -0
  84. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/ui/app.py +0 -0
  85. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/ui/console.py +0 -0
  86. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/ui/input/__init__.py +0 -0
  87. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/ui/input/keys.py +0 -0
  88. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/ui/layout.py +0 -0
  89. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/ui/screen.py +0 -0
  90. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/ui/widgets/__init__.py +0 -0
  91. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/ui/widgets/chat.py +0 -0
  92. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/ui/widgets/history.py +0 -0
  93. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/ui/widgets/overlay.py +0 -0
  94. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/ui/widgets/panel.py +0 -0
  95. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/ui/widgets/progress.py +0 -0
  96. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/ui/widgets/prompt.py +0 -0
  97. {comodor-0.2.0 → comodor-0.2.2}/src/comodor/ui/widgets/toast.py +0 -0
  98. {comodor-0.2.0 → comodor-0.2.2}/tests/conftest.py +0 -0
  99. {comodor-0.2.0 → comodor-0.2.2}/tests/support/fake_mcp_server.py +0 -0
  100. {comodor-0.2.0 → comodor-0.2.2}/tests/test_agent_loop.py +0 -0
  101. {comodor-0.2.0 → comodor-0.2.2}/tests/test_app.py +0 -0
  102. {comodor-0.2.0 → comodor-0.2.2}/tests/test_doctor.py +0 -0
  103. {comodor-0.2.0 → comodor-0.2.2}/tests/test_history.py +0 -0
  104. {comodor-0.2.0 → comodor-0.2.2}/tests/test_layout.py +0 -0
  105. {comodor-0.2.0 → comodor-0.2.2}/tests/test_learning.py +0 -0
  106. {comodor-0.2.0 → comodor-0.2.2}/tests/test_mcp.py +0 -0
  107. {comodor-0.2.0 → comodor-0.2.2}/tests/test_performance.py +0 -0
  108. {comodor-0.2.0 → comodor-0.2.2}/tests/test_progress.py +0 -0
  109. {comodor-0.2.0 → comodor-0.2.2}/tests/test_propose.py +0 -0
  110. {comodor-0.2.0 → comodor-0.2.2}/tests/test_providers.py +0 -0
  111. {comodor-0.2.0 → comodor-0.2.2}/tests/test_reflex.py +0 -0
  112. {comodor-0.2.0 → comodor-0.2.2}/tests/test_run_loop.py +0 -0
  113. {comodor-0.2.0 → comodor-0.2.2}/tests/test_setup.py +0 -0
  114. {comodor-0.2.0 → comodor-0.2.2}/tests/test_skills.py +0 -0
  115. {comodor-0.2.0 → comodor-0.2.2}/tests/test_tools.py +0 -0
@@ -29,3 +29,12 @@ next-env.d.ts
29
29
  .env*.local
30
30
  npm-debug.log*
31
31
  dist/
32
+
33
+ TODO
34
+
35
+ # Written by the build from the git tag.
36
+ src/comodor/_version.py
37
+
38
+ # uv writes this when it resolves an environment here. Comodor is a library
39
+ # as well as an application; a lock file would pin its users, not just us.
40
+ uv.lock
comodor-0.2.2/PKG-INFO ADDED
@@ -0,0 +1,435 @@
1
+ Metadata-Version: 2.5
2
+ Name: comodor
3
+ Version: 0.2.2
4
+ Summary: Comodor — a self-improving terminal coding agent with a Rich TUI
5
+ Project-URL: Homepage, https://comodor.ai
6
+ Project-URL: Repository, https://github.com/ifekri/Comodor
7
+ Project-URL: Issues, https://github.com/ifekri/Comodor/issues
8
+ Project-URL: Changelog, https://github.com/ifekri/Comodor/blob/main/CHANGELOG.md
9
+ Author-email: MMDRZA <mohammadreza.fekri.mojdehi@gmail.com>
10
+ License: MIT
11
+ License-File: LICENSE
12
+ Keywords: agent,cli,coding-assistant,llm,rich,terminal,tui
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Environment :: Console
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Topic :: Software Development :: Code Generators
21
+ Requires-Python: >=3.11
22
+ Requires-Dist: rich>=13.7
23
+ Provides-Extra: dev
24
+ Requires-Dist: pytest>=8.0; extra == 'dev'
25
+ Description-Content-Type: text/markdown
26
+
27
+ # Comodor
28
+
29
+ **A coding agent that lives in your terminal — and learns the way you correct it.**
30
+
31
+ [comodor.ai](https://comodor.ai) · [Install](#install) · [What it can do](#what-it-can-do)
32
+
33
+ ---
34
+
35
+ ## What this is
36
+
37
+ Comodor is a program you run in your terminal and talk to in plain language.
38
+ You describe a job — *fix the failing test*, *add a health endpoint*, *work out
39
+ why the deploy broke* — and it does the work: reads your files, writes changes,
40
+ runs your tests, searches the web, and keeps going until the job is done or it
41
+ needs you.
42
+
43
+ It asks before it changes anything, shows you exactly what it is about to do,
44
+ and can undo it.
45
+
46
+ What makes it different from every other tool of this kind is what happens
47
+ afterwards. **When you fix something it wrote, it notices, and it does not make
48
+ that mistake again.** Not because you configured it. Because it watched.
49
+
50
+ ```
51
+ › create defaults.py with 6 string constants
52
+ ⚙ write src/defaults.py — 6 constants
53
+
54
+ … you open the file and change "30s" to '30s' …
55
+
56
+ › now add the timeout constants
57
+ ◈ learned: Use single quotes for string literals. (31 of 34 literals)
58
+ ⚙ write src/defaults.py — '30s', '5m'
59
+ ```
60
+
61
+ That is a real transcript. Nobody told it anything.
62
+
63
+ ```
64
+ ┌─ History ──────────────┐ ┌─ Chat ───────────────────────────────────────────────┐
65
+ │ TASKS 2/4 ──────────── │ │ › add a health endpoint and a test for it │
66
+ │ ● read the app factory │ │ ◈ recalled 3 lessons · skill: review │
67
+ │ ● add the /health rou… │ │ │
68
+ │ ◐ write the test │ │ I'll add the route, then a test. │
69
+ │ ○ run the suite │ │ │
70
+ │ │ │ ⚙ edit src/app.py 0.2s │
71
+ │ │ │ + @app.get('/health') │
72
+ │ │ │ ⚙ run: pytest -q 3.4s │
73
+ │ │ │ 4 passed in 0.42s │
74
+ └────────────────────────┘ └──────────────────────────────────────────────────────┘
75
+ ```
76
+
77
+ ---
78
+
79
+ ## Install
80
+
81
+ **macOS and Linux**
82
+
83
+ ```bash
84
+ curl -fsSL https://comodor.ai/install.sh | sh
85
+ ```
86
+
87
+ **Windows**
88
+
89
+ ```powershell
90
+ irm https://comodor.ai/install.ps1 | iex
91
+ ```
92
+
93
+ **The installer finishes the job.** It finds a Python or fetches one, builds an
94
+ isolated environment so nothing on your machine is disturbed, puts `comodor` on
95
+ your PATH, and runs it once to prove it worked. You do not need Python
96
+ installed, and you will not be handed a wall of packaging errors.
97
+
98
+ Already have a package manager? Any of these work:
99
+
100
+ ```bash
101
+ uv tool install comodor
102
+ pipx install comodor
103
+ pip install comodor
104
+ ```
105
+
106
+ Then type `comodor`.
107
+
108
+ ---
109
+
110
+ ## First run
111
+
112
+ Four questions, once. Nothing to create beforehand — no config file, no
113
+ environment variable, no documentation to read first.
114
+
115
+ ```
116
+ 1/4 Which model provider? 18 to choose from, numbered
117
+ 2/4 API key masked, with a link to the page that issues one
118
+ 3/4 Which model? read live from the provider you just chose
119
+ 4/4 How much should it ask? ask first · writes allowed · full autonomy
120
+ ```
121
+
122
+ You are not asked again. Change your mind later with `comodor setup`.
123
+
124
+ **No API key?** `comodor --demo` runs the whole interface offline — every
125
+ panel, every command, no account required.
126
+
127
+ ---
128
+
129
+ ## What it can do
130
+
131
+ ### It learns from your corrections
132
+
133
+ Most assistants remember what you *tell* them. Comodor learns from what you
134
+ *fix*. It reads five things, all of which you produce just by working:
135
+
136
+ | what you did | what it means |
137
+ |---|---|
138
+ | you rewrote a file it wrote | the diff is the preference — quotes, indentation, verbosity |
139
+ | you pressed `/undo` | an outright rejection |
140
+ | you refused a command | one thing you do not want run |
141
+ | you asked the same thing twice | the answer missed |
142
+ | a tool failed the same way twice | a real pitfall in this environment |
143
+
144
+ Each becomes a **rule with its evidence attached** — not *"I think you prefer
145
+ single quotes"* but `31 of 34 literals`. How much evidence a rule needs depends
146
+ on where it came from: four agreeing observations to trust your codebase, two
147
+ for an edit you made, one for something you said outright.
148
+
149
+ It happens with **no extra model call and no waiting**, and it is announced
150
+ rather than silent. `/rules` shows every rule, what convinced it, and lets you
151
+ drop any of them.
152
+
153
+ ### It follows procedures you write down
154
+
155
+ A **skill** is a plain Markdown file describing how you want a kind of work
156
+ done — your review checklist, your commit conventions, the deploy steps nobody
157
+ remembers.
158
+
159
+ ```markdown
160
+ ---
161
+ name: review
162
+ description: Review a change for correctness before it is committed
163
+ ---
164
+
165
+ Read the whole change before saying anything about it.
166
+ Report only what would block a merge.
167
+ ```
168
+
169
+ Drop it in `~/.comodor/skills/` for everywhere, or `.comodor/skills/` to commit
170
+ it with the project so your whole team gets it. Comodor loads one only when the
171
+ request calls for it, so twenty skills cost no more than one.
172
+
173
+ It uses the [Agent Skills](https://agentskills.io) open format, so a skill
174
+ written for another tool works here, and yours work there.
175
+
176
+ **It also writes them for you.** When it has solved the same shape of problem
177
+ three times, `/skills draft` offers the procedure back as a finished file — with
178
+ the evidence — and writes nothing until you say yes.
179
+
180
+ ### It remembers every session
181
+
182
+ Everything you have ever asked is searchable.
183
+
184
+ ```
185
+ /search cursor pagination
186
+
187
+ you · 12 Apr · 20260412-090000
188
+ > add cursor pagination to the results endpoint
189
+ ```
190
+
191
+ The agent searches it too, on its own, when you refer to earlier work — *"like
192
+ we did last time"*, *"that bug from last week"*.
193
+
194
+ ### It connects to other tools
195
+
196
+ Comodor speaks the [Model Context Protocol](https://modelcontextprotocol.io),
197
+ so it can use capabilities it does not implement itself: a browser, a database,
198
+ your issue tracker.
199
+
200
+ ```bash
201
+ comodor mcp catalogue # twelve servers, ready to go
202
+ comodor mcp add filesystem --path ~/work
203
+ comodor mcp add github --env GITHUB_PERSONAL_ACCESS_TOKEN=…
204
+ comodor mcp custom my-server uvx my-package # anything else
205
+ ```
206
+
207
+ | | |
208
+ |---|---|
209
+ | **Files and code** | Filesystem · Git · GitHub |
210
+ | **Data** | SQLite · PostgreSQL |
211
+ | **The web** | Fetch · Brave Search · Browser (Puppeteer) |
212
+ | **Other** | Memory · Sequential thinking · Slack · Time |
213
+
214
+ Each entry says **what it can reach** before you enable it. Nothing starts
215
+ until it is used.
216
+
217
+ ### It fixes itself
218
+
219
+ ```
220
+ $ comodor doctor
221
+
222
+ Checks
223
+ ok provider Anthropic · claude-sonnet-4-5
224
+ warn session search the index is corrupt
225
+ → delete it — it is a cache built from the transcripts
226
+ ok mcp servers 2 enabled and reachable
227
+
228
+ 1 of these can be repaired automatically: comodor doctor --fix
229
+ ```
230
+
231
+ `--fix` repairs what it can rebuild and **refuses what it cannot**. A corrupt
232
+ cache gets deleted. A corrupt config is reported and left exactly as it was,
233
+ because it holds your API key — the one thing on your machine that cannot be
234
+ regenerated.
235
+
236
+ ### It leaves when you ask it to
237
+
238
+ ```
239
+ $ comodor uninstall
240
+
241
+ Your data
242
+ everything it has learned and everything you told it 14 MB
243
+ ~/.comodor
244
+ settings and your API key · learned rules and lessons · 62 sessions · 4 skills
245
+
246
+ In your projects
247
+ api-server 1.2 MB
248
+ ~/work/api-server/.comodor
249
+
250
+ The program
251
+ the isolated environment 112 MB
252
+ ~/.local/share/comodor
253
+
254
+ Your shell
255
+ the PATH line the installer added
256
+ ~/.bashrc
257
+
258
+ 127 MB across 5 places. None of it can be undone.
259
+
260
+ Type uninstall to confirm, or anything else to stop.
261
+ ```
262
+
263
+ It shows the list before it touches anything, and `--dry-run` stops there. What
264
+ goes is the data directory, the `.comodor` folder in every project it was used
265
+ in, the environment the installer built, the `comodor` command, and the line
266
+ the installer put in your shell profile. Afterwards there is nothing of it left
267
+ on the machine.
268
+
269
+ It knows which projects to clean because every session records where it ran —
270
+ not by searching your disk. Three things it will not do: touch a source
271
+ checkout, take a directory off your PATH that other programs are still using,
272
+ or claim to have deleted a file the operating system would not let go of.
273
+
274
+ ### It can prove it is improving
275
+
276
+ Every tool claims to get better over time. Comodor shows the numbers.
277
+
278
+ ```
279
+ ◈ Steps per task down 40% since the first tasks in this project.
280
+
281
+ metric trend now vs first
282
+ Steps per task ▇██▇▇▆▇▅▅▅▅▆▄▅▄▅▄▄▂▄▂▁▂▂▂▁▁▁▁▁ 5.3 ↓40%
283
+ Corrections per task ████▆▇▆█▆▆▆▇▆▆▅▃▃▅▆▆▅▃▆▃▆▃▂▁▁▃ 0.9 ↓65%
284
+ Approvals asked █▇▇▇▇▇▇▇▇▇▅▅▅▅▅▅▅▅▅▅▃▃▃▃▃▃▃▃▃▁ 0.8 ↓73%
285
+ ```
286
+
287
+ The panel is built to under-claim: with too little history it says so, and a
288
+ fall from 0.4 to 0 is never allowed to headline as "down 100%".
289
+
290
+ ---
291
+
292
+ ## You stay in control
293
+
294
+ - **Reads never interrupt you. Writes show a coloured diff and ask. Commands
295
+ and network calls always ask.**
296
+ - **Checkpoints.** Every file is snapshotted before it changes; `/undo`
297
+ restores it.
298
+ - **A deny list no prompt can talk past**, for commands that are never
299
+ acceptable — whatever the model, or you, may ask for in the moment.
300
+ - **It stays inside your project.** Writes outside it are refused by default.
301
+ - **Your keys never appear** in logs, transcripts or exports.
302
+
303
+ Three switches decide how much rope it gets:
304
+
305
+ | | |
306
+ |---|---|
307
+ | **Act** | the full tool set — it can change your project |
308
+ | **Plan** | read-only, and the write tools are hidden from the model entirely, so you get a plan rather than a thwarted attempt to edit |
309
+ | **Chat** | no tools at all |
310
+
311
+ **Loop** decides whether it keeps going by itself until the job is done or a
312
+ budget trips — steps, wall clock, or money. **Gateway** can spread work across
313
+ providers and fail over when one breaks.
314
+
315
+ ---
316
+
317
+ ## Bring your own model
318
+
319
+ | | |
320
+ |---|---|
321
+ | **Hosted** | OpenRouter · Anthropic · OpenAI · Google Gemini · DeepSeek · xAI · Mistral · Groq · Cerebras · Moonshot · Z.AI · Qwen · Together · Fireworks · Xiaomi MiMo |
322
+ | **On your machine** | Ollama · LM Studio — no key, no cost, no network |
323
+ | **Anything else** | any OpenAI-compatible endpoint |
324
+
325
+ Each knows its own endpoint, model list and where to get a key, so choosing one
326
+ is a single number. Switch any time with `/provider`, or per run:
327
+
328
+ ```bash
329
+ comodor --provider groq --model llama-3.3-70b-versatile
330
+ ```
331
+
332
+ ---
333
+
334
+ ## Everyday use
335
+
336
+ ```bash
337
+ comodor # the interface
338
+ comodor --demo # offline walkthrough, no key needed
339
+ comodor run "fix the failing test" --yes # one task, headless, for scripts
340
+ comodor run "audit this module" --json # machine-readable, for pipelines
341
+ comodor doctor # check everything; --fix repairs it
342
+ comodor uninstall # remove it completely; --dry-run first
343
+ ```
344
+
345
+ | Key | |
346
+ |---|---|
347
+ | `Enter` | send · `Ctrl+J` for a newline |
348
+ | `Esc` | stop the agent |
349
+ | `F1` … `F5` | help · sidebar · mode · loop · gateway |
350
+ | `Ctrl+O` | attach a file |
351
+ | `Ctrl+C` | stop; twice to quit |
352
+
353
+ `!command` runs a shell command directly. `@path` attaches a file.
354
+
355
+ **Commands** — `/help` `/model` `/provider` `/mode` `/loop` `/rules`
356
+ `/progress` `/memory` `/skills` `/search` `/mcp` `/undo` `/cost` `/export`
357
+ `/settings` `/resume` `/quit`
358
+
359
+ ---
360
+
361
+ ## Configuration
362
+
363
+ One JSON file, written for you and safe to edit by hand.
364
+
365
+ | | |
366
+ |---|---|
367
+ | Linux and macOS | `~/.comodor/config.json` |
368
+ | Windows | `%APPDATA%\Comodor\config.json` |
369
+
370
+ It is written atomically and, on Unix, readable only by you, because it holds
371
+ your key. A `.comodor/config.json` inside a repository is merged over your
372
+ personal one, so a team can pin settings without sharing secrets. Provider
373
+ environment variables still take precedence, which keeps CI working with no
374
+ file at all.
375
+
376
+ ---
377
+
378
+ ## Any terminal, any size
379
+
380
+ The layout is recomputed every frame, so resizing just works — from a
381
+ 40-column SSH window to an ultrawide monitor. Below the floor it says so
382
+ plainly rather than drawing a corrupted screen, `--ascii` covers terminals
383
+ without box-drawing glyphs, and a monochrome terminal gets a monochrome theme
384
+ automatically.
385
+
386
+ Recall — the wait between pressing Enter and the first token — is **0.38 ms and
387
+ stays there** whether the agent has learned three thousand things or twenty
388
+ thousand. That is measured, not asserted: `tests/test_performance.py` enforces
389
+ it as a ceiling, so a change that makes it slow fails the build.
390
+
391
+ ---
392
+
393
+ ## Development
394
+
395
+ ```bash
396
+ git clone https://github.com/ifekri/Comodor && cd Comodor
397
+ python -m venv .venv
398
+ .venv/Scripts/activate # Windows; source .venv/bin/activate elsewhere
399
+ pip install -e ".[dev]"
400
+ pytest -q # 472 tests, no network, no spend
401
+ ```
402
+
403
+ ```
404
+ src/comodor/
405
+ ├─ agent/ the reason/act loop, context budgeting, prompts
406
+ ├─ learning/ the brain: rules, lessons, signals, progress
407
+ ├─ skills/ authored skills: the open format, matching, drafts
408
+ ├─ mcp/ the Model Context Protocol client and server catalogue
409
+ ├─ providers/ every backend, and the gateway between them
410
+ ├─ safety/ permissions, checkpoints, redaction
411
+ ├─ session/ persistence, export, full-text search
412
+ ├─ tools/ files, search, shell, python, web, task list
413
+ └─ ui/ layout, theme, widgets, raw input, the app loop
414
+ ```
415
+
416
+ The suite runs the whole agent against a scripted provider — no network, no
417
+ spend — and renders the interface at a range of terminal sizes to prove the
418
+ responsive layout holds.
419
+
420
+ ```bash
421
+ comodor preview 120x34 # render one frame at a fixed size
422
+ ```
423
+
424
+ ---
425
+
426
+ ## Contributing
427
+
428
+ Bug reports welcome — please include `comodor doctor`, which prints everything
429
+ we would otherwise have to ask for. [CONTRIBUTING.md](CONTRIBUTING.md) covers
430
+ the setup. Security issues go [here](SECURITY.md), privately.
431
+ [CHANGELOG.md](CHANGELOG.md) records what changed in each release.
432
+
433
+ ## Licence
434
+
435
+ MIT — see [LICENSE](LICENSE).