agentworks-cli 0.2.1__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 (59) hide show
  1. agentworks/__init__.py +1 -0
  2. agentworks/agents/__init__.py +0 -0
  3. agentworks/agents/manager.py +1095 -0
  4. agentworks/agents/templates.py +145 -0
  5. agentworks/catalog.py +264 -0
  6. agentworks/catalog.toml +131 -0
  7. agentworks/cli.py +1462 -0
  8. agentworks/completions/__init__.py +33 -0
  9. agentworks/completions/bash.py +179 -0
  10. agentworks/completions/install.py +122 -0
  11. agentworks/completions/powershell.py +270 -0
  12. agentworks/completions/spec.py +216 -0
  13. agentworks/completions/zsh.py +256 -0
  14. agentworks/config.py +894 -0
  15. agentworks/db.py +1083 -0
  16. agentworks/doctor.py +430 -0
  17. agentworks/git_credentials/__init__.py +0 -0
  18. agentworks/git_credentials/azdo.py +29 -0
  19. agentworks/git_credentials/base.py +71 -0
  20. agentworks/git_credentials/github.py +22 -0
  21. agentworks/nerf-config.yaml +16 -0
  22. agentworks/output.py +296 -0
  23. agentworks/remote_exec.py +286 -0
  24. agentworks/sample-config.toml +289 -0
  25. agentworks/sessions/__init__.py +0 -0
  26. agentworks/sessions/console.py +164 -0
  27. agentworks/sessions/manager.py +1297 -0
  28. agentworks/sessions/templates.py +101 -0
  29. agentworks/sessions/tmux.py +503 -0
  30. agentworks/sources.py +303 -0
  31. agentworks/ssh.py +759 -0
  32. agentworks/ssh_config.py +255 -0
  33. agentworks/vm_hosts/__init__.py +0 -0
  34. agentworks/vm_hosts/manager.py +86 -0
  35. agentworks/vms/__init__.py +0 -0
  36. agentworks/vms/backup.py +409 -0
  37. agentworks/vms/base.py +56 -0
  38. agentworks/vms/bootstrap_script.py +185 -0
  39. agentworks/vms/cloud_init.py +55 -0
  40. agentworks/vms/initializer.py +1523 -0
  41. agentworks/vms/manager.py +1122 -0
  42. agentworks/vms/provisioners/__init__.py +0 -0
  43. agentworks/vms/provisioners/azure.py +602 -0
  44. agentworks/vms/provisioners/lima.py +295 -0
  45. agentworks/vms/provisioners/proxmox.py +279 -0
  46. agentworks/vms/provisioners/proxmox_api.py +261 -0
  47. agentworks/vms/provisioners/wsl2.py +340 -0
  48. agentworks/vms/templates.py +152 -0
  49. agentworks/workspaces/__init__.py +0 -0
  50. agentworks/workspaces/backends/__init__.py +0 -0
  51. agentworks/workspaces/backends/local.py +119 -0
  52. agentworks/workspaces/backends/vm.py +175 -0
  53. agentworks/workspaces/manager.py +1080 -0
  54. agentworks/workspaces/templates.py +76 -0
  55. agentworks/workspaces/tmuxinator.py +80 -0
  56. agentworks_cli-0.2.1.dist-info/METADATA +635 -0
  57. agentworks_cli-0.2.1.dist-info/RECORD +59 -0
  58. agentworks_cli-0.2.1.dist-info/WHEEL +4 -0
  59. agentworks_cli-0.2.1.dist-info/entry_points.txt +2 -0
@@ -0,0 +1,216 @@
1
+ """Introspect the Typer/Click command tree and build a completion spec."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import hashlib
6
+ import json
7
+ from dataclasses import dataclass, field
8
+
9
+ import click
10
+ import typer
11
+
12
+ # -- Data model ------------------------------------------------------------
13
+
14
+
15
+ @dataclass
16
+ class ParamSpec:
17
+ """Specification for a single CLI parameter."""
18
+
19
+ name: str
20
+ opts: list[str]
21
+ help: str
22
+ is_flag: bool
23
+ is_argument: bool
24
+ multiple: bool
25
+ required: bool
26
+ choices: list[str] | None = None
27
+ dynamic_completer: str | None = None
28
+
29
+
30
+ @dataclass
31
+ class CommandSpec:
32
+ """Specification for a CLI command or group."""
33
+
34
+ name: str
35
+ help: str
36
+ params: list[ParamSpec] = field(default_factory=list)
37
+ subcommands: dict[str, CommandSpec] = field(default_factory=dict)
38
+
39
+
40
+ # -- Dynamic completions (the only hand-maintained piece) ------------------
41
+
42
+ # Maps (dotted_command_path, param_name) to a completer identifier.
43
+ # Completer identifiers are abstract labels that each shell generator
44
+ # knows how to render into shell-specific completion functions.
45
+ #
46
+ # The completer identifiers and their corresponding CLI commands:
47
+ # "vms" -> agentworks vm list
48
+ # "vm_hosts" -> agentworks vm-host list
49
+ # "workspaces" -> agentworks workspace list
50
+ # "ws_templates" -> [workspace_templates.*] sections in config.toml
51
+ # "git_credentials" -> [git_credentials.*] sections in config.toml
52
+ # "catalog_entries" -> all entry names from built-in + custom catalog
53
+ # "sessions" -> agentworks session list --no-status
54
+ # "session_templates" -> [session_templates.*] sections in config.toml
55
+ # "agents" -> agentworks agent list
56
+ # "vm_templates" -> [vm_templates.*] sections in config.toml
57
+ # "agent_templates" -> [agent_templates.*] sections in config.toml
58
+
59
+ DYNAMIC_COMPLETIONS: dict[tuple[str, str], str] = {
60
+ ("vm.start", "name"): "vms",
61
+ ("vm.stop", "name"): "vms",
62
+ ("vm.delete", "name"): "vms",
63
+ ("vm.rekey", "name"): "vms",
64
+ ("vm.backup", "name"): "vms",
65
+ ("vm.describe", "name"): "vms",
66
+ ("vm.reinit", "name"): "vms",
67
+ ("vm.exec", "name"): "vms",
68
+ ("vm.shell", "name"): "vms",
69
+ ("vm.add-git-credential", "name"): "vms",
70
+ ("vm.port-forward", "name"): "vms",
71
+ ("vm.create", "template"): "vm_templates",
72
+ ("vm.create", "vm_host"): "vm_hosts",
73
+ ("vm-host.remove", "name"): "vm_hosts",
74
+ ("workspace.shell", "name"): "workspaces",
75
+ ("workspace.console", "name"): "workspaces",
76
+ ("workspace.copy", "source"): "workspaces",
77
+ ("workspace.copy", "vm"): "vms",
78
+ ("workspace.describe", "name"): "workspaces",
79
+ ("workspace.rehome", "name"): "workspaces",
80
+ ("workspace.repair", "name"): "workspaces",
81
+ ("workspace.delete", "name"): "workspaces",
82
+ ("workspace.create", "vm"): "vms",
83
+ ("workspace.create", "template"): "ws_templates",
84
+ ("workspace.list", "vm"): "vms",
85
+ ("vm.logs", "name"): "vms",
86
+ ("vm.add-git-credential", "credential"): "git_credentials",
87
+ ("agent.create", "vm"): "vms",
88
+ ("agent.create", "template"): "agent_templates",
89
+ ("agent.describe", "name"): "agents",
90
+ ("agent.reinit", "name"): "agents",
91
+ ("agent.workspace-grants.grant", "name"): "agents",
92
+ ("agent.workspace-grants.deny", "name"): "agents",
93
+ ("agent.workspace-grants.list", "name"): "agents",
94
+ ("agent.exec", "name"): "agents",
95
+ ("agent.shell", "name"): "agents",
96
+ ("agent.shell", "workspace"): "workspaces",
97
+ ("agent.delete", "name"): "agents",
98
+ ("agent.list", "vm"): "vms",
99
+ ("installer.describe", "name"): "catalog_entries",
100
+ # Session commands
101
+ ("session.create", "agent"): "agents",
102
+ ("session.create", "workspace"): "workspaces",
103
+ ("session.create", "template"): "session_templates",
104
+ ("session.create", "workspace_template"): "ws_templates",
105
+ ("session.create", "vm"): "vms",
106
+ ("session.describe", "name"): "sessions",
107
+ ("session.list", "workspace"): "workspaces",
108
+ ("session.stop", "name"): "sessions",
109
+ ("session.stop", "vm"): "vms",
110
+ ("session.stop", "workspace"): "workspaces",
111
+ ("session.restart", "name"): "sessions",
112
+ ("session.restart", "vm"): "vms",
113
+ ("session.restart", "workspace"): "workspaces",
114
+
115
+ ("session.attach", "name"): "sessions",
116
+ ("session.delete", "name"): "sessions",
117
+ ("session.logs", "name"): "sessions",
118
+
119
+ # VM console
120
+ ("vm.console", "name"): "vms",
121
+ }
122
+
123
+
124
+ # -- Introspection ---------------------------------------------------------
125
+
126
+
127
+ def build_spec(app: typer.Typer) -> CommandSpec:
128
+ """Walk the Typer app and build a CommandSpec tree."""
129
+ click_app = typer.main.get_command(app)
130
+ return _build_command_spec(click_app, path="")
131
+
132
+
133
+ def _build_command_spec(cmd: click.Command, path: str) -> CommandSpec:
134
+ """Recursively build a CommandSpec from a Click command."""
135
+ help_text = (cmd.help or "").split("\n")[0].strip()
136
+ name = cmd.name or ""
137
+
138
+ spec = CommandSpec(name=name, help=help_text)
139
+
140
+ # Build params
141
+ current_path = f"{path}.{name}" if path else name
142
+ for param in cmd.params:
143
+ if param.name == "help" or getattr(param, "hidden", False):
144
+ continue
145
+ spec.params.append(_build_param_spec(param, current_path))
146
+
147
+ # Build subcommands for groups
148
+ if isinstance(cmd, click.Group):
149
+ ctx = click.Context(cmd, info_name=name)
150
+ for sub_name in cmd.list_commands(ctx):
151
+ sub_cmd = cmd.get_command(ctx, sub_name)
152
+ if sub_cmd is not None:
153
+ spec.subcommands[sub_name] = _build_command_spec(sub_cmd, path=current_path)
154
+
155
+ return spec
156
+
157
+
158
+ def _build_param_spec(param: click.Parameter, command_path: str) -> ParamSpec:
159
+ """Build a ParamSpec from a Click parameter."""
160
+ is_argument = isinstance(param, click.Argument)
161
+
162
+ choices = None
163
+ if isinstance(param.type, click.Choice):
164
+ choices = list(param.type.choices)
165
+
166
+ opts: list[str] = []
167
+ if isinstance(param, click.Option):
168
+ opts = list(param.opts)
169
+
170
+ # DYNAMIC_COMPLETIONS keys use paths without the root app name
171
+ # (e.g. "vm.shell" not "agentworks.vm.shell")
172
+ lookup_path = ".".join(command_path.split(".")[1:]) if "." in command_path else command_path
173
+ dynamic = DYNAMIC_COMPLETIONS.get((lookup_path, param.name or ""))
174
+
175
+ return ParamSpec(
176
+ name=param.name or "",
177
+ opts=opts,
178
+ help=getattr(param, "help", None) or "",
179
+ is_flag=getattr(param, "is_flag", False),
180
+ is_argument=is_argument,
181
+ multiple=param.multiple,
182
+ required=param.required,
183
+ choices=choices,
184
+ dynamic_completer=dynamic,
185
+ )
186
+
187
+
188
+ # -- Version stamp ---------------------------------------------------------
189
+
190
+
191
+ def completion_version(spec: CommandSpec) -> str:
192
+ """Compute a content hash of the spec for staleness detection."""
193
+ serialized = json.dumps(_spec_to_dict(spec), sort_keys=True)
194
+ return hashlib.sha256(serialized.encode()).hexdigest()[:12]
195
+
196
+
197
+ def _spec_to_dict(spec: CommandSpec) -> dict: # type: ignore[type-arg]
198
+ """Serialize a CommandSpec tree to a dict for hashing."""
199
+ return {
200
+ "name": spec.name,
201
+ "help": spec.help,
202
+ "params": [
203
+ {
204
+ "name": p.name,
205
+ "opts": p.opts,
206
+ "is_flag": p.is_flag,
207
+ "is_argument": p.is_argument,
208
+ "multiple": p.multiple,
209
+ "required": p.required,
210
+ "choices": p.choices,
211
+ "dynamic_completer": p.dynamic_completer,
212
+ }
213
+ for p in spec.params
214
+ ],
215
+ "subcommands": {k: _spec_to_dict(v) for k, v in sorted(spec.subcommands.items())},
216
+ }
@@ -0,0 +1,256 @@
1
+ """Generate zsh completion script from a CommandSpec."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import TYPE_CHECKING
6
+
7
+ if TYPE_CHECKING:
8
+ from agentworks.completions.spec import CommandSpec, ParamSpec
9
+
10
+ # Shell functions that provide dynamic completions.
11
+ # Each key matches a completer identifier from DYNAMIC_COMPLETIONS.
12
+ DYNAMIC_FUNCTIONS: dict[str, str] = {
13
+ "vms": """\
14
+ _agentworks_vms() {
15
+ local -a vms
16
+ vms=(${(f)"$(agentworks vm list 2>/dev/null | tail -n +3 | awk '{print $1}')"})
17
+ _describe 'vm' vms
18
+ }""",
19
+ "vm_hosts": """\
20
+ _agentworks_vm_hosts() {
21
+ local -a hosts
22
+ hosts=(${(f)"$(agentworks vm-host list 2>/dev/null | tail -n +3 | awk '{print $1}')"})
23
+ _describe 'vm-host' hosts
24
+ }""",
25
+ "workspaces": """\
26
+ _agentworks_workspaces() {
27
+ local -a workspaces
28
+ workspaces=(${(f)"$(agentworks workspace list 2>/dev/null | tail -n +3 | awk '{print $1}')"})
29
+ _describe 'workspace' workspaces
30
+ }""",
31
+ "ws_templates": """\
32
+ _agentworks_templates() {
33
+ local -a templates config_file
34
+ config_file="${HOME}/.config/agentworks/config.toml"
35
+ [[ -f "$config_file" ]] || return
36
+ templates=(${(f)"$(sed -n 's/^\\[workspace_templates\\.\\([^]]*\\)\\]/\\1/p' "$config_file" 2>/dev/null)"})
37
+ _describe 'template' templates
38
+ }""",
39
+ "git_credentials": """\
40
+ _agentworks_git_credentials() {
41
+ local -a creds config_file
42
+ config_file="${HOME}/.config/agentworks/config.toml"
43
+ [[ -f "$config_file" ]] || return
44
+ creds=(${(f)"$(sed -n 's/^\\[git_credentials\\.\\([^]]*\\)\\]/\\1/p' "$config_file" 2>/dev/null)"})
45
+ _describe 'git-credential' creds
46
+ }""",
47
+ "catalog_entries": """\
48
+ _agentworks_catalog_entries() {
49
+ local -a entries
50
+ entries=(${(f)"$(agentworks installer list 2>/dev/null | tail -n +3 | awk '{print $2}')"})
51
+ _describe 'installer' entries
52
+ }""",
53
+ "sessions": """\
54
+ _agentworks_sessions() {
55
+ local -a sessions
56
+ sessions=(${(f)"$(agentworks session list --no-status 2>/dev/null | tail -n +3 | awk '{print $1}')"})
57
+ _describe 'session' sessions
58
+ }""",
59
+ "agents": """\
60
+ _agentworks_agents() {
61
+ local -a agents
62
+ agents=(${(f)"$(agentworks agent list 2>/dev/null | tail -n +3 | awk '{print $1}')"})
63
+ _describe 'agent' agents
64
+ }""",
65
+ "session_templates": """\
66
+ _agentworks_session_templates() {
67
+ local -a templates config_file
68
+ config_file="${HOME}/.config/agentworks/config.toml"
69
+ templates=(default)
70
+ if [[ -f "$config_file" ]]; then
71
+ templates+=(${(f)"$(sed -n 's/^\\[session_templates\\.\\([^]]*\\)\\]/\\1/p' "$config_file" 2>/dev/null)"})
72
+ fi
73
+ _describe 'session-template' templates
74
+ }""",
75
+ "vm_templates": """\
76
+ _agentworks_vm_templates() {
77
+ local -a templates config_file
78
+ config_file="${HOME}/.config/agentworks/config.toml"
79
+ templates=()
80
+ if [[ -f "$config_file" ]]; then
81
+ templates+=(${(f)"$(sed -n 's/^\\[vm_templates\\.\\([^]]*\\)\\]/\\1/p' "$config_file" 2>/dev/null)"})
82
+ fi
83
+ _describe 'vm-template' templates
84
+ }""",
85
+ "agent_templates": """\
86
+ _agentworks_agent_templates() {
87
+ local -a templates config_file
88
+ config_file="${HOME}/.config/agentworks/config.toml"
89
+ templates=()
90
+ if [[ -f "$config_file" ]]; then
91
+ templates+=(${(f)"$(sed -n 's/^\\[agent_templates\\.\\([^]]*\\)\\]/\\1/p' "$config_file" 2>/dev/null)"})
92
+ fi
93
+ _describe 'agent-template' templates
94
+ }""",
95
+ }
96
+
97
+ # Maps completer identifiers to their zsh function names.
98
+ COMPLETER_FUNC_NAMES: dict[str, str] = {
99
+ "vms": "_agentworks_vms",
100
+ "vm_hosts": "_agentworks_vm_hosts",
101
+ "workspaces": "_agentworks_workspaces",
102
+ "ws_templates": "_agentworks_templates",
103
+ "git_credentials": "_agentworks_git_credentials",
104
+ "catalog_entries": "_agentworks_catalog_entries",
105
+ "sessions": "_agentworks_sessions",
106
+ "session_templates": "_agentworks_session_templates",
107
+ "vm_templates": "_agentworks_vm_templates",
108
+ "agent_templates": "_agentworks_agent_templates",
109
+ "agents": "_agentworks_agents",
110
+ }
111
+
112
+
113
+ def generate_zsh(spec: CommandSpec, version: str) -> str:
114
+ """Generate a complete zsh completion script."""
115
+ lines: list[str] = []
116
+
117
+ lines.append("#compdef agentworks")
118
+ lines.append("")
119
+ lines.append("# Auto-generated by agentworks. Do not edit.")
120
+ lines.append(f"# agentworks-completion-version: {version}")
121
+ lines.append("#")
122
+ lines.append("# Install (Oh My Zsh):")
123
+ lines.append("# mkdir -p ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/completions")
124
+ lines.append("# agentworks completion zsh > ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/completions/_agentworks")
125
+ lines.append("#")
126
+ lines.append("# Install (manual):")
127
+ lines.append("# mkdir -p ~/.zfunc && agentworks completion zsh > ~/.zfunc/_agentworks")
128
+ lines.append("# then add: fpath=(~/.zfunc $fpath) to your .zshrc before compinit")
129
+ lines.append("")
130
+
131
+ # Emit dynamic completer functions
132
+ used_completers = _collect_completers(spec)
133
+ for completer_id in sorted(used_completers):
134
+ if completer_id in DYNAMIC_FUNCTIONS:
135
+ lines.append(DYNAMIC_FUNCTIONS[completer_id])
136
+ lines.append("")
137
+
138
+ # Emit the main dispatch function
139
+ _emit_group(lines, spec, func_name="_agentworks")
140
+ lines.append("")
141
+ lines.append('_agentworks "$@"')
142
+ lines.append("")
143
+
144
+ return "\n".join(lines)
145
+
146
+
147
+ def _collect_completers(spec: CommandSpec) -> set[str]:
148
+ """Collect all dynamic completer identifiers used in the spec tree."""
149
+ completers: set[str] = set()
150
+ for param in spec.params:
151
+ if param.dynamic_completer:
152
+ completers.add(param.dynamic_completer)
153
+ for sub in spec.subcommands.values():
154
+ completers.update(_collect_completers(sub))
155
+ return completers
156
+
157
+
158
+ def _emit_group(lines: list[str], spec: CommandSpec, func_name: str) -> None:
159
+ """Emit a zsh function for a command group."""
160
+ lines.append(f"{func_name}() {{")
161
+ lines.append(" local -a subcommands")
162
+ lines.append(" _arguments -C \\")
163
+ lines.append(" '--help[Show help]' \\")
164
+ lines.append(" '1:command:->command' \\")
165
+ lines.append(" '*::arg:->args'")
166
+ lines.append("")
167
+ lines.append(" case $state in")
168
+ lines.append(" command)")
169
+ lines.append(" subcommands=(")
170
+
171
+ for name, sub in sorted(spec.subcommands.items()):
172
+ escaped_help = sub.help.replace("'", "'\\''")
173
+ lines.append(f" '{name}:{escaped_help}'")
174
+
175
+ lines.append(" )")
176
+ lines.append(" _describe 'command' subcommands")
177
+ lines.append(" ;;")
178
+ lines.append(" args)")
179
+ lines.append(" case $line[1] in")
180
+
181
+ for name, _sub in sorted(spec.subcommands.items()):
182
+ sub_func = f"{func_name}_{name.replace('-', '_')}"
183
+ lines.append(f" {name})")
184
+ lines.append(f' {sub_func} "$@"')
185
+ lines.append(" ;;")
186
+
187
+ lines.append(" esac")
188
+ lines.append(" ;;")
189
+ lines.append(" esac")
190
+ lines.append("}")
191
+
192
+ # Emit sub-functions
193
+ for name, sub in sorted(spec.subcommands.items()):
194
+ sub_func = f"{func_name}_{name.replace('-', '_')}"
195
+ lines.append("")
196
+ if sub.subcommands:
197
+ _emit_group(lines, sub, func_name=sub_func)
198
+ else:
199
+ _emit_leaf(lines, sub, func_name=sub_func)
200
+
201
+
202
+ def _emit_leaf(lines: list[str], spec: CommandSpec, func_name: str) -> None:
203
+ """Emit a zsh function for a leaf command."""
204
+ args = _build_arguments(spec.params)
205
+ if not args:
206
+ lines.append(f"{func_name}() {{")
207
+ lines.append(" _arguments \\")
208
+ lines.append(" '--help[Show help]'")
209
+ lines.append("}")
210
+ return
211
+
212
+ lines.append(f"{func_name}() {{")
213
+ lines.append(" _arguments \\")
214
+ for i, arg in enumerate(args):
215
+ separator = " \\" if i < len(args) else ""
216
+ lines.append(f" {arg}{separator}")
217
+ lines.append(" '--help[Show help]'")
218
+ lines.append("}")
219
+
220
+
221
+ def _build_arguments(params: list[ParamSpec]) -> list[str]:
222
+ """Build zsh _arguments specs from params."""
223
+ args: list[str] = []
224
+ positional_index = 1
225
+
226
+ for param in params:
227
+ if param.is_argument:
228
+ label = param.name
229
+ if param.choices:
230
+ choices_str = " ".join(param.choices)
231
+ args.append(f"'{positional_index}:{label}:({choices_str})'")
232
+ elif param.dynamic_completer and param.dynamic_completer in COMPLETER_FUNC_NAMES:
233
+ completer = f":{COMPLETER_FUNC_NAMES[param.dynamic_completer]}"
234
+ args.append(f"'{positional_index}:{label}{completer}'")
235
+ else:
236
+ args.append(f"'{positional_index}:{label}:'")
237
+ positional_index += 1
238
+ elif param.is_flag:
239
+ escaped_help = param.help.replace("'", "'\\''")
240
+ opt = param.opts[0] if param.opts else f"--{param.name}"
241
+ args.append(f"'{opt}[{escaped_help}]'")
242
+ else:
243
+ escaped_help = param.help.replace("'", "'\\''")
244
+ opt = param.opts[0] if param.opts else f"--{param.name}"
245
+ multiple = "*" if param.multiple else ""
246
+
247
+ if param.choices:
248
+ choices_str = " ".join(param.choices)
249
+ args.append(f"'{multiple}{opt}[{escaped_help}]:{param.name}:({choices_str})'")
250
+ elif param.dynamic_completer and param.dynamic_completer in COMPLETER_FUNC_NAMES:
251
+ func = COMPLETER_FUNC_NAMES[param.dynamic_completer]
252
+ args.append(f"'{multiple}{opt}[{escaped_help}]:{param.name}:{func}'")
253
+ else:
254
+ args.append(f"'{multiple}{opt}[{escaped_help}]:{param.name}:'")
255
+
256
+ return args