@soulcraft/kit-schema (2.15.0)
Installation
@soulcraft:registry=npm install @soulcraft/kit-schema@2.15.0"@soulcraft/kit-schema": "2.15.0"About this package
@soulcraft/kit-schema
Shared kit manifest schema for the Soulcraft platform ecosystem.
Defines the contract between Soulcraft products (Venue, Workshop) and the domain-specific kits that configure them. A kit ships the branding, feature flags, AI personas, experience types, and content templates that turn a generic platform deployment into a polished, vertical-specific product.
What Is a Kit?
A kit is a directory containing:
my-kit/
├── kit.json # Manifest — validated by this package
├── files/ # Template content (email HTML, waiver text, CMS seed data)
└── skills/ # AI skill definitions in SKILL.md format
The kit.json manifest describes:
- Identity —
id,name,description,version,author - Variables — configurable values (
{{BUSINESS_NAME}},{{LOCATION_CITY}}) substituted at deploy time - Product config block —
venue,workshop, oracademy— product-specific settings
Kit Types
type field |
Product | Schema |
|---|---|---|
"venue" |
Soulcraft Venue | VenueKitSchema |
"content" |
Soulcraft Workshop | WorkshopKitSchema |
"app" |
Soulcraft Workshop | WorkshopKitSchema |
"academy" |
Soulcraft Academy (reserved) | AcademyKitSchema |
The universal KitManifestSchema is a discriminated union that selects the correct
schema based on type.
Installation
This package is a workspace dependency — it is not published to npm.
{
"dependencies": {
"@soulcraft/kit-schema": "workspace:*"
}
}
Usage
Validate a kit.json
import { KitManifestSchema } from '@soulcraft/kit-schema';
const rawJson = JSON.parse(await Bun.file('kit.json').text());
const result = KitManifestSchema.safeParse(rawJson);
if (!result.success) {
console.error('Invalid kit manifest:', result.error.format());
} else {
console.log('Kit loaded:', result.data.name);
}
Load a Venue kit
import { loadVenueKit } from '@soulcraft/kit-schema';
const kit = await loadVenueKit('./kits/wicks-and-whiskers');
const { features, theme, experienceTypes } = kit.manifest.venue;
Load any kit (Workshop or Venue)
import { loadKitFromDirectory } from '@soulcraft/kit-schema';
const kit = await loadKitFromDirectory('./kits/novel-writing-system');
// kit.manifest.type === 'content' | 'app' | 'venue' | 'soulcraft' | 'academy'
Parse a skill file
import { parseSkillFile } from '@soulcraft/kit-schema';
const skill = await parseSkillFile('./kits/my-kit/skills/expert-editor.md');
// skill.name, skill.description, skill.trigger, skill.content
Substitute variables
import { substituteVariables } from '@soulcraft/kit-schema';
const html = substituteVariables(template, {
BUSINESS_NAME: 'Wicks & Whiskers',
LOCATION_CITY: 'Charlotte',
});
TypeScript Types
import type {
// Kit manifests
VenueKitConfig, // Full Venue kit (manifest + resolved config)
WorkshopKitConfig, // Full Workshop kit (manifest + resolved config)
KitManifest, // Union of all kit manifest types
// Venue-specific
VenueFeatures, // Feature flags (animals, adoption, loyalty, pos…)
VenueKitTheme, // Theme (primary, accent, displayFont…)
VenueExperienceType, // Experience definition (price, duration, capacity…)
SessionAttributeDefinition, // What staff log after a session
// Workshop-specific
WorkshopKitSuggestion, // Prompt chip (label + prompt)
WorkshopExporter, // Custom export handler
// Workshop → Venue publish protocol
PublishPayload, // Discriminated union of content types
AppPublishContent, // Compiled Svelte bundle
DocumentPublishContent, // Markdown or HTML body
VisualizationPublishContent, // Graph snapshot + view type
SlideshowPublishContent, // Array of Markdown slides
StaticPublishContent, // Static file tree with entry point
// Loader output
LoadedKit, // { manifest, kitDir, variables, skills }
// Zod inferred inputs (before default resolution)
VenueKitInput,
WorkshopKitInput,
PublishPayloadInput,
} from '@soulcraft/kit-schema';
Venue Kit kit.json Example
{
"id": "wicks-and-whiskers",
"type": "venue",
"name": "Wicks & Whiskers",
"description": "Candle-making + kitten adoption café franchise platform",
"version": "1.0.0",
"author": { "name": "Soulcraft Labs", "email": "hello@soulcraft.com" },
"variables": [
{ "key": "BUSINESS_NAME", "label": "Business name", "type": "string", "required": true },
{ "key": "LOCATION_CITY", "label": "City", "type": "string", "required": true },
{ "key": "STRIPE_ACCOUNT_ID", "label": "Stripe Connect account ID", "type": "string" }
],
"venue": {
"features": {
"animals": true,
"adoption": true,
"memories": true,
"loyalty": true,
"giftCards": true,
"waivers": true,
"blog": true,
"pos": true
},
"theme": {
"primary": "oklch(0.45 0.18 35)",
"background": "oklch(0.98 0.015 90)",
"accent": "oklch(0.65 0.15 150)",
"text": "oklch(0.18 0.02 250)",
"displayFont": "Fraunces",
"bodyFont": "Inter"
},
"experienceTypes": [
{
"slug": "candle-making",
"name": "Candle Making",
"description": "Craft your own soy candle while surrounded by kittens",
"priceInCents": 5500,
"durationMinutes": 75,
"minGuests": 1,
"maxGuests": 8,
"requiresWaiver": true,
"sortOrder": 0
}
]
}
}
Workshop Kit kit.json Example
{
"id": "novel-writing-system",
"type": "content",
"name": "Novel Writing System",
"description": "Complete story development workspace for novelists",
"version": "2.1.0",
"author": { "name": "Soulcraft Labs" },
"workshop": {
"workspaceConfig": {
"paradigm": "writer",
"defaultView": "graph",
"defaultFile": "files/manuscript.md"
},
"aiPersona": {
"role": "developmental editor",
"expertise": ["narrative structure", "character arcs", "prose style"],
"tone": "mentor"
},
"suggestions": [
{ "label": "Add character", "prompt": "Create a new character and add them to the story graph" },
{ "label": "Outline act", "prompt": "Help me outline the next act of the story" }
]
}
}
Publish Protocol (Workshop → Venue)
When a Workshop workspace publishes content to Venue, it sends a PublishPayload:
import type { PublishPayload } from '@soulcraft/kit-schema';
const payload: PublishPayload = {
kitId: 'wicks-and-whiskers',
title: 'Our Story',
slug: 'our-story',
version: '1.0.0',
contentType: 'document',
content: {
body: '# Our Story\n\nWe started in 2019…',
mimeType: 'text/markdown',
},
sourceWorkshopUserId: 'user-abc123',
sourceWorkspaceId: 'workspace-xyz456',
deployedAt: new Date().toISOString(),
};
The contentType discriminant selects one of five content shapes:
document, visualization, slideshow, static, app.
License
Proprietary — Soulcraft Labs. All rights reserved.
Dependencies
Dependencies
| ID | Version |
|---|---|
| @soulcraft/theme | ^2.7.0 |
| zod | ^4.0.0 |
Development dependencies
| ID | Version |
|---|---|
| @types/node | ^25.3.0 |
| typescript | ^5.7.3 |
| vitest | ^3.0.5 |