Schematics is an Effect-native config-as-code control plane for external APIs and SaaS resources.
Connect an API, describe its resource kinds with Effect Schema, and get typed documents, semantic plans, agent tools, review, apply, and drift detection from one contract.
Schematics consumes @schema-reflection/algebra from the independent Schema
Reflection project. Its predicates and logic packages are the intended homes
for declarative conditions and behavior once the repositories share an Effect
release. Triplex is the intended durable home for definition releases,
observations, history, and provenance; Schematics owns the provider and
reconciliation lifecycle above it.
See Schematics in the constellation for the ownership boundaries and migration sequence.
Schematics brings four product capabilities around one resource contract:
- Provider integration for observing and mutating external resources.
- Desired-state documents for editing resource declarations with continuous validation.
- Semantic reconciliation for diffing declarations against observations and applying dependency-ordered plans.
- Human and agent review through the same typed capabilities, diagnostics, and provenance contract.
The product lifecycle is:
provider -> observations -> declarations -> plan -> review -> apply -> new observations
The existing ArtifactProject API remains as a compatibility implementation
for schema-routed documents while the public vocabulary migrates to resources,
declarations, releases, and observations. “Artifact” is reserved for published
outputs such as generated HTML.
Teams increasingly need humans and agents to manage important external configuration: repositories, identity providers, incident systems, CRM objects, workflows, policies, and infrastructure.
Plain text tools are not enough for that work. The agent needs to know:
- what each file means
- which schema applies
- what references are valid
- what downstream systems will change
- whether a proposed patch is safe
- what it will cost to inspect or materialize a view
- what deploy plan would result
Schematics answers each of those from the same resource contract. The current implementation routes documents through transitional artifact APIs, and every tool call is checked before it lands:
- Schema-routed artifact project. Files are addressed by artifact refs; paths match artifact routes by glob; validation runs continuously and produces a structured
SchematicsReflection. - Reflection stream. Diagnostics, parsed values, route matches, and validation summaries are first-class — consumable by the UI and the agent on equal footing.
- Schema-driven editor intelligence. CodeMirror uses the generated JSON Schema for completions, hover, lint actions, quick fixes, and reference lookups.
- Agent tools scoped to artifacts.
list_artifacts,get_artifact_capabilities,read_artifact_view,write_artifact_source, and compatibility file/workspace aliases all execute through artifact refs and declared views. - Safe edit modes. Direct mode can atomically apply validated multi-file edits; plan mode exposes read-only tools plus
propose_patchfor user approval. - Bring-your-own model. Ships with a standalone OpenRouter HTTP server, a typed HTTP client adapter, and a local debug adapter; the
SchematicsChatAdaptercontract is small enough to wire to anything. - React component.
<Schematics />gives you the CodeMirror editor, schema-derived form view, file tree, proposal review panel, diagnostics pane, timeline, and chat panel out of the box. - Config-as-code reconciliation. A Terraform/Alchemy-style
pull → edit → plan → applyloop (@schematics/alchemy, pending rename to a reconciliation package) turns validated declarations into managed changes against an external API.
@schematics/alchemy implements a Terraform-style resource lifecycle from
first principles. The package name is retained for compatibility while its
public contract moves toward resource reconciliation; the "cloud" can be any
external API and desired state is expressed as typed documents:
- Providers speak
list / read / create / update / deleteper entity kind. pullhydrates the working tree from the API;plandiffs your files against live (schema-value diff → create/update/delete/no-op);applyexecutes in dependency order with optimistic-concurrency guards;destroyunwinds it.- Lockfile identity (
config.lock.json) maps human slugs ↔ opaque remote ids, and resolves cross-entity references during apply. - Lazy/streaming sync — a
HydratingArtifactStorecan lay out a skeleton from list endpoints and hydrate file contents on first access, so the IDE fills in over time.
@schematics/provider is the authoring layer for domain providers. A provider
is a named external system plus the resources it manages: defineResource(...)
describes each file-level resource, and defineProvider(...) derives the
artifact project, workspace schema, relation diagnostics, mock transport,
reconciler, deploy service, and CLI wiring. examples/toy is the smallest
provider reference; examples/catalog remains the richest relation-modeling
reference.
@schema-reflection/algebra ───────> Schematics provider + planner + review
@schema-reflection/predicates - - > policy conditions (after Effect alignment)
@schema-reflection/logic - - - - -> behavior definitions (after Effect alignment)
Triplex ──────────────────────────> durable definitions, releases, observations
Foldworks ────────────────────────> reusable interaction surfaces
The @schema-reflection/* packages are neutral Effect libraries. Schematics
must not become their ownership boundary. Triplex integration follows after the
repositories converge on a compatible Effect release; serialized contracts are
the boundary until then.
The workspace consumes @schema-reflection/algebra@0.1.0 from npm. The
repository is in a boundary migration; its own packages currently are:
@schematics/artifacts— Effect-native artifact APIs, types, matchers, handlers, registries, stores, and project declarations.@schematics/core— Schematics artifact runtime, workspace compatibility projection, JSON/YAML codecs, validation, reflection, schema language-service helpers, and virtual filesystem helpers.@schematics/protocol— OpenRouter-compatible chat schemas plus the EffectHttpApicontract.@schematics/agent— Effect AI tool definitions, tool execution, and chat adapters.@schematics/ide— the<Schematics />React surface, built directly on MUI primitives.@schematics/server— standalone Effect HTTP server for the OpenRouter proxy.@schematics/cli— local filesystem CLI for loading artifact project configs and printing diagnostics/routes/JSON Schema.@schematics/alchemy— transitional name for the provider-agnostic reconciliation engine:pull/plan/apply/destroy, semantic diff, dependency ordering, state, and lazy hydration.@schematics/deploy— framework deploy service plumbing used by provider-backed projects.@schematics/provider— provider DSL: resources, provider composition, derived artifact projects, diagnostics, mock transports, reconcilers, deploy service integration, and provider CLI helpers.@schematics/example-catalog— the rich public-library catalog: relation-annotated schemas exercising the full algebra, a mockCatalogApi, catalog deploy tooling, the artifact project, the NYC Public Library sample, and embedded CLI bundle.@schematics/example-toy— the minimal provider DSL example (cards + decks) with deliberately broken fixtures (broken-refs,duplicate-ids) that showcase diagnostics.@schematics/example-github,@schematics/example-okta,@schematics/example-pagerduty,@schematics/example-salesforce— SaaS provider examples with derived mocks, deploy services, CLIs, and seeded fixture workspaces.@schematics/examples— generated JS examples backed by the first-party artifact projects and fixture files on disk.
Building your own domain-specific config-as-code project on top of Schematics?
See docs/consuming-schematics.md — the
recommended way to link the framework (git submodule today, npm later), build a
CLI binary, and optionally ship a frontend from @schematics/ide.
Start with examples/toy for the smallest provider package and use
examples/catalog when you need a dense relation-modeling reference.
- SaaS platform teams exposing a safe config-as-code surface over their API.
- Internal platform teams managing repositories, identity, incident response, CRM, and workflow configuration together.
- Agent product teams that need inspectable capabilities and reviewable plans instead of browser automation.
- Open Ontology and similar products that want typed external-resource management without rebuilding the control plane.
The whole stack is Effect-native: schemas are effect/Schema, the chat adapter is moving toward Effect<ChatResult, ChatError> with Stream for tool-call and token events, and the workspace runtime is a Context.Tag service so test layers and production layers compose the same way. If you already speak Effect, this should feel like home.
@schema-reflection/algebra is the semantic layer that lets Effect Schema nodes
describe more than local validation. The first implemented capability is
relation metadata:
import { Schema } from "effect";
import { Relation } from "@schema-reflection/algebra";
const ActionSchema = Schema.Struct({
id: Relation.id("Action"),
label: Schema.String,
});
const WorkflowSchema = Schema.Struct({
id: Relation.id("Workflow"),
actionIds: Relation.refs("Action"),
});From those annotations, algebra can extract a relation graph and validate duplicate IDs, unresolved references, scoped references, and invalid relation values. The larger direction is to derive autocomplete, go-to-definition, find-references, safe rename, impact analysis, patch generation, and agent-constrained edits from the same schema declarations.
Pre-1.0 and mid-migration. @schema-reflection/* is the neutral library
boundary. Schematics packages remain private while artifact terminology,
Triplex persistence, and Foldworks UI boundaries are migrated. Breaking changes
are expected.
PLAN.md is gitignored and reserved for local planning with coding agents. Use it for scratch plans, task breakdowns, and implementation notes that should stay out of commits.
- Schema-derived autocompletion and hover (Monaco / CodeMirror via JSON Schema language services).
- Patch-based time travel — every tool call produces a
WorkspacePatchwith undo/redo/branch. - Diff-and-approve mode — agent proposes, user applies.
- Cross-file constraints with structured references between schemas, powered by
@schema-reflection/algebra. - Plan mode — read-only tool subset plus a
propose_patchtool that does not apply. - Atomic
apply_editstool with validation rollback. - Token-aware reflection summarization.
- Tool-call eval harness — regression-test prompt changes against (schema, files, prompt) fixtures.
- MCP server exposing the same tool surface.
- Schema algebra modules for paths, traversal, annotations, constraints, lenses, projections, diffs, patches, generation, and schema fingerprints.
New Schematics projects should start from an ArtifactProject. The project is
the route and capability contract used by React, the CLI, protocol clients, and
agent tools. It is an implementation-stage name for a schema-routed document
project, not the long-term product vocabulary. Workspace.Struct is deprecated compatibility sugar for older
callers and tests. Provider-backed projects usually get their ArtifactProject
from defineProvider(...); see examples/toy for the minimal resource/provider
shape.
import { Schema } from "effect";
import { ArtifactProject } from "@schematics/artifacts";
import { SchematicsProjectFileArtifact } from "@schematics/core";
import { createSchematicsChatAdapter } from "@schematics/agent";
import { Schematics } from "@schematics/ide";
const UserSchema = Schema.Struct({
id: Schema.String,
name: Schema.String,
});
const UserProject = ArtifactProject.make("users").files("users/*.yaml", {
id: "Users",
type: SchematicsProjectFileArtifact,
schema: UserSchema,
metadata: {
attributes: {
workspaceField: "users",
indexBy: "id",
format: "yaml",
},
},
});
<Schematics
project={UserProject}
initialFiles={[{ path: "users/alice.yaml", content: "id: alice\nname: Alice\n" }]}
chat={createSchematicsChatAdapter({ baseUrl: "/v1" })}
/>;Run the isolated playground with:
pnpm install --frozen-lockfile
pnpm devRun just the standalone HTTP server with:
pnpm --dir packages/server devRun targeted tests through Turbo so workspace dependencies are built before
tests that import package dist entrypoints:
pnpm turbo run test --filter @schematics/cli
pnpm turbo run typecheck --filter @schematics/ideAvoid pnpm --filter <package> test for packages whose tests load consumer
configs or package exports; that bypasses Turbo's dependency graph and can fail
in a fresh checkout with missing dist files.
Validate a local directory with a consumer artifact project config:
schematics validate --schema ./schematics.config.ts --dir . --jsonThe bundled examples can also be tried from disk:
schematics validate \
--schema examples/toy/projects/valid/schematics.config.ts \
--dir examples/toy/projects/valid/files \
--jsonRun the reference catalog config CLI by building its package and invoking the embedded command:
pnpm turbo run build --filter @schematics/example-catalog
node examples/catalog/dist/cli.js validate \
--dir examples/catalog/projects/nyc-public-library/files \
--jsonPull the live (mock) NYC Public Library catalog to disk, then plan a change:
node examples/catalog/dist/deploy-cli-bin.js pull --dir /tmp/nypl
node examples/catalog/dist/deploy-cli-bin.js plan --dir /tmp/nyplTo smoke-test the consumer-style bundle:
pnpm turbo run build:bundle --filter @schematics/example-catalog
node examples/catalog/dist/bundle/catalog-config.cjs validate \
--dir examples/catalog/projects/nyc-public-library/files \
--jsonThe bundle also embeds the built playground UI, so it can serve the web app as a
single Node entry without apps/playground/dist on disk:
node examples/catalog/dist/bundle/catalog-config.cjs web \
--dir examples/catalog/projects/nyc-public-library/filesBuild a single Node SEA binary from the same bundled entry with:
pnpm turbo run build:sea --filter @schematics/example-catalog -- \
--out examples/catalog/dist/sea/catalog-configRun the catalog artifact project in the local web UI with:
pnpm playground:build
pnpm turbo run build --filter @schematics/example-catalog
node examples/catalog/dist/cli.js web \
--dir examples/catalog/projects/nyc-public-library/filesWithout SCHEMATICS_OPENROUTER_API_KEY, the server uses a local debug chat responder so the package-local UI and HTTP loop still work. Set SCHEMATICS_OPENROUTER_API_KEY or OPENROUTER_API_KEY to proxy real model calls through OpenRouter.
After building, the server package also exposes a schematics-server binary and pnpm --dir packages/server start.
Build and serve the isolated package UI and HTTP API from one Node process with:
pnpm serveThat command builds @schematics/*, builds the playground, starts @schematics/server, serves the playground at /, and reserves /v1 for the chat/model/health API.
Run pnpm serve:smoke to verify the same path in automation.
The repository includes .github/workflows/cloudflare-production.yml for
Cloudflare production deploys. Pushes to main deploy the prod Alchemy stage,
which includes the Cloudflare Vite playground and API worker.
The root alchemy.run.ts can also deploy the same stack from a local shell:
pnpm playground:deploy:dry-run
pnpm playground:deployAlchemy deploys apps/playground with Cloudflare.Vite and prints
playgroundUrl when the stack applies. It also deploys the Schematics API
worker and wires the playground to that API unless VITE_SCHEMATICS_API_BASE_URL
or SCHEMATICS_API_BASE_URL is set before deploy.
Production deploys use the prod Alchemy stage:
pnpm alchemy deploy --stage prod --yesMain-branch production deploys and pull request previews both require these repository secrets:
CLOUDFLARE_ACCOUNT_IDCLOUDFLARE_API_TOKEN
Set OPENROUTER_API_KEY as a repository secret to enable hosted chat calls.
Pull requests from this repository deploy isolated preview stacks named
pr-<number> and post the playground/API URLs back to the PR.
Stale PR previews are cleaned up by the nightly Cloudflare cleanup workflow.
The cleanup only considers Alchemy stages named pr-<number> and destroys them
after the matching GitHub PR has been closed for the configured number of days.
You can preview the cleanup locally with:
pnpm cloudflare:cleanup --dry-run --days 7The local Node server and Cloudflare worker both wrap the same makeSchematicsAppLayer entrypoint. They pass different debug-chat labels so a missing model key is obvious:
- Local: set
OPENROUTER_API_KEYorSCHEMATICS_OPENROUTER_API_KEYin your shell or repo.env. - Cloudflare: set
OPENROUTER_API_KEYin the Cloudflare/Alchemy deployment environment, then redeploy.
Without a key, chat still responds in deterministic debug mode and does not call a model.
When copied into its own repository, this directory includes its own pnpm-workspace.yaml, tsconfig.base.json, CI workflow, license, and contribution docs.