@krizic/vsuite
The vsuite command-line interface. It configures and generates project-local AI agents, skills, and MCP configuration for OpenCode, Claude Code, and GitHub Copilot from one validated vsuite.json. This page is the reference for the CLI and the configuration file; the desktop app (@vsuite/ui) runs the same workflows.
The package publishes only the vsuite binary and the JSON Schema @krizic/vsuite/schema/vsuite.schema.json. There is no JavaScript API: exports contains only ./schema/vsuite.schema.json and ./package.json. The internal @vsuite/* workspace packages are bundled into dist/main.js and are not published.
Install
Requires Node.js 24 or later. Run commands from the root of the project that receives the generated files.
The npm registry currently carries an older release (0.3.1) that predates most of this reference; the current version will be published together with the source code. Until then, contributors run the CLI from source (see Development).
pnpm dlx @krizic/vsuite init # run once without installing
pnpm add -D @krizic/vsuite # or install as a dev dependency (enables editor schema validation)
pnpm add --global @krizic/vsuite # or install globallyCommands
| Command | Description |
|---|---|
vsuite init |
Detects the stack, runs an interactive wizard, writes vsuite.json, and generates artifacts. Fails if vsuite.json already exists. |
vsuite generate [--update-packs] [--strict] |
Migrates vsuite.json to this vsuite version if needed, validates it, writes every output, and prints each written path. --update-packs accepts changed npm:/git: pack content and relocks it instead of failing with PACK_INTEGRITY. --strict treats Markdown lint warnings (MD_LINT) as errors and writes nothing. |
vsuite migrate [--dry-run] |
Upgrades vsuite.json to this vsuite version and regenerates. --dry-run prints the pending migrations and a diff, and writes nothing. |
vsuite graph [--format json|mermaid] [-o <path>] |
Prints the agent graph (JSON by default) or writes it to a file. |
vsuite stack set <category> <id...|none> |
Changes one stack category, updates the agents, and regenerates. |
vsuite pack add <source> [--name <name>] |
Fetches and validates a pack (path:<dir>, npm:<spec>, git:<url>#<ref>), writes vsuite.json and vsuite.lock.json, and reports what it adds or overrides. |
vsuite pack remove <name> [--reset-to-catalog] |
Removes a pack. Refuses while agents or skills use it unless --reset-to-catalog resets them (entries not in the catalog are removed). |
vsuite pack list [--json] |
Sources, locked versions, integrity status, and contributions. |
vsuite pack update [name] |
Refetches and relocks one or all packs. |
vsuite pack validate <dir> [--json] [--strict] |
Checks a pack directory without a project. |
vsuite agent use <id> --from <pack|catalog> |
Chooses where an agent comes from; a new pack agent is added as a specialist. |
vsuite skill use <id> --from <pack|catalog> |
Chooses where a skill comes from. |
vsuite, vsuite --help, vsuite -h |
Prints usage. Unknown commands print usage and exit 1. |
Commands exit 1 and print the error message on failure.
The init wizard
vsuite init detects technologies from package.json, requirements.txt, pyproject.toml, go.mod, pom.xml, build.gradle, build.gradle.kts, and *.csproj, and prefills the stack. It then asks for targets, stack, agents, skills, capabilities, the preferences the selected agents need, MCP connection settings, and one default model (with optional effort and reasoning) applied to every agent. Edit modelProfiles afterwards to override individual agents.
When the agent-memory capability is selected, init also checks that npx is available, that @agentmemory/mcp is reachable in the npm registry, and whether the local agentmemory engine is running, then prints the remaining manual steps.
Configuration
vsuite.json is validated against a strict schema. For editor validation and completion, reference the published schema; this requires a local dev install, because pnpm dlx and global installs do not create the node_modules path.
This example selects every target, wires Context7, and defines a coordinator with one specialist:
{
"$schema": "./node_modules/@krizic/vsuite/schema/vsuite.schema.json",
"version": "0.7.1",
"targets": ["opencode", "claude-code", "github-copilot"],
"mcpServers": { "context7": { "source": "catalog" } },
"agents": {
"orchestrator": {
"role": "coordinator",
"canCall": ["backend-engineer"],
"skills": ["agent-efficiency-protocol"],
"tools": ["read", "search", "todo", "agent"],
"mcps": { "context7": ["*"] }
},
"backend-engineer": {
"role": "specialist",
"skills": ["agent-efficiency-protocol"],
"tools": ["read", "edit", "search", "execute", "todo", "web"],
"mcps": { "context7": ["*"] }
}
},
"modelProfiles": {
"default": {
"agents": {
"orchestrator": { "model": "github-copilot/claude-opus-5.5" },
"backend-engineer": { "model": "github-copilot/claude-opus-5.5" }
}
}
},
"activeModelProfile": "default"
}Top-level fields: version, targets, stack, capabilities, mcpServers, packs, agents, skillSources, projectSkills, projectSkillsDirectory, preferences, modelProfiles, and activeModelProfile. Every configured agent needs model settings in every model profile.
Agents and the agent graph
agents is the only source of agent behavior. Each entry has:
role:coordinatororspecialist. At most one agent is the coordinator. Only the coordinator may declarecanCalland hold theagenttool. Specialists finish with a handoff back to the coordinator, which decides who runs next.skills: built-in skill ids, or ids listed inprojectSkills.tools: the neutral vocabularyread,edit,search,execute,web,browser,todo, andagent.mcps:{ "<server>": ["*"] }or specific tool names, such as"prisma": ["migrate-dev"]. Every server must be declared inmcpServers.stack(optional): stack categories whose conventions the agent’s prompt includes.metrics(optional, defaultfalse): adds the detailed job-metrics contract and a per-target report script.source(optional):catalogorpack:<name>.
Each target enforces the graph in its own way:
| Field | OpenCode | Claude Code | GitHub Copilot |
|---|---|---|---|
canCall |
permission.task |
Agent(...) in tools, enforced when started with claude --agent <coordinator> |
agents: allow-list |
skills |
permission.skill |
skills: preload (not enforced; warns) |
skill paths in the prompt |
tools |
tools map |
tools: |
tools: |
mcps |
mcp in .opencode/opencode.json with per-agent tool gates |
.mcp.json and mcp__<server>__<tool> |
.vscode/mcp.json and <server>/<tool> |
When a target cannot express a field, vsuite generate prints a named warning, such as warning [claude-code] skills-not-enforced: …. Nothing is dropped silently.
The catalog has 19 agents. The default set includes the orchestrator, backend and frontend engineers, software architect, project manager, UI/UX designer, design reviewer, docs steward, market requirements analyst, project onboarding agent, code reviewer, and QA evidence tester. Optional agents cover DevOps, Git workflow, database optimization, security auditing, performance engineering, tech debt analysis, and agent optimization.
GitHub Copilot agents use the custom agent frontmatter: review-only agents (code-reviewer, design-reviewer, qa-evidence-tester) get user-invocable: false, agent-optimizer gets disable-model-invocation: true, and planning and implementation roles get handoffs buttons to their next step.
Agent graph output
vsuite graph # JSON on stdout
vsuite graph --format mermaid # Mermaid on stdout
vsuite graph -o docs/agent-graph.mdWith -o/--output, the extension picks the format unless --format is given: .json writes JSON, .mmd writes Mermaid, and .md writes Mermaid in a fenced block. The file is replaced atomically.
Stack
stack records the selected technologies. frontend takes one framework plus optional companion shells (such as electron), database takes a list, and backend, orm, and designLibrary take one id or null.
| Category | Ids |
|---|---|
frontend |
nextjs, nuxt, angular, svelte, react, vue, and the companion electron |
backend |
nestjs, express, fastify, fastapi, django, go, spring-boot, aspnet-core |
orm |
prisma, drizzle, typeorm, sqlalchemy, django-orm, ef-core |
database |
postgresql, mysql, sqlite, mongodb, redis |
designLibrary |
daisyui, mui, antd, chakra-ui, radix-ui, tailwind |
Each technology except design libraries adds a <id>-conventions skill. The owning agents (the frontend engineer for frontend; the backend engineer for backend; the database optimizer and backend engineer for ORM and database) also get the technology’s MCP server where one exists. Reviewers and other readers get the skill and Context7.
vsuite stack set orm drizzle
vsuite stack set database postgresql redis
vsuite stack set frontend react electron
vsuite stack set frontend nonestack set removes what the catalog added for the old choice and adds what it adds for the new one. Entries you edited by hand are kept and reported as warning stack: ….
MCP servers and secrets
mcpServers declares the servers agents may use. Catalog servers: agent-memory, context7, playwright, prisma, prisma-remote, next-devtools, angular-cli, angular-cli-readonly, svelte, nuxt, microsoft-learn, gopls, mongodb, redis, postgres-mcp-pro, electron, github, gitlab, and obsidian.
Secret settings are stored as ${VAR} references in vsuite.json, never as values. The values live in the git-ignored .vsuite/.env; generate adds .vsuite/ to .gitignore.
"mcpServers": { "mongodb": { "source": "catalog", "env": { "MDB_MCP_CONNECTION_STRING": "${MONGODB_URI}" } } }vsuite also generates its own MCP server, vsuite (.vsuite/vsuite-mcp.mjs), and grants it to every agent. Its tools are current_time and log_job.
Capabilities
The top-level capabilities list holds declarable capabilities that are not MCP servers; currently only brainstorming. MCP-backed capabilities (agent-memory, context7, playwright, prisma) come from their mcpServers entry.
brainstormingwrites thebrainstormingandwriting-plansskills to every target and adds a Brainstorming And Planning section to the orchestrator. The skill text is vendored from superpowers v5.1.0 (MIT, © 2025 Jesse Vincent); see@vsuite/templates.agent-memorywires the agentmemory MCP server (npx -y @agentmemory/mcp) and adds a Persistent Memory section to the granted agents. Project-local data lives under.vsuite/agentmemory.initprints the command that starts the local engine (REST API on port 3111, viewer on port 3113).
Preferences
Agents that need a tracking system or documentation location read it from preferences. Both accept any non-empty string; the wizard and the desktop app offer these values:
| Preference | Offered values |
|---|---|
tracking.provider |
None, GitHub, GitLab, Gitea |
documentation.location |
None, Obsidian, Local |
Known values match case-insensitively; unknown values render with generic wording.
Per-target models
Targets use incompatible model ids, so model accepts either a string (for every target) or an object keyed by target with an optional default:
"code-reviewer": {
"model": { "opencode": "github-copilot/claude-opus-5.5", "claude-code": "opus", "default": "claude-opus-5.5" }
}| Target | model format |
Validated |
|---|---|---|
opencode |
provider/model-id |
Yes |
claude-code |
alias (such as sonnet or opus), inherit, or a full model id |
No |
github-copilot |
free string | No |
Each target resolves to its own key, then default. A selected target with neither fails validation with no model for target "<target>" (add "<target>" or "default").
Project skills
projectSkillsDirectory names a source-controlled directory of your own skills, such as .vsuite/skills. List each skill id in projectSkills and in the skills of the agents that use it. Each <directory>/<id>/SKILL.md needs frontmatter whose name equals the id and whose description says when to use the skill:
---
name: tenancy-rls-verification
description: Use when verifying tenant isolation and row-level security.
---Generated files
| Target | Agents | Skills | MCP and native config |
|---|---|---|---|
opencode |
.opencode/agents/<id>.md |
.opencode/skills/<id>/SKILL.md |
.opencode/opencode.json |
claude-code |
.claude/agents/<id>.md |
.claude/skills/<id>/SKILL.md |
.mcp.json |
github-copilot |
.github/agents/<id>.agent.md |
.github/skills/<id>/SKILL.md |
.vscode/mcp.json |
Every run also writes .vsuite/vsuite-mcp.mjs and the job-metrics tooling in .vsuite/agent-metrics/ (jobs.schema.json, validate-metrics.mjs, merge-telemetry.mjs). When any agent sets metrics: true, each target also gets <target dir>/scripts/agent-metrics.mjs. .vsuite/mcp-env.mjs is written when a stdio server needs .vsuite/.env.
Existing native config is extended, not replaced: unrelated .opencode/opencode.json settings, MCP servers, and custom agents are preserved. JSONC comments in .opencode/opencode.json are not preserved, and a malformed file stops generation before anything is written.
generate removes catalog skills that are no longer selected and pack agents, skills, and instructions that are no longer generated. It does not remove catalog agents you deselect or files of targets you deselect; delete those deliberately.
Job metrics
Every agent logs its own completed job through the vsuite MCP server: current_time supplies timestamps and log_job validates the record and appends it to .vsuite/agent-metrics/jobs.jsonl. Records from the pre-0.7 .agent-metrics/ directory are merged into the new location on the next generate. The desktop app’s Metrics tab reads this log.
Packs
Packs add or override agents, skills, and instructions with Liquid templates. A typical session:
$ vsuite pack add path:./packs/acme
Added pack acme: Acme Engineering Standards 1.2.0
agents added: secure-reviewer
agents overriding the catalog: code-reviewer
skills added: acme-threat-model
skills overriding the catalog: -
instructions added: development-standards
Select entries with `vsuite agent use <id> --from acme`, then run `vsuite generate`.
$ vsuite agent use secure-reviewer --from acme
agent secure-reviewer now uses pack:acme
added agent secure-reviewer as a specialist
Run `vsuite generate` to update generated files.Pack errors print their code (PACK_*, TPL_*, MD_LINT), the file and line, and a hint. See the pack author guide (including the error table) and the enterprise pack guide.
Config versions and migration
version in vsuite.json is the vsuite release the config conforms to. vsuite init writes the running CLI version; the legacy integer "version": 1 is treated as 0.0.0.
vsuite generatemigrates automatically, prints one line per applied migration and the version change, and writesvsuite.jsonatomically.vsuite migratedoes the same and regenerates. With nothing to do, it printsvsuite.json is up to date (<version>)and still regenerates.vsuite migrate --dry-runprintsvsuite.json <from> → <to> (dry run, nothing written), the pending migrations, and a unified diff.- Upgrading the CLI restamps
versionon the nextgenerateormigrate, even when no format change applies. - A config newer than the CLI fails with
vsuite.json was written by vsuite <version>; upgrade @krizic/vsuite to <version> or later.
The registered format changes are listed in @vsuite/migrations.
Development
From the repository root:
pnpm vsuite <command> # run the CLI from source (tsx)
pnpm run build # bundle packages/cli/dist/main.js
pnpm run schema # regenerate schema/vsuite.schema.json
pnpm vitest run --project @krizic/vsuite # this package's testsTo try a local build in another project, pack it and install the tarball; it is self-contained:
pnpm --filter @krizic/vsuite pack --pack-destination /tmp # prepack runs build and schema
pnpm add -g /tmp/krizic-vsuite-<version>.tgzA globally installed vsuite is a separate copy. If it lacks a command listed above, it is out of date.
The version comes from the root package.json; pnpm run version:sync copies it into this package (a test enforces they match). See architecture for bundling and the release flow.