agent-switchboard 0.1.24 → 0.1.26
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/README.md +168 -229
- package/dist/agents/cursor.d.ts +1 -4
- package/dist/agents/cursor.js +4 -12
- package/dist/agents/cursor.js.map +1 -1
- package/dist/commands/distribution.d.ts +1 -1
- package/dist/commands/distribution.js +11 -2
- package/dist/commands/distribution.js.map +1 -1
- package/dist/commands/importer.d.ts +1 -1
- package/dist/commands/importer.js +4 -0
- package/dist/commands/importer.js.map +1 -1
- package/dist/config/paths.d.ts +2 -0
- package/dist/config/paths.js +6 -0
- package/dist/config/paths.js.map +1 -1
- package/dist/index.js +99 -68
- package/dist/index.js.map +1 -1
- package/dist/rules/agents.d.ts +6 -1
- package/dist/rules/agents.js +5 -1
- package/dist/rules/agents.js.map +1 -1
- package/dist/rules/distribution.d.ts +3 -1
- package/dist/rules/distribution.js +120 -2
- package/dist/rules/distribution.js.map +1 -1
- package/dist/skills/distribution.d.ts +1 -1
- package/dist/skills/distribution.js +40 -5
- package/dist/skills/distribution.js.map +1 -1
- package/dist/skills/importer.d.ts +1 -1
- package/dist/subagents/distribution.d.ts +1 -1
- package/dist/subagents/distribution.js +38 -2
- package/dist/subagents/distribution.js.map +1 -1
- package/dist/subagents/importer.d.ts +1 -1
- package/dist/subagents/importer.js +2 -1
- package/dist/subagents/importer.js.map +1 -1
- package/dist/subagents/inventory.js +2 -2
- package/dist/subagents/inventory.js.map +1 -1
- package/dist/ui/subagent-ui.js +5 -1
- package/dist/ui/subagent-ui.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,341 +1,280 @@
|
|
|
1
1
|
# Agent Switchboard
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/agent-switchboard)
|
|
4
|
+
[](https://github.com/qyhfrank/agent-switchboard/actions/workflows/ci.yml)
|
|
5
|
+
[](LICENSE)
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
Manage MCP servers, rules, commands, subagents, and skills from a single source of truth, then sync them to every AI coding agent you use.
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
Alias: `asb`
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
## Why
|
|
12
|
+
|
|
13
|
+
AI coding agents (Codex, Claude Code, Cursor, Gemini, OpenCode ...) each store MCP servers, prompt rules, slash commands, and skills in their own formats and locations. When you add a new MCP server or tweak a coding rule, you repeat the work for each agent. Configs drift, setups go stale.
|
|
14
|
+
|
|
15
|
+
Agent Switchboard solves this with **one library, one config, many targets**:
|
|
10
16
|
|
|
11
|
-
```bash
|
|
12
|
-
npm i -g agent-switchboard
|
|
13
17
|
```
|
|
18
|
+
Libraries Config Layers Distribution
|
|
19
|
+
┌──────────────┐ ┌─────────────────────┐ ┌────────────────┐
|
|
20
|
+
│ mcp.json │ │ User config.toml │ │ Claude Code │
|
|
21
|
+
│ rules/ │ │ Profile <name>.toml │ │ Codex │
|
|
22
|
+
│ commands/ │ ─► │ Project .asb.toml │ ─► │ Cursor │
|
|
23
|
+
│ subagents/ │ │ │ │ Gemini │
|
|
24
|
+
│ skills/ │ │ Per-agent overrides │ │ OpenCode │
|
|
25
|
+
└──────────────┘ └─────────────────────┘ │ Claude Desktop │
|
|
26
|
+
└────────────────┘
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
All library entries are agent-agnostic Markdown files (or directories for skills). Agent Switchboard reads them, applies layered configuration and per-agent overrides, then writes the correct format to each agent's config location.
|
|
30
|
+
|
|
31
|
+
## Compatibility
|
|
14
32
|
|
|
15
|
-
|
|
33
|
+
| Feature | Claude Code | Codex | Cursor | Gemini | OpenCode | Claude Desktop |
|
|
34
|
+
|:-----------------|:-----------:|:-----:|:------:|:------:|:--------:|:--------------:|
|
|
35
|
+
| MCP servers | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
|
36
|
+
| Project-level MCP| ✓ | ✓ | ✓ | ✓ | ✓ | |
|
|
37
|
+
| Rules | ✓ | ✓ | ✓ mdc | ✓ | ✓ | |
|
|
38
|
+
| Commands | ✓ | ✓\* | ✓ | ✓ | ✓ | |
|
|
39
|
+
| Subagents | ✓ | | ✓ | | ✓ | |
|
|
40
|
+
| Skills | ✓ | ✓ | ✓ | ✓ | ✓ | |
|
|
41
|
+
|
|
42
|
+
\* Codex commands use deprecated `~/.codex/prompts/`; prefer skills instead.
|
|
43
|
+
|
|
44
|
+
Cursor rules are distributed as individual `.mdc` files to `~/.cursor/rules/` (native format), not as a single composed document.
|
|
45
|
+
|
|
46
|
+
## Quick Start
|
|
16
47
|
|
|
17
48
|
```bash
|
|
18
|
-
npx agent-switchboard@latest mcp
|
|
49
|
+
npm i -g agent-switchboard # or: npx agent-switchboard@latest mcp
|
|
19
50
|
```
|
|
20
51
|
|
|
21
|
-
|
|
52
|
+
1. **Pick your agents** -- create `~/.agent-switchboard/config.toml`:
|
|
22
53
|
|
|
23
|
-
|
|
24
|
-
|
|
54
|
+
```toml
|
|
55
|
+
[agents]
|
|
56
|
+
active = ["claude-code", "codex", "cursor"]
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
2. **Manage MCP servers** -- launches an interactive checkbox UI:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
asb mcp
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
3. **Sync everything** -- pushes all libraries (rules, commands, subagents, skills) and MCP config to every active agent:
|
|
25
66
|
|
|
26
67
|
```bash
|
|
27
|
-
|
|
68
|
+
asb sync
|
|
28
69
|
```
|
|
29
70
|
|
|
30
|
-
That
|
|
71
|
+
That's it. Library content lives under `~/.agent-switchboard/` and agent configs are updated in place.
|
|
72
|
+
|
|
73
|
+
## Command Reference
|
|
74
|
+
|
|
75
|
+
| Command | Description |
|
|
76
|
+
|:---------------------|:--------------------------------------------------------|
|
|
77
|
+
| `asb mcp` | Interactive MCP server selector |
|
|
78
|
+
| `asb rule` | Interactive rule snippet selector with ordering |
|
|
79
|
+
| `asb command` | Interactive command selector |
|
|
80
|
+
| `asb subagent` | Interactive subagent selector |
|
|
81
|
+
| `asb skill` | Interactive skill selector |
|
|
82
|
+
| `asb sync` | Push all libraries + MCP to agents (no UI) |
|
|
83
|
+
| `asb <lib> load` | Import files from a platform into the library |
|
|
84
|
+
| `asb <lib> list` | Show inventory, activation state, and sync timestamps |
|
|
85
|
+
| `asb subscribe` | Add an external library subscription |
|
|
86
|
+
| `asb unsubscribe` | Remove a subscription |
|
|
87
|
+
| `asb subscriptions` | List active subscriptions |
|
|
31
88
|
|
|
32
|
-
|
|
89
|
+
`<lib>` = `rule`, `command`, `subagent`, or `skill`.
|
|
33
90
|
|
|
34
|
-
|
|
91
|
+
**Shared flags**: `-p, --profile <name>`, `--project <path>`, `--json` (on `list` and `subscriptions`).
|
|
35
92
|
|
|
36
|
-
|
|
93
|
+
## Configuration
|
|
94
|
+
|
|
95
|
+
### `config.toml`
|
|
96
|
+
|
|
97
|
+
The central config file at `~/.agent-switchboard/config.toml` controls which agents and library entries are active:
|
|
37
98
|
|
|
38
99
|
```toml
|
|
39
|
-
# ~/.agent-switchboard/config.toml
|
|
40
100
|
[agents]
|
|
41
|
-
active = ["codex", "cursor"]
|
|
101
|
+
active = ["claude-code", "codex", "cursor", "gemini", "opencode"]
|
|
42
102
|
|
|
43
103
|
[rules]
|
|
44
|
-
includeDelimiters = false
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
Supported agent IDs:
|
|
48
|
-
- `codex` - Codex CLI
|
|
49
|
-
- `cursor` - Cursor IDE
|
|
50
|
-
- `claude-code` - Claude Code CLI
|
|
51
|
-
- `claude-desktop` - Claude Desktop app
|
|
52
|
-
- `gemini` - Gemini CLI
|
|
53
|
-
- `opencode` - OpenCode (supports `opencode.json` and `opencode.jsonc`)
|
|
54
|
-
|
|
55
|
-
Toggle `rules.includeDelimiters` to `true` if you want each snippet surrounded by markers such as:
|
|
56
|
-
```
|
|
57
|
-
<!-- your-rule-name:start -->
|
|
58
|
-
…
|
|
59
|
-
<!-- your-rule-name:end -->
|
|
104
|
+
includeDelimiters = false # wrap each rule snippet in <!-- id:start/end --> markers
|
|
60
105
|
```
|
|
61
106
|
|
|
62
|
-
|
|
107
|
+
Supported agent IDs: `claude-code`, `claude-desktop`, `codex`, `cursor`, `gemini`, `opencode`.
|
|
63
108
|
|
|
64
109
|
### Per-Agent Overrides
|
|
65
110
|
|
|
66
|
-
|
|
111
|
+
Fine-tune which library entries reach each agent using `add` / `remove` / `active`:
|
|
67
112
|
|
|
68
113
|
```toml
|
|
69
114
|
[agents]
|
|
70
115
|
active = ["claude-code", "codex", "opencode"]
|
|
71
116
|
|
|
72
|
-
# Codex: exclude skill-codex (avoid self-reference)
|
|
73
117
|
codex.skills.remove = ["skill-codex"]
|
|
74
|
-
codex.rules.remove
|
|
118
|
+
codex.rules.remove = ["skill-codex"]
|
|
75
119
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
opencode.rules.remove = ["skill-codex"]
|
|
79
|
-
|
|
80
|
-
# Gemini: add extra command, remove a skill
|
|
81
|
-
gemini.commands.add = ["cmd-gemini-only"]
|
|
82
|
-
gemini.skills.remove = ["skill-go"]
|
|
120
|
+
gemini.commands.add = ["cmd-gemini-only"]
|
|
121
|
+
gemini.skills.remove = ["skill-go"]
|
|
83
122
|
```
|
|
84
123
|
|
|
85
|
-
| Syntax
|
|
86
|
-
|
|
87
|
-
| `<agent>.<section>.active = [...]
|
|
88
|
-
| `<agent>.<section>.add = [...]`
|
|
89
|
-
| `<agent>.<section>.remove = [...]
|
|
90
|
-
|
|
91
|
-
Sections: `mcp`, `commands`, `subagents`, `skills`, `rules`
|
|
124
|
+
| Syntax | Behavior |
|
|
125
|
+
|:----------------------------------|:---------------------------|
|
|
126
|
+
| `<agent>.<section>.active = [...]`| Replace the global list |
|
|
127
|
+
| `<agent>.<section>.add = [...]` | Append to the global list |
|
|
128
|
+
| `<agent>.<section>.remove = [...]`| Remove from the global list|
|
|
92
129
|
|
|
93
|
-
|
|
130
|
+
Sections: `mcp`, `rules`, `commands`, `subagents`, `skills`.
|
|
94
131
|
|
|
95
|
-
|
|
132
|
+
### Layered Configuration
|
|
96
133
|
|
|
97
|
-
|
|
98
|
-
- **Profile**: `<ASB_HOME>/<profile>.toml`
|
|
99
|
-
- **Project**: `<project>/.asb.toml`
|
|
134
|
+
Three TOML layers merge in priority order (higher wins):
|
|
100
135
|
|
|
101
|
-
|
|
136
|
+
| Layer | File | Scope |
|
|
137
|
+
|:--------|:--------------------------------|:----------------------------------|
|
|
138
|
+
| User | `<ASB_HOME>/config.toml` | Personal defaults |
|
|
139
|
+
| Profile | `<ASB_HOME>/<profile>.toml` | Team or workflow presets (`-p`) |
|
|
140
|
+
| Project | `<project>/.asb.toml` | Per-repository overrides |
|
|
102
141
|
|
|
103
142
|
```bash
|
|
104
|
-
#
|
|
105
|
-
|
|
143
|
+
asb command -p team # profile layer
|
|
144
|
+
asb rule --project /path/to/repo # project layer
|
|
145
|
+
asb subagent -p team --project /path/to/repo # both
|
|
146
|
+
```
|
|
106
147
|
|
|
107
|
-
|
|
108
|
-
agent-switchboard rule --project /path/to/repo
|
|
148
|
+
When `--project` is used, outputs target the project directory (e.g. `<project>/AGENTS.md`, `<project>/.claude/commands/`).
|
|
109
149
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
150
|
+
## Libraries
|
|
151
|
+
|
|
152
|
+
All library types follow the same pattern:
|
|
113
153
|
|
|
114
|
-
|
|
154
|
+
1. **Store** entries in `~/.agent-switchboard/<type>/` as Markdown files (or directories for skills).
|
|
155
|
+
2. **Import** existing platform files: `asb <type> load <platform> [path] [-r]`.
|
|
156
|
+
3. **Select** active entries: `asb <type>` (interactive fuzzy-search selector).
|
|
157
|
+
4. **Audit** inventory: `asb <type> list [--json]`.
|
|
115
158
|
|
|
116
|
-
|
|
117
|
-
- Rules: Codex writes `<project>/AGENTS.md`. Gemini writes `<project>/AGENTS.md`. OpenCode writes `<project>/.opencode/AGENTS.md`.
|
|
118
|
-
- Commands (project-level supported):
|
|
119
|
-
- Claude Code → `<project>/.claude/commands/`
|
|
120
|
-
- Gemini → `<project>/.gemini/commands/`
|
|
121
|
-
- OpenCode → `<project>/.opencode/command/`
|
|
122
|
-
- Codex → global only (`~/.codex/prompts/`, deprecated; consider migrating to skills)
|
|
123
|
-
- Subagents (project-level supported):
|
|
124
|
-
- Claude Code → `<project>/.claude/agents/`
|
|
125
|
-
- OpenCode → `<project>/.opencode/agent/`
|
|
126
|
-
- Skills (project-level supported):
|
|
127
|
-
- Claude Code → `<project>/.claude/skills/`
|
|
128
|
-
- Gemini → `<project>/.gemini/skills/`
|
|
129
|
-
- OpenCode → `<project>/.opencode/skill/`
|
|
130
|
-
- Codex → `~/.agents/skills/` (global) or `<project>/.agents/skills/` (project-level)
|
|
159
|
+
Selections are saved into the highest-priority config layer. Distribution writes each entry in the format the target agent expects, skipping unchanged files (hash-based).
|
|
131
160
|
|
|
132
|
-
|
|
161
|
+
### Rules
|
|
133
162
|
|
|
134
|
-
|
|
163
|
+
Snippets in `~/.agent-switchboard/rules/` with optional YAML frontmatter:
|
|
135
164
|
|
|
136
165
|
```markdown
|
|
137
166
|
---
|
|
138
167
|
title: Prompt Hygiene
|
|
139
|
-
tags:
|
|
140
|
-
|
|
141
|
-
requires:
|
|
142
|
-
- claude-code
|
|
168
|
+
tags: [hygiene]
|
|
169
|
+
requires: [claude-code]
|
|
143
170
|
---
|
|
144
171
|
Keep commit messages scoped to the change.
|
|
145
172
|
```
|
|
146
173
|
|
|
147
|
-
|
|
174
|
+
Cursor-specific options can be set via `extras.cursor` in rule frontmatter:
|
|
148
175
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
- `~/.config/opencode/AGENTS.md` (or `%APPDATA%/opencode/AGENTS.md` on Windows)
|
|
160
|
-
|
|
161
|
-
Unsupportive agents such as Claude Desktop and Cursor are reported and left untouched. If you rerun the selector without changing the order, the tool refreshes the destination files to overwrite any manual edits.
|
|
162
|
-
|
|
163
|
-
### Auditing Rules
|
|
164
|
-
|
|
165
|
-
See the full inventory, activation state, and per-agent sync timestamps:
|
|
166
|
-
|
|
167
|
-
```bash
|
|
168
|
-
agent-switchboard rule list [-p <profile>] [--project <path>]
|
|
176
|
+
```markdown
|
|
177
|
+
---
|
|
178
|
+
title: Python Rules
|
|
179
|
+
description: Python coding standards
|
|
180
|
+
extras:
|
|
181
|
+
cursor:
|
|
182
|
+
alwaysApply: false
|
|
183
|
+
globs: "*.py"
|
|
184
|
+
---
|
|
185
|
+
Use type hints everywhere.
|
|
169
186
|
```
|
|
170
187
|
|
|
171
|
-
|
|
188
|
+
The interactive selector lets you **reorder** snippets. For most agents, rules are composed into a single document. For Cursor, each rule is written as an individual `.mdc` file with native frontmatter (`description`, `alwaysApply`, `globs`):
|
|
172
189
|
|
|
173
|
-
|
|
174
|
-
|
|
190
|
+
| Agent | Global output | Project output |
|
|
191
|
+
|:------------|:------------------------------------|:----------------------------------|
|
|
192
|
+
| Claude Code | `~/.claude/CLAUDE.md` | `<project>/.claude/CLAUDE.md` |
|
|
193
|
+
| Codex | `~/.codex/AGENTS.md` | `<project>/AGENTS.md` |
|
|
194
|
+
| Cursor | `~/.cursor/rules/<id>.mdc` | `<project>/.cursor/rules/<id>.mdc`|
|
|
195
|
+
| Gemini | `~/.gemini/AGENTS.md` | `<project>/.gemini/AGENTS.md` |
|
|
196
|
+
| OpenCode | `~/.config/opencode/AGENTS.md` | `<project>/AGENTS.md` |
|
|
175
197
|
|
|
176
|
-
###
|
|
177
|
-
|
|
178
|
-
```bash
|
|
179
|
-
# Import an existing platform file or directory into the library
|
|
180
|
-
# Use -r/--recursive to traverse subdirectories when <path> is a directory
|
|
181
|
-
agent-switchboard command load <platform> [path] [-r]
|
|
182
|
-
# <platform>: claude-code | codex | gemini | opencode
|
|
183
|
-
# If [path] is omitted, defaults by platform:
|
|
184
|
-
# claude-code → ~/.claude/commands
|
|
185
|
-
# codex → ~/.codex/prompts
|
|
186
|
-
# gemini → ~/.gemini/commands
|
|
187
|
-
# opencode → ~/.config/opencode/command (Windows: %APPDATA%/opencode/command)
|
|
188
|
-
```
|
|
198
|
+
### Commands
|
|
189
199
|
|
|
190
|
-
|
|
200
|
+
Markdown files in `~/.agent-switchboard/commands/` with optional `description` and `extras.<platform>`:
|
|
191
201
|
|
|
192
202
|
```bash
|
|
193
|
-
|
|
203
|
+
asb command load claude-code # import from ~/.claude/commands/
|
|
204
|
+
asb command load gemini [path] -r # import recursively
|
|
194
205
|
```
|
|
195
206
|
|
|
196
|
-
|
|
207
|
+
Platforms: `claude-code`, `codex`, `cursor`, `gemini`, `opencode`.
|
|
197
208
|
|
|
198
|
-
|
|
209
|
+
### Subagents
|
|
199
210
|
|
|
200
|
-
|
|
211
|
+
Same format as commands, stored in `~/.agent-switchboard/subagents/`.
|
|
201
212
|
|
|
202
213
|
```bash
|
|
203
|
-
#
|
|
204
|
-
agent-switchboard command list [-p <profile>] [--project <path>]
|
|
214
|
+
asb subagent load claude-code # import from ~/.claude/agents/
|
|
205
215
|
```
|
|
206
216
|
|
|
207
|
-
|
|
217
|
+
Platforms: `claude-code`, `opencode`, `cursor`.
|
|
208
218
|
|
|
209
|
-
|
|
210
|
-
- Frontmatter: only global `description` (optional). Any platform-native options must live under `extras.<platform>` and are written through verbatim. We do not parse, validate, or showcase platform key names in this README. Platforms that do not support subagent files are skipped.
|
|
219
|
+
### Skills
|
|
211
220
|
|
|
212
|
-
|
|
221
|
+
Multi-file directory bundles in `~/.agent-switchboard/skills/<skill-id>/`, each containing a `SKILL.md` entry file:
|
|
213
222
|
|
|
214
|
-
```bash
|
|
215
|
-
agent-switchboard subagent load <platform> [path] [-r]
|
|
216
|
-
# <platform>: claude-code | opencode
|
|
217
|
-
# If [path] is omitted, defaults by platform:
|
|
218
|
-
# claude-code → ~/.claude/agents
|
|
219
|
-
# opencode → ~/.config/opencode/agent (Windows: %APPDATA%/opencode/agent)
|
|
220
223
|
```
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
224
|
+
~/.agent-switchboard/skills/my-skill/
|
|
225
|
+
├── SKILL.md # name + description in frontmatter
|
|
226
|
+
├── helper.py
|
|
227
|
+
└── templates/
|
|
228
|
+
└── template.txt
|
|
226
229
|
```
|
|
227
230
|
|
|
228
|
-
Type to fuzzy filter the list, then confirm to persist the selection into the active configuration layer. Adapters write each selected subagent to the corresponding platform output in your user home (platform defaults), using the file format that platform expects. The frontmatter consists of the global `description` (if present) plus `extras.<platform>` written as-is. Platforms that do not accept subagent files are skipped with a hint.
|
|
229
|
-
|
|
230
|
-
### Inventory
|
|
231
|
-
|
|
232
231
|
```bash
|
|
233
|
-
|
|
232
|
+
asb skill load claude-code # import from ~/.claude/skills/
|
|
233
|
+
asb skill load codex # import from ~/.agents/skills/
|
|
234
234
|
```
|
|
235
235
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
Skills are multi-file bundles (directories) that provide reusable capabilities to agents. Each skill is a directory containing a `SKILL.md` file and any supporting files.
|
|
239
|
-
|
|
240
|
-
- Location: `~/.agent-switchboard/skills/<skill-id>/` (respects `ASB_HOME`).
|
|
241
|
-
- Entry file: `SKILL.md` with required `name` and `description` in frontmatter.
|
|
236
|
+
Entire directories are copied to each agent's skill location. Deactivated skills are cleaned up automatically.
|
|
242
237
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
```
|
|
246
|
-
~/.agent-switchboard/skills/
|
|
247
|
-
└── my-skill/
|
|
248
|
-
├── SKILL.md
|
|
249
|
-
├── helper.py
|
|
250
|
-
└── templates/
|
|
251
|
-
└── template.txt
|
|
252
|
-
```
|
|
238
|
+
## Library Subscriptions
|
|
253
239
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
```markdown
|
|
257
|
-
---
|
|
258
|
-
name: my-skill
|
|
259
|
-
description: A helpful skill that does something useful
|
|
260
|
-
extras:
|
|
261
|
-
claude-code:
|
|
262
|
-
# Platform-specific options
|
|
263
|
-
---
|
|
264
|
-
Skill instructions and content here.
|
|
265
|
-
```
|
|
266
|
-
|
|
267
|
-
### Import
|
|
268
|
-
|
|
269
|
-
```bash
|
|
270
|
-
# Import skills from an existing platform directory
|
|
271
|
-
agent-switchboard skill load <platform> [path]
|
|
272
|
-
# <platform>: claude-code | codex
|
|
273
|
-
# If [path] is omitted, defaults by platform:
|
|
274
|
-
# claude-code → ~/.claude/skills
|
|
275
|
-
# codex → ~/.agents/skills (fallback: ~/.codex/skills)
|
|
276
|
-
```
|
|
277
|
-
|
|
278
|
-
### Select and Distribute
|
|
240
|
+
Pull library entries from external directories (e.g. a team-shared repo):
|
|
279
241
|
|
|
280
242
|
```bash
|
|
281
|
-
|
|
243
|
+
asb subscribe team /path/to/team-library
|
|
244
|
+
asb subscriptions # list active subscriptions
|
|
245
|
+
asb unsubscribe team # remove
|
|
282
246
|
```
|
|
283
247
|
|
|
284
|
-
|
|
285
|
-
- Claude Code → `~/.claude/skills/<skill-id>/`
|
|
286
|
-
- Codex → `~/.agents/skills/<skill-id>/` (or `<project>/.agents/skills/<skill-id>/`)
|
|
287
|
-
- Gemini → `~/.gemini/skills/<skill-id>/`
|
|
288
|
-
- OpenCode → `~/.config/opencode/skill/<skill-id>/`
|
|
289
|
-
|
|
290
|
-
### Inventory
|
|
291
|
-
|
|
292
|
-
```bash
|
|
293
|
-
agent-switchboard skill list [-p <profile>] [--project <path>]
|
|
294
|
-
```
|
|
248
|
+
The subscription path must contain at least one of `rules/`, `commands/`, `subagents/`, or `skills/`. Entries from subscriptions appear with a namespace prefix (e.g. `team:my-rule`) in selectors and config.
|
|
295
249
|
|
|
296
250
|
## Sync
|
|
297
251
|
|
|
298
|
-
|
|
252
|
+
Push all libraries and MCP config to every active agent in one step:
|
|
299
253
|
|
|
300
254
|
```bash
|
|
301
|
-
|
|
255
|
+
asb sync [-p <profile>] [--project <path>]
|
|
302
256
|
```
|
|
303
257
|
|
|
304
|
-
|
|
258
|
+
This merges layered config, applies per-agent overrides, and writes target files in place. Files are only rewritten when content changes.
|
|
305
259
|
|
|
306
260
|
## Environment
|
|
307
261
|
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
All `list` subcommands support `--json` for machine-readable output:
|
|
314
|
-
|
|
315
|
-
```bash
|
|
316
|
-
agent-switchboard rule list --json
|
|
317
|
-
agent-switchboard command list --json
|
|
318
|
-
agent-switchboard subagent list --json
|
|
319
|
-
agent-switchboard skill list --json
|
|
320
|
-
```
|
|
262
|
+
| Variable | Default | Purpose |
|
|
263
|
+
|:-----------------|:---------------------------|:---------------------------------------------|
|
|
264
|
+
| `ASB_HOME` | `~/.agent-switchboard` | Library, config, and state directory |
|
|
265
|
+
| `ASB_AGENTS_HOME`| OS user home | Base path for agent config locations |
|
|
321
266
|
|
|
322
267
|
## Development
|
|
323
268
|
|
|
324
|
-
Install dependencies, build, and link globally:
|
|
325
|
-
|
|
326
269
|
```bash
|
|
327
270
|
pnpm install
|
|
328
271
|
pnpm build
|
|
329
|
-
pnpm link --global
|
|
272
|
+
pnpm link --global # global `agent-switchboard` points to local build
|
|
330
273
|
```
|
|
331
274
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
To unlink:
|
|
275
|
+
Code changes take effect after `pnpm build`. To unlink: `pnpm uninstall -g agent-switchboard`.
|
|
335
276
|
|
|
336
|
-
|
|
337
|
-
pnpm uninstall -g agent-switchboard
|
|
338
|
-
```
|
|
277
|
+
Other scripts: `pnpm dev` (tsx), `pnpm test`, `pnpm lint`, `pnpm typecheck`.
|
|
339
278
|
|
|
340
279
|
## License
|
|
341
280
|
|
package/dist/agents/cursor.d.ts
CHANGED
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Cursor agent adapter
|
|
3
|
-
* Manages MCP server configuration for Cursor IDE
|
|
3
|
+
* Manages MCP server configuration for Cursor IDE/CLI
|
|
4
4
|
*/
|
|
5
5
|
import type { McpServer } from '../config/schemas.js';
|
|
6
6
|
import type { AgentAdapter } from './adapter.js';
|
|
7
|
-
/**
|
|
8
|
-
* Cursor config file structure
|
|
9
|
-
*/
|
|
10
7
|
/**
|
|
11
8
|
* Cursor agent adapter
|
|
12
9
|
* Config location: ~/.cursor/mcp.json
|
package/dist/agents/cursor.js
CHANGED
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Cursor agent adapter
|
|
3
|
-
* Manages MCP server configuration for Cursor IDE
|
|
3
|
+
* Manages MCP server configuration for Cursor IDE/CLI
|
|
4
4
|
*/
|
|
5
5
|
import fs from 'node:fs';
|
|
6
|
-
import os from 'node:os';
|
|
7
6
|
import path from 'node:path';
|
|
7
|
+
import { getCursorDir, getProjectCursorDir } from '../config/paths.js';
|
|
8
8
|
import { loadJsonFile, mergeMcpIntoAgent, saveJsonFile, } from './json-utils.js';
|
|
9
|
-
/**
|
|
10
|
-
* Cursor config file structure
|
|
11
|
-
*/
|
|
12
|
-
// Uses shared JsonAgentConfig
|
|
13
9
|
/**
|
|
14
10
|
* Cursor agent adapter
|
|
15
11
|
* Config location: ~/.cursor/mcp.json
|
|
@@ -17,16 +13,13 @@ import { loadJsonFile, mergeMcpIntoAgent, saveJsonFile, } from './json-utils.js'
|
|
|
17
13
|
export class CursorAgent {
|
|
18
14
|
id = 'cursor';
|
|
19
15
|
configPath() {
|
|
20
|
-
|
|
21
|
-
? process.env.ASB_AGENTS_HOME
|
|
22
|
-
: os.homedir();
|
|
23
|
-
return path.join(base, '.cursor', 'mcp.json');
|
|
16
|
+
return path.join(getCursorDir(), 'mcp.json');
|
|
24
17
|
}
|
|
25
18
|
/**
|
|
26
19
|
* Project-level config: <project>/.cursor/mcp.json
|
|
27
20
|
*/
|
|
28
21
|
projectConfigPath(projectRoot) {
|
|
29
|
-
return path.join(
|
|
22
|
+
return path.join(getProjectCursorDir(projectRoot), 'mcp.json');
|
|
30
23
|
}
|
|
31
24
|
applyConfig(config) {
|
|
32
25
|
const configPath = this.configPath();
|
|
@@ -38,7 +31,6 @@ export class CursorAgent {
|
|
|
38
31
|
const configPath = this.projectConfigPath(projectRoot);
|
|
39
32
|
const existing = loadJsonFile(configPath, { mcpServers: {} });
|
|
40
33
|
const merged = mergeMcpIntoAgent(existing, config.mcpServers);
|
|
41
|
-
// Ensure .cursor directory exists
|
|
42
34
|
const dir = path.dirname(configPath);
|
|
43
35
|
if (!fs.existsSync(dir))
|
|
44
36
|
fs.mkdirSync(dir, { recursive: true });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cursor.js","sourceRoot":"","sources":["../../src/agents/cursor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,
|
|
1
|
+
{"version":3,"file":"cursor.js","sourceRoot":"","sources":["../../src/agents/cursor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAGvE,OAAO,EAEL,YAAY,EACZ,iBAAiB,EACjB,YAAY,GACb,MAAM,iBAAiB,CAAC;AAEzB;;;GAGG;AACH,MAAM,OAAO,WAAW;IACb,EAAE,GAAG,QAAiB,CAAC;IAEhC,UAAU;QACR,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,UAAU,CAAC,CAAC;IAC/C,CAAC;IAED;;OAEG;IACH,iBAAiB,CAAC,WAAmB;QACnC,OAAO,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,WAAW,CAAC,EAAE,UAAU,CAAC,CAAC;IACjE,CAAC;IAED,WAAW,CAAC,MAAkE;QAC5E,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QACrC,MAAM,WAAW,GAAG,YAAY,CAAkB,UAAU,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC;QAClF,MAAM,MAAM,GAAG,iBAAiB,CAAC,WAAW,EAAE,MAAM,CAAC,UAAoC,CAAC,CAAC;QAC3F,YAAY,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IACnC,CAAC;IAED,kBAAkB,CAChB,WAAmB,EACnB,MAAkE;QAElE,MAAM,UAAU,GAAG,IAAI,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;QACvD,MAAM,QAAQ,GAAG,YAAY,CAAkB,UAAU,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC;QAC/E,MAAM,MAAM,GAAG,iBAAiB,CAAC,QAAQ,EAAE,MAAM,CAAC,UAAoC,CAAC,CAAC;QACxF,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QACrC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAChE,YAAY,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IACnC,CAAC;CACF"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ConfigScope } from '../config/scope.js';
|
|
2
2
|
import { type DistributeOutcome } from '../library/distribute.js';
|
|
3
|
-
export type CommandPlatform = 'claude-code' | 'codex' | 'gemini' | 'opencode';
|
|
3
|
+
export type CommandPlatform = 'claude-code' | 'codex' | 'cursor' | 'gemini' | 'opencode';
|
|
4
4
|
export interface CommandDistributionResult {
|
|
5
5
|
platform: CommandPlatform;
|
|
6
6
|
filePath: string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import { stringify as toToml } from '@iarna/toml';
|
|
3
|
-
import { getClaudeDir, getCodexDir, getGeminiDir, getOpencodePath, getProjectClaudeDir, getProjectGeminiDir, getProjectOpencodePath, } from '../config/paths.js';
|
|
3
|
+
import { getClaudeDir, getCodexDir, getCursorDir, getGeminiDir, getOpencodePath, getProjectClaudeDir, getProjectCursorDir, getProjectGeminiDir, getProjectOpencodePath, } from '../config/paths.js';
|
|
4
4
|
import { distributeLibrary, } from '../library/distribute.js';
|
|
5
5
|
import { loadLibraryStateSectionForAgent } from '../library/state.js';
|
|
6
6
|
import { wrapFrontmatter } from '../util/frontmatter.js';
|
|
@@ -26,6 +26,12 @@ function resolveCommandTargetDir(platform, scope) {
|
|
|
26
26
|
case 'codex': {
|
|
27
27
|
return path.join(getCodexDir(), 'prompts');
|
|
28
28
|
}
|
|
29
|
+
case 'cursor': {
|
|
30
|
+
if (projectRoot && projectRoot.length > 0) {
|
|
31
|
+
return path.join(getProjectCursorDir(projectRoot), 'commands');
|
|
32
|
+
}
|
|
33
|
+
return path.join(getCursorDir(), 'commands');
|
|
34
|
+
}
|
|
29
35
|
case 'gemini': {
|
|
30
36
|
if (projectRoot && projectRoot.length > 0) {
|
|
31
37
|
return path.join(getProjectGeminiDir(projectRoot), 'commands');
|
|
@@ -98,12 +104,15 @@ function renderForPlatform(platform, entry) {
|
|
|
98
104
|
const fm = buildFrontmatterForOpencode(entry);
|
|
99
105
|
return wrapFrontmatter(fm, entry.content);
|
|
100
106
|
}
|
|
107
|
+
case 'cursor': {
|
|
108
|
+
return `${entry.content.trimEnd()}\n`;
|
|
109
|
+
}
|
|
101
110
|
}
|
|
102
111
|
}
|
|
103
112
|
export function distributeCommands(scope) {
|
|
104
113
|
const entries = loadCommandLibrary();
|
|
105
114
|
const byId = new Map(entries.map((e) => [e.id, e]));
|
|
106
|
-
const platforms = ['claude-code', 'codex', 'gemini', 'opencode'];
|
|
115
|
+
const platforms = ['claude-code', 'codex', 'cursor', 'gemini', 'opencode'];
|
|
107
116
|
// Cleanup config to remove orphan command files
|
|
108
117
|
const cleanup = {
|
|
109
118
|
resolveTargetDir: (p) => resolveCommandTargetDir(p, scope),
|