@softspark/ai-toolkit 2.2.0 → 2.3.0
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.
- package/AGENTS.md +1 -1
- package/CHANGELOG.md +12 -0
- package/README.md +3 -3
- package/app/.claude-plugin/plugin.json +1 -1
- package/app/ARCHITECTURE.md +1 -1
- package/app/mcp-templates/README.md +5 -3
- package/app/mcp-templates/jira.json +11 -0
- package/kb/reference/architecture-overview.md +1 -1
- package/kb/reference/cli-reference.md +1 -1
- package/kb/reference/manifest-install.md +1 -1
- package/kb/reference/mcp-templates.md +2 -2
- package/llms-full.txt +5 -5
- package/manifest.json +2 -2
- package/package.json +1 -1
- package/scripts/install.py +32 -0
- package/scripts/install_steps/install_state.py +29 -0
- package/scripts/mcp_editors.py +2 -2
- package/scripts/mcp_manager.py +29 -0
package/AGENTS.md
CHANGED
|
@@ -602,7 +602,7 @@ Tools: `sync_tasks`, `read_cached_tasks`, `update_task_status`, `update_task`, `
|
|
|
602
602
|
3. `get_task_details(task_key="PROJ-123")` -- deep dive (description + comments as markdown)
|
|
603
603
|
4. `update_task_status(...)` / `add_task_comment(...)` / `log_task_time(...)` -- mutate
|
|
604
604
|
|
|
605
|
-
## Comment Templates (
|
|
605
|
+
## Comment Templates (built-in)
|
|
606
606
|
|
|
607
607
|
| ID | Use for |
|
|
608
608
|
|----|---------|
|
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,18 @@ Versioning follows [Semantic Versioning](https://semver.org/).
|
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
+
## v2.3.0 — Jira MCP Template & Cross-Editor Sync (2026-04-14)
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- **Jira MCP template** — `ai-toolkit mcp add jira` installs `@softspark/jira-mcp` via global binary. Templates now support `postInstall` field for first-time setup hints shown after `mcp add`, `mcp install`, and `mcp show`. MCP template count: 25 → 26.
|
|
14
|
+
- **MCP template tracking** — globally installed templates are recorded in `state.json`. `ai-toolkit update` automatically syncs tracked templates to Claude global config. `ai-toolkit status` shows tracked MCP templates. "Install once, sync everywhere."
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
- **Claude MCP config paths** — corrected to `~/.claude.json` (global) and `.mcp.json` (project) per official Claude Code docs. Previously wrote to `~/.claude/settings.json` and `.claude/settings.local.json`.
|
|
18
|
+
- **Jira MCP template uses global binary** — `jira-mcp` instead of `npx -y` for faster startup and offline support
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
10
22
|
## v2.2.0 — URL Rules & Registry Safety (2026-04-14)
|
|
11
23
|
|
|
12
24
|
### Added
|
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
[](LICENSE)
|
|
7
7
|
[](app/skills/)
|
|
8
8
|
[](app/agents/)
|
|
9
|
-
[](tests/)
|
|
10
10
|
|
|
11
11
|
---
|
|
12
12
|
|
|
@@ -142,7 +142,7 @@ ai-toolkit/
|
|
|
142
142
|
│ └── ARCHITECTURE.md # Full system design
|
|
143
143
|
├── kb/ # Reference docs, procedures, plans
|
|
144
144
|
├── scripts/ # Validation, install, evaluation scripts
|
|
145
|
-
├── tests/ # Bats test suite (
|
|
145
|
+
├── tests/ # Bats test suite (606 tests)
|
|
146
146
|
└── CHANGELOG.md
|
|
147
147
|
```
|
|
148
148
|
|
|
@@ -174,7 +174,7 @@ ai-toolkit/
|
|
|
174
174
|
|
|
175
175
|
**68 language rules** — 13 languages, 5 categories each. Auto-detected or explicit `--lang`. See [Language Rules](kb/reference/language-rules.md).
|
|
176
176
|
|
|
177
|
-
**
|
|
177
|
+
**26 MCP templates** — Ready-to-use configs for GitHub, PostgreSQL, Slack, Jira, Sentry, and more. See [MCP Templates](kb/reference/mcp-templates.md).
|
|
178
178
|
|
|
179
179
|
See [Unique Features](kb/reference/unique-features.md) for detailed descriptions of all differentiators.
|
|
180
180
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ai-toolkit",
|
|
3
3
|
"description": "Professional-grade Claude Code toolkit with persona presets, skill security auditor, expanded lifecycle hooks, experimental opt-in plugin packs, benchmark harvesting, and multi-tool support.",
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.3.0",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "SoftSpark",
|
|
7
7
|
"url": "https://github.com/softspark"
|
package/app/ARCHITECTURE.md
CHANGED
|
@@ -302,7 +302,7 @@ Lead Session (You)
|
|
|
302
302
|
## Extension Points
|
|
303
303
|
|
|
304
304
|
### MCP Templates (25)
|
|
305
|
-
`app/plugins/mcp-templates/` ships
|
|
305
|
+
`app/plugins/mcp-templates/` ships 26 ready-to-use MCP server config templates (filesystems, databases, GitHub, Slack, etc.). Opt-in via `ai-toolkit install --modules mcp-templates` or activated automatically with `--profile strict|full`.
|
|
306
306
|
|
|
307
307
|
### Language Rules (68 files, 13 languages)
|
|
308
308
|
`app/rules/` contains per-language coding rules. Supported languages: TypeScript, Python, Go, Rust, Java, Kotlin, Swift, Dart, C#, PHP, C++, Ruby, and common (shared). Auto-detected from project files via `--auto-detect` or selected with `--modules rules-<lang>`.
|
|
@@ -77,6 +77,7 @@ Example -- adding GitHub to `.mcp.json`:
|
|
|
77
77
|
| `vercel` | Vercel deployments and settings |
|
|
78
78
|
| `datadog` | Datadog monitoring and metrics |
|
|
79
79
|
| `grafana` | Grafana dashboards and alerting |
|
|
80
|
+
| `jira` | Jira multi-instance routing, ADF, caching, comment templates |
|
|
80
81
|
| `custom-template` | Empty template for custom servers |
|
|
81
82
|
|
|
82
83
|
## Contributing a new template
|
|
@@ -100,6 +101,7 @@ Example -- adding GitHub to `.mcp.json`:
|
|
|
100
101
|
```
|
|
101
102
|
|
|
102
103
|
2. Use `${ENV_VAR}` syntax for any secrets or tokens
|
|
103
|
-
3.
|
|
104
|
-
4.
|
|
105
|
-
5.
|
|
104
|
+
3. Optional: add `"postInstall": "setup instructions"` for first-time config hints
|
|
105
|
+
4. Keep the `name` field matching the filename (without `.json`)
|
|
106
|
+
5. Update this README table
|
|
107
|
+
6. Run `python3 scripts/validate.py` to verify
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "jira",
|
|
3
|
+
"description": "Jira integration — multi-instance routing, ADF formatting, task caching, and comment templates",
|
|
4
|
+
"mcpServers": {
|
|
5
|
+
"jira": {
|
|
6
|
+
"command": "jira-mcp",
|
|
7
|
+
"args": []
|
|
8
|
+
}
|
|
9
|
+
},
|
|
10
|
+
"postInstall": "Run 'npm install -g @softspark/jira-mcp && jira-mcp config init' to install and set up credentials."
|
|
11
|
+
}
|
|
@@ -335,7 +335,7 @@ Severity levels: HIGH (blocks deployment), WARN (should fix), INFO (best practic
|
|
|
335
335
|
## Extension Points
|
|
336
336
|
|
|
337
337
|
### MCP Templates
|
|
338
|
-
`app/plugins/mcp-templates/` contains
|
|
338
|
+
`app/plugins/mcp-templates/` contains 26 ready-to-use MCP server config templates. Opt-in via `ai-toolkit install --modules mcp-templates` or activated automatically with `--profile strict|full`.
|
|
339
339
|
|
|
340
340
|
### Language Rules
|
|
341
341
|
`app/rules/` provides language-specific rule files covering 13 languages (TypeScript, Python, Go, Rust, Java, Kotlin, Swift, Dart, C#, PHP, C++, Ruby, common). Auto-detected from project files via `--auto-detect` or selectable with `--modules rules-<lang>`. See README.md for current count.
|
|
@@ -43,7 +43,7 @@ Usage: ai-toolkit <command> [options]
|
|
|
43
43
|
|
|
44
44
|
| Command | Description |
|
|
45
45
|
|---------|-------------|
|
|
46
|
-
| `mcp list` | List available MCP server templates (
|
|
46
|
+
| `mcp list` | List available MCP server templates (26 templates) |
|
|
47
47
|
| `mcp editors` | List editors with native MCP config adapters and scopes |
|
|
48
48
|
| `mcp add <name> [names...]` | Add MCP server template(s) to `.mcp.json` |
|
|
49
49
|
| `mcp install --editor <name[,..]> [names...]` | Install templates into native editor MCP config |
|
|
@@ -39,7 +39,7 @@ Modules are defined in `manifest.json` at the repository root. There are 17 modu
|
|
|
39
39
|
| `rules-php` | PHP-specific rules (5 files) | auto-detect |
|
|
40
40
|
| `rules-cpp` | C++-specific rules (5 files) | auto-detect |
|
|
41
41
|
| `rules-ruby` | Ruby-specific rules (5 files) | auto-detect |
|
|
42
|
-
| `mcp-templates` |
|
|
42
|
+
| `mcp-templates` | 26 MCP server config templates | strict, full |
|
|
43
43
|
|
|
44
44
|
## Profiles
|
|
45
45
|
|
|
@@ -6,14 +6,14 @@ tags: [mcp, templates, servers, configuration, editors]
|
|
|
6
6
|
version: "1.1.0"
|
|
7
7
|
created: "2026-04-07"
|
|
8
8
|
last_updated: "2026-04-12"
|
|
9
|
-
description: "Reference for
|
|
9
|
+
description: "Reference for 26 MCP server templates plus native editor MCP installation support."
|
|
10
10
|
---
|
|
11
11
|
|
|
12
12
|
# MCP Server Templates
|
|
13
13
|
|
|
14
14
|
## Overview
|
|
15
15
|
|
|
16
|
-
ai-toolkit ships
|
|
16
|
+
ai-toolkit ships 26 ready-to-use MCP server configuration templates in `app/mcp-templates/`. Each template is a JSON file that defines the canonical `mcpServers` block for a specific service. Templates can be merged into the project's `.mcp.json` and rendered into editor-native MCP config files via the `ai-toolkit mcp` CLI subcommand.
|
|
17
17
|
|
|
18
18
|
## CLI
|
|
19
19
|
|
package/llms-full.txt
CHANGED
|
@@ -4774,7 +4774,7 @@ Severity levels: HIGH (blocks deployment), WARN (should fix), INFO (best practic
|
|
|
4774
4774
|
## Extension Points
|
|
4775
4775
|
|
|
4776
4776
|
### MCP Templates
|
|
4777
|
-
`app/plugins/mcp-templates/` contains
|
|
4777
|
+
`app/plugins/mcp-templates/` contains 26 ready-to-use MCP server config templates. Opt-in via `ai-toolkit install --modules mcp-templates` or activated automatically with `--profile strict|full`.
|
|
4778
4778
|
|
|
4779
4779
|
### Language Rules
|
|
4780
4780
|
`app/rules/` provides language-specific rule files covering 13 languages (TypeScript, Python, Go, Rust, Java, Kotlin, Swift, Dart, C#, PHP, C++, Ruby, common). Auto-detected from project files via `--auto-detect` or selectable with `--modules rules-<lang>`. See README.md for current count.
|
|
@@ -5164,7 +5164,7 @@ Usage: ai-toolkit <command> [options]
|
|
|
5164
5164
|
|
|
5165
5165
|
| Command | Description |
|
|
5166
5166
|
|---------|-------------|
|
|
5167
|
-
| `mcp list` | List available MCP server templates (
|
|
5167
|
+
| `mcp list` | List available MCP server templates (26 templates) |
|
|
5168
5168
|
| `mcp editors` | List editors with native MCP config adapters and scopes |
|
|
5169
5169
|
| `mcp add <name> [names...]` | Add MCP server template(s) to `.mcp.json` |
|
|
5170
5170
|
| `mcp install --editor <name[,..]> [names...]` | Install templates into native editor MCP config |
|
|
@@ -7814,7 +7814,7 @@ Modules are defined in `manifest.json` at the repository root. There are 17 modu
|
|
|
7814
7814
|
| `rules-php` | PHP-specific rules (5 files) | auto-detect |
|
|
7815
7815
|
| `rules-cpp` | C++-specific rules (5 files) | auto-detect |
|
|
7816
7816
|
| `rules-ruby` | Ruby-specific rules (5 files) | auto-detect |
|
|
7817
|
-
| `mcp-templates` |
|
|
7817
|
+
| `mcp-templates` | 26 MCP server config templates | strict, full |
|
|
7818
7818
|
|
|
7819
7819
|
## Profiles
|
|
7820
7820
|
|
|
@@ -8018,14 +8018,14 @@ tags: [mcp, templates, servers, configuration, editors]
|
|
|
8018
8018
|
version: "1.1.0"
|
|
8019
8019
|
created: "2026-04-07"
|
|
8020
8020
|
last_updated: "2026-04-12"
|
|
8021
|
-
description: "Reference for
|
|
8021
|
+
description: "Reference for 26 MCP server templates plus native editor MCP installation support."
|
|
8022
8022
|
---
|
|
8023
8023
|
|
|
8024
8024
|
# MCP Server Templates
|
|
8025
8025
|
|
|
8026
8026
|
## Overview
|
|
8027
8027
|
|
|
8028
|
-
ai-toolkit ships
|
|
8028
|
+
ai-toolkit ships 26 ready-to-use MCP server configuration templates in `app/mcp-templates/`. Each template is a JSON file that defines the canonical `mcpServers` block for a specific service. Templates can be merged into the project's `.mcp.json` and rendered into editor-native MCP config files via the `ai-toolkit mcp` CLI subcommand.
|
|
8029
8029
|
|
|
8030
8030
|
## CLI
|
|
8031
8031
|
|
package/manifest.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "2.
|
|
2
|
+
"version": "2.3.0",
|
|
3
3
|
"components": {
|
|
4
4
|
"agents": {
|
|
5
5
|
"description": "44 specialized agents (orchestrator, backend, frontend, security, devops, etc.)",
|
|
@@ -146,7 +146,7 @@
|
|
|
146
146
|
"auto_detect": ["Gemfile", "*.gemspec"]
|
|
147
147
|
},
|
|
148
148
|
"mcp-templates": {
|
|
149
|
-
"description": "
|
|
149
|
+
"description": "26 MCP server config templates",
|
|
150
150
|
"default": false
|
|
151
151
|
}
|
|
152
152
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@softspark/ai-toolkit",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.0",
|
|
4
4
|
"description": "Professional-grade AI coding toolkit: 92 skills, 44 agents, multi-platform support (Claude, Cursor, Windsurf, Copilot, Gemini, Cline, Roo Code, Aider, Augment, Google Antigravity, Codex CLI), machine-enforced safety constitution, persona presets, skill security auditor, expanded lifecycle hooks, 11 plugin packs, and benchmark tooling.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"claude",
|
package/scripts/install.py
CHANGED
|
@@ -432,6 +432,38 @@ def install_claude_code(target_dir: Path, hooks_scripts_dir: Path,
|
|
|
432
432
|
inject_rules(claude_dir, target_dir, rules_dir, only, skip, dry_run,
|
|
433
433
|
refresh_urls=True)
|
|
434
434
|
|
|
435
|
+
_sync_mcp_templates(dry_run)
|
|
436
|
+
|
|
437
|
+
|
|
438
|
+
def _sync_mcp_templates(dry_run: bool) -> None:
|
|
439
|
+
"""Re-install tracked MCP templates into Claude global config."""
|
|
440
|
+
from install_steps.install_state import get_mcp_templates
|
|
441
|
+
|
|
442
|
+
templates = get_mcp_templates()
|
|
443
|
+
if not templates:
|
|
444
|
+
return
|
|
445
|
+
|
|
446
|
+
if dry_run:
|
|
447
|
+
print(f" Would sync MCP templates: {', '.join(templates)}")
|
|
448
|
+
return
|
|
449
|
+
|
|
450
|
+
from mcp_editors import install_servers
|
|
451
|
+
|
|
452
|
+
servers: dict = {}
|
|
453
|
+
for name in templates:
|
|
454
|
+
try:
|
|
455
|
+
tpl_path = app_dir / "mcp-templates" / f"{name}.json"
|
|
456
|
+
if tpl_path.is_file():
|
|
457
|
+
import json as _json
|
|
458
|
+
data = _json.loads(tpl_path.read_text(encoding="utf-8"))
|
|
459
|
+
servers.update(data.get("mcpServers", {}))
|
|
460
|
+
except Exception:
|
|
461
|
+
pass # Skip broken templates silently
|
|
462
|
+
|
|
463
|
+
if servers:
|
|
464
|
+
install_servers(["claude"], servers, scope="global")
|
|
465
|
+
print(f" MCP synced: {', '.join(templates)}")
|
|
466
|
+
|
|
435
467
|
|
|
436
468
|
VALID_PERSONAS = ("backend-lead", "frontend-lead", "devops-eng", "junior-dev")
|
|
437
469
|
|
|
@@ -60,6 +60,31 @@ def get_installed_profile() -> str:
|
|
|
60
60
|
return state.get("profile", "")
|
|
61
61
|
|
|
62
62
|
|
|
63
|
+
def get_mcp_templates() -> list[str]:
|
|
64
|
+
"""Return list of globally tracked MCP template names."""
|
|
65
|
+
state = load_state()
|
|
66
|
+
templates = state.get("mcp_templates", [])
|
|
67
|
+
return templates if isinstance(templates, list) else []
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def record_mcp_template(name: str) -> None:
|
|
71
|
+
"""Add a template name to the tracked set in state.json."""
|
|
72
|
+
state = load_state()
|
|
73
|
+
templates = set(state.get("mcp_templates", []))
|
|
74
|
+
templates.add(name)
|
|
75
|
+
state["mcp_templates"] = sorted(templates)
|
|
76
|
+
save_state(state)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def remove_mcp_template(name: str) -> None:
|
|
80
|
+
"""Remove a template name from the tracked set in state.json."""
|
|
81
|
+
state = load_state()
|
|
82
|
+
templates = set(state.get("mcp_templates", []))
|
|
83
|
+
templates.discard(name)
|
|
84
|
+
state["mcp_templates"] = sorted(templates)
|
|
85
|
+
save_state(state)
|
|
86
|
+
|
|
87
|
+
|
|
63
88
|
def _now_iso() -> str:
|
|
64
89
|
"""Return current UTC time in ISO 8601 format."""
|
|
65
90
|
return datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
|
|
@@ -138,6 +163,10 @@ def print_status() -> None:
|
|
|
138
163
|
langs = [m.replace("rules-", "") for m in detected]
|
|
139
164
|
print(f" Detected: {', '.join(langs)}")
|
|
140
165
|
|
|
166
|
+
mcp = state.get("mcp_templates", [])
|
|
167
|
+
if mcp:
|
|
168
|
+
print(f" MCP: {', '.join(mcp)}")
|
|
169
|
+
|
|
141
170
|
extends = state.get("extends")
|
|
142
171
|
if extends:
|
|
143
172
|
print(f" Extends: {extends.get('source', 'unknown')}")
|
package/scripts/mcp_editors.py
CHANGED
|
@@ -15,8 +15,8 @@ except ModuleNotFoundError: # pragma: no cover - Python 3.11+ should have tomll
|
|
|
15
15
|
EDITOR_SPECS: dict[str, dict[str, str | None]] = {
|
|
16
16
|
"claude": {
|
|
17
17
|
"label": "Claude Code",
|
|
18
|
-
"project_path": ".
|
|
19
|
-
"global_path": ".claude
|
|
18
|
+
"project_path": ".mcp.json",
|
|
19
|
+
"global_path": ".claude.json",
|
|
20
20
|
"format": "json",
|
|
21
21
|
"doc_scope": "project + global",
|
|
22
22
|
},
|
package/scripts/mcp_manager.py
CHANGED
|
@@ -130,6 +130,11 @@ def cmd_show(name: str) -> None:
|
|
|
130
130
|
for key, val in env_vars:
|
|
131
131
|
print(f" {key} = {val}")
|
|
132
132
|
|
|
133
|
+
post_install = data.get("postInstall")
|
|
134
|
+
if post_install:
|
|
135
|
+
print()
|
|
136
|
+
print(f"Setup: {post_install}")
|
|
137
|
+
|
|
133
138
|
|
|
134
139
|
def cmd_add(names: list[str], target_dir: Path) -> None:
|
|
135
140
|
"""Add one or more MCP templates to .mcp.json."""
|
|
@@ -155,6 +160,13 @@ def cmd_add(names: list[str], target_dir: Path) -> None:
|
|
|
155
160
|
write_mcp_config(target_dir, config)
|
|
156
161
|
print(f"Added: {', '.join(added)}")
|
|
157
162
|
|
|
163
|
+
# Show postInstall hints from added templates
|
|
164
|
+
for name in names:
|
|
165
|
+
data = load_template(name)
|
|
166
|
+
post_install = data.get("postInstall")
|
|
167
|
+
if post_install:
|
|
168
|
+
print(f"\n Note ({name}): {post_install}")
|
|
169
|
+
|
|
158
170
|
|
|
159
171
|
def cmd_install(
|
|
160
172
|
names: list[str],
|
|
@@ -203,6 +215,20 @@ def cmd_install(
|
|
|
203
215
|
for path in updated:
|
|
204
216
|
print(f"Updated: {path}")
|
|
205
217
|
|
|
218
|
+
# Track globally installed templates in state.json
|
|
219
|
+
if eff_scope == "global" and names:
|
|
220
|
+
from install_steps.install_state import record_mcp_template
|
|
221
|
+
for name in names:
|
|
222
|
+
record_mcp_template(name)
|
|
223
|
+
|
|
224
|
+
# Show postInstall hints from installed templates
|
|
225
|
+
if names:
|
|
226
|
+
for name in names:
|
|
227
|
+
data = load_template(name)
|
|
228
|
+
post_install = data.get("postInstall")
|
|
229
|
+
if post_install:
|
|
230
|
+
print(f"\n Note ({name}): {post_install}")
|
|
231
|
+
|
|
206
232
|
|
|
207
233
|
def cmd_remove(name: str, target_dir: Path | None, *, editors: list[str], scope: str | None) -> None:
|
|
208
234
|
"""Remove an MCP server from .mcp.json."""
|
|
@@ -223,6 +249,9 @@ def cmd_remove(name: str, target_dir: Path | None, *, editors: list[str], scope:
|
|
|
223
249
|
)
|
|
224
250
|
else:
|
|
225
251
|
updated = remove_servers(editors, [name], scope="global")
|
|
252
|
+
# Untrack globally removed template from state.json
|
|
253
|
+
from install_steps.install_state import remove_mcp_template
|
|
254
|
+
remove_mcp_template(name)
|
|
226
255
|
for path in updated:
|
|
227
256
|
print(f"Updated: {path}")
|
|
228
257
|
print(f"Removed: {name}")
|