agent-toggle 0.7.2__tar.gz → 0.7.3__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.7.2 → agent_toggle-0.7.3}/PKG-INFO +5 -1
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/README.md +4 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/agent_toggle/__init__.py +1 -1
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/agent_toggle/backends/plugin_cli.py +2 -1
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/agent_toggle/ui/picker.py +21 -12
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/agent_toggle.egg-info/PKG-INFO +5 -1
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/tests/test_picker.py +13 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/tests/test_platform.py +12 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/LICENSE +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/agent_toggle/__main__.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/agent_toggle/backends/__init__.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/agent_toggle/backends/flag_json.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/agent_toggle/backends/mcp_json.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/agent_toggle/backends/mcp_toml.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/agent_toggle/cli.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/agent_toggle/companions.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/agent_toggle/config.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/agent_toggle/cost.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/agent_toggle/doctor.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/agent_toggle/fs.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/agent_toggle/harnesses.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/agent_toggle/help.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/agent_toggle/i18n.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/agent_toggle/locales/__init__.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/agent_toggle/locales/zh_tw_cli.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/agent_toggle/locales/zh_tw_common.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/agent_toggle/locales/zh_tw_config.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/agent_toggle/locales/zh_tw_picker.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/agent_toggle/mechanisms.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/agent_toggle/ops.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/agent_toggle/output.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/agent_toggle/profiles.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/agent_toggle/settings.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/agent_toggle/shims/claude.md.tmpl +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/agent_toggle/shims/generic.md.tmpl +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/agent_toggle/spinner.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/agent_toggle/store.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/agent_toggle/toml_check.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/agent_toggle/ui/__init__.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/agent_toggle/ui/config_menu.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/agent_toggle/ui/menu.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/agent_toggle/ui/model.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/agent_toggle/ui/theme.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/agent_toggle/undo.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/agent_toggle/update_check.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/agent_toggle/update_prompt.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/agent_toggle.egg-info/SOURCES.txt +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/agent_toggle.egg-info/dependency_links.txt +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/agent_toggle.egg-info/entry_points.txt +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/agent_toggle.egg-info/requires.txt +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/agent_toggle.egg-info/top_level.txt +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/pyproject.toml +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/setup.cfg +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/tests/test_alias.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/tests/test_backends.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/tests/test_cli.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/tests/test_cli_surface.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/tests/test_color.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/tests/test_companions.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/tests/test_completions.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/tests/test_config.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/tests/test_config_menu.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/tests/test_conformance.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/tests/test_containment.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/tests/test_cost.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/tests/test_crash.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/tests/test_doctor.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/tests/test_encoding.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/tests/test_fs.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/tests/test_harnesses.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/tests/test_help.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/tests/test_i18n.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/tests/test_install.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/tests/test_mechanisms.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/tests/test_menu.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/tests/test_profiles.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/tests/test_project.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/tests/test_safety.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/tests/test_secret_audit.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/tests/test_settings.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/tests/test_store.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/tests/test_theme.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/tests/test_undo.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/tests/test_update_check.py +0 -0
- {agent_toggle-0.7.2 → agent_toggle-0.7.3}/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.7.
|
|
3
|
+
Version: 0.7.3
|
|
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
|
|
@@ -855,6 +855,10 @@ ruff check .
|
|
|
855
855
|
stdlib `unittest`, no fixtures, no network. Every test runs against a
|
|
856
856
|
throwaway temp `HOME` and a stubbed `claude` CLI.
|
|
857
857
|
|
|
858
|
+
`python3 tools/wheel_smoke.py` builds the wheel, installs it without extras into a
|
|
859
|
+
fresh venv (what a PyPI user gets) and runs the CLI against a temp `HOME`; CI runs
|
|
860
|
+
it on macOS, Linux and Windows.
|
|
861
|
+
|
|
858
862
|
## CI notifications
|
|
859
863
|
|
|
860
864
|
`.github/workflows/ci.yml` can send a Telegram message when the test matrix fails on a
|
|
@@ -823,6 +823,10 @@ ruff check .
|
|
|
823
823
|
stdlib `unittest`, no fixtures, no network. Every test runs against a
|
|
824
824
|
throwaway temp `HOME` and a stubbed `claude` CLI.
|
|
825
825
|
|
|
826
|
+
`python3 tools/wheel_smoke.py` builds the wheel, installs it without extras into a
|
|
827
|
+
fresh venv (what a PyPI user gets) and runs the CLI against a temp `HOME`; CI runs
|
|
828
|
+
it on macOS, Linux and Windows.
|
|
829
|
+
|
|
826
830
|
## CI notifications
|
|
827
831
|
|
|
828
832
|
`.github/workflows/ci.yml` can send a Telegram message when the test matrix fails on a
|
|
@@ -28,7 +28,8 @@ def claude_bin() -> str | None:
|
|
|
28
28
|
if found:
|
|
29
29
|
return found
|
|
30
30
|
home = fs.home()
|
|
31
|
-
for cand in (home / ".local/bin/claude", home / ".
|
|
31
|
+
for cand in (home / ".local/bin/claude", home / ".local/bin/claude.exe", # .exe: Windows
|
|
32
|
+
home / ".claude/local/claude"):
|
|
32
33
|
if cand.is_file() and os.access(cand, os.X_OK):
|
|
33
34
|
return str(cand)
|
|
34
35
|
return None
|
|
@@ -201,22 +201,18 @@ def heading(type_: str, count: int, width: int, g: theme.Glyphs) -> list[theme.S
|
|
|
201
201
|
return [(label, "title"), (str(count), "muted"), (" " + g.h * max(0, rest), "muted")]
|
|
202
202
|
|
|
203
203
|
|
|
204
|
-
def detail_lines(r: Row, width: int, g: theme.Glyphs
|
|
205
|
-
|
|
204
|
+
def detail_lines(r: Row, width: int, g: theme.Glyphs,
|
|
205
|
+
height: int | None = None) -> list[list[theme.Segment]]:
|
|
206
|
+
"""The detail pane for the cursor row: one segment list per screen line. With `height`,
|
|
207
|
+
the description is cut (with an ellipsis) so the fields below it still fit."""
|
|
206
208
|
lab = 12 # "description" is 11 cells; leave a gap
|
|
207
209
|
val = max(1, width - lab)
|
|
208
210
|
out = [[(theme.truncate(r.name, width, g.ellipsis), "title")], []]
|
|
211
|
+
rest: list[list[theme.Segment]] = []
|
|
209
212
|
|
|
210
213
|
def field(label: str, text: str, role: str = "text") -> None:
|
|
211
214
|
for n in range(0, max(1, len(text)), val): # a long path wraps
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
if r.description: # frontmatter prose, not a path
|
|
215
|
-
chunks = wrap_cells(r.description, val)
|
|
216
|
-
label = t("picker.d.description", "description")
|
|
217
|
-
for n, chunk in enumerate(chunks):
|
|
218
|
-
out.append([(pad(label if n == 0 else "", lab), "muted"), (chunk, "text")])
|
|
219
|
-
out.append([])
|
|
215
|
+
rest.append([(pad(label if n == 0 else "", lab), "muted"), (text[n:n + val], role)])
|
|
220
216
|
|
|
221
217
|
state = t("picker.state.live", "live") if r.enabled else t("picker.state.parked", "parked")
|
|
222
218
|
field(t("picker.d.harness", "harness"), r.harness, theme.harness_role(r.harness))
|
|
@@ -242,7 +238,20 @@ def detail_lines(r: Row, width: int, g: theme.Glyphs) -> list[list[theme.Segment
|
|
|
242
238
|
field(t("picker.d.since", "since"), r.since[:19].replace("T", " "))
|
|
243
239
|
if r.mechanism:
|
|
244
240
|
field(t("picker.d.mechanism", "mechanism"), r.mechanism)
|
|
245
|
-
|
|
241
|
+
|
|
242
|
+
if r.description: # frontmatter prose, not a path
|
|
243
|
+
chunks = wrap_cells(r.description, val)
|
|
244
|
+
# the "staged" line comes and goes with Space; reserving it keeps the text from jumping
|
|
245
|
+
spare = len(rest) + (not r.changed)
|
|
246
|
+
room = len(chunks) if height is None else max(1, height - len(out) - spare - 1)
|
|
247
|
+
if len(chunks) > room:
|
|
248
|
+
chunks = chunks[:room - 1] + [theme.truncate(" ".join(chunks[room - 1:]), val,
|
|
249
|
+
g.ellipsis)]
|
|
250
|
+
label = t("picker.d.description", "description")
|
|
251
|
+
for n, chunk in enumerate(chunks):
|
|
252
|
+
out.append([(pad(label if n == 0 else "", lab), "muted"), (chunk, "text")])
|
|
253
|
+
out.append([])
|
|
254
|
+
return out + rest
|
|
246
255
|
|
|
247
256
|
|
|
248
257
|
def chips(v: View, g: theme.Glyphs) -> list[tuple[str, str]]:
|
|
@@ -322,7 +331,7 @@ def draw(win, v: View, shown: list[Row], pal: theme.Palette, g: theme.Glyphs,
|
|
|
322
331
|
else:
|
|
323
332
|
put(y, row_segments(line[1], lw, v, g, line[1] is cursor_row, any_shared))
|
|
324
333
|
if dw:
|
|
325
|
-
pane = detail_lines(cursor_row, dw - 2, g) if cursor_row else []
|
|
334
|
+
pane = detail_lines(cursor_row, dw - 2, g, body) if cursor_row else []
|
|
326
335
|
for i in range(body):
|
|
327
336
|
put(BODY_TOP + i, [(g.v, "muted"), (" ", "text"), *(pane[i] if i < len(pane) else [])],
|
|
328
337
|
lw)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agent-toggle
|
|
3
|
-
Version: 0.7.
|
|
3
|
+
Version: 0.7.3
|
|
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
|
|
@@ -855,6 +855,10 @@ ruff check .
|
|
|
855
855
|
stdlib `unittest`, no fixtures, no network. Every test runs against a
|
|
856
856
|
throwaway temp `HOME` and a stubbed `claude` CLI.
|
|
857
857
|
|
|
858
|
+
`python3 tools/wheel_smoke.py` builds the wheel, installs it without extras into a
|
|
859
|
+
fresh venv (what a PyPI user gets) and runs the CLI against a temp `HOME`; CI runs
|
|
860
|
+
it on macOS, Linux and Windows.
|
|
861
|
+
|
|
858
862
|
## CI notifications
|
|
859
863
|
|
|
860
864
|
`.github/workflows/ci.yml` can send a Telegram message when the test matrix fails on a
|
|
@@ -465,6 +465,19 @@ class LayoutTest(ScreenCase):
|
|
|
465
465
|
self.assertIn("alpha beta", body)
|
|
466
466
|
self.assertIn("gamma delta", body)
|
|
467
467
|
|
|
468
|
+
def test_long_description_is_cut_so_the_fields_still_show(self) -> None:
|
|
469
|
+
r = model.Row("claude", "skill", "solo", True, description="word " * 200,
|
|
470
|
+
mechanism="move")
|
|
471
|
+
lines = picker.detail_lines(r, 30, theme.ASCII, height=12)
|
|
472
|
+
self.assertLessEqual(len(lines), 12)
|
|
473
|
+
flat = ["".join(s for s, _ in line) for line in lines]
|
|
474
|
+
self.assertTrue(any(line.rstrip().endswith("...") for line in flat))
|
|
475
|
+
self.assertTrue(any(line.startswith("mechanism") for line in flat))
|
|
476
|
+
r.staged = False # toggling adds the "staged" line, not a cut
|
|
477
|
+
toggled = picker.detail_lines(r, 30, theme.ASCII, height=12)
|
|
478
|
+
self.assertLessEqual(len(toggled), 12)
|
|
479
|
+
self.assertEqual(lines[:8], toggled[:8])
|
|
480
|
+
|
|
468
481
|
def test_detail_pane_description_is_translated(self) -> None:
|
|
469
482
|
self.addCleanup(i18n.set_language, i18n.LANGUAGE)
|
|
470
483
|
i18n.set_language("zh-TW")
|
|
@@ -11,6 +11,7 @@ from base import SandboxCase
|
|
|
11
11
|
|
|
12
12
|
from agent_toggle import fs
|
|
13
13
|
from agent_toggle import mechanisms as mech
|
|
14
|
+
from agent_toggle.backends import plugin_cli
|
|
14
15
|
|
|
15
16
|
|
|
16
17
|
class PluginIdTest(SandboxCase):
|
|
@@ -103,5 +104,16 @@ class CaseRulesTest(SandboxCase):
|
|
|
103
104
|
self.assertEqual(mech.live_names(self.home / "commands", "command"), ["group:sub:tool"])
|
|
104
105
|
|
|
105
106
|
|
|
107
|
+
class ClaudeBinTest(SandboxCase):
|
|
108
|
+
def test_off_path_windows_install_is_found_by_its_exe_name(self) -> None:
|
|
109
|
+
"""The native Windows installer writes ~/.local/bin/claude.exe; PATH may lack it."""
|
|
110
|
+
plugin_cli.which = lambda name: None
|
|
111
|
+
exe = self.tmp / ".local" / "bin" / "claude.exe"
|
|
112
|
+
exe.parent.mkdir(parents=True)
|
|
113
|
+
exe.touch()
|
|
114
|
+
exe.chmod(0o755)
|
|
115
|
+
self.assertEqual(plugin_cli.claude_bin(), str(exe))
|
|
116
|
+
|
|
117
|
+
|
|
106
118
|
if __name__ == "__main__":
|
|
107
119
|
unittest.main()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|