agent-toggle 0.8.1__tar.gz → 0.10.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 (90) hide show
  1. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/PKG-INFO +144 -14
  2. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/README.md +143 -13
  3. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/agent_toggle/__init__.py +1 -1
  4. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/agent_toggle/cli.py +12 -15
  5. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/agent_toggle/fs.py +4 -0
  6. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/agent_toggle/help.py +7 -5
  7. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/agent_toggle/locales/zh_tw_cli.py +2 -1
  8. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/agent_toggle/locales/zh_tw_config.py +2 -0
  9. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/agent_toggle/profiles.py +46 -3
  10. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/agent_toggle/settings.py +2 -0
  11. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/agent_toggle/shims/claude.md.tmpl +45 -3
  12. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/agent_toggle/shims/generic.md.tmpl +36 -4
  13. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/agent_toggle/store.py +9 -0
  14. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/agent_toggle/ui/config_menu.py +101 -30
  15. agent_toggle-0.10.0/agent_toggle/ui/logo.py +182 -0
  16. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/agent_toggle/ui/picker.py +2 -1
  17. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/agent_toggle.egg-info/PKG-INFO +144 -14
  18. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/agent_toggle.egg-info/SOURCES.txt +2 -0
  19. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/tests/test_cli.py +5 -0
  20. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/tests/test_cli_surface.py +13 -0
  21. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/tests/test_config_menu.py +22 -2
  22. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/tests/test_help.py +2 -1
  23. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/tests/test_install.py +1 -2
  24. agent_toggle-0.10.0/tests/test_logo.py +147 -0
  25. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/tests/test_mods.py +9 -0
  26. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/tests/test_profiles.py +52 -0
  27. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/LICENSE +0 -0
  28. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/agent_toggle/__main__.py +0 -0
  29. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/agent_toggle/backends/__init__.py +0 -0
  30. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/agent_toggle/backends/flag_json.py +0 -0
  31. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/agent_toggle/backends/mcp_json.py +0 -0
  32. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/agent_toggle/backends/mcp_toml.py +0 -0
  33. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/agent_toggle/backends/plugin_cli.py +0 -0
  34. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/agent_toggle/companions.py +0 -0
  35. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/agent_toggle/config.py +0 -0
  36. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/agent_toggle/cost.py +0 -0
  37. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/agent_toggle/doctor.py +0 -0
  38. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/agent_toggle/harnesses.py +0 -0
  39. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/agent_toggle/i18n.py +0 -0
  40. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/agent_toggle/locales/__init__.py +0 -0
  41. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/agent_toggle/locales/zh_tw_common.py +0 -0
  42. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/agent_toggle/locales/zh_tw_picker.py +0 -0
  43. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/agent_toggle/mechanisms.py +0 -0
  44. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/agent_toggle/ops.py +0 -0
  45. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/agent_toggle/output.py +0 -0
  46. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/agent_toggle/spinner.py +0 -0
  47. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/agent_toggle/toml_check.py +0 -0
  48. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/agent_toggle/ui/__init__.py +0 -0
  49. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/agent_toggle/ui/menu.py +0 -0
  50. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/agent_toggle/ui/model.py +0 -0
  51. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/agent_toggle/ui/theme.py +0 -0
  52. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/agent_toggle/undo.py +0 -0
  53. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/agent_toggle/update_check.py +0 -0
  54. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/agent_toggle/update_prompt.py +0 -0
  55. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/agent_toggle.egg-info/dependency_links.txt +0 -0
  56. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/agent_toggle.egg-info/entry_points.txt +0 -0
  57. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/agent_toggle.egg-info/requires.txt +0 -0
  58. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/agent_toggle.egg-info/top_level.txt +0 -0
  59. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/pyproject.toml +0 -0
  60. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/setup.cfg +0 -0
  61. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/tests/test_alias.py +0 -0
  62. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/tests/test_all_type.py +0 -0
  63. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/tests/test_backends.py +0 -0
  64. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/tests/test_color.py +0 -0
  65. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/tests/test_companions.py +0 -0
  66. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/tests/test_completions.py +0 -0
  67. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/tests/test_config.py +0 -0
  68. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/tests/test_conformance.py +0 -0
  69. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/tests/test_containment.py +0 -0
  70. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/tests/test_cost.py +0 -0
  71. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/tests/test_crash.py +0 -0
  72. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/tests/test_doctor.py +0 -0
  73. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/tests/test_encoding.py +0 -0
  74. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/tests/test_fs.py +0 -0
  75. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/tests/test_harnesses.py +0 -0
  76. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/tests/test_i18n.py +0 -0
  77. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/tests/test_mechanisms.py +0 -0
  78. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/tests/test_menu.py +0 -0
  79. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/tests/test_picker.py +0 -0
  80. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/tests/test_platform.py +0 -0
  81. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/tests/test_project.py +0 -0
  82. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/tests/test_safety.py +0 -0
  83. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/tests/test_same_name.py +0 -0
  84. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/tests/test_secret_audit.py +0 -0
  85. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/tests/test_settings.py +0 -0
  86. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/tests/test_store.py +0 -0
  87. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/tests/test_theme.py +0 -0
  88. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/tests/test_undo.py +0 -0
  89. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/tests/test_update_check.py +0 -0
  90. {agent_toggle-0.8.1 → agent_toggle-0.10.0}/tests/test_update_prompt.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agent-toggle
3
- Version: 0.8.1
3
+ Version: 0.10.0
4
4
  Summary: Temporarily disable / re-enable AI-agent skills, agents, commands, rules, plugins and MCP servers across harnesses (Claude Code, Codex, Grok, OpenCode, OpenClaw, Copilot, Vibe, Devin, Antigravity)
5
5
  License-Expression: MIT
6
6
  Project-URL: Homepage, https://github.com/weskao/agent-toggle
@@ -32,6 +32,8 @@ Dynamic: license-file
32
32
 
33
33
  # agent-toggle
34
34
 
35
+ PyPI: <https://pypi.org/project/agent-toggle/>
36
+
35
37
  Temporarily disable and restore AI-agent resources — skills, agents, commands,
36
38
  rules, plugins (mods included), MCP servers — across Claude Code, Codex, Grok CLI, OpenCode,
37
39
  OpenClaw, Copilot, Vibe, Devin and Antigravity — and show what each one costs at
@@ -40,6 +42,27 @@ session start.
40
42
  **Nothing is ever deleted.** Everything is parked and recorded, and `enable`
41
43
  puts it back where it came from.
42
44
 
45
+ ## At a glance
46
+
47
+ <!-- Absolute URLs so the images also render on PyPI, which uses this README. -->
48
+
49
+ **`agent-toggle ui`**: one list per harness, with what each resource costs in tokens.
50
+ Toggle rows, see the token change before you apply it, and apply it as one batch that
51
+ `undo` reverses ([Interactive picker](#interactive-picker)).
52
+
53
+ ![agent-toggle ui: the interactive picker](https://raw.githubusercontent.com/weskao/agent-toggle/main/docs/images/ui-picker.jpeg)
54
+
55
+ **`agent-toggle config`**: every setting in one menu. Turn harnesses on or off and set the
56
+ language, update check and Telegram notifications. It also runs tools such as `doctor` and
57
+ `undo` ([Settings & config menu](#settings--config-menu)).
58
+
59
+ ![agent-toggle config: the settings menu](https://raw.githubusercontent.com/weskao/agent-toggle/main/docs/images/config-menu.jpeg)
60
+
61
+ **`/agent-toggle` inside Claude Code**: the same picker as a pane, for turning skills, MCP
62
+ servers, plugins and mods on or off without leaving the session ([Claude Code pane mod](#claude-code-pane-mod)).
63
+
64
+ ![/agent-toggle: the picker as a Claude Code pane](https://raw.githubusercontent.com/weskao/agent-toggle/main/docs/images/claude-pane-mod.jpeg)
65
+
43
66
  ## Why
44
67
 
45
68
  | target | native mechanism | the gap |
@@ -59,18 +82,19 @@ uv tool install agent-toggle
59
82
  agent-toggle --version
60
83
  ```
61
84
 
62
- Straight from this repository, pinned to a release tag (`v0.5.1` is the current one;
63
- an unpinned `git+` URL installs whatever is on the default branch):
85
+ Straight from this repository, pinned to a release tag (replace `vX.Y.Z` with one from
86
+ [tags](https://github.com/weskao/agent-toggle/tags); an unpinned `git+` URL installs
87
+ whatever is on the default branch):
64
88
 
65
89
  ```sh
66
- uv tool install git+https://github.com/weskao/agent-toggle@v0.5.1
90
+ uv tool install git+https://github.com/weskao/agent-toggle@vX.Y.Z
67
91
  agent-toggle --version
68
92
  ```
69
93
 
70
94
  Alternatively, use `pipx`:
71
95
 
72
96
  ```sh
73
- pipx install agent-toggle # from PyPI; or: pipx install git+https://github.com/weskao/agent-toggle@v0.5.1
97
+ pipx install agent-toggle # from PyPI; or: pipx install git+https://github.com/weskao/agent-toggle@vX.Y.Z
74
98
  ```
75
99
 
76
100
  From a checkout, either install it editable or run it in place:
@@ -86,12 +110,13 @@ Python 3.10+, no runtime dependencies. Then write the skill shim:
86
110
 
87
111
  ```sh
88
112
  agent-toggle install-shims # installed, or: ./install.sh (a thin wrapper)
89
- python3 agent_toggle.py install-shims # from a checkout, no install needed
113
+ python3 agent_toggle.py install-shims # from a checkout
90
114
  ```
91
115
 
92
116
  `install-shims` writes a thin skill shim (`skills/agent-toggle/SKILL.md`) into
93
117
  every installed harness that supports skills, so `/agent-toggle` works from any
94
- of them. It writes nothing else into a harness home: parked items live under
118
+ of them. The shim calls `agent-toggle` on `PATH` and never a checkout path, so install
119
+ the package (or `pip install -e .`) before relying on it. It writes nothing else into a harness home: parked items live under
95
120
  `~/.agent-toggle/parked/`, so a harness-home `.gitignore` needs no park-dir
96
121
  line. Older versions appended `<dir>-disabled/` lines there; inside a git work
97
122
  tree, `install-shims` reports such stale lines once `migrate` has emptied the
@@ -133,6 +158,18 @@ Without the extra everything else works exactly as before. Only `config test`,
133
158
  [settings menu](#settings--config-menu) need it; bare `config` still opens, and
134
159
  those rows read `install agent-toggle[telegram]`.
135
160
 
161
+ **Optional: the Claude Code pane mod** (the picker as a pane inside Claude Code, claude harness
162
+ only). It is not part of the PyPI package; with `agent-toggle` already on `PATH` from one of the
163
+ installs above, type this at the prompt of a Claude Code terminal session (2.1.275 or later):
164
+
165
+ ```
166
+ /plugin install agent-toggle --marketplace weskao/agent-toggle
167
+ ```
168
+
169
+ Answer `y` to add the marketplace, pick a scope (user is the default), then run `/agent-toggle`.
170
+
171
+ See [Claude Code pane mod](#claude-code-pane-mod).
172
+
136
173
  ## Shell completion
137
174
 
138
175
  Each release publishes static completion files for bash, zsh and fish as the
@@ -164,7 +201,7 @@ agent-toggle <command> [args] # or: python3 agent_toggle.py <command> [
164
201
  | `disable\|enable all <name>...` | every type on the harness with that name at once (skill, command, MCP, ...); a name with no match is an `error` row; one batch, so `undo` reverses it |
165
202
  | `enable --all` | put back **every** disabled item (`--harness H` narrows it, `--project <dir>` takes only that project's) |
166
203
  | `undo` | reverse the last logged batch (`--dry-run` shows the plan) |
167
- | `profile save\|apply\|diff\|list` | named sets of live items; see [Profiles](#profiles) |
204
+ | `profile save\|apply\|diff\|list\|delete\|rename` | named sets of live items; see [Profiles](#profiles) |
168
205
  | `config` | settings menu (curses, else a numbered list); `config --json` lists every setting and the package version; see [Settings & config menu](#settings--config-menu) |
169
206
  | `config test\|sync-ci` | send one Telegram test message / set the GitHub CI secrets; needs the `[telegram]` extra; see [CI notifications](#ci-notifications) |
170
207
  | `help [command]` | styled help; `help ui` = `--help ui` = `ui --help`; see [Help](#help) |
@@ -256,7 +293,7 @@ agent-toggle # same, on a terminal; elsewhere prints help and exits
256
293
  ```
257
294
 
258
295
  ```
259
- agent-toggle v0.5.1 5 resources · ~6.3k tok live · 1 staged (+300 tok)
296
+ agent-toggle vX.Y.Z 5 resources · ~6.3k tok live · 1 staged (+300 tok)
260
297
  All 5 │ claude 4 │ codex 2
261
298
  🔍 Type to search (name, path, fuzzy) type: All sort: name
262
299
  Skills 3 ─────────────────────────────────────────────────────────────│ beta
@@ -297,7 +334,7 @@ What is on screen:
297
334
 
298
335
  | key | action |
299
336
  |---|---|
300
- | `Space` | toggle the highlighted row (live / parked) and stay on it (while filtering, `Space` types a space) |
337
+ | `Space` | toggle the highlighted row (live / parked) and stay on it (while searching, the first `Space` separates search terms and a second one toggles) |
301
338
  | `Tab` | toggle the highlighted row and advance to the next |
302
339
  | `Enter` | apply every staged change (with `--dry-run`: show the plan) |
303
340
  | `Esc` / `Ctrl-C` | cancel; nothing is applied |
@@ -332,7 +369,8 @@ off under `--dry-run`. Esc closes the prompt.
332
369
  Nothing happens while the picker is open. Changes are staged, the screen is
333
370
  torn down, and only then do the real operations run, so their output (which
334
371
  companion files moved, which were kept because they are shared) is readable
335
- instead of fighting curses for the terminal.
372
+ instead of fighting curses for the terminal. Claude Code sessions running the
373
+ [pane mod](#claude-code-pane-mod) pick up the Claude changes within 5 s and reload them.
336
374
 
337
375
  Built on stdlib `curses`, so there is nothing to install on macOS and Linux
338
376
  (on Windows, `pip install "agent-toggle[windows]"` pulls `windows-curses`).
@@ -384,10 +422,10 @@ end of input, `q` or an empty line exits `0`
384
422
 
385
423
  | group | rows |
386
424
  |---|---|
387
- | General | Check for updates, Color, Language, Default harness |
425
+ | General | Check for updates, Color, Logo, Language, Default harness |
388
426
  | Harnesses | one On/Off per harness, with `found ~/.x` or `not on this machine` |
389
427
  | Picker | default sort, harness filter, type filter |
390
- | Notifications | Telegram bot token (masked), Telegram chat ID |
428
+ | Notifications | Telegram bot token (masked, last 4 characters shown), Telegram chat ID |
391
429
  | Tools | Health check (`doctor`; then asks y/n per fix it can run), Install shims, Undo last change (asks y/n), Send test message, Sync CI secrets (asks y/n); their output shows in an overlay |
392
430
 
393
431
  Keys: `↑` `↓` move (wraps, skips headings), `←` `→` cycle a value, `Enter` / `Space` change or run
@@ -403,6 +441,7 @@ tool does not know are kept):
403
441
  |---|---|---|---|
404
442
  | `update_check` | `true` / `false` | `true` | `AGENT_TOGGLE_UPDATE_CHECK` |
405
443
  | `color` | `auto` / `always` / `never` | `auto` | `AGENT_TOGGLE_COLOR` |
444
+ | `logo` | `color` / `mono` / `animated` / `off` | `animated` | `AGENT_TOGGLE_LOGO` |
406
445
  | `language` | `en` / `zh-TW` | `en` | `AGENT_TOGGLE_LANG` |
407
446
  | `default_harness` | a harness name | `claude` | `AGENT_TOGGLE_DEFAULT_HARNESS` |
408
447
  | `harness.<name>` | `true` / `false`, for `claude` `codex` `grok` `opencode` `openclaw` `copilot` `vibe` `devin` `agy` | `true` | |
@@ -459,6 +498,13 @@ options and examples; `help help` is the overview, `help version` shows how to p
459
498
  and an unknown command exits `2`. It honours `--color` and `NO_COLOR`, and is
460
499
  translated when `language` is `zh-TW`.
461
500
 
501
+ The overview opens with the agent-toggle logo (cyan to blue to magenta): the large one from 97
502
+ columns, a compact one from 49, none below that. Piped output gets the plain glyphs, a stream
503
+ that cannot encode them gets none. The `logo` setting picks `color`, `mono` (one colour),
504
+ `animated` (one light sweep, only on a colour terminal) or `off`. The config menu shows the same
505
+ logo, centred, when the window is tall enough to fit the whole menu beside it; there,
506
+ `animated` sweeps on entry and again after every 5 s without a key, and any key stops it.
507
+
462
508
  ## What each harness supports
463
509
 
464
510
  | harness | home | skill | agent | command | rule | plugin | mcp |
@@ -555,7 +601,8 @@ visible rather than silent.
555
601
  hand-rolled serializer would mangle comments — a text slice is lossless and
556
602
  much less code.
557
603
 
558
- MCP changes need a **new session** to take effect.
604
+ MCP changes need a **new session** to take effect, except in a Claude Code session running the
605
+ agent-toggle mod, which runs `/mcp disable|enable <name>` for you (see the mod section).
559
606
 
560
607
  ### Claude MCP scopes
561
608
 
@@ -586,6 +633,8 @@ agent-toggle profile diff work # what apply would do; writ
586
633
  agent-toggle profile apply ~/dotfiles/agent-toggle/work.json --dry-run
587
634
  agent-toggle profile apply work
588
635
  agent-toggle profile list
636
+ agent-toggle profile rename work flutter # -> ~/.agent-toggle/profiles/flutter.json
637
+ agent-toggle profile delete flutter
589
638
  ```
590
639
 
591
640
  **`apply` toggles only the items the profile mentions.** An item the profile
@@ -614,6 +663,14 @@ one batch, logged, undoable with `undo`).
614
663
  so a project profile can never disable the user's items.
615
664
  - `save` skips (with a warning) any item whose name `apply` would refuse, such as
616
665
  an MCP server called `team/search`, so a saved profile always applies.
666
+ - `save` to an existing name overwrites it with the live state now; that is how a
667
+ profile is updated.
668
+ - `delete <name>` and `rename <old> <new>` work on stored profiles only (a file
669
+ you saved with `--out` is yours to move or remove) and change no item. Both exit
670
+ `2` for a name with no stored profile or a path; `rename` also exits `2` when
671
+ `<new>` already exists (it never overwrites) or is not a valid profile name, and
672
+ keeps the file byte for byte. Neither takes `--dry-run` or `--project`: a
673
+ project profile is renamed or deleted by its name like any other.
617
674
 
618
675
  ## Undo and `enable --all`
619
676
 
@@ -793,6 +850,7 @@ bookkeeping.
793
850
  | `state.json` | current disabled list (schema v3; atomic write, mode `0600`), saved before each flag write or dir move with the op in flight under an optional `pending` key, and after each MCP / plugin item |
794
851
  | `lock` | held by `disable` / `enable` / `enable --all` / `undo` / `profile apply` / `migrate` / `ui` for the whole batch; a second run waits 5 s then exits `3` (stale after 10 min *and* its PID is gone; a live batch refreshes it per item; the error says when its PID is gone, i.e. a killed run left it) |
795
852
  | `log.jsonl` | one line per operation (mode `0600`), see below |
853
+ | `reload.json` | the Claude rows the last `ui` Enter changed, rewritten each time; open Claude Code sessions running the mod poll it and reload them |
796
854
  | `mcp-backups/` | `<harness>__<server>.json`, or `<sha8>__<harness>__<server>.json` for a project `.mcp.json` (mode `0600` -- may hold auth headers) |
797
855
  | `companions/` | parked exclusive helper files |
798
856
  | `parked/user/<owner>/<dir>/` | user-scope items, e.g. `parked/user/claude/skills/<name>` (`<owner>` = the harness whose home holds the dir; a dir shared by several harnesses parks once, under its owner); an absolute OpenCode `skills.paths` dir parks under `parked/user/opencode/ext-<sha8>/` (`<sha8>` of its resolved path). Nothing is ever parked inside a harness home |
@@ -870,6 +928,69 @@ deletion lines in `git status`.
870
928
  unresolved paths makes every companion look like it lives outside the harness.
871
929
  Both sides are resolved first.
872
930
 
931
+ ## Claude Code pane mod
932
+
933
+ A Claude Code mod in `mod/` that shows the picker as a pane inside Claude (not to be confused
934
+ with the [Mods](#mods) group the picker lists). It is driven by the installed `agent-toggle`
935
+ CLI (`cost --json`, `disable|enable --json`) and works for the claude harness only; the curses
936
+ `agent-toggle ui` stays the cross-harness UI.
937
+
938
+ Install it with `/plugin install agent-toggle --marketplace weskao/agent-toggle` (see
939
+ [Install](#install)); `claude plugin update agent-toggle@agent-toggle` picks up a new release. To
940
+ run your own checkout instead (edits reload as you save):
941
+
942
+ ```sh
943
+ claude --plugin-dir ./mod # then run /agent-toggle inside Claude
944
+ ```
945
+
946
+ - `/agent-toggle` or `/agent-toggle open` opens the pane, `/agent-toggle close` closes it,
947
+ `/agent-toggle toggle` does whichever applies; any other argument that is not a CLI command (below) prints the usage. Ctrl-X X
948
+ also closes it. Claude can do the same when you ask it to open or close agent-toggle: the mod
949
+ registers a `pane` tool (`mcp__agent-toggle__pane`, `action`: `open` | `close` | `toggle`),
950
+ e.g. "open agent-toggle", "close the agent-toggle pane", "toggle the agent-toggle pane".
951
+ Turning resources on or off is unchanged: toggle a row in the pane, or ask Claude in plain
952
+ words ("disable the demo-skill skill", "add it back"), which runs the CLI through the skill shim.
953
+ - It looks like the `ui` picker: a title with the live-token total, a search line, rows under
954
+ type headings with counts, green `●` live / yellow `○` parked, tokens and a bar per row (a
955
+ parked row shows `(N)`, what restoring it would load), the cursor row in reverse video, and a
956
+ key-chip footer. The list scrolls with the cursor; the status line shows its position (`7/23`),
957
+ and the first and last list lines count the rows out of view (`↑ 4`, `↓ 12`).
958
+ - The mouse wheel over the list moves the cursor, as in the terminal picker; no click needed.
959
+ - Click the list once so it takes keys (Esc hands the keyboard back to the prompt). Then `↑` `↓`
960
+ `PgUp` `PgDn` `Home` `End` (also `Ctrl-P` / `Ctrl-N`) move; `Space` or `Enter` toggles the row,
961
+ `Tab` toggles and moves on; `/` or any other letter starts a search (terms ANDed over
962
+ `type/name` and the group, letters-in-order if nothing matches; a second `Space` toggles);
963
+ `s` sorts by name or cost; `n` toggles every type with this row's name (skill, command, MCP,
964
+ ...), like `disable all <name>`; `Ctrl-U` clears the search. A click moves the cursor.
965
+ - A toggle applies at once (no staging, no Enter to apply); the toast names the target and the state
966
+ with an emoji and a bracketed tag (no colour codes, so nothing garbles; on the Linux console and the
967
+ legacy Windows console, where emoji draw as boxes, the tag alone): `✅ [ENABLED] skill: foo`, `⛔ [DISABLED] mod: bar (/reload-plugins)`,
968
+ `⛔ [DISABLED] rule: baz (takes effect in a new session)`, `⛔ [DISABLED] all: foo` after `n`, or `❌ [FAILED] disable skill: foo - <error>`.
969
+ The row flips the moment you press (and flips back
970
+ if the CLI fails); the list reloads in the background. While a toggle runs, further keys are ignored.
971
+ - Opening the pane shows the same braille spinner and `Loading resources…` as `agent-toggle ui`
972
+ until the list arrives, and a spinner beside `working…` while a toggle runs.
973
+ - Not in the pane: harness tabs (claude only), and the `t` `p` `a` keys. Where Claude draws no
974
+ such pane (the mobile app, VS Code) it is a plain list of buttons instead.
975
+ - `/agent-toggle <command> ...` with `disable`, `enable`,
976
+ `undo`, `list`, `status`, `cost` or `doctor` runs the CLI instead of opening the pane and prints
977
+ one line per result row: `/agent-toggle disable skill foo bar` (it adds `--json`, and
978
+ `--harness claude` unless you pass `--harness`). A toggle reloads an open pane.
979
+ - Inside Claude Code the mod then applies the change to the running session by queueing the slash
980
+ command for you, once per kind: skills and commands `/reload-skills`, plugins (mods included)
981
+ `/reload-plugins`, an MCP server `/mcp disable|enable <name>`. The toast names it, e.g.
982
+ `⛔ [DISABLED] skill: foo (/reload-skills)`. Agents and rules have no reload and still say
983
+ `takes effect in a new session`. If Claude refuses a queued command, a toast says so.
984
+ - `agent-toggle ui` in another terminal applies on Enter and writes the Claude rows it changed to
985
+ `~/.agent-toggle/reload.json`. Every open session running the mod checks that file's mtime every
986
+ 5 s (one `stat`) and queues the same reloads, toasting `agent-toggle ui: /reload-skills`. A file
987
+ older than the session is ignored.
988
+ - Needs `agent-toggle` on `PATH`.
989
+ - On Windows `agent-toggle` must resolve to a real executable on `PATH` (a pip or uv install
990
+ provides `agent-toggle.exe`).
991
+
992
+ The design is in `docs/MOD.md`.
993
+
873
994
  ## Design and roadmap
874
995
 
875
996
  Architecture, harness survey, cost model, known gaps and the phased roadmap
@@ -887,6 +1008,13 @@ ruff check .
887
1008
  stdlib `unittest`, no fixtures, no network. Every test runs against a
888
1009
  throwaway temp `HOME` and a stubbed `claude` CLI.
889
1010
 
1011
+ The pane mod has its own checks (they need the `claude` CLI, so CI does not run them):
1012
+
1013
+ ```sh
1014
+ claude plugin validate mod
1015
+ claude plugin test mod
1016
+ ```
1017
+
890
1018
  `python3 tools/wheel_smoke.py` builds the wheel, installs it without extras into a
891
1019
  fresh venv (what a PyPI user gets) and runs the CLI against a temp `HOME`; CI runs
892
1020
  it on macOS, Linux and Windows.
@@ -929,6 +1057,8 @@ prints a `::notice::` and exits 0, so it never adds a second red X.
929
1057
  ## Releasing
930
1058
 
931
1059
  A release is a git tag `vX.Y.Z` (where `X.Y.Z` must match `agent_toggle.__version__`).
1060
+ Bump `version` in `mod/.claude-plugin/plugin.json` to the same value by hand; nothing checks it,
1061
+ and without it `claude plugin update` does not hand marketplace installs the new mod.
932
1062
  Pushing the tag triggers `.github/workflows/release.yml`:
933
1063
 
934
1064
  1. **Build** job checks that the tag matches `__version__`, builds a wheel and
@@ -1,5 +1,7 @@
1
1
  # agent-toggle
2
2
 
3
+ PyPI: <https://pypi.org/project/agent-toggle/>
4
+
3
5
  Temporarily disable and restore AI-agent resources — skills, agents, commands,
4
6
  rules, plugins (mods included), MCP servers — across Claude Code, Codex, Grok CLI, OpenCode,
5
7
  OpenClaw, Copilot, Vibe, Devin and Antigravity — and show what each one costs at
@@ -8,6 +10,27 @@ session start.
8
10
  **Nothing is ever deleted.** Everything is parked and recorded, and `enable`
9
11
  puts it back where it came from.
10
12
 
13
+ ## At a glance
14
+
15
+ <!-- Absolute URLs so the images also render on PyPI, which uses this README. -->
16
+
17
+ **`agent-toggle ui`**: one list per harness, with what each resource costs in tokens.
18
+ Toggle rows, see the token change before you apply it, and apply it as one batch that
19
+ `undo` reverses ([Interactive picker](#interactive-picker)).
20
+
21
+ ![agent-toggle ui: the interactive picker](https://raw.githubusercontent.com/weskao/agent-toggle/main/docs/images/ui-picker.jpeg)
22
+
23
+ **`agent-toggle config`**: every setting in one menu. Turn harnesses on or off and set the
24
+ language, update check and Telegram notifications. It also runs tools such as `doctor` and
25
+ `undo` ([Settings & config menu](#settings--config-menu)).
26
+
27
+ ![agent-toggle config: the settings menu](https://raw.githubusercontent.com/weskao/agent-toggle/main/docs/images/config-menu.jpeg)
28
+
29
+ **`/agent-toggle` inside Claude Code**: the same picker as a pane, for turning skills, MCP
30
+ servers, plugins and mods on or off without leaving the session ([Claude Code pane mod](#claude-code-pane-mod)).
31
+
32
+ ![/agent-toggle: the picker as a Claude Code pane](https://raw.githubusercontent.com/weskao/agent-toggle/main/docs/images/claude-pane-mod.jpeg)
33
+
11
34
  ## Why
12
35
 
13
36
  | target | native mechanism | the gap |
@@ -27,18 +50,19 @@ uv tool install agent-toggle
27
50
  agent-toggle --version
28
51
  ```
29
52
 
30
- Straight from this repository, pinned to a release tag (`v0.5.1` is the current one;
31
- an unpinned `git+` URL installs whatever is on the default branch):
53
+ Straight from this repository, pinned to a release tag (replace `vX.Y.Z` with one from
54
+ [tags](https://github.com/weskao/agent-toggle/tags); an unpinned `git+` URL installs
55
+ whatever is on the default branch):
32
56
 
33
57
  ```sh
34
- uv tool install git+https://github.com/weskao/agent-toggle@v0.5.1
58
+ uv tool install git+https://github.com/weskao/agent-toggle@vX.Y.Z
35
59
  agent-toggle --version
36
60
  ```
37
61
 
38
62
  Alternatively, use `pipx`:
39
63
 
40
64
  ```sh
41
- pipx install agent-toggle # from PyPI; or: pipx install git+https://github.com/weskao/agent-toggle@v0.5.1
65
+ pipx install agent-toggle # from PyPI; or: pipx install git+https://github.com/weskao/agent-toggle@vX.Y.Z
42
66
  ```
43
67
 
44
68
  From a checkout, either install it editable or run it in place:
@@ -54,12 +78,13 @@ Python 3.10+, no runtime dependencies. Then write the skill shim:
54
78
 
55
79
  ```sh
56
80
  agent-toggle install-shims # installed, or: ./install.sh (a thin wrapper)
57
- python3 agent_toggle.py install-shims # from a checkout, no install needed
81
+ python3 agent_toggle.py install-shims # from a checkout
58
82
  ```
59
83
 
60
84
  `install-shims` writes a thin skill shim (`skills/agent-toggle/SKILL.md`) into
61
85
  every installed harness that supports skills, so `/agent-toggle` works from any
62
- of them. It writes nothing else into a harness home: parked items live under
86
+ of them. The shim calls `agent-toggle` on `PATH` and never a checkout path, so install
87
+ the package (or `pip install -e .`) before relying on it. It writes nothing else into a harness home: parked items live under
63
88
  `~/.agent-toggle/parked/`, so a harness-home `.gitignore` needs no park-dir
64
89
  line. Older versions appended `<dir>-disabled/` lines there; inside a git work
65
90
  tree, `install-shims` reports such stale lines once `migrate` has emptied the
@@ -101,6 +126,18 @@ Without the extra everything else works exactly as before. Only `config test`,
101
126
  [settings menu](#settings--config-menu) need it; bare `config` still opens, and
102
127
  those rows read `install agent-toggle[telegram]`.
103
128
 
129
+ **Optional: the Claude Code pane mod** (the picker as a pane inside Claude Code, claude harness
130
+ only). It is not part of the PyPI package; with `agent-toggle` already on `PATH` from one of the
131
+ installs above, type this at the prompt of a Claude Code terminal session (2.1.275 or later):
132
+
133
+ ```
134
+ /plugin install agent-toggle --marketplace weskao/agent-toggle
135
+ ```
136
+
137
+ Answer `y` to add the marketplace, pick a scope (user is the default), then run `/agent-toggle`.
138
+
139
+ See [Claude Code pane mod](#claude-code-pane-mod).
140
+
104
141
  ## Shell completion
105
142
 
106
143
  Each release publishes static completion files for bash, zsh and fish as the
@@ -132,7 +169,7 @@ agent-toggle <command> [args] # or: python3 agent_toggle.py <command> [
132
169
  | `disable\|enable all <name>...` | every type on the harness with that name at once (skill, command, MCP, ...); a name with no match is an `error` row; one batch, so `undo` reverses it |
133
170
  | `enable --all` | put back **every** disabled item (`--harness H` narrows it, `--project <dir>` takes only that project's) |
134
171
  | `undo` | reverse the last logged batch (`--dry-run` shows the plan) |
135
- | `profile save\|apply\|diff\|list` | named sets of live items; see [Profiles](#profiles) |
172
+ | `profile save\|apply\|diff\|list\|delete\|rename` | named sets of live items; see [Profiles](#profiles) |
136
173
  | `config` | settings menu (curses, else a numbered list); `config --json` lists every setting and the package version; see [Settings & config menu](#settings--config-menu) |
137
174
  | `config test\|sync-ci` | send one Telegram test message / set the GitHub CI secrets; needs the `[telegram]` extra; see [CI notifications](#ci-notifications) |
138
175
  | `help [command]` | styled help; `help ui` = `--help ui` = `ui --help`; see [Help](#help) |
@@ -224,7 +261,7 @@ agent-toggle # same, on a terminal; elsewhere prints help and exits
224
261
  ```
225
262
 
226
263
  ```
227
- agent-toggle v0.5.1 5 resources · ~6.3k tok live · 1 staged (+300 tok)
264
+ agent-toggle vX.Y.Z 5 resources · ~6.3k tok live · 1 staged (+300 tok)
228
265
  All 5 │ claude 4 │ codex 2
229
266
  🔍 Type to search (name, path, fuzzy) type: All sort: name
230
267
  Skills 3 ─────────────────────────────────────────────────────────────│ beta
@@ -265,7 +302,7 @@ What is on screen:
265
302
 
266
303
  | key | action |
267
304
  |---|---|
268
- | `Space` | toggle the highlighted row (live / parked) and stay on it (while filtering, `Space` types a space) |
305
+ | `Space` | toggle the highlighted row (live / parked) and stay on it (while searching, the first `Space` separates search terms and a second one toggles) |
269
306
  | `Tab` | toggle the highlighted row and advance to the next |
270
307
  | `Enter` | apply every staged change (with `--dry-run`: show the plan) |
271
308
  | `Esc` / `Ctrl-C` | cancel; nothing is applied |
@@ -300,7 +337,8 @@ off under `--dry-run`. Esc closes the prompt.
300
337
  Nothing happens while the picker is open. Changes are staged, the screen is
301
338
  torn down, and only then do the real operations run, so their output (which
302
339
  companion files moved, which were kept because they are shared) is readable
303
- instead of fighting curses for the terminal.
340
+ instead of fighting curses for the terminal. Claude Code sessions running the
341
+ [pane mod](#claude-code-pane-mod) pick up the Claude changes within 5 s and reload them.
304
342
 
305
343
  Built on stdlib `curses`, so there is nothing to install on macOS and Linux
306
344
  (on Windows, `pip install "agent-toggle[windows]"` pulls `windows-curses`).
@@ -352,10 +390,10 @@ end of input, `q` or an empty line exits `0`
352
390
 
353
391
  | group | rows |
354
392
  |---|---|
355
- | General | Check for updates, Color, Language, Default harness |
393
+ | General | Check for updates, Color, Logo, Language, Default harness |
356
394
  | Harnesses | one On/Off per harness, with `found ~/.x` or `not on this machine` |
357
395
  | Picker | default sort, harness filter, type filter |
358
- | Notifications | Telegram bot token (masked), Telegram chat ID |
396
+ | Notifications | Telegram bot token (masked, last 4 characters shown), Telegram chat ID |
359
397
  | Tools | Health check (`doctor`; then asks y/n per fix it can run), Install shims, Undo last change (asks y/n), Send test message, Sync CI secrets (asks y/n); their output shows in an overlay |
360
398
 
361
399
  Keys: `↑` `↓` move (wraps, skips headings), `←` `→` cycle a value, `Enter` / `Space` change or run
@@ -371,6 +409,7 @@ tool does not know are kept):
371
409
  |---|---|---|---|
372
410
  | `update_check` | `true` / `false` | `true` | `AGENT_TOGGLE_UPDATE_CHECK` |
373
411
  | `color` | `auto` / `always` / `never` | `auto` | `AGENT_TOGGLE_COLOR` |
412
+ | `logo` | `color` / `mono` / `animated` / `off` | `animated` | `AGENT_TOGGLE_LOGO` |
374
413
  | `language` | `en` / `zh-TW` | `en` | `AGENT_TOGGLE_LANG` |
375
414
  | `default_harness` | a harness name | `claude` | `AGENT_TOGGLE_DEFAULT_HARNESS` |
376
415
  | `harness.<name>` | `true` / `false`, for `claude` `codex` `grok` `opencode` `openclaw` `copilot` `vibe` `devin` `agy` | `true` | |
@@ -427,6 +466,13 @@ options and examples; `help help` is the overview, `help version` shows how to p
427
466
  and an unknown command exits `2`. It honours `--color` and `NO_COLOR`, and is
428
467
  translated when `language` is `zh-TW`.
429
468
 
469
+ The overview opens with the agent-toggle logo (cyan to blue to magenta): the large one from 97
470
+ columns, a compact one from 49, none below that. Piped output gets the plain glyphs, a stream
471
+ that cannot encode them gets none. The `logo` setting picks `color`, `mono` (one colour),
472
+ `animated` (one light sweep, only on a colour terminal) or `off`. The config menu shows the same
473
+ logo, centred, when the window is tall enough to fit the whole menu beside it; there,
474
+ `animated` sweeps on entry and again after every 5 s without a key, and any key stops it.
475
+
430
476
  ## What each harness supports
431
477
 
432
478
  | harness | home | skill | agent | command | rule | plugin | mcp |
@@ -523,7 +569,8 @@ visible rather than silent.
523
569
  hand-rolled serializer would mangle comments — a text slice is lossless and
524
570
  much less code.
525
571
 
526
- MCP changes need a **new session** to take effect.
572
+ MCP changes need a **new session** to take effect, except in a Claude Code session running the
573
+ agent-toggle mod, which runs `/mcp disable|enable <name>` for you (see the mod section).
527
574
 
528
575
  ### Claude MCP scopes
529
576
 
@@ -554,6 +601,8 @@ agent-toggle profile diff work # what apply would do; writ
554
601
  agent-toggle profile apply ~/dotfiles/agent-toggle/work.json --dry-run
555
602
  agent-toggle profile apply work
556
603
  agent-toggle profile list
604
+ agent-toggle profile rename work flutter # -> ~/.agent-toggle/profiles/flutter.json
605
+ agent-toggle profile delete flutter
557
606
  ```
558
607
 
559
608
  **`apply` toggles only the items the profile mentions.** An item the profile
@@ -582,6 +631,14 @@ one batch, logged, undoable with `undo`).
582
631
  so a project profile can never disable the user's items.
583
632
  - `save` skips (with a warning) any item whose name `apply` would refuse, such as
584
633
  an MCP server called `team/search`, so a saved profile always applies.
634
+ - `save` to an existing name overwrites it with the live state now; that is how a
635
+ profile is updated.
636
+ - `delete <name>` and `rename <old> <new>` work on stored profiles only (a file
637
+ you saved with `--out` is yours to move or remove) and change no item. Both exit
638
+ `2` for a name with no stored profile or a path; `rename` also exits `2` when
639
+ `<new>` already exists (it never overwrites) or is not a valid profile name, and
640
+ keeps the file byte for byte. Neither takes `--dry-run` or `--project`: a
641
+ project profile is renamed or deleted by its name like any other.
585
642
 
586
643
  ## Undo and `enable --all`
587
644
 
@@ -761,6 +818,7 @@ bookkeeping.
761
818
  | `state.json` | current disabled list (schema v3; atomic write, mode `0600`), saved before each flag write or dir move with the op in flight under an optional `pending` key, and after each MCP / plugin item |
762
819
  | `lock` | held by `disable` / `enable` / `enable --all` / `undo` / `profile apply` / `migrate` / `ui` for the whole batch; a second run waits 5 s then exits `3` (stale after 10 min *and* its PID is gone; a live batch refreshes it per item; the error says when its PID is gone, i.e. a killed run left it) |
763
820
  | `log.jsonl` | one line per operation (mode `0600`), see below |
821
+ | `reload.json` | the Claude rows the last `ui` Enter changed, rewritten each time; open Claude Code sessions running the mod poll it and reload them |
764
822
  | `mcp-backups/` | `<harness>__<server>.json`, or `<sha8>__<harness>__<server>.json` for a project `.mcp.json` (mode `0600` -- may hold auth headers) |
765
823
  | `companions/` | parked exclusive helper files |
766
824
  | `parked/user/<owner>/<dir>/` | user-scope items, e.g. `parked/user/claude/skills/<name>` (`<owner>` = the harness whose home holds the dir; a dir shared by several harnesses parks once, under its owner); an absolute OpenCode `skills.paths` dir parks under `parked/user/opencode/ext-<sha8>/` (`<sha8>` of its resolved path). Nothing is ever parked inside a harness home |
@@ -838,6 +896,69 @@ deletion lines in `git status`.
838
896
  unresolved paths makes every companion look like it lives outside the harness.
839
897
  Both sides are resolved first.
840
898
 
899
+ ## Claude Code pane mod
900
+
901
+ A Claude Code mod in `mod/` that shows the picker as a pane inside Claude (not to be confused
902
+ with the [Mods](#mods) group the picker lists). It is driven by the installed `agent-toggle`
903
+ CLI (`cost --json`, `disable|enable --json`) and works for the claude harness only; the curses
904
+ `agent-toggle ui` stays the cross-harness UI.
905
+
906
+ Install it with `/plugin install agent-toggle --marketplace weskao/agent-toggle` (see
907
+ [Install](#install)); `claude plugin update agent-toggle@agent-toggle` picks up a new release. To
908
+ run your own checkout instead (edits reload as you save):
909
+
910
+ ```sh
911
+ claude --plugin-dir ./mod # then run /agent-toggle inside Claude
912
+ ```
913
+
914
+ - `/agent-toggle` or `/agent-toggle open` opens the pane, `/agent-toggle close` closes it,
915
+ `/agent-toggle toggle` does whichever applies; any other argument that is not a CLI command (below) prints the usage. Ctrl-X X
916
+ also closes it. Claude can do the same when you ask it to open or close agent-toggle: the mod
917
+ registers a `pane` tool (`mcp__agent-toggle__pane`, `action`: `open` | `close` | `toggle`),
918
+ e.g. "open agent-toggle", "close the agent-toggle pane", "toggle the agent-toggle pane".
919
+ Turning resources on or off is unchanged: toggle a row in the pane, or ask Claude in plain
920
+ words ("disable the demo-skill skill", "add it back"), which runs the CLI through the skill shim.
921
+ - It looks like the `ui` picker: a title with the live-token total, a search line, rows under
922
+ type headings with counts, green `●` live / yellow `○` parked, tokens and a bar per row (a
923
+ parked row shows `(N)`, what restoring it would load), the cursor row in reverse video, and a
924
+ key-chip footer. The list scrolls with the cursor; the status line shows its position (`7/23`),
925
+ and the first and last list lines count the rows out of view (`↑ 4`, `↓ 12`).
926
+ - The mouse wheel over the list moves the cursor, as in the terminal picker; no click needed.
927
+ - Click the list once so it takes keys (Esc hands the keyboard back to the prompt). Then `↑` `↓`
928
+ `PgUp` `PgDn` `Home` `End` (also `Ctrl-P` / `Ctrl-N`) move; `Space` or `Enter` toggles the row,
929
+ `Tab` toggles and moves on; `/` or any other letter starts a search (terms ANDed over
930
+ `type/name` and the group, letters-in-order if nothing matches; a second `Space` toggles);
931
+ `s` sorts by name or cost; `n` toggles every type with this row's name (skill, command, MCP,
932
+ ...), like `disable all <name>`; `Ctrl-U` clears the search. A click moves the cursor.
933
+ - A toggle applies at once (no staging, no Enter to apply); the toast names the target and the state
934
+ with an emoji and a bracketed tag (no colour codes, so nothing garbles; on the Linux console and the
935
+ legacy Windows console, where emoji draw as boxes, the tag alone): `✅ [ENABLED] skill: foo`, `⛔ [DISABLED] mod: bar (/reload-plugins)`,
936
+ `⛔ [DISABLED] rule: baz (takes effect in a new session)`, `⛔ [DISABLED] all: foo` after `n`, or `❌ [FAILED] disable skill: foo - <error>`.
937
+ The row flips the moment you press (and flips back
938
+ if the CLI fails); the list reloads in the background. While a toggle runs, further keys are ignored.
939
+ - Opening the pane shows the same braille spinner and `Loading resources…` as `agent-toggle ui`
940
+ until the list arrives, and a spinner beside `working…` while a toggle runs.
941
+ - Not in the pane: harness tabs (claude only), and the `t` `p` `a` keys. Where Claude draws no
942
+ such pane (the mobile app, VS Code) it is a plain list of buttons instead.
943
+ - `/agent-toggle <command> ...` with `disable`, `enable`,
944
+ `undo`, `list`, `status`, `cost` or `doctor` runs the CLI instead of opening the pane and prints
945
+ one line per result row: `/agent-toggle disable skill foo bar` (it adds `--json`, and
946
+ `--harness claude` unless you pass `--harness`). A toggle reloads an open pane.
947
+ - Inside Claude Code the mod then applies the change to the running session by queueing the slash
948
+ command for you, once per kind: skills and commands `/reload-skills`, plugins (mods included)
949
+ `/reload-plugins`, an MCP server `/mcp disable|enable <name>`. The toast names it, e.g.
950
+ `⛔ [DISABLED] skill: foo (/reload-skills)`. Agents and rules have no reload and still say
951
+ `takes effect in a new session`. If Claude refuses a queued command, a toast says so.
952
+ - `agent-toggle ui` in another terminal applies on Enter and writes the Claude rows it changed to
953
+ `~/.agent-toggle/reload.json`. Every open session running the mod checks that file's mtime every
954
+ 5 s (one `stat`) and queues the same reloads, toasting `agent-toggle ui: /reload-skills`. A file
955
+ older than the session is ignored.
956
+ - Needs `agent-toggle` on `PATH`.
957
+ - On Windows `agent-toggle` must resolve to a real executable on `PATH` (a pip or uv install
958
+ provides `agent-toggle.exe`).
959
+
960
+ The design is in `docs/MOD.md`.
961
+
841
962
  ## Design and roadmap
842
963
 
843
964
  Architecture, harness survey, cost model, known gaps and the phased roadmap
@@ -855,6 +976,13 @@ ruff check .
855
976
  stdlib `unittest`, no fixtures, no network. Every test runs against a
856
977
  throwaway temp `HOME` and a stubbed `claude` CLI.
857
978
 
979
+ The pane mod has its own checks (they need the `claude` CLI, so CI does not run them):
980
+
981
+ ```sh
982
+ claude plugin validate mod
983
+ claude plugin test mod
984
+ ```
985
+
858
986
  `python3 tools/wheel_smoke.py` builds the wheel, installs it without extras into a
859
987
  fresh venv (what a PyPI user gets) and runs the CLI against a temp `HOME`; CI runs
860
988
  it on macOS, Linux and Windows.
@@ -897,6 +1025,8 @@ prints a `::notice::` and exits 0, so it never adds a second red X.
897
1025
  ## Releasing
898
1026
 
899
1027
  A release is a git tag `vX.Y.Z` (where `X.Y.Z` must match `agent_toggle.__version__`).
1028
+ Bump `version` in `mod/.claude-plugin/plugin.json` to the same value by hand; nothing checks it,
1029
+ and without it `claude plugin update` does not hand marketplace installs the new mod.
900
1030
  Pushing the tag triggers `.github/workflows/release.yml`:
901
1031
 
902
1032
  1. **Build** job checks that the tag matches `__version__`, builds a wheel and
@@ -1,3 +1,3 @@
1
1
  """agent-toggle: temporarily disable / re-enable AI-agent resources."""
2
2
 
3
- __version__ = "0.8.1"
3
+ __version__ = "0.10.0"