agent-toggle 0.13.0__tar.gz → 0.14.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.13.0 → agent_toggle-0.14.0}/PKG-INFO +61 -29
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/README.md +60 -28
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/agent_toggle/__init__.py +1 -1
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/agent_toggle/backends/mcp_json.py +6 -4
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/agent_toggle/backends/plugin_cli.py +33 -3
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/agent_toggle/locales/zh_tw_picker.py +12 -7
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/agent_toggle/mechanisms.py +58 -11
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/agent_toggle/ui/menu.py +17 -1
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/agent_toggle/ui/picker.py +240 -54
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/agent_toggle/ui/theme.py +4 -3
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/agent_toggle.egg-info/PKG-INFO +61 -29
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/tests/test_backends.py +24 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/tests/test_crash.py +14 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/tests/test_mechanisms.py +94 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/tests/test_menu.py +9 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/tests/test_mods.py +28 -17
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/tests/test_picker.py +294 -76
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/tests/test_project.py +17 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/tests/test_same_name.py +2 -2
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/tests/test_theme.py +2 -2
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/LICENSE +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/agent_toggle/__main__.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/agent_toggle/backends/__init__.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/agent_toggle/backends/flag_json.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/agent_toggle/backends/mcp_toml.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/agent_toggle/cli.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/agent_toggle/companions.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/agent_toggle/completions.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/agent_toggle/config.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/agent_toggle/cost.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/agent_toggle/doctor.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/agent_toggle/fs.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/agent_toggle/harnesses.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/agent_toggle/help.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/agent_toggle/i18n.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/agent_toggle/locales/__init__.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/agent_toggle/locales/zh_tw_cli.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/agent_toggle/locales/zh_tw_common.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/agent_toggle/locales/zh_tw_config.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/agent_toggle/ops.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/agent_toggle/output.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/agent_toggle/profiles.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/agent_toggle/settings.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/agent_toggle/shims/claude.md.tmpl +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/agent_toggle/shims/generic.md.tmpl +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/agent_toggle/spinner.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/agent_toggle/store.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/agent_toggle/toml_check.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/agent_toggle/ui/__init__.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/agent_toggle/ui/config_menu.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/agent_toggle/ui/logo.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/agent_toggle/ui/model.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/agent_toggle/undo.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/agent_toggle/update_check.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/agent_toggle/update_prompt.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/agent_toggle.egg-info/SOURCES.txt +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/agent_toggle.egg-info/dependency_links.txt +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/agent_toggle.egg-info/entry_points.txt +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/agent_toggle.egg-info/requires.txt +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/agent_toggle.egg-info/top_level.txt +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/pyproject.toml +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/setup.cfg +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/tests/test_alias.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/tests/test_all_type.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/tests/test_cli.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/tests/test_cli_surface.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/tests/test_color.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/tests/test_companions.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/tests/test_completions.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/tests/test_config.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/tests/test_config_menu.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/tests/test_conformance.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/tests/test_containment.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/tests/test_cost.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/tests/test_doctor.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/tests/test_encoding.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/tests/test_fs.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/tests/test_harnesses.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/tests/test_help.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/tests/test_i18n.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/tests/test_install.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/tests/test_logo.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/tests/test_platform.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/tests/test_profiles.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/tests/test_safety.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/tests/test_secret_audit.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/tests/test_settings.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/tests/test_store.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/tests/test_undo.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.0}/tests/test_update_check.py +0 -0
- {agent_toggle-0.13.0 → agent_toggle-0.14.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.14.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
|
|
@@ -69,7 +69,7 @@ queues the matching reload ([Claude Code pane mod](#claude-code-pane-mod)).
|
|
|
69
69
|
|
|
70
70
|
| target | native mechanism | the gap |
|
|
71
71
|
|---|---|---|
|
|
72
|
-
| plugin | `claude plugin disable/enable` |
|
|
72
|
+
| plugin | `claude plugin disable/enable` | without `-s` the scope follows the current dir, so a project plugin enabled from elsewhere stays off; this tool pins the install's scope and project |
|
|
73
73
|
| skill | none | moving files by hand hits the rename trap below |
|
|
74
74
|
| agent | none | same |
|
|
75
75
|
| command | none | same, plus nested `group/name.md` paths get flattened |
|
|
@@ -316,7 +316,7 @@ agent-toggle # same, on a terminal; elsewhere prints help and exits
|
|
|
316
316
|
● delta codex 10 ▏ │ cost 0 now; ~300 tok if restored
|
|
317
317
|
│ since 2026-09-19 10:00:00
|
|
318
318
|
5 of 5 shown · 2/5
|
|
319
|
-
|
|
319
|
+
Tab toggle Enter apply Esc cancel ? help / search ←→ harness t type s sort p profile a all
|
|
320
320
|
```
|
|
321
321
|
|
|
322
322
|
What is on screen:
|
|
@@ -344,38 +344,54 @@ What is on screen:
|
|
|
344
344
|
|
|
345
345
|
| key | action |
|
|
346
346
|
|---|---|
|
|
347
|
-
| `
|
|
348
|
-
| `
|
|
347
|
+
| `Tab` | toggle the highlighted row (live / parked) and stay on it, including while searching |
|
|
348
|
+
| `Space` | enter a space in the search (separates search terms) |
|
|
349
349
|
| `Enter` | apply every staged change (with `--dry-run`: show the plan) |
|
|
350
|
-
| `Esc`
|
|
350
|
+
| `Esc` | leave; if changes are staged, review them in a centered Save changes? dialog |
|
|
351
|
+
| `Ctrl-C` | discard staged changes and leave |
|
|
351
352
|
| `↑` `↓` `PgUp` `PgDn` `Home` `End`, `Ctrl-P` / `Ctrl-N` | move |
|
|
352
|
-
| `/` | start a search; any
|
|
353
|
+
| `/` | start a search; any letter or digit starts one too. Terms are ANDed, case-insensitive, and match the harness/type/name, the group (`mod` or `mods` finds every mod) and the path; when nothing matches, letters-in-order (fuzzy) is tried: `ctxmd` finds `context-md`, and the bar says `≈ fuzzy match` |
|
|
353
354
|
| `Backspace` / `Ctrl-U` | delete one character / clear the filter |
|
|
354
|
-
| `←` `→` | switch harness tab (also while typing a filter)
|
|
355
|
-
| `
|
|
356
|
-
| `
|
|
357
|
-
| `
|
|
355
|
+
| `←` `→` | switch harness tab (also while typing a filter) |
|
|
356
|
+
| `Ctrl-T` | cycle the type filter |
|
|
357
|
+
| `Ctrl-S` | cycle sort: name, cost (biggest first); applies within each type group |
|
|
358
|
+
| `Ctrl-O` | profiles: stage a saved one, or save the live state (see below) |
|
|
358
359
|
| `?` | show the key list |
|
|
359
|
-
| `
|
|
360
|
-
| `
|
|
360
|
+
| `Ctrl-A` | toggle every visible row |
|
|
361
|
+
| `Ctrl-E` | toggle every row on this row's harness with the same name, of any type (skill, command, MCP, ...), shown or filtered out; like `disable all <name>` |
|
|
361
362
|
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
363
|
+
Commands are `Ctrl` chords, so every letter and digit types into the search, and the chords
|
|
364
|
+
work while a filter is active too. `?` and `/` act only while no filter is active. The picker
|
|
365
|
+
reads keys in raw mode, so `Ctrl-S`, `Ctrl-T` and `Ctrl-O` reach it instead of the terminal
|
|
366
|
+
(flow control, `SIGINFO`, discard).
|
|
365
367
|
|
|
366
368
|
The start view (sort, harness tab, type filter) comes from the `picker_sort`, `picker_harness`
|
|
367
369
|
and `picker_type` [settings](#settings--config-menu). A profile skips harnesses that are hidden
|
|
368
370
|
and counts those items as `hidden by settings`; `ui --harness <name>` shows that harness even
|
|
369
371
|
when it is switched off.
|
|
370
372
|
|
|
371
|
-
`
|
|
373
|
+
`Ctrl-O` opens a prompt over the list of saved profiles: type a number or name (or
|
|
372
374
|
`apply <name>`) and Enter to **stage** that profile's changes (only the items it
|
|
373
375
|
mentions; ones this machine lacks are skipped), then Enter in the picker applies
|
|
374
376
|
them like any other change, so `ui --dry-run` previews a profile and a stray
|
|
375
|
-
`
|
|
377
|
+
`Ctrl-O` changes nothing. `save <name>` writes the live state (not your staged changes) as
|
|
376
378
|
a profile, with the same name rules and project scope as `profile save`; it is
|
|
377
379
|
off under `--dry-run`. Esc closes the prompt.
|
|
378
380
|
|
|
381
|
+
The exit dialog lists all staged changes, including rows hidden by a filter. Choose
|
|
382
|
+
**Yes** to apply and leave, or **No** to discard and leave. Use Left/Right
|
|
383
|
+
to select, Enter to confirm, Y/N shortcuts, or click either button (hovering selects it and underlines it). Esc in the
|
|
384
|
+
dialog returns to editing. Up/Down, PgUp/PgDn, Home/End and the mouse wheel scroll
|
|
385
|
+
a long change list. Its height is capped at 80% of the terminal (up to 24 lines,
|
|
386
|
+
with a compact layout on tiny terminals); the confirmation buttons stay visible.
|
|
387
|
+
Up/Down and the mouse wheel move the selected row, just like the main picker;
|
|
388
|
+
the list scrolls when the selection reaches its edge. Tab or a click toggles the
|
|
389
|
+
row's staged enabled/disabled state. The picker stays visible behind the opaque
|
|
390
|
+
dialog; both are painted together in one refresh to prevent background flashes.
|
|
391
|
+
Reverted rows stay in the review so they can be toggled again; Yes applies only
|
|
392
|
+
the remaining changes. The dialog follows the selected language and color mode;
|
|
393
|
+
with `--dry-run`, Yes only shows the plan.
|
|
394
|
+
|
|
379
395
|
Nothing happens while the picker is open. Changes are staged, the screen is
|
|
380
396
|
torn down, and only then do the real operations run, so their output (which
|
|
381
397
|
companion files moved, which were kept because they are shared) is readable
|
|
@@ -390,7 +406,8 @@ numbers (`1 3 5-7`) to tick or untick, `n <number>` to toggle every type with th
|
|
|
390
406
|
row's name, `/text` to filter (`/` alone clears it),
|
|
391
407
|
`s` / `h` / `t` to sort and cycle the harness and type filters, `p` to list profiles,
|
|
392
408
|
`p <number|name>` to stage one and `p save <name>` to save the live state, `a` to
|
|
393
|
-
apply, `q`
|
|
409
|
+
apply, `q` to review staged changes with a `y/n` save prompt (no changes: exit
|
|
410
|
+
immediately). End of input discards changes.
|
|
394
411
|
|
|
395
412
|
### Mods
|
|
396
413
|
|
|
@@ -408,7 +425,7 @@ plugin: it ships skills, commands, agents, MCP servers or hooks and draws nothin
|
|
|
408
425
|
grep -l modules ~/.claude/plugins/cache/*/*/*/hooks/hooks.json
|
|
409
426
|
```
|
|
410
427
|
|
|
411
|
-
- The picker lists mods under **Mods**, right after Plugins. `
|
|
428
|
+
- The picker lists mods under **Mods**, right after Plugins. `Ctrl-T` cycles to it, the
|
|
412
429
|
`picker_type` setting can open on it, and a search for `mod` or `mods` finds every mod.
|
|
413
430
|
The detail pane shows its type as `mod (plugin)`.
|
|
414
431
|
- A mod is still a plugin everywhere else: it toggles through `claude plugin
|
|
@@ -534,7 +551,9 @@ logo, centred, when the window is tall enough to fit the whole menu beside it; t
|
|
|
534
551
|
| agy | `~/.gemini/config` | ✓ | — | — | — | — | ✓ `mcp_config.json` |
|
|
535
552
|
|
|
536
553
|
Per-harness locations, mechanisms and the harness versions this was checked
|
|
537
|
-
against are in [docs/harnesses.md](docs/harnesses.md).
|
|
554
|
+
against are in [docs/harnesses.md](docs/harnesses.md). What `disable` and `enable`
|
|
555
|
+
change on disk for each type, with example live, parked and backup paths, is in
|
|
556
|
+
[docs/toggle-paths.md](docs/toggle-paths.md).
|
|
538
557
|
|
|
539
558
|
**Homes per OS.** Every `~` above is Python's `Path.home()`: `$HOME` on macOS and
|
|
540
559
|
Linux, `%USERPROFILE%` on Windows (so `~/.claude` is `C:\Users\<you>\.claude`).
|
|
@@ -551,8 +570,13 @@ Plugin ids are passed to `claude plugin ...`, which on Windows runs through
|
|
|
551
570
|
|
|
552
571
|
Copilot's `config.json` is machine-managed and never edited by this tool; Copilot
|
|
553
572
|
plugins are not yet supported. `claude` plugins are toggled through `claude
|
|
554
|
-
plugin enable/disable
|
|
555
|
-
|
|
573
|
+
plugin enable/disable -s <scope>`. The scope comes from the plugin's one install in
|
|
574
|
+
`~/.claude/plugins/installed_plugins.json`, and a project or local install runs in its
|
|
575
|
+
project dir, so a disable and an enable from different directories still hit the same
|
|
576
|
+
setting. With several installs of one id, the CLI picks the scope from the current dir;
|
|
577
|
+
`enable` then runs in the dir the disable ran in. Details are in
|
|
578
|
+
[docs/toggle-paths.md](docs/toggle-paths.md#plugins). `openclaw` plugins are toggled
|
|
579
|
+
through a config flag (see [Assumed formats](#assumed-formats)). Codex has no plugin CLI this tool can drive: `disable
|
|
556
580
|
plugin x --harness codex` exits `4`, which is why the matrix leaves it unchecked.
|
|
557
581
|
|
|
558
582
|
Flag items (openclaw plugins and flagged skills, opencode mcp) are toggled with
|
|
@@ -623,6 +647,11 @@ visible rather than silent.
|
|
|
623
647
|
MCP changes need a **new session** to take effect, except in a Claude Code session running the
|
|
624
648
|
agent-toggle mod, which runs `/mcp disable|enable <name>` for you (see the mod section).
|
|
625
649
|
|
|
650
|
+
`/mcp disable <name>` also lists the server in that project's `disabledMcpServers` in
|
|
651
|
+
`~/.claude.json`. Left there, a restored server would stay off in that project, so `enable`
|
|
652
|
+
removes the name again: from every project for a user- or local-scope server, and only from
|
|
653
|
+
that repo and the dirs inside it for a `--project` `.mcp.json` server.
|
|
654
|
+
|
|
626
655
|
### Claude MCP scopes
|
|
627
656
|
|
|
628
657
|
Both scopes stored in `~/.claude.json` are togglable, and the scope round-trips:
|
|
@@ -977,20 +1006,20 @@ claude --plugin-dir ./mod # then run /agent-toggle inside Claude
|
|
|
977
1006
|
and the first and last list lines count the rows out of view (`↑ 4`, `↓ 12`).
|
|
978
1007
|
- The mouse wheel over the list moves the cursor, as in the terminal picker; no click needed.
|
|
979
1008
|
- Click the list once so it takes keys (Esc hands the keyboard back to the prompt). Then `↑` `↓`
|
|
980
|
-
`PgUp` `PgDn` `Home` `End` (also `Ctrl-P` / `Ctrl-N`) move; `
|
|
981
|
-
|
|
982
|
-
`type/name` and the group, letters-in-order if nothing matches;
|
|
983
|
-
`
|
|
1009
|
+
`PgUp` `PgDn` `Home` `End` (also `Ctrl-P` / `Ctrl-N`) move; `Tab` toggles the row
|
|
1010
|
+
and stays on it, including while searching; `/` or any letter starts a search (terms ANDed over
|
|
1011
|
+
`type/name` and the group, letters-in-order if nothing matches; `Space` separates terms);
|
|
1012
|
+
`Ctrl-S` sorts by name or cost; `Ctrl-E` toggles every type with this row's name (skill, command, MCP,
|
|
984
1013
|
...), like `disable all <name>`; `Ctrl-U` clears the search. A click moves the cursor.
|
|
985
1014
|
- A toggle applies at once (no staging, no Enter to apply); the toast names the target and the state
|
|
986
1015
|
with an emoji and a bracketed tag (no colour codes, so nothing garbles; on the Linux console and the
|
|
987
1016
|
legacy Windows console, where emoji draw as boxes, the tag alone): `✅ [ENABLED] skill: foo`, `⛔ [DISABLED] mod: bar (/reload-plugins)`,
|
|
988
|
-
`⛔ [DISABLED] rule: baz (takes effect in a new session)`, `⛔ [DISABLED] all: foo` after `
|
|
1017
|
+
`⛔ [DISABLED] rule: baz (takes effect in a new session)`, `⛔ [DISABLED] all: foo` after `Ctrl-E`, or `❌ [FAILED] disable skill: foo - <error>`.
|
|
989
1018
|
The row flips the moment you press (and flips back
|
|
990
1019
|
if the CLI fails); the list reloads in the background. While a toggle runs, further keys are ignored.
|
|
991
1020
|
- Opening the pane shows the same braille spinner and `Loading resources…` as `agent-toggle ui`
|
|
992
1021
|
until the list arrives, and a spinner beside `working…` while a toggle runs.
|
|
993
|
-
- Not in the pane: harness tabs (claude only), and the `
|
|
1022
|
+
- Not in the pane: harness tabs (claude only), and the `Ctrl-T` `Ctrl-O` `Ctrl-A` keys. Where Claude draws no
|
|
994
1023
|
such pane (the mobile app, VS Code) it is a plain list of buttons instead.
|
|
995
1024
|
- `/agent-toggle <command> ...` with `disable`, `enable`,
|
|
996
1025
|
`undo`, `list`, `status`, `cost` or `doctor` runs the CLI instead of opening the pane and prints
|
|
@@ -1001,6 +1030,9 @@ claude --plugin-dir ./mod # then run /agent-toggle inside Claude
|
|
|
1001
1030
|
`/reload-plugins`, an MCP server `/mcp disable|enable <name>`. The toast names it, e.g.
|
|
1002
1031
|
`⛔ [DISABLED] skill: foo (/reload-skills)`. Agents and rules have no reload and still say
|
|
1003
1032
|
`takes effect in a new session`. If Claude refuses a queued command, a toast says so.
|
|
1033
|
+
`/reload-skills` and `/reload-plugins` only re-read what is on disk. `/mcp disable` also
|
|
1034
|
+
leaves the per-project mark that `enable` clears (see
|
|
1035
|
+
[MCP backups are verbatim](#mcp-backups-are-verbatim)).
|
|
1004
1036
|
- `agent-toggle ui` in another terminal applies on Enter and writes the Claude rows it changed to
|
|
1005
1037
|
`~/.agent-toggle/reload.json`. Every open session running the mod checks that file's mtime every
|
|
1006
1038
|
5 s (one `stat`) and queues the same reloads, toasting `agent-toggle ui: /reload-skills`. A file
|
|
@@ -36,7 +36,7 @@ queues the matching reload ([Claude Code pane mod](#claude-code-pane-mod)).
|
|
|
36
36
|
|
|
37
37
|
| target | native mechanism | the gap |
|
|
38
38
|
|---|---|---|
|
|
39
|
-
| plugin | `claude plugin disable/enable` |
|
|
39
|
+
| plugin | `claude plugin disable/enable` | without `-s` the scope follows the current dir, so a project plugin enabled from elsewhere stays off; this tool pins the install's scope and project |
|
|
40
40
|
| skill | none | moving files by hand hits the rename trap below |
|
|
41
41
|
| agent | none | same |
|
|
42
42
|
| command | none | same, plus nested `group/name.md` paths get flattened |
|
|
@@ -283,7 +283,7 @@ agent-toggle # same, on a terminal; elsewhere prints help and exits
|
|
|
283
283
|
● delta codex 10 ▏ │ cost 0 now; ~300 tok if restored
|
|
284
284
|
│ since 2026-09-19 10:00:00
|
|
285
285
|
5 of 5 shown · 2/5
|
|
286
|
-
|
|
286
|
+
Tab toggle Enter apply Esc cancel ? help / search ←→ harness t type s sort p profile a all
|
|
287
287
|
```
|
|
288
288
|
|
|
289
289
|
What is on screen:
|
|
@@ -311,38 +311,54 @@ What is on screen:
|
|
|
311
311
|
|
|
312
312
|
| key | action |
|
|
313
313
|
|---|---|
|
|
314
|
-
| `
|
|
315
|
-
| `
|
|
314
|
+
| `Tab` | toggle the highlighted row (live / parked) and stay on it, including while searching |
|
|
315
|
+
| `Space` | enter a space in the search (separates search terms) |
|
|
316
316
|
| `Enter` | apply every staged change (with `--dry-run`: show the plan) |
|
|
317
|
-
| `Esc`
|
|
317
|
+
| `Esc` | leave; if changes are staged, review them in a centered Save changes? dialog |
|
|
318
|
+
| `Ctrl-C` | discard staged changes and leave |
|
|
318
319
|
| `↑` `↓` `PgUp` `PgDn` `Home` `End`, `Ctrl-P` / `Ctrl-N` | move |
|
|
319
|
-
| `/` | start a search; any
|
|
320
|
+
| `/` | start a search; any letter or digit starts one too. Terms are ANDed, case-insensitive, and match the harness/type/name, the group (`mod` or `mods` finds every mod) and the path; when nothing matches, letters-in-order (fuzzy) is tried: `ctxmd` finds `context-md`, and the bar says `≈ fuzzy match` |
|
|
320
321
|
| `Backspace` / `Ctrl-U` | delete one character / clear the filter |
|
|
321
|
-
| `←` `→` | switch harness tab (also while typing a filter)
|
|
322
|
-
| `
|
|
323
|
-
| `
|
|
324
|
-
| `
|
|
322
|
+
| `←` `→` | switch harness tab (also while typing a filter) |
|
|
323
|
+
| `Ctrl-T` | cycle the type filter |
|
|
324
|
+
| `Ctrl-S` | cycle sort: name, cost (biggest first); applies within each type group |
|
|
325
|
+
| `Ctrl-O` | profiles: stage a saved one, or save the live state (see below) |
|
|
325
326
|
| `?` | show the key list |
|
|
326
|
-
| `
|
|
327
|
-
| `
|
|
327
|
+
| `Ctrl-A` | toggle every visible row |
|
|
328
|
+
| `Ctrl-E` | toggle every row on this row's harness with the same name, of any type (skill, command, MCP, ...), shown or filtered out; like `disable all <name>` |
|
|
328
329
|
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
330
|
+
Commands are `Ctrl` chords, so every letter and digit types into the search, and the chords
|
|
331
|
+
work while a filter is active too. `?` and `/` act only while no filter is active. The picker
|
|
332
|
+
reads keys in raw mode, so `Ctrl-S`, `Ctrl-T` and `Ctrl-O` reach it instead of the terminal
|
|
333
|
+
(flow control, `SIGINFO`, discard).
|
|
332
334
|
|
|
333
335
|
The start view (sort, harness tab, type filter) comes from the `picker_sort`, `picker_harness`
|
|
334
336
|
and `picker_type` [settings](#settings--config-menu). A profile skips harnesses that are hidden
|
|
335
337
|
and counts those items as `hidden by settings`; `ui --harness <name>` shows that harness even
|
|
336
338
|
when it is switched off.
|
|
337
339
|
|
|
338
|
-
`
|
|
340
|
+
`Ctrl-O` opens a prompt over the list of saved profiles: type a number or name (or
|
|
339
341
|
`apply <name>`) and Enter to **stage** that profile's changes (only the items it
|
|
340
342
|
mentions; ones this machine lacks are skipped), then Enter in the picker applies
|
|
341
343
|
them like any other change, so `ui --dry-run` previews a profile and a stray
|
|
342
|
-
`
|
|
344
|
+
`Ctrl-O` changes nothing. `save <name>` writes the live state (not your staged changes) as
|
|
343
345
|
a profile, with the same name rules and project scope as `profile save`; it is
|
|
344
346
|
off under `--dry-run`. Esc closes the prompt.
|
|
345
347
|
|
|
348
|
+
The exit dialog lists all staged changes, including rows hidden by a filter. Choose
|
|
349
|
+
**Yes** to apply and leave, or **No** to discard and leave. Use Left/Right
|
|
350
|
+
to select, Enter to confirm, Y/N shortcuts, or click either button (hovering selects it and underlines it). Esc in the
|
|
351
|
+
dialog returns to editing. Up/Down, PgUp/PgDn, Home/End and the mouse wheel scroll
|
|
352
|
+
a long change list. Its height is capped at 80% of the terminal (up to 24 lines,
|
|
353
|
+
with a compact layout on tiny terminals); the confirmation buttons stay visible.
|
|
354
|
+
Up/Down and the mouse wheel move the selected row, just like the main picker;
|
|
355
|
+
the list scrolls when the selection reaches its edge. Tab or a click toggles the
|
|
356
|
+
row's staged enabled/disabled state. The picker stays visible behind the opaque
|
|
357
|
+
dialog; both are painted together in one refresh to prevent background flashes.
|
|
358
|
+
Reverted rows stay in the review so they can be toggled again; Yes applies only
|
|
359
|
+
the remaining changes. The dialog follows the selected language and color mode;
|
|
360
|
+
with `--dry-run`, Yes only shows the plan.
|
|
361
|
+
|
|
346
362
|
Nothing happens while the picker is open. Changes are staged, the screen is
|
|
347
363
|
torn down, and only then do the real operations run, so their output (which
|
|
348
364
|
companion files moved, which were kept because they are shared) is readable
|
|
@@ -357,7 +373,8 @@ numbers (`1 3 5-7`) to tick or untick, `n <number>` to toggle every type with th
|
|
|
357
373
|
row's name, `/text` to filter (`/` alone clears it),
|
|
358
374
|
`s` / `h` / `t` to sort and cycle the harness and type filters, `p` to list profiles,
|
|
359
375
|
`p <number|name>` to stage one and `p save <name>` to save the live state, `a` to
|
|
360
|
-
apply, `q`
|
|
376
|
+
apply, `q` to review staged changes with a `y/n` save prompt (no changes: exit
|
|
377
|
+
immediately). End of input discards changes.
|
|
361
378
|
|
|
362
379
|
### Mods
|
|
363
380
|
|
|
@@ -375,7 +392,7 @@ plugin: it ships skills, commands, agents, MCP servers or hooks and draws nothin
|
|
|
375
392
|
grep -l modules ~/.claude/plugins/cache/*/*/*/hooks/hooks.json
|
|
376
393
|
```
|
|
377
394
|
|
|
378
|
-
- The picker lists mods under **Mods**, right after Plugins. `
|
|
395
|
+
- The picker lists mods under **Mods**, right after Plugins. `Ctrl-T` cycles to it, the
|
|
379
396
|
`picker_type` setting can open on it, and a search for `mod` or `mods` finds every mod.
|
|
380
397
|
The detail pane shows its type as `mod (plugin)`.
|
|
381
398
|
- A mod is still a plugin everywhere else: it toggles through `claude plugin
|
|
@@ -501,7 +518,9 @@ logo, centred, when the window is tall enough to fit the whole menu beside it; t
|
|
|
501
518
|
| agy | `~/.gemini/config` | ✓ | — | — | — | — | ✓ `mcp_config.json` |
|
|
502
519
|
|
|
503
520
|
Per-harness locations, mechanisms and the harness versions this was checked
|
|
504
|
-
against are in [docs/harnesses.md](docs/harnesses.md).
|
|
521
|
+
against are in [docs/harnesses.md](docs/harnesses.md). What `disable` and `enable`
|
|
522
|
+
change on disk for each type, with example live, parked and backup paths, is in
|
|
523
|
+
[docs/toggle-paths.md](docs/toggle-paths.md).
|
|
505
524
|
|
|
506
525
|
**Homes per OS.** Every `~` above is Python's `Path.home()`: `$HOME` on macOS and
|
|
507
526
|
Linux, `%USERPROFILE%` on Windows (so `~/.claude` is `C:\Users\<you>\.claude`).
|
|
@@ -518,8 +537,13 @@ Plugin ids are passed to `claude plugin ...`, which on Windows runs through
|
|
|
518
537
|
|
|
519
538
|
Copilot's `config.json` is machine-managed and never edited by this tool; Copilot
|
|
520
539
|
plugins are not yet supported. `claude` plugins are toggled through `claude
|
|
521
|
-
plugin enable/disable
|
|
522
|
-
|
|
540
|
+
plugin enable/disable -s <scope>`. The scope comes from the plugin's one install in
|
|
541
|
+
`~/.claude/plugins/installed_plugins.json`, and a project or local install runs in its
|
|
542
|
+
project dir, so a disable and an enable from different directories still hit the same
|
|
543
|
+
setting. With several installs of one id, the CLI picks the scope from the current dir;
|
|
544
|
+
`enable` then runs in the dir the disable ran in. Details are in
|
|
545
|
+
[docs/toggle-paths.md](docs/toggle-paths.md#plugins). `openclaw` plugins are toggled
|
|
546
|
+
through a config flag (see [Assumed formats](#assumed-formats)). Codex has no plugin CLI this tool can drive: `disable
|
|
523
547
|
plugin x --harness codex` exits `4`, which is why the matrix leaves it unchecked.
|
|
524
548
|
|
|
525
549
|
Flag items (openclaw plugins and flagged skills, opencode mcp) are toggled with
|
|
@@ -590,6 +614,11 @@ visible rather than silent.
|
|
|
590
614
|
MCP changes need a **new session** to take effect, except in a Claude Code session running the
|
|
591
615
|
agent-toggle mod, which runs `/mcp disable|enable <name>` for you (see the mod section).
|
|
592
616
|
|
|
617
|
+
`/mcp disable <name>` also lists the server in that project's `disabledMcpServers` in
|
|
618
|
+
`~/.claude.json`. Left there, a restored server would stay off in that project, so `enable`
|
|
619
|
+
removes the name again: from every project for a user- or local-scope server, and only from
|
|
620
|
+
that repo and the dirs inside it for a `--project` `.mcp.json` server.
|
|
621
|
+
|
|
593
622
|
### Claude MCP scopes
|
|
594
623
|
|
|
595
624
|
Both scopes stored in `~/.claude.json` are togglable, and the scope round-trips:
|
|
@@ -944,20 +973,20 @@ claude --plugin-dir ./mod # then run /agent-toggle inside Claude
|
|
|
944
973
|
and the first and last list lines count the rows out of view (`↑ 4`, `↓ 12`).
|
|
945
974
|
- The mouse wheel over the list moves the cursor, as in the terminal picker; no click needed.
|
|
946
975
|
- Click the list once so it takes keys (Esc hands the keyboard back to the prompt). Then `↑` `↓`
|
|
947
|
-
`PgUp` `PgDn` `Home` `End` (also `Ctrl-P` / `Ctrl-N`) move; `
|
|
948
|
-
|
|
949
|
-
`type/name` and the group, letters-in-order if nothing matches;
|
|
950
|
-
`
|
|
976
|
+
`PgUp` `PgDn` `Home` `End` (also `Ctrl-P` / `Ctrl-N`) move; `Tab` toggles the row
|
|
977
|
+
and stays on it, including while searching; `/` or any letter starts a search (terms ANDed over
|
|
978
|
+
`type/name` and the group, letters-in-order if nothing matches; `Space` separates terms);
|
|
979
|
+
`Ctrl-S` sorts by name or cost; `Ctrl-E` toggles every type with this row's name (skill, command, MCP,
|
|
951
980
|
...), like `disable all <name>`; `Ctrl-U` clears the search. A click moves the cursor.
|
|
952
981
|
- A toggle applies at once (no staging, no Enter to apply); the toast names the target and the state
|
|
953
982
|
with an emoji and a bracketed tag (no colour codes, so nothing garbles; on the Linux console and the
|
|
954
983
|
legacy Windows console, where emoji draw as boxes, the tag alone): `✅ [ENABLED] skill: foo`, `⛔ [DISABLED] mod: bar (/reload-plugins)`,
|
|
955
|
-
`⛔ [DISABLED] rule: baz (takes effect in a new session)`, `⛔ [DISABLED] all: foo` after `
|
|
984
|
+
`⛔ [DISABLED] rule: baz (takes effect in a new session)`, `⛔ [DISABLED] all: foo` after `Ctrl-E`, or `❌ [FAILED] disable skill: foo - <error>`.
|
|
956
985
|
The row flips the moment you press (and flips back
|
|
957
986
|
if the CLI fails); the list reloads in the background. While a toggle runs, further keys are ignored.
|
|
958
987
|
- Opening the pane shows the same braille spinner and `Loading resources…` as `agent-toggle ui`
|
|
959
988
|
until the list arrives, and a spinner beside `working…` while a toggle runs.
|
|
960
|
-
- Not in the pane: harness tabs (claude only), and the `
|
|
989
|
+
- Not in the pane: harness tabs (claude only), and the `Ctrl-T` `Ctrl-O` `Ctrl-A` keys. Where Claude draws no
|
|
961
990
|
such pane (the mobile app, VS Code) it is a plain list of buttons instead.
|
|
962
991
|
- `/agent-toggle <command> ...` with `disable`, `enable`,
|
|
963
992
|
`undo`, `list`, `status`, `cost` or `doctor` runs the CLI instead of opening the pane and prints
|
|
@@ -968,6 +997,9 @@ claude --plugin-dir ./mod # then run /agent-toggle inside Claude
|
|
|
968
997
|
`/reload-plugins`, an MCP server `/mcp disable|enable <name>`. The toast names it, e.g.
|
|
969
998
|
`⛔ [DISABLED] skill: foo (/reload-skills)`. Agents and rules have no reload and still say
|
|
970
999
|
`takes effect in a new session`. If Claude refuses a queued command, a toast says so.
|
|
1000
|
+
`/reload-skills` and `/reload-plugins` only re-read what is on disk. `/mcp disable` also
|
|
1001
|
+
leaves the per-project mark that `enable` clears (see
|
|
1002
|
+
[MCP backups are verbatim](#mcp-backups-are-verbatim)).
|
|
971
1003
|
- `agent-toggle ui` in another terminal applies on Enter and writes the Claude rows it changed to
|
|
972
1004
|
`~/.agent-toggle/reload.json`. Every open session running the mod checks that file's mtime every
|
|
973
1005
|
5 s (one `stat`) and queues the same reloads, toasting `agent-toggle ui: /reload-skills`. A file
|
|
@@ -58,11 +58,12 @@ def claudeai_connector_names() -> set[str]:
|
|
|
58
58
|
return set(cfg.get("claudeAiMcpEverConnected", []) or [])
|
|
59
59
|
|
|
60
60
|
|
|
61
|
-
def toggle_claudeai_connector(action: str, name: str,
|
|
62
|
-
|
|
61
|
+
def toggle_claudeai_connector(action: str, name: str, dry_run: bool = False,
|
|
62
|
+
under: Path | None = None) -> tuple[bool, list | str]:
|
|
63
63
|
"""Fan a claude.ai connector on/off across every EXISTING project entry
|
|
64
64
|
in ~/.claude.json's disabledMcpServers list -- the only place /mcp writes
|
|
65
|
-
that state; no `claude mcp` CLI verb reaches it.
|
|
65
|
+
that state; no `claude mcp` CLI verb reaches it. `under`: only the project
|
|
66
|
+
entries that are that dir or inside it.
|
|
66
67
|
|
|
67
68
|
ponytail: covers projects that exist now; a project dir opened for the
|
|
68
69
|
first time later starts without the entry until this is re-run for it.
|
|
@@ -75,7 +76,8 @@ def toggle_claudeai_connector(action: str, name: str,
|
|
|
75
76
|
|
|
76
77
|
touched = []
|
|
77
78
|
for proj, pdata in cfg.get("projects", {}).items():
|
|
78
|
-
if not isinstance(pdata, dict)
|
|
79
|
+
if not isinstance(pdata, dict) or (
|
|
80
|
+
under is not None and under != Path(proj) and under not in Path(proj).parents):
|
|
79
81
|
continue
|
|
80
82
|
cur = pdata.get("disabledMcpServers") or []
|
|
81
83
|
has = name in cur
|
|
@@ -10,6 +10,7 @@ import os
|
|
|
10
10
|
import shutil
|
|
11
11
|
import subprocess
|
|
12
12
|
import sys
|
|
13
|
+
from pathlib import Path
|
|
13
14
|
from typing import Callable
|
|
14
15
|
|
|
15
16
|
from .. import fs
|
|
@@ -17,6 +18,8 @@ from .. import fs
|
|
|
17
18
|
which = shutil.which
|
|
18
19
|
runner = subprocess.run
|
|
19
20
|
|
|
21
|
+
PLUGIN_SCOPES = ("user", "project", "local") # `claude plugin enable|disable -s`
|
|
22
|
+
|
|
20
23
|
TIMEOUT_ENV = "AGENT_TOGGLE_CLI_TIMEOUT"
|
|
21
24
|
MUTATE_TIMEOUT = 120 # enable / disable / install / mcp add|remove: may fetch from a marketplace
|
|
22
25
|
READ_TIMEOUT = 30 # read-only `plugin list`
|
|
@@ -68,12 +71,39 @@ def run_cli(binary: str | None, args: list[str], cwd: str | None = None,
|
|
|
68
71
|
return p.returncode == 0, (p.stdout + p.stderr).strip()
|
|
69
72
|
|
|
70
73
|
|
|
71
|
-
def
|
|
72
|
-
"""
|
|
74
|
+
def plugin_where(name: str, claude_home: Path) -> tuple[str | None, str | None]:
|
|
75
|
+
"""(scope, cwd) of plugin `name`'s one install, from Claude Code's install registry
|
|
76
|
+
(`<claude_home>/plugins/installed_plugins.json`; a bare name: its one `name@mkt` id).
|
|
77
|
+
|
|
78
|
+
Without `-s` the CLI picks the scope from its cwd, so a project-scope plugin toggled
|
|
79
|
+
from another dir lands in user scope. (None, None) when the registry cannot say --
|
|
80
|
+
absent, another shape, several installs, a project dir that is gone: the caller
|
|
81
|
+
then lets the CLI auto-detect, as before. A file read, not `claude plugin list`
|
|
82
|
+
(~0.8 s per call, paid on every pane toggle)."""
|
|
83
|
+
try:
|
|
84
|
+
reg = json.loads((claude_home / "plugins" / "installed_plugins.json")
|
|
85
|
+
.read_text(encoding="utf-8"))
|
|
86
|
+
rows = [r for k, v in reg["plugins"].items()
|
|
87
|
+
if k == name or ("@" not in name and k.partition("@")[0] == name) for r in v]
|
|
88
|
+
except (OSError, ValueError, KeyError, TypeError, AttributeError):
|
|
89
|
+
return None, None
|
|
90
|
+
if len(rows) != 1 or not isinstance(rows[0], dict) or rows[0].get("scope") not in PLUGIN_SCOPES:
|
|
91
|
+
return None, None
|
|
92
|
+
scope, proj = rows[0]["scope"], rows[0].get("projectPath")
|
|
93
|
+
if scope == "user":
|
|
94
|
+
return scope, None
|
|
95
|
+
if isinstance(proj, str) and os.path.isabs(proj) and os.path.isdir(proj):
|
|
96
|
+
return scope, proj
|
|
97
|
+
return None, None
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def list_plugins(warn: Callable[[str], None], cwd: str | None = None) -> list[dict]:
|
|
101
|
+
"""`claude plugin list --json` through the injectable runner; [] when unavailable.
|
|
102
|
+
`cwd`: its `enabled` is the plugin's state as seen from there."""
|
|
73
103
|
exe = claude_bin()
|
|
74
104
|
if not exe:
|
|
75
105
|
return []
|
|
76
|
-
ok, text = run_cli(exe, ["plugin", "list", "--json"], timeout=READ_TIMEOUT)
|
|
106
|
+
ok, text = run_cli(exe, ["plugin", "list", "--json"], cwd=cwd, timeout=READ_TIMEOUT)
|
|
77
107
|
try: # run_cli merges stderr into the text: skip any notice before the array
|
|
78
108
|
data = json.JSONDecoder().raw_decode(text, max(text.find("["), 0))[0] if ok else None
|
|
79
109
|
except ValueError:
|
|
@@ -25,10 +25,10 @@ CATALOG: dict[str, str] = {
|
|
|
25
25
|
"picker.loading": "載入資源中…",
|
|
26
26
|
"picker.filter.type": "類型:",
|
|
27
27
|
"picker.filter.sort": "排序:",
|
|
28
|
-
"picker.empty": "沒有符合的項目 -- Ctrl-U 清除篩選,Left/Right 換 harness,
|
|
28
|
+
"picker.empty": "沒有符合的項目 -- Ctrl-U 清除篩選,Left/Right 換 harness,Ctrl-T 換類型",
|
|
29
29
|
"picker.status.shown": "顯示 %s / %s",
|
|
30
30
|
"picker.status.dry_run": "試跑:Enter 只顯示計畫",
|
|
31
|
-
"picker.
|
|
31
|
+
"picker.chip.leave": "離開/檢視變更",
|
|
32
32
|
"picker.badge.shared": "+共用",
|
|
33
33
|
# detail pane
|
|
34
34
|
"picker.state.live": "啟用",
|
|
@@ -49,7 +49,7 @@ CATALOG: dict[str, str] = {
|
|
|
49
49
|
# key chips
|
|
50
50
|
"picker.chip.toggle": "切換",
|
|
51
51
|
"picker.chip.apply": "套用",
|
|
52
|
-
"picker.chip.cancel": "
|
|
52
|
+
"picker.chip.cancel": "放棄",
|
|
53
53
|
"picker.chip.help": "說明",
|
|
54
54
|
"picker.chip.filter": "搜尋",
|
|
55
55
|
"picker.chip.harness": "harness",
|
|
@@ -64,12 +64,17 @@ CATALOG: dict[str, str] = {
|
|
|
64
64
|
"picker.help.title": "按鍵",
|
|
65
65
|
"picker.help.move": "移動(也可用 Ctrl-P / Ctrl-N)",
|
|
66
66
|
"picker.help.toggle": "切換此列(啟用 <-> 停用),停留在該列",
|
|
67
|
-
"picker.help.toggle_next": "切換此列,然後移到下一列",
|
|
68
67
|
"picker.help.apply": "套用暫存的變更(--dry-run:只看計畫)",
|
|
69
|
-
"picker.help.cancel": "
|
|
70
|
-
"picker.help.
|
|
68
|
+
"picker.help.cancel": "離開;有暫存變更時先詢問是否儲存",
|
|
69
|
+
"picker.help.discard": "放棄變更並離開",
|
|
70
|
+
"picker.save.title": "儲存變更?",
|
|
71
|
+
"picker.save.count": "%s 項變更",
|
|
72
|
+
"picker.save.yes": "是",
|
|
73
|
+
"picker.save.no": "否",
|
|
74
|
+
"picker.save.keys": "Tab/點擊 切換 · 上下 移動 · Enter 確認 · Esc 返回",
|
|
75
|
+
"picker.help.filter": "搜尋名稱 / harness / 路徑(可模糊);直接打任何字母或數字也會開始搜尋",
|
|
71
76
|
"picker.help.edit": "編輯 / 清除篩選",
|
|
72
|
-
"picker.help.harness": "harness
|
|
77
|
+
"picker.help.harness": "harness 分頁",
|
|
73
78
|
"picker.help.type": "循環切換類型篩選",
|
|
74
79
|
"picker.help.sort": "循環切換排序:名稱 / 成本(由大到小)",
|
|
75
80
|
"picker.help.profile": "設定檔:暫存一個,或儲存目前啟用的狀態",
|