batrachian-toad 0.5.22__py3-none-any.whl

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 (120) hide show
  1. batrachian_toad-0.5.22.dist-info/METADATA +197 -0
  2. batrachian_toad-0.5.22.dist-info/RECORD +120 -0
  3. batrachian_toad-0.5.22.dist-info/WHEEL +4 -0
  4. batrachian_toad-0.5.22.dist-info/entry_points.txt +2 -0
  5. batrachian_toad-0.5.22.dist-info/licenses/LICENSE +661 -0
  6. toad/__init__.py +46 -0
  7. toad/__main__.py +4 -0
  8. toad/_loop.py +86 -0
  9. toad/about.py +90 -0
  10. toad/acp/agent.py +671 -0
  11. toad/acp/api.py +47 -0
  12. toad/acp/encode_tool_call_id.py +12 -0
  13. toad/acp/messages.py +138 -0
  14. toad/acp/prompt.py +54 -0
  15. toad/acp/protocol.py +426 -0
  16. toad/agent.py +62 -0
  17. toad/agent_schema.py +70 -0
  18. toad/agents.py +45 -0
  19. toad/ansi/__init__.py +1 -0
  20. toad/ansi/_ansi.py +1612 -0
  21. toad/ansi/_ansi_colors.py +264 -0
  22. toad/ansi/_control_codes.py +37 -0
  23. toad/ansi/_keys.py +251 -0
  24. toad/ansi/_sgr_styles.py +64 -0
  25. toad/ansi/_stream_parser.py +418 -0
  26. toad/answer.py +22 -0
  27. toad/app.py +557 -0
  28. toad/atomic.py +37 -0
  29. toad/cli.py +257 -0
  30. toad/code_analyze.py +28 -0
  31. toad/complete.py +34 -0
  32. toad/constants.py +58 -0
  33. toad/conversation_markdown.py +19 -0
  34. toad/danger.py +371 -0
  35. toad/data/agents/ampcode.com.toml +51 -0
  36. toad/data/agents/augmentcode.com.toml +40 -0
  37. toad/data/agents/claude.com.toml +41 -0
  38. toad/data/agents/docker.com.toml +59 -0
  39. toad/data/agents/geminicli.com.toml +28 -0
  40. toad/data/agents/goose.ai.toml +51 -0
  41. toad/data/agents/inference.huggingface.co.toml +33 -0
  42. toad/data/agents/kimi.com.toml +35 -0
  43. toad/data/agents/openai.com.toml +53 -0
  44. toad/data/agents/opencode.ai.toml +61 -0
  45. toad/data/agents/openhands.dev.toml +44 -0
  46. toad/data/agents/stakpak.dev.toml +61 -0
  47. toad/data/agents/vibe.mistral.ai.toml +27 -0
  48. toad/data/agents/vtcode.dev.toml +62 -0
  49. toad/data/images/frog.png +0 -0
  50. toad/data/sounds/turn-over.wav +0 -0
  51. toad/db.py +5 -0
  52. toad/dec.py +332 -0
  53. toad/directory.py +234 -0
  54. toad/directory_watcher.py +96 -0
  55. toad/fuzzy.py +140 -0
  56. toad/gist.py +2 -0
  57. toad/history.py +138 -0
  58. toad/jsonrpc.py +576 -0
  59. toad/menus.py +14 -0
  60. toad/messages.py +74 -0
  61. toad/option_content.py +51 -0
  62. toad/os.py +0 -0
  63. toad/path_complete.py +145 -0
  64. toad/path_filter.py +124 -0
  65. toad/paths.py +71 -0
  66. toad/pill.py +23 -0
  67. toad/prompt/extract.py +19 -0
  68. toad/prompt/resource.py +68 -0
  69. toad/protocol.py +28 -0
  70. toad/screens/action_modal.py +94 -0
  71. toad/screens/agent_modal.py +172 -0
  72. toad/screens/command_edit_modal.py +58 -0
  73. toad/screens/main.py +192 -0
  74. toad/screens/permissions.py +390 -0
  75. toad/screens/permissions.tcss +72 -0
  76. toad/screens/settings.py +254 -0
  77. toad/screens/settings.tcss +101 -0
  78. toad/screens/store.py +476 -0
  79. toad/screens/store.tcss +261 -0
  80. toad/settings.py +354 -0
  81. toad/settings_schema.py +318 -0
  82. toad/shell.py +263 -0
  83. toad/shell_read.py +42 -0
  84. toad/slash_command.py +34 -0
  85. toad/toad.tcss +752 -0
  86. toad/version.py +80 -0
  87. toad/visuals/columns.py +273 -0
  88. toad/widgets/agent_response.py +79 -0
  89. toad/widgets/agent_thought.py +41 -0
  90. toad/widgets/command_pane.py +224 -0
  91. toad/widgets/condensed_path.py +93 -0
  92. toad/widgets/conversation.py +1626 -0
  93. toad/widgets/danger_warning.py +65 -0
  94. toad/widgets/diff_view.py +709 -0
  95. toad/widgets/flash.py +81 -0
  96. toad/widgets/future_text.py +126 -0
  97. toad/widgets/grid_select.py +223 -0
  98. toad/widgets/highlighted_textarea.py +180 -0
  99. toad/widgets/mandelbrot.py +294 -0
  100. toad/widgets/markdown_note.py +13 -0
  101. toad/widgets/menu.py +147 -0
  102. toad/widgets/non_selectable_label.py +5 -0
  103. toad/widgets/note.py +18 -0
  104. toad/widgets/path_search.py +381 -0
  105. toad/widgets/plan.py +180 -0
  106. toad/widgets/project_directory_tree.py +74 -0
  107. toad/widgets/prompt.py +741 -0
  108. toad/widgets/question.py +337 -0
  109. toad/widgets/shell_result.py +35 -0
  110. toad/widgets/shell_terminal.py +18 -0
  111. toad/widgets/side_bar.py +74 -0
  112. toad/widgets/slash_complete.py +211 -0
  113. toad/widgets/strike_text.py +66 -0
  114. toad/widgets/terminal.py +526 -0
  115. toad/widgets/terminal_tool.py +338 -0
  116. toad/widgets/throbber.py +90 -0
  117. toad/widgets/tool_call.py +303 -0
  118. toad/widgets/user_input.py +23 -0
  119. toad/widgets/version.py +5 -0
  120. toad/widgets/welcome.py +31 -0
toad/danger.py ADDED
@@ -0,0 +1,371 @@
1
+ from enum import IntEnum
2
+ from functools import lru_cache
3
+ from pathlib import Path
4
+ from typing import Iterable, NamedTuple, Sequence
5
+
6
+ from textual.content import Span
7
+
8
+
9
+ SAFE_COMMANDS = {
10
+ # Display & Output
11
+ "echo",
12
+ "cat",
13
+ "less",
14
+ "more",
15
+ "head",
16
+ "tail",
17
+ "tac",
18
+ "nl",
19
+ # File & Directory Information
20
+ "ls",
21
+ "tree",
22
+ "pwd",
23
+ "file",
24
+ "stat",
25
+ "du",
26
+ "df",
27
+ # Search & Find
28
+ "find",
29
+ "locate",
30
+ "which",
31
+ "whereis",
32
+ "type",
33
+ "grep",
34
+ "egrep",
35
+ "fgrep",
36
+ # Text Processing (read-only)
37
+ "wc",
38
+ "sort",
39
+ "uniq",
40
+ "cut",
41
+ "paste",
42
+ "column",
43
+ "tr",
44
+ "diff",
45
+ "cmp",
46
+ "comm",
47
+ # System Information
48
+ "whoami",
49
+ "who",
50
+ "w",
51
+ "id",
52
+ "hostname",
53
+ "uname",
54
+ "uptime",
55
+ "date",
56
+ "cal",
57
+ "env",
58
+ "printenv",
59
+ # Process Information
60
+ "ps",
61
+ "top",
62
+ "htop",
63
+ "pgrep",
64
+ "jobs",
65
+ "pstree",
66
+ # Network (read-only operations)
67
+ "ping",
68
+ "traceroute",
69
+ "nslookup",
70
+ "dig",
71
+ "host",
72
+ "netstat",
73
+ "ss",
74
+ "ifconfig",
75
+ "ip",
76
+ # View compressed files (without extracting)
77
+ "zcat",
78
+ "zless",
79
+ # History & Help
80
+ "history",
81
+ "man",
82
+ "help",
83
+ "info",
84
+ "apropos",
85
+ "whatis",
86
+ # Comparison & Checksums
87
+ "md5sum",
88
+ "sha256sum",
89
+ "sha1sum",
90
+ "cksum",
91
+ "sum",
92
+ # Other Safe Commands
93
+ "bc",
94
+ "expr",
95
+ "test",
96
+ "sleep",
97
+ "true",
98
+ "false",
99
+ "yes",
100
+ "seq",
101
+ "basename",
102
+ "dirname",
103
+ "realpath",
104
+ "readlink",
105
+ }
106
+
107
+ UNSAFE_COMMANDS = {
108
+ # File/Directory Creation
109
+ "mkdir",
110
+ "touch",
111
+ "mktemp",
112
+ "mkfifo",
113
+ "mknod",
114
+ # File/Directory Deletion
115
+ "rm",
116
+ "rmdir",
117
+ "shred",
118
+ # File/Directory Moving/Copying
119
+ "mv",
120
+ "cp",
121
+ "rsync",
122
+ "scp",
123
+ "install",
124
+ # File Modification/Editing
125
+ "sed", # with -i flag
126
+ "awk", # can write files
127
+ "tee", # writes to files and stdout
128
+ # Permissions/Ownership
129
+ "chmod",
130
+ "chown",
131
+ "chgrp",
132
+ "chattr",
133
+ "setfacl",
134
+ # Linking
135
+ "ln",
136
+ "link",
137
+ "unlink",
138
+ # Archive/Compression (extract/compress operations)
139
+ "tar",
140
+ "untar",
141
+ "zip",
142
+ "unzip",
143
+ "gzip",
144
+ "gunzip",
145
+ "bzip2",
146
+ "bunzip2",
147
+ "xz",
148
+ "unxz",
149
+ "7z",
150
+ "rar",
151
+ "unrar",
152
+ # Download Tools
153
+ "wget",
154
+ "curl",
155
+ "fetch",
156
+ "aria2c",
157
+ # Low-level Disk Operations
158
+ "dd",
159
+ "truncate",
160
+ "fallocate",
161
+ # File Splitting
162
+ "split",
163
+ "csplit",
164
+ # Synchronization
165
+ "sync",
166
+ # System Administration
167
+ "useradd",
168
+ "userdel",
169
+ "usermod",
170
+ "groupadd",
171
+ "groupdel",
172
+ "passwd",
173
+ "mount",
174
+ "umount",
175
+ "mkfs",
176
+ "fdisk",
177
+ "parted",
178
+ "swapon",
179
+ "swapoff",
180
+ # Other Potentially Dangerous
181
+ "patch",
182
+ }
183
+
184
+
185
+ COMMAND_SPLIT = {";", "&&", "||", "|"}
186
+ CHANGE_DIRECTORY = {"cd"}
187
+
188
+
189
+ class DangerLevel(IntEnum):
190
+ """The danger level of a command."""
191
+
192
+ SAFE = 0 # Command is know to be generally save
193
+ UNKNOWN = 1 # We don't know about this command
194
+ DANGEROUS = 2 # Command is potentially dangerous (can modify filesystem)
195
+ DESTRUCTIVE = 3 # Command is both dangerous and refers outside of project root
196
+
197
+
198
+ class CommandAtom(NamedTuple):
199
+ """A command "atom"."""
200
+
201
+ name: str
202
+ """Name of the command."""
203
+ level: DangerLevel
204
+ """Danger level."""
205
+ path: Path
206
+ """The path to which this command is expected to apply."""
207
+ span: tuple[int, int]
208
+ """Span to highlight error."""
209
+
210
+
211
+ @lru_cache(maxsize=1024)
212
+ def detect(
213
+ project_directory: str,
214
+ current_working_directory: str,
215
+ command_line: str,
216
+ *,
217
+ danger_style: str = "",
218
+ destructive_style: str = "$text-error on $error-muted 70%",
219
+ ) -> tuple[Sequence[Span], DangerLevel]:
220
+ """Attempt to detect potentially destructive commands.
221
+
222
+ Args:
223
+ project_directory: Project directory.
224
+ current_working_directory: Current working directory.
225
+ command_line: Bash command.
226
+ danger_style: Style to highlight dangerous commands.
227
+ destructive_style: Style highlight destructive commands.
228
+
229
+ Returns:
230
+ A tuple of spans to highlight the command, and a `DangerLevel` enumeration.
231
+ """
232
+ try:
233
+ atoms = list(
234
+ analyze(project_directory, current_working_directory, command_line)
235
+ )
236
+ except OSError:
237
+ return [], DangerLevel.UNKNOWN
238
+ spans: list[Span] = []
239
+ for atom in atoms:
240
+ if atom.level == DangerLevel.DANGEROUS and danger_style:
241
+ spans.append(Span(*atom.span, danger_style))
242
+ elif atom.level == DangerLevel.DESTRUCTIVE and destructive_style:
243
+ spans.append(Span(*atom.span, destructive_style))
244
+
245
+ if atoms:
246
+ danger_level = max(command_atom.level for command_atom in atoms)
247
+ else:
248
+ danger_level = DangerLevel.SAFE
249
+
250
+ return (spans, danger_level)
251
+
252
+
253
+ def analyze(
254
+ project_directory: str, current_working_directory: str, command_line: str
255
+ ) -> Iterable[CommandAtom]:
256
+ """Analyze a command and generate information about potentially destructive commands.
257
+
258
+ Args:
259
+ project_dir: The project directory.
260
+ command_line: A bash command line.
261
+
262
+ Yields:
263
+ `CommandAtom` objects.
264
+ """
265
+ project_path = Path(project_directory).resolve()
266
+
267
+ import bashlex
268
+ from bashlex import ast
269
+
270
+ def recurse_nodes(root_path: Path, nodes: list[ast.node]) -> Iterable[CommandAtom]:
271
+ for node in nodes:
272
+ kind: str = node.kind
273
+
274
+ if kind == "list":
275
+ yield from recurse_nodes(root_path, node.parts)
276
+ return
277
+
278
+ if kind == "operator":
279
+ continue
280
+
281
+ level = DangerLevel.UNKNOWN
282
+
283
+ if not hasattr(node, "parts"):
284
+ continue
285
+
286
+ if node.parts:
287
+ command_name = command_line[slice(*node.parts[0].pos)]
288
+ if command_name in SAFE_COMMANDS:
289
+ level = DangerLevel.SAFE
290
+ elif command_name in UNSAFE_COMMANDS:
291
+ level = DangerLevel.DANGEROUS
292
+ parts = node.parts[1:]
293
+ else:
294
+ parts = node.parts
295
+
296
+ if not parts:
297
+ yield CommandAtom(command_name, level, root_path, node.pos)
298
+ continue
299
+
300
+ change_directory = command_name in CHANGE_DIRECTORY
301
+
302
+ for command_node in parts:
303
+ command_word = command_line[slice(*node.pos)]
304
+
305
+ if command_node.kind == "redirect":
306
+ redirect = command_line[slice(*command_node.output.pos)]
307
+ try:
308
+ target_path = (
309
+ root_path / Path(redirect).expanduser()
310
+ ).resolve()
311
+ except OSError:
312
+ continue
313
+ if not target_path.is_relative_to(project_path):
314
+ yield CommandAtom(
315
+ "redirect",
316
+ DangerLevel.DESTRUCTIVE,
317
+ target_path,
318
+ command_node.pos,
319
+ )
320
+ continue
321
+
322
+ if command_node.kind == "command":
323
+ yield from recurse_nodes(root_path, command_node.parts)
324
+ continue
325
+ if command_word.startswith(("-", "+")):
326
+ continue
327
+ word = command_line[slice(*command_node.pos)]
328
+ if change_directory:
329
+ try:
330
+ root_path = (root_path / Path(word)).expanduser().resolve()
331
+ except OSError:
332
+ pass
333
+ continue
334
+
335
+ try:
336
+ target_path = (root_path / Path(word)).expanduser().resolve()
337
+ except OSError:
338
+ continue
339
+ if level == DangerLevel.DANGEROUS and not target_path.is_relative_to(
340
+ project_path
341
+ ):
342
+ # If refers to a path outside of the project, upgrade to destructive
343
+ level = DangerLevel.DESTRUCTIVE
344
+
345
+ yield CommandAtom(command_word, level, target_path, node.pos)
346
+
347
+ current_path = Path(current_working_directory)
348
+ try:
349
+ nodes = bashlex.parse(command_line)
350
+ except Exception:
351
+ # Failed to parse bash
352
+ return
353
+
354
+ yield from recurse_nodes(current_path, nodes)
355
+
356
+
357
+ if __name__ == "__main__":
358
+ import os
359
+ from rich import print
360
+
361
+ TEST = [
362
+ "ls;ls",
363
+ "echo 'hello world'",
364
+ "rm foo",
365
+ "rm ../foo",
366
+ "rm /",
367
+ "cat foo > ../foo.txt",
368
+ ]
369
+
370
+ for test in TEST:
371
+ print(repr(test), detect(os.getcwd(), os.getcwd(), test))
@@ -0,0 +1,51 @@
1
+ # Schema defined in agent_schema.py
2
+ # https://github.com/tao12345666333/amp-acp
3
+
4
+ identity = "ampcode.com"
5
+ name = "Amp (AmpCode)"
6
+ short_name = "amp"
7
+ url = "https://ampcode.com"
8
+ protocol = "acp"
9
+ author_name = "AmpCode"
10
+ author_url = "https://ampcode.com"
11
+ publisher_name = "Will McGugan"
12
+ publisher_url = "https://willmcgugan.github.io/"
13
+ type = "coding"
14
+ description = "Open-source ACP adapter that exposes the Amp CLI to editors such as Zed via the Agent Client Protocol."
15
+ tags = []
16
+ run_command."*" = "npx -y amp-acp"
17
+
18
+ help = '''
19
+ # Amp (AmpCode)
20
+
21
+ Amp is a frontier coding agent for your terminal and editor, built by Sourcegraph.
22
+
23
+ - **Multi-Model** Sonnet, GPT-5, fast models—Amp uses them all, for what each model is best at.
24
+ - **Opinionated** You're always using the good parts of Amp. If we don't use and love a feature, we kill it.
25
+ - **On the Frontier** Amp goes where the models take it. No backcompat, no legacy features.
26
+ - **Threads** You can save and share your interactions with Amp. You wouldn't code without version control, would you?
27
+
28
+ ## Prerequisites
29
+
30
+ - Node.js 18+ so `npx` can run the adapter
31
+ - Ensure the `AMP_EXECUTABLE` environment variable points at your Amp binary (or place `amp` on `PATH`)
32
+
33
+
34
+ ---
35
+
36
+ ## ACP adapter for AmpCode
37
+
38
+ **Repository**: https://github.com/tao12345666333/amp-acp
39
+ '''
40
+
41
+ [actions."*".install]
42
+ command = "curl -fsSL https://ampcode.com/install.sh | bash && npm install -g amp-acp"
43
+ description = "Install AMP Code"
44
+
45
+ [actions."*".install_adapter]
46
+ command = "npm install -g amp-acp"
47
+ description = "Install the Amp ACP adapter"
48
+
49
+ [actions."*".login]
50
+ command = "amp login"
51
+ description = "Login to Amp (run once)"
@@ -0,0 +1,40 @@
1
+ # Schema defined in agent_schema.py
2
+ # https://github.com/augmentcode/auggie
3
+
4
+ identity = "augmentcode.com"
5
+ name = "Auggie (Augment Code)"
6
+ short_name = "auggie"
7
+ url = "https://www.augmentcode.com/product/CLI"
8
+ protocol = "acp"
9
+ author_name = "Augment Code"
10
+ author_url = "https://www.augmentcode.com/"
11
+ publisher_name = "Will McGugan"
12
+ publisher_url = "https://willmcgugan.github.io/"
13
+ type = "coding"
14
+ description = "An AI agent that brings Augment Code's power to the terminal with ACP support for Zed, Neovim, and Emacs."
15
+ tags = []
16
+ run_command."*" = "auggie --acp"
17
+
18
+ help = '''
19
+ # Auggie (Augment Code)
20
+
21
+ *The agentic CLI that goes where your code does*
22
+
23
+ ## Features
24
+
25
+ - **Agent Client Protocol (ACP) Support**: Use Auggie in Zed, Neovim, Emacs, and other ACP-compatible editors
26
+ - **Autonomous Code Analysis**: Intelligently explore codebases and build working memory
27
+ - **Multi-Editor Integration**: Seamlessly integrates with your favorite development environment
28
+
29
+ ---
30
+
31
+ **Documentation**: https://docs.augmentcode.com/cli/setup-auggie/install-auggie-cli
32
+ '''
33
+
34
+ [actions."*".install]
35
+ command = "npm install -g @augmentcode/auggie"
36
+ description = "Install Auggie CLI (requires Node 22+)"
37
+
38
+ [actions."*".login]
39
+ command = "auggie login"
40
+ description = "Login it Auggie (run once)"
@@ -0,0 +1,41 @@
1
+ # Schema defined in agent_schema.py
2
+ # https://www.claude.com/product/claude-code
3
+
4
+ identity = "claude.com"
5
+ name = "Claude Code"
6
+ short_name = "claude"
7
+ url = "https://www.claude.com/product/claude-code"
8
+ protocol = "acp"
9
+ author_name = "Anthropic"
10
+ author_url = "https://www.anthropic.com/"
11
+ publisher_name = "Will McGugan"
12
+ publisher_url = "https://willmcgugan.github.io/"
13
+ type = "coding"
14
+ description = "Unleash Claude’s raw power directly in your terminal."
15
+ tags = []
16
+ run_command."*" = "claude-code-acp"
17
+
18
+ help = '''
19
+ # Claude Code
20
+
21
+ Built for developers
22
+ Unleash Claude’s raw power directly in your terminal.
23
+ Search million-line codebases instantly.
24
+ Turn hours-long workflows into a single command.
25
+ Your tools.
26
+ Your workflow.
27
+ Your codebase, evolving at thought speed.
28
+
29
+ ---
30
+ [ACP adapter for Claude Code](https://github.com/zed-industries/claude-code-acp) by Zed Industries.
31
+
32
+ '''
33
+
34
+
35
+ [actions."*".install]
36
+ command = "curl -fsSL https://claude.ai/install.sh | bash && npm install -g @zed-industries/claude-code-acp"
37
+ description = "Install Claude Code + ACP adapter"
38
+
39
+ [actions."*".install_acp]
40
+ command = "npm install -g @zed-industries/claude-code-acp"
41
+ description = "Install ACP adapter"
@@ -0,0 +1,59 @@
1
+ # Schema defined in agent_schema.py
2
+ # https://github.com/docker/cagent
3
+
4
+ identity = "docker.com"
5
+ name = "Docker cagent"
6
+ short_name = "cagent"
7
+ url = "https://docs.docker.com/ai/cagent/"
8
+ protocol = "acp"
9
+ author_name = "Docker"
10
+ author_url = "https://www.docker.com/"
11
+ publisher_name = "Will McGugan"
12
+ publisher_url = "https://willmcgugan.github.io/"
13
+ type = "coding"
14
+ description = "Agent Builder and Runtime by Docker Engineering. Build, orchestrate, and share AI agents with MCP and ACP support."
15
+ tags = []
16
+ run_command."*" = "cagent acp"
17
+ recommended = false
18
+
19
+ help = '''
20
+ # Docker cagent
21
+
22
+ **Agent Builder and Runtime by Docker Engineering**
23
+
24
+ Docker cagent lets you build, orchestrate, and share AI agents that work together as a team.
25
+
26
+ ## Key Features
27
+
28
+ - **Hierarchical Agent System**: Intelligent task delegation between multiple agents
29
+ - **Model Context Protocol (MCP)**: Rich tool ecosystem via MCP integration
30
+ - **Multiple Interfaces**: CLI, TUI, API server, and MCP server modes
31
+ - **Share & Distribute**: Package and share agents to Docker Hub as OCI artifacts
32
+
33
+ ## Agent Client Protocol Support
34
+
35
+ cagent supports ACP, enabling integration with ACP-compatible editors and development environments.
36
+
37
+ ## Installation
38
+
39
+ The easiest way to get cagent is to install Docker Desktop version 4.49 or later, which includes cagent.
40
+
41
+ ## Distribution
42
+
43
+ Agent configurations can be packaged and shared using the `cagent push` command, treating agents as reproducible OCI artifacts.
44
+
45
+ ---
46
+
47
+ **Documentation**: https://docs.docker.com/ai/cagent/
48
+ **GitHub**: https://github.com/docker/cagent
49
+ **Blog Post**: https://www.docker.com/blog/cagent-build-and-distribute-ai-agents-and-workflows/
50
+ '''
51
+
52
+ welcome = '''
53
+ Say "hello" to CAgent!
54
+
55
+ '''
56
+
57
+ [actions."*".install]
58
+ command = "echo 'Install Docker Desktop 4.49+ which includes cagent: https://www.docker.com/products/docker-desktop/'"
59
+ description = "Install Docker Desktop with cagent"
@@ -0,0 +1,28 @@
1
+ # Schema defined in agent_schema.py
2
+ # https://github.com/google-gemini/gemini-cli
3
+ identity = "geminicli.com"
4
+ name = "Gemini CLI"
5
+ short_name = "gemini"
6
+ url = "https://geminicli.com/"
7
+ protocol = "acp"
8
+ author_name = "Google"
9
+ author_url = "https://www.gooogle.com"
10
+ publisher_name = "Will McGugan"
11
+ publisher_url = "https://willmcgugan.github.io/"
12
+ type = "coding"
13
+ description = "Query and edit large codebases, generate apps from images or PDFs, and automate complex workflows—all from your terminal."
14
+ tags = []
15
+ run_command."*" = "gemini --experimental-acp"
16
+
17
+ help = '''
18
+ # Gemini CLI
19
+
20
+ **Build debug & deploy with AI**
21
+
22
+ Query and edit large codebases, generate apps from images or PDFs, and automate complex workflows—all from your terminal.
23
+
24
+ '''
25
+
26
+ [actions."*".install]
27
+ command = "npm install -g @google/gemini-cli"
28
+ description = "Install Gemini CLI"
@@ -0,0 +1,51 @@
1
+ # Schema defined in agent_schema.py
2
+ # https://github.com/block/goose
3
+
4
+ identity = "goose.ai"
5
+ name = "Goose"
6
+ short_name = "goose"
7
+ url = "https://block.github.io/goose/"
8
+ protocol = "acp"
9
+ author_name = "Block"
10
+ author_url = "https://block.xyz/"
11
+ publisher_name = "Will McGugan"
12
+ publisher_url = "https://willmcgugan.github.io/"
13
+ type = "coding"
14
+ description = "An open source, extensible AI agent that goes beyond code suggestions - install, execute, edit, and test with any LLM."
15
+ tags = []
16
+ run_command."*" = "goose acp"
17
+
18
+ help = '''
19
+ # Goose 🪿
20
+
21
+ **An open source, extensible AI agent**
22
+
23
+ Goose is an open framework for AI agents that goes beyond code suggestions to install dependencies, execute commands, edit files, and run tests.
24
+
25
+ ## Key Features
26
+
27
+ - **Extensible Framework**: Plugin-based architecture for custom tools and behaviors
28
+ - **Multi-LLM Support**: Works with various LLM providers
29
+ - **Agent Client Protocol (ACP)**: Native ACP support for editor integration
30
+ - **Multiple Interfaces**: CLI, and ACP server modes
31
+
32
+ ## Configuration
33
+
34
+ You can override ACP configurations using environment variables:
35
+ - `GOOSE_PROVIDER`: Set your preferred LLM provider
36
+ - `GOOSE_MODEL`: Specify the model to use
37
+
38
+ ---
39
+
40
+ **Documentation**: https://block.github.io/goose/docs/guides/acp-clients/
41
+ **GitHub**: https://github.com/block/goose
42
+ **Quickstart**: https://block.github.io/goose/docs/quickstart/
43
+ '''
44
+
45
+ [actions."*".install]
46
+ command = "curl -fsSL https://github.com/block/goose/releases/download/stable/download_cli.sh | bash"
47
+ description = "Install Goose"
48
+
49
+ [action."*".update]
50
+ command = "Update Goose"
51
+ description = "Update Goose"
@@ -0,0 +1,33 @@
1
+ # Schema defined in agent_schema.py
2
+
3
+ active = true
4
+ identity = "inference.huggingface.co"
5
+ name = "Hugging Face Inference Providers"
6
+ short_name = "hf"
7
+ url = "https://huggingface.co"
8
+ protocol = "acp"
9
+ author_name = "Hugging Face"
10
+ author_url = "https://huffingface.co"
11
+ publisher_name = "Hugging Face"
12
+ publisher_url = "https://huffingface.co"
13
+ type = "chat"
14
+ description = """
15
+ Chat with the latest open weight models from Hugging Face inference Providers. Create an account at HuggingFace account and register with [b]toad-hf-inference-explorers[/] for [bold $success]$10[/] of free credit!"""
16
+ tags = []
17
+ run_command."*" = "hf-inference-acp -x"
18
+
19
+ help = '''
20
+ # Hugging Face Inference Providers
21
+
22
+ Chat with the latest open weight models using Hugging Face inference providers.
23
+
24
+ ---
25
+
26
+ Create an account at huggingface.co/join and register with [Toad Explorers](https://huggingface.co/toad-hf-inference-explorers) for **$10** of free credit!
27
+ '''
28
+
29
+ recommended = true
30
+
31
+ [actions."*".install]
32
+ command = "uv tool install -U hf-inference-acp --with-executables-from huggingface_hub --force"
33
+ description = "Install Hugging Face Inference Providers"