agent-toggle 0.9.0__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.
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/PKG-INFO +21 -6
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/README.md +20 -5
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/agent_toggle/__init__.py +1 -1
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/agent_toggle/cli.py +1 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/agent_toggle/fs.py +4 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/agent_toggle/shims/claude.md.tmpl +1 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/agent_toggle/store.py +9 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/agent_toggle.egg-info/PKG-INFO +21 -6
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/tests/test_cli.py +5 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/LICENSE +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/agent_toggle/__main__.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/agent_toggle/backends/__init__.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/agent_toggle/backends/flag_json.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/agent_toggle/backends/mcp_json.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/agent_toggle/backends/mcp_toml.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/agent_toggle/backends/plugin_cli.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/agent_toggle/companions.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/agent_toggle/config.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/agent_toggle/cost.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/agent_toggle/doctor.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/agent_toggle/harnesses.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/agent_toggle/help.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/agent_toggle/i18n.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/agent_toggle/locales/__init__.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/agent_toggle/locales/zh_tw_cli.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/agent_toggle/locales/zh_tw_common.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/agent_toggle/locales/zh_tw_config.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/agent_toggle/locales/zh_tw_picker.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/agent_toggle/mechanisms.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/agent_toggle/ops.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/agent_toggle/output.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/agent_toggle/profiles.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/agent_toggle/settings.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/agent_toggle/shims/generic.md.tmpl +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/agent_toggle/spinner.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/agent_toggle/toml_check.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/agent_toggle/ui/__init__.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/agent_toggle/ui/config_menu.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/agent_toggle/ui/logo.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/agent_toggle/ui/menu.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/agent_toggle/ui/model.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/agent_toggle/ui/picker.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/agent_toggle/ui/theme.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/agent_toggle/undo.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/agent_toggle/update_check.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/agent_toggle/update_prompt.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/agent_toggle.egg-info/SOURCES.txt +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/agent_toggle.egg-info/dependency_links.txt +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/agent_toggle.egg-info/entry_points.txt +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/agent_toggle.egg-info/requires.txt +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/agent_toggle.egg-info/top_level.txt +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/pyproject.toml +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/setup.cfg +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/tests/test_alias.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/tests/test_all_type.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/tests/test_backends.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/tests/test_cli_surface.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/tests/test_color.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/tests/test_companions.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/tests/test_completions.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/tests/test_config.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/tests/test_config_menu.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/tests/test_conformance.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/tests/test_containment.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/tests/test_cost.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/tests/test_crash.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/tests/test_doctor.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/tests/test_encoding.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/tests/test_fs.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/tests/test_harnesses.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/tests/test_help.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/tests/test_i18n.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/tests/test_install.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/tests/test_logo.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/tests/test_mechanisms.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/tests/test_menu.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/tests/test_mods.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/tests/test_picker.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/tests/test_platform.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/tests/test_profiles.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/tests/test_project.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/tests/test_safety.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/tests/test_same_name.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/tests/test_secret_audit.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/tests/test_settings.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/tests/test_store.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/tests/test_theme.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/tests/test_undo.py +0 -0
- {agent_toggle-0.9.0 → agent_toggle-0.10.0}/tests/test_update_check.py +0 -0
- {agent_toggle-0.9.0 → 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.
|
|
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
|
|
@@ -367,7 +369,8 @@ off under `--dry-run`. Esc closes the prompt.
|
|
|
367
369
|
Nothing happens while the picker is open. Changes are staged, the screen is
|
|
368
370
|
torn down, and only then do the real operations run, so their output (which
|
|
369
371
|
companion files moved, which were kept because they are shared) is readable
|
|
370
|
-
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.
|
|
371
374
|
|
|
372
375
|
Built on stdlib `curses`, so there is nothing to install on macOS and Linux
|
|
373
376
|
(on Windows, `pip install "agent-toggle[windows]"` pulls `windows-curses`).
|
|
@@ -598,7 +601,8 @@ visible rather than silent.
|
|
|
598
601
|
hand-rolled serializer would mangle comments — a text slice is lossless and
|
|
599
602
|
much less code.
|
|
600
603
|
|
|
601
|
-
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).
|
|
602
606
|
|
|
603
607
|
### Claude MCP scopes
|
|
604
608
|
|
|
@@ -846,6 +850,7 @@ bookkeeping.
|
|
|
846
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 |
|
|
847
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) |
|
|
848
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 |
|
|
849
854
|
| `mcp-backups/` | `<harness>__<server>.json`, or `<sha8>__<harness>__<server>.json` for a project `.mcp.json` (mode `0600` -- may hold auth headers) |
|
|
850
855
|
| `companions/` | parked exclusive helper files |
|
|
851
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 |
|
|
@@ -948,7 +953,8 @@ claude --plugin-dir ./mod # then run /agent-toggle inside Claude
|
|
|
948
953
|
- It looks like the `ui` picker: a title with the live-token total, a search line, rows under
|
|
949
954
|
type headings with counts, green `●` live / yellow `○` parked, tokens and a bar per row (a
|
|
950
955
|
parked row shows `(N)`, what restoring it would load), the cursor row in reverse video, and a
|
|
951
|
-
key-chip footer. The list scrolls with the cursor
|
|
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`).
|
|
952
958
|
- The mouse wheel over the list moves the cursor, as in the terminal picker; no click needed.
|
|
953
959
|
- Click the list once so it takes keys (Esc hands the keyboard back to the prompt). Then `↑` `↓`
|
|
954
960
|
`PgUp` `PgDn` `Home` `End` (also `Ctrl-P` / `Ctrl-N`) move; `Space` or `Enter` toggles the row,
|
|
@@ -958,8 +964,8 @@ claude --plugin-dir ./mod # then run /agent-toggle inside Claude
|
|
|
958
964
|
...), like `disable all <name>`; `Ctrl-U` clears the search. A click moves the cursor.
|
|
959
965
|
- A toggle applies at once (no staging, no Enter to apply); the toast names the target and the state
|
|
960
966
|
with an emoji and a bracketed tag (no colour codes, so nothing garbles; on the Linux console and the
|
|
961
|
-
legacy Windows console, where emoji draw as boxes, the tag alone): `✅ [ENABLED] skill: foo`, `⛔ [DISABLED] mod: bar (
|
|
962
|
-
session)`, `⛔ [DISABLED] all: foo` after `n`, or `❌ [FAILED] disable skill: foo - <error>`.
|
|
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>`.
|
|
963
969
|
The row flips the moment you press (and flips back
|
|
964
970
|
if the CLI fails); the list reloads in the background. While a toggle runs, further keys are ignored.
|
|
965
971
|
- Opening the pane shows the same braille spinner and `Loading resources…` as `agent-toggle ui`
|
|
@@ -970,6 +976,15 @@ claude --plugin-dir ./mod # then run /agent-toggle inside Claude
|
|
|
970
976
|
`undo`, `list`, `status`, `cost` or `doctor` runs the CLI instead of opening the pane and prints
|
|
971
977
|
one line per result row: `/agent-toggle disable skill foo bar` (it adds `--json`, and
|
|
972
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.
|
|
973
988
|
- Needs `agent-toggle` on `PATH`.
|
|
974
989
|
- On Windows `agent-toggle` must resolve to a real executable on `PATH` (a pip or uv install
|
|
975
990
|
provides `agent-toggle.exe`).
|
|
@@ -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
|
|
@@ -335,7 +337,8 @@ off under `--dry-run`. Esc closes the prompt.
|
|
|
335
337
|
Nothing happens while the picker is open. Changes are staged, the screen is
|
|
336
338
|
torn down, and only then do the real operations run, so their output (which
|
|
337
339
|
companion files moved, which were kept because they are shared) is readable
|
|
338
|
-
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.
|
|
339
342
|
|
|
340
343
|
Built on stdlib `curses`, so there is nothing to install on macOS and Linux
|
|
341
344
|
(on Windows, `pip install "agent-toggle[windows]"` pulls `windows-curses`).
|
|
@@ -566,7 +569,8 @@ visible rather than silent.
|
|
|
566
569
|
hand-rolled serializer would mangle comments — a text slice is lossless and
|
|
567
570
|
much less code.
|
|
568
571
|
|
|
569
|
-
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).
|
|
570
574
|
|
|
571
575
|
### Claude MCP scopes
|
|
572
576
|
|
|
@@ -814,6 +818,7 @@ bookkeeping.
|
|
|
814
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 |
|
|
815
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) |
|
|
816
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 |
|
|
817
822
|
| `mcp-backups/` | `<harness>__<server>.json`, or `<sha8>__<harness>__<server>.json` for a project `.mcp.json` (mode `0600` -- may hold auth headers) |
|
|
818
823
|
| `companions/` | parked exclusive helper files |
|
|
819
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 |
|
|
@@ -916,7 +921,8 @@ claude --plugin-dir ./mod # then run /agent-toggle inside Claude
|
|
|
916
921
|
- It looks like the `ui` picker: a title with the live-token total, a search line, rows under
|
|
917
922
|
type headings with counts, green `●` live / yellow `○` parked, tokens and a bar per row (a
|
|
918
923
|
parked row shows `(N)`, what restoring it would load), the cursor row in reverse video, and a
|
|
919
|
-
key-chip footer. The list scrolls with the cursor
|
|
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`).
|
|
920
926
|
- The mouse wheel over the list moves the cursor, as in the terminal picker; no click needed.
|
|
921
927
|
- Click the list once so it takes keys (Esc hands the keyboard back to the prompt). Then `↑` `↓`
|
|
922
928
|
`PgUp` `PgDn` `Home` `End` (also `Ctrl-P` / `Ctrl-N`) move; `Space` or `Enter` toggles the row,
|
|
@@ -926,8 +932,8 @@ claude --plugin-dir ./mod # then run /agent-toggle inside Claude
|
|
|
926
932
|
...), like `disable all <name>`; `Ctrl-U` clears the search. A click moves the cursor.
|
|
927
933
|
- A toggle applies at once (no staging, no Enter to apply); the toast names the target and the state
|
|
928
934
|
with an emoji and a bracketed tag (no colour codes, so nothing garbles; on the Linux console and the
|
|
929
|
-
legacy Windows console, where emoji draw as boxes, the tag alone): `✅ [ENABLED] skill: foo`, `⛔ [DISABLED] mod: bar (
|
|
930
|
-
session)`, `⛔ [DISABLED] all: foo` after `n`, or `❌ [FAILED] disable skill: foo - <error>`.
|
|
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>`.
|
|
931
937
|
The row flips the moment you press (and flips back
|
|
932
938
|
if the CLI fails); the list reloads in the background. While a toggle runs, further keys are ignored.
|
|
933
939
|
- Opening the pane shows the same braille spinner and `Loading resources…` as `agent-toggle ui`
|
|
@@ -938,6 +944,15 @@ claude --plugin-dir ./mod # then run /agent-toggle inside Claude
|
|
|
938
944
|
`undo`, `list`, `status`, `cost` or `doctor` runs the CLI instead of opening the pane and prints
|
|
939
945
|
one line per result row: `/agent-toggle disable skill foo bar` (it adds `--json`, and
|
|
940
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.
|
|
941
956
|
- Needs `agent-toggle` on `PATH`.
|
|
942
957
|
- On Windows `agent-toggle` must resolve to a real executable on `PATH` (a pip or uv install
|
|
943
958
|
provides `agent-toggle.exe`).
|
|
@@ -325,6 +325,7 @@ def cmd_ui(state: dict, out: Result, dry_run: bool = False, project: str | None
|
|
|
325
325
|
if dry_run:
|
|
326
326
|
out.say("\ndry run -- nothing changed")
|
|
327
327
|
return
|
|
328
|
+
store.signal_reload(out.rows)
|
|
328
329
|
if any(r.type in ("mcp", "plugin") for r in changes):
|
|
329
330
|
out.say("\nMCP/plugin changed -- open a NEW session for it to take effect.")
|
|
330
331
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: agent-toggle
|
|
3
3
|
description: Temporarily disable or restore AI-agent resources — skills, agents, commands, rules, plugins, MCP servers — across Claude Code, Codex, Grok CLI, OpenCode, OpenClaw, Copilot and Vibe. Nothing is deleted; everything is parked and reversible. Use when the user wants to turn something off, trim startup context cost, re-enable something previously disabled, or asks "how do I disable X" / "turn off this MCP" / "add it back". Also when they ask to open, close or toggle the agent-toggle pane ("open agent-toggle" / "close the agent-toggle pane"), and to save, switch, rename or delete a profile ("save my setup as work" / "switch to my work profile").
|
|
4
|
+
argument-hint: "[status | list | cost | disable|enable <type> <name>... | undo | profile | doctor | open | close]"
|
|
4
5
|
---
|
|
5
6
|
<!-- agent-toggle shim: written by `agent-toggle install-shims`; re-running it overwrites this file -->
|
|
6
7
|
|
|
@@ -259,6 +259,15 @@ def log(action: str, type_: str, name: str, result: str, detail: str = "", *,
|
|
|
259
259
|
fh.write(json.dumps(rec, ensure_ascii=False) + "\n")
|
|
260
260
|
|
|
261
261
|
|
|
262
|
+
def signal_reload(rows: list[dict]) -> None:
|
|
263
|
+
"""`ui` runs in a terminal of its own, so it cannot reload a Claude Code session: it leaves the claude rows it
|
|
264
|
+
changed here, and every session running the agent-toggle mod polls the file and reloads them (mod/hooks/register.tsx)."""
|
|
265
|
+
done = [r for r in rows if r["harness"] == "claude" and r["status"] == "ok" and r["action"] in ("disable", "enable")]
|
|
266
|
+
if done:
|
|
267
|
+
fs.private_dir(fs.state_dir())
|
|
268
|
+
fs.atomic_write(fs.reload_file(), json.dumps({"batch": BATCH, "results": done}, ensure_ascii=False))
|
|
269
|
+
|
|
270
|
+
|
|
262
271
|
def migrate(state: dict) -> int:
|
|
263
272
|
"""Import ~/.claude-toggle state so existing rollbacks keep working."""
|
|
264
273
|
legacy_state_dir, backup_dir = fs.legacy_state_dir(), fs.backup_dir()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agent-toggle
|
|
3
|
-
Version: 0.
|
|
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
|
|
@@ -367,7 +369,8 @@ off under `--dry-run`. Esc closes the prompt.
|
|
|
367
369
|
Nothing happens while the picker is open. Changes are staged, the screen is
|
|
368
370
|
torn down, and only then do the real operations run, so their output (which
|
|
369
371
|
companion files moved, which were kept because they are shared) is readable
|
|
370
|
-
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.
|
|
371
374
|
|
|
372
375
|
Built on stdlib `curses`, so there is nothing to install on macOS and Linux
|
|
373
376
|
(on Windows, `pip install "agent-toggle[windows]"` pulls `windows-curses`).
|
|
@@ -598,7 +601,8 @@ visible rather than silent.
|
|
|
598
601
|
hand-rolled serializer would mangle comments — a text slice is lossless and
|
|
599
602
|
much less code.
|
|
600
603
|
|
|
601
|
-
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).
|
|
602
606
|
|
|
603
607
|
### Claude MCP scopes
|
|
604
608
|
|
|
@@ -846,6 +850,7 @@ bookkeeping.
|
|
|
846
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 |
|
|
847
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) |
|
|
848
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 |
|
|
849
854
|
| `mcp-backups/` | `<harness>__<server>.json`, or `<sha8>__<harness>__<server>.json` for a project `.mcp.json` (mode `0600` -- may hold auth headers) |
|
|
850
855
|
| `companions/` | parked exclusive helper files |
|
|
851
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 |
|
|
@@ -948,7 +953,8 @@ claude --plugin-dir ./mod # then run /agent-toggle inside Claude
|
|
|
948
953
|
- It looks like the `ui` picker: a title with the live-token total, a search line, rows under
|
|
949
954
|
type headings with counts, green `●` live / yellow `○` parked, tokens and a bar per row (a
|
|
950
955
|
parked row shows `(N)`, what restoring it would load), the cursor row in reverse video, and a
|
|
951
|
-
key-chip footer. The list scrolls with the cursor
|
|
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`).
|
|
952
958
|
- The mouse wheel over the list moves the cursor, as in the terminal picker; no click needed.
|
|
953
959
|
- Click the list once so it takes keys (Esc hands the keyboard back to the prompt). Then `↑` `↓`
|
|
954
960
|
`PgUp` `PgDn` `Home` `End` (also `Ctrl-P` / `Ctrl-N`) move; `Space` or `Enter` toggles the row,
|
|
@@ -958,8 +964,8 @@ claude --plugin-dir ./mod # then run /agent-toggle inside Claude
|
|
|
958
964
|
...), like `disable all <name>`; `Ctrl-U` clears the search. A click moves the cursor.
|
|
959
965
|
- A toggle applies at once (no staging, no Enter to apply); the toast names the target and the state
|
|
960
966
|
with an emoji and a bracketed tag (no colour codes, so nothing garbles; on the Linux console and the
|
|
961
|
-
legacy Windows console, where emoji draw as boxes, the tag alone): `✅ [ENABLED] skill: foo`, `⛔ [DISABLED] mod: bar (
|
|
962
|
-
session)`, `⛔ [DISABLED] all: foo` after `n`, or `❌ [FAILED] disable skill: foo - <error>`.
|
|
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>`.
|
|
963
969
|
The row flips the moment you press (and flips back
|
|
964
970
|
if the CLI fails); the list reloads in the background. While a toggle runs, further keys are ignored.
|
|
965
971
|
- Opening the pane shows the same braille spinner and `Loading resources…` as `agent-toggle ui`
|
|
@@ -970,6 +976,15 @@ claude --plugin-dir ./mod # then run /agent-toggle inside Claude
|
|
|
970
976
|
`undo`, `list`, `status`, `cost` or `doctor` runs the CLI instead of opening the pane and prints
|
|
971
977
|
one line per result row: `/agent-toggle disable skill foo bar` (it adds `--json`, and
|
|
972
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.
|
|
973
988
|
- Needs `agent-toggle` on `PATH`.
|
|
974
989
|
- On Windows `agent-toggle` must resolve to a real executable on `PATH` (a pip or uv install
|
|
975
990
|
provides `agent-toggle.exe`).
|
|
@@ -78,6 +78,7 @@ class ApplyPlanSeamTest(SandboxCase):
|
|
|
78
78
|
self.assertEqual(plan, [ops.Op("claude", "skill", "disable", "demo-skill")])
|
|
79
79
|
self.assertEqual(spy.call_args.kwargs["batch"], store.BATCH)
|
|
80
80
|
self.assertFalse((self.home / "skills/demo-skill").exists())
|
|
81
|
+
self.assertFalse(fs.reload_file().exists()) # only `ui` signals: the mod reloads its own runs itself
|
|
81
82
|
|
|
82
83
|
def test_cmd_ui_goes_through_apply_plan(self) -> None:
|
|
83
84
|
try:
|
|
@@ -94,6 +95,10 @@ class ApplyPlanSeamTest(SandboxCase):
|
|
|
94
95
|
[ops.Op("claude", "skill", "disable", "demo-skill")])
|
|
95
96
|
self.assertFalse((self.home / "skills/demo-skill").exists())
|
|
96
97
|
self.assertIn("claude:skill:demo-skill", store.load_state()["disabled"])
|
|
98
|
+
# Enter applied it: open Claude Code sessions (the mod polls this file) reload the skill
|
|
99
|
+
sig = json.loads(fs.reload_file().read_text(encoding="utf-8"))
|
|
100
|
+
self.assertEqual([(r["type"], r["name"], r["action"], r["status"]) for r in sig["results"]],
|
|
101
|
+
[("skill", "demo-skill", "disable", "ok")])
|
|
97
102
|
|
|
98
103
|
def test_type_without_a_mechanism_is_an_unsupported_row(self) -> None:
|
|
99
104
|
out = Result()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|