agent-toggle 0.14.0__tar.gz → 0.16.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.16.0}/PKG-INFO +35 -9
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/README.md +33 -8
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/agent_toggle/__init__.py +1 -1
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/agent_toggle/cli.py +3 -3
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/agent_toggle/help.py +8 -6
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/agent_toggle/locales/zh_tw_cli.py +4 -3
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/agent_toggle/shims/claude.md.tmpl +1 -1
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/agent_toggle/shims/generic.md.tmpl +1 -1
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/agent_toggle/update_prompt.py +63 -45
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/agent_toggle.egg-info/PKG-INFO +35 -9
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/agent_toggle.egg-info/requires.txt +1 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/pyproject.toml +1 -1
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/tests/test_cli.py +55 -17
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/tests/test_cli_surface.py +7 -1
- agent_toggle-0.16.0/tests/test_update_prompt.py +162 -0
- agent_toggle-0.14.0/tests/test_update_prompt.py +0 -90
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/LICENSE +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/agent_toggle/__main__.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/agent_toggle/backends/__init__.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/agent_toggle/backends/flag_json.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/agent_toggle/backends/mcp_json.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/agent_toggle/backends/mcp_toml.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/agent_toggle/backends/plugin_cli.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/agent_toggle/companions.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/agent_toggle/completions.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/agent_toggle/config.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/agent_toggle/cost.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/agent_toggle/doctor.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/agent_toggle/fs.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/agent_toggle/harnesses.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/agent_toggle/i18n.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/agent_toggle/locales/__init__.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/agent_toggle/locales/zh_tw_common.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/agent_toggle/locales/zh_tw_config.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/agent_toggle/locales/zh_tw_picker.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/agent_toggle/mechanisms.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/agent_toggle/ops.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/agent_toggle/output.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/agent_toggle/profiles.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/agent_toggle/settings.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/agent_toggle/spinner.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/agent_toggle/store.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/agent_toggle/toml_check.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/agent_toggle/ui/__init__.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/agent_toggle/ui/config_menu.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/agent_toggle/ui/logo.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/agent_toggle/ui/menu.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/agent_toggle/ui/model.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/agent_toggle/ui/picker.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/agent_toggle/ui/theme.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/agent_toggle/undo.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/agent_toggle/update_check.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/agent_toggle.egg-info/SOURCES.txt +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/agent_toggle.egg-info/dependency_links.txt +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/agent_toggle.egg-info/entry_points.txt +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/agent_toggle.egg-info/top_level.txt +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/setup.cfg +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/tests/test_alias.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/tests/test_all_type.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/tests/test_backends.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/tests/test_color.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/tests/test_companions.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/tests/test_completions.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/tests/test_config.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/tests/test_config_menu.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/tests/test_conformance.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/tests/test_containment.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/tests/test_cost.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/tests/test_crash.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/tests/test_doctor.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/tests/test_encoding.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/tests/test_fs.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/tests/test_harnesses.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/tests/test_help.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/tests/test_i18n.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/tests/test_install.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/tests/test_logo.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/tests/test_mechanisms.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/tests/test_menu.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/tests/test_mods.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/tests/test_picker.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/tests/test_platform.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/tests/test_profiles.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/tests/test_project.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/tests/test_safety.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/tests/test_same_name.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/tests/test_secret_audit.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/tests/test_settings.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/tests/test_store.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/tests/test_theme.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/tests/test_undo.py +0 -0
- {agent_toggle-0.14.0 → agent_toggle-0.16.0}/tests/test_update_check.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agent-toggle
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.16.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.3,>=0.2.1
|
|
28
29
|
Provides-Extra: windows
|
|
29
30
|
Requires-Dist: windows-curses; sys_platform == "win32" and extra == "windows"
|
|
30
31
|
Provides-Extra: telegram
|
|
@@ -40,6 +41,10 @@ rules, plugins (mods included), MCP servers — across Claude Code, Codex, Grok
|
|
|
40
41
|
OpenClaw, Copilot, Vibe, Devin and Antigravity — and show what each one costs at
|
|
41
42
|
session start.
|
|
42
43
|
|
|
44
|
+
It ships in two forms: a **CLI** (`agent-toggle`, all harnesses) and a **Claude Code mod**
|
|
45
|
+
(the `/agent-toggle` pane, claude harness only; see [Claude Code pane mod](#claude-code-pane-mod)).
|
|
46
|
+
Both drive the same toggle engine and state.
|
|
47
|
+
|
|
43
48
|
**Nothing is ever deleted.** Everything is parked and recorded, and `enable`
|
|
44
49
|
puts it back where it came from.
|
|
45
50
|
|
|
@@ -202,7 +207,7 @@ agent-toggle <command> [args] # or: python3 agent_toggle.py <command> [
|
|
|
202
207
|
| `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
208
|
| `list [type]` | what is currently disabled (`--project <dir>` filters to one project) |
|
|
204
209
|
| `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` |
|
|
210
|
+
| `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. Always the newest tag: a dev checkout, a branch or an unmanaged install is replaced by it. Exit `0` updated or already current, `1` the check or install failed (offline, rate limit), `2` neither uv nor pipx is found (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
211
|
| `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
212
|
| `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
213
|
| `enable <type> <name>...` | put them back (`--dry-run` shows the plan; `--project <dir>` likewise) |
|
|
@@ -495,18 +500,17 @@ invalid value in either is ignored with one warning on stderr.
|
|
|
495
500
|
|
|
496
501
|
On every invocation (unless disabled) agent-toggle checks PyPI for a newer release. It starts
|
|
497
502
|
before the command and is offered after it, on every exit path; it overlaps the command and waits at most 0.8 s afterwards.
|
|
503
|
+
`update` and `completion` skip it.
|
|
498
504
|
|
|
499
505
|
- **On a terminal** (stdin and stderr are TTYs, no `--json`): a panel on stderr, "agent-toggle X
|
|
500
506
|
is available (you have Y)", with `Update now`, `Skip` and `Skip until next version`, a release
|
|
501
|
-
notes link, and `↑` `↓` `Enter` `q`. `Update now` runs
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
`claude plugin update agent-toggle@agent-toggle`, then `agent-toggle install-shims`. A failure
|
|
505
|
-
gives a yellow warning listing the commands to run yourself.
|
|
507
|
+
notes link, and `↑` `↓` `Enter` `q`. `Update now` runs [`agent-toggle update`](#update) (the
|
|
508
|
+
newest release tag, then the Claude Code plugin and the shims). A failure gives a yellow warning
|
|
509
|
+
naming the command to run yourself.
|
|
506
510
|
- **Windows**: a running `agent-toggle.exe` cannot be replaced, so there is no `Update now`; the
|
|
507
|
-
|
|
511
|
+
command is printed instead (as below), to run once agent-toggle has exited.
|
|
508
512
|
- **Off a terminal** (or `--json`): a stderr line, `agent-toggle X is available (you have Y)`,
|
|
509
|
-
then
|
|
513
|
+
then ` agent-toggle update`.
|
|
510
514
|
- It never changes the exit code or stdout, so `--json` output stays one document.
|
|
511
515
|
|
|
512
516
|
It is one `GET https://pypi.org/pypi/agent-toggle/json` on a background thread with a 0.8 s
|
|
@@ -515,6 +519,28 @@ normal HTTP request with the User-Agent `agent-toggle-update-check`. See `SECURI
|
|
|
515
519
|
for the hardening. To turn it off, set `AGENT_TOGGLE_UPDATE_CHECK=0` or the `update_check` setting
|
|
516
520
|
to off (the settings menu's "Check for updates").
|
|
517
521
|
|
|
522
|
+
## Update
|
|
523
|
+
|
|
524
|
+
`agent-toggle update` (or `agent-toggle --update`) is a self-update through
|
|
525
|
+
update-kit (a small stdlib-only helper library): it asks the repository for its newest `vX.Y.Z`
|
|
526
|
+
tag (`git ls-remote --tags`) and always installs that tag with
|
|
527
|
+
`uv tool install --force --no-sources git+<repo>@<tag>` (`pipx install --force` for a pipx install).
|
|
528
|
+
A dev checkout, a branch or commit install, or an unmanaged install is replaced by the tag too
|
|
529
|
+
(with uv, else pipx); only an install made from exactly that tag is already up to date.
|
|
530
|
+
It then runs, with the new binary and in order: when the Claude Code plugin is installed,
|
|
531
|
+
`claude plugin marketplace update agent-toggle` and `claude plugin update agent-toggle@agent-toggle`,
|
|
532
|
+
then `agent-toggle install-shims`. A failing step prints a warning and makes the exit code `1`.
|
|
533
|
+
It never prompts and writes to stderr only.
|
|
534
|
+
|
|
535
|
+
| Exit | Meaning |
|
|
536
|
+
|---|---|
|
|
537
|
+
| `0` | updated, or already up to date |
|
|
538
|
+
| `1` | could not check (offline, rate limit) or the install failed |
|
|
539
|
+
| `2` | neither uv nor pipx is found (the manual command is printed) |
|
|
540
|
+
|
|
541
|
+
On Windows a running `agent-toggle.exe` cannot be replaced, so the install runs detached after
|
|
542
|
+
agent-toggle exits (log in `%USERPROFILE%\.update-kit\`).
|
|
543
|
+
|
|
518
544
|
## Help
|
|
519
545
|
|
|
520
546
|
```sh
|
|
@@ -7,6 +7,10 @@ rules, plugins (mods included), MCP servers — across Claude Code, Codex, Grok
|
|
|
7
7
|
OpenClaw, Copilot, Vibe, Devin and Antigravity — and show what each one costs at
|
|
8
8
|
session start.
|
|
9
9
|
|
|
10
|
+
It ships in two forms: a **CLI** (`agent-toggle`, all harnesses) and a **Claude Code mod**
|
|
11
|
+
(the `/agent-toggle` pane, claude harness only; see [Claude Code pane mod](#claude-code-pane-mod)).
|
|
12
|
+
Both drive the same toggle engine and state.
|
|
13
|
+
|
|
10
14
|
**Nothing is ever deleted.** Everything is parked and recorded, and `enable`
|
|
11
15
|
puts it back where it came from.
|
|
12
16
|
|
|
@@ -169,7 +173,7 @@ agent-toggle <command> [args] # or: python3 agent_toggle.py <command> [
|
|
|
169
173
|
| `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
174
|
| `list [type]` | what is currently disabled (`--project <dir>` filters to one project) |
|
|
171
175
|
| `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` |
|
|
176
|
+
| `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. Always the newest tag: a dev checkout, a branch or an unmanaged install is replaced by it. Exit `0` updated or already current, `1` the check or install failed (offline, rate limit), `2` neither uv nor pipx is found (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
177
|
| `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
178
|
| `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
179
|
| `enable <type> <name>...` | put them back (`--dry-run` shows the plan; `--project <dir>` likewise) |
|
|
@@ -462,18 +466,17 @@ invalid value in either is ignored with one warning on stderr.
|
|
|
462
466
|
|
|
463
467
|
On every invocation (unless disabled) agent-toggle checks PyPI for a newer release. It starts
|
|
464
468
|
before the command and is offered after it, on every exit path; it overlaps the command and waits at most 0.8 s afterwards.
|
|
469
|
+
`update` and `completion` skip it.
|
|
465
470
|
|
|
466
471
|
- **On a terminal** (stdin and stderr are TTYs, no `--json`): a panel on stderr, "agent-toggle X
|
|
467
472
|
is available (you have Y)", with `Update now`, `Skip` and `Skip until next version`, a release
|
|
468
|
-
notes link, and `↑` `↓` `Enter` `q`. `Update now` runs
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
`claude plugin update agent-toggle@agent-toggle`, then `agent-toggle install-shims`. A failure
|
|
472
|
-
gives a yellow warning listing the commands to run yourself.
|
|
473
|
+
notes link, and `↑` `↓` `Enter` `q`. `Update now` runs [`agent-toggle update`](#update) (the
|
|
474
|
+
newest release tag, then the Claude Code plugin and the shims). A failure gives a yellow warning
|
|
475
|
+
naming the command to run yourself.
|
|
473
476
|
- **Windows**: a running `agent-toggle.exe` cannot be replaced, so there is no `Update now`; the
|
|
474
|
-
|
|
477
|
+
command is printed instead (as below), to run once agent-toggle has exited.
|
|
475
478
|
- **Off a terminal** (or `--json`): a stderr line, `agent-toggle X is available (you have Y)`,
|
|
476
|
-
then
|
|
479
|
+
then ` agent-toggle update`.
|
|
477
480
|
- It never changes the exit code or stdout, so `--json` output stays one document.
|
|
478
481
|
|
|
479
482
|
It is one `GET https://pypi.org/pypi/agent-toggle/json` on a background thread with a 0.8 s
|
|
@@ -482,6 +485,28 @@ normal HTTP request with the User-Agent `agent-toggle-update-check`. See `SECURI
|
|
|
482
485
|
for the hardening. To turn it off, set `AGENT_TOGGLE_UPDATE_CHECK=0` or the `update_check` setting
|
|
483
486
|
to off (the settings menu's "Check for updates").
|
|
484
487
|
|
|
488
|
+
## Update
|
|
489
|
+
|
|
490
|
+
`agent-toggle update` (or `agent-toggle --update`) is a self-update through
|
|
491
|
+
update-kit (a small stdlib-only helper library): it asks the repository for its newest `vX.Y.Z`
|
|
492
|
+
tag (`git ls-remote --tags`) and always installs that tag with
|
|
493
|
+
`uv tool install --force --no-sources git+<repo>@<tag>` (`pipx install --force` for a pipx install).
|
|
494
|
+
A dev checkout, a branch or commit install, or an unmanaged install is replaced by the tag too
|
|
495
|
+
(with uv, else pipx); only an install made from exactly that tag is already up to date.
|
|
496
|
+
It then runs, with the new binary and in order: when the Claude Code plugin is installed,
|
|
497
|
+
`claude plugin marketplace update agent-toggle` and `claude plugin update agent-toggle@agent-toggle`,
|
|
498
|
+
then `agent-toggle install-shims`. A failing step prints a warning and makes the exit code `1`.
|
|
499
|
+
It never prompts and writes to stderr only.
|
|
500
|
+
|
|
501
|
+
| Exit | Meaning |
|
|
502
|
+
|---|---|
|
|
503
|
+
| `0` | updated, or already up to date |
|
|
504
|
+
| `1` | could not check (offline, rate limit) or the install failed |
|
|
505
|
+
| `2` | neither uv nor pipx is found (the manual command is printed) |
|
|
506
|
+
|
|
507
|
+
On Windows a running `agent-toggle.exe` cannot be replaced, so the install runs detached after
|
|
508
|
+
agent-toggle exits (log in `%USERPROFILE%\.update-kit\`).
|
|
509
|
+
|
|
485
510
|
## Help
|
|
486
511
|
|
|
487
512
|
```sh
|
|
@@ -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"),
|
|
@@ -734,7 +734,7 @@ 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
|
-
# `update` is the
|
|
737
|
+
# `update` is the update; `completion` may run on every shell start (eval "$(...)")
|
|
738
738
|
started = None if argv[i:i + 1] in (["update"], ["completion"]) else update_prompt.start()
|
|
739
739
|
try:
|
|
740
740
|
return _main(argv, color)
|
|
@@ -804,7 +804,7 @@ def _main(argv: list[str], color: str) -> int:
|
|
|
804
804
|
if fixes and _interactive(out):
|
|
805
805
|
doctor.offer_fixes(fixes, out)
|
|
806
806
|
elif cmd == "update":
|
|
807
|
-
update_prompt.cmd_update(
|
|
807
|
+
return update_prompt.cmd_update()
|
|
808
808
|
elif cmd == "config":
|
|
809
809
|
config.cmd_config(args, out)
|
|
810
810
|
elif cmd == "completion":
|
|
@@ -137,12 +137,14 @@ 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. Always "
|
|
144
|
+
"the newest tag: a dev or unmanaged install is replaced by it. "
|
|
145
|
+
"Exit 1 when the check or the install fails, 2 when neither uv "
|
|
146
|
+
"nor pipx is found."),
|
|
147
|
+
examples=["update"]),
|
|
146
148
|
"completion": Cmd(
|
|
147
149
|
"completion bash|zsh|fish|powershell",
|
|
148
150
|
t("help.completion.summary", "print the shell completion script"),
|
|
@@ -27,9 +27,10 @@ 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`。一律安裝最新標籤:開發版或非受管安裝也會被取代。"
|
|
33
|
+
"檢查或安裝失敗時結束碼 1;找不到 uv 與 pipx 時結束碼 2。",
|
|
33
34
|
"help.completion.summary": "印出 shell 自動補完腳本",
|
|
34
35
|
"help.completion.desc": "在 stdout 印出某個 shell 的 Tab 補完腳本;"
|
|
35
36
|
"存到該 shell 載入補完的位置(見 README「Shell completion」)。",
|
|
@@ -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` /
|
|
@@ -1,12 +1,15 @@
|
|
|
1
|
-
"""The update check's UI
|
|
1
|
+
"""The update check's UI, and `update` / `--update`.
|
|
2
2
|
|
|
3
3
|
started = start() # None when update_check is off; never raises
|
|
4
4
|
... # the command
|
|
5
5
|
offer(started, json_mode=..., color=...) # never raises, never touches stdout
|
|
6
6
|
|
|
7
|
+
cmd_update() # install the newest tag (update_kit), then the plugin and shims
|
|
8
|
+
|
|
7
9
|
On a terminal (stdin AND stderr are TTYs) and not under --json, :func:`ask` shows
|
|
8
10
|
a small arrow-key panel on stderr; elsewhere :func:`hint` prints two plain lines
|
|
9
|
-
on stderr. What each answer does lives in :func:`update_check.offer
|
|
11
|
+
on stderr. What each answer does lives in :func:`update_check.offer`; Update now
|
|
12
|
+
is :func:`cmd_update`.
|
|
10
13
|
"""
|
|
11
14
|
from __future__ import annotations
|
|
12
15
|
|
|
@@ -14,20 +17,20 @@ import os
|
|
|
14
17
|
import re
|
|
15
18
|
import subprocess
|
|
16
19
|
import sys
|
|
17
|
-
from collections.abc import Iterable, Iterator
|
|
20
|
+
from collections.abc import Iterable, Iterator, Sequence
|
|
21
|
+
from functools import cached_property
|
|
18
22
|
from pathlib import Path
|
|
19
23
|
|
|
20
|
-
from . import __version__, fs, settings, update_check
|
|
24
|
+
from . import __version__, fs, i18n, settings, update_check
|
|
21
25
|
from .backends import plugin_cli
|
|
22
26
|
from .i18n import t
|
|
23
27
|
from .output import use_color
|
|
24
28
|
from .ui import theme
|
|
25
29
|
|
|
26
30
|
DIST = "agent-toggle"
|
|
31
|
+
REPO = "weskao/agent-toggle"
|
|
27
32
|
PLUGIN = "agent-toggle@agent-toggle"
|
|
28
|
-
|
|
29
|
-
UPGRADE = (["pipx", "upgrade", DIST] if "pipx" in Path(sys.prefix).parts
|
|
30
|
-
else ["uv", "tool", "upgrade", DIST])
|
|
33
|
+
UPDATE = [DIST, "update"]
|
|
31
34
|
RELEASE_NOTES = "https://github.com/weskao/agent-toggle/releases/tag/v%s"
|
|
32
35
|
ANSWERS = (update_check.UPDATE_NOW, update_check.SKIP, update_check.SKIP_VERSION)
|
|
33
36
|
|
|
@@ -40,16 +43,51 @@ def _clean(text: str) -> str:
|
|
|
40
43
|
return _CONTROL.sub("", text)
|
|
41
44
|
|
|
42
45
|
|
|
43
|
-
def
|
|
44
|
-
"""
|
|
45
|
-
|
|
46
|
-
|
|
46
|
+
def after_steps() -> list[list[str]]:
|
|
47
|
+
"""Run with the NEW binary once the install is done: the Claude Code plugin when it is
|
|
48
|
+
installed, then the shims."""
|
|
49
|
+
steps: list[list[str]] = []
|
|
50
|
+
# bare "claude": what a person pastes; _run() resolves it, as claude is often off PATH
|
|
47
51
|
if plugin_cli.claude_bin() and any(p["id"] == PLUGIN for p in plugin_cli.list_plugins(lambda _msg: None)):
|
|
48
52
|
steps += [["claude", "plugin", "marketplace", "update", DIST],
|
|
49
53
|
["claude", "plugin", "update", PLUGIN]]
|
|
50
54
|
return [*steps, [DIST, "install-shims"]]
|
|
51
55
|
|
|
52
56
|
|
|
57
|
+
class _LazySteps(Sequence):
|
|
58
|
+
"""after_steps(), computed on first use: update_kit only reads `after` once an install
|
|
59
|
+
will happen, so a failed check / "already the latest" skips `claude plugin list` (0.8 s)."""
|
|
60
|
+
|
|
61
|
+
@cached_property
|
|
62
|
+
def _steps(self) -> list[list[str]]:
|
|
63
|
+
return after_steps()
|
|
64
|
+
|
|
65
|
+
def __len__(self) -> int:
|
|
66
|
+
return len(self._steps)
|
|
67
|
+
|
|
68
|
+
def __getitem__(self, i):
|
|
69
|
+
return self._steps[i]
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def _run(cmd, **kw):
|
|
73
|
+
"""update_kit's subprocess runner: their output stays off stdout and no step may prompt,
|
|
74
|
+
and a step like `install-shims` must not re-check for updates and print the hint."""
|
|
75
|
+
if cmd[0] == "claude":
|
|
76
|
+
cmd = [plugin_cli.claude_bin() or "claude", *cmd[1:]]
|
|
77
|
+
# update_kit passes its own env (no-prompt git vars) for the install step: merge, don't replace
|
|
78
|
+
kw["env"] = {**kw.get("env", os.environ), "AGENT_TOGGLE_UPDATE_CHECK": "0"}
|
|
79
|
+
return subprocess.run(cmd, stdout=sys.stderr, stdin=subprocess.DEVNULL, **kw)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def cmd_update() -> int:
|
|
83
|
+
"""`update` / `--update` and the panel's Update now: install the newest release tag, then
|
|
84
|
+
refresh the plugin and shims. Returns update_kit's exit code."""
|
|
85
|
+
# imported here, like telegram_kit: a checkout run (`python3 agent_toggle.py`) or a stale env lacks it
|
|
86
|
+
import update_kit
|
|
87
|
+
return update_kit.update(app=DIST, repo=REPO, dist=DIST, lang=i18n.LANGUAGE,
|
|
88
|
+
after=_LazySteps(), out=sys.stderr, run=_run)
|
|
89
|
+
|
|
90
|
+
|
|
53
91
|
def cache_path() -> Path:
|
|
54
92
|
return fs.state_dir() / "update-check.json"
|
|
55
93
|
|
|
@@ -78,17 +116,16 @@ def _available(found: update_check.UpdateAvailable) -> str:
|
|
|
78
116
|
|
|
79
117
|
|
|
80
118
|
def hint(found: update_check.UpdateAvailable) -> str:
|
|
81
|
-
"""The `ask` off a terminal (CI, pipes, --json): the headline, then
|
|
119
|
+
"""The `ask` off a terminal (CI, pipes, --json): the headline, then the command to run."""
|
|
82
120
|
print(_available(found), file=sys.stderr)
|
|
83
|
-
|
|
84
|
-
print(" " + " ".join(step), file=sys.stderr)
|
|
121
|
+
print(" " + " ".join(UPDATE), file=sys.stderr)
|
|
85
122
|
return update_check.SKIP
|
|
86
123
|
|
|
87
124
|
|
|
88
125
|
def _lines(found: update_check.UpdateAvailable, selected: int, color: bool,
|
|
89
126
|
g: theme.Glyphs) -> list[str]:
|
|
90
127
|
rows = (
|
|
91
|
-
(t("update.now", "Update now"), " ".join(
|
|
128
|
+
(t("update.now", "Update now"), " ".join(UPDATE)),
|
|
92
129
|
(t("update.skip", "Skip"), t("update.skip_detail", "ask again next run")),
|
|
93
130
|
(t("update.skip_version", "Skip until next version"),
|
|
94
131
|
t("update.skip_version_detail", "ask again once a newer version ships")),
|
|
@@ -197,46 +234,27 @@ def offer(started: update_check.Started | None, *, json_mode: bool = False,
|
|
|
197
234
|
stderr only and never raises, so neither stdout nor the exit code can change."""
|
|
198
235
|
if started is None:
|
|
199
236
|
return None
|
|
200
|
-
# Windows cannot replace the agent-toggle.exe that is running: print the
|
|
237
|
+
# Windows cannot replace the agent-toggle.exe that is running: print the command, run none
|
|
201
238
|
if is_interactive() and not json_mode and not fs.WIN:
|
|
202
239
|
def asker(found):
|
|
203
240
|
return ask(found, color_mode)
|
|
204
241
|
else:
|
|
205
242
|
asker = hint
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
return steps
|
|
216
|
-
answer = update_check.offer(started, asker, cache_path=cache_path(), upgrade=upgrade, run=run)
|
|
243
|
+
# no steps for update_check to run: Update now is cmd_update() (update_kit, newest tag)
|
|
244
|
+
answer = update_check.offer(started, asker, cache_path=cache_path(), upgrade=lambda _found: ())
|
|
245
|
+
if answer == update_check.UPDATE_NOW:
|
|
246
|
+
try:
|
|
247
|
+
failed = cmd_update() != 0
|
|
248
|
+
except Exception: # noqa: BLE001 - an update offer must never fail the command
|
|
249
|
+
failed = True
|
|
250
|
+
if failed:
|
|
251
|
+
answer = update_check.UPGRADE_FAILED
|
|
217
252
|
if answer == update_check.UPGRADE_FAILED:
|
|
218
253
|
try:
|
|
219
254
|
mark = theme.ansi("warning", "⚠" if theme.get_glyphs(sys.stderr).unicode else "!",
|
|
220
255
|
use_color(sys.stderr, color_mode))
|
|
221
256
|
print(mark + " " + t("update.failed", "upgrade did not finish — run it yourself: %s",
|
|
222
|
-
"
|
|
257
|
+
" ".join(UPDATE)), file=sys.stderr)
|
|
223
258
|
except Exception: # noqa: BLE001, S110 - a hint must never fail the command
|
|
224
259
|
pass
|
|
225
260
|
return answer
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
def cmd_update(out) -> None:
|
|
229
|
-
"""`update`: check PyPI now (cache and "skipped" ignored), show what would be updated and
|
|
230
|
-
the commands for it. Runs none of them: the picker's Update now does that."""
|
|
231
|
-
found = update_check.check(DIST, __version__, cache_path=cache_path(), ttl_seconds=0,
|
|
232
|
-
timeout=5.0, ignore_skip=True)
|
|
233
|
-
if found is None:
|
|
234
|
-
out.row(None, "cli", DIST, "update", "ok", f"no newer release found (you have {__version__})",
|
|
235
|
-
current=__version__, latest=None, commands=[])
|
|
236
|
-
return
|
|
237
|
-
steps = [" ".join(s) for s in upgrade_steps()]
|
|
238
|
-
out.row(None, "cli", DIST, "update", "ok", f"{found.current} -> {found.latest}", show=False,
|
|
239
|
-
current=found.current, latest=found.latest, commands=steps)
|
|
240
|
-
out.say(_available(found) + ". Run, in order:")
|
|
241
|
-
for step in steps:
|
|
242
|
-
out.say(" " + step)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agent-toggle
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.16.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.3,>=0.2.1
|
|
28
29
|
Provides-Extra: windows
|
|
29
30
|
Requires-Dist: windows-curses; sys_platform == "win32" and extra == "windows"
|
|
30
31
|
Provides-Extra: telegram
|
|
@@ -40,6 +41,10 @@ rules, plugins (mods included), MCP servers — across Claude Code, Codex, Grok
|
|
|
40
41
|
OpenClaw, Copilot, Vibe, Devin and Antigravity — and show what each one costs at
|
|
41
42
|
session start.
|
|
42
43
|
|
|
44
|
+
It ships in two forms: a **CLI** (`agent-toggle`, all harnesses) and a **Claude Code mod**
|
|
45
|
+
(the `/agent-toggle` pane, claude harness only; see [Claude Code pane mod](#claude-code-pane-mod)).
|
|
46
|
+
Both drive the same toggle engine and state.
|
|
47
|
+
|
|
43
48
|
**Nothing is ever deleted.** Everything is parked and recorded, and `enable`
|
|
44
49
|
puts it back where it came from.
|
|
45
50
|
|
|
@@ -202,7 +207,7 @@ agent-toggle <command> [args] # or: python3 agent_toggle.py <command> [
|
|
|
202
207
|
| `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
208
|
| `list [type]` | what is currently disabled (`--project <dir>` filters to one project) |
|
|
204
209
|
| `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` |
|
|
210
|
+
| `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. Always the newest tag: a dev checkout, a branch or an unmanaged install is replaced by it. Exit `0` updated or already current, `1` the check or install failed (offline, rate limit), `2` neither uv nor pipx is found (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
211
|
| `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
212
|
| `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
213
|
| `enable <type> <name>...` | put them back (`--dry-run` shows the plan; `--project <dir>` likewise) |
|
|
@@ -495,18 +500,17 @@ invalid value in either is ignored with one warning on stderr.
|
|
|
495
500
|
|
|
496
501
|
On every invocation (unless disabled) agent-toggle checks PyPI for a newer release. It starts
|
|
497
502
|
before the command and is offered after it, on every exit path; it overlaps the command and waits at most 0.8 s afterwards.
|
|
503
|
+
`update` and `completion` skip it.
|
|
498
504
|
|
|
499
505
|
- **On a terminal** (stdin and stderr are TTYs, no `--json`): a panel on stderr, "agent-toggle X
|
|
500
506
|
is available (you have Y)", with `Update now`, `Skip` and `Skip until next version`, a release
|
|
501
|
-
notes link, and `↑` `↓` `Enter` `q`. `Update now` runs
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
`claude plugin update agent-toggle@agent-toggle`, then `agent-toggle install-shims`. A failure
|
|
505
|
-
gives a yellow warning listing the commands to run yourself.
|
|
507
|
+
notes link, and `↑` `↓` `Enter` `q`. `Update now` runs [`agent-toggle update`](#update) (the
|
|
508
|
+
newest release tag, then the Claude Code plugin and the shims). A failure gives a yellow warning
|
|
509
|
+
naming the command to run yourself.
|
|
506
510
|
- **Windows**: a running `agent-toggle.exe` cannot be replaced, so there is no `Update now`; the
|
|
507
|
-
|
|
511
|
+
command is printed instead (as below), to run once agent-toggle has exited.
|
|
508
512
|
- **Off a terminal** (or `--json`): a stderr line, `agent-toggle X is available (you have Y)`,
|
|
509
|
-
then
|
|
513
|
+
then ` agent-toggle update`.
|
|
510
514
|
- It never changes the exit code or stdout, so `--json` output stays one document.
|
|
511
515
|
|
|
512
516
|
It is one `GET https://pypi.org/pypi/agent-toggle/json` on a background thread with a 0.8 s
|
|
@@ -515,6 +519,28 @@ normal HTTP request with the User-Agent `agent-toggle-update-check`. See `SECURI
|
|
|
515
519
|
for the hardening. To turn it off, set `AGENT_TOGGLE_UPDATE_CHECK=0` or the `update_check` setting
|
|
516
520
|
to off (the settings menu's "Check for updates").
|
|
517
521
|
|
|
522
|
+
## Update
|
|
523
|
+
|
|
524
|
+
`agent-toggle update` (or `agent-toggle --update`) is a self-update through
|
|
525
|
+
update-kit (a small stdlib-only helper library): it asks the repository for its newest `vX.Y.Z`
|
|
526
|
+
tag (`git ls-remote --tags`) and always installs that tag with
|
|
527
|
+
`uv tool install --force --no-sources git+<repo>@<tag>` (`pipx install --force` for a pipx install).
|
|
528
|
+
A dev checkout, a branch or commit install, or an unmanaged install is replaced by the tag too
|
|
529
|
+
(with uv, else pipx); only an install made from exactly that tag is already up to date.
|
|
530
|
+
It then runs, with the new binary and in order: when the Claude Code plugin is installed,
|
|
531
|
+
`claude plugin marketplace update agent-toggle` and `claude plugin update agent-toggle@agent-toggle`,
|
|
532
|
+
then `agent-toggle install-shims`. A failing step prints a warning and makes the exit code `1`.
|
|
533
|
+
It never prompts and writes to stderr only.
|
|
534
|
+
|
|
535
|
+
| Exit | Meaning |
|
|
536
|
+
|---|---|
|
|
537
|
+
| `0` | updated, or already up to date |
|
|
538
|
+
| `1` | could not check (offline, rate limit) or the install failed |
|
|
539
|
+
| `2` | neither uv nor pipx is found (the manual command is printed) |
|
|
540
|
+
|
|
541
|
+
On Windows a running `agent-toggle.exe` cannot be replaced, so the install runs detached after
|
|
542
|
+
agent-toggle exits (log in `%USERPROFILE%\.update-kit\`).
|
|
543
|
+
|
|
518
544
|
## Help
|
|
519
545
|
|
|
520
546
|
```sh
|
|
@@ -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.2.1,<0.3"]
|
|
31
31
|
|
|
32
32
|
[project.urls]
|
|
33
33
|
Homepage = "https://github.com/weskao/agent-toggle"
|