agent-toggle 0.12.0__tar.gz → 0.12.1__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.
Files changed (90) hide show
  1. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/PKG-INFO +3 -1
  2. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/README.md +2 -0
  3. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/agent_toggle/__init__.py +1 -1
  4. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/agent_toggle/backends/mcp_json.py +1 -1
  5. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/agent_toggle/doctor.py +1 -1
  6. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/agent_toggle/fs.py +9 -0
  7. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/agent_toggle.egg-info/PKG-INFO +3 -1
  8. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/tests/test_backends.py +6 -0
  9. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/LICENSE +0 -0
  10. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/agent_toggle/__main__.py +0 -0
  11. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/agent_toggle/backends/__init__.py +0 -0
  12. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/agent_toggle/backends/flag_json.py +0 -0
  13. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/agent_toggle/backends/mcp_toml.py +0 -0
  14. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/agent_toggle/backends/plugin_cli.py +0 -0
  15. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/agent_toggle/cli.py +0 -0
  16. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/agent_toggle/companions.py +0 -0
  17. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/agent_toggle/config.py +0 -0
  18. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/agent_toggle/cost.py +0 -0
  19. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/agent_toggle/harnesses.py +0 -0
  20. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/agent_toggle/help.py +0 -0
  21. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/agent_toggle/i18n.py +0 -0
  22. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/agent_toggle/locales/__init__.py +0 -0
  23. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/agent_toggle/locales/zh_tw_cli.py +0 -0
  24. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/agent_toggle/locales/zh_tw_common.py +0 -0
  25. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/agent_toggle/locales/zh_tw_config.py +0 -0
  26. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/agent_toggle/locales/zh_tw_picker.py +0 -0
  27. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/agent_toggle/mechanisms.py +0 -0
  28. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/agent_toggle/ops.py +0 -0
  29. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/agent_toggle/output.py +0 -0
  30. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/agent_toggle/profiles.py +0 -0
  31. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/agent_toggle/settings.py +0 -0
  32. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/agent_toggle/shims/claude.md.tmpl +0 -0
  33. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/agent_toggle/shims/generic.md.tmpl +0 -0
  34. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/agent_toggle/spinner.py +0 -0
  35. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/agent_toggle/store.py +0 -0
  36. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/agent_toggle/toml_check.py +0 -0
  37. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/agent_toggle/ui/__init__.py +0 -0
  38. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/agent_toggle/ui/config_menu.py +0 -0
  39. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/agent_toggle/ui/logo.py +0 -0
  40. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/agent_toggle/ui/menu.py +0 -0
  41. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/agent_toggle/ui/model.py +0 -0
  42. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/agent_toggle/ui/picker.py +0 -0
  43. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/agent_toggle/ui/theme.py +0 -0
  44. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/agent_toggle/undo.py +0 -0
  45. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/agent_toggle/update_check.py +0 -0
  46. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/agent_toggle/update_prompt.py +0 -0
  47. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/agent_toggle.egg-info/SOURCES.txt +0 -0
  48. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/agent_toggle.egg-info/dependency_links.txt +0 -0
  49. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/agent_toggle.egg-info/entry_points.txt +0 -0
  50. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/agent_toggle.egg-info/requires.txt +0 -0
  51. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/agent_toggle.egg-info/top_level.txt +0 -0
  52. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/pyproject.toml +0 -0
  53. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/setup.cfg +0 -0
  54. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/tests/test_alias.py +0 -0
  55. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/tests/test_all_type.py +0 -0
  56. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/tests/test_cli.py +0 -0
  57. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/tests/test_cli_surface.py +0 -0
  58. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/tests/test_color.py +0 -0
  59. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/tests/test_companions.py +0 -0
  60. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/tests/test_completions.py +0 -0
  61. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/tests/test_config.py +0 -0
  62. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/tests/test_config_menu.py +0 -0
  63. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/tests/test_conformance.py +0 -0
  64. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/tests/test_containment.py +0 -0
  65. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/tests/test_cost.py +0 -0
  66. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/tests/test_crash.py +0 -0
  67. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/tests/test_doctor.py +0 -0
  68. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/tests/test_encoding.py +0 -0
  69. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/tests/test_fs.py +0 -0
  70. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/tests/test_harnesses.py +0 -0
  71. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/tests/test_help.py +0 -0
  72. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/tests/test_i18n.py +0 -0
  73. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/tests/test_install.py +0 -0
  74. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/tests/test_logo.py +0 -0
  75. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/tests/test_mechanisms.py +0 -0
  76. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/tests/test_menu.py +0 -0
  77. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/tests/test_mods.py +0 -0
  78. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/tests/test_picker.py +0 -0
  79. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/tests/test_platform.py +0 -0
  80. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/tests/test_profiles.py +0 -0
  81. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/tests/test_project.py +0 -0
  82. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/tests/test_safety.py +0 -0
  83. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/tests/test_same_name.py +0 -0
  84. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/tests/test_secret_audit.py +0 -0
  85. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/tests/test_settings.py +0 -0
  86. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/tests/test_store.py +0 -0
  87. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/tests/test_theme.py +0 -0
  88. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/tests/test_undo.py +0 -0
  89. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/tests/test_update_check.py +0 -0
  90. {agent_toggle-0.12.0 → agent_toggle-0.12.1}/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.12.0
3
+ Version: 0.12.1
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
@@ -391,6 +391,8 @@ a band above the prompt, buttons) and change Claude Code's behaviour. A plugin w
391
391
  `hooks.json`, or with only ordinary hooks (shell commands such as `PreToolUse`), is a plain
392
392
  plugin: it ships skills, commands, agents, MCP servers or hooks and draws nothing.
393
393
 
394
+ ![Claude Mods: toggling mods from the picker](https://raw.githubusercontent.com/weskao/agent-toggle/main/docs/images/claude-mods-demo.gif)
395
+
394
396
  - The check reads the install path `claude plugin list` reports and every cached version
395
397
  under `~/.claude/plugins/cache/<marketplace>/<name>/`, so a parked mod is still a mod.
396
398
  To list the installed mods by hand:
@@ -358,6 +358,8 @@ a band above the prompt, buttons) and change Claude Code's behaviour. A plugin w
358
358
  `hooks.json`, or with only ordinary hooks (shell commands such as `PreToolUse`), is a plain
359
359
  plugin: it ships skills, commands, agents, MCP servers or hooks and draws nothing.
360
360
 
361
+ ![Claude Mods: toggling mods from the picker](https://raw.githubusercontent.com/weskao/agent-toggle/main/docs/images/claude-mods-demo.gif)
362
+
361
363
  - The check reads the install path `claude plugin list` reports and every cached version
362
364
  under `~/.claude/plugins/cache/<marketplace>/<name>/`, so a parked mod is still a mod.
363
365
  To list the installed mods by hand:
@@ -1,3 +1,3 @@
1
1
  """agent-toggle: temporarily disable / re-enable AI-agent resources."""
2
2
 
3
- __version__ = "0.12.0"
3
+ __version__ = "0.12.1"
@@ -134,7 +134,7 @@ def read_project_mcp(file: Path) -> tuple[str, dict]:
134
134
  try:
135
135
  if file.stat().st_size > MAX_PROJECT_MCP:
136
136
  raise ProjectMcpError(f"{file} is larger than {MAX_PROJECT_MCP >> 20} MiB")
137
- text = file.read_bytes().decode("utf-8") # bytes: CRLF must survive
137
+ text = fs.read_utf8(file) # bytes: CRLF must survive
138
138
  except FileNotFoundError:
139
139
  raise ProjectMcpError(f"{file} not found") from None
140
140
  except (OSError, UnicodeDecodeError) as e:
@@ -94,7 +94,7 @@ def _move_back(p: Path, live: Path) -> None:
94
94
  def _read_json(file: Path) -> tuple[object, str, str]:
95
95
  """(data, kind, why); kind is ok | missing | jsonc | broken."""
96
96
  try:
97
- text = file.read_bytes().decode("utf-8").removeprefix("\ufeff")
97
+ text = fs.read_utf8(file).removeprefix("\ufeff")
98
98
  except FileNotFoundError:
99
99
  return None, "missing", "is missing"
100
100
  except (OSError, UnicodeDecodeError) as e:
@@ -254,6 +254,15 @@ def lock():
254
254
  pass
255
255
 
256
256
 
257
+ def read_utf8(path: Path) -> str:
258
+ """Exact text of `path`; a git-crypt-locked file raises OSError naming the fix,
259
+ not an opaque UnicodeDecodeError."""
260
+ raw = path.read_bytes()
261
+ if raw.startswith(b"\x00GITCRYPT\x00"):
262
+ raise OSError("git-crypt encrypted -- run `git-crypt unlock` in its repo")
263
+ return raw.decode("utf-8")
264
+
265
+
257
266
  def atomic_write(path: Path, text: str, mode: int = 0o600, newline: str | None = None) -> None:
258
267
  """Write `text` to `path` via a same-dir tmp file created with `mode`.
259
268
  `newline=""` writes line endings as given (a user file edited in place)."""
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agent-toggle
3
- Version: 0.12.0
3
+ Version: 0.12.1
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
@@ -391,6 +391,8 @@ a band above the prompt, buttons) and change Claude Code's behaviour. A plugin w
391
391
  `hooks.json`, or with only ordinary hooks (shell commands such as `PreToolUse`), is a plain
392
392
  plugin: it ships skills, commands, agents, MCP servers or hooks and draws nothing.
393
393
 
394
+ ![Claude Mods: toggling mods from the picker](https://raw.githubusercontent.com/weskao/agent-toggle/main/docs/images/claude-mods-demo.gif)
395
+
394
396
  - The check reads the install path `claude plugin list` reports and every cached version
395
397
  under `~/.claude/plugins/cache/<marketplace>/<name>/`, so a parked mod is still a mod.
396
398
  To list the installed mods by hand:
@@ -162,6 +162,12 @@ class ProjectMcpJsonTest(SandboxCase):
162
162
  with self.assertRaises(mcp_json.ProjectMcpError):
163
163
  mcp_json.project_mcp_remove(self.put('{"mcpServers": {}}'), "a-mcp")
164
164
 
165
+ def test_git_crypt_locked_file_names_the_fix(self) -> None:
166
+ f = self.tmp / ".mcp.json"
167
+ f.write_bytes(b"\x00GITCRYPT\x00\xa4\xc7}")
168
+ with self.assertRaisesRegex(mcp_json.ProjectMcpError, "git-crypt unlock"):
169
+ mcp_json.read_project_mcp(f)
170
+
165
171
 
166
172
  class CopilotMcpTest(CliCase):
167
173
  """copilot's user-scope strict-JSON mcp-config.json (backend `json`)."""
File without changes
File without changes