System shape
Thin commands. Clear layers. Testable by design.
The plugin follows the same architectural patterns as profiler and JT_DynamicQueries: each layer has a single responsibility, and the command layer stays as thin as possible.
Parse flags, delegate to setup layer, return typed results.
promptScope and printToConsole are injected into setup functions so tests avoid global mocks.
Result<T, E> in src/types/index.ts keeps error handling composable without exceptions.
All content generation is side-effect free: inputs in, strings out. Zero I/O.
Boundaries
sf setup-agents local ·
sf setup-agents mcp ·
sf setup-agents update
Parse flags · Call detectTools / resolveProfiles · Delegate to Setup Layer · Return typed result
src/setup/
cursor-setup.ts ·
vscode-setup.ts ·
codex-setup.ts ·
claude-setup.ts ·
agentforce-setup.ts
Orchestrates file creation. Calls Generators to build content. Calls FileWriter to persist. Receives promptScope and printToConsole as injected functions.
src/generators/
src/services/
FileWriter — centralises force/skip logic, calls writeFileSync, invokes log/warn callbacks.
ensureDir — creates directories recursively if they don't exist.
Repository map
src/
├── commands/
│ └── setup-agents/
│ ├── local.ts ← sf setup-agents local
│ ├── mcp.ts ← sf setup-agents mcp
│ └── update.ts ← sf setup-agents update
├── generators/
│ ├── mdc-generator.ts
│ ├── workflow-generator.ts
│ ├── copilot-generator.ts
│ ├── codex-generator.ts
│ ├── claude-generator.ts
│ ├── extensions-generator.ts
│ ├── agentforce-generator.ts
│ ├── shared.ts
│ └── index.ts
├── setup/
│ ├── cursor-setup.ts
│ ├── vscode-setup.ts
│ ├── codex-setup.ts
│ ├── claude-setup.ts
│ ├── agentforce-setup.ts
│ └── index.ts
├── profiles/
│ ├── types.ts ← Profile interface
│ ├── developer.ts
│ ├── architect.ts
│ ├── ba.ts mulesoft.ts ux.ts cgcloud.ts
│ ├── devops.ts qa.ts crma.ts data360.ts
│ └── index.ts
├── services/
│ └── file-writer.ts ← FileWriter + ensureDir
├── types/
│ └── index.ts ← SupportedTool, Result<T,E>, SetupLocalResult
└── version.ts ← PLUGIN_VERSION constant
Contracts
Result<T, E>Lightweight Result monad. ok<T>(value) and err<E>(error) constructors. Enables composable error flows without throw/catch chains.
type Result<T, E = Error> =
| { ok: true; value: T }
| { ok: false; error: E }
ProfileInterface every profile object implements. detect?(cwd) for auto-detection, ruleContent() for .mdc generation, workflows?(version) for Agentforce workflows.
interface Profile {
id: ProfileId
label: string
ruleFile: string
ruleContent(): string
extensions?: string[]
detect?(cwd: string): boolean
workflows?(v: string): Record<string, string>
}
SupportedToolUnion type for the 5 supported AI tools. Used by detectTools() and the --rules flag.
type SupportedTool =
| 'cursor'
| 'vscode'
| 'codex'
| 'claude'
| 'agentforce'
FileWriterInjected into every setup function. Centralises the force/skip decision so all setup modules share the same write behaviour.
class FileWriter {
write(path: string, content: string)
: 'written' | 'skipped'
}
Tests were written error-first following the EDD (Error-Driven Development) philosophy.