agent-toggle 0.14.0__tar.gz → 0.15.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.14.0 → agent_toggle-0.15.0}/PKG-INFO +31 -27
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/README.md +29 -26
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/agent_toggle/__init__.py +1 -1
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/agent_toggle/cli.py +12 -11
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/agent_toggle/help.py +7 -6
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/agent_toggle/locales/zh_tw_cli.py +3 -15
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/agent_toggle/shims/claude.md.tmpl +1 -1
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/agent_toggle/shims/generic.md.tmpl +1 -1
- agent_toggle-0.15.0/agent_toggle/update_prompt.py +80 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/agent_toggle.egg-info/PKG-INFO +31 -27
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/agent_toggle.egg-info/SOURCES.txt +0 -2
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/agent_toggle.egg-info/requires.txt +1 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/pyproject.toml +1 -1
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/tests/test_cli.py +54 -95
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/tests/test_cli_surface.py +7 -1
- agent_toggle-0.15.0/tests/test_update_prompt.py +104 -0
- agent_toggle-0.14.0/agent_toggle/update_check.py +0 -361
- agent_toggle-0.14.0/agent_toggle/update_prompt.py +0 -242
- agent_toggle-0.14.0/tests/test_update_check.py +0 -423
- agent_toggle-0.14.0/tests/test_update_prompt.py +0 -90
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/LICENSE +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/agent_toggle/__main__.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/agent_toggle/backends/__init__.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/agent_toggle/backends/flag_json.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/agent_toggle/backends/mcp_json.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/agent_toggle/backends/mcp_toml.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/agent_toggle/backends/plugin_cli.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/agent_toggle/companions.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/agent_toggle/completions.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/agent_toggle/config.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/agent_toggle/cost.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/agent_toggle/doctor.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/agent_toggle/fs.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/agent_toggle/harnesses.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/agent_toggle/i18n.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/agent_toggle/locales/__init__.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/agent_toggle/locales/zh_tw_common.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/agent_toggle/locales/zh_tw_config.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/agent_toggle/locales/zh_tw_picker.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/agent_toggle/mechanisms.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/agent_toggle/ops.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/agent_toggle/output.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/agent_toggle/profiles.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/agent_toggle/settings.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/agent_toggle/spinner.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/agent_toggle/store.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/agent_toggle/toml_check.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/agent_toggle/ui/__init__.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/agent_toggle/ui/config_menu.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/agent_toggle/ui/logo.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/agent_toggle/ui/menu.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/agent_toggle/ui/model.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/agent_toggle/ui/picker.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/agent_toggle/ui/theme.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/agent_toggle/undo.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/agent_toggle.egg-info/dependency_links.txt +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/agent_toggle.egg-info/entry_points.txt +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/agent_toggle.egg-info/top_level.txt +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/setup.cfg +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/tests/test_alias.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/tests/test_all_type.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/tests/test_backends.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/tests/test_color.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/tests/test_companions.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/tests/test_completions.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/tests/test_config.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/tests/test_config_menu.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/tests/test_conformance.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/tests/test_containment.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/tests/test_cost.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/tests/test_crash.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/tests/test_doctor.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/tests/test_encoding.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/tests/test_fs.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/tests/test_harnesses.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/tests/test_help.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/tests/test_i18n.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/tests/test_install.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/tests/test_logo.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/tests/test_mechanisms.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/tests/test_menu.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/tests/test_mods.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/tests/test_picker.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/tests/test_platform.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/tests/test_profiles.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/tests/test_project.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/tests/test_safety.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/tests/test_same_name.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/tests/test_secret_audit.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/tests/test_settings.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/tests/test_store.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/tests/test_theme.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.15.0}/tests/test_undo.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agent-toggle
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.15.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
|
|
@@ -25,6 +25,7 @@ Requires-Python: >=3.10
|
|
|
25
25
|
Description-Content-Type: text/markdown
|
|
26
26
|
License-File: LICENSE
|
|
27
27
|
Requires-Dist: telegram-kit<0.3,>=0.2.2
|
|
28
|
+
Requires-Dist: update-kit<0.2,>=0.1
|
|
28
29
|
Provides-Extra: windows
|
|
29
30
|
Requires-Dist: windows-curses; sys_platform == "win32" and extra == "windows"
|
|
30
31
|
Provides-Extra: telegram
|
|
@@ -202,7 +203,7 @@ agent-toggle <command> [args] # or: python3 agent_toggle.py <command> [
|
|
|
202
203
|
| `status` | health check: harnesses found, types each supports, parked counts, gitignore, untracked parked items, stale live twins, shared dirs, and state entries whose parked item is gone (a `stale` row with the fix command; read-only, still exit `0`) |
|
|
203
204
|
| `list [type]` | what is currently disabled (`--project <dir>` filters to one project) |
|
|
204
205
|
| `cost [--type T]` | estimated startup tokens per item, biggest first (read-only; `--harness H` filters; `--project <dir>` prices a repo's `.claude/` and `.mcp.json` instead of user scope) |
|
|
205
|
-
| `update` |
|
|
206
|
+
| `update` (also `--update`) | install the newest release tag (`uv tool install --force --no-sources git+<repo>@<tag>`, or `pipx install --force` for a pipx install), then, with the new version, update the Claude Code plugin (when installed) and the shims. Never asks. Exit `0` updated or already current, `1` the check or install failed (offline, rate limit), `2` a dev install (use `git pull`) or an install it cannot manage (the manual command is printed). Messages go to stderr; `--json` has no JSON for it. The `/agent-toggle` pane command has no `update`: run it in a terminal |
|
|
206
207
|
| `install-shims` | write the skill shim into every installed harness that is on in the settings (an off one is skipped unless named with `--harness`); refuses to overwrite a file it did not write (`--dry-run` shows the plan); reports stale legacy `<dir>-disabled/` lines in a harness-home `.gitignore` (`--gitignore` removes them, `--no-gitignore` skips the check); on a terminal, then asks y/n for each problem `doctor` can fix (see [Fixing](#fixing)) |
|
|
207
208
|
| `disable <type> <name>...` | park one or more items (`--dry-run` shows the plan; `--project <dir>` for a repo's own `.claude/` and `.mcp.json`) |
|
|
208
209
|
| `enable <type> <name>...` | put them back (`--dry-run` shows the plan; `--project <dir>` likewise) |
|
|
@@ -487,33 +488,37 @@ invalid value in either is ignored with one warning on stderr.
|
|
|
487
488
|
- `default_harness` is what `disable` / `enable` act on without `--harness`, even when that
|
|
488
489
|
harness is switched off (with one warning on stderr);
|
|
489
490
|
`disable` / `enable --project` without `--harness` still default to `claude`.
|
|
490
|
-
- `language` translates the config menu, help, update
|
|
491
|
+
- `language` translates the config menu, help, update messages and picker chrome; command output stays English.
|
|
491
492
|
- telegram-kit is a regular dependency now, so reinstalling keeps the Telegram settings working;
|
|
492
493
|
`agent-toggle[telegram]` still resolves.
|
|
493
494
|
|
|
494
|
-
## Update
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
495
|
+
## Update
|
|
496
|
+
|
|
497
|
+
`agent-toggle update` (or `agent-toggle --update`) is a self-update through
|
|
498
|
+
update-kit (a small stdlib-only helper library): it asks the repository for its newest `vX.Y.Z`
|
|
499
|
+
tag (`git ls-remote --tags`), and when that is newer than the running version it installs it with
|
|
500
|
+
`uv tool install --force --no-sources git+<repo>@<tag>` (`pipx install --force` for a pipx install).
|
|
501
|
+
It then runs, with the new binary and in order: when the Claude Code plugin is installed,
|
|
502
|
+
`claude plugin marketplace update agent-toggle` and `claude plugin update agent-toggle@agent-toggle`,
|
|
503
|
+
then `agent-toggle install-shims`. A failing step prints a warning and makes the exit code `1`.
|
|
504
|
+
It never prompts and writes to stderr only.
|
|
505
|
+
|
|
506
|
+
| Exit | Meaning |
|
|
507
|
+
|---|---|
|
|
508
|
+
| `0` | updated, or already up to date |
|
|
509
|
+
| `1` | could not check (offline, rate limit) or the install failed |
|
|
510
|
+
| `2` | a dev install (`git pull` instead), or an install kind it cannot manage (the manual command is printed) |
|
|
511
|
+
|
|
512
|
+
On Windows a running `agent-toggle.exe` cannot be replaced, so the install runs detached after
|
|
513
|
+
agent-toggle exits (log in `%USERPROFILE%\.update-kit\`).
|
|
514
|
+
|
|
515
|
+
**The hint.** After a command, on an interactive terminal only (stderr is a TTY, never under
|
|
516
|
+
`--json`, pipes, launchd or timers), agent-toggle prints one stderr line when a newer release
|
|
517
|
+
exists, `agent-toggle vX.Y.Z is available (you have A) — run `agent-toggle update``. The check is
|
|
518
|
+
`git ls-remote` with a 1.5 s timeout, cached for 24 hours (failures too) in
|
|
519
|
+
`~/.update-kit/state.json`. It never changes the exit code or stdout. To turn it off, set
|
|
520
|
+
`AGENT_TOGGLE_UPDATE_CHECK=0` or the `update_check` setting to off (the settings menu's
|
|
521
|
+
"Check for updates").
|
|
517
522
|
|
|
518
523
|
## Help
|
|
519
524
|
|
|
@@ -905,7 +910,6 @@ bookkeeping.
|
|
|
905
910
|
| `parked/<sha8>/` | items parked by `--project` (`<sha8>` = first 8 hex of the SHA-1 of the resolved project dir) |
|
|
906
911
|
| `profiles/` | `<name>.json` profiles (dir `0700`, files `0600`) |
|
|
907
912
|
| `config.json` | [settings](#settings--config-menu) and the Telegram chat id (mode `0600`, atomic write, unknown keys kept) |
|
|
908
|
-
| `update-check.json` | the [update check](#update-check)'s 10-minute cache (mode `0600`, atomic write) |
|
|
909
913
|
|
|
910
914
|
A killed run loses at most the one item in flight. If that was a flag write or a
|
|
911
915
|
dir move (with its companions), its `pending` record (the full entry, a flag's
|
|
@@ -169,7 +169,7 @@ agent-toggle <command> [args] # or: python3 agent_toggle.py <command> [
|
|
|
169
169
|
| `status` | health check: harnesses found, types each supports, parked counts, gitignore, untracked parked items, stale live twins, shared dirs, and state entries whose parked item is gone (a `stale` row with the fix command; read-only, still exit `0`) |
|
|
170
170
|
| `list [type]` | what is currently disabled (`--project <dir>` filters to one project) |
|
|
171
171
|
| `cost [--type T]` | estimated startup tokens per item, biggest first (read-only; `--harness H` filters; `--project <dir>` prices a repo's `.claude/` and `.mcp.json` instead of user scope) |
|
|
172
|
-
| `update` |
|
|
172
|
+
| `update` (also `--update`) | install the newest release tag (`uv tool install --force --no-sources git+<repo>@<tag>`, or `pipx install --force` for a pipx install), then, with the new version, update the Claude Code plugin (when installed) and the shims. Never asks. Exit `0` updated or already current, `1` the check or install failed (offline, rate limit), `2` a dev install (use `git pull`) or an install it cannot manage (the manual command is printed). Messages go to stderr; `--json` has no JSON for it. The `/agent-toggle` pane command has no `update`: run it in a terminal |
|
|
173
173
|
| `install-shims` | write the skill shim into every installed harness that is on in the settings (an off one is skipped unless named with `--harness`); refuses to overwrite a file it did not write (`--dry-run` shows the plan); reports stale legacy `<dir>-disabled/` lines in a harness-home `.gitignore` (`--gitignore` removes them, `--no-gitignore` skips the check); on a terminal, then asks y/n for each problem `doctor` can fix (see [Fixing](#fixing)) |
|
|
174
174
|
| `disable <type> <name>...` | park one or more items (`--dry-run` shows the plan; `--project <dir>` for a repo's own `.claude/` and `.mcp.json`) |
|
|
175
175
|
| `enable <type> <name>...` | put them back (`--dry-run` shows the plan; `--project <dir>` likewise) |
|
|
@@ -454,33 +454,37 @@ invalid value in either is ignored with one warning on stderr.
|
|
|
454
454
|
- `default_harness` is what `disable` / `enable` act on without `--harness`, even when that
|
|
455
455
|
harness is switched off (with one warning on stderr);
|
|
456
456
|
`disable` / `enable --project` without `--harness` still default to `claude`.
|
|
457
|
-
- `language` translates the config menu, help, update
|
|
457
|
+
- `language` translates the config menu, help, update messages and picker chrome; command output stays English.
|
|
458
458
|
- telegram-kit is a regular dependency now, so reinstalling keeps the Telegram settings working;
|
|
459
459
|
`agent-toggle[telegram]` still resolves.
|
|
460
460
|
|
|
461
|
-
## Update
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
461
|
+
## Update
|
|
462
|
+
|
|
463
|
+
`agent-toggle update` (or `agent-toggle --update`) is a self-update through
|
|
464
|
+
update-kit (a small stdlib-only helper library): it asks the repository for its newest `vX.Y.Z`
|
|
465
|
+
tag (`git ls-remote --tags`), and when that is newer than the running version it installs it with
|
|
466
|
+
`uv tool install --force --no-sources git+<repo>@<tag>` (`pipx install --force` for a pipx install).
|
|
467
|
+
It then runs, with the new binary and in order: when the Claude Code plugin is installed,
|
|
468
|
+
`claude plugin marketplace update agent-toggle` and `claude plugin update agent-toggle@agent-toggle`,
|
|
469
|
+
then `agent-toggle install-shims`. A failing step prints a warning and makes the exit code `1`.
|
|
470
|
+
It never prompts and writes to stderr only.
|
|
471
|
+
|
|
472
|
+
| Exit | Meaning |
|
|
473
|
+
|---|---|
|
|
474
|
+
| `0` | updated, or already up to date |
|
|
475
|
+
| `1` | could not check (offline, rate limit) or the install failed |
|
|
476
|
+
| `2` | a dev install (`git pull` instead), or an install kind it cannot manage (the manual command is printed) |
|
|
477
|
+
|
|
478
|
+
On Windows a running `agent-toggle.exe` cannot be replaced, so the install runs detached after
|
|
479
|
+
agent-toggle exits (log in `%USERPROFILE%\.update-kit\`).
|
|
480
|
+
|
|
481
|
+
**The hint.** After a command, on an interactive terminal only (stderr is a TTY, never under
|
|
482
|
+
`--json`, pipes, launchd or timers), agent-toggle prints one stderr line when a newer release
|
|
483
|
+
exists, `agent-toggle vX.Y.Z is available (you have A) — run `agent-toggle update``. The check is
|
|
484
|
+
`git ls-remote` with a 1.5 s timeout, cached for 24 hours (failures too) in
|
|
485
|
+
`~/.update-kit/state.json`. It never changes the exit code or stdout. To turn it off, set
|
|
486
|
+
`AGENT_TOGGLE_UPDATE_CHECK=0` or the `update_check` setting to off (the settings menu's
|
|
487
|
+
"Check for updates").
|
|
484
488
|
|
|
485
489
|
## Help
|
|
486
490
|
|
|
@@ -872,7 +876,6 @@ bookkeeping.
|
|
|
872
876
|
| `parked/<sha8>/` | items parked by `--project` (`<sha8>` = first 8 hex of the SHA-1 of the resolved project dir) |
|
|
873
877
|
| `profiles/` | `<name>.json` profiles (dir `0700`, files `0600`) |
|
|
874
878
|
| `config.json` | [settings](#settings--config-menu) and the Telegram chat id (mode `0600`, atomic write, unknown keys kept) |
|
|
875
|
-
| `update-check.json` | the [update check](#update-check)'s 10-minute cache (mode `0600`, atomic write) |
|
|
876
879
|
|
|
877
880
|
A killed run loses at most the one item in flight. If that was a flag write or a
|
|
878
881
|
dir move (with its companions), its `pending` record (the full entry, a flag's
|
|
@@ -36,7 +36,7 @@ Usage:
|
|
|
36
36
|
failure, 2 usage error, 3 locked, 4 unsupported pair / harness missing.
|
|
37
37
|
Settings: $HOME/.agent-toggle/config.json (see `config`); env overrides
|
|
38
38
|
AGENT_TOGGLE_UPDATE_CHECK / _COLOR / _LANG / _DEFAULT_HARNESS.
|
|
39
|
-
Update
|
|
39
|
+
Update hint: on by default, a terminal's stderr only; AGENT_TOGGLE_UPDATE_CHECK=0 turns it off.
|
|
40
40
|
"""
|
|
41
41
|
from __future__ import annotations
|
|
42
42
|
|
|
@@ -695,7 +695,7 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
695
695
|
sub.add_parser("doctor", parents=[common],
|
|
696
696
|
help="check harness layouts and state against disk; offers y/n fixes")
|
|
697
697
|
sub.add_parser("update", parents=[common],
|
|
698
|
-
help="
|
|
698
|
+
help="install the newest release, then refresh the plugin and shims")
|
|
699
699
|
cf = sub.add_parser("config", parents=[common],
|
|
700
700
|
help="Telegram settings for the CI failure alerts")
|
|
701
701
|
cf.add_argument("action", nargs="?", choices=("test", "sync-ci"),
|
|
@@ -723,9 +723,9 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
723
723
|
def main(argv: list[str] | None = None) -> int:
|
|
724
724
|
"""Run one command and return its exit code (the process exit code).
|
|
725
725
|
|
|
726
|
-
Settings apply first; the update
|
|
727
|
-
|
|
728
|
-
|
|
726
|
+
Settings apply first; the update hint is printed in a `finally`, so every way out
|
|
727
|
+
(a command, --help/--version, a usage error, Locked, CliError) gets it. It writes
|
|
728
|
+
to stderr only and never changes the exit code."""
|
|
729
729
|
argv = normalize_argv(sys.argv[1:] if argv is None else argv)
|
|
730
730
|
try:
|
|
731
731
|
language, color = settings.get("language"), settings.get("color")
|
|
@@ -734,16 +734,17 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
734
734
|
i18n.set_language(language)
|
|
735
735
|
color = scan_color(argv, color) # --color > env > setting > auto
|
|
736
736
|
i = _command_index(argv)
|
|
737
|
-
|
|
738
|
-
started = None if argv[i:i + 1] in (["update"], ["completion"]) else update_prompt.start()
|
|
737
|
+
hint = True
|
|
739
738
|
try:
|
|
740
739
|
return _main(argv, color)
|
|
741
740
|
except KeyboardInterrupt:
|
|
742
|
-
|
|
741
|
+
hint = False # never ask anything after the user hit Ctrl-C
|
|
743
742
|
raise
|
|
744
743
|
finally:
|
|
745
|
-
|
|
746
|
-
|
|
744
|
+
# `update` is the update; `completion` may run on every shell start (eval "$(...)")
|
|
745
|
+
if hint and argv[i:i + 1] not in (["update"], ["completion"]):
|
|
746
|
+
with contextlib.suppress(KeyboardInterrupt):
|
|
747
|
+
update_prompt.hint(json_mode="--json" in argv)
|
|
747
748
|
|
|
748
749
|
|
|
749
750
|
def _main(argv: list[str], color: str) -> int:
|
|
@@ -804,7 +805,7 @@ def _main(argv: list[str], color: str) -> int:
|
|
|
804
805
|
if fixes and _interactive(out):
|
|
805
806
|
doctor.offer_fixes(fixes, out)
|
|
806
807
|
elif cmd == "update":
|
|
807
|
-
update_prompt.cmd_update(
|
|
808
|
+
return update_prompt.cmd_update()
|
|
808
809
|
elif cmd == "config":
|
|
809
810
|
config.cmd_config(args, out)
|
|
810
811
|
elif cmd == "completion":
|
|
@@ -137,12 +137,13 @@ def commands(default_harness: str = "claude") -> dict[str, Cmd]:
|
|
|
137
137
|
examples=["config", "config test", "config sync-ci --dry-run"]),
|
|
138
138
|
"update": Cmd(
|
|
139
139
|
"update",
|
|
140
|
-
t("help.update.summary", "
|
|
141
|
-
t("help.update.desc", "
|
|
142
|
-
"
|
|
143
|
-
"
|
|
144
|
-
"
|
|
145
|
-
|
|
140
|
+
t("help.update.summary", "install the newest release; refresh the plugin and shims"),
|
|
141
|
+
t("help.update.desc", "Install the newest release tag (uv tool or pipx), then, with the "
|
|
142
|
+
"new version, update the Claude Code plugin (if installed) and "
|
|
143
|
+
"reinstall the shims. Never asks; `--update` is the same. A dev "
|
|
144
|
+
"install says to git pull (exit 2). Exit 1 when the check or "
|
|
145
|
+
"the install fails."),
|
|
146
|
+
examples=["update"]),
|
|
146
147
|
"completion": Cmd(
|
|
147
148
|
"completion bash|zsh|fish|powershell",
|
|
148
149
|
t("help.completion.summary", "print the shell completion script"),
|
|
@@ -27,9 +27,9 @@ CATALOG: dict[str, str] = {
|
|
|
27
27
|
"help.cost.summary": "每個項目的預估啟動 token 數,由大到小",
|
|
28
28
|
"help.cost.desc": "估算每個項目啟動時載入多少 token(字元數/4,±25%),"
|
|
29
29
|
"以及暫存項目已省下多少。",
|
|
30
|
-
"help.update.summary": "
|
|
31
|
-
"help.update.desc": "
|
|
32
|
-
"
|
|
30
|
+
"help.update.summary": "安裝最新版本,並更新外掛與 shim",
|
|
31
|
+
"help.update.desc": "安裝最新的發行標籤(uv tool / pipx),完成後以新版更新 Claude Code 外掛(若已安裝)"
|
|
32
|
+
"並重新安裝 shim。不會提問;`--update` 等同 `update`。開發版安裝請改用 git pull(結束碼 2)。",
|
|
33
33
|
"help.completion.summary": "印出 shell 自動補完腳本",
|
|
34
34
|
"help.completion.desc": "在 stdout 印出某個 shell 的 Tab 補完腳本;"
|
|
35
35
|
"存到該 shell 載入補完的位置(見 README「Shell completion」)。",
|
|
@@ -85,16 +85,4 @@ CATALOG: dict[str, str] = {
|
|
|
85
85
|
"help.opt.help": "顯示說明(`help <command>` 看單一指令)",
|
|
86
86
|
"help.arguments": "參數",
|
|
87
87
|
"help.options": "選項",
|
|
88
|
-
# update prompt
|
|
89
|
-
"update.available": "agent-toggle %s 已推出(目前版本 %s)",
|
|
90
|
-
"update.keys": "↑↓ 選擇 · ⏎ 確認 · q/Ctrl+C 略過",
|
|
91
|
-
"update.keys_ascii": "上/下 選擇,Enter 確認,q/Ctrl+C 略過",
|
|
92
|
-
"update.choose": "請選擇 1-3(Enter = 1,q/Ctrl+C = 略過):",
|
|
93
|
-
"update.now": "立即更新",
|
|
94
|
-
"update.skip": "略過",
|
|
95
|
-
"update.skip_detail": "下次執行再問",
|
|
96
|
-
"update.skip_version": "略過到下一個版本",
|
|
97
|
-
"update.skip_version_detail": "有更新的版本時再問",
|
|
98
|
-
"update.notes": "版本說明:%s",
|
|
99
|
-
"update.failed": "更新未完成 — 請自行執行:%s",
|
|
100
88
|
}
|
|
@@ -17,7 +17,7 @@ agent-toggle <command> --json
|
|
|
17
17
|
```
|
|
18
18
|
If `agent-toggle` is not on PATH, ask the user to install it (`uv tool install agent-toggle`); do not guess where a checkout lives.
|
|
19
19
|
|
|
20
|
-
Commands: `status` (run first), `doctor` (read-only health check), `update` (
|
|
20
|
+
Commands: `status` (run first), `doctor` (read-only health check), `update` (installs the newest release, then refreshes the plugin and shims; run it only when the user asks to update), `list [type]`,
|
|
21
21
|
`cost [--type T]` (startup token estimates, biggest first), `disable <type> <name>...` (type `all`: every type with that name),
|
|
22
22
|
`enable <type> <name>...`, `enable --all`, `undo` (reverse the last batch),
|
|
23
23
|
`profile save|apply|diff|delete <name>`, `profile rename <old> <new>`, `profile list` (see Profiles), `migrate`; add `--harness claude|codex|grok|opencode|openclaw|copilot|vibe|devin|agy`
|
|
@@ -20,7 +20,7 @@ You are running in `__HARNESS__`: pass `--harness __HARNESS__` for its own items
|
|
|
20
20
|
(the default is `claude`). Other harnesses: `--harness claude|codex|grok|opencode|openclaw|copilot|vibe|devin|agy`.
|
|
21
21
|
|
|
22
22
|
Commands: `status` (run first; shows which types this harness supports),
|
|
23
|
-
`doctor` (read-only health check), `update` (
|
|
23
|
+
`doctor` (read-only health check), `update` (installs the newest release, then refreshes the plugin and shims; run it only when the user asks to update), `list [type]`, `cost [--type T]` (startup
|
|
24
24
|
token estimates, biggest first), `disable <type> <name>...` (type `all`: every type with that name), `enable <type> <name>...`,
|
|
25
25
|
`enable --all`, `undo` (reverse the last batch), `profile save|apply|diff|delete <name>`,
|
|
26
26
|
`profile rename <old> <new>`, `profile list` (see Profiles); add `--dry-run` to preview. `<type>` = `skill` / `agent` /
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"""`update` / `--update` and the one-line "newer release" hint, both through update_kit.
|
|
2
|
+
|
|
3
|
+
cmd_update() # install the newest tag, then refresh the plugin and shims; returns the exit code
|
|
4
|
+
hint() # after a command: one stderr line when a newer release exists (TTY only)
|
|
5
|
+
|
|
6
|
+
No prompts: the old arrow-key panel and its skip-version bookkeeping are gone.
|
|
7
|
+
"""
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import os
|
|
11
|
+
import subprocess
|
|
12
|
+
import sys
|
|
13
|
+
from collections.abc import Sequence
|
|
14
|
+
from functools import cached_property
|
|
15
|
+
|
|
16
|
+
from . import __version__, i18n, settings
|
|
17
|
+
from .backends import plugin_cli
|
|
18
|
+
from .ui import theme
|
|
19
|
+
|
|
20
|
+
DIST = "agent-toggle"
|
|
21
|
+
REPO = "weskao/agent-toggle"
|
|
22
|
+
PLUGIN = "agent-toggle@agent-toggle"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def after_steps() -> list[list[str]]:
|
|
26
|
+
"""Run with the NEW binary once the install is done: the Claude Code plugin when it is
|
|
27
|
+
installed, then the shims."""
|
|
28
|
+
steps: list[list[str]] = []
|
|
29
|
+
# bare "claude": what a person pastes; _run() resolves it, as claude is often off PATH
|
|
30
|
+
if plugin_cli.claude_bin() and any(p["id"] == PLUGIN for p in plugin_cli.list_plugins(lambda _msg: None)):
|
|
31
|
+
steps += [["claude", "plugin", "marketplace", "update", DIST],
|
|
32
|
+
["claude", "plugin", "update", PLUGIN]]
|
|
33
|
+
return [*steps, [DIST, "install-shims"]]
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class _LazySteps(Sequence):
|
|
37
|
+
"""after_steps(), computed on first use: update_kit only reads `after` once an install
|
|
38
|
+
will happen, so a dev refusal / "already up to date" skips `claude plugin list` (0.8 s)."""
|
|
39
|
+
|
|
40
|
+
@cached_property
|
|
41
|
+
def _steps(self) -> list[list[str]]:
|
|
42
|
+
return after_steps()
|
|
43
|
+
|
|
44
|
+
def __len__(self) -> int:
|
|
45
|
+
return len(self._steps)
|
|
46
|
+
|
|
47
|
+
def __getitem__(self, i):
|
|
48
|
+
return self._steps[i]
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def _run(cmd, **kw):
|
|
52
|
+
"""update_kit's subprocess runner: their output stays off stdout and no step may prompt,
|
|
53
|
+
and a step like `install-shims` must not re-check for updates and print the hint."""
|
|
54
|
+
if cmd[0] == "claude":
|
|
55
|
+
cmd = [plugin_cli.claude_bin() or "claude", *cmd[1:]]
|
|
56
|
+
# update_kit passes its own env (no-prompt git vars) for the install step: merge, don't replace
|
|
57
|
+
kw["env"] = {**kw.get("env", os.environ), "AGENT_TOGGLE_UPDATE_CHECK": "0"}
|
|
58
|
+
return subprocess.run(cmd, stdout=sys.stderr, stdin=subprocess.DEVNULL, **kw)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def cmd_update() -> int:
|
|
62
|
+
# imported here, like telegram_kit: a checkout run (`python3 agent_toggle.py`) or a stale env lacks it
|
|
63
|
+
import update_kit
|
|
64
|
+
return update_kit.update(app=DIST, repo=REPO, dist=DIST, lang=i18n.LANGUAGE,
|
|
65
|
+
after=_LazySteps(), out=sys.stderr, run=_run)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def hint(*, json_mode: bool = False) -> None:
|
|
69
|
+
"""One stderr line when a newer release exists: only on a terminal, never under --json,
|
|
70
|
+
off with the `update_check` setting (env AGENT_TOGGLE_UPDATE_CHECK wins). Never raises."""
|
|
71
|
+
try:
|
|
72
|
+
import update_kit
|
|
73
|
+
if json_mode or not settings.get("update_check") or not update_kit.should_hint(sys.stderr):
|
|
74
|
+
return
|
|
75
|
+
latest = update_kit.check(repo=REPO, current=__version__)
|
|
76
|
+
if latest:
|
|
77
|
+
print(theme.encodable(update_kit.hint(DIST, latest, __version__, i18n.LANGUAGE), sys.stderr),
|
|
78
|
+
file=sys.stderr)
|
|
79
|
+
except Exception: # noqa: BLE001 - a hint must never fail the command
|
|
80
|
+
pass
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agent-toggle
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.15.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
|
|
@@ -25,6 +25,7 @@ Requires-Python: >=3.10
|
|
|
25
25
|
Description-Content-Type: text/markdown
|
|
26
26
|
License-File: LICENSE
|
|
27
27
|
Requires-Dist: telegram-kit<0.3,>=0.2.2
|
|
28
|
+
Requires-Dist: update-kit<0.2,>=0.1
|
|
28
29
|
Provides-Extra: windows
|
|
29
30
|
Requires-Dist: windows-curses; sys_platform == "win32" and extra == "windows"
|
|
30
31
|
Provides-Extra: telegram
|
|
@@ -202,7 +203,7 @@ agent-toggle <command> [args] # or: python3 agent_toggle.py <command> [
|
|
|
202
203
|
| `status` | health check: harnesses found, types each supports, parked counts, gitignore, untracked parked items, stale live twins, shared dirs, and state entries whose parked item is gone (a `stale` row with the fix command; read-only, still exit `0`) |
|
|
203
204
|
| `list [type]` | what is currently disabled (`--project <dir>` filters to one project) |
|
|
204
205
|
| `cost [--type T]` | estimated startup tokens per item, biggest first (read-only; `--harness H` filters; `--project <dir>` prices a repo's `.claude/` and `.mcp.json` instead of user scope) |
|
|
205
|
-
| `update` |
|
|
206
|
+
| `update` (also `--update`) | install the newest release tag (`uv tool install --force --no-sources git+<repo>@<tag>`, or `pipx install --force` for a pipx install), then, with the new version, update the Claude Code plugin (when installed) and the shims. Never asks. Exit `0` updated or already current, `1` the check or install failed (offline, rate limit), `2` a dev install (use `git pull`) or an install it cannot manage (the manual command is printed). Messages go to stderr; `--json` has no JSON for it. The `/agent-toggle` pane command has no `update`: run it in a terminal |
|
|
206
207
|
| `install-shims` | write the skill shim into every installed harness that is on in the settings (an off one is skipped unless named with `--harness`); refuses to overwrite a file it did not write (`--dry-run` shows the plan); reports stale legacy `<dir>-disabled/` lines in a harness-home `.gitignore` (`--gitignore` removes them, `--no-gitignore` skips the check); on a terminal, then asks y/n for each problem `doctor` can fix (see [Fixing](#fixing)) |
|
|
207
208
|
| `disable <type> <name>...` | park one or more items (`--dry-run` shows the plan; `--project <dir>` for a repo's own `.claude/` and `.mcp.json`) |
|
|
208
209
|
| `enable <type> <name>...` | put them back (`--dry-run` shows the plan; `--project <dir>` likewise) |
|
|
@@ -487,33 +488,37 @@ invalid value in either is ignored with one warning on stderr.
|
|
|
487
488
|
- `default_harness` is what `disable` / `enable` act on without `--harness`, even when that
|
|
488
489
|
harness is switched off (with one warning on stderr);
|
|
489
490
|
`disable` / `enable --project` without `--harness` still default to `claude`.
|
|
490
|
-
- `language` translates the config menu, help, update
|
|
491
|
+
- `language` translates the config menu, help, update messages and picker chrome; command output stays English.
|
|
491
492
|
- telegram-kit is a regular dependency now, so reinstalling keeps the Telegram settings working;
|
|
492
493
|
`agent-toggle[telegram]` still resolves.
|
|
493
494
|
|
|
494
|
-
## Update
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
495
|
+
## Update
|
|
496
|
+
|
|
497
|
+
`agent-toggle update` (or `agent-toggle --update`) is a self-update through
|
|
498
|
+
update-kit (a small stdlib-only helper library): it asks the repository for its newest `vX.Y.Z`
|
|
499
|
+
tag (`git ls-remote --tags`), and when that is newer than the running version it installs it with
|
|
500
|
+
`uv tool install --force --no-sources git+<repo>@<tag>` (`pipx install --force` for a pipx install).
|
|
501
|
+
It then runs, with the new binary and in order: when the Claude Code plugin is installed,
|
|
502
|
+
`claude plugin marketplace update agent-toggle` and `claude plugin update agent-toggle@agent-toggle`,
|
|
503
|
+
then `agent-toggle install-shims`. A failing step prints a warning and makes the exit code `1`.
|
|
504
|
+
It never prompts and writes to stderr only.
|
|
505
|
+
|
|
506
|
+
| Exit | Meaning |
|
|
507
|
+
|---|---|
|
|
508
|
+
| `0` | updated, or already up to date |
|
|
509
|
+
| `1` | could not check (offline, rate limit) or the install failed |
|
|
510
|
+
| `2` | a dev install (`git pull` instead), or an install kind it cannot manage (the manual command is printed) |
|
|
511
|
+
|
|
512
|
+
On Windows a running `agent-toggle.exe` cannot be replaced, so the install runs detached after
|
|
513
|
+
agent-toggle exits (log in `%USERPROFILE%\.update-kit\`).
|
|
514
|
+
|
|
515
|
+
**The hint.** After a command, on an interactive terminal only (stderr is a TTY, never under
|
|
516
|
+
`--json`, pipes, launchd or timers), agent-toggle prints one stderr line when a newer release
|
|
517
|
+
exists, `agent-toggle vX.Y.Z is available (you have A) — run `agent-toggle update``. The check is
|
|
518
|
+
`git ls-remote` with a 1.5 s timeout, cached for 24 hours (failures too) in
|
|
519
|
+
`~/.update-kit/state.json`. It never changes the exit code or stdout. To turn it off, set
|
|
520
|
+
`AGENT_TOGGLE_UPDATE_CHECK=0` or the `update_check` setting to off (the settings menu's
|
|
521
|
+
"Check for updates").
|
|
517
522
|
|
|
518
523
|
## Help
|
|
519
524
|
|
|
@@ -905,7 +910,6 @@ bookkeeping.
|
|
|
905
910
|
| `parked/<sha8>/` | items parked by `--project` (`<sha8>` = first 8 hex of the SHA-1 of the resolved project dir) |
|
|
906
911
|
| `profiles/` | `<name>.json` profiles (dir `0700`, files `0600`) |
|
|
907
912
|
| `config.json` | [settings](#settings--config-menu) and the Telegram chat id (mode `0600`, atomic write, unknown keys kept) |
|
|
908
|
-
| `update-check.json` | the [update check](#update-check)'s 10-minute cache (mode `0600`, atomic write) |
|
|
909
913
|
|
|
910
914
|
A killed run loses at most the one item in flight. If that was a flag write or a
|
|
911
915
|
dir move (with its companions), its `pending` record (the full entry, a flag's
|
|
@@ -22,7 +22,6 @@ agent_toggle/spinner.py
|
|
|
22
22
|
agent_toggle/store.py
|
|
23
23
|
agent_toggle/toml_check.py
|
|
24
24
|
agent_toggle/undo.py
|
|
25
|
-
agent_toggle/update_check.py
|
|
26
25
|
agent_toggle/update_prompt.py
|
|
27
26
|
agent_toggle.egg-info/PKG-INFO
|
|
28
27
|
agent_toggle.egg-info/SOURCES.txt
|
|
@@ -85,5 +84,4 @@ tests/test_settings.py
|
|
|
85
84
|
tests/test_store.py
|
|
86
85
|
tests/test_theme.py
|
|
87
86
|
tests/test_undo.py
|
|
88
|
-
tests/test_update_check.py
|
|
89
87
|
tests/test_update_prompt.py
|
|
@@ -27,7 +27,7 @@ classifiers = [
|
|
|
27
27
|
]
|
|
28
28
|
requires-python = ">=3.10"
|
|
29
29
|
# telegram-kit is core (stdlib-only) so a plain reinstall can't drop the Telegram settings
|
|
30
|
-
dependencies = ["telegram-kit>=0.2.2,<0.3"]
|
|
30
|
+
dependencies = ["telegram-kit>=0.2.2,<0.3", "update-kit>=0.1,<0.2"]
|
|
31
31
|
|
|
32
32
|
[project.urls]
|
|
33
33
|
Homepage = "https://github.com/weskao/agent-toggle"
|