sf-aidev 1.0.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/README.md +544 -0
- package/messages/aidev.add.agent.md +89 -0
- package/messages/aidev.add.command.md +89 -0
- package/messages/aidev.add.md +77 -0
- package/messages/aidev.add.prompt.md +89 -0
- package/messages/aidev.add.skill.md +89 -0
- package/messages/aidev.init.md +133 -0
- package/messages/aidev.list.agents.md +76 -0
- package/messages/aidev.list.commands.md +65 -0
- package/messages/aidev.list.instructions.md +35 -0
- package/messages/aidev.list.md +92 -0
- package/messages/aidev.list.skills.md +76 -0
- package/messages/aidev.remove.agent.md +45 -0
- package/messages/aidev.remove.command.md +45 -0
- package/messages/aidev.remove.md +57 -0
- package/messages/aidev.remove.prompt.md +45 -0
- package/messages/aidev.remove.skill.md +45 -0
- package/messages/aidev.source.add.md +65 -0
- package/messages/aidev.source.list.md +21 -0
- package/messages/aidev.source.refresh.md +71 -0
- package/messages/aidev.source.remove.md +57 -0
- package/messages/aidev.source.set-default.md +41 -0
- package/messages/messages.json +3 -0
- package/oclif.lock +8743 -0
- package/oclif.manifest.json +4 -0
- package/package.json +189 -0
package/README.md
ADDED
|
@@ -0,0 +1,544 @@
|
|
|
1
|
+
# sf-aidev
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/sf-aidev) [](https://npmjs.org/package/sf-aidev) [](https://raw.githubusercontent.com/salesforcecli/sf-aidev/main/LICENSE.txt)
|
|
4
|
+
|
|
5
|
+
Salesforce CLI plugin that installs production-ready AI development tool configurations (skills, agents, prompts, commands) from GitHub source repositories. Auto-detects which AI tool is in use, supports multiple tools, and provides unified management commands with rich interactive experiences.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
sf plugins install sf-aidev
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# Initialize — detects your AI tool, configures source, installs artifacts
|
|
17
|
+
sf aidev init
|
|
18
|
+
|
|
19
|
+
# Interactive multi-select picker (browse and select multiple artifacts)
|
|
20
|
+
sf aidev add
|
|
21
|
+
|
|
22
|
+
# Or add individual artifacts by name
|
|
23
|
+
sf aidev add skill --name apex-review
|
|
24
|
+
sf aidev add agent --name code-helper
|
|
25
|
+
sf aidev add prompt --name deploy-checklist
|
|
26
|
+
sf aidev add command --name review-pr
|
|
27
|
+
|
|
28
|
+
# Manage sources
|
|
29
|
+
sf aidev source add myorg/ai-templates --set-default
|
|
30
|
+
sf aidev source list
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Commands
|
|
34
|
+
|
|
35
|
+
### `sf aidev init`
|
|
36
|
+
|
|
37
|
+
Initialize AI development tools in your project. Auto-detects the AI tool in use, configures a source repository, and optionally installs available artifacts.
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
sf aidev init
|
|
41
|
+
sf aidev init --tool copilot --source owner/ai-dev-lifecycle
|
|
42
|
+
sf aidev init --no-install --no-prompt
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
| Flag | Char | Description |
|
|
46
|
+
| -------------- | ---- | ----------------------------------------------------------------- |
|
|
47
|
+
| `--tool` | `-t` | AI tool to configure (copilot, claude). Auto-detected if omitted. |
|
|
48
|
+
| `--source` | `-s` | Source repository in `owner/repo` format. |
|
|
49
|
+
| `--no-install` | | Skip artifact installation, only configure tool and source. |
|
|
50
|
+
| `--no-prompt` | | Skip confirmation prompts (for scripting). |
|
|
51
|
+
|
|
52
|
+
### `sf aidev add`
|
|
53
|
+
|
|
54
|
+
Interactively select and install multiple artifacts at once. Displays a multi-select picker with artifacts grouped by category (Agents, Skills, Prompts, Commands).
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
sf aidev add
|
|
58
|
+
sf aidev add --source owner/repo
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
| Flag | Char | Description |
|
|
62
|
+
| ---------- | ---- | ------------------------------------------------- |
|
|
63
|
+
| `--source` | `-s` | Filter artifacts to a specific source repository. |
|
|
64
|
+
|
|
65
|
+
**Note:** This command requires an interactive terminal. For non-interactive use (scripts, CI/CD), use the subcommands below.
|
|
66
|
+
|
|
67
|
+
### `sf aidev add skill|agent|prompt|command`
|
|
68
|
+
|
|
69
|
+
Install an artifact from a configured source repository. When called without the `--name` flag, some subcommands support interactive selection.
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
sf aidev add skill --name my-skill
|
|
73
|
+
sf aidev add agent --name my-agent --source owner/repo
|
|
74
|
+
sf aidev add prompt --name my-prompt
|
|
75
|
+
sf aidev add command --name review-pr
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
| Flag | Char | Description |
|
|
79
|
+
| ---------- | ---- | --------------------------------------------------------------------------------- |
|
|
80
|
+
| `--name` | `-n` | Name of the artifact to install. If omitted, shows interactive selection (where supported). |
|
|
81
|
+
| `--source` | `-s` | Source repository. Defaults to the configured default. |
|
|
82
|
+
|
|
83
|
+
### `sf aidev remove`
|
|
84
|
+
|
|
85
|
+
Interactively select and remove multiple installed artifacts at once. Displays a multi-select picker with installed artifacts grouped by category.
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
sf aidev remove
|
|
89
|
+
sf aidev remove --no-prompt
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
| Flag | Description |
|
|
93
|
+
| ------------- | --------------------------------- |
|
|
94
|
+
| `--no-prompt` | Skip the confirmation prompt. |
|
|
95
|
+
|
|
96
|
+
**Note:** This command requires an interactive terminal. For non-interactive use, use the subcommands below.
|
|
97
|
+
|
|
98
|
+
### `sf aidev remove skill|agent|prompt|command`
|
|
99
|
+
|
|
100
|
+
Remove an installed artifact by name.
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
sf aidev remove skill --name my-skill
|
|
104
|
+
sf aidev remove agent --name my-agent --no-prompt
|
|
105
|
+
sf aidev remove prompt --name my-prompt
|
|
106
|
+
sf aidev remove command --name review-pr
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
| Flag | Char | Description |
|
|
110
|
+
| ------------- | ---- | ---------------------------------------------- |
|
|
111
|
+
| `--name` | `-n` | **(Required)** Name of the artifact to remove. |
|
|
112
|
+
| `--no-prompt` | | Skip the confirmation prompt. |
|
|
113
|
+
|
|
114
|
+
### `sf aidev list`
|
|
115
|
+
|
|
116
|
+
Display a unified view of all AI artifacts in your project, grouped by type with checkboxes indicating installation status:
|
|
117
|
+
|
|
118
|
+
- ☑ (checked) - artifact exists locally
|
|
119
|
+
- ☐ (unchecked) - artifact is available from source but not installed
|
|
120
|
+
|
|
121
|
+
In interactive mode, press Enter on any artifact to expand and view its full description inline. The description is fetched on-demand from the source repository's frontmatter metadata.
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
sf aidev list
|
|
125
|
+
sf aidev list --source owner/repo
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
| Flag | Char | Description |
|
|
129
|
+
| ---------- | ---- | ------------------------------------------------ |
|
|
130
|
+
| `--source` | `-s` | Filter available artifacts by source repository. |
|
|
131
|
+
|
|
132
|
+
**Interactive Features:**
|
|
133
|
+
- Press **Enter** to expand/collapse artifact descriptions
|
|
134
|
+
- Press **Escape** or **Ctrl+C** to exit
|
|
135
|
+
- Descriptions are fetched on-demand from source repository frontmatter
|
|
136
|
+
|
|
137
|
+
### `sf aidev list agents|skills|commands|instructions`
|
|
138
|
+
|
|
139
|
+
List artifacts filtered by type with interactive action menus.
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
sf aidev list agents
|
|
143
|
+
sf aidev list skills --source owner/repo
|
|
144
|
+
sf aidev list commands
|
|
145
|
+
sf aidev list instructions
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
| Command | Description |
|
|
149
|
+
| ------------------- | ---------------------------------------------------------------------------------------------------------- |
|
|
150
|
+
| `list agents` | Show only agents. Merges local and source manifest. Supports interactive actions (view, install, remove). |
|
|
151
|
+
| `list skills` | Show only skills. Merges local and source manifest. Supports interactive actions. |
|
|
152
|
+
| `list commands` | Show only commands. Merges local and source manifest. Supports interactive actions. |
|
|
153
|
+
| `list instructions` | Show local instruction files (CLAUDE.md, CURSOR.md, CODEX.md, copilot-instructions.md, \*.instructions.md) |
|
|
154
|
+
|
|
155
|
+
The `agents`, `skills`, and `commands` subcommands support the `--source` flag. The `instructions` command is local-only.
|
|
156
|
+
|
|
157
|
+
**Interactive Features:**
|
|
158
|
+
- Select an artifact to view actions: View details, Install (if not installed), or Remove (if installed)
|
|
159
|
+
- Press **Escape** to go back to the list
|
|
160
|
+
- Descriptions are fetched from source frontmatter when viewing details
|
|
161
|
+
|
|
162
|
+
### `sf aidev source add|remove|list|set-default|refresh`
|
|
163
|
+
|
|
164
|
+
Manage source repositories that provide artifacts.
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
sf aidev source add owner/repo --set-default
|
|
168
|
+
sf aidev source list
|
|
169
|
+
sf aidev source remove owner/repo
|
|
170
|
+
sf aidev source set-default owner/repo
|
|
171
|
+
sf aidev source refresh
|
|
172
|
+
sf aidev source refresh owner/repo
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
| Command | Arguments / Flags |
|
|
176
|
+
| -------------------- | --------------------------------------------------- |
|
|
177
|
+
| `source add` | `REPO` (positional), `--repo` `-r`, `--set-default` |
|
|
178
|
+
| `source remove` | `REPO` (positional), `--repo` `-r`, `--no-prompt` |
|
|
179
|
+
| `source list` | _(none)_ |
|
|
180
|
+
| `source set-default` | `REPO` (positional), `--repo` `-r` |
|
|
181
|
+
| `source refresh` | `REPO` (positional, optional), `--repo` `-r` |
|
|
182
|
+
|
|
183
|
+
The `REPO` argument (in `owner/repo` format) can be provided as a positional argument or via the `--repo` flag.
|
|
184
|
+
|
|
185
|
+
The `source refresh` command re-fetches manifests from GitHub and updates the local cache. For repositories without a `manifest.json`, it re-runs auto-discovery. Use this command when source repositories have been updated.
|
|
186
|
+
|
|
187
|
+
All commands support `--json` for machine-readable output.
|
|
188
|
+
|
|
189
|
+
## Interactive Mode
|
|
190
|
+
|
|
191
|
+
Many commands support rich interactive experiences when running in a terminal:
|
|
192
|
+
|
|
193
|
+
### Features
|
|
194
|
+
|
|
195
|
+
- **Multi-select checkboxes** - Select multiple artifacts to install/remove at once
|
|
196
|
+
- **Expandable descriptions** - Press Enter to expand/collapse artifact descriptions in lists
|
|
197
|
+
- **Action menus** - View details, install, or remove artifacts directly from list views
|
|
198
|
+
- **Keyboard navigation** - Space to select, Enter to confirm/expand, Escape to go back
|
|
199
|
+
- **On-demand fetching** - Artifact descriptions are loaded from source repositories when needed
|
|
200
|
+
- **Visual indicators** - Clear checkmarks (☑) for installed, empty boxes (☐) for available artifacts
|
|
201
|
+
|
|
202
|
+
### Keyboard Shortcuts
|
|
203
|
+
|
|
204
|
+
| Key | Action |
|
|
205
|
+
| -------------- | -------------------------------------------------- |
|
|
206
|
+
| **Space** | Select/deselect items in checkbox lists |
|
|
207
|
+
| **Enter** | Confirm selection or expand/collapse descriptions |
|
|
208
|
+
| **Escape** | Go back or exit |
|
|
209
|
+
| **Ctrl+C** | Cancel and exit |
|
|
210
|
+
| **↑/↓ Arrows** | Navigate through lists |
|
|
211
|
+
|
|
212
|
+
Interactive mode is automatically disabled when:
|
|
213
|
+
- Running with `--json` flag
|
|
214
|
+
- Output is piped or redirected
|
|
215
|
+
- Running in CI/CD environments (non-TTY)
|
|
216
|
+
- Using `--no-prompt` flag
|
|
217
|
+
|
|
218
|
+
## AI Tools Detection
|
|
219
|
+
|
|
220
|
+
The plugin auto-detects which AI coding tool is configured in your project:
|
|
221
|
+
|
|
222
|
+
| Tool | Detection Paths | Artifact Installation Paths |
|
|
223
|
+
| ------------------ | ------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------- |
|
|
224
|
+
| **GitHub Copilot** | `.github/copilot-instructions.md`, `.github/agents/`, `.github/prompts/` | Skills: `.github/copilot-skills/`, Agents: `.github/agents/`, Prompts: `.github/prompts/`, Commands: `.github/prompts/` |
|
|
225
|
+
| **Claude Code** | `.claude/` | Skills: `.claude/skills/`, Agents: `.claude/agents/`, Prompts: `.claude/commands/`, Commands: `.claude/commands/` |
|
|
226
|
+
|
|
227
|
+
Additional tools (Cursor, Windsurf, Gemini, Codex) are planned.
|
|
228
|
+
|
|
229
|
+
## Source Repository Format
|
|
230
|
+
|
|
231
|
+
Source repositories must contain a `manifest.json` at the root:
|
|
232
|
+
|
|
233
|
+
```json
|
|
234
|
+
{
|
|
235
|
+
"version": "1.0",
|
|
236
|
+
"artifacts": [
|
|
237
|
+
{
|
|
238
|
+
"name": "apex-review",
|
|
239
|
+
"type": "skill",
|
|
240
|
+
"description": "Code review skill for Apex",
|
|
241
|
+
"files": [{ "source": "skills/apex-review.md" }],
|
|
242
|
+
"tools": ["copilot", "claude"]
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
"name": "review-pr",
|
|
246
|
+
"type": "command",
|
|
247
|
+
"description": "Review pull requests with AI assistance",
|
|
248
|
+
"files": [{ "source": "commands/review-pr.md" }],
|
|
249
|
+
"tools": ["copilot", "claude"]
|
|
250
|
+
}
|
|
251
|
+
]
|
|
252
|
+
}
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
### Artifact Types
|
|
256
|
+
|
|
257
|
+
The plugin supports four artifact types:
|
|
258
|
+
|
|
259
|
+
| Type | Description | Example |
|
|
260
|
+
| ----------- | ------------------------------------------------ | -------------------------------- |
|
|
261
|
+
| `skill` | Specialized capabilities for AI assistants | code review, testing, deployment |
|
|
262
|
+
| `agent` | Autonomous AI agents for complex tasks | code helper, architect |
|
|
263
|
+
| `prompt` | Reusable prompt templates | deploy checklist, code standards |
|
|
264
|
+
| `command` | Executable commands with AI assistance | review PR, generate tests |
|
|
265
|
+
|
|
266
|
+
### Frontmatter Support
|
|
267
|
+
|
|
268
|
+
Artifact files can include frontmatter metadata for rich descriptions displayed in interactive mode:
|
|
269
|
+
|
|
270
|
+
```markdown
|
|
271
|
+
---
|
|
272
|
+
description: |
|
|
273
|
+
Detailed multi-line description of the artifact.
|
|
274
|
+
Supports full markdown formatting.
|
|
275
|
+
---
|
|
276
|
+
|
|
277
|
+
# Artifact Content
|
|
278
|
+
|
|
279
|
+
The actual content of the skill, agent, prompt, or command...
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
When viewing artifacts in interactive mode, descriptions are fetched from the source repository's frontmatter metadata.
|
|
283
|
+
|
|
284
|
+
### Auto-Discovery
|
|
285
|
+
|
|
286
|
+
If a source repository doesn't have a `manifest.json`, the plugin automatically discovers artifacts by scanning the repository structure using pattern matching:
|
|
287
|
+
|
|
288
|
+
- **Skills**: `skills/*.md`, `skills/*/README.md`
|
|
289
|
+
- **Agents**: `agents/*.md`, `agents/*/README.md`
|
|
290
|
+
- **Prompts**: `prompts/*.md`, `prompts/*/README.md`
|
|
291
|
+
- **Commands**: `commands/*.md`, `commands/*/README.md`
|
|
292
|
+
|
|
293
|
+
Auto-discovered artifacts are cached locally at `~/.sf/sf-aidev-manifests/` for one week. Use `sf aidev source refresh` to manually update the cache.
|
|
294
|
+
|
|
295
|
+
### Directory-based Artifacts
|
|
296
|
+
|
|
297
|
+
Skills can be defined as either single files or directories:
|
|
298
|
+
|
|
299
|
+
**Single file**: `skills/apex-review.md`
|
|
300
|
+
**Directory**: `skills/apex-review/` with `README.md` and supporting files
|
|
301
|
+
|
|
302
|
+
When a skill is defined as a directory, all files in that directory are installed together.
|
|
303
|
+
|
|
304
|
+
## Configuration Files
|
|
305
|
+
|
|
306
|
+
The plugin uses two configuration scopes:
|
|
307
|
+
|
|
308
|
+
### Global Config (`~/.sf/sf-aidev.json`)
|
|
309
|
+
|
|
310
|
+
Stores source repositories available across all projects:
|
|
311
|
+
|
|
312
|
+
```json
|
|
313
|
+
{
|
|
314
|
+
"sources": [
|
|
315
|
+
{
|
|
316
|
+
"repo": "owner/ai-templates",
|
|
317
|
+
"isDefault": true
|
|
318
|
+
}
|
|
319
|
+
]
|
|
320
|
+
}
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
### Local Config (`.sf/sf-aidev.json`)
|
|
324
|
+
|
|
325
|
+
Stores project-specific settings and installed artifacts:
|
|
326
|
+
|
|
327
|
+
```json
|
|
328
|
+
{
|
|
329
|
+
"tool": "copilot",
|
|
330
|
+
"installedArtifacts": [
|
|
331
|
+
{
|
|
332
|
+
"name": "apex-review",
|
|
333
|
+
"type": "skill",
|
|
334
|
+
"source": "owner/ai-templates"
|
|
335
|
+
}
|
|
336
|
+
]
|
|
337
|
+
}
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
## Project Structure
|
|
341
|
+
|
|
342
|
+
```
|
|
343
|
+
src/
|
|
344
|
+
├── commands/aidev/ # CLI command implementations
|
|
345
|
+
│ ├── init.ts # Initialize AI tool and sources
|
|
346
|
+
│ ├── add.ts # Interactive multi-select add (parent)
|
|
347
|
+
│ ├── add/ # skill.ts, agent.ts, prompt.ts, command.ts
|
|
348
|
+
│ ├── remove.ts # Interactive multi-select remove (parent)
|
|
349
|
+
│ ├── remove/ # skill.ts, agent.ts, prompt.ts, command.ts
|
|
350
|
+
│ ├── list/ # index.ts, agents.ts, skills.ts, commands.ts, instructions.ts
|
|
351
|
+
│ └── source/ # add.ts, remove.ts, list.ts, set-default.ts, refresh.ts
|
|
352
|
+
├── config/ # Configuration file management (AiDevConfig)
|
|
353
|
+
├── detectors/ # AI tool auto-detection (CopilotDetector, ClaudeDetector)
|
|
354
|
+
├── installers/ # Tool-specific file installers + path resolution
|
|
355
|
+
├── services/ # ArtifactService, SourceService, LocalFileScanner
|
|
356
|
+
├── sources/ # GitHubFetcher, SourceManager, ManifestCache, ManifestBuilder
|
|
357
|
+
├── ui/ # Interactive UI components (prompts, tables, expandable select)
|
|
358
|
+
├── utils/ # FrontmatterParser and utility functions
|
|
359
|
+
└── types/ # TypeScript type definitions (Manifest, Artifact, etc.)
|
|
360
|
+
messages/ # Markdown help/error messages per command
|
|
361
|
+
test/ # Mirrors src/ structure with Mocha + Chai + Sinon
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
## Development
|
|
365
|
+
|
|
366
|
+
### Prerequisites
|
|
367
|
+
|
|
368
|
+
- Node.js >= 18
|
|
369
|
+
- Yarn
|
|
370
|
+
|
|
371
|
+
### Setup
|
|
372
|
+
|
|
373
|
+
```bash
|
|
374
|
+
git clone git@github.com:yurybond/sf-aidev.git
|
|
375
|
+
cd sf-aidev
|
|
376
|
+
yarn install
|
|
377
|
+
yarn build
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
### Run Locally
|
|
381
|
+
|
|
382
|
+
```bash
|
|
383
|
+
# Run commands via dev script
|
|
384
|
+
./bin/dev.js aidev init
|
|
385
|
+
|
|
386
|
+
# Or link to sf CLI
|
|
387
|
+
sf plugins link .
|
|
388
|
+
sf aidev init
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
### Scripts
|
|
392
|
+
|
|
393
|
+
| Script | Description |
|
|
394
|
+
| ---------------- | ------------------------------- |
|
|
395
|
+
| `yarn build` | Compile TypeScript + lint |
|
|
396
|
+
| `yarn test` | Compile + lint + run unit tests |
|
|
397
|
+
| `yarn test:only` | Run unit tests with coverage |
|
|
398
|
+
| `yarn compile` | TypeScript compilation only |
|
|
399
|
+
| `yarn lint` | ESLint check |
|
|
400
|
+
| `yarn format` | Prettier formatting |
|
|
401
|
+
|
|
402
|
+
### Technology Stack
|
|
403
|
+
|
|
404
|
+
| Category | Tool | Config |
|
|
405
|
+
| -------------- | -------------------------------------------------- | ------------------ |
|
|
406
|
+
| CLI Framework | [oclif](https://oclif.io/) v4 | `package.json` |
|
|
407
|
+
| Language | TypeScript 5.x (strict ESM) | `tsconfig.json` |
|
|
408
|
+
| Build | [Wireit](https://github.com/nicolo-ribaudo/wireit) | `package.json` |
|
|
409
|
+
| Test | Mocha + Chai + Sinon | `.mocharc.json` |
|
|
410
|
+
| Coverage | c8 (90% threshold) | `.c8rc.json` |
|
|
411
|
+
| Lint | ESLint + sf-plugin rules | `.eslintrc.cjs` |
|
|
412
|
+
| Format | Prettier | `.prettierrc.json` |
|
|
413
|
+
| Git Hooks | Husky + commitlint + lint-staged | `.husky/` |
|
|
414
|
+
| Interactive UI | @inquirer/prompts | `package.json` |
|
|
415
|
+
| HTTP Client | got 13.0.0 | `package.json` |
|
|
416
|
+
|
|
417
|
+
### Adding a New Command
|
|
418
|
+
|
|
419
|
+
Each command requires 3 files:
|
|
420
|
+
|
|
421
|
+
**1. Command** — `src/commands/aidev/{topic}/{name}.ts`
|
|
422
|
+
|
|
423
|
+
```typescript
|
|
424
|
+
import { SfCommand, Flags } from '@salesforce/sf-plugins-core';
|
|
425
|
+
import { Messages } from '@salesforce/core';
|
|
426
|
+
|
|
427
|
+
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
|
|
428
|
+
const messages = Messages.loadMessages('sf-aidev', 'aidev.{topic}.{name}');
|
|
429
|
+
|
|
430
|
+
export type MyResult = {
|
|
431
|
+
/* fields */
|
|
432
|
+
};
|
|
433
|
+
|
|
434
|
+
export default class MyCommand extends SfCommand<MyResult> {
|
|
435
|
+
public static readonly summary = messages.getMessage('summary');
|
|
436
|
+
public static readonly description = messages.getMessage('description');
|
|
437
|
+
public static readonly examples = messages.getMessages('examples');
|
|
438
|
+
public static readonly enableJsonFlag = true;
|
|
439
|
+
|
|
440
|
+
public static readonly flags = {
|
|
441
|
+
name: Flags.string({ char: 'n', summary: messages.getMessage('flags.name.summary'), required: true }),
|
|
442
|
+
};
|
|
443
|
+
|
|
444
|
+
public async run(): Promise<MyResult> {
|
|
445
|
+
const { flags } = await this.parse(MyCommand);
|
|
446
|
+
// implementation
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
**2. Messages** — `messages/aidev.{topic}.{name}.md`
|
|
452
|
+
|
|
453
|
+
```markdown
|
|
454
|
+
# summary
|
|
455
|
+
|
|
456
|
+
Short description of the command.
|
|
457
|
+
|
|
458
|
+
# description
|
|
459
|
+
|
|
460
|
+
Longer description with details.
|
|
461
|
+
|
|
462
|
+
# flags.name.summary
|
|
463
|
+
|
|
464
|
+
Description of the --name flag.
|
|
465
|
+
|
|
466
|
+
# examples
|
|
467
|
+
|
|
468
|
+
- Install by name:
|
|
469
|
+
<%= config.bin %> <%= command.id %> --name value
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
**3. Tests** — `test/commands/aidev/{topic}/{name}.test.ts`
|
|
473
|
+
|
|
474
|
+
Tests use Mocha + Chai + Sinon. Stub services and config, then call `Command.run([flags], oclifConfig)`.
|
|
475
|
+
|
|
476
|
+
### Conventions
|
|
477
|
+
|
|
478
|
+
- **Flags**: lowercase kebab-case (`--no-prompt`, not `--noPrompt`). Short flags: `-n` for name, `-s` for source, `-r` for repo, `-t` for type.
|
|
479
|
+
- **Errors**: Use `SfError` with a name ending in `Error` (e.g., `NotInstalledError`).
|
|
480
|
+
- **Result types**: Use `type` (not `interface`) for command result definitions.
|
|
481
|
+
- **Messages**: All user-facing strings must be in `messages/*.md` files, never hardcoded. Use `Messages.loadMessages()`.
|
|
482
|
+
- **Commands**: All commands must set `enableJsonFlag = true` for `--json` support.
|
|
483
|
+
- **Testing**: Aim for 90% coverage across lines, statements, functions, and branches.
|
|
484
|
+
- **Commits**: Follow Conventional Commits format: `<type>(<scope>): <subject>` (enforced by commitlint).
|
|
485
|
+
|
|
486
|
+
### Architecture Guidelines
|
|
487
|
+
|
|
488
|
+
- **Commands are thin** - Parse flags, call services, format output. No business logic in commands.
|
|
489
|
+
- **Services orchestrate** - `ArtifactService` and `SourceService` contain business logic.
|
|
490
|
+
- **Two config scopes** - Global config (`~/.sf/sf-aidev.json`) for sources, local config (`.sf/sf-aidev.json`) for artifacts and tool.
|
|
491
|
+
- **Static fetcher** - `GitHubFetcher` uses static methods for all GitHub API calls.
|
|
492
|
+
- **Immutable config** - Config methods return deep copies to prevent accidental mutation.
|
|
493
|
+
- **Type safety** - Use strict TypeScript types, avoid `any` unless absolutely necessary.
|
|
494
|
+
|
|
495
|
+
### Testing Guidelines
|
|
496
|
+
|
|
497
|
+
Run a single test file during development:
|
|
498
|
+
|
|
499
|
+
```bash
|
|
500
|
+
npx mocha "test/commands/aidev/add/skill.test.ts"
|
|
501
|
+
```
|
|
502
|
+
|
|
503
|
+
Standard test pattern with Sinon:
|
|
504
|
+
|
|
505
|
+
```typescript
|
|
506
|
+
const sandbox = sinon.createSandbox();
|
|
507
|
+
afterEach(() => sandbox.restore());
|
|
508
|
+
|
|
509
|
+
sandbox.stub(AiDevConfig, 'create').resolves(mockConfig);
|
|
510
|
+
sandbox.stub(ArtifactService.prototype, 'install').resolves(result);
|
|
511
|
+
const output = await Command.run(['--name', 'value'], oclifConfig);
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
Always stub:
|
|
515
|
+
- Config creation (`AiDevConfig.create`)
|
|
516
|
+
- Service methods
|
|
517
|
+
- File system operations
|
|
518
|
+
- GitHub API calls
|
|
519
|
+
|
|
520
|
+
### Git Workflow
|
|
521
|
+
|
|
522
|
+
Pre-commit hooks enforce:
|
|
523
|
+
- **Linting** - ESLint must pass
|
|
524
|
+
- **Formatting** - Prettier auto-formats staged files
|
|
525
|
+
- **Commit message** - Conventional Commits format required
|
|
526
|
+
|
|
527
|
+
Pre-push hooks enforce:
|
|
528
|
+
- **Build** - TypeScript compilation must succeed
|
|
529
|
+
- **Tests** - All tests must pass with 90% coverage
|
|
530
|
+
|
|
531
|
+
## Contributing
|
|
532
|
+
|
|
533
|
+
1. Fork the repository
|
|
534
|
+
2. Create a feature branch: `git checkout -b feat/your-feature`
|
|
535
|
+
3. Make changes following the conventions above
|
|
536
|
+
4. Write tests (aim for 90% coverage)
|
|
537
|
+
5. Ensure `yarn build` and `yarn test` pass
|
|
538
|
+
6. Commit using Conventional Commits format
|
|
539
|
+
7. Push and create a Pull Request
|
|
540
|
+
|
|
541
|
+
## Documentation
|
|
542
|
+
|
|
543
|
+
- [PLUGIN_DEV_GUIDE.md](PLUGIN_DEV_GUIDE.md) — Complete Salesforce CLI Plugin Developer Guide
|
|
544
|
+
- [PLUGIN_DEV_SUMMARY.md](PLUGIN_DEV_SUMMARY.md) — Quick reference summary
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# summary
|
|
2
|
+
|
|
3
|
+
Install an agent from a configured source repository.
|
|
4
|
+
|
|
5
|
+
# description
|
|
6
|
+
|
|
7
|
+
Install an agent by name from a configured source repository, or interactively select from available agents when no name is provided. The agent is installed to the correct path for the detected AI tool (e.g., `.github/agents/` for Copilot, `.claude/agents/` for Claude).
|
|
8
|
+
|
|
9
|
+
# flags.name.summary
|
|
10
|
+
|
|
11
|
+
Name of the agent to install. If not provided, shows interactive selection.
|
|
12
|
+
|
|
13
|
+
# flags.source.summary
|
|
14
|
+
|
|
15
|
+
Source repository (owner/repo) to install from. Defaults to the configured default source.
|
|
16
|
+
|
|
17
|
+
# examples
|
|
18
|
+
|
|
19
|
+
- Interactively select agents to install:
|
|
20
|
+
|
|
21
|
+
<%= config.bin %> <%= command.id %>
|
|
22
|
+
|
|
23
|
+
- Install an agent named "my-agent":
|
|
24
|
+
|
|
25
|
+
<%= config.bin %> <%= command.id %> --name my-agent
|
|
26
|
+
|
|
27
|
+
- Install from a specific source:
|
|
28
|
+
|
|
29
|
+
<%= config.bin %> <%= command.id %> --name my-agent --source owner/repo
|
|
30
|
+
|
|
31
|
+
# error.InstallFailed
|
|
32
|
+
|
|
33
|
+
Installation of agent "%s" failed: %s
|
|
34
|
+
|
|
35
|
+
# error.NonInteractive
|
|
36
|
+
|
|
37
|
+
This command requires an interactive terminal when no agent name is provided.
|
|
38
|
+
|
|
39
|
+
# error.NonInteractiveActions
|
|
40
|
+
|
|
41
|
+
Provide an agent name with --name flag, or run in an interactive terminal.
|
|
42
|
+
|
|
43
|
+
# error.NoTool
|
|
44
|
+
|
|
45
|
+
No AI tool is configured for this project.
|
|
46
|
+
|
|
47
|
+
# error.NoToolActions
|
|
48
|
+
|
|
49
|
+
Run `sf aidev init` to detect and configure an AI tool, or set one manually.
|
|
50
|
+
|
|
51
|
+
# info.AgentInstalled
|
|
52
|
+
|
|
53
|
+
Successfully installed agent "%s" to %s
|
|
54
|
+
|
|
55
|
+
# info.Fetching
|
|
56
|
+
|
|
57
|
+
Fetching available agents...
|
|
58
|
+
|
|
59
|
+
# info.NoArtifacts
|
|
60
|
+
|
|
61
|
+
No agents available in configured sources.
|
|
62
|
+
|
|
63
|
+
# info.AllInstalled
|
|
64
|
+
|
|
65
|
+
All available agents are already installed.
|
|
66
|
+
|
|
67
|
+
# info.NoneSelected
|
|
68
|
+
|
|
69
|
+
No agents selected for installation.
|
|
70
|
+
|
|
71
|
+
# info.Installing
|
|
72
|
+
|
|
73
|
+
Installing %s agent(s)...
|
|
74
|
+
|
|
75
|
+
# info.Installed
|
|
76
|
+
|
|
77
|
+
Successfully installed %s agent(s):
|
|
78
|
+
|
|
79
|
+
# info.Skipped
|
|
80
|
+
|
|
81
|
+
Skipped %s agent(s) (already installed):
|
|
82
|
+
|
|
83
|
+
# warning.Failed
|
|
84
|
+
|
|
85
|
+
Failed to install %s agent(s):
|
|
86
|
+
|
|
87
|
+
# prompt.Select
|
|
88
|
+
|
|
89
|
+
Select agents to install (use Space to select, Enter to confirm):
|