meanwhile-cli 0.1.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 (38) hide show
  1. meanwhile_cli-0.1.0/.agents/plugins/marketplace.json +20 -0
  2. meanwhile_cli-0.1.0/.claude-plugin/marketplace.json +15 -0
  3. meanwhile_cli-0.1.0/.claude-plugin/plugin.json +15 -0
  4. meanwhile_cli-0.1.0/.gitignore +6 -0
  5. meanwhile_cli-0.1.0/LICENSE +21 -0
  6. meanwhile_cli-0.1.0/PKG-INFO +265 -0
  7. meanwhile_cli-0.1.0/README.md +250 -0
  8. meanwhile_cli-0.1.0/commands/meanwhile-build.md +24 -0
  9. meanwhile_cli-0.1.0/hooks/codex-hooks.json +26 -0
  10. meanwhile_cli-0.1.0/hooks/hooks.json +26 -0
  11. meanwhile_cli-0.1.0/hooks/meanwhile-state.sh +103 -0
  12. meanwhile_cli-0.1.0/plugin.json +30 -0
  13. meanwhile_cli-0.1.0/pyproject.toml +54 -0
  14. meanwhile_cli-0.1.0/src/meanwhile/__init__.py +1 -0
  15. meanwhile_cli-0.1.0/src/meanwhile/agents.py +314 -0
  16. meanwhile_cli-0.1.0/src/meanwhile/app.py +187 -0
  17. meanwhile_cli-0.1.0/src/meanwhile/app.tcss +6 -0
  18. meanwhile_cli-0.1.0/src/meanwhile/build_prompt.md +73 -0
  19. meanwhile_cli-0.1.0/src/meanwhile/cli.py +223 -0
  20. meanwhile_cli-0.1.0/src/meanwhile/game.py +70 -0
  21. meanwhile_cli-0.1.0/src/meanwhile/hooks_cli.py +308 -0
  22. meanwhile_cli-0.1.0/src/meanwhile/meanwhile-state.sh +103 -0
  23. meanwhile_cli-0.1.0/src/meanwhile/pool.py +101 -0
  24. meanwhile_cli-0.1.0/src/meanwhile/repo.py +30 -0
  25. meanwhile_cli-0.1.0/src/meanwhile/scores.py +44 -0
  26. meanwhile_cli-0.1.0/src/meanwhile/state.py +66 -0
  27. meanwhile_cli-0.1.0/src/meanwhile/strings.py +42 -0
  28. meanwhile_cli-0.1.0/tests/test_agents.py +287 -0
  29. meanwhile_cli-0.1.0/tests/test_app.py +454 -0
  30. meanwhile_cli-0.1.0/tests/test_cli.py +173 -0
  31. meanwhile_cli-0.1.0/tests/test_game.py +86 -0
  32. meanwhile_cli-0.1.0/tests/test_hooks_cli.py +539 -0
  33. meanwhile_cli-0.1.0/tests/test_plugin_files.py +212 -0
  34. meanwhile_cli-0.1.0/tests/test_pool.py +112 -0
  35. meanwhile_cli-0.1.0/tests/test_repo.py +51 -0
  36. meanwhile_cli-0.1.0/tests/test_scores.py +32 -0
  37. meanwhile_cli-0.1.0/tests/test_state.py +394 -0
  38. meanwhile_cli-0.1.0/tests/test_strings.py +27 -0
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "meanwhile",
3
+ "interface": {
4
+ "displayName": "meanwhile"
5
+ },
6
+ "plugins": [
7
+ {
8
+ "name": "meanwhile",
9
+ "source": {
10
+ "source": "local",
11
+ "path": "./"
12
+ },
13
+ "policy": {
14
+ "installation": "AVAILABLE",
15
+ "authentication": "ON_INSTALL"
16
+ },
17
+ "category": "Productivity"
18
+ }
19
+ ]
20
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "meanwhile",
3
+ "description": "Play a quiz about your own repository while Claude Code is working, so your context stays loaded for the diff review that follows.",
4
+ "owner": {
5
+ "name": "Ismail Bayram"
6
+ },
7
+ "plugins": [
8
+ {
9
+ "name": "meanwhile",
10
+ "source": ".",
11
+ "version": "0.1.0",
12
+ "description": "Play a quiz about your own repository while Claude Code is working, so your context stays loaded for the diff review that follows."
13
+ }
14
+ ]
15
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "meanwhile",
3
+ "description": "Play a quiz about your own repository while Claude Code is working, so your context stays loaded for the diff review that follows.",
4
+ "version": "0.1.0",
5
+ "author": {
6
+ "name": "Ismail Bayram"
7
+ },
8
+ "license": "MIT",
9
+ "keywords": [
10
+ "quiz",
11
+ "context",
12
+ "review",
13
+ "waiting"
14
+ ]
15
+ }
@@ -0,0 +1,6 @@
1
+ __pycache__/
2
+ *.egg-info/
3
+ .pytest_cache/
4
+ dist/
5
+ .venv/
6
+ .meanwhile/scores.json
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ismail Bayram
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,265 @@
1
+ Metadata-Version: 2.5
2
+ Name: meanwhile-cli
3
+ Version: 0.1.0
4
+ Summary: Play a quiz about your own repository while your coding agent works
5
+ Project-URL: Homepage, https://github.com/ismailbayram/meanwhile
6
+ Project-URL: Repository, https://github.com/ismailbayram/meanwhile
7
+ License: MIT
8
+ License-File: LICENSE
9
+ Requires-Python: >=3.10
10
+ Requires-Dist: textual>=0.80
11
+ Provides-Extra: dev
12
+ Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
13
+ Requires-Dist: pytest>=8.0; extra == 'dev'
14
+ Description-Content-Type: text/markdown
15
+
16
+ # meanwhile
17
+
18
+ Claude Code takes a while on real tasks — often ten or fifteen minutes. During
19
+ that wait, attention drifts: a browser tab, a chat, something unrelated. When
20
+ the diff finally lands, you no longer hold the task in your head, and the
21
+ review that follows is slower and shallower than it should be. meanwhile fills
22
+ that wait with a quiz built entirely from your own repository, so that
23
+ instead of drifting away you stay warmed up on the code you're about to
24
+ review. It works the same way alongside Codex, Cursor and OpenCode.
25
+
26
+ ## Install
27
+
28
+ ### Claude Code
29
+
30
+ meanwhile is a Claude Code plugin, and this repository is also its own
31
+ marketplace (`.claude-plugin/marketplace.json`). Add it as a marketplace,
32
+ then install the plugin from it:
33
+
34
+ ```
35
+ /plugin marketplace add ismailbayram/meanwhile
36
+ /plugin install meanwhile@meanwhile
37
+ ```
38
+
39
+ (While developing against a checkout of this repo, add the local path
40
+ instead — `/plugin marketplace add /path/to/meanwhile`.) Restart Claude Code
41
+ afterwards so the plugin's hooks are picked up.
42
+
43
+ Installing the plugin adds two hooks and one slash command; it does not
44
+ install the `meanwhile` command itself. That's a separate, ordinary Python
45
+ package — see "Daily use" below.
46
+
47
+ ### Codex
48
+
49
+ This repository is a Codex plugin and marketplace too (`plugin.json`,
50
+ `.agents/plugins/marketplace.json`). Add the marketplace:
51
+
52
+ ```
53
+ codex plugin marketplace add ismailbayram/meanwhile
54
+ ```
55
+
56
+ then install `meanwhile` from the Plugins Directory. Codex does not run a
57
+ plugin's hooks until you have reviewed and trusted them, so do that once
58
+ after installing — until then the pane never wakes.
59
+
60
+ ### Cursor, OpenCode, or Codex without the plugin
61
+
62
+ Cursor has no plugin system, so `meanwhile` writes the hook registration into
63
+ the agent's config file directly. The same works for Codex if you would
64
+ rather not install the plugin:
65
+
66
+ ```
67
+ uvx meanwhile-cli hooks install --agent cursor
68
+ uvx meanwhile-cli hooks install --agent codex
69
+ ```
70
+
71
+ OpenCode has no shell hooks at all, only JavaScript plugins, so there the
72
+ same command writes a small plugin file — `.opencode/plugins/meanwhile.js`,
73
+ or `~/.config/opencode/plugins/meanwhile.js` with `--user` — that calls the
74
+ hook script whenever a session goes busy or idle:
75
+
76
+ ```
77
+ uvx meanwhile-cli hooks install --agent opencode
78
+ ```
79
+
80
+ Restart OpenCode afterwards; plugins are loaded at startup. A file already
81
+ at that path that `meanwhile` did not write is refused, never overwritten.
82
+
83
+ (While developing against a checkout of this repo instead of the published
84
+ package, use `uv run meanwhile hooks install --agent codex` from inside it.)
85
+
86
+ Leaving off `--agent` (or passing `--agent auto` explicitly) installs for
87
+ every agent whose config directory already exists in this project — it never
88
+ creates one, so an agent you don't use is left alone. `meanwhile hooks status`
89
+ reports what's registered and where — only the registrations meanwhile itself
90
+ wrote, so a *plugin* install is invisible to it: Claude Code shows as `not
91
+ installed (the plugin registers its own hooks separately)`, Codex as plain
92
+ `not installed`. `meanwhile hooks
93
+ uninstall --agent <agent>` takes a registration back out.
94
+
95
+ Cursor only supports project-scope registration. `--user` is refused for it:
96
+ Cursor runs its user-level hooks from `~/.cursor/`, while the hook keys the
97
+ state file on its working directory, so a user-level registration could
98
+ never wake the right pane.
99
+
100
+ For Claude Code, a `hooks install` registration is written to
101
+ `.claude/settings.local.json`, not `settings.json` — the entry embeds an
102
+ absolute path to this machine's copy of the hook script, and `settings.json`
103
+ is the file teams commit. A Codex, Cursor or OpenCode project registration
104
+ has no such gitignored sibling to move to, so `hooks install` prints a note there — every
105
+ time, whether or not git already tracks the file — saying that the path it
106
+ just wrote is specific to this machine and that committing it would leave
107
+ teammates running a script they do not have.
108
+
109
+ If you both install the plugin *and* run `meanwhile hooks install` for the
110
+ same agent, the two hooks fire twice per prompt. That's harmless — both copies
111
+ are byte-identical (`hooks/meanwhile-state.sh` for the plugin,
112
+ `~/.meanwhile/meanwhile-state.sh` for the standalone registration) and are run
113
+ with the same arguments against the same state file, so it's one redundant
114
+ run per event — but worth knowing so you don't go looking for a bug.
115
+
116
+ `hooks` is handled before the normal argument parser is built, so it never
117
+ appears in `meanwhile --help`. `build-prompt` (below) does appear there, but
118
+ only as a bare choice with no explanation of what it does — so this README
119
+ is where to learn about both.
120
+
121
+ ## First run
122
+
123
+ In a project you want to play against, build a pool once, up front — nothing
124
+ regenerates it in the background.
125
+
126
+ **Claude Code**: run
127
+
128
+ ```
129
+ /meanwhile-build
130
+ ```
131
+
132
+ This asks Claude to read the repository — models, routes, the README,
133
+ `CHANGELOG.md`, recent commits — and write `.meanwhile/pool.json`: a set of
134
+ multiple-choice questions drawn from that project's actual code.
135
+
136
+ **Codex, Cursor, OpenCode, or any other agent**: `/meanwhile-build` is a Claude Code
137
+ slash command, so run this instead and paste the printed instructions to
138
+ your agent:
139
+
140
+ ```
141
+ uvx meanwhile-cli build-prompt --lang en --repo .
142
+ ```
143
+
144
+ It prints the exact same instructions the slash command uses, so the pool
145
+ comes out the same either way.
146
+
147
+ Commit `.meanwhile/pool.json`. It's checked into the repository on purpose, so
148
+ everyone on the team plays the same pool and nobody pays to regenerate it.
149
+
150
+ `--lang` takes a short language code — `tr` or `en` — not a language name:
151
+ `--lang Turkish` is not recognised and silently leaves the interface in
152
+ English. Those two codes are the only ones the interface itself speaks.
153
+
154
+ A pool built by the build prompt records the language it was written in, and
155
+ the playing interface follows it, with `--lang` overriding that for just your
156
+ pane. `--lang` on `build-prompt` controls what language the cards themselves
157
+ get written in — any code is allowed there, so `--lang de` writes German cards
158
+ and leaves the interface in English. `pool.json` carries the same code in a
159
+ top-level `language` field (it defaults to `en` when absent); the playing
160
+ interface's own chrome — the waiting banner, "correct"/"wrong", and so on —
161
+ follows that field, in `tr` or `en` and in English for anything else.
162
+
163
+ ## Daily use
164
+
165
+ Open a second terminal pane next to the one running your agent — a tmux
166
+ split, an iTerm pane, or just another window — sitting in the *same directory
167
+ you started it in*, and run:
168
+
169
+ ```
170
+ uvx meanwhile-cli
171
+ ```
172
+
173
+ `uvx` runs it without installing anything. To install it for good instead,
174
+ `uv tool install meanwhile-cli` (or `pipx install meanwhile-cli`) — the
175
+ command that leaves on your path is plain `meanwhile`, and it takes the same
176
+ arguments everywhere this README writes `uvx meanwhile-cli`.
177
+
178
+ (While developing against a checkout of this repo instead of the published
179
+ package, use `uv run meanwhile` from inside it.)
180
+
181
+ Open it whenever you like — before your first prompt is fine. The pane sits
182
+ waiting until your agent starts working, wakes up within about a second of
183
+ you submitting a prompt, and serves multiple-choice cards about the
184
+ codebase one at a time. Answer with the number key for the choice you want;
185
+ the footer only ever offers the keys the card on screen can actually take.
186
+ Answering shows the explanation, `space` deals the next card, and a streak
187
+ counter tracks that wait. If a wait runs long enough to reach the end of the
188
+ pool, the pane says so and sits out the rest of it rather than repeating
189
+ questions.
190
+
191
+ The moment your agent finishes, the current card freezes and the pane shows
192
+ `<Agent> is done ^` (or `the agent is done ^` if it can't tell which one),
193
+ which is your cue to switch back.
194
+
195
+ Then leave it open. It stays on that line — it does not clear itself or
196
+ return to the waiting message — until your next prompt, which deals a fresh,
197
+ re-shuffled round, so a long wait never exhausts the pool for the next one.
198
+ You only ever press `q` when you are done for the day. Each wait is scored as
199
+ its own session and added to your totals when it ends; a wait you answered
200
+ nothing in is not recorded.
201
+
202
+ The interface follows the language recorded in the pool. Override it for
203
+ just your pane with `--lang` and a short code, for example `uvx
204
+ meanwhile-cli --lang en`, regardless of what the pool says. `tr` and `en`
205
+ are the two the interface speaks; any other code leaves it in English.
206
+
207
+ ## How it works
208
+
209
+ meanwhile is three independent parts that only ever talk to each other
210
+ through two files on disk — nothing imports anything else, and each part can
211
+ be tested alone:
212
+
213
+ ```
214
+ /meanwhile-build (Claude Code slash command)
215
+ build-prompt (same instructions, any other agent)
216
+ │ writes
217
+ ▼
218
+ .meanwhile/pool.json ← committed to the repo, shared by the team
219
+ │ reads
220
+ ▼
221
+ meanwhile TUI ──watches──► ~/.meanwhile/state/<project-hash>.json
222
+ (uvx, separate pane) ▲
223
+ │ writes
224
+ hooks: plugin (Claude Code, Codex), or `meanwhile
225
+ hooks install` (those two, Cursor, OpenCode)
226
+ ```
227
+
228
+ - **`/meanwhile-build`** (or `meanwhile build-prompt` for every other agent) is
229
+ the only part that costs tokens or touches an LLM. It reads the repository
230
+ and writes `.meanwhile/pool.json`.
231
+ - **The hooks** are a few lines of pure bash (`hooks/meanwhile-state.sh` for
232
+ the plugin; the same script, packaged inside the wheel and copied to
233
+ `~/.meanwhile/meanwhile-state.sh`, for `hooks install`), fired on the moment
234
+ each agent starts and stops working — `UserPromptSubmit`/`Stop` for
235
+ Claude Code and Codex, `beforeSubmitPrompt`/`stop` for Cursor, and the
236
+ `session.status` event for OpenCode, whose plugin file does nothing but
237
+ call the same script. They write nothing but a
238
+ `{"status": "busy"|"idle", "ts": ..., "agent": ...}` file under
239
+ `~/.meanwhile/state/`, keyed by a hash of the directory the agent was
240
+ started in (that is what `CLAUDE_PROJECT_DIR` holds for Claude Code — not
241
+ necessarily the git root, which is why the TUI must be launched from the
242
+ same directory). No interpreter, no network, no measurable delay added to
243
+ your prompt.
244
+ - **The `meanwhile` TUI**, run separately as `uvx meanwhile-cli`, polls
245
+ that state file and renders cards from the pool. It finds
246
+ `.meanwhile/pool.json` at the git root above wherever you launched it. It makes no LLM calls and
247
+ parses no source code at play time — it only reads the two JSON files
248
+ above.
249
+
250
+ ## Refreshing a stale pool
251
+
252
+ `pool.json` records the commit it was built from. If the repository has
253
+ moved on more than about 50 commits since then, the TUI shows a banner —
254
+ `pool is N commits behind — run the build command for fresh questions` — but
255
+ it never regenerates the pool on its own. Silent background regeneration
256
+ would spend tokens you didn't ask for, which is exactly what this design
257
+ avoids. Run `/meanwhile-build` (or `meanwhile build-prompt`) again when you see
258
+ the banner (or whenever the pool just feels stale) and commit the updated
259
+ file.
260
+
261
+ ## Scores
262
+
263
+ Your running total and best streak are written to `.meanwhile/scores.json`.
264
+ That file is gitignored — scores are local to your machine and never shared
265
+ or synced between teammates.
@@ -0,0 +1,250 @@
1
+ # meanwhile
2
+
3
+ Claude Code takes a while on real tasks — often ten or fifteen minutes. During
4
+ that wait, attention drifts: a browser tab, a chat, something unrelated. When
5
+ the diff finally lands, you no longer hold the task in your head, and the
6
+ review that follows is slower and shallower than it should be. meanwhile fills
7
+ that wait with a quiz built entirely from your own repository, so that
8
+ instead of drifting away you stay warmed up on the code you're about to
9
+ review. It works the same way alongside Codex, Cursor and OpenCode.
10
+
11
+ ## Install
12
+
13
+ ### Claude Code
14
+
15
+ meanwhile is a Claude Code plugin, and this repository is also its own
16
+ marketplace (`.claude-plugin/marketplace.json`). Add it as a marketplace,
17
+ then install the plugin from it:
18
+
19
+ ```
20
+ /plugin marketplace add ismailbayram/meanwhile
21
+ /plugin install meanwhile@meanwhile
22
+ ```
23
+
24
+ (While developing against a checkout of this repo, add the local path
25
+ instead — `/plugin marketplace add /path/to/meanwhile`.) Restart Claude Code
26
+ afterwards so the plugin's hooks are picked up.
27
+
28
+ Installing the plugin adds two hooks and one slash command; it does not
29
+ install the `meanwhile` command itself. That's a separate, ordinary Python
30
+ package — see "Daily use" below.
31
+
32
+ ### Codex
33
+
34
+ This repository is a Codex plugin and marketplace too (`plugin.json`,
35
+ `.agents/plugins/marketplace.json`). Add the marketplace:
36
+
37
+ ```
38
+ codex plugin marketplace add ismailbayram/meanwhile
39
+ ```
40
+
41
+ then install `meanwhile` from the Plugins Directory. Codex does not run a
42
+ plugin's hooks until you have reviewed and trusted them, so do that once
43
+ after installing — until then the pane never wakes.
44
+
45
+ ### Cursor, OpenCode, or Codex without the plugin
46
+
47
+ Cursor has no plugin system, so `meanwhile` writes the hook registration into
48
+ the agent's config file directly. The same works for Codex if you would
49
+ rather not install the plugin:
50
+
51
+ ```
52
+ uvx meanwhile-cli hooks install --agent cursor
53
+ uvx meanwhile-cli hooks install --agent codex
54
+ ```
55
+
56
+ OpenCode has no shell hooks at all, only JavaScript plugins, so there the
57
+ same command writes a small plugin file — `.opencode/plugins/meanwhile.js`,
58
+ or `~/.config/opencode/plugins/meanwhile.js` with `--user` — that calls the
59
+ hook script whenever a session goes busy or idle:
60
+
61
+ ```
62
+ uvx meanwhile-cli hooks install --agent opencode
63
+ ```
64
+
65
+ Restart OpenCode afterwards; plugins are loaded at startup. A file already
66
+ at that path that `meanwhile` did not write is refused, never overwritten.
67
+
68
+ (While developing against a checkout of this repo instead of the published
69
+ package, use `uv run meanwhile hooks install --agent codex` from inside it.)
70
+
71
+ Leaving off `--agent` (or passing `--agent auto` explicitly) installs for
72
+ every agent whose config directory already exists in this project — it never
73
+ creates one, so an agent you don't use is left alone. `meanwhile hooks status`
74
+ reports what's registered and where — only the registrations meanwhile itself
75
+ wrote, so a *plugin* install is invisible to it: Claude Code shows as `not
76
+ installed (the plugin registers its own hooks separately)`, Codex as plain
77
+ `not installed`. `meanwhile hooks
78
+ uninstall --agent <agent>` takes a registration back out.
79
+
80
+ Cursor only supports project-scope registration. `--user` is refused for it:
81
+ Cursor runs its user-level hooks from `~/.cursor/`, while the hook keys the
82
+ state file on its working directory, so a user-level registration could
83
+ never wake the right pane.
84
+
85
+ For Claude Code, a `hooks install` registration is written to
86
+ `.claude/settings.local.json`, not `settings.json` — the entry embeds an
87
+ absolute path to this machine's copy of the hook script, and `settings.json`
88
+ is the file teams commit. A Codex, Cursor or OpenCode project registration
89
+ has no such gitignored sibling to move to, so `hooks install` prints a note there — every
90
+ time, whether or not git already tracks the file — saying that the path it
91
+ just wrote is specific to this machine and that committing it would leave
92
+ teammates running a script they do not have.
93
+
94
+ If you both install the plugin *and* run `meanwhile hooks install` for the
95
+ same agent, the two hooks fire twice per prompt. That's harmless — both copies
96
+ are byte-identical (`hooks/meanwhile-state.sh` for the plugin,
97
+ `~/.meanwhile/meanwhile-state.sh` for the standalone registration) and are run
98
+ with the same arguments against the same state file, so it's one redundant
99
+ run per event — but worth knowing so you don't go looking for a bug.
100
+
101
+ `hooks` is handled before the normal argument parser is built, so it never
102
+ appears in `meanwhile --help`. `build-prompt` (below) does appear there, but
103
+ only as a bare choice with no explanation of what it does — so this README
104
+ is where to learn about both.
105
+
106
+ ## First run
107
+
108
+ In a project you want to play against, build a pool once, up front — nothing
109
+ regenerates it in the background.
110
+
111
+ **Claude Code**: run
112
+
113
+ ```
114
+ /meanwhile-build
115
+ ```
116
+
117
+ This asks Claude to read the repository — models, routes, the README,
118
+ `CHANGELOG.md`, recent commits — and write `.meanwhile/pool.json`: a set of
119
+ multiple-choice questions drawn from that project's actual code.
120
+
121
+ **Codex, Cursor, OpenCode, or any other agent**: `/meanwhile-build` is a Claude Code
122
+ slash command, so run this instead and paste the printed instructions to
123
+ your agent:
124
+
125
+ ```
126
+ uvx meanwhile-cli build-prompt --lang en --repo .
127
+ ```
128
+
129
+ It prints the exact same instructions the slash command uses, so the pool
130
+ comes out the same either way.
131
+
132
+ Commit `.meanwhile/pool.json`. It's checked into the repository on purpose, so
133
+ everyone on the team plays the same pool and nobody pays to regenerate it.
134
+
135
+ `--lang` takes a short language code — `tr` or `en` — not a language name:
136
+ `--lang Turkish` is not recognised and silently leaves the interface in
137
+ English. Those two codes are the only ones the interface itself speaks.
138
+
139
+ A pool built by the build prompt records the language it was written in, and
140
+ the playing interface follows it, with `--lang` overriding that for just your
141
+ pane. `--lang` on `build-prompt` controls what language the cards themselves
142
+ get written in — any code is allowed there, so `--lang de` writes German cards
143
+ and leaves the interface in English. `pool.json` carries the same code in a
144
+ top-level `language` field (it defaults to `en` when absent); the playing
145
+ interface's own chrome — the waiting banner, "correct"/"wrong", and so on —
146
+ follows that field, in `tr` or `en` and in English for anything else.
147
+
148
+ ## Daily use
149
+
150
+ Open a second terminal pane next to the one running your agent — a tmux
151
+ split, an iTerm pane, or just another window — sitting in the *same directory
152
+ you started it in*, and run:
153
+
154
+ ```
155
+ uvx meanwhile-cli
156
+ ```
157
+
158
+ `uvx` runs it without installing anything. To install it for good instead,
159
+ `uv tool install meanwhile-cli` (or `pipx install meanwhile-cli`) — the
160
+ command that leaves on your path is plain `meanwhile`, and it takes the same
161
+ arguments everywhere this README writes `uvx meanwhile-cli`.
162
+
163
+ (While developing against a checkout of this repo instead of the published
164
+ package, use `uv run meanwhile` from inside it.)
165
+
166
+ Open it whenever you like — before your first prompt is fine. The pane sits
167
+ waiting until your agent starts working, wakes up within about a second of
168
+ you submitting a prompt, and serves multiple-choice cards about the
169
+ codebase one at a time. Answer with the number key for the choice you want;
170
+ the footer only ever offers the keys the card on screen can actually take.
171
+ Answering shows the explanation, `space` deals the next card, and a streak
172
+ counter tracks that wait. If a wait runs long enough to reach the end of the
173
+ pool, the pane says so and sits out the rest of it rather than repeating
174
+ questions.
175
+
176
+ The moment your agent finishes, the current card freezes and the pane shows
177
+ `<Agent> is done ^` (or `the agent is done ^` if it can't tell which one),
178
+ which is your cue to switch back.
179
+
180
+ Then leave it open. It stays on that line — it does not clear itself or
181
+ return to the waiting message — until your next prompt, which deals a fresh,
182
+ re-shuffled round, so a long wait never exhausts the pool for the next one.
183
+ You only ever press `q` when you are done for the day. Each wait is scored as
184
+ its own session and added to your totals when it ends; a wait you answered
185
+ nothing in is not recorded.
186
+
187
+ The interface follows the language recorded in the pool. Override it for
188
+ just your pane with `--lang` and a short code, for example `uvx
189
+ meanwhile-cli --lang en`, regardless of what the pool says. `tr` and `en`
190
+ are the two the interface speaks; any other code leaves it in English.
191
+
192
+ ## How it works
193
+
194
+ meanwhile is three independent parts that only ever talk to each other
195
+ through two files on disk — nothing imports anything else, and each part can
196
+ be tested alone:
197
+
198
+ ```
199
+ /meanwhile-build (Claude Code slash command)
200
+ build-prompt (same instructions, any other agent)
201
+ │ writes
202
+ ▼
203
+ .meanwhile/pool.json ← committed to the repo, shared by the team
204
+ │ reads
205
+ ▼
206
+ meanwhile TUI ──watches──► ~/.meanwhile/state/<project-hash>.json
207
+ (uvx, separate pane) ▲
208
+ │ writes
209
+ hooks: plugin (Claude Code, Codex), or `meanwhile
210
+ hooks install` (those two, Cursor, OpenCode)
211
+ ```
212
+
213
+ - **`/meanwhile-build`** (or `meanwhile build-prompt` for every other agent) is
214
+ the only part that costs tokens or touches an LLM. It reads the repository
215
+ and writes `.meanwhile/pool.json`.
216
+ - **The hooks** are a few lines of pure bash (`hooks/meanwhile-state.sh` for
217
+ the plugin; the same script, packaged inside the wheel and copied to
218
+ `~/.meanwhile/meanwhile-state.sh`, for `hooks install`), fired on the moment
219
+ each agent starts and stops working — `UserPromptSubmit`/`Stop` for
220
+ Claude Code and Codex, `beforeSubmitPrompt`/`stop` for Cursor, and the
221
+ `session.status` event for OpenCode, whose plugin file does nothing but
222
+ call the same script. They write nothing but a
223
+ `{"status": "busy"|"idle", "ts": ..., "agent": ...}` file under
224
+ `~/.meanwhile/state/`, keyed by a hash of the directory the agent was
225
+ started in (that is what `CLAUDE_PROJECT_DIR` holds for Claude Code — not
226
+ necessarily the git root, which is why the TUI must be launched from the
227
+ same directory). No interpreter, no network, no measurable delay added to
228
+ your prompt.
229
+ - **The `meanwhile` TUI**, run separately as `uvx meanwhile-cli`, polls
230
+ that state file and renders cards from the pool. It finds
231
+ `.meanwhile/pool.json` at the git root above wherever you launched it. It makes no LLM calls and
232
+ parses no source code at play time — it only reads the two JSON files
233
+ above.
234
+
235
+ ## Refreshing a stale pool
236
+
237
+ `pool.json` records the commit it was built from. If the repository has
238
+ moved on more than about 50 commits since then, the TUI shows a banner —
239
+ `pool is N commits behind — run the build command for fresh questions` — but
240
+ it never regenerates the pool on its own. Silent background regeneration
241
+ would spend tokens you didn't ask for, which is exactly what this design
242
+ avoids. Run `/meanwhile-build` (or `meanwhile build-prompt`) again when you see
243
+ the banner (or whenever the pool just feels stale) and commit the updated
244
+ file.
245
+
246
+ ## Scores
247
+
248
+ Your running total and best streak are written to `.meanwhile/scores.json`.
249
+ That file is gitignored — scores are local to your machine and never shared
250
+ or synced between teammates.
@@ -0,0 +1,24 @@
1
+ ---
2
+ description: Generate the meanwhile question pool for this repository
3
+ ---
4
+
5
+ Build `.meanwhile/pool.json` for the current repository.
6
+
7
+ The instructions for this now live in `meanwhile/build_prompt.md`, packaged
8
+ with the CLI, so Codex and Cursor users get the same text through
9
+ `meanwhile build-prompt` — this command is a thin pointer at it, not a copy.
10
+
11
+ Run:
12
+
13
+ uvx meanwhile-cli build-prompt --lang <code> --repo .
14
+
15
+ (during development, from a checkout of this plugin: `uv run meanwhile
16
+ build-prompt --lang <code> --repo .`)
17
+
18
+ `<code>` is a short language code, not a language name: pass `en` unless the
19
+ user asked for another language. `tr` and `en` are the two the playing
20
+ interface speaks; any other code (`de`, `fr`, ...) still writes the cards in
21
+ that language, but leaves the interface in English. `--repo` is a path, and
22
+ `.` — this repository — is what you want. Then follow the printed instructions
23
+ exactly — they cover what to read, the pool's JSON shape, the secret-file
24
+ rules, and how to finish — to build `.meanwhile/pool.json`.
@@ -0,0 +1,26 @@
1
+ {
2
+ "hooks": {
3
+ "UserPromptSubmit": [
4
+ {
5
+ "hooks": [
6
+ {
7
+ "type": "command",
8
+ "command": "\"${PLUGIN_ROOT}/hooks/meanwhile-state.sh\" busy codex",
9
+ "timeout": 5
10
+ }
11
+ ]
12
+ }
13
+ ],
14
+ "Stop": [
15
+ {
16
+ "hooks": [
17
+ {
18
+ "type": "command",
19
+ "command": "\"${PLUGIN_ROOT}/hooks/meanwhile-state.sh\" idle codex",
20
+ "timeout": 5
21
+ }
22
+ ]
23
+ }
24
+ ]
25
+ }
26
+ }
@@ -0,0 +1,26 @@
1
+ {
2
+ "hooks": {
3
+ "UserPromptSubmit": [
4
+ {
5
+ "hooks": [
6
+ {
7
+ "type": "command",
8
+ "command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/meanwhile-state.sh\" busy claude",
9
+ "timeout": 5
10
+ }
11
+ ]
12
+ }
13
+ ],
14
+ "Stop": [
15
+ {
16
+ "hooks": [
17
+ {
18
+ "type": "command",
19
+ "command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/meanwhile-state.sh\" idle claude",
20
+ "timeout": 5
21
+ }
22
+ ]
23
+ }
24
+ ]
25
+ }
26
+ }