Jay-Stack Setup Command
Jay Stack Setup Command
Written for AI agents. See Log Methodology Note below for details.
Date: February 9, 2026
Status: Draft
Related: Design Logs #60 (plugin system), #65 (makeJayInit), #85 (agent-kit), #86 (lifecycle)
Background
Design Log #86 identifies Phase 2 "Plugin Setup" as a gap: after installing plugins and before running agent-kit, plugins need configuration (credentials, connections) and can generate reference data (collection schemas, category lists). Today:
- Plugin init (
makeJayInit) registers services but has no mechanism for first-time config setup - No CLI command creates config templates or validates credentials
- The agent-kit template docs (
cli-commands.md,project-structure.md) already referencejay-stack setupbut it doesn't exist PluginManifesthas nosetupfield
Problem
Plugins like wix-data and wix-stores need credentials (API keys, site URLs) to function. Currently a developer must manually create config files by reading plugin docs. There's no:
- Guided config creation (templates with required fields)
- Credential/connection validation before attempting to build
- Reference data generation (collection schemas, product lists) that agents need for informed page generation
Design
Three-Phase Setup Flow
jay-stack setup [plugin] [--force]
│
▼
┌──────────────────────────┐
│ 1. CONFIG CHECK │
│ Does config exist? │
│ No → create template │
│ Yes → continue │
├──────────────────────────┤
│ 2. SERVICE INIT + VERIFY │
│ Run plugin init │
│ Failed → report error │
│ OK → continue │
├──────────────────────────┤
│ 3. REFERENCE GENERATION │
│ Call setup hook with │
│ live services │
│ Write to agent-kit/ │
│ references/<plugin>/ │
└──────────────────────────┘
Plugin.yaml Extension
# plugin.yaml
name: wix-stores
setup:
handler: setupWixStores # Export name (NPM) or path (local)
description: Configure Wix Stores credentials and generate product catalog reference
PluginManifest Type Change
In compiler-shared/lib/plugin-resolution.ts:
export interface PluginManifest {
// ...existing fields...
setup?: {
handler: string; // Export name or relative path to setup module
description?: string; // Human-readable description of what setup does
};
}
Setup Handler Interface
interface PluginSetupContext {
pluginName: string;
projectRoot: string;
configDir: string; // From .jay configBase, defaults to ./config
referencesDir: string; // agent-kit/references/<plugin>/
services: Map<symbol, unknown>; // Registered services (empty if init failed)
initError?: Error; // Present if plugin init failed
force: boolean; // --force flag
}
interface PluginSetupResult {
status: 'configured' | 'needs-config' | 'error';
configCreated?: string[]; // Config files created (relative paths)
referencesCreated?: string[]; // Reference files created (relative paths)
message?: string; // Human-readable status message
}
// Plugin exports this function:
type PluginSetupHandler = (context: PluginSetupContext) => Promise<PluginSetupResult>;
How the Handler Works
The handler gets full context and decides what to do:
// Example: wix-stores/lib/setup.ts
export async function setupWixStores(ctx: PluginSetupContext): Promise<PluginSetupResult> {
const configPath = path.join(ctx.configDir, 'wix-stores.yaml');
// Phase 1: Config check
if (!fs.existsSync(configPath)) {
// Create template with placeholders
fs.writeFileSync(
configPath,
YAML.stringify({
apiKey: '<your-api-key>',
siteUrl: '<your-site-url>',
}),
);
return {
status: 'needs-config',
configCreated: ['config/wix-stores.yaml'],
message: 'Config template created. Fill in credentials and re-run setup.',
};
}
// Phase 2: Verify services
if (ctx.initError) {
return {
status: 'error',
message: `Service initialization failed: ${ctx.initError.message}`,
};
}
// Phase 3: Generate references
const storesService = ctx.services.get(WIX_STORES_SERVICE_MARKER);
const products = await storesService.products.list({ limit: 50 });
const categories = await storesService.categories.list();
await fs.promises.mkdir(ctx.referencesDir, { recursive: true });
fs.writeFileSync(
path.join(ctx.referencesDir, 'products.yaml'),
YAML.stringify({
products: products.items.map((p) => ({ id: p._id, name: p.name, slug: p.slug })),
}),
);
fs.writeFileSync(
path.join(ctx.referencesDir, 'categories.yaml'),
YAML.stringify({
categories: categories.items.map((c) => ({ id: c._id, name: c.name, slug: c.slug })),
}),
);
return {
status: 'configured',
referencesCreated: [
'agent-kit/references/wix-stores/products.yaml',
'agent-kit/references/wix-stores/categories.yaml',
],
message: `Found ${products.items.length} products, ${categories.items.length} categories`,
};
}
CLI Command
# Run setup for all plugins that declare setup in plugin.yaml
jay-stack setup
# Run setup for a specific plugin
jay-stack setup wix-stores
# Force re-run (overwrite config templates and regenerate references)
jay-stack setup --force
# Verbose output
jay-stack setup -v
CLI Output
$ jay-stack setup
🔧 Setting up plugins...
📦 wix-stores
⚠️ Config template created: config/wix-stores.yaml
→ Fill in credentials and re-run: jay-stack setup wix-stores
📦 wix-data
✅ Services verified
✅ Generated references:
agent-kit/references/wix-data/collections.yaml (4 collections)
Setup complete: 1 configured, 1 needs config
Reference Data Location
Reference data goes to agent-kit/references/<plugin>/ because:
- It's discovery material for agents, not runtime config
- Same audience as
agent-kit/materialized-contracts/ - Design Log #85 already proposed
agent-kit/references/ - Keeps
config/focused on credentials and runtime settings
File Layout After Setup
config/
├── project.conf.yaml
├── wix-stores.yaml ← credentials (may be gitignored)
└── wix-data.yaml ← credentials
agent-kit/
├── references/
│ ├── wix-stores/
│ │ ├── products.yaml ← reference catalog
│ │ └── categories.yaml
│ └── wix-data/
│ └── collections.yaml ← collection schemas
├── materialized-contracts/ ← from jay-stack agent-kit
└── INSTRUCTIONS.md ← from jay-stack agent-kit
Implementation Plan
Phase 1: PluginManifest + Setup Handler Types
- Add
setupfield toPluginManifestincompiler-shared/lib/plugin-resolution.ts - Create setup handler types in
stack-server-runtime(or a shared location) - Update plugin-validator to accept
setupfield
Phase 2: CLI Command
- Add
setupcommand tostack-cli/lib/cli.ts - Create
stack-cli/lib/run-setup.tswith:- Discover plugins with
setupin plugin.yaml - For each plugin: attempt init → load setup handler → call it → report result
- Discover plugins with
- Wire up Vite server for TypeScript loading (same pattern as
run-action.ts)
Phase 3: Update Docs
- Verify agent-kit template
cli-commands.mdmatches implementation - Verify
project-structure.mdreferences are accurate - Update skill files if needed
Phase 4: Example Plugin Setup Handler
- Add
setuptowix-stores/plugin.yaml - Implement
setupWixStoresinwix-stores/lib/setup.ts - Test full flow: no config → template → fill in → setup → references
Questions
Q1: Should setup run init for ALL plugins or only the target plugin?
Answer: Run init for all plugins (they may depend on each other), but only call the setup handler for the target plugin(s). Uses the existing initializeServicesForCli which already handles dependency ordering.
Q2: What if a plugin has no setup but needs config?
Plugins without setup in plugin.yaml are skipped by jay-stack setup. The setup handler is opt-in — not all plugins need first-time configuration. Plugins that only provide static contracts (no credentials needed) don't need it.
Q3: Should setup validate the config file schema?
Not in v1. The setup handler receives the config dir and can validate itself. A schema validation system could be added later if needed.
Q4: Should --force recreate config templates even if config exists?
Yes. --force means "start fresh" — recreate config template (backing up existing) and regenerate all references.
Plugin Setup Handlers
wix-server-client
This is the foundation — wix-stores and wix-data both depend on WIX_CLIENT_SERVICE.
Setup behavior:
- No config → create
config/.wix.yamltemplate with placeholder apiKey, siteId, oauthClientId - Config exists → run init, try to create a WixClient, report success/failure
- No reference data (credentials-only plugin)
# plugin.yaml addition
setup:
handler: setupWixServerClient
description: Configure Wix API credentials
wix-stores
Depends on: wix-server-client (needs WIX_CLIENT_SERVICE)
Setup behavior:
- No own config — credentials come from wix-server-client
- If services available → fetch products (via
searchProducts) and categories (viaqueryCategories), write toagent-kit/references/wix-stores/ - If services unavailable (wix-server-client not configured) → report dependency error
References generated:
agent-kit/references/wix-stores/products.yaml— product catalog (id, name, slug, price)agent-kit/references/wix-stores/categories.yaml— category list (id, name, slug)
# plugin.yaml addition
setup:
handler: setupWixStores
description: Generate product and category reference data
wix-data
Depends on: wix-server-client (needs WIX_CLIENT_SERVICE)
Setup behavior:
- No config → call existing
generateDefaultConfig(wixClient)which fetches collection schemas from API and writesconfig/wix-data.yaml+config/wix-data-collections.md - Config exists → validate, generate reference data
- Already has config auto-generation logic in
config-loader.ts— setup handler delegates to it
References generated:
agent-kit/references/wix-data/collections.yaml— collection schemas with field types and relationships
# plugin.yaml addition
setup:
handler: setupWixData
description: Configure CMS collections and generate schema references
Setup Order
Since setup runs init for all plugins (dependency-ordered), the natural execution order is:
- wix-server-client setup → creates credentials config
- wix-data setup → generates collection config + references
- wix-stores setup → generates product/category references
Running jay-stack setup with no args runs all three in order. Running jay-stack setup wix-stores runs init for all but only calls the wix-stores setup handler.
Trade-offs
| Decision | Pro | Con |
|---|---|---|
| Single handler function (not 3 separate hooks) | Simple API, plugin decides what to do | Plugin must handle all phases internally |
References in agent-kit/ not config/ |
Clean separation: config = runtime, references = discovery | Two output locations from one command |
| Handler gets services map directly | Plugins can use their own service markers | Loosely typed (Map<symbol, unknown>) |
| Setup is explicit CLI command, not automatic | Developer controls when setup runs, no surprise side effects | Extra step to remember |
Implementation Results
Files Created/Modified
New files:
jay/packages/jay-stack/stack-server-runtime/lib/plugin-setup.ts— Types (PluginSetupContext,PluginSetupResult,PluginSetupHandler) + discovery + execution logicjay/packages/jay-stack/stack-cli/lib/run-setup.ts— CLI handler with config dir resolution, init error capture, per-plugin reportingwix/packages/wix-server-client/lib/setup.ts— Creates.wix.yamltemplate, validates credentialswix/packages/wix-stores/lib/setup.ts— Generates products.yaml + categories.yaml referenceswix/packages/wix-data/lib/setup.ts— Generates collections.yaml references with field schemas
Modified files:
compiler-shared/lib/plugin-resolution.ts— Addedsetupfield toPluginManifeststack-server-runtime/lib/index.ts— Exportsplugin-setupstack-cli/lib/cli.ts— Registeredsetupcommandwix-server-client/plugin.yaml,lib/index.ts— Added setup handler/exportwix-stores/plugin.yaml,lib/index.ts— Added setup handler/exportwix-data/plugin.yaml,lib/index.ts— Added setup handler/exportagent-kit-template/cli-commands.md— Updated setup descriptionagent-kit-template/project-structure.md— Addedagent-kit/references/to layout
Deviations from Design
- Handler loading for NPM plugins: Design proposed handler as export name. Implementation loads from package main module and looks up the named export. For local plugins, it resolves as a file path and looks for
setupordefaultexport. - wix-data config creation: Not handled by the setup handler directly. wix-data's existing
loadConfig()in init already auto-generatesconfig/wix-data.yamlwhen missing. The setup handler validates this happened. - Init error handling: The CLI runs
initializeServicesForClionce for all plugins (not per-plugin). If it fails, the error is passed to all setup handlers. Handlers decide how to react based on their needs. - Reference generation split from setup: Original design had setup handlers generating references. Refactored so setup only handles config + validation, and reference generation is a separate
setup.referenceshook called byjay-stack agent-kit. This is cleaner: setup answers "can I connect?", agent-kit answers "prepare everything for agents". Plugin.yaml hassetup.handler(for config/validation) andsetup.references(for discovery data). Agent-kit command runs references after materializing contracts, using the same Vite server and initialized services. Added--no-referencesflag to agent-kit for skipping.
Log Methodology Note
Note: These design logs are written primarily for AI agents as part of the Design Log methodology and made accessible here for human readers. The language and structure are optimized for machine consumption — expect precise, specification-style prose rather than narrative documentation.